Rework how QP bounds are passed
Pass via an (variable length) set of settings for picture types
instead of the fixed I/P/B types. Also makes it possible to
pass a max without also passing a min.
Bug: 181830609
Test: vq testing, ALOG
Change-Id: I69bba8e35f0eda234530df92706230dc898b4ae9
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 8e8a08b..f8aa672 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -187,7 +187,7 @@
kParamIndexPictureType,
kParamIndexHdr10PlusMetadata,
- kParamIndexQuantization,
+ kParamIndexPictureQuantization,
/* ------------------------------------ video components ------------------------------------ */
@@ -710,38 +710,6 @@
C2StreamProfileLevelInfo;
constexpr char C2_PARAMKEY_PROFILE_LEVEL[] = "coded.pl";
-struct C2QuantizationStruct {
- int32_t iMax; ///< max/min for I frames
- int32_t iMin;
- int32_t pMax; ///< max/min for P frames
- int32_t pMin;
- int32_t bMax; ///< max/min for B frames
- int32_t bMin;
-
- C2QuantizationStruct(
- int32_t iMax_ = INT32_MAX,
- int32_t iMin_ = INT32_MIN,
- int32_t pMax_ = INT32_MAX,
- int32_t pMin_ = INT32_MIN,
- int32_t bMax_ = INT32_MAX,
- int32_t bMin_ = INT32_MIN)
- : iMax(iMax_), iMin(iMin_),
- pMax(pMax_), pMin(pMin_),
- bMax(bMax_), bMin(bMin_) { }
-
- DEFINE_AND_DESCRIBE_C2STRUCT(Quantization) // reference?
- C2FIELD(iMax, "i-max")
- C2FIELD(iMin, "i-min")
- C2FIELD(pMax, "p-max")
- C2FIELD(pMin, "p-min")
- C2FIELD(bMax, "b-max")
- C2FIELD(bMin, "b-min")
-};
-
-typedef C2StreamParam<C2Info, C2QuantizationStruct, kParamIndexQuantization>
- C2StreamQuantizationInfo;
-constexpr char C2_PARAMKEY_QUANTIZATION[] = "coded.qp";
-
/**
* Codec-specific initialization data.
*
@@ -1733,6 +1701,31 @@
constexpr char C2_PARAMKEY_GOP[] = "coding.gop";
/**
+ * Quantization
+ * min/max for each picture type
+ *
+ */
+struct C2PictureQuantizationStruct {
+ C2PictureQuantizationStruct() : type_((C2Config::picture_type_t)0),
+ min(INT32_MIN), max(INT32_MAX) {}
+ C2PictureQuantizationStruct(C2Config::picture_type_t type, int32_t min_, int32_t max_)
+ : type_(type), min(min_), max(max_) { }
+
+ C2Config::picture_type_t type_;
+ int32_t min; // INT32_MIN == 'no lower bound specified'
+ int32_t max; // INT32_MAX == 'no upper bound specified'
+
+ DEFINE_AND_DESCRIBE_C2STRUCT(PictureQuantization)
+ C2FIELD(type_, "type")
+ C2FIELD(min, "min")
+ C2FIELD(max, "max")
+};
+
+typedef C2StreamParam<C2Tuning, C2SimpleArrayStruct<C2PictureQuantizationStruct>,
+ kParamIndexPictureQuantization> C2StreamPictureQuantizationTuning;
+constexpr char C2_PARAMKEY_PICTURE_QUANTIZATION[] = "coding.qp";
+
+/**
* Sync frame can be requested on demand by the client.
*
* If true, the next I frame shall be encoded as a sync frame. This config can be passed
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index f3cde54..76efdaf 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1066,6 +1066,45 @@
configUpdate.push_back(std::move(gop));
}
+ if ((config->mDomain & Config::IS_ENCODER)
+ && (config->mDomain & Config::IS_VIDEO)) {
+ // we may not use all 3 of these entries
+ std::unique_ptr<C2StreamPictureQuantizationTuning::output> qp =
+ C2StreamPictureQuantizationTuning::output::AllocUnique(3 /* flexCount */,
+ 0u /* stream */);
+
+ int ix = 0;
+
+ int32_t iMax = INT32_MAX;
+ int32_t iMin = INT32_MIN;
+ (void) sdkParams->findInt32(KEY_VIDEO_QP_I_MAX, &iMax);
+ (void) sdkParams->findInt32(KEY_VIDEO_QP_I_MIN, &iMin);
+ if (iMax != INT32_MAX || iMin != INT32_MIN) {
+ qp->m.values[ix++] = {I_FRAME, iMin, iMax};
+ }
+
+ int32_t pMax = INT32_MAX;
+ int32_t pMin = INT32_MIN;
+ (void) sdkParams->findInt32(KEY_VIDEO_QP_P_MAX, &pMax);
+ (void) sdkParams->findInt32(KEY_VIDEO_QP_P_MIN, &pMin);
+ if (pMax != INT32_MAX || pMin != INT32_MIN) {
+ qp->m.values[ix++] = {P_FRAME, pMin, pMax};
+ }
+
+ int32_t bMax = INT32_MAX;
+ int32_t bMin = INT32_MIN;
+ (void) sdkParams->findInt32(KEY_VIDEO_QP_B_MAX, &bMax);
+ (void) sdkParams->findInt32(KEY_VIDEO_QP_B_MIN, &bMin);
+ if (bMax != INT32_MAX || bMin != INT32_MIN) {
+ qp->m.values[ix++] = {B_FRAME, bMin, bMax};
+ }
+
+ // adjust to reflect actual use.
+ qp->setFlexCount(ix);
+
+ configUpdate.push_back(std::move(qp));
+ }
+
err = config->setParameters(comp, configUpdate, C2_DONT_BLOCK);
if (err != OK) {
ALOGW("failed to configure c2 params");
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 5de7539..f5cc98e 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -729,19 +729,6 @@
return C2Value();
}));
- add(ConfigMapper(KEY_VIDEO_QP_I_MAX, C2_PARAMKEY_QUANTIZATION, "i-max")
- .limitTo(D::VIDEO & D::ENCODER));
- add(ConfigMapper(KEY_VIDEO_QP_I_MIN, C2_PARAMKEY_QUANTIZATION, "i-min")
- .limitTo(D::VIDEO & D::ENCODER));
- add(ConfigMapper(KEY_VIDEO_QP_P_MAX, C2_PARAMKEY_QUANTIZATION, "p-max")
- .limitTo(D::VIDEO & D::ENCODER));
- add(ConfigMapper(KEY_VIDEO_QP_P_MIN, C2_PARAMKEY_QUANTIZATION, "p-min")
- .limitTo(D::VIDEO & D::ENCODER));
- add(ConfigMapper(KEY_VIDEO_QP_B_MAX, C2_PARAMKEY_QUANTIZATION, "b-max")
- .limitTo(D::VIDEO & D::ENCODER));
- add(ConfigMapper(KEY_VIDEO_QP_B_MIN, C2_PARAMKEY_QUANTIZATION, "b-min")
- .limitTo(D::VIDEO & D::ENCODER));
-
// convert to dBFS and add default
add(ConfigMapper(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL, "value")
.limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM | D::READ))