C2/CCodec: allow setting temporal layering
- add constructors for temporal layering (and info structures, the
only other flex structure without a flex constructor)
- support setting temporal layering
TODO: query temporal layering
Bug: 90469941
Change-Id: I12a2751f2064b2a226e67af184e6ec75e2c3c1bb
diff --git a/codec2/include/C2Config.h b/codec2/include/C2Config.h
index 93897bf..91349f7 100644
--- a/codec2/include/C2Config.h
+++ b/codec2/include/C2Config.h
@@ -710,6 +710,12 @@
C2SupplementalDataStruct()
: type_(INFO_NONE) { }
+ C2SupplementalDataStruct(
+ size_t flexCount, C2Config::supplemental_info_t type, std::vector<uint8_t> data_)
+ : type_(type) {
+ memcpy(data, &data_[0], c2_min(data_.size(), flexCount));
+ }
+
C2Config::supplemental_info_t type_;
uint8_t data[];
@@ -1705,9 +1711,21 @@
C2TemporalLayeringStruct()
: layerCount(0), bLayerCount(0) { }
- C2TemporalLayeringStruct(uint32_t layerCount_, uint32_t bLayerCount_)
+ C2TemporalLayeringStruct(size_t /* flexCount */, uint32_t layerCount_, uint32_t bLayerCount_)
: layerCount(layerCount_), bLayerCount(c2_min(layerCount_, bLayerCount_)) { }
+ C2TemporalLayeringStruct(size_t flexCount, uint32_t layerCount_, uint32_t bLayerCount_,
+ std::initializer_list<float> ratios)
+ : layerCount(layerCount_), bLayerCount(c2_min(layerCount_, bLayerCount_)) {
+ size_t ix = 0;
+ for (float ratio : ratios) {
+ if (ix == flexCount) {
+ break;
+ }
+ bitrateRatios[ix++] = ratio;
+ }
+ }
+
uint32_t layerCount; ///< total number of layers (0 means no temporal layering)
uint32_t bLayerCount; ///< total number of bidirectional layers (<= num layers)
/**
diff --git a/media/sfplugin/CCodecConfig.cpp b/media/sfplugin/CCodecConfig.cpp
index d68031e..1a6e641 100644
--- a/media/sfplugin/CCodecConfig.cpp
+++ b/media/sfplugin/CCodecConfig.cpp
@@ -138,7 +138,7 @@
Domain domain() const { return mDomain; }
std::string mediaKey() const { return mMediaKey; }
- std::string path() const { return mStruct + '.' + mField; }
+ std::string path() const { return mField.size() ? mStruct + '.' + mField : mStruct; }
Mapper mapper() const { return mMapper; }
Mapper reverse() const { return mReverse; }
@@ -446,6 +446,9 @@
add(ConfigMapper("csd-0", C2_PARAMKEY_INIT_DATA, "value")
.limitTo(D::OUTPUT & D::READ));
+ add(ConfigMapper(C2_PARAMKEY_TEMPORAL_LAYERING, C2_PARAMKEY_TEMPORAL_LAYERING, "")
+ .limitTo(D::ENCODER & D::VIDEO & D::OUTPUT));
+
// Pixel Format (use local key for actual pixel format as we don't distinguish between
// SDK layouts for flexible format and we need the actual SDK color format in the media format)
add(ConfigMapper("android._color-format", C2_PARAMKEY_PIXEL_FORMAT, "value")
@@ -735,6 +738,8 @@
// enumerate all fields
mParamUpdater = std::make_shared<ReflectedParamUpdater>();
mParamUpdater->clear();
+ mParamUpdater->supportWholeParam(
+ C2_PARAMKEY_TEMPORAL_LAYERING, C2StreamTemporalLayeringTuning::CORE_INDEX);
mParamUpdater->addParamDesc(mReflector, mParamDescs);
// TEMP: add some standard fields even if not reflected
@@ -994,6 +999,50 @@
}
}
+ { // reflect temporal layering into a binary blob
+ AString schema;
+ if (params->findString(KEY_TEMPORAL_LAYERING, &schema)) {
+ unsigned int numLayers = 0;
+ unsigned int numBLayers = 0;
+ int tags;
+ char dummy;
+ std::unique_ptr<C2StreamTemporalLayeringTuning::output> layering;
+ if (sscanf(schema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
+ && numLayers > 0) {
+ switch (numLayers) {
+ case 1:
+ layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+ {}, 0u, 1u, 0u);
+ break;
+ case 2:
+ layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+ { .6f }, 0u, 2u, 0u);
+ break;
+ case 3:
+ layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+ { .4f, .6f }, 0u, 3u, 0u);
+ break;
+ default:
+ layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+ { .25f, .4f, .6f }, 0u, 4u, 0u);
+ break;
+ }
+ } else if ((tags = sscanf(schema.c_str(), "android.generic.%u%c%u%c",
+ &numLayers, &dummy, &numBLayers, &dummy))
+ && (tags == 1 || (tags == 3 && dummy == '+'))
+ && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
+ layering = C2StreamTemporalLayeringTuning::output::AllocUnique(
+ {}, 0u, numLayers, numBLayers);
+ } else {
+ ALOGD("Ignoring unsupported ts-schema [%s]", schema.c_str());
+ }
+ if (layering) {
+ params->setBuffer(C2_PARAMKEY_TEMPORAL_LAYERING,
+ ABuffer::CreateAsCopy(layering.get(), layering->size()));
+ }
+ }
+ }
+
{ // convert from MediaFormat rect to Codec 2.0 rect
int32_t offset;
int32_t end;