Loading media/codec2/components/hevc/C2SoftHevcEnc.cpp +106 −2 Original line number Diff line number Diff line Loading @@ -245,6 +245,19 @@ class C2SoftHevcEnc::IntfImpl : public SimpleInterface<void>::BaseParams { }) .withSetter(CodedColorAspectsSetter, mColorAspects) .build()); addParameter( DefineParam(mPictureQuantization, C2_PARAMKEY_PICTURE_QUANTIZATION) .withDefault(C2StreamPictureQuantizationTuning::output::AllocShared( 0 /* flexCount */, 0u /* stream */)) .withFields({C2F(mPictureQuantization, m.values[0].type_).oneOf( {C2Config::picture_type_t(I_FRAME), C2Config::picture_type_t(P_FRAME), C2Config::picture_type_t(B_FRAME)}), C2F(mPictureQuantization, m.values[0].min).any(), C2F(mPictureQuantization, m.values[0].max).any()}) .withSetter(PictureQuantizationSetter) .build()); } static C2R InputDelaySetter( Loading Loading @@ -464,9 +477,69 @@ class C2SoftHevcEnc::IntfImpl : public SimpleInterface<void>::BaseParams { me.set().matrix = coded.v.matrix; return C2R::Ok(); } static C2R PictureQuantizationSetter(bool mayBlock, C2P<C2StreamPictureQuantizationTuning::output> &me) { (void)mayBlock; // these are the ones we're going to set, so want them to default // to the DEFAULT values for the codec int32_t iMin = HEVC_QP_MIN, pMin = HEVC_QP_MIN, bMin = HEVC_QP_MIN; int32_t iMax = HEVC_QP_MAX, pMax = HEVC_QP_MAX, bMax = HEVC_QP_MAX; for (size_t i = 0; i < me.v.flexCount(); ++i) { const C2PictureQuantizationStruct &layer = me.v.m.values[i]; // layerMin is clamped to [HEVC_QP_MIN, layerMax] to avoid error // cases where layer.min > layer.max int32_t layerMax = std::clamp(layer.max, HEVC_QP_MIN, HEVC_QP_MAX); int32_t layerMin = std::clamp(layer.min, HEVC_QP_MIN, layerMax); if (layer.type_ == C2Config::picture_type_t(I_FRAME)) { iMax = layerMax; iMin = layerMin; ALOGV("iMin %d iMax %d", iMin, iMax); } else if (layer.type_ == C2Config::picture_type_t(P_FRAME)) { pMax = layerMax; pMin = layerMin; ALOGV("pMin %d pMax %d", pMin, pMax); } else if (layer.type_ == C2Config::picture_type_t(B_FRAME)) { bMax = layerMax; bMin = layerMin; 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); int32_t maxFrameQP = std::min(std::min(iMax, pMax), bMax); int32_t minFrameQP = std::max(std::max(iMin, pMin), bMin); if (minFrameQP > maxFrameQP) { minFrameQP = maxFrameQP; } // 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) || layer.type_ == C2Config::picture_type_t(P_FRAME) || layer.type_ == C2Config::picture_type_t(B_FRAME)) { me.set().m.values[i].max = maxFrameQP; me.set().m.values[i].min = minFrameQP; } } ALOGV("PictureQuantizationSetter(exit): i = p = b = %d-%d", minFrameQP, maxFrameQP); return C2R::Ok(); } std::shared_ptr<C2StreamColorAspectsInfo::output> getCodedColorAspects_l() { return mCodedColorAspects; } std::shared_ptr<C2StreamPictureQuantizationTuning::output> getPictureQuantization_l() const { return mPictureQuantization; } private: std::shared_ptr<C2StreamUsageTuning::input> mUsage; Loading @@ -482,6 +555,7 @@ class C2SoftHevcEnc::IntfImpl : public SimpleInterface<void>::BaseParams { std::shared_ptr<C2StreamGopTuning::output> mGop; std::shared_ptr<C2StreamColorAspectsInfo::input> mColorAspects; std::shared_ptr<C2StreamColorAspectsInfo::output> mCodedColorAspects; std::shared_ptr<C2StreamPictureQuantizationTuning::output> mPictureQuantization; }; static size_t GetCPUCoreCount() { Loading Loading @@ -654,12 +728,41 @@ c2_status_t C2SoftHevcEnc::initEncParams() { mEncParams.s_coding_tools_prms.i4_max_temporal_layers = 3; } // we resolved out-of-bound and unspecified values in PictureQuantizationSetter() // so we can start with defaults that are overridden as needed. int32_t maxFrameQP = mEncParams.s_config_prms.i4_max_frame_qp; int32_t minFrameQP = mEncParams.s_config_prms.i4_min_frame_qp; for (size_t i = 0; i < mQpBounds->flexCount(); ++i) { const C2PictureQuantizationStruct &layer = mQpBounds->m.values[i]; // no need to loop, hevc library takes same range for I/P/B picture type if (layer.type_ == C2Config::picture_type_t(I_FRAME) || layer.type_ == C2Config::picture_type_t(P_FRAME) || layer.type_ == C2Config::picture_type_t(B_FRAME)) { maxFrameQP = layer.max; minFrameQP = layer.min; break; } } mEncParams.s_config_prms.i4_max_frame_qp = maxFrameQP; mEncParams.s_config_prms.i4_min_frame_qp = minFrameQP; ALOGV("MaxFrameQp: %d MinFrameQp: %d", maxFrameQP, minFrameQP); mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_frame_qp[0] = std::clamp(kDefaultInitQP, minFrameQP, maxFrameQP); switch (mBitrateMode->value) { case C2Config::BITRATE_IGNORE: case C2Config::BITRATE_IGNORE: { mEncParams.s_config_prms.i4_rate_control_mode = 3; // ensure initial qp values are within our newly configured bounds int32_t frameQp = getQpFromQuality(mQuality->value); mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_frame_qp[0] = getQpFromQuality(mQuality->value); std::clamp(frameQp, minFrameQP, maxFrameQP); break; } case C2Config::BITRATE_CONST: mEncParams.s_config_prms.i4_rate_control_mode = 5; break; Loading Loading @@ -723,6 +826,7 @@ c2_status_t C2SoftHevcEnc::initEncoder() { mGop = mIntf->getGop_l(); mRequestSync = mIntf->getRequestSync_l(); mColorAspects = mIntf->getCodedColorAspects_l(); mQpBounds = mIntf->getPictureQuantization_l();; } c2_status_t status = initEncParams(); Loading media/codec2/components/hevc/C2SoftHevcEnc.h +6 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,11 @@ namespace android { #define DEFAULT_B_FRAMES 0 #define DEFAULT_RC_LOOKAHEAD 0 #define HEVC_QP_MIN 1 #define HEVC_QP_MAX 51 constexpr int32_t kDefaultInitQP = 32; struct C2SoftHevcEnc : public SimpleC2Component { class IntfImpl; Loading Loading @@ -90,6 +95,7 @@ struct C2SoftHevcEnc : public SimpleC2Component { std::shared_ptr<C2StreamGopTuning::output> mGop; std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync; std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects; std::shared_ptr<C2StreamPictureQuantizationTuning::output> mQpBounds; #ifdef FILE_DUMP_ENABLE char mInFile[200]; char mOutFile[200]; Loading Loading
media/codec2/components/hevc/C2SoftHevcEnc.cpp +106 −2 Original line number Diff line number Diff line Loading @@ -245,6 +245,19 @@ class C2SoftHevcEnc::IntfImpl : public SimpleInterface<void>::BaseParams { }) .withSetter(CodedColorAspectsSetter, mColorAspects) .build()); addParameter( DefineParam(mPictureQuantization, C2_PARAMKEY_PICTURE_QUANTIZATION) .withDefault(C2StreamPictureQuantizationTuning::output::AllocShared( 0 /* flexCount */, 0u /* stream */)) .withFields({C2F(mPictureQuantization, m.values[0].type_).oneOf( {C2Config::picture_type_t(I_FRAME), C2Config::picture_type_t(P_FRAME), C2Config::picture_type_t(B_FRAME)}), C2F(mPictureQuantization, m.values[0].min).any(), C2F(mPictureQuantization, m.values[0].max).any()}) .withSetter(PictureQuantizationSetter) .build()); } static C2R InputDelaySetter( Loading Loading @@ -464,9 +477,69 @@ class C2SoftHevcEnc::IntfImpl : public SimpleInterface<void>::BaseParams { me.set().matrix = coded.v.matrix; return C2R::Ok(); } static C2R PictureQuantizationSetter(bool mayBlock, C2P<C2StreamPictureQuantizationTuning::output> &me) { (void)mayBlock; // these are the ones we're going to set, so want them to default // to the DEFAULT values for the codec int32_t iMin = HEVC_QP_MIN, pMin = HEVC_QP_MIN, bMin = HEVC_QP_MIN; int32_t iMax = HEVC_QP_MAX, pMax = HEVC_QP_MAX, bMax = HEVC_QP_MAX; for (size_t i = 0; i < me.v.flexCount(); ++i) { const C2PictureQuantizationStruct &layer = me.v.m.values[i]; // layerMin is clamped to [HEVC_QP_MIN, layerMax] to avoid error // cases where layer.min > layer.max int32_t layerMax = std::clamp(layer.max, HEVC_QP_MIN, HEVC_QP_MAX); int32_t layerMin = std::clamp(layer.min, HEVC_QP_MIN, layerMax); if (layer.type_ == C2Config::picture_type_t(I_FRAME)) { iMax = layerMax; iMin = layerMin; ALOGV("iMin %d iMax %d", iMin, iMax); } else if (layer.type_ == C2Config::picture_type_t(P_FRAME)) { pMax = layerMax; pMin = layerMin; ALOGV("pMin %d pMax %d", pMin, pMax); } else if (layer.type_ == C2Config::picture_type_t(B_FRAME)) { bMax = layerMax; bMin = layerMin; 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); int32_t maxFrameQP = std::min(std::min(iMax, pMax), bMax); int32_t minFrameQP = std::max(std::max(iMin, pMin), bMin); if (minFrameQP > maxFrameQP) { minFrameQP = maxFrameQP; } // 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) || layer.type_ == C2Config::picture_type_t(P_FRAME) || layer.type_ == C2Config::picture_type_t(B_FRAME)) { me.set().m.values[i].max = maxFrameQP; me.set().m.values[i].min = minFrameQP; } } ALOGV("PictureQuantizationSetter(exit): i = p = b = %d-%d", minFrameQP, maxFrameQP); return C2R::Ok(); } std::shared_ptr<C2StreamColorAspectsInfo::output> getCodedColorAspects_l() { return mCodedColorAspects; } std::shared_ptr<C2StreamPictureQuantizationTuning::output> getPictureQuantization_l() const { return mPictureQuantization; } private: std::shared_ptr<C2StreamUsageTuning::input> mUsage; Loading @@ -482,6 +555,7 @@ class C2SoftHevcEnc::IntfImpl : public SimpleInterface<void>::BaseParams { std::shared_ptr<C2StreamGopTuning::output> mGop; std::shared_ptr<C2StreamColorAspectsInfo::input> mColorAspects; std::shared_ptr<C2StreamColorAspectsInfo::output> mCodedColorAspects; std::shared_ptr<C2StreamPictureQuantizationTuning::output> mPictureQuantization; }; static size_t GetCPUCoreCount() { Loading Loading @@ -654,12 +728,41 @@ c2_status_t C2SoftHevcEnc::initEncParams() { mEncParams.s_coding_tools_prms.i4_max_temporal_layers = 3; } // we resolved out-of-bound and unspecified values in PictureQuantizationSetter() // so we can start with defaults that are overridden as needed. int32_t maxFrameQP = mEncParams.s_config_prms.i4_max_frame_qp; int32_t minFrameQP = mEncParams.s_config_prms.i4_min_frame_qp; for (size_t i = 0; i < mQpBounds->flexCount(); ++i) { const C2PictureQuantizationStruct &layer = mQpBounds->m.values[i]; // no need to loop, hevc library takes same range for I/P/B picture type if (layer.type_ == C2Config::picture_type_t(I_FRAME) || layer.type_ == C2Config::picture_type_t(P_FRAME) || layer.type_ == C2Config::picture_type_t(B_FRAME)) { maxFrameQP = layer.max; minFrameQP = layer.min; break; } } mEncParams.s_config_prms.i4_max_frame_qp = maxFrameQP; mEncParams.s_config_prms.i4_min_frame_qp = minFrameQP; ALOGV("MaxFrameQp: %d MinFrameQp: %d", maxFrameQP, minFrameQP); mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_frame_qp[0] = std::clamp(kDefaultInitQP, minFrameQP, maxFrameQP); switch (mBitrateMode->value) { case C2Config::BITRATE_IGNORE: case C2Config::BITRATE_IGNORE: { mEncParams.s_config_prms.i4_rate_control_mode = 3; // ensure initial qp values are within our newly configured bounds int32_t frameQp = getQpFromQuality(mQuality->value); mEncParams.s_tgt_lyr_prms.as_tgt_params[0].ai4_frame_qp[0] = getQpFromQuality(mQuality->value); std::clamp(frameQp, minFrameQP, maxFrameQP); break; } case C2Config::BITRATE_CONST: mEncParams.s_config_prms.i4_rate_control_mode = 5; break; Loading Loading @@ -723,6 +826,7 @@ c2_status_t C2SoftHevcEnc::initEncoder() { mGop = mIntf->getGop_l(); mRequestSync = mIntf->getRequestSync_l(); mColorAspects = mIntf->getCodedColorAspects_l(); mQpBounds = mIntf->getPictureQuantization_l();; } c2_status_t status = initEncParams(); Loading
media/codec2/components/hevc/C2SoftHevcEnc.h +6 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,11 @@ namespace android { #define DEFAULT_B_FRAMES 0 #define DEFAULT_RC_LOOKAHEAD 0 #define HEVC_QP_MIN 1 #define HEVC_QP_MAX 51 constexpr int32_t kDefaultInitQP = 32; struct C2SoftHevcEnc : public SimpleC2Component { class IntfImpl; Loading Loading @@ -90,6 +95,7 @@ struct C2SoftHevcEnc : public SimpleC2Component { std::shared_ptr<C2StreamGopTuning::output> mGop; std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync; std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects; std::shared_ptr<C2StreamPictureQuantizationTuning::output> mQpBounds; #ifdef FILE_DUMP_ENABLE char mInFile[200]; char mOutFile[200]; Loading