Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82df815a authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "C2SoftAomEnc: Add support for configuring min max QP Params" into main

parents e8cd125e e355f2e2
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
@@ -29,6 +29,12 @@

#include "C2SoftAomEnc.h"

/* Quantization param values defined by the spec */
#define AOM_QP_MIN 0
#define AOM_QP_MAX 63
#define AOM_QP_DEFAULT_MIN AOM_QP_MIN
#define AOM_QP_DEFAULT_MAX AOM_QP_MAX

namespace android {

constexpr char COMPONENT_NAME[] = "c2.android.av1.encoder";
@@ -175,6 +181,19 @@ C2SoftAomEnc::IntfImpl::IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helpe
                                     .inRange(C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER)})
                    .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::I_FRAME, C2Config::P_FRAME}),
                         C2F(mPictureQuantization, m.values[0].min).inRange(
                            AOM_QP_DEFAULT_MIN, AOM_QP_DEFAULT_MAX),
                         C2F(mPictureQuantization, m.values[0].max).inRange(
                            AOM_QP_DEFAULT_MIN, AOM_QP_DEFAULT_MAX)})
            .withSetter(PictureQuantizationSetter)
            .build());
}

C2R C2SoftAomEnc::IntfImpl::BitrateSetter(bool mayBlock, C2P<C2StreamBitrateInfo::output>& me) {
@@ -307,6 +326,54 @@ C2R C2SoftAomEnc::IntfImpl::CodedColorAspectsSetter(
    return C2R::Ok();
}

C2R C2SoftAomEnc::IntfImpl::PictureQuantizationSetter(
        bool mayBlock, C2P<C2StreamPictureQuantizationTuning::output>& me) {
    (void)mayBlock;
    int32_t iMin = AOM_QP_DEFAULT_MIN, pMin = AOM_QP_DEFAULT_MIN;
    int32_t iMax = AOM_QP_DEFAULT_MAX, pMax = AOM_QP_DEFAULT_MAX;
    for (size_t i = 0; i < me.v.flexCount(); ++i) {
        const C2PictureQuantizationStruct &layer = me.v.m.values[i];
        // layerMin is clamped to [AOM_QP_MIN, layerMax] to avoid error
        // cases where layer.min > layer.max
        int32_t layerMax = std::clamp(layer.max, AOM_QP_MIN, AOM_QP_MAX);
        int32_t layerMin = std::clamp(layer.min, AOM_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);
        }
    }
    ALOGV("PictureQuantizationSetter(entry): i %d-%d p %d-%d",
          iMin, iMax, pMin, pMax);

    // aom library takes same range for I/P picture type
    int32_t maxFrameQP = std::min(iMax, pMax);
    int32_t minFrameQP = std::max(iMin, pMin);
    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)) {
            me.set().m.values[i].max = maxFrameQP;
            me.set().m.values[i].min = minFrameQP;
        }
        else if (layer.type_ == C2Config::picture_type_t(P_FRAME)) {
            me.set().m.values[i].max = maxFrameQP;
            me.set().m.values[i].min = minFrameQP;
        }
    }
    ALOGV("PictureQuantizationSetter(exit): minFrameQP = %d maxFrameQP = %d",
          minFrameQP, maxFrameQP);
    return C2R::Ok();
}

uint32_t C2SoftAomEnc::IntfImpl::getLevel_l() const {
        return mProfileLevel->level - LEVEL_AV1_2;
}
@@ -558,6 +625,7 @@ status_t C2SoftAomEnc::initEncoder() {
        mQuality = mIntf->getQuality_l();
        mComplexity = mIntf->getComplexity_l();
        mAV1EncLevel = mIntf->getLevel_l();
        mQpBounds = mIntf->getPictureQuantization_l();
    }


@@ -575,6 +643,18 @@ status_t C2SoftAomEnc::initEncoder() {
            break;
    }

    if (mQpBounds->flexCount() > 0) {
        // read min max qp for sequence
        for (size_t i = 0; i < mQpBounds->flexCount(); ++i) {
            const C2PictureQuantizationStruct &layer = mQpBounds->m.values[i];
            if (layer.type_ == C2Config::picture_type_t(I_FRAME)) {
                mMaxQuantizer = layer.max;
                mMinQuantizer = layer.min;
                break;
            }
        }
    }

    mCodecInterface = aom_codec_av1_cx();
    if (!mCodecInterface) goto CleanUp;

+7 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ struct C2SoftAomEnc : public SimpleC2Component {
    std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
    std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
    std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
    std::shared_ptr<C2StreamPictureQuantizationTuning::output> mQpBounds;

    aom_codec_err_t setupCodecParameters();
};
@@ -126,6 +127,8 @@ class C2SoftAomEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
                                  const C2P<C2StreamPictureSizeInfo::input>& size,
                                  const C2P<C2StreamFrameRateInfo::output>& frameRate,
                                  const C2P<C2StreamBitrateInfo::output>& bitrate);
    static C2R PictureQuantizationSetter(bool mayBlock,
                                         C2P<C2StreamPictureQuantizationTuning::output> &me);

    // unsafe getters
    std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
@@ -150,6 +153,9 @@ class C2SoftAomEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
    std::shared_ptr<C2StreamPixelFormatInfo::input> getPixelFormat_l() const {
        return mPixelFormat;
    }
    std::shared_ptr<C2StreamPictureQuantizationTuning::output> getPictureQuantization_l() const {
        return mPictureQuantization;
    }
    uint32_t getSyncFramePeriod() const;
    static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input>& me);
    static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output>& me,
@@ -171,6 +177,7 @@ class C2SoftAomEnc::IntfImpl : public SimpleInterface<void>::BaseParams {
    std::shared_ptr<C2StreamColorAspectsInfo::input> mColorAspects;
    std::shared_ptr<C2StreamColorAspectsInfo::output> mCodedColorAspects;
    std::shared_ptr<C2StreamPixelFormatInfo::input> mPixelFormat;
    std::shared_ptr<C2StreamPictureQuantizationTuning::output> mPictureQuantization;

};

+4 −7
Original line number Diff line number Diff line
@@ -354,12 +354,9 @@ uint32_t C2SoftVpxEnc::IntfImpl::getSyncFramePeriod() const {
    return (uint32_t)c2_max(c2_min(period + 0.5, double(UINT32_MAX)), 1.);
}

C2R C2SoftVpxEnc::IntfImpl::PictureQuantizationSetter(bool mayBlock,
                                                     C2P<C2StreamPictureQuantizationTuning::output>
                                                     &me) {
C2R C2SoftVpxEnc::IntfImpl::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 = VPX_QP_DEFAULT_MIN, pMin = VPX_QP_DEFAULT_MIN;
    int32_t iMax = VPX_QP_DEFAULT_MAX, pMax = VPX_QP_DEFAULT_MAX;
    for (size_t i = 0; i < me.v.flexCount(); ++i) {
@@ -382,8 +379,8 @@ C2R C2SoftVpxEnc::IntfImpl::PictureQuantizationSetter(bool mayBlock,
          iMin, iMax, pMin, pMax);

    // vpx library takes same range for I/P picture type
    int32_t maxFrameQP = std::min({iMax, pMax});
    int32_t minFrameQP = std::max({iMin, pMin});
    int32_t maxFrameQP = std::min(iMax, pMax);
    int32_t minFrameQP = std::max(iMin, pMin);
    if (minFrameQP > maxFrameQP) {
        minFrameQP = maxFrameQP;
    }