Move QP bounding to reflect properly
Bounding of QP values was handled late and not being propagated back to the client.
Bug: 183211971
Test: VQ tests
Change-Id: Id77df74a3b2311983bf45a4a37eab7cbda6cfdbf
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index 0b121ad..d65ffa5 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -393,6 +393,61 @@
C2P<C2StreamPictureQuantizationTuning::output> &me) {
(void)mayBlock;
(void)me;
+
+ // TODO: refactor with same algorithm in the SetQp()
+ int32_t iMin = DEFAULT_I_QP_MIN, pMin = DEFAULT_P_QP_MIN, bMin = DEFAULT_B_QP_MIN;
+ int32_t iMax = DEFAULT_I_QP_MAX, pMax = DEFAULT_P_QP_MAX, bMax = DEFAULT_B_QP_MAX;
+
+ for (size_t i = 0; i < me.v.flexCount(); ++i) {
+ const C2PictureQuantizationStruct &layer = me.v.m.values[i];
+
+ if (layer.type_ == C2Config::picture_type_t(I_FRAME)) {
+ iMax = layer.max;
+ iMin = layer.min;
+ ALOGV("iMin %d iMax %d", iMin, iMax);
+ } else if (layer.type_ == C2Config::picture_type_t(P_FRAME)) {
+ pMax = layer.max;
+ pMin = layer.min;
+ ALOGV("pMin %d pMax %d", pMin, pMax);
+ } else if (layer.type_ == C2Config::picture_type_t(B_FRAME)) {
+ bMax = layer.max;
+ bMin = layer.min;
+ ALOGV("bMin %d bMax %d", bMin, bMax);
+ }
+ }
+
+ ALOGV("PictureQuantizationSetter(entry): i %d-%d p %d-%d b %d-%d",
+ iMin, iMax, pMin, pMax, bMin, bMax);
+
+ // ensure we have legal values
+ iMax = std::clamp(iMax, CODEC_QP_MIN, CODEC_QP_MAX);
+ iMin = std::clamp(iMin, CODEC_QP_MIN, CODEC_QP_MAX);
+ pMax = std::clamp(pMax, CODEC_QP_MIN, CODEC_QP_MAX);
+ pMin = std::clamp(pMin, CODEC_QP_MIN, CODEC_QP_MAX);
+ bMax = std::clamp(bMax, CODEC_QP_MIN, CODEC_QP_MAX);
+ bMin = std::clamp(bMin, CODEC_QP_MIN, CODEC_QP_MAX);
+
+ // put them back into the structure
+ for (size_t i = 0; i < me.v.flexCount(); ++i) {
+ const C2PictureQuantizationStruct &layer = me.v.m.values[i];
+
+ if (layer.type_ == C2Config::picture_type_t(I_FRAME)) {
+ me.set().m.values[i].max = iMax;
+ me.set().m.values[i].min = iMin;
+ }
+ if (layer.type_ == C2Config::picture_type_t(P_FRAME)) {
+ me.set().m.values[i].max = pMax;
+ me.set().m.values[i].min = pMin;
+ }
+ if (layer.type_ == C2Config::picture_type_t(B_FRAME)) {
+ me.set().m.values[i].max = bMax;
+ me.set().m.values[i].min = bMin;
+ }
+ }
+
+ ALOGV("PictureQuantizationSetter(exit): i %d-%d p %d-%d b %d-%d",
+ iMin, iMax, pMin, pMax, bMin, bMax);
+
return C2R::Ok();
}
@@ -765,10 +820,11 @@
s_qp_ip.e_cmd = IVE_CMD_VIDEO_CTL;
s_qp_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP;
- // these are the ones we're going to set, so want them to default ....
- // to the DEFAULT values for the codec instea dof CODEC_ bounding
- int32_t iMin = INT32_MIN, pMin = INT32_MIN, bMin = INT32_MIN;
- int32_t iMax = INT32_MAX, pMax = INT32_MAX, bMax = INT32_MAX;
+ // TODO: refactor with same algorithm in the PictureQuantizationSetter()
+ int32_t iMin = DEFAULT_I_QP_MIN, pMin = DEFAULT_P_QP_MIN, bMin = DEFAULT_B_QP_MIN;
+ int32_t iMax = DEFAULT_I_QP_MAX, pMax = DEFAULT_P_QP_MAX, bMax = DEFAULT_B_QP_MAX;
+
+ IntfImpl::Lock lock = mIntf->lock();
std::shared_ptr<C2StreamPictureQuantizationTuning::output> qp =
mIntf->getPictureQuantization_l();
@@ -790,22 +846,6 @@
}
}
- // INT32_{MIN,MAX} means unspecified, so use the codec's default
- if (iMax == INT32_MAX) iMax = DEFAULT_I_QP_MAX;
- if (iMin == INT32_MIN) iMin = DEFAULT_I_QP_MIN;
- if (pMax == INT32_MAX) pMax = DEFAULT_P_QP_MAX;
- if (pMin == INT32_MIN) pMin = DEFAULT_P_QP_MIN;
- if (bMax == INT32_MAX) bMax = DEFAULT_B_QP_MAX;
- if (bMin == INT32_MIN) bMin = DEFAULT_B_QP_MIN;
-
- // ensure we have legal values
- iMax = std::clamp(iMax, CODEC_QP_MIN, CODEC_QP_MAX);
- iMin = std::clamp(iMin, CODEC_QP_MIN, CODEC_QP_MAX);
- pMax = std::clamp(pMax, CODEC_QP_MIN, CODEC_QP_MAX);
- pMin = std::clamp(pMin, CODEC_QP_MIN, CODEC_QP_MAX);
- bMax = std::clamp(bMax, CODEC_QP_MIN, CODEC_QP_MAX);
- bMin = std::clamp(bMin, CODEC_QP_MIN, CODEC_QP_MAX);
-
s_qp_ip.u4_i_qp_max = iMax;
s_qp_ip.u4_i_qp_min = iMin;
s_qp_ip.u4_p_qp_max = pMax;
@@ -818,7 +858,7 @@
s_qp_ip.u4_p_qp = std::clamp(DEFAULT_P_QP, pMin, pMax);
s_qp_ip.u4_b_qp = std::clamp(DEFAULT_B_QP, bMin, bMax);
- ALOGV("setting QP: i %d-%d p %d-%d b %d-%d", iMin, iMax, pMin, pMax, bMin, bMax);
+ ALOGV("setQp(): i %d-%d p %d-%d b %d-%d", iMin, iMax, pMin, pMax, bMin, bMax);
s_qp_ip.u4_timestamp_high = -1;
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.h b/media/codec2/components/avc/C2SoftAvcEnc.h
index baf33e2..1fecd9e 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.h
+++ b/media/codec2/components/avc/C2SoftAvcEnc.h
@@ -99,8 +99,10 @@
#define STRLENGTH 500
#define DEFAULT_CONSTRAINED_INTRA 0
-/** limits as specified by h264 */
-#define CODEC_QP_MIN 0
+/** limits as specified by h264
+ * (QP_MIN==4 is actually a limitation of this SW codec, not the H.264 standard)
+ **/
+#define CODEC_QP_MIN 4
#define CODEC_QP_MAX 51