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

Commit 9dc24bd9 authored by Dichen Zhang's avatar Dichen Zhang Committed by Automerger Merge Worker
Browse files

Merge "CCodec: support region of interest parameters" into main am: 1a34a50b

parents 5fc88f88 1a34a50b
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
#include <sstream>
#include <thread>

#include <android_media_codec.h>

#include <C2Config.h>
#include <C2Debug.h>
#include <C2ParamInternal.h>
@@ -1411,6 +1413,23 @@ void CCodec::configure(const sp<AMessage> &msg) {
            }
        }

        /*
         * configure mock region of interest if Feature_Roi is enabled
         */
        if (android::media::codec::provider_->region_of_interest()
            && android::media::codec::provider_->region_of_interest_support()) {
            if ((config->mDomain & Config::IS_ENCODER) && (config->mDomain & Config::IS_VIDEO)) {
                int32_t enableRoi;
                if (msg->findInt32("feature-region-of-interest", &enableRoi) && enableRoi != 0) {
                    if (!msg->contains(PARAMETER_KEY_QP_OFFSET_MAP) &&
                        !msg->contains(PARAMETER_KEY_QP_OFFSET_RECTS)) {
                        msg->setString(PARAMETER_KEY_QP_OFFSET_RECTS,
                                       AStringPrintf("%d,%d-%d,%d=%d;", 0, 0, 16, 16, 0));
                    }
                }
            }
        }

        std::vector<std::unique_ptr<C2Param>> configUpdate;
        // NOTE: We used to ignore "video-bitrate" at configure; replicate
        //       the behavior here.
+47 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@

#include <initializer_list>

#include <android_media_codec.h>

#include <cutils/properties.h>
#include <log/log.h>
#include <utils/NativeHandle.h>
@@ -591,6 +593,13 @@ void CCodecConfig::initializeStandardParams() {
            }
            return C2Value();
        }));

    if (android::media::codec::provider_->region_of_interest()
        && android::media::codec::provider_->region_of_interest_support()) {
        add(ConfigMapper(C2_PARAMKEY_QP_OFFSET_RECTS, C2_PARAMKEY_QP_OFFSET_RECTS, "")
            .limitTo(D::VIDEO & (D::CONFIG | D::PARAM) & D::ENCODER & D::INPUT));
    }

    deprecated(ConfigMapper(PARAMETER_KEY_REQUEST_SYNC_FRAME,
                     "coding.request-sync", "value")
        .limitTo(D::PARAM & D::ENCODER)
@@ -1121,6 +1130,11 @@ status_t CCodecConfig::initialize(
    mParamUpdater->clear();
    mParamUpdater->supportWholeParam(
            C2_PARAMKEY_TEMPORAL_LAYERING, C2StreamTemporalLayeringTuning::CORE_INDEX);
    if (android::media::codec::provider_->region_of_interest()
        && android::media::codec::provider_->region_of_interest_support()) {
        mParamUpdater->supportWholeParam(
                C2_PARAMKEY_QP_OFFSET_RECTS, C2StreamQpOffsetRects::CORE_INDEX);
    }
    mParamUpdater->addParamDesc(mReflector, mParamDescs);

    // TEMP: add some standard fields even if not reflected
@@ -1871,6 +1885,39 @@ ReflectedParamUpdater::Dict CCodecConfig::getReflectedFormat(
        }
    }

    if (android::media::codec::provider_->region_of_interest()
        && android::media::codec::provider_->region_of_interest_support()) {
        if (mDomain == (IS_VIDEO | IS_ENCODER)) {
            AString qpOffsetRects;
            if (params->findString(PARAMETER_KEY_QP_OFFSET_RECTS, &qpOffsetRects)) {
                std::vector<C2QpOffsetRectStruct> c2QpOffsetRects;
                char mutableStrQpOffsetRects[strlen(qpOffsetRects.c_str()) + 1];
                strcpy(mutableStrQpOffsetRects, qpOffsetRects.c_str());
                char* box = strtok(mutableStrQpOffsetRects, ";");
                while (box != nullptr) {
                    int top, left, bottom, right, offset;
                    if (sscanf(box, "%d,%d-%d,%d=%d", &top, &left, &bottom, &right, &offset) == 5) {
                        left = c2_max(0, left);
                        top = c2_max(0, top);
                        if (right > left && bottom > top) {
                            C2Rect rect(right - left, bottom - top);
                            rect.at(left, top);
                            c2QpOffsetRects.push_back(C2QpOffsetRectStruct(rect, offset));
                        }
                    }
                    box = strtok(nullptr, ";");
                }
                if (c2QpOffsetRects.size() != 0) {
                    const std::unique_ptr<C2StreamQpOffsetRects::output> regions =
                            C2StreamQpOffsetRects::output::AllocUnique(
                                    c2QpOffsetRects.size(), 0u, c2QpOffsetRects);
                    params->setBuffer(C2_PARAMKEY_QP_OFFSET_RECTS,
                                      ABuffer::CreateAsCopy(regions.get(), regions->size()));
                }
            }
        }
    }

    // this is to verify that we set proper signedness for standard parameters
    bool beVeryStrict = property_get_bool("debug.stagefright.ccodec_strict_type", false);
    // this is to allow vendors to use the wrong signedness for standard parameters
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ cc_test {
    ],

    static_libs: [
        "android.media.codec-aconfig-cc",
        "libcodec2_hidl@1.0",
        "libstagefright_bufferpool@2.0",
    ],
+71 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@

#include <gtest/gtest.h>

#include <android_media_codec.h>

#include <codec2/hidl/1.0/Configurable.h>
#include <codec2/hidl/client.h>
#include <util/C2InterfaceHelper.h>
@@ -235,6 +237,22 @@ public:
                            })
                            .withSetter(Setter<C2StreamProfileLevelInfo::output>)
                            .build());

                    std::vector<C2QpOffsetRectStruct> c2QpOffsetRectsInfo;
                    addParameter(
                            DefineParam(mInputQpOffsetRects, C2_PARAMKEY_QP_OFFSET_RECTS)
                                    .withDefault(C2StreamQpOffsetRects::output::AllocShared(
                                            c2QpOffsetRectsInfo.size(), 0, c2QpOffsetRectsInfo))
                                    .withFields({
                                            C2F(mInputQpOffsetRects, m.values[0].qpOffset)
                                                    .inRange(-128, 127),
                                            C2F(mInputQpOffsetRects, m.values[0].left).any(),
                                            C2F(mInputQpOffsetRects, m.values[0].top).any(),
                                            C2F(mInputQpOffsetRects, m.values[0].width).any(),
                                            C2F(mInputQpOffsetRects, m.values[0].height).any(),
                                    })
                                    .withSetter(Setter<C2StreamQpOffsetRects::output>)
                                    .build());
                }

                // TODO: more SDK params
@@ -254,6 +272,7 @@ public:
            std::shared_ptr<C2StreamBitrateInfo::output> mOutputBitrate;
            std::shared_ptr<C2StreamProfileLevelInfo::input> mInputProfileLevel;
            std::shared_ptr<C2StreamProfileLevelInfo::output> mOutputProfileLevel;
            std::shared_ptr<C2StreamQpOffsetRects::output> mInputQpOffsetRects;

            template<typename T>
            static C2R Setter(bool, C2P<T> &) {
@@ -636,4 +655,56 @@ INSTANTIATE_TEST_SUITE_P(
        HdrProfilesTest,
        ::testing::ValuesIn(kHdrProfilesParams));

TEST_F(CCodecConfigTest, SetRegionOfInterestParams) {
    if (!android::media::codec::provider_->region_of_interest()
        || !android::media::codec::provider_->region_of_interest_support()) {
        GTEST_SKIP() << "Skipping the test as region_of_interest flags are not enabled.\n";
    }

    init(C2Component::DOMAIN_VIDEO, C2Component::KIND_ENCODER, MIMETYPE_VIDEO_VP9);

    ASSERT_EQ(OK, mConfig.initialize(mReflector, mConfigurable));

    const int kWidth = 32;
    const int kHeight = 32;
    const int kNumBlocks = ((kWidth + 15) / 16) * ((kHeight + 15) / 16);
    int8_t mapInfo[kNumBlocks] = {-1, 0, 1, 1};
    int top[kNumBlocks] = {0, 0, 16, 16};
    int left[kNumBlocks] = {0, 16, 0, 16};
    int bottom[kNumBlocks] = {16, 16, 32, 32};
    int right[kNumBlocks] = {16, 32, 16, 32};
    sp<AMessage> format{new AMessage};
    format->setInt32(KEY_WIDTH, kWidth);
    format->setInt32(KEY_HEIGHT, kHeight);
    AString val;
    for (int i = 0; i < kNumBlocks; i++) {
        val.append(AStringPrintf("%d,%d-%d,%d=%d;", top[i], left[i], bottom[i],
                                 right[i], mapInfo[i]));
    }
    format->setString(PARAMETER_KEY_QP_OFFSET_RECTS, val);

    std::vector<std::unique_ptr<C2Param>> configUpdate;
    ASSERT_EQ(OK, mConfig.getConfigUpdateFromSdkParams(mConfigurable, format, D::CONFIG,
                                                       C2_MAY_BLOCK, &configUpdate));

    EXPECT_EQ(1u, configUpdate.size());

    C2StreamQpOffsetRects::output* qpRectParam =
            FindParam<std::remove_pointer<decltype(qpRectParam)>::type>(configUpdate);
    ASSERT_NE(nullptr, qpRectParam);
    ASSERT_EQ(kNumBlocks, qpRectParam->flexCount());
    for (auto i = 0; i < kNumBlocks; i++) {
        EXPECT_EQ(mapInfo[i], (int8_t)qpRectParam->m.values[i].qpOffset)
                << "qp offset for index " << i << " is not as expected ";
        EXPECT_EQ(left[i], qpRectParam->m.values[i].left)
                << "left for index " << i << " is not as expected ";
        EXPECT_EQ(top[i], qpRectParam->m.values[i].top)
                << "top for index " << i << " is not as expected ";
        EXPECT_EQ(right[i] - left[i], qpRectParam->m.values[i].width)
                << "width for index " << i << " is not as expected ";
        EXPECT_EQ(bottom[i] - top[i], qpRectParam->m.values[i].height)
                << "height for index " << i << " is not as expected ";
    }
}

} // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -893,6 +893,8 @@ inline constexpr char PARAMETER_KEY_SUSPEND[] = "drop-input-frames";
inline constexpr char PARAMETER_KEY_SUSPEND_TIME[] = "drop-start-time-us";
inline constexpr char PARAMETER_KEY_TUNNEL_PEEK[] =  "tunnel-peek";
inline constexpr char PARAMETER_KEY_VIDEO_BITRATE[] = "video-bitrate";
inline constexpr char PARAMETER_KEY_QP_OFFSET_MAP[] = "qp-offset-map";
inline constexpr char PARAMETER_KEY_QP_OFFSET_RECTS[] = "qp-offset-rects";

}