Loading media/codec2/sfplugin/CCodec.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <sstream> #include <thread> #include <android_media_codec.h> #include <C2Config.h> #include <C2Debug.h> #include <C2ParamInternal.h> Loading Loading @@ -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. Loading media/codec2/sfplugin/CCodecConfig.cpp +47 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <initializer_list> #include <android_media_codec.h> #include <cutils/properties.h> #include <log/log.h> #include <utils/NativeHandle.h> Loading Loading @@ -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) Loading Loading @@ -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 Loading Loading @@ -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 Loading media/codec2/sfplugin/tests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ cc_test { ], static_libs: [ "android.media.codec-aconfig-cc", "libcodec2_hidl@1.0", "libstagefright_bufferpool@2.0", ], Loading media/codec2/sfplugin/tests/CCodecConfig_test.cpp +71 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 Loading @@ -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> &) { Loading Loading @@ -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 media/libstagefright/include/media/stagefright/MediaCodecConstants.h +2 −0 Original line number Diff line number Diff line Loading @@ -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"; } Loading Loading
media/codec2/sfplugin/CCodec.cpp +19 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <sstream> #include <thread> #include <android_media_codec.h> #include <C2Config.h> #include <C2Debug.h> #include <C2ParamInternal.h> Loading Loading @@ -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. Loading
media/codec2/sfplugin/CCodecConfig.cpp +47 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <initializer_list> #include <android_media_codec.h> #include <cutils/properties.h> #include <log/log.h> #include <utils/NativeHandle.h> Loading Loading @@ -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) Loading Loading @@ -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 Loading Loading @@ -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 Loading
media/codec2/sfplugin/tests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ cc_test { ], static_libs: [ "android.media.codec-aconfig-cc", "libcodec2_hidl@1.0", "libstagefright_bufferpool@2.0", ], Loading
media/codec2/sfplugin/tests/CCodecConfig_test.cpp +71 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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 Loading @@ -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> &) { Loading Loading @@ -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
media/libstagefright/include/media/stagefright/MediaCodecConstants.h +2 −0 Original line number Diff line number Diff line Loading @@ -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"; } Loading