Merge "aidl PersistentSurface: remove unnecessary definitions" into main
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index d14068d..463b63f 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -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 @@
             }
         }
 
+        /*
+         * 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, height, width, 0));
+                    }
+                }
+            }
+        }
+
         std::vector<std::unique_ptr<C2Param>> configUpdate;
         // NOTE: We used to ignore "video-bitrate" at configure; replicate
         //       the behavior here.
@@ -2534,6 +2553,40 @@
         }
     }
 
+    /**
+     * Handle ROI QP map configuration. Recover the QP map configuration from AMessage as an
+     * ABuffer and configure to CCodecBufferChannel as a C2InfoBuffer
+     */
+    if (android::media::codec::provider_->region_of_interest()
+            && android::media::codec::provider_->region_of_interest_support()) {
+        sp<ABuffer> qpOffsetMap;
+        if ((config->mDomain & (Config::IS_VIDEO | Config::IS_IMAGE))
+                && (config->mDomain & Config::IS_ENCODER)
+                &&  params->findBuffer(PARAMETER_KEY_QP_OFFSET_MAP, &qpOffsetMap)) {
+            std::shared_ptr<C2BlockPool> pool;
+            // TODO(b/331443865) Use pooled block pool to improve efficiency
+            c2_status_t status = GetCodec2BlockPool(C2BlockPool::BASIC_LINEAR, nullptr, &pool);
+
+            if (status == C2_OK) {
+                size_t mapSize = qpOffsetMap->size();
+                std::shared_ptr<C2LinearBlock> block;
+                status = pool->fetchLinearBlock(mapSize,
+                        C2MemoryUsage{C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block);
+                if (status == C2_OK && !block->map().get().error()) {
+                    C2WriteView wView = block->map().get();
+                    uint8_t* outData = wView.data();
+                    memcpy(outData, qpOffsetMap->data(), mapSize);
+                    C2InfoBuffer info = C2InfoBuffer::CreateLinearBuffer(
+                            kParamIndexQpOffsetMapBuffer,
+                            block->share(0, mapSize, C2Fence()));
+                    mChannel->setInfoBuffer(std::make_shared<C2InfoBuffer>(info));
+                }
+            }
+            params->removeEntryByName(PARAMETER_KEY_QP_OFFSET_MAP);
+        }
+    }
+
+
     std::vector<std::unique_ptr<C2Param>> configUpdate;
     (void)config->getConfigUpdateFromSdkParams(
             comp, params, Config::IS_PARAM, C2_MAY_BLOCK, &configUpdate);
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index f58dc65..3984b83 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -28,6 +28,8 @@
 #include <thread>
 #include <chrono>
 
+#include <android_media_codec.h>
+
 #include <C2AllocatorGralloc.h>
 #include <C2PlatformSupport.h>
 #include <C2BlockInternal.h>
@@ -370,7 +372,17 @@
         }
     } else {
         work->input.flags = (C2FrameData::flags_t)flags;
+
         // TODO: fill info's
+        if (android::media::codec::provider_->region_of_interest()
+                && android::media::codec::provider_->region_of_interest_support()) {
+            if (mInfoBuffers.size()) {
+                for (auto infoBuffer : mInfoBuffers) {
+                    work->input.infoBuffers.emplace_back(*infoBuffer);
+                }
+                mInfoBuffers.clear();
+            }
+        }
 
         work->input.configUpdate = std::move(mParamsToBeSet);
         if (tunnelFirstFrame) {
@@ -2058,6 +2070,7 @@
 void CCodecBufferChannel::stop() {
     mSync.stop();
     mFirstValidFrameIndex = mFrameIndex.load(std::memory_order_relaxed);
+    mInfoBuffers.clear();
 }
 
 void CCodecBufferChannel::stopUseOutputSurface(bool pushBlankBuffer) {
@@ -2099,6 +2112,7 @@
 }
 
 void CCodecBufferChannel::release() {
+    mInfoBuffers.clear();
     mComponent.reset();
     mInputAllocator.reset();
     mOutputSurface.lock()->surface.clear();
@@ -2164,6 +2178,7 @@
             output->buffers->flushStash();
         }
     }
+    mInfoBuffers.clear();
 }
 
 void CCodecBufferChannel::onWorkDone(
@@ -2768,6 +2783,10 @@
     }
 }
 
+void CCodecBufferChannel::setInfoBuffer(const std::shared_ptr<C2InfoBuffer> &buffer) {
+    mInfoBuffers.push_back(buffer);
+}
+
 status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) {
     // C2_OK is always translated to OK.
     if (c2s == C2_OK) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index b470655..94a5998 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -227,6 +227,14 @@
 
     void resetBuffersPixelFormat(bool isEncoder);
 
+    /**
+     * Queue a C2 info buffer that will be sent to codec in the subsequent
+     * queueInputBuffer
+     *
+     * @param buffer C2 info buffer
+     */
+    void setInfoBuffer(const std::shared_ptr<C2InfoBuffer> &buffer);
+
 private:
     uint32_t getInputBuffersPixelFormat();
 
@@ -400,6 +408,8 @@
     std::atomic_bool mSendEncryptedInfoBuffer;
 
     std::atomic_bool mTunneled;
+
+    std::vector<std::shared_ptr<C2InfoBuffer>> mInfoBuffers;
 };
 
 // Conversion of a c2_status_t value to a status_t value may depend on the
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index c22deca..db59227 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -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 @@
             }
             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 @@
     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 @@
         }
     }
 
+    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
diff --git a/media/codec2/sfplugin/tests/Android.bp b/media/codec2/sfplugin/tests/Android.bp
index 246e563..2739f44 100644
--- a/media/codec2/sfplugin/tests/Android.bp
+++ b/media/codec2/sfplugin/tests/Android.bp
@@ -42,6 +42,7 @@
     ],
 
     static_libs: [
+        "android.media.codec-aconfig-cc",
         "libcodec2_hidl@1.0",
         "libstagefright_bufferpool@2.0",
     ],
diff --git a/media/codec2/sfplugin/tests/CCodecConfig_test.cpp b/media/codec2/sfplugin/tests/CCodecConfig_test.cpp
index 3615289..508bec2 100644
--- a/media/codec2/sfplugin/tests/CCodecConfig_test.cpp
+++ b/media/codec2/sfplugin/tests/CCodecConfig_test.cpp
@@ -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 @@
                             })
                             .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 @@
             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 @@
         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
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index 24ac2e8..72785d5 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -893,6 +893,8 @@
 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";
 
 }
 
diff --git a/media/libstagefright/renderfright/fuzzer/Android.bp b/media/libstagefright/renderfright/fuzzer/Android.bp
new file mode 100644
index 0000000..574e49f
--- /dev/null
+++ b/media/libstagefright/renderfright/fuzzer/Android.bp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_team: "trendy_team_android_media_codec_framework",
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_av_media_libstagefright_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_av_media_libstagefright_license"],
+}
+
+cc_fuzz {
+    name: "libstagefright_renderfright_fuzzer",
+    srcs: [
+        "libstagefright_renderfright_fuzzer.cpp",
+    ],
+    static_libs: [
+        "librenderfright",
+    ],
+    header_libs: [
+        "librenderfright_gl_headers",
+    ],
+    shared_libs: [
+        "libcutils",
+        "libgui",
+        "liblog",
+        "libutils",
+        "libEGL",
+        "libGLESv1_CM",
+        "libGLESv2",
+        "libGLESv3",
+        "libui",
+        "libbase",
+        "libprocessgroup",
+        "libsync",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+        hotlists: ["4593311"],
+        description: "The fuzzer targets the APIs of librenderfright",
+        vector: "local_no_privileges_required",
+        service_privilege: "constrained",
+        users: "multi_user",
+        fuzzed_code_usage: "shipped",
+    },
+}
diff --git a/media/libstagefright/renderfright/fuzzer/README.md b/media/libstagefright/renderfright/fuzzer/README.md
new file mode 100644
index 0000000..742bfdc
--- /dev/null
+++ b/media/libstagefright/renderfright/fuzzer/README.md
@@ -0,0 +1,33 @@
+# Fuzzer for libstagefright_renderfright
+
+RenderFright supports the following parameters:
+1. SetContextPriority (parameter name: "kSetContextPriority")
+2. SetRenderEngineType (parameter name: "kSetRenderEngineType")
+3. CleanupMode (parameter name: "kCleanupMode")
+4. DataSpace (parameter name: "kDataSpace")
+5. ReadBufferUsage(parameter name: "kReadBufferUsage")
+6. WriteBufferUsage(parameter name: "kWriteBufferUsage")
+7. RenderBufferUsage(parameter name: "kRenderBufferUsage")
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`kSetContextPriority`| 0. `RenderEngine::ContextPriority::LOW`<br/>1. `RenderEngine::ContextPriority::MEDIUM`<br/>2. `RenderEngine::ContextPriority::HIGH` |Value obtained from FuzzedDataProvider|
+|`kSetRenderEngineType`| 0. `RenderEngine::RenderEngineType::GLES`<br/>1. `RenderEngine::RenderEngineType::THREADED`|Value obtained from FuzzedDataProvider|
+|`kCleanupMode`| 0. `RenderEngine::CleanupMode::CLEAN_OUTPUT_RESOURCES`<br/>1. `RenderEngine::CleanupMode::CLEAN_ALL`|Value obtained from FuzzedDataProvider|
+|`kDataSpace`| 0. `ui::Dataspace::UNKNOWN`<br/>1. `ui::Dataspace::ARBITRARY`<br/>2. `ui::Dataspace::STANDARD_SHIFT`<br/>3. `ui::Dataspace::STANDARD_MASK`<br/>4. `ui::Dataspace::STANDARD_UNSPECIFIED`<br/>5. `ui::Dataspace::STANDARD_BT709`<br/>6. `ui::Dataspace::STANDARD_BT601_625`<br/>7. `ui::Dataspace::STANDARD_BT601_625_UNADJUSTED`<br/>8. `ui::Dataspace::STANDARD_BT601_525`<br/>9. `ui::Dataspace::STANDARD_BT601_525_UNADJUSTED`<br/>10. `ui::Dataspace::STANDARD_BT2020`<br/>11. `ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE`<br/>12. `ui::Dataspace::STANDARD_BT470M`<br/>13. `ui::Dataspace::STANDARD_FILM`<br/>14. `ui::Dataspace::STANDARD_DCI_P3`<br/>15. `ui::Dataspace::STANDARD_ADOBE_RGB`<br/>16. `ui::Dataspace::TRANSFER_SHIFT`<br/>17. `ui::Dataspace::TRANSFER_MASK`<br/>18. `ui::Dataspace::TRANSFER_UNSPECIFIED`<br/>19. `ui::Dataspace::TRANSFER_LINEAR`<br/>20. `ui::Dataspace::TRANSFER_SRGB`<br/>21. `ui::Dataspace::TRANSFER_SMPTE_170M`<br/>22. `ui::Dataspace::TRANSFER_GAMMA2_2`<br/>23. `ui::Dataspace::TRANSFER_GAMMA2_6`<br/>24. `ui::Dataspace::TRANSFER_GAMMA2_8`<br/>25. `ui::Dataspace::TRANSFER_ST2084`<br/>26. `ui::Dataspace::TRANSFER_HLG`<br/>27. `ui::Dataspace::RANGE_SHIFT`<br/>28. `ui::Dataspace::RANGE_MASK`<br/>29. `ui::Dataspace::RANGE_UNSPECIFIED`<br/>30. `ui::Dataspace::RANGE_FULL`<br/>31. `ui::Dataspace::RANGE_LIMITED`<br/>32. `ui::Dataspace::RANGE_EXTENDED`<br/>33. `ui::Dataspace::SRGB_LINEAR`<br/>34. `ui::Dataspace::V0_SRGB_LINEAR`<br/>35. `ui::Dataspace::V0_SCRGB_LINEAR`<br/>36. `ui::Dataspace::SRGB`<br/>37. `ui::Dataspace::V0_SRGB`<br/>38. `ui::Dataspace::V0_SCRGB`<br/>39. `ui::Dataspace::JFIF`<br/>40. `ui::Dataspace::V0_JFIF`<br/>41. `ui::Dataspace::BT601_625`<br/>42. `ui::Dataspace::V0_BT601_625`<br/>43. `ui::Dataspace::BT601_525`<br/>44. `ui::Dataspace::V0_BT601_525`<br/>45. `ui::Dataspace::BT709`<br/>46. `ui::Dataspace::V0_BT709`<br/>47. `ui::Dataspace::DCI_P3_LINEAR`<br/>48. `ui::Dataspace::DCI_P3`<br/>49. `ui::Dataspace::DISPLAY_P3_LINEAR`<br/>50. `ui::Dataspace::DISPLAY_P3`<br/>51. `ui::Dataspace::ADOBE_RGB`<br/>52. `ui::Dataspace::BT2020_LINEAR`<br/>53. `ui::Dataspace::BT2020`<br/>54. `ui::Dataspace::BT2020_PQ`<br/>55. `ui::Dataspace::DEPTH`<br/>56. `ui::Dataspace::SENSOR`<br/>57. `ui::Dataspace::BT2020_ITU`<br/>58. `ui::Dataspace::BT2020_ITU_PQ`<br/>59. `ui::Dataspace::BT2020_ITU_HLG`<br/>60. `ui::Dataspace::BT2020_HLG`<br/>61. `ui::Dataspace::DISPLAY_BT2020`<br/>62. `ui::Dataspace::DYNAMIC_DEPTH`<br/>63. `ui::Dataspace::JPEG_APP_SEGMENTS`<br/>64. `ui::Dataspace::HEIF`|Value obtained from FuzzedDataProvider|
+|`kReadBufferUsage`| 0. `GRALLOC_USAGE_SW_READ_NEVER`<br/>1. `GRALLOC_USAGE_SW_READ_RARELY`<br/>2. `GRALLOC_USAGE_SW_READ_OFTEN`<br/>3. `GRALLOC_USAGE_SW_READ_MASK`|Value obtained from FuzzedDataProvider|
+|`kWriteBufferUsage`| 0. `GRALLOC_USAGE_SW_WRITE_NEVER`<br/>1. `GRALLOC_USAGE_SW_WRITE_RARELY`<br/>2. `GRALLOC_USAGE_SW_WRITE_OFTEN`<br/>3. `GRALLOC_USAGE_SW_WRITE_MASK`|Value obtained from FuzzedDataProvider|
+|`kRenderBufferUsage`| 0. `GRALLOC_USAGE_HW_TEXTURE`<br/>1. `GRALLOC_USAGE_HW_RENDER`<br/>2. `GRALLOC_USAGE_HW_2D`<br/>3. `GRALLOC_USAGE_HW_COMPOSER`<br/>4. `GRALLOC_USAGE_HW_FB`<br/>5. `GRALLOC_USAGE_EXTERNAL_DISP`<br/>6. `GRALLOC_USAGE_PROTECTED`<br/>7. `GRALLOC_USAGE_CURSOR`<br/>8. `GRALLOC_USAGE_HW_VIDEO_ENCODER`<br/>9. `GRALLOC_USAGE_HW_CAMERA_WRITE`<br/>10. `GRALLOC_USAGE_HW_CAMERA_READ`<br/>11. `GRALLOC_USAGE_HW_CAMERA_ZSL`<br/>12. `GRALLOC_USAGE_HW_CAMERA_MASK`<br/>13. `GRALLOC_USAGE_HW_MASK`<br/>14. `GRALLOC_USAGE_RENDERSCRIPT`<br/>15. `GRALLOC_USAGE_FOREIGN_BUFFERS`<br/>16. `GRALLOC_USAGE_HW_IMAGE_ENCODER`|Value obtained from FuzzedDataProvider|
+
+
+
+#### Steps to run
+1. Build the fuzzer
+```
+  $ mm -j$(nproc) libstagefright_renderfright_fuzzer
+```
+2. Run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/libstagefright_renderfright_fuzzer/libstagefright_renderfright_fuzzer
+```
diff --git a/media/libstagefright/renderfright/fuzzer/libstagefright_renderfright_fuzzer.cpp b/media/libstagefright/renderfright/fuzzer/libstagefright_renderfright_fuzzer.cpp
new file mode 100644
index 0000000..b0721e0
--- /dev/null
+++ b/media/libstagefright/renderfright/fuzzer/libstagefright_renderfright_fuzzer.cpp
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <GLESRenderEngine.h>
+#include <GLFramebuffer.h>
+#include <GLImage.h>
+#include <Program.h>
+#include <ProgramCache.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <renderengine/RenderEngine.h>
+
+using namespace android::renderengine;
+using namespace android;
+
+static constexpr int32_t kMinRenderAPI = 0;
+static constexpr int32_t kMaxRenderAPI = 8;
+static constexpr int32_t kMaxTextureCount = 100;
+static constexpr int32_t KMaxDisplayWidth = 3840;
+static constexpr int32_t KMaxDisplayHeight = 2160;
+static constexpr int32_t kMinPixelFormat = 1;
+static constexpr int32_t kMaxPixelFormat = 55;
+static constexpr int32_t kMaxRenderLayer = 5;
+
+static constexpr ui::Dataspace kDataSpace[] = {
+        ui::Dataspace::UNKNOWN,
+        ui::Dataspace::ARBITRARY,
+        ui::Dataspace::STANDARD_SHIFT,
+        ui::Dataspace::STANDARD_MASK,
+        ui::Dataspace::STANDARD_UNSPECIFIED,
+        ui::Dataspace::STANDARD_BT709,
+        ui::Dataspace::STANDARD_BT601_625,
+        ui::Dataspace::STANDARD_BT601_625_UNADJUSTED,
+        ui::Dataspace::STANDARD_BT601_525,
+        ui::Dataspace::STANDARD_BT601_525_UNADJUSTED,
+        ui::Dataspace::STANDARD_BT2020,
+        ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE,
+        ui::Dataspace::STANDARD_BT470M,
+        ui::Dataspace::STANDARD_FILM,
+        ui::Dataspace::STANDARD_DCI_P3,
+        ui::Dataspace::STANDARD_ADOBE_RGB,
+        ui::Dataspace::TRANSFER_SHIFT,
+        ui::Dataspace::TRANSFER_MASK,
+        ui::Dataspace::TRANSFER_UNSPECIFIED,
+        ui::Dataspace::TRANSFER_LINEAR,
+        ui::Dataspace::TRANSFER_SRGB,
+        ui::Dataspace::TRANSFER_SMPTE_170M,
+        ui::Dataspace::TRANSFER_GAMMA2_2,
+        ui::Dataspace::TRANSFER_GAMMA2_6,
+        ui::Dataspace::TRANSFER_GAMMA2_8,
+        ui::Dataspace::TRANSFER_ST2084,
+        ui::Dataspace::TRANSFER_HLG,
+        ui::Dataspace::RANGE_SHIFT,
+        ui::Dataspace::RANGE_MASK,
+        ui::Dataspace::RANGE_UNSPECIFIED,
+        ui::Dataspace::RANGE_FULL,
+        ui::Dataspace::RANGE_LIMITED,
+        ui::Dataspace::RANGE_EXTENDED,
+        ui::Dataspace::SRGB_LINEAR,
+        ui::Dataspace::V0_SRGB_LINEAR,
+        ui::Dataspace::V0_SCRGB_LINEAR,
+        ui::Dataspace::SRGB,
+        ui::Dataspace::V0_SRGB,
+        ui::Dataspace::V0_SCRGB,
+        ui::Dataspace::JFIF,
+        ui::Dataspace::V0_JFIF,
+        ui::Dataspace::BT601_625,
+        ui::Dataspace::V0_BT601_625,
+        ui::Dataspace::BT601_525,
+        ui::Dataspace::V0_BT601_525,
+        ui::Dataspace::BT709,
+        ui::Dataspace::V0_BT709,
+        ui::Dataspace::DCI_P3_LINEAR,
+        ui::Dataspace::DCI_P3,
+        ui::Dataspace::DISPLAY_P3_LINEAR,
+        ui::Dataspace::DISPLAY_P3,
+        ui::Dataspace::ADOBE_RGB,
+        ui::Dataspace::BT2020_LINEAR,
+        ui::Dataspace::BT2020,
+        ui::Dataspace::BT2020_PQ,
+        ui::Dataspace::DEPTH,
+        ui::Dataspace::SENSOR,
+        ui::Dataspace::BT2020_ITU,
+        ui::Dataspace::BT2020_ITU_PQ,
+        ui::Dataspace::BT2020_ITU_HLG,
+        ui::Dataspace::BT2020_HLG,
+        ui::Dataspace::DISPLAY_BT2020,
+        ui::Dataspace::DYNAMIC_DEPTH,
+        ui::Dataspace::JPEG_APP_SEGMENTS,
+        ui::Dataspace::HEIF,
+};
+
+static constexpr int32_t kReadBufferUsage[] = {
+        GRALLOC_USAGE_SW_READ_NEVER, GRALLOC_USAGE_SW_READ_RARELY, GRALLOC_USAGE_SW_READ_OFTEN,
+        GRALLOC_USAGE_SW_READ_MASK};
+
+static constexpr int32_t kWriteBufferUsage[] = {
+        GRALLOC_USAGE_SW_WRITE_NEVER, GRALLOC_USAGE_SW_WRITE_RARELY, GRALLOC_USAGE_SW_WRITE_OFTEN,
+        GRALLOC_USAGE_SW_WRITE_MASK};
+
+static constexpr int32_t kRenderBufferUsage[] = {
+        GRALLOC_USAGE_HW_TEXTURE,
+        GRALLOC_USAGE_HW_RENDER,
+        GRALLOC_USAGE_HW_2D,
+        GRALLOC_USAGE_HW_COMPOSER,
+        GRALLOC_USAGE_HW_FB,
+        GRALLOC_USAGE_EXTERNAL_DISP,
+        GRALLOC_USAGE_PROTECTED,
+        GRALLOC_USAGE_CURSOR,
+        GRALLOC_USAGE_HW_VIDEO_ENCODER,
+        GRALLOC_USAGE_HW_CAMERA_WRITE,
+        GRALLOC_USAGE_HW_CAMERA_READ,
+        GRALLOC_USAGE_HW_CAMERA_ZSL,
+        GRALLOC_USAGE_HW_CAMERA_MASK,
+        GRALLOC_USAGE_HW_MASK,
+        GRALLOC_USAGE_RENDERSCRIPT,
+        GRALLOC_USAGE_FOREIGN_BUFFERS,
+        GRALLOC_USAGE_HW_IMAGE_ENCODER,
+};
+
+static constexpr RenderEngine::ContextPriority kSetContextPriority[] = {
+        RenderEngine::ContextPriority::LOW, RenderEngine::ContextPriority::MEDIUM,
+        RenderEngine::ContextPriority::HIGH};
+
+static constexpr RenderEngine::RenderEngineType kSetRenderEngineType[] = {
+        RenderEngine::RenderEngineType::GLES, RenderEngine::RenderEngineType::THREADED};
+
+static constexpr RenderEngine::CleanupMode kCleanupMode[] = {
+        RenderEngine::CleanupMode::CLEAN_OUTPUT_RESOURCES, RenderEngine::CleanupMode::CLEAN_ALL};
+
+class RenderFrightFuzzer {
+  public:
+    RenderFrightFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+    void process();
+
+  private:
+    FuzzedDataProvider mFdp;
+    void getLayerSetting(renderengine::LayerSettings& layerSetting, sp<GraphicBuffer> buffer,
+                         const Rect& sourceCrop, uint32_t textureName);
+};
+
+void RenderFrightFuzzer::getLayerSetting(renderengine::LayerSettings& layerSetting,
+                                         sp<GraphicBuffer> buffer, const Rect& sourceCrop,
+                                         uint32_t textureName) {
+    layerSetting.geometry.boundaries = sourceCrop.toFloatRect();
+    layerSetting.geometry.roundedCornersRadius = mFdp.ConsumeFloatingPoint<float>();
+    layerSetting.geometry.roundedCornersCrop = sourceCrop.toFloatRect();
+
+    layerSetting.alpha = mFdp.ConsumeFloatingPoint<float>();
+    layerSetting.sourceDataspace = mFdp.PickValueInArray(kDataSpace);
+    layerSetting.backgroundBlurRadius = mFdp.ConsumeFloatingPoint<float>();
+    layerSetting.source.buffer.buffer = buffer;
+    layerSetting.source.buffer.isOpaque = mFdp.ConsumeBool();
+    layerSetting.source.buffer.fence = Fence::NO_FENCE;
+    layerSetting.source.buffer.textureName = textureName;
+    layerSetting.source.buffer.usePremultipliedAlpha = mFdp.ConsumeBool();
+    layerSetting.source.buffer.isY410BT2020 =
+            (layerSetting.sourceDataspace == ui::Dataspace::BT2020_ITU_PQ ||
+             layerSetting.sourceDataspace == ui::Dataspace::BT2020_ITU_HLG);
+    layerSetting.source.buffer.maxMasteringLuminance = mFdp.ConsumeFloatingPoint<float>();
+    layerSetting.source.buffer.maxContentLuminance = mFdp.ConsumeFloatingPoint<float>();
+
+    layerSetting.shadow.lightPos =
+            vec3(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(), 0);
+    layerSetting.shadow.ambientColor = {
+            mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+            mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>()};
+    layerSetting.shadow.spotColor = {
+            mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+            mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>()};
+    layerSetting.shadow.length = mFdp.ConsumeFloatingPoint<float>();
+    layerSetting.shadow.casterIsTranslucent = mFdp.ConsumeBool();
+}
+
+void RenderFrightFuzzer::process() {
+    auto args = RenderEngineCreationArgs::Builder()
+                        .setPixelFormat(mFdp.ConsumeIntegralInRange<int32_t>(kMinPixelFormat,
+                                                                             kMaxPixelFormat))
+                        .setImageCacheSize(mFdp.ConsumeIntegral<uint32_t>())
+                        .setUseColorManagerment(mFdp.ConsumeBool())
+                        .setEnableProtectedContext(mFdp.ConsumeBool())
+                        .setPrecacheToneMapperShaderOnly(mFdp.ConsumeBool())
+                        .setSupportsBackgroundBlur(mFdp.ConsumeBool())
+                        .setContextPriority(mFdp.PickValueInArray(kSetContextPriority))
+                        .setRenderEngineType(mFdp.PickValueInArray(kSetRenderEngineType))
+                        .build();
+    std::unique_ptr<RenderEngine> renderEngine = RenderEngine::create(args);
+
+    std::vector<uint32_t> textures;
+    int32_t maxCount = mFdp.ConsumeIntegralInRange<size_t>(0, kMaxTextureCount);
+    for (size_t i = 0; i < maxCount; ++i) {
+        textures.push_back(mFdp.ConsumeIntegral<uint32_t>());
+    }
+
+    while (mFdp.remaining_bytes()) {
+        int32_t renderFrightAPIs =
+                mFdp.ConsumeIntegralInRange<int32_t>(kMinRenderAPI, kMaxRenderAPI);
+        switch (renderFrightAPIs) {
+            case 0: {
+                renderEngine->genTextures(textures.size(), textures.data());
+                break;
+            }
+            case 1: {
+                renderEngine->deleteTextures(textures.size(), textures.data());
+                break;
+            }
+            case 2: {
+                renderEngine->useProtectedContext(mFdp.ConsumeBool());
+                break;
+            }
+            case 3: {
+                renderEngine->cleanupPostRender(mFdp.PickValueInArray(kCleanupMode));
+                break;
+            }
+            case 4: {
+                renderEngine->unbindExternalTextureBuffer(mFdp.ConsumeIntegral<uint64_t>());
+                break;
+            }
+            case 5: {
+                renderEngine->primeCache();
+                break;
+            }
+            case 6: {
+                sp<Fence> fence = sp<Fence>::make();
+                sp<GraphicBuffer> buffer = sp<GraphicBuffer>::make();
+                renderEngine->bindExternalTextureBuffer(mFdp.ConsumeIntegral<uint32_t>(), buffer,
+                                                        fence);
+                break;
+            }
+            case 7: {
+                sp<GraphicBuffer> buffer = sp<GraphicBuffer>::make();
+                renderEngine->cacheExternalTextureBuffer(buffer);
+                break;
+            }
+            case 8: {
+                std::vector<const renderengine::LayerSettings*> layers;
+                renderengine::LayerSettings layerSetting;
+                int32_t width = mFdp.ConsumeIntegralInRange<int32_t>(0, KMaxDisplayWidth);
+                int32_t height = mFdp.ConsumeIntegralInRange<int32_t>(0, KMaxDisplayHeight);
+                Rect sourceCrop(mFdp.ConsumeIntegralInRange<int32_t>(0, width),
+                                mFdp.ConsumeIntegralInRange<int32_t>(0, height));
+                uint32_t textureName = 0;
+                /* Get a single texture name to pass to layers */
+                renderEngine->genTextures(1 /*numTextures*/, &textureName);
+                sp<GraphicBuffer> buffer;
+                const uint32_t usage = (mFdp.PickValueInArray(kReadBufferUsage) |
+                                        mFdp.PickValueInArray(kWriteBufferUsage) |
+                                        mFdp.PickValueInArray(kRenderBufferUsage));
+
+                for (int i = 0; i < kMaxRenderLayer; ++i) {
+                    buffer = new GraphicBuffer(
+                            width, height,
+                            mFdp.ConsumeIntegralInRange<int32_t>(PIXEL_FORMAT_RGBA_8888,
+                                                                 PIXEL_FORMAT_RGBA_4444),
+                            usage, "input");
+                    getLayerSetting(layerSetting, buffer, sourceCrop, textureName);
+                    layers.push_back(&layerSetting);
+                }
+
+                DisplaySettings settings;
+                settings.physicalDisplay = sourceCrop;
+                settings.clip = sourceCrop;
+                settings.outputDataspace = mFdp.PickValueInArray(kDataSpace);
+                settings.maxLuminance = mFdp.ConsumeFloatingPoint<float>();
+
+                sp<GraphicBuffer> dstBuffer =
+                        new GraphicBuffer(width, height,
+                                          mFdp.ConsumeIntegralInRange<int32_t>(
+                                                  PIXEL_FORMAT_RGBA_8888, PIXEL_FORMAT_RGBA_4444),
+                                          usage, "output");
+                base::unique_fd bufferFence;
+                base::unique_fd drawFence;
+
+                renderEngine->drawLayers(settings, layers, dstBuffer, mFdp.ConsumeBool(),
+                                         std::move(bufferFence),
+                                         (mFdp.ConsumeBool() ? nullptr : &drawFence));
+            }
+        }
+    }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    RenderFrightFuzzer renderFrightFuzzer(data, size);
+    renderFrightFuzzer.process();
+    return 0;
+}
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index a126f61..959bd3c 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -135,16 +135,17 @@
         return NO_INIT;
     }
 
+    // Verify ops permissions
+    res = TClientBase::startCameraOps();
+    if (res != OK) {
+        TClientBase::finishCameraOps();
+        return res;
+    }
+
     res = mDevice->initialize(providerPtr, monitorTags);
     if (res != OK) {
         ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
                 __FUNCTION__, TClientBase::mCameraIdStr.c_str(), strerror(-res), res);
-        return res;
-    }
-
-    // Verify ops permissions
-    res = TClientBase::startCameraOps();
-    if (res != OK) {
         TClientBase::finishCameraOps();
         return res;
     }
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 28b2d78..2718604 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -205,6 +205,8 @@
         return res;
     }
 
+    setCameraMuteLocked(mCameraMuteInitial);
+
     mPreparerThread = new PreparerThread();
 
     internalUpdateStatusLocked(STATUS_UNCONFIGURED);
@@ -5526,10 +5528,19 @@
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
+    return setCameraMuteLocked(enabled);
+}
 
-    if (mRequestThread == nullptr || !mSupportCameraMute) {
+status_t Camera3Device::setCameraMuteLocked(bool enabled) {
+    if (mRequestThread == nullptr) {
+        mCameraMuteInitial = enabled;
+        return OK;
+    }
+
+    if (!mSupportCameraMute) {
         return INVALID_OPERATION;
     }
+
     int32_t muteMode =
             !enabled                      ? ANDROID_SENSOR_TEST_PATTERN_MODE_OFF :
             mSupportTestPatternSolidColor ? ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR :
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index c1b173e..9a2f2b1 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -301,6 +301,15 @@
     status_t setCameraMute(bool enabled);
 
     /**
+     * Mute the camera.
+     *
+     * When muted, black image data is output on all output streams.
+     * This method assumes the caller already acquired the 'mInterfaceLock'
+     * and 'mLock' locks.
+     */
+    status_t setCameraMuteLocked(bool enabled);
+
+    /**
      * Enables/disables camera service watchdog
      */
     status_t setCameraServiceWatchdog(bool enabled);
@@ -1499,6 +1508,10 @@
     // Auto framing override value
     camera_metadata_enum_android_control_autoframing mAutoframingOverride;
 
+    // Initial camera mute state stored before the request thread
+    // is active.
+    bool mCameraMuteInitial = false;
+
     // Settings override value
     int32_t mSettingsOverride; // -1 = use original, otherwise
                                // the settings override to use.
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index aef6531..11ef9b7 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -1133,7 +1133,7 @@
 }
 
 void filterParameters(const CameraMetadata& src, const CameraMetadata& deviceInfo,
-        int vendorTagId, CameraMetadata& dst) {
+        metadata_vendor_id_t vendorTagId, CameraMetadata& dst) {
     const CameraMetadata params(src);
     camera_metadata_ro_entry_t availableSessionKeys = deviceInfo.find(
             ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 29e3eca..5b2ea5c 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -177,7 +177,7 @@
         aidl::android::hardware::camera::device::RequestTemplate* tempId /*out*/);
 
 void filterParameters(const CameraMetadata& src, const CameraMetadata& deviceInfo,
-        int vendorTagId, CameraMetadata& dst);
+        metadata_vendor_id_t vendorTagId, CameraMetadata& dst);
 
 constexpr int32_t MAX_SURFACES_PER_STREAM = 4;