Merge "Control audio HAL services in start/stop" into rvc-dev
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 8b7f57d..f87f830 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -139,8 +139,13 @@
     std::vector<uint8_t> sessionId = session->sessionId();
 
     Status status = setSecurityLevel(sessionId, securityLevel);
+    if (status == Status::OK) {
+        mOpenSessionOkCount++;
+    } else {
+        mSessionLibrary->destroySession(session);
+        sessionId.clear();
+    }
     _hidl_cb(status, toHidlVec(sessionId));
-    mOpenSessionOkCount++;
     return Void();
 }
 
@@ -151,12 +156,12 @@
 
     sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
     if (session.get()) {
+        mSessionLibrary->destroySession(session);
         if (session->getMockError() != Status_V1_2::OK) {
             sendSessionLostState(sessionId);
             return Status::ERROR_DRM_INVALID_STATE;
         }
         mCloseSessionOkCount++;
-        mSessionLibrary->destroySession(session);
         return Status::OK;
     }
     mCloseSessionNotOpenedCount++;
@@ -387,6 +392,7 @@
         if (isOfflineLicense) {
             if (isRelease) {
                 mFileHandle.DeleteLicense(keySetId);
+                mSessionLibrary->destroySession(session);
             } else {
                 if (!makeKeySetId(&keySetId)) {
                     _hidl_cb(Status::ERROR_DRM_UNKNOWN, hidl_vec<uint8_t>());
diff --git a/media/codec2/hidl/1.0/vts/OWNERS b/media/codec2/hidl/1.0/vts/OWNERS
index 6733e0c..dbe89cf 100644
--- a/media/codec2/hidl/1.0/vts/OWNERS
+++ b/media/codec2/hidl/1.0/vts/OWNERS
@@ -5,5 +5,4 @@
 wonsik@google.com
 
 # VTS team
-yim@google.com
-zhuoyao@google.com
+dshi@google.com
diff --git a/media/codec2/hidl/1.0/vts/functional/Android.bp b/media/codec2/hidl/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..5f0ba7d
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/Android.bp
@@ -0,0 +1,101 @@
+//
+// Copyright (C) 2020 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.
+//
+
+filegroup {
+    name: "media_c2_v1_audio_decode_res",
+    path: "res",
+    srcs: [
+        "res/bbb_aac_stereo_128kbps_48000hz.aac",
+        "res/bbb_aac_stereo_128kbps_48000hz.info",
+        "res/bbb_aac_stereo_128kbps_48000hz_multi_frame.info",
+        "res/bbb_amrwb_1ch_14kbps_16000hz.amrwb",
+        "res/bbb_amrwb_1ch_14kbps_16000hz.info",
+        "res/bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info",
+        "res/bbb_flac_stereo_680kbps_48000hz.flac",
+        "res/bbb_flac_stereo_680kbps_48000hz.info",
+        "res/bbb_g711alaw_1ch_8khz.info",
+        "res/bbb_g711alaw_1ch_8khz.raw",
+        "res/bbb_g711mulaw_1ch_8khz.info",
+        "res/bbb_g711mulaw_1ch_8khz.raw",
+        "res/bbb_gsm_1ch_8khz_13kbps.info",
+        "res/bbb_gsm_1ch_8khz_13kbps.raw",
+        "res/bbb_mp3_stereo_192kbps_48000hz.info",
+        "res/bbb_mp3_stereo_192kbps_48000hz.mp3",
+        "res/bbb_mp3_stereo_192kbps_48000hz_multi_frame.info",
+        "res/bbb_opus_stereo_128kbps_48000hz.info",
+        "res/bbb_opus_stereo_128kbps_48000hz.opus",
+        "res/bbb_raw_1ch_8khz_s32le.info",
+        "res/bbb_raw_1ch_8khz_s32le.raw",
+        "res/bbb_vorbis_stereo_128kbps_48000hz.info",
+        "res/bbb_vorbis_stereo_128kbps_48000hz.vorbis",
+        "res/sine_amrnb_1ch_12kbps_8000hz.amrnb",
+        "res/sine_amrnb_1ch_12kbps_8000hz.info",
+        "res/sine_amrnb_1ch_12kbps_8000hz_multi_frame.info",
+    ],
+}
+
+filegroup {
+    name: "media_c2_v1_audio_encode_res",
+    path: "res",
+    srcs: [
+        "res/bbb_raw_2ch_48khz_s16le.raw",
+        "res/bbb_raw_1ch_8khz_s16le.raw",
+        "res/bbb_raw_1ch_16khz_s16le.raw",
+    ],
+}
+
+filegroup {
+    name: "media_c2_v1_video_decode_res",
+    path: "res",
+    srcs: [
+        "res/bbb_avc_176x144_300kbps_60fps.h264",
+        "res/bbb_avc_640x360_768kbps_30fps.h264",
+        "res/bbb_avc_176x144_300kbps_60fps.info",
+        "res/bbb_avc_640x360_768kbps_30fps.info",
+        "res/bbb_hevc_176x144_176kbps_60fps.hevc",
+        "res/bbb_hevc_640x360_1600kbps_30fps.hevc",
+        "res/bbb_hevc_176x144_176kbps_60fps.info",
+        "res/bbb_hevc_640x360_1600kbps_30fps.info",
+        "res/bbb_mpeg2_176x144_105kbps_25fps.m2v",
+        "res/bbb_mpeg2_352x288_1mbps_60fps.m2v",
+        "res/bbb_mpeg2_176x144_105kbps_25fps.info",
+        "res/bbb_mpeg2_352x288_1mbps_60fps.info",
+        "res/bbb_h263_352x288_300kbps_12fps.h263",
+        "res/bbb_h263_352x288_300kbps_12fps.info",
+        "res/bbb_mpeg4_352x288_512kbps_30fps.m4v",
+        "res/bbb_mpeg4_352x288_512kbps_30fps.info",
+        "res/bbb_vp8_176x144_240kbps_60fps.vp8",
+        "res/bbb_vp8_640x360_2mbps_30fps.vp8",
+        "res/bbb_vp8_176x144_240kbps_60fps.info",
+        "res/bbb_vp8_640x360_2mbps_30fps.info",
+        "res/bbb_vp9_176x144_285kbps_60fps.vp9",
+        "res/bbb_vp9_640x360_1600kbps_30fps.vp9",
+        "res/bbb_vp9_176x144_285kbps_60fps.info",
+        "res/bbb_vp9_640x360_1600kbps_30fps.info",
+        "res/bbb_av1_640_360.av1",
+        "res/bbb_av1_176_144.av1",
+        "res/bbb_av1_640_360.info",
+        "res/bbb_av1_176_144.info",
+    ],
+}
+
+filegroup {
+    name: "media_c2_v1_video_encode_res",
+    path: "res",
+    srcs: [
+        "res/bbb_352x288_420p_30fps_32frames.yuv",
+    ],
+}
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/Android.bp b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
index 65f0d09..014cbe9 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/Android.bp
@@ -16,18 +16,22 @@
 
 cc_test {
     name: "VtsHalMediaC2V1_0TargetAudioDecTest",
+    stem: "vts_media_c2_v1_0_audio_dec_test",
     defaults: ["VtsHalMediaC2V1_0Defaults"],
     srcs: [
         "VtsHalMediaC2V1_0TargetAudioDecTest.cpp",
-        //"media_audio_hidl_test_common.cpp"
     ],
+    data: [":media_c2_v1_audio_decode_res"],
+    test_config: "VtsHalMediaC2V1_0TargetAudioDecTest.xml",
 }
 
 cc_test {
     name: "VtsHalMediaC2V1_0TargetAudioEncTest",
+    stem: "vts_media_c2_v1_0_audio_enc_test",
     defaults: ["VtsHalMediaC2V1_0Defaults"],
     srcs: [
         "VtsHalMediaC2V1_0TargetAudioEncTest.cpp",
-        //"media_audio_hidl_test_common.cpp"
     ],
+    data: [":media_c2_v1_audio_encode_res"],
+    test_config: "VtsHalMediaC2V1_0TargetAudioEncTest.xml",
 }
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
index 20f4665..264abba 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.cpp
@@ -19,21 +19,20 @@
 
 #include <android-base/logging.h>
 #include <gtest/gtest.h>
-#include <algorithm>
+#include <hidl/GtestPrinter.h>
 #include <stdio.h>
+#include <algorithm>
 #include <fstream>
 
-#include <codec2/hidl/client.h>
 #include <C2AllocatorIon.h>
-#include <C2Config.h>
-#include <C2Debug.h>
 #include <C2Buffer.h>
 #include <C2BufferPriv.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <codec2/hidl/client.h>
 
 using android::C2AllocatorIon;
 
-#include <VtsHalHidlTargetTestBase.h>
-#include "media_c2_audio_hidl_test_common.h"
 #include "media_c2_hidl_test_common.h"
 
 struct FrameInfo {
@@ -42,57 +41,44 @@
     int64_t timestamp;
 };
 
-class LinearBuffer : public C2Buffer {
-   public:
-    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
-        : C2Buffer(
-              {block->share(block->offset(), block->size(), ::C2Fence())}) {}
-};
+static std::vector<std::tuple<std::string, std::string, std::string, std::string>>
+        kDecodeTestParameters;
 
-static ComponentTestEnvironment* gEnv = nullptr;
+// Resource directory
+static std::string sResourceDir = "";
+
+class LinearBuffer : public C2Buffer {
+  public:
+    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
+        : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {}
+};
 
 namespace {
 
-class Codec2AudioDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
-   private:
-    typedef ::testing::VtsHalHidlTargetTestBase Super;
-
-   public:
-    ::std::string getTestCaseInfo() const override {
-        return ::std::string() +
-                "Component: " + gEnv->getComponent().c_str() + " | " +
-                "Instance: " + gEnv->getInstance().c_str() + " | " +
-                "Res: " + gEnv->getRes().c_str();
-    }
-
+class Codec2AudioDecHidlTestBase : public ::testing::Test {
+  public:
     // google.codec2 Audio test setup
     virtual void SetUp() override {
-        Super::SetUp();
+        getParams();
         mDisableTest = false;
         ALOGV("Codec2AudioDecHidlTest SetUp");
         mClient = android::Codec2Client::CreateFromService(
-            gEnv->getInstance().c_str(),
-            !bool(android::Codec2Client::CreateFromService("default", true)));
+                mInstanceName.c_str(),
+                !bool(android::Codec2Client::CreateFromService("default", true)));
         ASSERT_NE(mClient, nullptr);
-        mListener.reset(new CodecListener(
-            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
-                handleWorkDone(workItems);
-            }));
+        mListener.reset(new CodecListener([this](std::list<std::unique_ptr<C2Work>>& workItems) {
+            handleWorkDone(workItems);
+        }));
         ASSERT_NE(mListener, nullptr);
         for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
             mWorkQueue.emplace_back(new C2Work);
         }
-        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
-                                 &mComponent);
+        mClient->createComponent(mComponentName, mListener, &mComponent);
         ASSERT_NE(mComponent, nullptr);
 
-        std::shared_ptr<C2AllocatorStore> store =
-            android::GetCodec2PlatformAllocatorStore();
-        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR,
-                                       &mLinearAllocator),
-                 C2_OK);
-        mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator,
-                                                          mBlockPoolId++);
+        std::shared_ptr<C2AllocatorStore> store = android::GetCodec2PlatformAllocatorStore();
+        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator), C2_OK);
+        mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator, mBlockPoolId++);
         ASSERT_NE(mLinearPool, nullptr);
 
         mCompName = unknown_comp;
@@ -101,27 +87,17 @@
             standardComp CompName;
         };
         const StringToName kStringToName[] = {
-            {"xaac", xaac},
-            {"mp3", mp3},
-            {"amrnb", amrnb},
-            {"amrwb", amrwb},
-            {"aac", aac},
-            {"vorbis", vorbis},
-            {"opus", opus},
-            {"pcm", pcm},
-            {"g711.alaw", g711alaw},
-            {"g711.mlaw", g711mlaw},
-            {"gsm", gsm},
-            {"raw", raw},
-            {"flac", flac},
+                {"xaac", xaac},          {"mp3", mp3}, {"amrnb", amrnb},
+                {"amrwb", amrwb},        {"aac", aac}, {"vorbis", vorbis},
+                {"opus", opus},          {"pcm", pcm}, {"g711.alaw", g711alaw},
+                {"g711.mlaw", g711mlaw}, {"gsm", gsm}, {"raw", raw},
+                {"flac", flac},
         };
-        const size_t kNumStringToName =
-            sizeof(kStringToName) / sizeof(kStringToName[0]);
+        const size_t kNumStringToName = sizeof(kStringToName) / sizeof(kStringToName[0]);
 
         // Find the component type
-        std::string comp = std::string(gEnv->getComponent());
         for (size_t i = 0; i < kNumStringToName; ++i) {
-            if (strcasestr(comp.c_str(), kStringToName[i].Name)) {
+            if (strcasestr(mComponentName.c_str(), kStringToName[i].Name)) {
                 mCompName = kStringToName[i].CompName;
                 break;
             }
@@ -140,9 +116,11 @@
             mComponent->release();
             mComponent = nullptr;
         }
-        Super::TearDown();
     }
 
+    // Get the test parameters from GetParam call.
+    virtual void getParams() {}
+
     struct outputMetaData {
         uint64_t timestampUs;
         uint32_t rangeLength;
@@ -155,25 +133,27 @@
                 // previous timestamp
                 bool codecConfig = ((work->worklets.front()->output.flags &
                                      C2FrameData::FLAG_CODEC_CONFIG) != 0);
-                if (!codecConfig &&
-                    !work->worklets.front()->output.buffers.empty()) {
+                if (!codecConfig && !work->worklets.front()->output.buffers.empty()) {
                     EXPECT_GE(work->worklets.front()->output.ordinal.timestamp.peeku(),
-                        mTimestampUs);
-                    mTimestampUs =
-                        work->worklets.front()->output.ordinal.timestamp.peeku();
-                    uint32_t rangeLength =
-                        work->worklets.front()->output.buffers[0]->data()
-                        .linearBlocks().front().map().get().capacity();
-                    //List of timestamp values and output size to calculate timestamp
+                              mTimestampUs);
+                    mTimestampUs = work->worklets.front()->output.ordinal.timestamp.peeku();
+                    uint32_t rangeLength = work->worklets.front()
+                                                   ->output.buffers[0]
+                                                   ->data()
+                                                   .linearBlocks()
+                                                   .front()
+                                                   .map()
+                                                   .get()
+                                                   .capacity();
+                    // List of timestamp values and output size to calculate timestamp
                     if (mTimestampDevTest) {
                         outputMetaData meta = {mTimestampUs, rangeLength};
                         oBufferMetaData.push_back(meta);
                     }
                 }
                 bool mCsd = false;
-                workDone(mComponent, work, mFlushedIndices, mQueueLock,
-                         mQueueCondition, mWorkQueue, mEos, mCsd,
-                         mFramesReceived);
+                workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue,
+                         mEos, mCsd, mFramesReceived);
                 (void)mCsd;
             }
         }
@@ -196,6 +176,8 @@
         unknown_comp,
     };
 
+    std::string mInstanceName;
+    std::string mComponentName;
     bool mEos;
     bool mDisableTest;
     bool mTimestampDevTest;
@@ -218,15 +200,23 @@
     std::shared_ptr<android::Codec2Client::Listener> mListener;
     std::shared_ptr<android::Codec2Client::Component> mComponent;
 
-   protected:
+  protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
     }
 };
 
-void validateComponent(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    Codec2AudioDecHidlTest::standardComp compName, bool& disableTest) {
+class Codec2AudioDecHidlTest
+    : public Codec2AudioDecHidlTestBase,
+      public ::testing::WithParamInterface<std::tuple<std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
+};
+
+void validateComponent(const std::shared_ptr<android::Codec2Client::Component>& component,
+                       Codec2AudioDecHidlTest::standardComp compName, bool& disableTest) {
     // Validate its a C2 Component
     if (component->getName().find("c2") == std::string::npos) {
         ALOGE("Not a c2 component");
@@ -241,14 +231,12 @@
         return;
     }
     std::vector<std::unique_ptr<C2Param>> queried;
-    c2_status_t c2err =
-        component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
-                         C2_DONT_BLOCK, &queried);
+    c2_status_t c2err = component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+                                         C2_DONT_BLOCK, &queried);
     if (c2err != C2_OK && queried.size() == 0) {
         ALOGE("Query media type failed => %d", c2err);
     } else {
-        std::string inputDomain =
-            ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
+        std::string inputDomain = ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
         if (inputDomain.find("audio/") == std::string::npos) {
             ALOGE("Expected Audio Component");
             disableTest = true;
@@ -266,16 +254,14 @@
 }
 
 // Set Default config param.
-bool setupConfigParam(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    int32_t* bitStreamInfo) {
+bool setupConfigParam(const std::shared_ptr<android::Codec2Client::Component>& component,
+                      int32_t* bitStreamInfo) {
     std::vector<std::unique_ptr<C2SettingResult>> failures;
     C2StreamSampleRateInfo::output sampleRateInfo(0u, bitStreamInfo[0]);
     C2StreamChannelCountInfo::output channelCountInfo(0u, bitStreamInfo[1]);
 
     std::vector<C2Param*> configParam{&sampleRateInfo, &channelCountInfo};
-    c2_status_t status =
-        component->config(configParam, C2_DONT_BLOCK, &failures);
+    c2_status_t status = component->config(configParam, C2_DONT_BLOCK, &failures);
     if (status == C2_OK && failures.size() == 0u) return true;
     return false;
 }
@@ -283,17 +269,15 @@
 // In decoder components, often the input parameters get updated upon
 // parsing the header of elementary stream. Client needs to collect this
 // information and reconfigure
-void getInputChannelInfo(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    Codec2AudioDecHidlTest::standardComp compName, int32_t* bitStreamInfo) {
+void getInputChannelInfo(const std::shared_ptr<android::Codec2Client::Component>& component,
+                         Codec2AudioDecHidlTest::standardComp compName, int32_t* bitStreamInfo) {
     // query nSampleRate and nChannels
     std::initializer_list<C2Param::Index> indices{
-        C2StreamSampleRateInfo::output::PARAM_TYPE,
-        C2StreamChannelCountInfo::output::PARAM_TYPE,
+            C2StreamSampleRateInfo::output::PARAM_TYPE,
+            C2StreamChannelCountInfo::output::PARAM_TYPE,
     };
     std::vector<std::unique_ptr<C2Param>> inParams;
-    c2_status_t status =
-        component->query({}, indices, C2_DONT_BLOCK, &inParams);
+    c2_status_t status = component->query({}, indices, C2_DONT_BLOCK, &inParams);
     if (status != C2_OK && inParams.size() == 0) {
         ALOGE("Query media type failed => %d", status);
         ASSERT_TRUE(false);
@@ -328,8 +312,8 @@
 #define STREAM_COUNT 2
 
 // LookUpTable of clips and metadata for component testing
-void GetURLForComponent(Codec2AudioDecHidlTest::standardComp comp, char* mURL,
-                        char* info, size_t streamIndex = 0) {
+void GetURLForComponent(Codec2AudioDecHidlTest::standardComp comp, char* mURL, char* info,
+                        size_t streamIndex = 0) {
     struct CompToURL {
         Codec2AudioDecHidlTest::standardComp comp;
         const char mURL[STREAM_COUNT][512];
@@ -338,52 +322,47 @@
     ASSERT_TRUE(streamIndex < STREAM_COUNT);
 
     static const CompToURL kCompToURL[] = {
-        {Codec2AudioDecHidlTest::standardComp::xaac,
-         {"bbb_aac_stereo_128kbps_48000hz.aac",
-          "bbb_aac_stereo_128kbps_48000hz.aac"},
-         {"bbb_aac_stereo_128kbps_48000hz.info",
-          "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}},
-        {Codec2AudioDecHidlTest::standardComp::mp3,
-         {"bbb_mp3_stereo_192kbps_48000hz.mp3",
-          "bbb_mp3_stereo_192kbps_48000hz.mp3"},
-         {"bbb_mp3_stereo_192kbps_48000hz.info",
-          "bbb_mp3_stereo_192kbps_48000hz_multi_frame.info"}},
-        {Codec2AudioDecHidlTest::standardComp::aac,
-         {"bbb_aac_stereo_128kbps_48000hz.aac",
-          "bbb_aac_stereo_128kbps_48000hz.aac"},
-         {"bbb_aac_stereo_128kbps_48000hz.info",
-          "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}},
-        {Codec2AudioDecHidlTest::standardComp::amrnb,
-         {"sine_amrnb_1ch_12kbps_8000hz.amrnb",
-          "sine_amrnb_1ch_12kbps_8000hz.amrnb"},
-         {"sine_amrnb_1ch_12kbps_8000hz.info",
-          "sine_amrnb_1ch_12kbps_8000hz_multi_frame.info"}},
-        {Codec2AudioDecHidlTest::standardComp::amrwb,
-         {"bbb_amrwb_1ch_14kbps_16000hz.amrwb",
-          "bbb_amrwb_1ch_14kbps_16000hz.amrwb"},
-         {"bbb_amrwb_1ch_14kbps_16000hz.info",
-          "bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info"}},
-        {Codec2AudioDecHidlTest::standardComp::vorbis,
-         {"bbb_vorbis_stereo_128kbps_48000hz.vorbis", ""},
-         {"bbb_vorbis_stereo_128kbps_48000hz.info", ""}},
-        {Codec2AudioDecHidlTest::standardComp::opus,
-         {"bbb_opus_stereo_128kbps_48000hz.opus", ""},
-         {"bbb_opus_stereo_128kbps_48000hz.info", ""}},
-        {Codec2AudioDecHidlTest::standardComp::g711alaw,
-         {"bbb_g711alaw_1ch_8khz.raw", ""},
-         {"bbb_g711alaw_1ch_8khz.info", ""}},
-        {Codec2AudioDecHidlTest::standardComp::g711mlaw,
-         {"bbb_g711mulaw_1ch_8khz.raw", ""},
-         {"bbb_g711mulaw_1ch_8khz.info", ""}},
-        {Codec2AudioDecHidlTest::standardComp::gsm,
-         {"bbb_gsm_1ch_8khz_13kbps.raw", ""},
-         {"bbb_gsm_1ch_8khz_13kbps.info", ""}},
-        {Codec2AudioDecHidlTest::standardComp::raw,
-         {"bbb_raw_1ch_8khz_s32le.raw", ""},
-         {"bbb_raw_1ch_8khz_s32le.info", ""}},
-        {Codec2AudioDecHidlTest::standardComp::flac,
-         {"bbb_flac_stereo_680kbps_48000hz.flac", ""},
-         {"bbb_flac_stereo_680kbps_48000hz.info", ""}},
+            {Codec2AudioDecHidlTest::standardComp::xaac,
+             {"bbb_aac_stereo_128kbps_48000hz.aac", "bbb_aac_stereo_128kbps_48000hz.aac"},
+             {"bbb_aac_stereo_128kbps_48000hz.info",
+              "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}},
+            {Codec2AudioDecHidlTest::standardComp::mp3,
+             {"bbb_mp3_stereo_192kbps_48000hz.mp3", "bbb_mp3_stereo_192kbps_48000hz.mp3"},
+             {"bbb_mp3_stereo_192kbps_48000hz.info",
+              "bbb_mp3_stereo_192kbps_48000hz_multi_frame.info"}},
+            {Codec2AudioDecHidlTest::standardComp::aac,
+             {"bbb_aac_stereo_128kbps_48000hz.aac", "bbb_aac_stereo_128kbps_48000hz.aac"},
+             {"bbb_aac_stereo_128kbps_48000hz.info",
+              "bbb_aac_stereo_128kbps_48000hz_multi_frame.info"}},
+            {Codec2AudioDecHidlTest::standardComp::amrnb,
+             {"sine_amrnb_1ch_12kbps_8000hz.amrnb", "sine_amrnb_1ch_12kbps_8000hz.amrnb"},
+             {"sine_amrnb_1ch_12kbps_8000hz.info",
+              "sine_amrnb_1ch_12kbps_8000hz_multi_frame.info"}},
+            {Codec2AudioDecHidlTest::standardComp::amrwb,
+             {"bbb_amrwb_1ch_14kbps_16000hz.amrwb", "bbb_amrwb_1ch_14kbps_16000hz.amrwb"},
+             {"bbb_amrwb_1ch_14kbps_16000hz.info",
+              "bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info"}},
+            {Codec2AudioDecHidlTest::standardComp::vorbis,
+             {"bbb_vorbis_stereo_128kbps_48000hz.vorbis", ""},
+             {"bbb_vorbis_stereo_128kbps_48000hz.info", ""}},
+            {Codec2AudioDecHidlTest::standardComp::opus,
+             {"bbb_opus_stereo_128kbps_48000hz.opus", ""},
+             {"bbb_opus_stereo_128kbps_48000hz.info", ""}},
+            {Codec2AudioDecHidlTest::standardComp::g711alaw,
+             {"bbb_g711alaw_1ch_8khz.raw", ""},
+             {"bbb_g711alaw_1ch_8khz.info", ""}},
+            {Codec2AudioDecHidlTest::standardComp::g711mlaw,
+             {"bbb_g711mulaw_1ch_8khz.raw", ""},
+             {"bbb_g711mulaw_1ch_8khz.info", ""}},
+            {Codec2AudioDecHidlTest::standardComp::gsm,
+             {"bbb_gsm_1ch_8khz_13kbps.raw", ""},
+             {"bbb_gsm_1ch_8khz_13kbps.info", ""}},
+            {Codec2AudioDecHidlTest::standardComp::raw,
+             {"bbb_raw_1ch_8khz_s32le.raw", ""},
+             {"bbb_raw_1ch_8khz_s32le.info", ""}},
+            {Codec2AudioDecHidlTest::standardComp::flac,
+             {"bbb_flac_stereo_680kbps_48000hz.flac", ""},
+             {"bbb_flac_stereo_680kbps_48000hz.info", ""}},
     };
 
     for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
@@ -396,13 +375,11 @@
 }
 
 void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
-                   std::mutex &queueLock, std::condition_variable& queueCondition,
+                   std::mutex& queueLock, std::condition_variable& queueCondition,
                    std::list<std::unique_ptr<C2Work>>& workQueue,
-                   std::list<uint64_t>& flushedIndices,
-                   std::shared_ptr<C2BlockPool>& linearPool,
-                   std::ifstream& eleStream,
-                   android::Vector<FrameInfo>* Info,
-                   int offset, int range, bool signalEOS = true) {
+                   std::list<uint64_t>& flushedIndices, std::shared_ptr<C2BlockPool>& linearPool,
+                   std::ifstream& eleStream, android::Vector<FrameInfo>* Info, int offset,
+                   int range, bool signalEOS = true) {
     typedef std::unique_lock<std::mutex> ULock;
     int frameID = offset;
     int maxRetry = 0;
@@ -426,8 +403,7 @@
         }
         int64_t timestamp = (*Info)[frameID].timestamp;
         if ((*Info)[frameID].flags) flags = 1u << ((*Info)[frameID].flags - 1);
-        if (signalEOS && ((frameID == (int)Info->size() - 1) ||
-                          (frameID == (offset + range - 1))))
+        if (signalEOS && ((frameID == (int)Info->size() - 1) || (frameID == (offset + range - 1))))
             flags |= C2FrameData::FLAG_END_OF_STREAM;
 
         work->input.flags = (C2FrameData::flags_t)flags;
@@ -448,9 +424,8 @@
         if (size) {
             std::shared_ptr<C2LinearBlock> block;
             ASSERT_EQ(C2_OK,
-                    linearPool->fetchLinearBlock(
-                        size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
-                        &block));
+                      linearPool->fetchLinearBlock(
+                              size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block));
             ASSERT_TRUE(block);
 
             // Write View
@@ -482,45 +457,49 @@
     }
 }
 
-TEST_F(Codec2AudioDecHidlTest, validateCompName) {
-    if (mDisableTest) return;
+TEST_P(Codec2AudioDecHidlTest, validateCompName) {
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     ALOGV("Checks if the given component is a valid audio component");
     validateComponent(mComponent, mCompName, mDisableTest);
     ASSERT_EQ(mDisableTest, false);
 }
 
-TEST_F(Codec2AudioDecHidlTest, configComp) {
+TEST_P(Codec2AudioDecHidlTest, configComp) {
     description("Tests component specific configuration");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     ASSERT_EQ(mComponent->start(), C2_OK);
     int32_t bitStreamInfo[2] = {0};
-    ASSERT_NO_FATAL_FAILURE(
-        getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+    ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
     setupConfigParam(mComponent, bitStreamInfo);
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
 class Codec2AudioDecDecodeTest
-    : public Codec2AudioDecHidlTest,
-      public ::testing::WithParamInterface<std::pair<int32_t, bool>> {
+    : public Codec2AudioDecHidlTestBase,
+      public ::testing::WithParamInterface<
+              std::tuple<std::string, std::string, std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
 };
 
 TEST_P(Codec2AudioDecDecodeTest, DecodeTest) {
     description("Decodes input file");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
-    uint32_t streamIndex = GetParam().first;
-    bool signalEOS = GetParam().second;
+    uint32_t streamIndex = std::stoi(std::get<2>(GetParam()));
+    ;
+    bool signalEOS = !std::get<3>(GetParam()).compare("true");
     mTimestampDevTest = true;
     char mURL[512], info[512];
     std::ifstream eleStream, eleInfo;
 
-    strcpy(mURL, gEnv->getRes().c_str());
-    strcpy(info, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
+    strcpy(info, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL, info, streamIndex);
-    if (!strcmp(mURL, gEnv->getRes().c_str())) {
-        ALOGV("EMPTY INPUT gEnv->getRes().c_str() %s mURL  %s ",
-              gEnv->getRes().c_str(), mURL);
+    if (!strcmp(mURL, sResourceDir.c_str())) {
+        ALOGV("EMPTY INPUT sResourceDir.c_str() %s mURL  %s ", sResourceDir.c_str(), mURL);
         return;
     }
 
@@ -534,10 +513,8 @@
         if (!(eleInfo >> bytesCount)) break;
         eleInfo >> flags;
         eleInfo >> timestamp;
-        bool codecConfig =
-            ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0;
-        if (mTimestampDevTest && !codecConfig)
-            mTimestampUslist.push_back(timestamp);
+        bool codecConfig = ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0;
+        if (mTimestampDevTest && !codecConfig) mTimestampUslist.push_back(timestamp);
         Info.push_back({bytesCount, flags, timestamp});
     }
     eleInfo.close();
@@ -549,8 +526,7 @@
         bitStreamInfo[0] = 8000;
         bitStreamInfo[1] = 1;
     } else {
-        ASSERT_NO_FATAL_FAILURE(
-            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+        ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
     }
     if (!setupConfigParam(mComponent, bitStreamInfo)) {
         std::cout << "[   WARN   ] Test Skipped \n";
@@ -560,29 +536,25 @@
     ALOGV("mURL : %s", mURL);
     eleStream.open(mURL, std::ifstream::binary);
     ASSERT_EQ(eleStream.is_open(), true);
-    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
-        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
-        mLinearPool, eleStream, &Info, 0, (int)Info.size(), signalEOS));
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mLinearPool, eleStream, &Info, 0,
+                                          (int)Info.size(), signalEOS));
 
     // If EOS is not sent, sending empty input with EOS flag
     size_t infoSize = Info.size();
     if (!signalEOS) {
-        ASSERT_NO_FATAL_FAILURE(
-            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
-        ASSERT_NO_FATAL_FAILURE(
-            testInputBuffer(mComponent, mQueueLock, mWorkQueue,
-                            C2FrameData::FLAG_END_OF_STREAM, false));
+        ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
+        ASSERT_NO_FATAL_FAILURE(testInputBuffer(mComponent, mQueueLock, mWorkQueue,
+                                                C2FrameData::FLAG_END_OF_STREAM, false));
         infoSize += 1;
     }
     // blocking call to ensures application to Wait till all the inputs are
     // consumed
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
     eleStream.close();
     if (mFramesReceived != infoSize) {
         ALOGE("Input buffer count and Output buffer count mismatch");
-        ALOGE("framesReceived : %d inputFrames : %zu", mFramesReceived,
-              infoSize);
+        ALOGE("framesReceived : %d inputFrames : %zu", mFramesReceived, infoSize);
         ASSERT_TRUE(false);
     }
     ASSERT_EQ(mEos, true);
@@ -590,8 +562,7 @@
         uint64_t expTs;
         uint32_t samplesReceived = 0;
         // Update SampleRate and ChannelCount
-        ASSERT_NO_FATAL_FAILURE(
-            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+        ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
         int nSampleRate = bitStreamInfo[0];
         int nChannels = bitStreamInfo[1];
         std::list<uint64_t>::iterator itIn = mTimestampUslist.begin();
@@ -614,23 +585,17 @@
     }
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
-// DecodeTest with StreamIndex and EOS / No EOS
-INSTANTIATE_TEST_CASE_P(StreamIndexAndEOS, Codec2AudioDecDecodeTest,
-                        ::testing::Values(std::make_pair(0, false),
-                                          std::make_pair(0, true),
-                                          std::make_pair(1, false),
-                                          std::make_pair(1, true)));
 
 // thumbnail test
-TEST_F(Codec2AudioDecHidlTest, ThumbnailTest) {
+TEST_P(Codec2AudioDecHidlTest, ThumbnailTest) {
     description("Test Request for thumbnail");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
     char mURL[512], info[512];
     std::ifstream eleStream, eleInfo;
 
-    strcpy(mURL, gEnv->getRes().c_str());
-    strcpy(info, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
+    strcpy(info, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL, info);
 
     eleInfo.open(info);
@@ -651,8 +616,7 @@
         bitStreamInfo[0] = 8000;
         bitStreamInfo[1] = 1;
     } else {
-        ASSERT_NO_FATAL_FAILURE(
-            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+        ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
     }
     if (!setupConfigParam(mComponent, bitStreamInfo)) {
         std::cout << "[   WARN   ] Test Skipped \n";
@@ -672,20 +636,19 @@
     } while (!(flags & SYNC_FRAME));
     eleStream.open(mURL, std::ifstream::binary);
     ASSERT_EQ(eleStream.is_open(), true);
-    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
-        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
-        mLinearPool, eleStream, &Info, 0, i + 1));
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mLinearPool, eleStream, &Info, 0,
+                                          i + 1));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
     eleStream.close();
     EXPECT_GE(mFramesReceived, 1U);
     ASSERT_EQ(mEos, true);
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2AudioDecHidlTest, EOSTest) {
+TEST_P(Codec2AudioDecHidlTest, EOSTest) {
     description("Test empty input buffer with EOS flag");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     typedef std::unique_lock<std::mutex> ULock;
     ASSERT_EQ(mComponent->start(), C2_OK);
     std::unique_ptr<C2Work> work;
@@ -723,15 +686,15 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2AudioDecHidlTest, FlushTest) {
+TEST_P(Codec2AudioDecHidlTest, FlushTest) {
     description("Tests Flush calls");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     typedef std::unique_lock<std::mutex> ULock;
     char mURL[512], info[512];
     std::ifstream eleStream, eleInfo;
 
-    strcpy(mURL, gEnv->getRes().c_str());
-    strcpy(info, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
+    strcpy(info, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL, info);
 
     eleInfo.open(info);
@@ -753,8 +716,7 @@
         bitStreamInfo[0] = 8000;
         bitStreamInfo[1] = 1;
     } else {
-        ASSERT_NO_FATAL_FAILURE(
-            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+        ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
     }
     if (!setupConfigParam(mComponent, bitStreamInfo)) {
         std::cout << "[   WARN   ] Test Skipped \n";
@@ -768,29 +730,25 @@
     // frame after this so that the below section can be covered for all
     // components
     uint32_t numFramesFlushed = 128;
-    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
-        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
-        mLinearPool, eleStream, &Info, 0, numFramesFlushed, false));
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mLinearPool, eleStream, &Info, 0,
+                                          numFramesFlushed, false));
     // flush
     std::list<std::unique_ptr<C2Work>> flushedWork;
-    c2_status_t err =
-        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    c2_status_t err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
     ASSERT_EQ(err, C2_OK);
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
-            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                                                   (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
     uint64_t frameIndex;
     {
-        //Update mFlushedIndices based on the index received from flush()
+        // Update mFlushedIndices based on the index received from flush()
         ULock l(mQueueLock);
         for (std::unique_ptr<C2Work>& work : flushedWork) {
             ASSERT_NE(work, nullptr);
             frameIndex = work->input.ordinal.frameIndex.peeku();
             std::list<uint64_t>::iterator frameIndexIt =
-                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
-                          frameIndex);
-            if (!mFlushedIndices.empty() &&
-                (frameIndexIt != mFlushedIndices.end())) {
+                    std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) {
                 mFlushedIndices.erase(frameIndexIt);
                 work->input.buffers.clear();
                 work->worklets.clear();
@@ -814,29 +772,24 @@
         index++;
     }
     if (keyFrame) {
-        ASSERT_NO_FATAL_FAILURE(
-            decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                          mFlushedIndices, mLinearPool, eleStream, &Info, index,
-                          (int)Info.size() - index));
+        ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                              mFlushedIndices, mLinearPool, eleStream, &Info, index,
+                                              (int)Info.size() - index));
     }
     eleStream.close();
-    err =
-        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
     ASSERT_EQ(err, C2_OK);
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
-            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                                                   (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
     {
-        //Update mFlushedIndices based on the index received from flush()
+        // Update mFlushedIndices based on the index received from flush()
         ULock l(mQueueLock);
         for (std::unique_ptr<C2Work>& work : flushedWork) {
             ASSERT_NE(work, nullptr);
             frameIndex = work->input.ordinal.frameIndex.peeku();
             std::list<uint64_t>::iterator frameIndexIt =
-                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
-                          frameIndex);
-            if (!mFlushedIndices.empty() &&
-                (frameIndexIt != mFlushedIndices.end())) {
+                    std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) {
                 mFlushedIndices.erase(frameIndexIt);
                 work->input.buffers.clear();
                 work->worklets.clear();
@@ -848,15 +801,15 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) {
+TEST_P(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) {
     description("Decode with multiple empty input frames");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
     char mURL[512], info[512];
     std::ifstream eleStream, eleInfo;
 
-    strcpy(mURL, gEnv->getRes().c_str());
-    strcpy(info, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
+    strcpy(info, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL, info);
 
     eleInfo.open(info);
@@ -871,15 +824,16 @@
     // and empty input frames at an interval of 5 frames.
     while (1) {
         if (!(frameId % 5)) {
-            if (!(frameId % 20)) flags = 32;
-            else flags = 0;
+            if (!(frameId % 20))
+                flags = 32;
+            else
+                flags = 0;
             bytesCount = 0;
         } else {
             if (!(eleInfo >> bytesCount)) break;
             eleInfo >> flags;
             eleInfo >> timestamp;
-            codecConfig = flags ?
-                ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+            codecConfig = flags ? ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
         }
         Info.push_back({bytesCount, flags, timestamp});
         frameId++;
@@ -890,8 +844,7 @@
         bitStreamInfo[0] = 8000;
         bitStreamInfo[1] = 1;
     } else {
-        ASSERT_NO_FATAL_FAILURE(
-            getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
+        ASSERT_NO_FATAL_FAILURE(getInputChannelInfo(mComponent, mCompName, bitStreamInfo));
     }
     if (!setupConfigParam(mComponent, bitStreamInfo)) {
         std::cout << "[   WARN   ] Test Skipped \n";
@@ -901,40 +854,59 @@
     ALOGV("mURL : %s", mURL);
     eleStream.open(mURL, std::ifstream::binary);
     ASSERT_EQ(eleStream.is_open(), true);
-    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
-        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
-        mLinearPool, eleStream, &Info, 0, (int)Info.size()));
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mLinearPool, eleStream, &Info, 0,
+                                          (int)Info.size()));
 
     // blocking call to ensures application to Wait till all the inputs are
     // consumed
     if (!mEos) {
         ALOGV("Waiting for input consumption");
-        ASSERT_NO_FATAL_FAILURE(
-            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+        ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
     }
 
     eleStream.close();
     if (mFramesReceived != Info.size()) {
         ALOGE("Input buffer count and Output buffer count mismatch");
-        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
-              Info.size());
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, Info.size());
         ASSERT_TRUE(false);
     }
 
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2AudioDecHidlTest, testing::ValuesIn(kTestParameters),
+                         android::hardware::PrintInstanceTupleNameToString<>);
+
+// DecodeTest with StreamIndex and EOS / No EOS
+INSTANTIATE_TEST_SUITE_P(StreamIndexAndEOS, Codec2AudioDecDecodeTest,
+                         testing::ValuesIn(kDecodeTestParameters),
+                         android::hardware::PrintInstanceTupleNameToString<>);
+
 }  // anonymous namespace
 
 int main(int argc, char** argv) {
-    gEnv = new ComponentTestEnvironment();
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    int status = gEnv->initFromOptions(argc, argv);
-    if (status == 0) {
-        int status = RUN_ALL_TESTS();
-        LOG(INFO) << "C2 Test result = " << status;
+    kTestParameters = getTestParameters(C2Component::DOMAIN_AUDIO, C2Component::KIND_DECODER);
+    for (auto params : kTestParameters) {
+        kDecodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "false"));
+        kDecodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "true"));
+        kDecodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "1", "false"));
+        kDecodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "1", "true"));
     }
-    return status;
-}
+
+    // Set the resource directory based on command line args.
+    // Test will fail to set up if the argument is not set.
+    for (int i = 1; i < argc; i++) {
+        if (strcmp(argv[i], "-P") == 0 && i < argc - 1) {
+            sResourceDir = argv[i + 1];
+            break;
+        }
+    }
+
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.xml b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.xml
new file mode 100644
index 0000000..a22f8cf
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioDecTest.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Runs VtsHalMediaC2V1_0TargetAudioDecTest.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file" key="vts_media_c2_v1_0_audio_dec_test" value="/data/local/tmp/vts_media_c2_v1_0_audio_dec_test" />
+
+        <!-- Files used for audio testing -->
+        <option name="push-file" key="bbb_aac_stereo_128kbps_48000hz.aac" value="/data/local/tmp/media/bbb_aac_stereo_128kbps_48000hz.aac" />
+        <option name="push-file" key="bbb_aac_stereo_128kbps_48000hz.info" value="/data/local/tmp/media/bbb_aac_stereo_128kbps_48000hz.info" />
+        <option name="push-file" key="bbb_aac_stereo_128kbps_48000hz_multi_frame.info" value="/data/local/tmp/media/bbb_aac_stereo_128kbps_48000hz_multi_frame.info" />
+        <option name="push-file" key="bbb_amrwb_1ch_14kbps_16000hz.amrwb" value="/data/local/tmp/media/bbb_amrwb_1ch_14kbps_16000hz.amrwb" />
+        <option name="push-file" key="bbb_amrwb_1ch_14kbps_16000hz.info" value="/data/local/tmp/media/bbb_amrwb_1ch_14kbps_16000hz.info" />
+        <option name="push-file" key="bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info" value="/data/local/tmp/media/bbb_amrwb_1ch_14kbps_16000hz_multi_frame.info" />
+        <option name="push-file" key="bbb_flac_stereo_680kbps_48000hz.flac" value="/data/local/tmp/media/bbb_flac_stereo_680kbps_48000hz.flac" />
+        <option name="push-file" key="bbb_flac_stereo_680kbps_48000hz.info" value="/data/local/tmp/media/bbb_flac_stereo_680kbps_48000hz.info" />
+        <option name="push-file" key="bbb_g711alaw_1ch_8khz.info" value="/data/local/tmp/media/bbb_g711alaw_1ch_8khz.info" />
+        <option name="push-file" key="bbb_g711alaw_1ch_8khz.raw" value="/data/local/tmp/media/bbb_g711alaw_1ch_8khz.raw" />
+        <option name="push-file" key="bbb_g711mulaw_1ch_8khz.info" value="/data/local/tmp/media/bbb_g711mulaw_1ch_8khz.info" />
+        <option name="push-file" key="bbb_g711mulaw_1ch_8khz.raw" value="/data/local/tmp/media/bbb_g711mulaw_1ch_8khz.raw" />
+        <option name="push-file" key="bbb_gsm_1ch_8khz_13kbps.info" value="/data/local/tmp/media/bbb_gsm_1ch_8khz_13kbps.info" />
+        <option name="push-file" key="bbb_gsm_1ch_8khz_13kbps.raw" value="/data/local/tmp/media/bbb_gsm_1ch_8khz_13kbps.raw" />
+        <option name="push-file" key="bbb_mp3_stereo_192kbps_48000hz.info" value="/data/local/tmp/media/bbb_mp3_stereo_192kbps_48000hz.info" />
+        <option name="push-file" key="bbb_mp3_stereo_192kbps_48000hz.mp3" value="/data/local/tmp/media/bbb_mp3_stereo_192kbps_48000hz.mp3" />
+        <option name="push-file" key="bbb_mp3_stereo_192kbps_48000hz_multi_frame.info" value="/data/local/tmp/media/bbb_mp3_stereo_192kbps_48000hz_multi_frame.info" />
+        <option name="push-file" key="bbb_opus_stereo_128kbps_48000hz.info" value="/data/local/tmp/media/bbb_opus_stereo_128kbps_48000hz.info" />
+        <option name="push-file" key="bbb_opus_stereo_128kbps_48000hz.opus" value="/data/local/tmp/media/bbb_opus_stereo_128kbps_48000hz.opus" />
+        <option name="push-file" key="bbb_raw_1ch_8khz_s32le.info" value="/data/local/tmp/media/bbb_raw_1ch_8khz_s32le.info" />
+        <option name="push-file" key="bbb_raw_1ch_8khz_s32le.raw" value="/data/local/tmp/media/bbb_raw_1ch_8khz_s32le.raw" />
+        <option name="push-file" key="bbb_vorbis_stereo_128kbps_48000hz.info" value="/data/local/tmp/media/bbb_vorbis_stereo_128kbps_48000hz.info" />
+        <option name="push-file" key="bbb_vorbis_stereo_128kbps_48000hz.vorbis" value="/data/local/tmp/media/bbb_vorbis_stereo_128kbps_48000hz.vorbis" />
+        <option name="push-file" key="sine_amrnb_1ch_12kbps_8000hz.amrnb" value="/data/local/tmp/media/sine_amrnb_1ch_12kbps_8000hz.amrnb" />
+        <option name="push-file" key="sine_amrnb_1ch_12kbps_8000hz.info" value="/data/local/tmp/media/sine_amrnb_1ch_12kbps_8000hz.info" />
+        <option name="push-file" key="sine_amrnb_1ch_12kbps_8000hz_multi_frame.info" value="/data/local/tmp/media/sine_amrnb_1ch_12kbps_8000hz_multi_frame.info" />
+
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="vts_media_c2_v1_0_audio_dec_test" />
+        <option name="native-test-flag" value="-P /data/local/tmp/media/" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
index ab6bfb2..5f3ae41 100644
--- a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.cpp
@@ -19,74 +19,60 @@
 
 #include <android-base/logging.h>
 #include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
 #include <stdio.h>
-#include <fstream>
 #include <algorithm>
+#include <fstream>
 
-#include <codec2/hidl/client.h>
 #include <C2AllocatorIon.h>
-#include <C2Config.h>
-#include <C2Debug.h>
 #include <C2Buffer.h>
 #include <C2BufferPriv.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <codec2/hidl/client.h>
 
 using android::C2AllocatorIon;
 
-#include <VtsHalHidlTargetTestBase.h>
-#include "media_c2_audio_hidl_test_common.h"
 #include "media_c2_hidl_test_common.h"
 
-class LinearBuffer : public C2Buffer {
-   public:
-    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
-        : C2Buffer(
-              {block->share(block->offset(), block->size(), ::C2Fence())}) {}
-};
+static std::vector<std::tuple<std::string, std::string, std::string, std::string>>
+        kEncodeTestParameters;
 
-static ComponentTestEnvironment* gEnv = nullptr;
+// Resource directory
+static std::string sResourceDir = "";
+
+class LinearBuffer : public C2Buffer {
+  public:
+    explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
+        : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {}
+};
 
 namespace {
 
-class Codec2AudioEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
-   private:
-    typedef ::testing::VtsHalHidlTargetTestBase Super;
-
-   public:
-    ::std::string getTestCaseInfo() const override {
-        return ::std::string() +
-                "Component: " + gEnv->getComponent().c_str() + " | " +
-                "Instance: " + gEnv->getInstance().c_str() + " | " +
-                "Res: " + gEnv->getRes().c_str();
-    }
-
+class Codec2AudioEncHidlTestBase : public ::testing::Test {
+  public:
     // google.codec2 Audio test setup
     virtual void SetUp() override {
-        Super::SetUp();
+        getParams();
         mDisableTest = false;
         ALOGV("Codec2AudioEncHidlTest SetUp");
         mClient = android::Codec2Client::CreateFromService(
-            gEnv->getInstance().c_str(),
-            !bool(android::Codec2Client::CreateFromService("default", true)));
+                mInstanceName.c_str(),
+                !bool(android::Codec2Client::CreateFromService("default", true)));
         ASSERT_NE(mClient, nullptr);
-        mListener.reset(new CodecListener(
-            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
-                handleWorkDone(workItems);
-            }));
+        mListener.reset(new CodecListener([this](std::list<std::unique_ptr<C2Work>>& workItems) {
+            handleWorkDone(workItems);
+        }));
         ASSERT_NE(mListener, nullptr);
         for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
             mWorkQueue.emplace_back(new C2Work);
         }
-        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
-                                 &mComponent);
+        mClient->createComponent(mComponentName, mListener, &mComponent);
         ASSERT_NE(mComponent, nullptr);
 
-        std::shared_ptr<C2AllocatorStore> store =
-            android::GetCodec2PlatformAllocatorStore();
-        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR,
-                                       &mLinearAllocator),
-                 C2_OK);
-        mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator,
-                                                          mBlockPoolId++);
+        std::shared_ptr<C2AllocatorStore> store = android::GetCodec2PlatformAllocatorStore();
+        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator), C2_OK);
+        mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator, mBlockPoolId++);
         ASSERT_NE(mLinearPool, nullptr);
 
         mCompName = unknown_comp;
@@ -95,19 +81,13 @@
             standardComp CompName;
         };
         const StringToName kStringToName[] = {
-            {"aac", aac},
-            {"flac", flac},
-            {"opus", opus},
-            {"amrnb", amrnb},
-            {"amrwb", amrwb},
+                {"aac", aac}, {"flac", flac}, {"opus", opus}, {"amrnb", amrnb}, {"amrwb", amrwb},
         };
-        const size_t kNumStringToName =
-            sizeof(kStringToName) / sizeof(kStringToName[0]);
+        const size_t kNumStringToName = sizeof(kStringToName) / sizeof(kStringToName[0]);
 
         // Find the component type
-        std::string comp = std::string(gEnv->getComponent());
         for (size_t i = 0; i < kNumStringToName; ++i) {
-            if (strcasestr(comp.c_str(), kStringToName[i].Name)) {
+            if (strcasestr(mComponentName.c_str(), kStringToName[i].Name)) {
                 mCompName = kStringToName[i].CompName;
                 break;
             }
@@ -126,15 +106,17 @@
             mComponent->release();
             mComponent = nullptr;
         }
-        Super::TearDown();
     }
+
+    // Get the test parameters from GetParam call.
+    virtual void getParams() {}
+
     // callback function to process onWorkDone received by Listener
     void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
         for (std::unique_ptr<C2Work>& work : workItems) {
             if (!work->worklets.empty()) {
-                workDone(mComponent, work, mFlushedIndices, mQueueLock,
-                         mQueueCondition, mWorkQueue, mEos, mCsd,
-                         mFramesReceived);
+                workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue,
+                         mEos, mCsd, mFramesReceived);
             }
         }
     }
@@ -147,6 +129,8 @@
         unknown_comp,
     };
 
+    std::string mInstanceName;
+    std::string mComponentName;
     bool mEos;
     bool mCsd;
     bool mDisableTest;
@@ -167,7 +151,7 @@
     std::shared_ptr<android::Codec2Client::Listener> mListener;
     std::shared_ptr<android::Codec2Client::Component> mComponent;
 
-   protected:
+  protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
     }
@@ -176,9 +160,8 @@
     void getInputMaxBufSize() {
         int32_t bitStreamInfo[1] = {0};
         std::vector<std::unique_ptr<C2Param>> inParams;
-        c2_status_t status = mComponent->query(
-            {}, {C2StreamMaxBufferSizeInfo::input::PARAM_TYPE}, C2_DONT_BLOCK,
-            &inParams);
+        c2_status_t status = mComponent->query({}, {C2StreamMaxBufferSizeInfo::input::PARAM_TYPE},
+                                               C2_DONT_BLOCK, &inParams);
         if (status != C2_OK && inParams.size() == 0) {
             ALOGE("Query MaxBufferSizeInfo failed => %d", status);
             ASSERT_TRUE(false);
@@ -191,12 +174,19 @@
         }
         mInputMaxBufSize = bitStreamInfo[0];
     }
-
 };
 
-void validateComponent(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    Codec2AudioEncHidlTest::standardComp compName, bool& disableTest) {
+class Codec2AudioEncHidlTest
+    : public Codec2AudioEncHidlTestBase,
+      public ::testing::WithParamInterface<std::tuple<std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
+};
+
+void validateComponent(const std::shared_ptr<android::Codec2Client::Component>& component,
+                       Codec2AudioEncHidlTest::standardComp compName, bool& disableTest) {
     // Validate its a C2 Component
     if (component->getName().find("c2") == std::string::npos) {
         ALOGE("Not a c2 component");
@@ -211,14 +201,12 @@
         return;
     }
     std::vector<std::unique_ptr<C2Param>> queried;
-    c2_status_t c2err =
-        component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
-                         C2_DONT_BLOCK, &queried);
+    c2_status_t c2err = component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+                                         C2_DONT_BLOCK, &queried);
     if (c2err != C2_OK && queried.size() == 0) {
         ALOGE("Query media type failed => %d", c2err);
     } else {
-        std::string inputDomain =
-            ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
+        std::string inputDomain = ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
         if (inputDomain.find("audio/") == std::string::npos) {
             ALOGE("Expected Audio Component");
             disableTest = true;
@@ -236,16 +224,14 @@
 }
 
 // Set Default config param.
-bool setupConfigParam(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    int32_t nChannels, int32_t nSampleRate) {
+bool setupConfigParam(const std::shared_ptr<android::Codec2Client::Component>& component,
+                      int32_t nChannels, int32_t nSampleRate) {
     std::vector<std::unique_ptr<C2SettingResult>> failures;
     C2StreamSampleRateInfo::input sampleRateInfo(0u, nSampleRate);
     C2StreamChannelCountInfo::input channelCountInfo(0u, nChannels);
 
     std::vector<C2Param*> configParam{&sampleRateInfo, &channelCountInfo};
-    c2_status_t status =
-        component->config(configParam, C2_DONT_BLOCK, &failures);
+    c2_status_t status = component->config(configParam, C2_DONT_BLOCK, &failures);
     if (status == C2_OK && failures.size() == 0u) return true;
     return false;
 }
@@ -257,16 +243,11 @@
         const char* mURL;
     };
     static const CompToURL kCompToURL[] = {
-        {Codec2AudioEncHidlTest::standardComp::aac,
-         "bbb_raw_2ch_48khz_s16le.raw"},
-        {Codec2AudioEncHidlTest::standardComp::amrnb,
-         "bbb_raw_1ch_8khz_s16le.raw"},
-        {Codec2AudioEncHidlTest::standardComp::amrwb,
-         "bbb_raw_1ch_16khz_s16le.raw"},
-        {Codec2AudioEncHidlTest::standardComp::flac,
-         "bbb_raw_2ch_48khz_s16le.raw"},
-        {Codec2AudioEncHidlTest::standardComp::opus,
-         "bbb_raw_2ch_48khz_s16le.raw"},
+            {Codec2AudioEncHidlTest::standardComp::aac, "bbb_raw_2ch_48khz_s16le.raw"},
+            {Codec2AudioEncHidlTest::standardComp::amrnb, "bbb_raw_1ch_8khz_s16le.raw"},
+            {Codec2AudioEncHidlTest::standardComp::amrwb, "bbb_raw_1ch_16khz_s16le.raw"},
+            {Codec2AudioEncHidlTest::standardComp::flac, "bbb_raw_2ch_48khz_s16le.raw"},
+            {Codec2AudioEncHidlTest::standardComp::opus, "bbb_raw_2ch_48khz_s16le.raw"},
     };
 
     for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
@@ -278,21 +259,18 @@
 }
 
 void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
-                   std::mutex &queueLock, std::condition_variable& queueCondition,
+                   std::mutex& queueLock, std::condition_variable& queueCondition,
                    std::list<std::unique_ptr<C2Work>>& workQueue,
-                   std::list<uint64_t>& flushedIndices,
-                   std::shared_ptr<C2BlockPool>& linearPool,
-                   std::ifstream& eleStream, uint32_t nFrames,
-                   int32_t samplesPerFrame, int32_t nChannels,
-                   int32_t nSampleRate, bool flushed = false,
+                   std::list<uint64_t>& flushedIndices, std::shared_ptr<C2BlockPool>& linearPool,
+                   std::ifstream& eleStream, uint32_t nFrames, int32_t samplesPerFrame,
+                   int32_t nChannels, int32_t nSampleRate, bool flushed = false,
                    bool signalEOS = true) {
     typedef std::unique_lock<std::mutex> ULock;
 
     uint32_t frameID = 0;
     uint32_t maxRetry = 0;
     int bytesCount = samplesPerFrame * nChannels * 2;
-    int32_t timestampIncr =
-        (int)(((float)samplesPerFrame / nSampleRate) * 1000000);
+    int32_t timestampIncr = (int)(((float)samplesPerFrame / nSampleRate) * 1000000);
     uint64_t timestamp = 0;
     while (1) {
         if (nFrames == 0) break;
@@ -312,8 +290,7 @@
         if (!work && (maxRetry >= MAX_RETRY)) {
             ASSERT_TRUE(false) << "Wait for generating C2Work exceeded timeout";
         }
-        if (signalEOS && (nFrames == 1))
-            flags |= C2FrameData::FLAG_END_OF_STREAM;
+        if (signalEOS && (nFrames == 1)) flags |= C2FrameData::FLAG_END_OF_STREAM;
         if (flushed) {
             flags |= SYNC_FRAME;
             flushed = false;
@@ -330,10 +307,9 @@
         eleStream.read(data, bytesCount);
         ASSERT_EQ(eleStream.gcount(), bytesCount);
         std::shared_ptr<C2LinearBlock> block;
-        ASSERT_EQ(C2_OK, linearPool->fetchLinearBlock(
-                             bytesCount, {C2MemoryUsage::CPU_READ,
-                                          C2MemoryUsage::CPU_WRITE},
-                             &block));
+        ASSERT_EQ(C2_OK,
+                  linearPool->fetchLinearBlock(
+                          bytesCount, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block));
         ASSERT_TRUE(block);
         // Write View
         C2WriteView view = block->map().get();
@@ -365,27 +341,33 @@
     }
 }
 
-TEST_F(Codec2AudioEncHidlTest, validateCompName) {
-    if (mDisableTest) return;
+TEST_P(Codec2AudioEncHidlTest, validateCompName) {
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     ALOGV("Checks if the given component is a valid audio component");
     validateComponent(mComponent, mCompName, mDisableTest);
     ASSERT_EQ(mDisableTest, false);
 }
 
 class Codec2AudioEncEncodeTest
-    : public Codec2AudioEncHidlTest,
-      public ::testing::WithParamInterface<std::pair<bool, int32_t>> {
+    : public Codec2AudioEncHidlTestBase,
+      public ::testing::WithParamInterface<
+              std::tuple<std::string, std::string, std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
 };
 
 TEST_P(Codec2AudioEncEncodeTest, EncodeTest) {
     ALOGV("EncodeTest");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     char mURL[512];
-    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL);
-    bool signalEOS = GetParam().first;
+    bool signalEOS = !std::get<2>(GetParam()).compare("true");
     // Ratio w.r.t to mInputMaxBufSize
-    int32_t inputMaxBufRatio = GetParam().second;
+    int32_t inputMaxBufRatio = std::stoi(std::get<3>(GetParam()));
+    ;
 
     // Setting default sampleRate
     int32_t nChannels = 2;
@@ -414,10 +396,9 @@
         default:
             ASSERT_TRUE(false);
     }
-    int32_t samplesPerFrame =
-        ((mInputMaxBufSize / inputMaxBufRatio) / (nChannels * 2));
-    ALOGV("signalEOS %d mInputMaxBufSize %d samplesPerFrame %d", signalEOS,
-          mInputMaxBufSize, samplesPerFrame);
+    int32_t samplesPerFrame = ((mInputMaxBufSize / inputMaxBufRatio) / (nChannels * 2));
+    ALOGV("signalEOS %d mInputMaxBufSize %d samplesPerFrame %d", signalEOS, mInputMaxBufSize,
+          samplesPerFrame);
 
     if (!setupConfigParam(mComponent, nChannels, nSampleRate)) {
         std::cout << "[   WARN   ] Test Skipped \n";
@@ -429,26 +410,21 @@
     eleStream.open(mURL, std::ifstream::binary);
     ASSERT_EQ(eleStream.is_open(), true);
     ALOGV("mURL : %s", mURL);
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mLinearPool, eleStream, numFrames,
-                      samplesPerFrame, nChannels, nSampleRate, false,
-                      signalEOS));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(
+            mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices, mLinearPool,
+            eleStream, numFrames, samplesPerFrame, nChannels, nSampleRate, false, signalEOS));
 
     // If EOS is not sent, sending empty input with EOS flag
     if (!signalEOS) {
-        ASSERT_NO_FATAL_FAILURE(
-            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
-        ASSERT_NO_FATAL_FAILURE(
-            testInputBuffer(mComponent, mQueueLock, mWorkQueue,
-                            C2FrameData::FLAG_END_OF_STREAM, false));
+        ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
+        ASSERT_NO_FATAL_FAILURE(testInputBuffer(mComponent, mQueueLock, mWorkQueue,
+                                                C2FrameData::FLAG_END_OF_STREAM, false));
         numFrames += 1;
     }
 
     // blocking call to ensures application to Wait till all the inputs are
     // consumed
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
     eleStream.close();
     if (mFramesReceived != numFrames) {
         ALOGE("Input buffer count and Output buffer count mismatch");
@@ -465,18 +441,9 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-// EncodeTest with EOS / No EOS and inputMaxBufRatio
-// inputMaxBufRatio is ratio w.r.t. to mInputMaxBufSize
-INSTANTIATE_TEST_CASE_P(EncodeTest, Codec2AudioEncEncodeTest,
-                        ::testing::Values(std::make_pair(false, 1),
-                                          std::make_pair(false, 2),
-                                          std::make_pair(true, 1),
-                                          std::make_pair(true, 2)));
-
-
-TEST_F(Codec2AudioEncHidlTest, EOSTest) {
+TEST_P(Codec2AudioEncHidlTest, EOSTest) {
     description("Test empty input buffer with EOS flag");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     ASSERT_EQ(mComponent->start(), C2_OK);
 
     typedef std::unique_lock<std::mutex> ULock;
@@ -514,13 +481,13 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2AudioEncHidlTest, FlushTest) {
+TEST_P(Codec2AudioEncHidlTest, FlushTest) {
     description("Test Request for flush");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
     typedef std::unique_lock<std::mutex> ULock;
     char mURL[512];
-    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL);
 
     // Setting default configuration
@@ -570,29 +537,24 @@
     eleStream.open(mURL, std::ifstream::binary);
     ASSERT_EQ(eleStream.is_open(), true);
     ALOGV("mURL : %s", mURL);
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mLinearPool, eleStream, numFramesFlushed,
-                      samplesPerFrame, nChannels, nSampleRate));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mLinearPool, eleStream, numFramesFlushed,
+                                          samplesPerFrame, nChannels, nSampleRate));
     std::list<std::unique_ptr<C2Work>> flushedWork;
-    c2_status_t err =
-        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    c2_status_t err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
     ASSERT_EQ(err, C2_OK);
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
-            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                                                   (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
     uint64_t frameIndex;
     {
-        //Update mFlushedIndices based on the index received from flush()
+        // Update mFlushedIndices based on the index received from flush()
         ULock l(mQueueLock);
         for (std::unique_ptr<C2Work>& work : flushedWork) {
             ASSERT_NE(work, nullptr);
             frameIndex = work->input.ordinal.frameIndex.peeku();
             std::list<uint64_t>::iterator frameIndexIt =
-                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
-                          frameIndex);
-            if (!mFlushedIndices.empty() &&
-                (frameIndexIt != mFlushedIndices.end())) {
+                    std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) {
                 mFlushedIndices.erase(frameIndexIt);
                 work->input.buffers.clear();
                 work->worklets.clear();
@@ -601,29 +563,24 @@
         }
     }
     mFlushedIndices.clear();
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mLinearPool, eleStream,
-                      numFrames - numFramesFlushed, samplesPerFrame,
-                      nChannels, nSampleRate, true));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mLinearPool, eleStream,
+                                          numFrames - numFramesFlushed, samplesPerFrame, nChannels,
+                                          nSampleRate, true));
     eleStream.close();
-    err =
-        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
     ASSERT_EQ(err, C2_OK);
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
-            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                                                   (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
     {
-        //Update mFlushedIndices based on the index received from flush()
+        // Update mFlushedIndices based on the index received from flush()
         ULock l(mQueueLock);
         for (std::unique_ptr<C2Work>& work : flushedWork) {
             ASSERT_NE(work, nullptr);
             frameIndex = work->input.ordinal.frameIndex.peeku();
             std::list<uint64_t>::iterator frameIndexIt =
-                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
-                          frameIndex);
-            if (!mFlushedIndices.empty() &&
-                (frameIndexIt != mFlushedIndices.end())) {
+                    std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) {
                 mFlushedIndices.erase(frameIndexIt);
                 work->input.buffers.clear();
                 work->worklets.clear();
@@ -635,17 +592,39 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2AudioEncHidlTest, testing::ValuesIn(kTestParameters),
+                         android::hardware::PrintInstanceTupleNameToString<>);
+
+// EncodeTest with EOS / No EOS and inputMaxBufRatio
+// inputMaxBufRatio is ratio w.r.t. to mInputMaxBufSize
+INSTANTIATE_TEST_SUITE_P(EncodeTest, Codec2AudioEncEncodeTest,
+                         testing::ValuesIn(kEncodeTestParameters),
+                         android::hardware::PrintInstanceTupleNameToString<>);
+
 }  // anonymous namespace
 
 int main(int argc, char** argv) {
-    gEnv = new ComponentTestEnvironment();
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    int status = gEnv->initFromOptions(argc, argv);
-    if (status == 0) {
-        int status = RUN_ALL_TESTS();
-        LOG(INFO) << "C2 Test result = " << status;
+    kTestParameters = getTestParameters(C2Component::DOMAIN_AUDIO, C2Component::KIND_ENCODER);
+    for (auto params : kTestParameters) {
+        kEncodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "false", "1"));
+        kEncodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "false", "2"));
+        kEncodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "true", "1"));
+        kEncodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "true", "2"));
     }
-    return status;
+
+    // Set the resource directory based on command line args.
+    // Test will fail to set up if the argument is not set.
+    for (int i = 1; i < argc; i++) {
+        if (strcmp(argv[i], "-P") == 0 && i < argc - 1) {
+            sResourceDir = argv[i + 1];
+            break;
+        }
+    }
+
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
 }
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.xml b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.xml
new file mode 100644
index 0000000..2e37111
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/audio/VtsHalMediaC2V1_0TargetAudioEncTest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Runs VtsHalMediaC2V1_0TargetAudioEncTest.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file" key="vts_media_c2_v1_0_audio_enc_test" value="/data/local/tmp/vts_media_c2_v1_0_audio_enc_test" />
+
+        <!-- Files used for audio testing -->
+        <option name="push-file" key="bbb_raw_2ch_48khz_s16le.raw" value="/data/local/tmp/media/bbb_raw_2ch_48khz_s16le.raw" />
+        <option name="push-file" key="bbb_raw_1ch_8khz_s16le.raw" value="/data/local/tmp/media/bbb_raw_1ch_8khz_s16le.raw" />
+        <option name="push-file" key="bbb_raw_1ch_16khz_s16le.raw" value="/data/local/tmp/media/bbb_raw_1ch_16khz_s16le.raw" />
+        <option name="push-file" key="bbb_raw_2ch_48khz_s16le.raw" value="/data/local/tmp/media/bbb_raw_2ch_48khz_s16le.raw" />
+        <option name="push-file" key="bbb_raw_2ch_48khz_s16le.raw" value="/data/local/tmp/media/bbb_raw_2ch_48khz_s16le.raw" />
+
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="vts_media_c2_v1_0_audio_enc_test" />
+        <option name="native-test-flag" value="-P /data/local/tmp/media/" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/audio/media_c2_audio_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/audio/media_c2_audio_hidl_test_common.h
deleted file mode 100644
index 4d773ce..0000000
--- a/media/codec2/hidl/1.0/vts/functional/audio/media_c2_audio_hidl_test_common.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#ifndef MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
-#define MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
-
-
-#endif  // MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/functional/common/Android.bp b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
index 3b4e232..f9ec5ae 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/common/Android.bp
@@ -1,7 +1,7 @@
 cc_library_static {
     name: "VtsHalMediaC2V1_0CommonUtil",
     defaults: [
-        "Vts10HalTargetTestDefaults",
+        "VtsHalTargetTestDefaults",
         "libcodec2-hidl-client-defaults",
     ],
 
@@ -19,15 +19,19 @@
 cc_defaults {
     name: "VtsHalMediaC2V1_0Defaults",
     defaults: [
-        "Vts10HalTargetTestDefaults",
+        "VtsHalTargetTestDefaults",
         "libcodec2-hidl-client-defaults",
     ],
 
     static_libs: [
+        "libgtest",
         "VtsHalMediaC2V1_0CommonUtil",
     ],
 
     shared_libs: [
         "libcodec2_client",
     ],
+    test_suites: [
+        "vts",
+    ],
 }
diff --git a/media/codec2/hidl/1.0/vts/functional/common/README.md b/media/codec2/hidl/1.0/vts/functional/common/README.md
index f2f579c..ac510c5 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/README.md
+++ b/media/codec2/hidl/1.0/vts/functional/common/README.md
@@ -3,34 +3,22 @@
 ## master :
 Functionality of master is to enumerate all the Codec2 components available in C2 media service.
 
-usage: `VtsHalMediaC2V1_0TargetMasterTest -I default`
+usage: `atest VtsHalMediaC2V1_0TargetMasterTest`
 
 ## component :
 Functionality of component test is to validate common functionality across all the Codec2 components available in C2 media service. For a standard C2 component, these tests are expected to pass.
 
-usage: `VtsHalMediaC2V1_0TargetComponentTest -I software -C <comp name>`
-
-example: `VtsHalMediaC2V1_0TargetComponentTest -I software -C c2.android.vorbis.decoder`
+usage: `atest VtsHalMediaC2V1_0TargetComponentTest`
 
 ## audio :
 Functionality of audio test is to validate audio specific functionality of Codec2 components. The resource files for this test are taken from `frameworks/av/media/codec2/hidl/1.0/vts/functional/res`. The path to these files on the device can be specified with `-P`. (If the device path is omitted, `/data/local/tmp/media/` is the default value.)
 
-usage: `VtsHalMediaC2V1_0TargetAudioDecTest -I default -C <comp name> -P <path to resource files>`
+usage: `atest VtsHalMediaC2V1_0TargetAudioDecTest`
 
-usage: `VtsHalMediaC2V1_0TargetAudioEncTest -I software -C <comp name> -P <path to resource files>`
-
-example: `VtsHalMediaC2V1_0TargetAudioDecTest -I software -C c2.android.flac.decoder -P /data/local/tmp/media/`
-
-example: `VtsHalMediaC2V1_0TargetAudioEncTest -I software -C c2.android.opus.encoder -P /data/local/tmp/media/`
+usage: `atest VtsHalMediaC2V1_0TargetAudioEncTest`
 
 ## video :
 Functionality of video test is to validate video specific functionality of Codec2 components. The resource files for this test are taken from `frameworks/av/media/codec2/hidl/1.0/vts/functional/res`. The path to these files on the device can be specified with `-P`. (If the device path is omitted, `/data/local/tmp/media/` is the default value.)
 
-usage: `VtsHalMediaC2V1_0TargetVideoDecTest -I default -C <comp name> -P <path to resource files>`
-
-usage: `VtsHalMediaC2V1_0TargetVideoEncTest -I software -C <comp name> -P <path to resource files>`
-
-example: `VtsHalMediaC2V1_0TargetVideoDecTest -I software -C c2.android.avc.decoder -P /data/local/tmp/media/`
-
-example: `VtsHalMediaC2V1_0TargetVideoEncTest -I software -C c2.android.vp9.encoder -P /data/local/tmp/media/`
-
+usage: `atest VtsHalMediaC2V1_0TargetVideoDecTest`
+usage: `atest VtsHalMediaC2V1_0TargetVideoEncTest`
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
index 2f02913..5d4b001 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.cpp
@@ -22,16 +22,10 @@
 
 #include <android/hardware/media/c2/1.0/IComponentStore.h>
 
-void ComponentTestEnvironment::registerTestServices() {
-    registerTestService<::android::hardware::media::c2::V1_0::
-                        IComponentStore>();
-}
-
 // Test the codecs for NullBuffer, Empty Input Buffer with(out) flags set
-void testInputBuffer(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
-    uint32_t flags, bool isNullBuffer) {
+void testInputBuffer(const std::shared_ptr<android::Codec2Client::Component>& component,
+                     std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
+                     uint32_t flags, bool isNullBuffer) {
     std::unique_ptr<C2Work> work;
     {
         typedef std::unique_lock<std::mutex> ULock;
@@ -61,10 +55,8 @@
 }
 
 // Wait for all the inputs to be consumed by the plugin.
-void waitOnInputConsumption(std::mutex& queueLock,
-                            std::condition_variable& queueCondition,
-                            std::list<std::unique_ptr<C2Work>>& workQueue,
-                            size_t bufferCount) {
+void waitOnInputConsumption(std::mutex& queueLock, std::condition_variable& queueCondition,
+                            std::list<std::unique_ptr<C2Work>>& workQueue, size_t bufferCount) {
     typedef std::unique_lock<std::mutex> ULock;
     uint32_t queueSize;
     uint32_t maxRetry = 0;
@@ -85,29 +77,25 @@
 }
 
 // process onWorkDone received by Listener
-void workDone(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
-    std::mutex& queueLock, std::condition_variable& queueCondition,
-    std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
-    uint32_t& framesReceived) {
+void workDone(const std::shared_ptr<android::Codec2Client::Component>& component,
+              std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+              std::mutex& queueLock, std::condition_variable& queueCondition,
+              std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
+              uint32_t& framesReceived) {
     // handle configuration changes in work done
     if (work->worklets.front()->output.configUpdate.size() != 0) {
         ALOGV("Config Update");
         std::vector<std::unique_ptr<C2Param>> updates =
-            std::move(work->worklets.front()->output.configUpdate);
+                std::move(work->worklets.front()->output.configUpdate);
         std::vector<C2Param*> configParam;
         std::vector<std::unique_ptr<C2SettingResult>> failures;
         for (size_t i = 0; i < updates.size(); ++i) {
             C2Param* param = updates[i].get();
             if (param->index() == C2StreamInitDataInfo::output::PARAM_TYPE) {
                 csd = true;
-            } else if ((param->index() ==
-                        C2StreamSampleRateInfo::output::PARAM_TYPE) ||
-                       (param->index() ==
-                        C2StreamChannelCountInfo::output::PARAM_TYPE) ||
-                       (param->index() ==
-                        C2StreamPictureSizeInfo::output::PARAM_TYPE)) {
+            } else if ((param->index() == C2StreamSampleRateInfo::output::PARAM_TYPE) ||
+                       (param->index() == C2StreamChannelCountInfo::output::PARAM_TYPE) ||
+                       (param->index() == C2StreamPictureSizeInfo::output::PARAM_TYPE)) {
                 configParam.push_back(param);
             }
         }
@@ -116,8 +104,7 @@
     }
     if (work->worklets.front()->output.flags != C2FrameData::FLAG_INCOMPLETE) {
         framesReceived++;
-        eos = (work->worklets.front()->output.flags &
-               C2FrameData::FLAG_END_OF_STREAM) != 0;
+        eos = (work->worklets.front()->output.flags & C2FrameData::FLAG_END_OF_STREAM) != 0;
         auto frameIndexIt = std::find(flushedIndices.begin(), flushedIndices.end(),
                                       work->input.ordinal.frameIndex.peeku());
         ALOGV("WorkDone: frameID received %d",
@@ -143,3 +130,33 @@
 
     return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
 }
+
+// Return all test parameters, a list of tuple of <instance, component>
+const std::vector<std::tuple<std::string, std::string>>& getTestParameters() {
+    return getTestParameters(C2Component::DOMAIN_OTHER, C2Component::KIND_OTHER);
+}
+
+// Return all test parameters, a list of tuple of <instance, component> with matching domain and
+// kind.
+const std::vector<std::tuple<std::string, std::string>>& getTestParameters(
+        C2Component::domain_t domain, C2Component::kind_t kind) {
+    static std::vector<std::tuple<std::string, std::string>> parameters;
+
+    auto instances = android::Codec2Client::GetServiceNames();
+    for (std::string instance : instances) {
+        std::shared_ptr<android::Codec2Client> client =
+                android::Codec2Client::CreateFromService(instance.c_str());
+        std::vector<C2Component::Traits> components = client->listComponents();
+        for (C2Component::Traits traits : components) {
+            if (instance.compare(traits.owner)) continue;
+            if (domain != C2Component::DOMAIN_OTHER &&
+                (traits.domain != domain || traits.kind != kind)) {
+                continue;
+            }
+
+            parameters.push_back(std::make_tuple(instance, traits.name));
+        }
+    }
+
+    return parameters;
+}
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
index 23e332a..4b5e0a6 100644
--- a/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/functional/common/media_c2_hidl_test_common.h
@@ -22,31 +22,34 @@
 
 #include <codec2/hidl/client.h>
 #include <getopt.h>
+#include <gtest/gtest.h>
 #include <hidl/HidlSupport.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <chrono>
 
 #define MAX_RETRY 20
 #define TIME_OUT 400ms
 #define MAX_INPUT_BUFFERS 8
 
-using ::android::hardware::Void;
-using ::android::hardware::Return;
-using ::android::hardware::hidl_vec;
 using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using namespace ::std::chrono;
+
+static std::vector<std::tuple<std::string, std::string>> kTestParameters;
 
 /*
  * Handle Callback functions onWorkDone(), onTripped(),
  * onError(), onDeath(), onFramesRendered()
  */
 struct CodecListener : public android::Codec2Client::Listener {
-   public:
+  public:
     CodecListener(
-        const std::function<void(std::list<std::unique_ptr<C2Work>>& workItems)> fn =
-            nullptr)
+            const std::function<void(std::list<std::unique_ptr<C2Work>>& workItems)> fn = nullptr)
         : callBack(fn) {}
-    virtual void onWorkDone(
-        const std::weak_ptr<android::Codec2Client::Component>& comp,
-        std::list<std::unique_ptr<C2Work>>& workItems) override {
+    virtual void onWorkDone(const std::weak_ptr<android::Codec2Client::Component>& comp,
+                            std::list<std::unique_ptr<C2Work>>& workItems) override {
         /* TODO */
         ALOGD("onWorkDone called");
         (void)comp;
@@ -54,40 +57,34 @@
     }
 
     virtual void onTripped(
-        const std::weak_ptr<android::Codec2Client::Component>& comp,
-        const std::vector<std::shared_ptr<C2SettingResult>>& settingResults)
-        override {
+            const std::weak_ptr<android::Codec2Client::Component>& comp,
+            const std::vector<std::shared_ptr<C2SettingResult>>& settingResults) override {
         /* TODO */
         (void)comp;
         (void)settingResults;
     }
 
-    virtual void onError(
-        const std::weak_ptr<android::Codec2Client::Component>& comp,
-        uint32_t errorCode) override {
+    virtual void onError(const std::weak_ptr<android::Codec2Client::Component>& comp,
+                         uint32_t errorCode) override {
         /* TODO */
         (void)comp;
         ALOGD("onError called");
         if (errorCode != 0) ALOGE("Error : %u", errorCode);
     }
 
-    virtual void onDeath(
-        const std::weak_ptr<android::Codec2Client::Component>& comp) override {
+    virtual void onDeath(const std::weak_ptr<android::Codec2Client::Component>& comp) override {
         /* TODO */
         (void)comp;
     }
 
-    virtual void onInputBufferDone(
-        uint64_t frameIndex, size_t arrayIndex) override {
+    virtual void onInputBufferDone(uint64_t frameIndex, size_t arrayIndex) override {
         /* TODO */
         (void)frameIndex;
         (void)arrayIndex;
     }
 
-    virtual void onFrameRendered(
-        uint64_t bufferQueueId,
-        int32_t slotId,
-        int64_t timestampNs) override {
+    virtual void onFrameRendered(uint64_t bufferQueueId, int32_t slotId,
+                                 int64_t timestampNs) override {
         /* TODO */
         (void)bufferQueueId;
         (void)slotId;
@@ -99,96 +96,30 @@
     std::function<void(std::list<std::unique_ptr<C2Work>>& workItems)> callBack;
 };
 
-// A class for test environment setup
-class ComponentTestEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   private:
-    typedef ::testing::VtsHalHidlTargetTestEnvBase Super;
+// Return all test parameters, a list of tuple of <instance, component>.
+const std::vector<std::tuple<std::string, std::string>>& getTestParameters();
 
-   public:
-    virtual void registerTestServices() override;
-
-    ComponentTestEnvironment() : res("/data/local/tmp/media/") {}
-
-    void setComponent(const char* _component) { component = _component; }
-
-    void setInstance(const char* _instance) { instance = _instance; }
-
-    void setRes(const char* _res) { res = _res; }
-
-    const hidl_string getInstance() const { return instance; }
-
-    const hidl_string getComponent() const { return component; }
-
-    const hidl_string getRes() const { return res; }
-
-    int initFromOptions(int argc, char** argv) {
-        static struct option options[] = {
-            {"instance", required_argument, 0, 'I'},
-            {"component", required_argument, 0, 'C'},
-            {"res", required_argument, 0, 'P'},
-            {0, 0, 0, 0}};
-
-        while (true) {
-            int index = 0;
-            int c = getopt_long(argc, argv, "I:C:P:", options, &index);
-            if (c == -1) {
-                break;
-            }
-
-            switch (c) {
-                case 'I':
-                    setInstance(optarg);
-                    break;
-                case 'C':
-                    setComponent(optarg);
-                    break;
-                case 'P':
-                    setRes(optarg);
-                    break;
-                case '?':
-                    break;
-            }
-        }
-
-        if (optind < argc) {
-            fprintf(stderr,
-                    "unrecognized option: %s\n\n"
-                    "usage: %s <gtest options> <test options>\n\n"
-                    "test options are:\n\n"
-                    "-I, --instance: software for C2 components, else default\n"
-                    "-C, --component: C2 component to test\n"
-                    "-P, --res: Resource files directory location\n",
-                    argv[optind ?: 1], argv[0]);
-            return 2;
-        }
-        return 0;
-    }
-
-   private:
-    hidl_string instance;
-    hidl_string component;
-    hidl_string res;
-};
+// Return all test parameters, a list of tuple of <instance, component> with matching domain and
+// kind.
+const std::vector<std::tuple<std::string, std::string>>& getTestParameters(
+        C2Component::domain_t domain, C2Component::kind_t kind);
 
 /*
  * common functions declarations
  */
-void testInputBuffer(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
-    uint32_t flags, bool isNullBuffer);
+void testInputBuffer(const std::shared_ptr<android::Codec2Client::Component>& component,
+                     std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
+                     uint32_t flags, bool isNullBuffer);
 
-void waitOnInputConsumption(std::mutex& queueLock,
-                            std::condition_variable& queueCondition,
+void waitOnInputConsumption(std::mutex& queueLock, std::condition_variable& queueCondition,
                             std::list<std::unique_ptr<C2Work>>& workQueue,
                             size_t bufferCount = MAX_INPUT_BUFFERS);
 
-void workDone(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
-    std::mutex& queueLock, std::condition_variable& queueCondition,
-    std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
-    uint32_t& framesReceived);
+void workDone(const std::shared_ptr<android::Codec2Client::Component>& component,
+              std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+              std::mutex& queueLock, std::condition_variable& queueCondition,
+              std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
+              uint32_t& framesReceived);
 
 int64_t getNowUs();
 
diff --git a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
index 9dc541c..119ce14 100644
--- a/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/component/VtsHalMediaC2V1_0TargetComponentTest.cpp
@@ -19,11 +19,11 @@
 
 #include <android-base/logging.h>
 #include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
 
 #include <C2Config.h>
 #include <codec2/hidl/client.h>
 
-#include <VtsHalHidlTargetTestBase.h>
 #include "media_c2_hidl_test_common.h"
 
 /* Time_Out for start(), stop(), reset(), release(), flush(), queue() are
@@ -31,50 +31,45 @@
  * extra in case of timeout is 500ms, 1ms extra in case timeout is 1ms/5ms. All
  * timeout is calculated in us.
  */
-#define START_TIME_OUT                  550000
-#define STOP_TIME_OUT                   550000
-#define RESET_TIME_OUT                  550000
-#define RELEASE_TIME_OUT                550000
-#define FLUSH_TIME_OUT                  6000
-#define QUEUE_TIME_OUT                  2000
+#define START_TIME_OUT 550000
+#define STOP_TIME_OUT 550000
+#define RESET_TIME_OUT 550000
+#define RELEASE_TIME_OUT 550000
+#define FLUSH_TIME_OUT 6000
+#define QUEUE_TIME_OUT 2000
 
 // Time_Out for config(), query(), querySupportedParams() are defined in
 // hardware/interfaces/media/c2/1.0/IConfigurable.hal.
-#define CONFIG_TIME_OUT                 6000
-#define QUERY_TIME_OUT                  6000
-#define QUERYSUPPORTEDPARAMS_TIME_OUT   2000
+#define CONFIG_TIME_OUT 6000
+#define QUERY_TIME_OUT 6000
+#define QUERYSUPPORTEDPARAMS_TIME_OUT 2000
 
-#define CHECK_TIMEOUT(timeConsumed, TIME_OUT, FuncName)          \
-    if (timeConsumed > TIME_OUT) {                               \
-        ALOGW(                                                   \
-            "TIMED_OUT %s  timeConsumed=%" PRId64 " us is "      \
-            "greater than threshold %d us",                      \
-            FuncName, timeConsumed, TIME_OUT);                   \
+#define CHECK_TIMEOUT(timeConsumed, TIME_OUT, FuncName) \
+    if (timeConsumed > TIME_OUT) {                      \
+        ALOGW("TIMED_OUT %s  timeConsumed=%" PRId64     \
+              " us is "                                 \
+              "greater than threshold %d us",           \
+              FuncName, timeConsumed, TIME_OUT);        \
     }
 
-static ComponentTestEnvironment* gEnv = nullptr;
-
 namespace {
 
-// google.codec2 Component test setup
-class Codec2ComponentHidlTest : public ::testing::VtsHalHidlTargetTestBase {
-   private:
-    typedef ::testing::VtsHalHidlTargetTestBase Super;
+static std::vector<std::tuple<std::string, std::string, std::string, std::string>>
+        kInputTestParameters;
 
-   public:
+// google.codec2 Component test setup
+class Codec2ComponentHidlTestBase : public ::testing::Test {
+  public:
     virtual void SetUp() override {
-        Super::SetUp();
+        getParams();
         mEos = false;
-        mClient = android::Codec2Client::CreateFromService(
-            gEnv->getInstance().c_str());
+        mClient = android::Codec2Client::CreateFromService(mInstanceName.c_str());
         ASSERT_NE(mClient, nullptr);
-        mListener.reset(new CodecListener(
-            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
-                handleWorkDone(workItems);
-            }));
+        mListener.reset(new CodecListener([this](std::list<std::unique_ptr<C2Work>>& workItems) {
+            handleWorkDone(workItems);
+        }));
         ASSERT_NE(mListener, nullptr);
-        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
-                                 &mComponent);
+        mClient->createComponent(mComponentName.c_str(), mListener, &mComponent);
         ASSERT_NE(mComponent, nullptr);
         for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
             mWorkQueue.emplace_back(new C2Work);
@@ -90,8 +85,11 @@
             mComponent->release();
             mComponent = nullptr;
         }
-        Super::TearDown();
     }
+
+    // Get the test parameters from GetParam call.
+    virtual void getParams() {}
+
     // callback function to process onWorkDone received by Listener
     void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
         for (std::unique_ptr<C2Work>& work : workItems) {
@@ -99,12 +97,14 @@
                 bool mCsd = false;
                 uint32_t mFramesReceived = 0;
                 std::list<uint64_t> mFlushedIndices;
-                workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition,
-                         mWorkQueue, mEos, mCsd, mFramesReceived);
+                workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue,
+                         mEos, mCsd, mFramesReceived);
             }
         }
     }
 
+    std::string mInstanceName;
+    std::string mComponentName;
     bool mEos;
     std::mutex mQueueLock;
     std::condition_variable mQueueCondition;
@@ -114,14 +114,23 @@
     std::shared_ptr<android::Codec2Client::Listener> mListener;
     std::shared_ptr<android::Codec2Client::Component> mComponent;
 
-   protected:
+  protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
     }
 };
 
+class Codec2ComponentHidlTest
+    : public Codec2ComponentHidlTestBase,
+      public ::testing::WithParamInterface<std::tuple<std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
+};
+
 // Test Empty Flush
-TEST_F(Codec2ComponentHidlTest, EmptyFlush) {
+TEST_P(Codec2ComponentHidlTest, EmptyFlush) {
     ALOGV("Empty Flush Test");
     c2_status_t err = mComponent->start();
     ASSERT_EQ(err, C2_OK);
@@ -137,7 +146,7 @@
 }
 
 // Test Queue Empty Work
-TEST_F(Codec2ComponentHidlTest, QueueEmptyWork) {
+TEST_P(Codec2ComponentHidlTest, QueueEmptyWork) {
     ALOGV("Queue Empty Work Test");
     c2_status_t err = mComponent->start();
     ASSERT_EQ(err, C2_OK);
@@ -151,7 +160,7 @@
 }
 
 // Test Component Configuration
-TEST_F(Codec2ComponentHidlTest, Config) {
+TEST_P(Codec2ComponentHidlTest, Config) {
     ALOGV("Configuration Test");
 
     C2String name = mComponent->getName();
@@ -180,7 +189,7 @@
 }
 
 // Test Multiple Start Stop Reset Test
-TEST_F(Codec2ComponentHidlTest, MultipleStartStopReset) {
+TEST_P(Codec2ComponentHidlTest, MultipleStartStopReset) {
     ALOGV("Multiple Start Stop and Reset Test");
 
     for (size_t i = 0; i < MAX_RETRY; i++) {
@@ -202,21 +211,21 @@
 }
 
 // Test Component Release API
-TEST_F(Codec2ComponentHidlTest, MultipleRelease) {
+TEST_P(Codec2ComponentHidlTest, MultipleRelease) {
     ALOGV("Multiple Release Test");
     c2_status_t err = mComponent->start();
     ASSERT_EQ(err, C2_OK);
 
     // Query Component Domain Type
     std::vector<std::unique_ptr<C2Param>> queried;
-    err = mComponent->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
-                            C2_DONT_BLOCK, &queried);
+    err = mComponent->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE}, C2_DONT_BLOCK,
+                            &queried);
     EXPECT_NE(queried.size(), 0u);
 
     // Configure Component Domain
     std::vector<std::unique_ptr<C2SettingResult>> failures;
     C2PortMediaTypeSetting::input* portMediaType =
-        C2PortMediaTypeSetting::input::From(queried[0].get());
+            C2PortMediaTypeSetting::input::From(queried[0].get());
     err = mComponent->config({portMediaType}, C2_DONT_BLOCK, &failures);
     ASSERT_EQ(err, C2_OK);
     ASSERT_EQ(failures.size(), 0u);
@@ -226,40 +235,8 @@
     }
 }
 
-class Codec2ComponentInputTests : public Codec2ComponentHidlTest,
-        public ::testing::WithParamInterface<std::pair<uint32_t, bool> > {
-};
-
-TEST_P(Codec2ComponentInputTests, InputBufferTest) {
-    description("Tests for different inputs");
-
-    uint32_t flags = GetParam().first;
-    bool isNullBuffer = GetParam().second;
-    if (isNullBuffer) ALOGD("Testing for null input buffer with flag : %u", flags);
-    else ALOGD("Testing for empty input buffer with flag : %u", flags);
-    mEos = false;
-    ASSERT_EQ(mComponent->start(), C2_OK);
-    ASSERT_NO_FATAL_FAILURE(testInputBuffer(
-        mComponent, mQueueLock, mWorkQueue, flags, isNullBuffer));
-
-    ALOGD("Waiting for input consumption");
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
-
-    if (flags == C2FrameData::FLAG_END_OF_STREAM) ASSERT_EQ(mEos, true);
-    ASSERT_EQ(mComponent->stop(), C2_OK);
-    ASSERT_EQ(mComponent->reset(), C2_OK);
-}
-
-INSTANTIATE_TEST_CASE_P(NonStdInputs, Codec2ComponentInputTests, ::testing::Values(
-    std::make_pair(0, true),
-    std::make_pair(C2FrameData::FLAG_END_OF_STREAM, true),
-    std::make_pair(0, false),
-    std::make_pair(C2FrameData::FLAG_CODEC_CONFIG, false),
-    std::make_pair(C2FrameData::FLAG_END_OF_STREAM, false)));
-
 // Test API's Timeout
-TEST_F(Codec2ComponentHidlTest, Timeout) {
+TEST_P(Codec2ComponentHidlTest, Timeout) {
     ALOGV("Timeout Test");
     c2_status_t err = C2_OK;
 
@@ -285,10 +262,8 @@
     startTime = getNowUs();
     err = mComponent->querySupportedParams(&params);
     timeConsumed = getNowUs() - startTime;
-    CHECK_TIMEOUT(timeConsumed, QUERYSUPPORTEDPARAMS_TIME_OUT,
-                  "querySupportedParams()");
-    ALOGV("mComponent->querySupportedParams() timeConsumed=%" PRId64 " us",
-          timeConsumed);
+    CHECK_TIMEOUT(timeConsumed, QUERYSUPPORTEDPARAMS_TIME_OUT, "querySupportedParams()");
+    ALOGV("mComponent->querySupportedParams() timeConsumed=%" PRId64 " us", timeConsumed);
     ASSERT_EQ(err, C2_OK);
 
     std::vector<std::unique_ptr<C2Param>> queried;
@@ -301,8 +276,8 @@
         CHECK_TIMEOUT(timeConsumed, QUERY_TIME_OUT, "query()");
         EXPECT_NE(queried.size(), 0u);
         EXPECT_EQ(err, C2_OK);
-        ALOGV("mComponent->query() for %s timeConsumed=%" PRId64 " us",
-              p->name().c_str(), timeConsumed);
+        ALOGV("mComponent->query() for %s timeConsumed=%" PRId64 " us", p->name().c_str(),
+              timeConsumed);
 
         startTime = getNowUs();
         err = mComponent->config({queried[0].get()}, C2_DONT_BLOCK, &failures);
@@ -310,8 +285,8 @@
         CHECK_TIMEOUT(timeConsumed, CONFIG_TIME_OUT, "config()");
         ASSERT_EQ(err, C2_OK);
         ASSERT_EQ(failures.size(), 0u);
-        ALOGV("mComponent->config() for %s timeConsumed=%" PRId64 " us",
-              p->name().c_str(), timeConsumed);
+        ALOGV("mComponent->config() for %s timeConsumed=%" PRId64 " us", p->name().c_str(),
+              timeConsumed);
     }
 
     std::list<std::unique_ptr<C2Work>> workList;
@@ -340,22 +315,68 @@
     ALOGV("mComponent->release() timeConsumed=%" PRId64 " us", timeConsumed);
     CHECK_TIMEOUT(timeConsumed, RELEASE_TIME_OUT, "release()");
     ASSERT_EQ(err, C2_OK);
-
 }
 
+class Codec2ComponentInputTests
+    : public Codec2ComponentHidlTestBase,
+      public ::testing::WithParamInterface<
+              std::tuple<std::string, std::string, std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
+};
+
+TEST_P(Codec2ComponentInputTests, InputBufferTest) {
+    description("Tests for different inputs");
+
+    uint32_t flags = std::stol(std::get<2>(GetParam()));
+    bool isNullBuffer = !std::get<3>(GetParam()).compare("true");
+    if (isNullBuffer)
+        ALOGD("Testing for null input buffer with flag : %u", flags);
+    else
+        ALOGD("Testing for empty input buffer with flag : %u", flags);
+    mEos = false;
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    ASSERT_NO_FATAL_FAILURE(
+            testInputBuffer(mComponent, mQueueLock, mWorkQueue, flags, isNullBuffer));
+
+    ALOGD("Waiting for input consumption");
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+
+    if (flags == C2FrameData::FLAG_END_OF_STREAM) ASSERT_EQ(mEos, true);
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+    ASSERT_EQ(mComponent->reset(), C2_OK);
+}
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2ComponentHidlTest, testing::ValuesIn(kTestParameters),
+                         android::hardware::PrintInstanceTupleNameToString<>);
+
+INSTANTIATE_TEST_CASE_P(NonStdInputs, Codec2ComponentInputTests,
+                        testing::ValuesIn(kInputTestParameters),
+                        android::hardware::PrintInstanceTupleNameToString<>);
 }  // anonymous namespace
 
 // TODO: Add test for Invalid work,
 // TODO: Add test for Invalid states
 int main(int argc, char** argv) {
-    gEnv = new ComponentTestEnvironment();
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    int status = gEnv->initFromOptions(argc, argv);
-    if (status == 0) {
-        status = RUN_ALL_TESTS();
-        LOG(INFO) << "C2 Test result = " << status;
+    kTestParameters = getTestParameters();
+    for (auto params : kTestParameters) {
+        kInputTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "true"));
+        kInputTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params),
+                                std::to_string(C2FrameData::FLAG_END_OF_STREAM), "true"));
+        kInputTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "false"));
+        kInputTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params),
+                                std::to_string(C2FrameData::FLAG_CODEC_CONFIG), "false"));
+        kInputTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params),
+                                std::to_string(C2FrameData::FLAG_END_OF_STREAM), "false"));
     }
-    return status;
+
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
 }
diff --git a/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
index e88fbc7..fb1c291 100644
--- a/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/master/VtsHalMediaC2V1_0TargetMasterTest.cpp
@@ -19,30 +19,25 @@
 
 #include <android-base/logging.h>
 #include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 #include <codec2/hidl/client.h>
 
 #include <VtsHalHidlTargetTestBase.h>
 #include "media_c2_hidl_test_common.h"
 
-static ComponentTestEnvironment* gEnv = nullptr;
-
 namespace {
 
 // google.codec2 Master test setup
-class Codec2MasterHalTest : public ::testing::VtsHalHidlTargetTestBase {
-   private:
-    typedef ::testing::VtsHalHidlTargetTestBase Super;
-
-   public:
+class Codec2MasterHalTest : public ::testing::TestWithParam<std::string> {
+  public:
     virtual void SetUp() override {
-        Super::SetUp();
-        mClient = android::Codec2Client::CreateFromService(
-            gEnv->getInstance().c_str());
+        mClient = android::Codec2Client::CreateFromService(GetParam().c_str());
         ASSERT_NE(mClient, nullptr);
     }
 
-   protected:
+  protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
     }
@@ -58,15 +53,14 @@
 }
 
 // List Components
-TEST_F(Codec2MasterHalTest, ListComponents) {
+TEST_P(Codec2MasterHalTest, ListComponents) {
     ALOGV("ListComponents Test");
 
     C2String name = mClient->getName();
     EXPECT_NE(name.empty(), true) << "Invalid Codec2Client Name";
 
     // Get List of components from all known services
-    const std::vector<C2Component::Traits> listTraits =
-        mClient->ListComponents();
+    const std::vector<C2Component::Traits> listTraits = mClient->ListComponents();
 
     if (listTraits.size() == 0)
         ALOGE("Warning, ComponentInfo list empty");
@@ -79,24 +73,16 @@
             ASSERT_NE(listener, nullptr);
 
             // Create component from all known services
-            component = mClient->CreateComponentByName(
-                listTraits[i].name.c_str(), listener, &mClient);
-            ASSERT_NE(component, nullptr) << "Create component failed for "
-                                          << listTraits[i].name.c_str();
+            component =
+                    mClient->CreateComponentByName(listTraits[i].name.c_str(), listener, &mClient);
+            ASSERT_NE(component, nullptr)
+                    << "Create component failed for " << listTraits[i].name.c_str();
         }
     }
 }
 
 }  // anonymous namespace
 
-int main(int argc, char** argv) {
-    gEnv = new ComponentTestEnvironment();
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    int status = gEnv->initFromOptions(argc, argv);
-    if (status == 0) {
-        status = RUN_ALL_TESTS();
-        LOG(INFO) << "C2 Test result = " << status;
-    }
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2MasterHalTest,
+                         testing::ValuesIn(android::Codec2Client::GetServiceNames()),
+                         android::hardware::PrintInstanceNameToString);
diff --git a/media/codec2/hidl/1.0/vts/functional/video/Android.bp b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
index b737323..760f4da 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/Android.bp
+++ b/media/codec2/hidl/1.0/vts/functional/video/Android.bp
@@ -16,6 +16,7 @@
 
 cc_test {
     name: "VtsHalMediaC2V1_0TargetVideoDecTest",
+    stem: "vts_media_c2_v1_0_video_dec_test",
     defaults: ["VtsHalMediaC2V1_0Defaults"],
     srcs: ["VtsHalMediaC2V1_0TargetVideoDecTest.cpp"],
     header_libs: [
@@ -26,11 +27,16 @@
         "libgui",
         "libutils",
     ],
+    data: [":media_c2_v1_video_decode_res"],
+    test_config: "VtsHalMediaC2V1_0TargetVideoDecTest.xml",
 }
 
 cc_test {
     name: "VtsHalMediaC2V1_0TargetVideoEncTest",
+    stem: "vts_media_c2_v1_0_video_enc_test",
     defaults: ["VtsHalMediaC2V1_0Defaults"],
     srcs: ["VtsHalMediaC2V1_0TargetVideoEncTest.cpp"],
+    data: [":media_c2_v1_video_encode_res"],
+    test_config: "VtsHalMediaC2V1_0TargetVideoEncTest.xml",
 }
 
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
index 256603c..ec3fd7b 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.cpp
@@ -19,15 +19,16 @@
 
 #include <android-base/logging.h>
 #include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
 #include <stdio.h>
 #include <fstream>
 
-#include <codec2/hidl/client.h>
 #include <C2AllocatorIon.h>
-#include <C2Config.h>
-#include <C2Debug.h>
 #include <C2Buffer.h>
 #include <C2BufferPriv.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <codec2/hidl/client.h>
 #include <gui/BufferQueue.h>
 #include <gui/IConsumerListener.h>
 #include <gui/IProducerListener.h>
@@ -35,9 +36,8 @@
 
 using android::C2AllocatorIon;
 
-#include <VtsHalHidlTargetTestBase.h>
-#include "media_c2_video_hidl_test_common.h"
 #include "media_c2_hidl_test_common.h"
+#include "media_c2_video_hidl_test_common.h"
 
 struct FrameInfo {
     int bytesCount;
@@ -45,61 +45,47 @@
     int64_t timestamp;
 };
 
+static std::vector<std::tuple<std::string, std::string, std::string, std::string>>
+        kDecodeTestParameters;
+
+// Resource directory
+static std::string sResourceDir = "";
+
 class LinearBuffer : public C2Buffer {
-   public:
+  public:
     explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block)
-        : C2Buffer(
-              {block->share(block->offset(), block->size(), ::C2Fence())}) {}
+        : C2Buffer({block->share(block->offset(), block->size(), ::C2Fence())}) {}
 
     explicit LinearBuffer(const std::shared_ptr<C2LinearBlock>& block, size_t size)
-        : C2Buffer(
-              {block->share(block->offset(), size, ::C2Fence())}) {}
+        : C2Buffer({block->share(block->offset(), size, ::C2Fence())}) {}
 };
 
-static ComponentTestEnvironment* gEnv = nullptr;
-
 namespace {
 
-class Codec2VideoDecHidlTest : public ::testing::VtsHalHidlTargetTestBase {
-   private:
-    typedef ::testing::VtsHalHidlTargetTestBase Super;
-
-   public:
-    ::std::string getTestCaseInfo() const override {
-        return ::std::string() +
-                "Component: " + gEnv->getComponent().c_str() + " | " +
-                "Instance: " + gEnv->getInstance().c_str() + " | " +
-                "Res: " + gEnv->getRes().c_str();
-    }
-
+class Codec2VideoDecHidlTestBase : public ::testing::Test {
+  public:
     // google.codec2 Video test setup
     virtual void SetUp() override {
-        Super::SetUp();
+        getParams();
         mDisableTest = false;
         ALOGV("Codec2VideoDecHidlTest SetUp");
         mClient = android::Codec2Client::CreateFromService(
-            gEnv->getInstance().c_str(),
-            !bool(android::Codec2Client::CreateFromService("default", true)));
+                mInstanceName.c_str(),
+                !bool(android::Codec2Client::CreateFromService("default", true)));
         ASSERT_NE(mClient, nullptr);
-        mListener.reset(new CodecListener(
-            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
-                handleWorkDone(workItems);
-            }));
+        mListener.reset(new CodecListener([this](std::list<std::unique_ptr<C2Work>>& workItems) {
+            handleWorkDone(workItems);
+        }));
         ASSERT_NE(mListener, nullptr);
         for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
             mWorkQueue.emplace_back(new C2Work);
         }
-        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
-                                 &mComponent);
+        mClient->createComponent(mComponentName, mListener, &mComponent);
         ASSERT_NE(mComponent, nullptr);
 
-        std::shared_ptr<C2AllocatorStore> store =
-            android::GetCodec2PlatformAllocatorStore();
-        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR,
-                                       &mLinearAllocator),
-                 C2_OK);
-        mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator,
-                                                          mBlockPoolId++);
+        std::shared_ptr<C2AllocatorStore> store = android::GetCodec2PlatformAllocatorStore();
+        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &mLinearAllocator), C2_OK);
+        mLinearPool = std::make_shared<C2PooledBlockPool>(mLinearAllocator, mBlockPoolId++);
         ASSERT_NE(mLinearPool, nullptr);
 
         mCompName = unknown_comp;
@@ -109,17 +95,15 @@
         };
 
         const StringToName kStringToName[] = {
-            {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
-            {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9}, {"av1", av1},
+                {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
+                {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},     {"av1", av1},
         };
 
-        const size_t kNumStringToName =
-            sizeof(kStringToName) / sizeof(kStringToName[0]);
+        const size_t kNumStringToName = sizeof(kStringToName) / sizeof(kStringToName[0]);
 
         // Find the component type
-        std::string comp = std::string(gEnv->getComponent());
         for (size_t i = 0; i < kNumStringToName; ++i) {
-            if (strcasestr(comp.c_str(), kStringToName[i].Name)) {
+            if (strcasestr(mComponentName.c_str(), kStringToName[i].Name)) {
                 mCompName = kStringToName[i].CompName;
                 break;
             }
@@ -131,7 +115,7 @@
         if (mCompName == unknown_comp) mDisableTest = true;
 
         C2SecureModeTuning secureModeTuning{};
-        mComponent->query({ &secureModeTuning }, {}, C2_MAY_BLOCK, nullptr);
+        mComponent->query({&secureModeTuning}, {}, C2_MAY_BLOCK, nullptr);
         if (secureModeTuning.value == C2Config::SM_READ_PROTECTED) {
             mDisableTest = true;
         }
@@ -145,9 +129,11 @@
             mComponent->release();
             mComponent = nullptr;
         }
-        Super::TearDown();
     }
 
+    // Get the test parameters from GetParam call.
+    virtual void getParams() {}
+
     // callback function to process onWorkDone received by Listener
     void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
         for (std::unique_ptr<C2Work>& work : workItems) {
@@ -157,13 +143,10 @@
                 typedef std::unique_lock<std::mutex> ULock;
                 bool codecConfig = ((work->worklets.front()->output.flags &
                                      C2FrameData::FLAG_CODEC_CONFIG) != 0);
-                if (!codecConfig &&
-                    !work->worklets.front()->output.buffers.empty()) {
-                    EXPECT_GE(
-                        (work->worklets.front()->output.ordinal.timestamp.peeku()),
-                        mTimestampUs);
-                    mTimestampUs =
-                        work->worklets.front()->output.ordinal.timestamp.peeku();
+                if (!codecConfig && !work->worklets.front()->output.buffers.empty()) {
+                    EXPECT_GE((work->worklets.front()->output.ordinal.timestamp.peeku()),
+                              mTimestampUs);
+                    mTimestampUs = work->worklets.front()->output.ordinal.timestamp.peeku();
 
                     ULock l(mQueueLock);
                     if (mTimestampDevTest) {
@@ -179,8 +162,7 @@
                         }
                         if (tsHit == false) {
                             if (mTimestampUslist.empty() == false) {
-                                EXPECT_EQ(tsHit, true)
-                                    << "TimeStamp not recognized";
+                                EXPECT_EQ(tsHit, true) << "TimeStamp not recognized";
                             } else {
                                 std::cout << "[   INFO   ] Received non-zero "
                                              "output / TimeStamp not recognized \n";
@@ -189,9 +171,8 @@
                     }
                 }
                 bool mCsd;
-                workDone(mComponent, work, mFlushedIndices, mQueueLock,
-                         mQueueCondition, mWorkQueue, mEos, mCsd,
-                         mFramesReceived);
+                workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue,
+                         mEos, mCsd, mFramesReceived);
                 (void)mCsd;
             }
         }
@@ -209,6 +190,9 @@
         unknown_comp,
     };
 
+    std::string mInstanceName;
+    std::string mComponentName;
+
     bool mEos;
     bool mDisableTest;
     bool mTimestampDevTest;
@@ -229,15 +213,23 @@
     std::shared_ptr<android::Codec2Client::Listener> mListener;
     std::shared_ptr<android::Codec2Client::Component> mComponent;
 
-   protected:
+  protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
     }
 };
 
-void validateComponent(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    Codec2VideoDecHidlTest::standardComp compName, bool& disableTest) {
+class Codec2VideoDecHidlTest
+    : public Codec2VideoDecHidlTestBase,
+      public ::testing::WithParamInterface<std::tuple<std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
+};
+
+void validateComponent(const std::shared_ptr<android::Codec2Client::Component>& component,
+                       Codec2VideoDecHidlTest::standardComp compName, bool& disableTest) {
     // Validate its a C2 Component
     if (component->getName().find("c2") == std::string::npos) {
         ALOGE("Not a c2 component");
@@ -252,14 +244,12 @@
         return;
     }
     std::vector<std::unique_ptr<C2Param>> queried;
-    c2_status_t c2err =
-        component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
-                         C2_DONT_BLOCK, &queried);
+    c2_status_t c2err = component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+                                         C2_DONT_BLOCK, &queried);
     if (c2err != C2_OK && queried.size() == 0) {
         ALOGE("Query media type failed => %d", c2err);
     } else {
-        std::string inputDomain =
-            ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
+        std::string inputDomain = ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
         if (inputDomain.find("video/") == std::string::npos) {
             ALOGE("Expected Video Component");
             disableTest = true;
@@ -279,8 +269,8 @@
 // number of elementary streams per component
 #define STREAM_COUNT 2
 // LookUpTable of clips and metadata for component testing
-void GetURLForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL,
-                        char* info, size_t streamIndex = 1) {
+void GetURLForComponent(Codec2VideoDecHidlTest::standardComp comp, char* mURL, char* info,
+                        size_t streamIndex = 1) {
     struct CompToURL {
         Codec2VideoDecHidlTest::standardComp comp;
         const char mURL[STREAM_COUNT][512];
@@ -289,42 +279,30 @@
     ASSERT_TRUE(streamIndex < STREAM_COUNT);
 
     static const CompToURL kCompToURL[] = {
-        {Codec2VideoDecHidlTest::standardComp::avc,
-         {"bbb_avc_176x144_300kbps_60fps.h264",
-          "bbb_avc_640x360_768kbps_30fps.h264"},
-         {"bbb_avc_176x144_300kbps_60fps.info",
-          "bbb_avc_640x360_768kbps_30fps.info"}},
-        {Codec2VideoDecHidlTest::standardComp::hevc,
-         {"bbb_hevc_176x144_176kbps_60fps.hevc",
-          "bbb_hevc_640x360_1600kbps_30fps.hevc"},
-         {"bbb_hevc_176x144_176kbps_60fps.info",
-          "bbb_hevc_640x360_1600kbps_30fps.info"}},
-        {Codec2VideoDecHidlTest::standardComp::mpeg2,
-         {"bbb_mpeg2_176x144_105kbps_25fps.m2v",
-          "bbb_mpeg2_352x288_1mbps_60fps.m2v"},
-         {"bbb_mpeg2_176x144_105kbps_25fps.info",
-          "bbb_mpeg2_352x288_1mbps_60fps.info"}},
-        {Codec2VideoDecHidlTest::standardComp::h263,
-         {"", "bbb_h263_352x288_300kbps_12fps.h263"},
-         {"", "bbb_h263_352x288_300kbps_12fps.info"}},
-        {Codec2VideoDecHidlTest::standardComp::mpeg4,
-         {"", "bbb_mpeg4_352x288_512kbps_30fps.m4v"},
-         {"", "bbb_mpeg4_352x288_512kbps_30fps.info"}},
-        {Codec2VideoDecHidlTest::standardComp::vp8,
-         {"bbb_vp8_176x144_240kbps_60fps.vp8",
-          "bbb_vp8_640x360_2mbps_30fps.vp8"},
-         {"bbb_vp8_176x144_240kbps_60fps.info",
-          "bbb_vp8_640x360_2mbps_30fps.info"}},
-        {Codec2VideoDecHidlTest::standardComp::vp9,
-         {"bbb_vp9_176x144_285kbps_60fps.vp9",
-          "bbb_vp9_640x360_1600kbps_30fps.vp9"},
-         {"bbb_vp9_176x144_285kbps_60fps.info",
-          "bbb_vp9_640x360_1600kbps_30fps.info"}},
-        {Codec2VideoDecHidlTest::standardComp::av1,
-         {"bbb_av1_640_360.av1",
-          "bbb_av1_176_144.av1"},
-         {"bbb_av1_640_360.info",
-          "bbb_av1_176_144.info"}},
+            {Codec2VideoDecHidlTest::standardComp::avc,
+             {"bbb_avc_176x144_300kbps_60fps.h264", "bbb_avc_640x360_768kbps_30fps.h264"},
+             {"bbb_avc_176x144_300kbps_60fps.info", "bbb_avc_640x360_768kbps_30fps.info"}},
+            {Codec2VideoDecHidlTest::standardComp::hevc,
+             {"bbb_hevc_176x144_176kbps_60fps.hevc", "bbb_hevc_640x360_1600kbps_30fps.hevc"},
+             {"bbb_hevc_176x144_176kbps_60fps.info", "bbb_hevc_640x360_1600kbps_30fps.info"}},
+            {Codec2VideoDecHidlTest::standardComp::mpeg2,
+             {"bbb_mpeg2_176x144_105kbps_25fps.m2v", "bbb_mpeg2_352x288_1mbps_60fps.m2v"},
+             {"bbb_mpeg2_176x144_105kbps_25fps.info", "bbb_mpeg2_352x288_1mbps_60fps.info"}},
+            {Codec2VideoDecHidlTest::standardComp::h263,
+             {"", "bbb_h263_352x288_300kbps_12fps.h263"},
+             {"", "bbb_h263_352x288_300kbps_12fps.info"}},
+            {Codec2VideoDecHidlTest::standardComp::mpeg4,
+             {"", "bbb_mpeg4_352x288_512kbps_30fps.m4v"},
+             {"", "bbb_mpeg4_352x288_512kbps_30fps.info"}},
+            {Codec2VideoDecHidlTest::standardComp::vp8,
+             {"bbb_vp8_176x144_240kbps_60fps.vp8", "bbb_vp8_640x360_2mbps_30fps.vp8"},
+             {"bbb_vp8_176x144_240kbps_60fps.info", "bbb_vp8_640x360_2mbps_30fps.info"}},
+            {Codec2VideoDecHidlTest::standardComp::vp9,
+             {"bbb_vp9_176x144_285kbps_60fps.vp9", "bbb_vp9_640x360_1600kbps_30fps.vp9"},
+             {"bbb_vp9_176x144_285kbps_60fps.info", "bbb_vp9_640x360_1600kbps_30fps.info"}},
+            {Codec2VideoDecHidlTest::standardComp::av1,
+             {"bbb_av1_640_360.av1", "bbb_av1_176_144.av1"},
+             {"bbb_av1_640_360.info", "bbb_av1_176_144.info"}},
     };
 
     for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
@@ -337,13 +315,11 @@
 }
 
 void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
-                   std::mutex &queueLock, std::condition_variable& queueCondition,
+                   std::mutex& queueLock, std::condition_variable& queueCondition,
                    std::list<std::unique_ptr<C2Work>>& workQueue,
-                   std::list<uint64_t>& flushedIndices,
-                   std::shared_ptr<C2BlockPool>& linearPool,
-                   std::ifstream& eleStream,
-                   android::Vector<FrameInfo>* Info,
-                   int offset, int range, bool signalEOS = true) {
+                   std::list<uint64_t>& flushedIndices, std::shared_ptr<C2BlockPool>& linearPool,
+                   std::ifstream& eleStream, android::Vector<FrameInfo>* Info, int offset,
+                   int range, bool signalEOS = true) {
     typedef std::unique_lock<std::mutex> ULock;
     int frameID = offset;
     int maxRetry = 0;
@@ -367,8 +343,7 @@
         }
         int64_t timestamp = (*Info)[frameID].timestamp;
         if ((*Info)[frameID].flags) flags = (1 << ((*Info)[frameID].flags - 1));
-        if (signalEOS && ((frameID == (int)Info->size() - 1) ||
-                          (frameID == (offset + range - 1))))
+        if (signalEOS && ((frameID == (int)Info->size() - 1) || (frameID == (offset + range - 1))))
             flags |= C2FrameData::FLAG_END_OF_STREAM;
 
         work->input.flags = (C2FrameData::flags_t)flags;
@@ -390,10 +365,9 @@
         auto alignedSize = ALIGN(size, PAGE_SIZE);
         if (size) {
             std::shared_ptr<C2LinearBlock> block;
-            ASSERT_EQ(C2_OK,
-                    linearPool->fetchLinearBlock(
-                        alignedSize, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
-                        &block));
+            ASSERT_EQ(C2_OK, linearPool->fetchLinearBlock(
+                                     alignedSize,
+                                     {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block));
             ASSERT_TRUE(block);
 
             // Write View
@@ -424,16 +398,16 @@
     }
 }
 
-TEST_F(Codec2VideoDecHidlTest, validateCompName) {
-    if (mDisableTest) return;
+TEST_P(Codec2VideoDecHidlTest, validateCompName) {
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     ALOGV("Checks if the given component is a valid video component");
     validateComponent(mComponent, mCompName, mDisableTest);
     ASSERT_EQ(mDisableTest, false);
 }
 
-TEST_F(Codec2VideoDecHidlTest, configureTunnel) {
+TEST_P(Codec2VideoDecHidlTest, configureTunnel) {
     description("Attempts to configure tunneling");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     ALOGV("Checks if the component can be configured for tunneling");
     native_handle_t* sidebandStream{};
     c2_status_t err = mComponent->configureVideoTunnel(0, &sidebandStream);
@@ -449,7 +423,7 @@
     BufferQueue::createBufferQueue(&producer, &consumer);
 
     class DummyConsumerListener : public BnConsumerListener {
-    public:
+      public:
         DummyConsumerListener() : BnConsumerListener() {}
         void onFrameAvailable(const BufferItem&) override {}
         void onBuffersReleased() override {}
@@ -458,37 +432,39 @@
     consumer->consumerConnect(new DummyConsumerListener(), false);
 
     class DummyProducerListener : public BnProducerListener {
-    public:
+      public:
         DummyProducerListener() : BnProducerListener() {}
         virtual void onBufferReleased() override {}
         virtual bool needsReleaseNotify() override { return false; }
         virtual void onBuffersDiscarded(const std::vector<int32_t>&) override {}
     };
     IGraphicBufferProducer::QueueBufferOutput qbo{};
-    producer->connect(new DummyProducerListener(),
-                      NATIVE_WINDOW_API_MEDIA,
-                      false,
-                      &qbo);
+    producer->connect(new DummyProducerListener(), NATIVE_WINDOW_API_MEDIA, false, &qbo);
 
     ASSERT_EQ(producer->setSidebandStream(nativeHandle), NO_ERROR);
 }
 
 class Codec2VideoDecDecodeTest
-    : public Codec2VideoDecHidlTest,
-      public ::testing::WithParamInterface<std::pair<int32_t, bool>> {
+    : public Codec2VideoDecHidlTestBase,
+      public ::testing::WithParamInterface<
+              std::tuple<std::string, std::string, std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
 };
 
 // Bitstream Test
 TEST_P(Codec2VideoDecDecodeTest, DecodeTest) {
     description("Decodes input file");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
-    uint32_t streamIndex = GetParam().first;
-    bool signalEOS = GetParam().second;
+    uint32_t streamIndex = std::stoi(std::get<2>(GetParam()));
+    bool signalEOS = !std::get<2>(GetParam()).compare("true");
     char mURL[512], info[512];
     std::ifstream eleStream, eleInfo;
-    strcpy(mURL, gEnv->getRes().c_str());
-    strcpy(info, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
+    strcpy(info, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL, info, streamIndex);
 
     eleInfo.open(info);
@@ -504,10 +480,8 @@
         if (!(eleInfo >> bytesCount)) break;
         eleInfo >> flags;
         eleInfo >> timestamp;
-        bool codecConfig = flags ?
-            ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
-        if (mTimestampDevTest && !codecConfig)
-            mTimestampUslist.push_back(timestamp);
+        bool codecConfig = flags ? ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+        if (mTimestampDevTest && !codecConfig) mTimestampUslist.push_back(timestamp);
         Info.push_back({bytesCount, flags, timestamp});
     }
     eleInfo.close();
@@ -519,52 +493,42 @@
     ALOGV("mURL : %s", mURL);
     eleStream.open(mURL, std::ifstream::binary);
     ASSERT_EQ(eleStream.is_open(), true);
-    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
-        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
-        mLinearPool, eleStream, &Info, 0, (int)Info.size(), signalEOS));
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mLinearPool, eleStream, &Info, 0,
+                                          (int)Info.size(), signalEOS));
 
     // If EOS is not sent, sending empty input with EOS flag
     size_t infoSize = Info.size();
     if (!signalEOS) {
-        ASSERT_NO_FATAL_FAILURE(
-            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
-        ASSERT_NO_FATAL_FAILURE(
-            testInputBuffer(mComponent, mQueueLock, mWorkQueue,
-                            C2FrameData::FLAG_END_OF_STREAM, false));
+        ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
+        ASSERT_NO_FATAL_FAILURE(testInputBuffer(mComponent, mQueueLock, mWorkQueue,
+                                                C2FrameData::FLAG_END_OF_STREAM, false));
         infoSize += 1;
     }
     // blocking call to ensures application to Wait till all the inputs are
     // consumed
     if (!mEos) {
         ALOGV("Waiting for input consumption");
-        ASSERT_NO_FATAL_FAILURE(
-            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+        ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
     }
 
     eleStream.close();
     if (mFramesReceived != infoSize) {
         ALOGE("Input buffer count and Output buffer count mismatch");
-        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
-              infoSize);
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, infoSize);
         ASSERT_TRUE(false);
     }
 
     if (mTimestampDevTest) EXPECT_EQ(mTimestampUslist.empty(), true);
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
-// DecodeTest with StreamIndex and EOS / No EOS
-INSTANTIATE_TEST_CASE_P(StreamIndexAndEOS, Codec2VideoDecDecodeTest,
-                        ::testing::Values(std::make_pair(0, false),
-                                          std::make_pair(0, true),
-                                          std::make_pair(1, false),
-                                          std::make_pair(1, true)));
 
 // Adaptive Test
-TEST_F(Codec2VideoDecHidlTest, AdaptiveDecodeTest) {
+TEST_P(Codec2VideoDecHidlTest, AdaptiveDecodeTest) {
     description("Adaptive Decode Test");
-    if (mDisableTest) return;
-    if (!(mCompName == avc || mCompName == hevc || mCompName == vp8 ||
-          mCompName == vp9 || mCompName == mpeg2))
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
+    if (!(mCompName == avc || mCompName == hevc || mCompName == vp8 || mCompName == vp9 ||
+          mCompName == mpeg2))
         return;
 
     typedef std::unique_lock<std::mutex> ULock;
@@ -578,8 +542,8 @@
         char mURL[512], info[512];
         std::ifstream eleStream, eleInfo;
 
-        strcpy(mURL, gEnv->getRes().c_str());
-        strcpy(info, gEnv->getRes().c_str());
+        strcpy(mURL, sResourceDir.c_str());
+        strcpy(info, sResourceDir.c_str());
         GetURLForComponent(mCompName, mURL, info, i % STREAM_COUNT);
 
         eleInfo.open(info);
@@ -594,13 +558,12 @@
             eleInfo >> timestamp;
             timestamp += timestampOffset;
             Info.push_back({bytesCount, flags, timestamp});
-            bool codecConfig = flags ?
-                ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+            bool codecConfig =
+                    flags ? ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
 
             {
                 ULock l(mQueueLock);
-                if (mTimestampDevTest && !codecConfig)
-                    mTimestampUslist.push_back(timestamp);
+                if (mTimestampDevTest && !codecConfig) mTimestampUslist.push_back(timestamp);
             }
             if (timestampMax < timestamp) timestampMax = timestamp;
         }
@@ -612,10 +575,9 @@
         ALOGV("mURL : %s", mURL);
         eleStream.open(mURL, std::ifstream::binary);
         ASSERT_EQ(eleStream.is_open(), true);
-        ASSERT_NO_FATAL_FAILURE(
-            decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                          mFlushedIndices, mLinearPool, eleStream, &Info,
-                          offset, (int)(Info.size() - offset), false));
+        ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                              mFlushedIndices, mLinearPool, eleStream, &Info,
+                                              offset, (int)(Info.size() - offset), false));
 
         eleStream.close();
         offset = (int)Info.size();
@@ -650,13 +612,11 @@
     // blocking call to ensures application to Wait till all the inputs are
     // consumed
     ALOGV("Waiting for input consumption");
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
 
     if (mFramesReceived != ((Info.size()) + 1)) {
         ALOGE("Input buffer count and Output buffer count mismatch");
-        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
-              Info.size() + 1);
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, Info.size() + 1);
         ASSERT_TRUE(false);
     }
 
@@ -664,15 +624,15 @@
 }
 
 // thumbnail test
-TEST_F(Codec2VideoDecHidlTest, ThumbnailTest) {
+TEST_P(Codec2VideoDecHidlTest, ThumbnailTest) {
     description("Test Request for thumbnail");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
     char mURL[512], info[512];
     std::ifstream eleStream, eleInfo;
 
-    strcpy(mURL, gEnv->getRes().c_str());
-    strcpy(info, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
+    strcpy(info, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL, info);
 
     eleInfo.open(info);
@@ -703,11 +663,10 @@
         } while (!(flags & SYNC_FRAME));
         eleStream.open(mURL, std::ifstream::binary);
         ASSERT_EQ(eleStream.is_open(), true);
-        ASSERT_NO_FATAL_FAILURE(decodeNFrames(
-            mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-            mFlushedIndices, mLinearPool, eleStream, &Info, 0, j + 1));
-        ASSERT_NO_FATAL_FAILURE(
-            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+        ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                              mFlushedIndices, mLinearPool, eleStream, &Info, 0,
+                                              j + 1));
+        ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
         eleStream.close();
         EXPECT_GE(mFramesReceived, 1U);
         ASSERT_EQ(mEos, true);
@@ -716,9 +675,9 @@
     ASSERT_EQ(mComponent->release(), C2_OK);
 }
 
-TEST_F(Codec2VideoDecHidlTest, EOSTest) {
+TEST_P(Codec2VideoDecHidlTest, EOSTest) {
     description("Test empty input buffer with EOS flag");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     typedef std::unique_lock<std::mutex> ULock;
     ASSERT_EQ(mComponent->start(), C2_OK);
     std::unique_ptr<C2Work> work;
@@ -756,16 +715,16 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2VideoDecHidlTest, FlushTest) {
+TEST_P(Codec2VideoDecHidlTest, FlushTest) {
     description("Tests Flush calls");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     typedef std::unique_lock<std::mutex> ULock;
     ASSERT_EQ(mComponent->start(), C2_OK);
     char mURL[512], info[512];
     std::ifstream eleStream, eleInfo;
 
-    strcpy(mURL, gEnv->getRes().c_str());
-    strcpy(info, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
+    strcpy(info, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL, info);
 
     eleInfo.open(info);
@@ -790,28 +749,24 @@
     // frame after this so that the below section can be covered for all
     // components
     uint32_t numFramesFlushed = 128;
-    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
-        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
-        mLinearPool, eleStream, &Info, 0, numFramesFlushed, false));
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mLinearPool, eleStream, &Info, 0,
+                                          numFramesFlushed, false));
     // flush
     std::list<std::unique_ptr<C2Work>> flushedWork;
-    c2_status_t err =
-        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    c2_status_t err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
     ASSERT_EQ(err, C2_OK);
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
-                               (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                                                   (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
 
     {
         // Update mFlushedIndices based on the index received from flush()
         ULock l(mQueueLock);
         for (std::unique_ptr<C2Work>& work : flushedWork) {
             ASSERT_NE(work, nullptr);
-            auto frameIndexIt =
-                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
-                          work->input.ordinal.frameIndex.peeku());
-            if (!mFlushedIndices.empty() &&
-                (frameIndexIt != mFlushedIndices.end())) {
+            auto frameIndexIt = std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
+                                          work->input.ordinal.frameIndex.peeku());
+            if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) {
                 mFlushedIndices.erase(frameIndexIt);
                 work->input.buffers.clear();
                 work->worklets.clear();
@@ -835,27 +790,24 @@
         index++;
     }
     if (keyFrame) {
-        ASSERT_NO_FATAL_FAILURE(
-            decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                          mFlushedIndices, mLinearPool, eleStream, &Info, index,
-                          (int)Info.size() - index));
+        ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                              mFlushedIndices, mLinearPool, eleStream, &Info, index,
+                                              (int)Info.size() - index));
     }
     eleStream.close();
     err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
     ASSERT_EQ(err, C2_OK);
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
-                               (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                                                   (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
     {
         // Update mFlushedIndices based on the index received from flush()
         ULock l(mQueueLock);
         for (std::unique_ptr<C2Work>& work : flushedWork) {
             ASSERT_NE(work, nullptr);
             uint64_t frameIndex = work->input.ordinal.frameIndex.peeku();
-            std::list<uint64_t>::iterator frameIndexIt = std::find(
-                mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
-            if (!mFlushedIndices.empty() &&
-                (frameIndexIt != mFlushedIndices.end())) {
+            std::list<uint64_t>::iterator frameIndexIt =
+                    std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) {
                 mFlushedIndices.erase(frameIndexIt);
                 work->input.buffers.clear();
                 work->worklets.clear();
@@ -867,15 +819,15 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) {
+TEST_P(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) {
     description("Decode with multiple empty input frames");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
     char mURL[512], info[512];
     std::ifstream eleStream, eleInfo;
 
-    strcpy(mURL, gEnv->getRes().c_str());
-    strcpy(info, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
+    strcpy(info, sResourceDir.c_str());
     GetURLForComponent(mCompName, mURL, info);
 
     eleInfo.open(info);
@@ -890,15 +842,16 @@
     // and empty input frames at an interval of 5 frames.
     while (1) {
         if (!(frameId % 5)) {
-            if (!(frameId % 20)) flags = 32;
-            else flags = 0;
+            if (!(frameId % 20))
+                flags = 32;
+            else
+                flags = 0;
             bytesCount = 0;
         } else {
             if (!(eleInfo >> bytesCount)) break;
             eleInfo >> flags;
             eleInfo >> timestamp;
-            codecConfig = flags ?
-                ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+            codecConfig = flags ? ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
         }
         Info.push_back({bytesCount, flags, timestamp});
         frameId++;
@@ -909,39 +862,58 @@
     ALOGV("mURL : %s", mURL);
     eleStream.open(mURL, std::ifstream::binary);
     ASSERT_EQ(eleStream.is_open(), true);
-    ASSERT_NO_FATAL_FAILURE(decodeNFrames(
-        mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
-        mLinearPool, eleStream, &Info, 0, (int)Info.size()));
+    ASSERT_NO_FATAL_FAILURE(decodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mLinearPool, eleStream, &Info, 0,
+                                          (int)Info.size()));
 
     // blocking call to ensures application to Wait till all the inputs are
     // consumed
     if (!mEos) {
         ALOGV("Waiting for input consumption");
-        ASSERT_NO_FATAL_FAILURE(
-            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+        ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
     }
 
     eleStream.close();
     if (mFramesReceived != Info.size()) {
         ALOGE("Input buffer count and Output buffer count mismatch");
-        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
-              Info.size());
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived, Info.size());
         ASSERT_TRUE(false);
     }
 }
 
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2VideoDecHidlTest, testing::ValuesIn(kTestParameters),
+                         android::hardware::PrintInstanceTupleNameToString<>);
+
+// DecodeTest with StreamIndex and EOS / No EOS
+INSTANTIATE_TEST_SUITE_P(StreamIndexAndEOS, Codec2VideoDecDecodeTest,
+                         testing::ValuesIn(kDecodeTestParameters),
+                         android::hardware::PrintInstanceTupleNameToString<>);
+
 }  // anonymous namespace
 
 // TODO : Video specific configuration Test
 int main(int argc, char** argv) {
-    gEnv = new ComponentTestEnvironment();
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    int status = gEnv->initFromOptions(argc, argv);
-    if (status == 0) {
-        int status = RUN_ALL_TESTS();
-        LOG(INFO) << "C2 Test result = " << status;
+    kTestParameters = getTestParameters(C2Component::DOMAIN_VIDEO, C2Component::KIND_DECODER);
+    for (auto params : kTestParameters) {
+        kDecodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "false"));
+        kDecodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "0", "true"));
+        kDecodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "1", "false"));
+        kDecodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "1", "true"));
     }
-    return status;
-}
+
+    // Set the resource directory based on command line args.
+    // Test will fail to set up if the argument is not set.
+    for (int i = 1; i < argc; i++) {
+        if (strcmp(argv[i], "-P") == 0 && i < argc - 1) {
+            sResourceDir = argv[i + 1];
+            break;
+        }
+    }
+
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml
new file mode 100644
index 0000000..8761797
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoDecTest.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Runs VtsHalMediaC2V1_0TargetVideoDecTest.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file" key="vts_media_c2_v1_0_video_dec_test" value="/data/local/tmp/vts_media_c2_v1_0_video_dec_test" />
+
+        <!-- Files used for video testing -->
+        <option name="push-file" key="bbb_avc_176x144_300kbps_60fps.h264" value="/data/local/tmp/media/bbb_avc_176x144_300kbps_60fps.h264" />
+        <option name="push-file" key="bbb_avc_640x360_768kbps_30fps.h264" value="/data/local/tmp/media/bbb_avc_640x360_768kbps_30fps.h264" />
+        <option name="push-file" key="bbb_avc_176x144_300kbps_60fps.info" value="/data/local/tmp/media/bbb_avc_176x144_300kbps_60fps.info" />
+        <option name="push-file" key="bbb_avc_640x360_768kbps_30fps.info" value="/data/local/tmp/media/bbb_avc_640x360_768kbps_30fps.info" />
+        <option name="push-file" key="bbb_hevc_176x144_176kbps_60fps.hevc" value="/data/local/tmp/media/bbb_hevc_176x144_176kbps_60fps.hevc" />
+        <option name="push-file" key="bbb_hevc_640x360_1600kbps_30fps.hevc" value="/data/local/tmp/media/bbb_hevc_640x360_1600kbps_30fps.hevc" />
+        <option name="push-file" key="bbb_hevc_176x144_176kbps_60fps.info" value="/data/local/tmp/media/bbb_hevc_176x144_176kbps_60fps.info" />
+        <option name="push-file" key="bbb_hevc_640x360_1600kbps_30fps.info" value="/data/local/tmp/media/bbb_hevc_640x360_1600kbps_30fps.info" />
+        <option name="push-file" key="bbb_mpeg2_176x144_105kbps_25fps.m2v" value="/data/local/tmp/media/bbb_mpeg2_176x144_105kbps_25fps.m2v" />
+        <option name="push-file" key="bbb_mpeg2_352x288_1mbps_60fps.m2v" value="/data/local/tmp/media/bbb_mpeg2_352x288_1mbps_60fps.m2v" />
+        <option name="push-file" key="bbb_mpeg2_176x144_105kbps_25fps.info" value="/data/local/tmp/media/bbb_mpeg2_176x144_105kbps_25fps.info" />
+        <option name="push-file" key="bbb_mpeg2_352x288_1mbps_60fps.info" value="/data/local/tmp/media/bbb_mpeg2_352x288_1mbps_60fps.info" />
+        <option name="push-file" key="bbb_h263_352x288_300kbps_12fps.h263" value="/data/local/tmp/media/bbb_h263_352x288_300kbps_12fps.h263" />
+        <option name="push-file" key="bbb_h263_352x288_300kbps_12fps.info" value="/data/local/tmp/media/bbb_h263_352x288_300kbps_12fps.info" />
+        <option name="push-file" key="bbb_mpeg4_352x288_512kbps_30fps.m4v" value="/data/local/tmp/media/bbb_mpeg4_352x288_512kbps_30fps.m4v" />
+        <option name="push-file" key="bbb_mpeg4_352x288_512kbps_30fps.info" value="/data/local/tmp/media/bbb_mpeg4_352x288_512kbps_30fps.info" />
+        <option name="push-file" key="bbb_vp8_176x144_240kbps_60fps.vp8" value="/data/local/tmp/media/bbb_vp8_176x144_240kbps_60fps.vp8" />
+        <option name="push-file" key="bbb_vp8_640x360_2mbps_30fps.vp8" value="/data/local/tmp/media/bbb_vp8_640x360_2mbps_30fps.vp8" />
+        <option name="push-file" key="bbb_vp8_176x144_240kbps_60fps.info" value="/data/local/tmp/media/bbb_vp8_176x144_240kbps_60fps.info" />
+        <option name="push-file" key="bbb_vp8_640x360_2mbps_30fps.info" value="/data/local/tmp/media/bbb_vp8_640x360_2mbps_30fps.info" />
+        <option name="push-file" key="bbb_vp9_176x144_285kbps_60fps.vp9" value="/data/local/tmp/media/bbb_vp9_176x144_285kbps_60fps.vp9" />
+        <option name="push-file" key="bbb_vp9_640x360_1600kbps_30fps.vp9" value="/data/local/tmp/media/bbb_vp9_640x360_1600kbps_30fps.vp9" />
+        <option name="push-file" key="bbb_vp9_176x144_285kbps_60fps.info" value="/data/local/tmp/media/bbb_vp9_176x144_285kbps_60fps.info" />
+        <option name="push-file" key="bbb_vp9_640x360_1600kbps_30fps.info" value="/data/local/tmp/media/bbb_vp9_640x360_1600kbps_30fps.info" />
+        <option name="push-file" key="bbb_av1_640_360.av1" value="/data/local/tmp/media/bbb_av1_640_360.av1" />
+        <option name="push-file" key="bbb_av1_176_144.av1" value="/data/local/tmp/media/bbb_av1_176_144.av1" />
+        <option name="push-file" key="bbb_av1_640_360.info" value="/data/local/tmp/media/bbb_av1_640_360.info" />
+        <option name="push-file" key="bbb_av1_176_144.info" value="/data/local/tmp/media/bbb_av1_176_144.info" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="vts_media_c2_v1_0_video_dec_test" />
+        <option name="native-test-flag" value="-P /data/local/tmp/media/" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
index 15f6acd..be97383 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
@@ -19,73 +19,62 @@
 
 #include <android-base/logging.h>
 #include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
 #include <stdio.h>
 #include <fstream>
 
-#include <codec2/hidl/client.h>
 #include <C2AllocatorIon.h>
-#include <C2Config.h>
-#include <C2Debug.h>
 #include <C2Buffer.h>
 #include <C2BufferPriv.h>
+#include <C2Config.h>
+#include <C2Debug.h>
+#include <codec2/hidl/client.h>
 
 using android::C2AllocatorIon;
 
-#include <VtsHalHidlTargetTestBase.h>
-#include "media_c2_video_hidl_test_common.h"
 #include "media_c2_hidl_test_common.h"
+#include "media_c2_video_hidl_test_common.h"
 
 class GraphicBuffer : public C2Buffer {
-public:
-  explicit GraphicBuffer(const std::shared_ptr<C2GraphicBlock> &block)
-      : C2Buffer({block->share(C2Rect(block->width(), block->height()),
-                               ::C2Fence())}) {}
+  public:
+    explicit GraphicBuffer(const std::shared_ptr<C2GraphicBlock>& block)
+        : C2Buffer({block->share(C2Rect(block->width(), block->height()), ::C2Fence())}) {}
 };
 
-static ComponentTestEnvironment* gEnv = nullptr;
+static std::vector<std::tuple<std::string, std::string, std::string>> kEncodeTestParameters;
+static std::vector<std::tuple<std::string, std::string, std::string, std::string>>
+        kEncodeResolutionTestParameters;
+
+// Resource directory
+static std::string sResourceDir = "";
 
 namespace {
 
-class Codec2VideoEncHidlTest : public ::testing::VtsHalHidlTargetTestBase {
-   private:
-    typedef ::testing::VtsHalHidlTargetTestBase Super;
-
-   public:
-    ::std::string getTestCaseInfo() const override {
-        return ::std::string() +
-                "Component: " + gEnv->getComponent().c_str() + " | " +
-                "Instance: " + gEnv->getInstance().c_str() + " | " +
-                "Res: " + gEnv->getRes().c_str();
-    }
-
+class Codec2VideoEncHidlTestBase : public ::testing::Test {
+  public:
     // google.codec2 Video test setup
     virtual void SetUp() override {
-        Super::SetUp();
+        getParams();
         mDisableTest = false;
         ALOGV("Codec2VideoEncHidlTest SetUp");
         mClient = android::Codec2Client::CreateFromService(
-            gEnv->getInstance().c_str(),
-            !bool(android::Codec2Client::CreateFromService("default", true)));
+                mInstanceName.c_str(),
+                !bool(android::Codec2Client::CreateFromService("default", true)));
         ASSERT_NE(mClient, nullptr);
-        mListener.reset(new CodecListener(
-            [this](std::list<std::unique_ptr<C2Work>>& workItems) {
-                handleWorkDone(workItems);
-            }));
+        mListener.reset(new CodecListener([this](std::list<std::unique_ptr<C2Work>>& workItems) {
+            handleWorkDone(workItems);
+        }));
         ASSERT_NE(mListener, nullptr);
         for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
             mWorkQueue.emplace_back(new C2Work);
         }
-        mClient->createComponent(gEnv->getComponent().c_str(), mListener,
-                                 &mComponent);
+        mClient->createComponent(mComponentName, mListener, &mComponent);
         ASSERT_NE(mComponent, nullptr);
 
-        std::shared_ptr<C2AllocatorStore> store =
-            android::GetCodec2PlatformAllocatorStore();
-        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC,
-                                       &mGraphicAllocator),
+        std::shared_ptr<C2AllocatorStore> store = android::GetCodec2PlatformAllocatorStore();
+        CHECK_EQ(store->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &mGraphicAllocator),
                  C2_OK);
-        mGraphicPool = std::make_shared<C2PooledBlockPool>(mGraphicAllocator,
-                                                           mBlockPoolId++);
+        mGraphicPool = std::make_shared<C2PooledBlockPool>(mGraphicAllocator, mBlockPoolId++);
         ASSERT_NE(mGraphicPool, nullptr);
 
         mCompName = unknown_comp;
@@ -95,17 +84,15 @@
         };
 
         const StringToName kStringToName[] = {
-            {"h263", h263}, {"avc", avc}, {"mpeg4", mpeg4},
-            {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
+                {"h263", h263}, {"avc", avc}, {"mpeg4", mpeg4},
+                {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
         };
 
-        const size_t kNumStringToName =
-            sizeof(kStringToName) / sizeof(kStringToName[0]);
+        const size_t kNumStringToName = sizeof(kStringToName) / sizeof(kStringToName[0]);
 
         // Find the component type
-        std::string comp = std::string(gEnv->getComponent());
         for (size_t i = 0; i < kNumStringToName; ++i) {
-            if (strcasestr(comp.c_str(), kStringToName[i].Name)) {
+            if (strcasestr(mComponentName.c_str(), kStringToName[i].Name)) {
                 mCompName = kStringToName[i].CompName;
                 break;
             }
@@ -126,9 +113,11 @@
             mComponent->release();
             mComponent = nullptr;
         }
-        Super::TearDown();
     }
 
+    // Get the test parameters from GetParam call.
+    virtual void getParams() {}
+
     bool setupConfigParam(int32_t nWidth, int32_t nHeight);
 
     // callback function to process onWorkDone received by Listener
@@ -139,11 +128,9 @@
                 // previous timestamp
                 typedef std::unique_lock<std::mutex> ULock;
                 if (!mTimestampUslist.empty()) {
-                    EXPECT_GE((work->worklets.front()
-                                   ->output.ordinal.timestamp.peeku()),
+                    EXPECT_GE((work->worklets.front()->output.ordinal.timestamp.peeku()),
                               mTimestampUs);
-                    mTimestampUs = work->worklets.front()
-                                       ->output.ordinal.timestamp.peeku();
+                    mTimestampUs = work->worklets.front()->output.ordinal.timestamp.peeku();
                     // Currently this lock is redundant as no mTimestampUslist is only initialized
                     // before queuing any work to component. Once AdaptiveTest is added similar to
                     // the one in video decoders, this is needed.
@@ -151,8 +138,7 @@
 
                     if (mTimestampDevTest) {
                         bool tsHit = false;
-                        std::list<uint64_t>::iterator it =
-                            mTimestampUslist.begin();
+                        std::list<uint64_t>::iterator it = mTimestampUslist.begin();
                         while (it != mTimestampUslist.end()) {
                             if (*it == mTimestampUs) {
                                 mTimestampUslist.erase(it);
@@ -163,21 +149,18 @@
                         }
                         if (tsHit == false) {
                             if (mTimestampUslist.empty() == false) {
-                                EXPECT_EQ(tsHit, true)
-                                    << "TimeStamp not recognized";
+                                EXPECT_EQ(tsHit, true) << "TimeStamp not recognized";
                             } else {
-                                std::cout
-                                    << "[   INFO   ] Received non-zero "
-                                       "output / TimeStamp not recognized \n";
+                                std::cout << "[   INFO   ] Received non-zero "
+                                             "output / TimeStamp not recognized \n";
                             }
                         }
                     }
                 }
 
                 if (work->result != C2_OK) mFailedWorkReceived++;
-                workDone(mComponent, work, mFlushedIndices, mQueueLock,
-                         mQueueCondition, mWorkQueue, mEos, mCsd,
-                         mFramesReceived);
+                workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition, mWorkQueue,
+                         mEos, mCsd, mFramesReceived);
             }
         }
     }
@@ -192,6 +175,8 @@
         unknown_comp,
     };
 
+    std::string mInstanceName;
+    std::string mComponentName;
     bool mEos;
     bool mCsd;
     bool mDisableTest;
@@ -217,15 +202,23 @@
     std::shared_ptr<android::Codec2Client::Listener> mListener;
     std::shared_ptr<android::Codec2Client::Component> mComponent;
 
-   protected:
+  protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
     }
 };
 
-void validateComponent(
-    const std::shared_ptr<android::Codec2Client::Component>& component,
-    Codec2VideoEncHidlTest::standardComp compName, bool& disableTest) {
+class Codec2VideoEncHidlTest
+    : public Codec2VideoEncHidlTestBase,
+      public ::testing::WithParamInterface<std::tuple<std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
+};
+
+void validateComponent(const std::shared_ptr<android::Codec2Client::Component>& component,
+                       Codec2VideoEncHidlTest::standardComp compName, bool& disableTest) {
     // Validate its a C2 Component
     if (component->getName().find("c2") == std::string::npos) {
         ALOGE("Not a c2 component");
@@ -240,14 +233,12 @@
         return;
     }
     std::vector<std::unique_ptr<C2Param>> queried;
-    c2_status_t c2err =
-        component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
-                         C2_DONT_BLOCK, &queried);
+    c2_status_t c2err = component->query({}, {C2PortMediaTypeSetting::input::PARAM_TYPE},
+                                         C2_DONT_BLOCK, &queried);
     if (c2err != C2_OK && queried.size() == 0) {
         ALOGE("Query media type failed => %d", c2err);
     } else {
-        std::string inputDomain =
-            ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
+        std::string inputDomain = ((C2StreamMediaTypeSetting::input*)queried[0].get())->m.value;
         if (inputDomain.find("video/") == std::string::npos) {
             ALOGE("Expected Video Component");
             disableTest = true;
@@ -265,12 +256,11 @@
 }
 
 // Set Default config param.
-bool Codec2VideoEncHidlTest::setupConfigParam(int32_t nWidth, int32_t nHeight) {
+bool Codec2VideoEncHidlTestBase::setupConfigParam(int32_t nWidth, int32_t nHeight) {
     std::vector<std::unique_ptr<C2SettingResult>> failures;
     C2StreamPictureSizeInfo::input inputSize(0u, nWidth, nHeight);
     std::vector<C2Param*> configParam{&inputSize};
-    c2_status_t status =
-        mComponent->config(configParam, C2_DONT_BLOCK, &failures);
+    c2_status_t status = mComponent->config(configParam, C2_DONT_BLOCK, &failures);
     if (status == C2_OK && failures.size() == 0u) return true;
     return false;
 }
@@ -281,13 +271,11 @@
 }
 
 void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
-                   std::mutex &queueLock, std::condition_variable& queueCondition,
+                   std::mutex& queueLock, std::condition_variable& queueCondition,
                    std::list<std::unique_ptr<C2Work>>& workQueue,
-                   std::list<uint64_t>& flushedIndices,
-                   std::shared_ptr<C2BlockPool>& graphicPool,
-                   std::ifstream& eleStream, bool& disableTest,
-                   uint32_t frameID, uint32_t nFrames, uint32_t nWidth,
-                   int32_t nHeight, bool flushed = false, bool signalEOS = true) {
+                   std::list<uint64_t>& flushedIndices, std::shared_ptr<C2BlockPool>& graphicPool,
+                   std::ifstream& eleStream, bool& disableTest, uint32_t frameID, uint32_t nFrames,
+                   uint32_t nWidth, int32_t nHeight, bool flushed = false, bool signalEOS = true) {
     typedef std::unique_lock<std::mutex> ULock;
 
     uint32_t maxRetry = 0;
@@ -313,8 +301,7 @@
         if (!work && (maxRetry >= MAX_RETRY)) {
             ASSERT_TRUE(false) << "Wait for generating C2Work exceeded timeout";
         }
-        if (signalEOS && (nFrames == 1))
-            flags |= C2FrameData::FLAG_END_OF_STREAM;
+        if (signalEOS && (nFrames == 1)) flags |= C2FrameData::FLAG_END_OF_STREAM;
         if (flushed) {
             flags |= SYNC_FRAME;
             flushed = false;
@@ -335,9 +322,9 @@
             ASSERT_EQ(eleStream.gcount(), bytesCount);
         }
         std::shared_ptr<C2GraphicBlock> block;
-        err = graphicPool->fetchGraphicBlock(
-                nWidth, nHeight, HAL_PIXEL_FORMAT_YV12,
-                {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}, &block);
+        err = graphicPool->fetchGraphicBlock(nWidth, nHeight, HAL_PIXEL_FORMAT_YV12,
+                                             {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+                                             &block);
         if (err != C2_OK) {
             fprintf(stderr, "fetchGraphicBlock failed : %d\n", err);
             disableTest = true;
@@ -380,27 +367,32 @@
     }
 }
 
-TEST_F(Codec2VideoEncHidlTest, validateCompName) {
-    if (mDisableTest) return;
+TEST_P(Codec2VideoEncHidlTest, validateCompName) {
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     ALOGV("Checks if the given component is a valid video component");
     validateComponent(mComponent, mCompName, mDisableTest);
     ASSERT_EQ(mDisableTest, false);
 }
 
-class Codec2VideoEncEncodeTest : public Codec2VideoEncHidlTest,
-                                 public ::testing::WithParamInterface<bool> {
+class Codec2VideoEncEncodeTest
+    : public Codec2VideoEncHidlTestBase,
+      public ::testing::WithParamInterface<std::tuple<std::string, std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
 };
 
 TEST_P(Codec2VideoEncEncodeTest, EncodeTest) {
     description("Encodes input file");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
     char mURL[512];
     int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH;
     int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT;
-    bool signalEOS = GetParam();
+    bool signalEOS = !std::get<2>(GetParam()).compare("true");
 
-    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
     GetURLForComponent(mURL);
 
     std::ifstream eleStream;
@@ -425,10 +417,9 @@
         return;
     }
     ASSERT_EQ(mComponent->start(), C2_OK);
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
-                      0, ENC_NUM_FRAMES, nWidth, nHeight, false, signalEOS));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 0,
+                                          ENC_NUM_FRAMES, nWidth, nHeight, false, signalEOS));
     // mDisableTest will be set if buffer was not fetched properly.
     // This may happen when resolution is not proper but config suceeded
     // In this cases, we skip encoding the input stream
@@ -441,25 +432,21 @@
     // If EOS is not sent, sending empty input with EOS flag
     inputFrames = ENC_NUM_FRAMES;
     if (!signalEOS) {
-        ASSERT_NO_FATAL_FAILURE(
-            waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
-        ASSERT_NO_FATAL_FAILURE(
-            testInputBuffer(mComponent, mQueueLock, mWorkQueue,
-                            C2FrameData::FLAG_END_OF_STREAM, false));
+        ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue, 1));
+        ASSERT_NO_FATAL_FAILURE(testInputBuffer(mComponent, mQueueLock, mWorkQueue,
+                                                C2FrameData::FLAG_END_OF_STREAM, false));
         inputFrames += 1;
     }
 
     // blocking call to ensures application to Wait till all the inputs are
     // consumed
     ALOGD("Waiting for input consumption");
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
 
     eleStream.close();
     if (mFramesReceived != inputFrames) {
         ALOGE("Input buffer count and Output buffer count mismatch");
-        ALOGE("framesReceived : %d inputFrames : %d", mFramesReceived,
-              inputFrames);
+        ALOGE("framesReceived : %d inputFrames : %d", mFramesReceived, inputFrames);
         ASSERT_TRUE(false);
     }
 
@@ -475,13 +462,9 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-// EncodeTest with EOS / No EOS
-INSTANTIATE_TEST_CASE_P(EncodeTestwithEOS, Codec2VideoEncEncodeTest,
-                        ::testing::Values(true, false));
-
-TEST_F(Codec2VideoEncHidlTest, EOSTest) {
+TEST_P(Codec2VideoEncHidlTest, EOSTest) {
     description("Test empty input buffer with EOS flag");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
     ASSERT_EQ(mComponent->start(), C2_OK);
 
     typedef std::unique_lock<std::mutex> ULock;
@@ -519,15 +502,15 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2VideoEncHidlTest, FlushTest) {
+TEST_P(Codec2VideoEncHidlTest, FlushTest) {
     description("Test Request for flush");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
     typedef std::unique_lock<std::mutex> ULock;
     char mURL[512];
     int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH;
     int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT;
-    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(mURL, sResourceDir.c_str());
     GetURLForComponent(mURL);
 
     if (!setupConfigParam(nWidth, nHeight)) {
@@ -544,10 +527,9 @@
     eleStream.open(mURL, std::ifstream::binary);
     ASSERT_EQ(eleStream.is_open(), true);
     ALOGV("mURL : %s", mURL);
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
-                      0, numFramesFlushed, nWidth, nHeight));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 0,
+                                          numFramesFlushed, nWidth, nHeight));
     // mDisableTest will be set if buffer was not fetched properly.
     // This may happen when resolution is not proper but config suceeded
     // In this cases, we skip encoding the input stream
@@ -558,23 +540,20 @@
     }
 
     std::list<std::unique_ptr<C2Work>> flushedWork;
-    c2_status_t err =
-        mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
+    c2_status_t err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
     ASSERT_EQ(err, C2_OK);
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
-            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                                                   (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
     uint64_t frameIndex;
     {
-        //Update mFlushedIndices based on the index received from flush()
+        // Update mFlushedIndices based on the index received from flush()
         ULock l(mQueueLock);
         for (std::unique_ptr<C2Work>& work : flushedWork) {
             ASSERT_NE(work, nullptr);
             frameIndex = work->input.ordinal.frameIndex.peeku();
-            std::list<uint64_t>::iterator frameIndexIt = std::find(
-                mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
-            if (!mFlushedIndices.empty() &&
-                (frameIndexIt != mFlushedIndices.end())) {
+            std::list<uint64_t>::iterator frameIndexIt =
+                    std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) {
                 mFlushedIndices.erase(frameIndexIt);
                 work->input.buffers.clear();
                 work->worklets.clear();
@@ -583,11 +562,10 @@
         }
     }
     mFlushedIndices.clear();
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
-                      numFramesFlushed, numFrames - numFramesFlushed,
-                      nWidth, nHeight, true));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
+                                          numFramesFlushed, numFrames - numFramesFlushed, nWidth,
+                                          nHeight, true));
     eleStream.close();
     // mDisableTest will be set if buffer was not fetched properly.
     // This may happen when resolution is not proper but config suceeded
@@ -600,19 +578,17 @@
 
     err = mComponent->flush(C2Component::FLUSH_COMPONENT, &flushedWork);
     ASSERT_EQ(err, C2_OK);
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
-            (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue,
+                                                   (size_t)MAX_INPUT_BUFFERS - flushedWork.size()));
     {
-        //Update mFlushedIndices based on the index received from flush()
+        // Update mFlushedIndices based on the index received from flush()
         ULock l(mQueueLock);
         for (std::unique_ptr<C2Work>& work : flushedWork) {
             ASSERT_NE(work, nullptr);
             frameIndex = work->input.ordinal.frameIndex.peeku();
-            std::list<uint64_t>::iterator frameIndexIt = std::find(
-                mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
-            if (!mFlushedIndices.empty() &&
-                (frameIndexIt != mFlushedIndices.end())) {
+            std::list<uint64_t>::iterator frameIndexIt =
+                    std::find(mFlushedIndices.begin(), mFlushedIndices.end(), frameIndex);
+            if (!mFlushedIndices.empty() && (frameIndexIt != mFlushedIndices.end())) {
                 mFlushedIndices.erase(frameIndexIt);
                 work->input.buffers.clear();
                 work->worklets.clear();
@@ -624,9 +600,9 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2VideoEncHidlTest, InvalidBufferTest) {
+TEST_P(Codec2VideoEncHidlTest, InvalidBufferTest) {
     description("Tests feeding larger/smaller input buffer");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
     std::ifstream eleStream;
     int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH / 2;
@@ -638,28 +614,24 @@
     }
     ASSERT_EQ(mComponent->start(), C2_OK);
 
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
-                      0, 1, nWidth, nHeight, false, false));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 0,
+                                          1, nWidth, nHeight, false, false));
 
     // Feed larger input buffer.
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
-                      1, 1, nWidth*2, nHeight*2, false, false));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 1,
+                                          1, nWidth * 2, nHeight * 2, false, false));
 
     // Feed smaller input buffer.
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
-                      2, 1, nWidth/2, nHeight/2, false, true));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 2,
+                                          1, nWidth / 2, nHeight / 2, false, true));
 
     // blocking call to ensures application to Wait till all the inputs are
     // consumed
     ALOGD("Waiting for input consumption");
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
 
     if (mFramesReceived != 3) {
         std::cout << "[   WARN   ] Component didn't receive all buffers back \n";
@@ -674,17 +646,23 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-class Codec2VideoEncResolutionTest : public Codec2VideoEncHidlTest,
-        public ::testing::WithParamInterface<std::pair<int32_t, int32_t> > {
+class Codec2VideoEncResolutionTest
+    : public Codec2VideoEncHidlTestBase,
+      public ::testing::WithParamInterface<
+              std::tuple<std::string, std::string, std::string, std::string>> {
+    void getParams() {
+        mInstanceName = std::get<0>(GetParam());
+        mComponentName = std::get<1>(GetParam());
+    }
 };
 
 TEST_P(Codec2VideoEncResolutionTest, ResolutionTest) {
     description("Tests encoding at different resolutions");
-    if (mDisableTest) return;
+    if (mDisableTest) GTEST_SKIP() << "Test is disabled";
 
     std::ifstream eleStream;
-    int32_t nWidth = GetParam().first;
-    int32_t nHeight = GetParam().second;
+    int32_t nWidth = std::stoi(std::get<2>(GetParam()));
+    int32_t nHeight = std::stoi(std::get<3>(GetParam()));
     ALOGD("Trying encode for width %d height %d", nWidth, nHeight);
     mEos = false;
 
@@ -694,10 +672,9 @@
     }
     ASSERT_EQ(mComponent->start(), C2_OK);
 
-    ASSERT_NO_FATAL_FAILURE(
-        encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
-                      mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
-                      0, MAX_INPUT_BUFFERS, nWidth, nHeight, false, true));
+    ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
+                                          mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 0,
+                                          MAX_INPUT_BUFFERS, nWidth, nHeight, false, true));
 
     // mDisableTest will be set if buffer was not fetched properly.
     // This may happen when resolution is not proper but config suceeded
@@ -709,31 +686,52 @@
     }
 
     ALOGD("Waiting for input consumption");
-    ASSERT_NO_FATAL_FAILURE(
-        waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+    ASSERT_NO_FATAL_FAILURE(waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
 
     ASSERT_EQ(mEos, true);
     ASSERT_EQ(mComponent->stop(), C2_OK);
     ASSERT_EQ(mComponent->reset(), C2_OK);
 }
 
-INSTANTIATE_TEST_CASE_P(NonStdSizes, Codec2VideoEncResolutionTest, ::testing::Values(
-    std::make_pair(52, 18),
-    std::make_pair(365, 365),
-    std::make_pair(484, 362),
-    std::make_pair(244, 488)));
+INSTANTIATE_TEST_SUITE_P(PerInstance, Codec2VideoEncHidlTest, testing::ValuesIn(kTestParameters),
+                         android::hardware::PrintInstanceTupleNameToString<>);
+
+INSTANTIATE_TEST_SUITE_P(NonStdSizes, Codec2VideoEncResolutionTest,
+                         ::testing::ValuesIn(kEncodeResolutionTestParameters));
+
+// EncodeTest with EOS / No EOS
+INSTANTIATE_TEST_SUITE_P(EncodeTestwithEOS, Codec2VideoEncEncodeTest,
+                         ::testing::ValuesIn(kEncodeTestParameters));
 
 }  // anonymous namespace
 
 int main(int argc, char** argv) {
-    gEnv = new ComponentTestEnvironment();
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    int status = gEnv->initFromOptions(argc, argv);
-    if (status == 0) {
-        int status = RUN_ALL_TESTS();
-        LOG(INFO) << "C2 Test result = " << status;
+    kTestParameters = getTestParameters(C2Component::DOMAIN_VIDEO, C2Component::KIND_ENCODER);
+    for (auto params : kTestParameters) {
+        kEncodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "true"));
+        kEncodeTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "false"));
+
+        kEncodeResolutionTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "52", "18"));
+        kEncodeResolutionTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "365", "365"));
+        kEncodeResolutionTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "484", "362"));
+        kEncodeResolutionTestParameters.push_back(
+                std::make_tuple(std::get<0>(params), std::get<1>(params), "244", "488"));
     }
-    return status;
-}
+
+    // Set the resource directory based on command line args.
+    // Test will fail to set up if the argument is not set.
+    for (int i = 1; i < argc; i++) {
+        if (strcmp(argv[i], "-P") == 0 && i < argc - 1) {
+            sResourceDir = argv[i + 1];
+            break;
+        }
+    }
+
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.xml b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.xml
new file mode 100644
index 0000000..260a616
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Runs VtsHalMediaC2V1_0TargetVideoEncTest.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file" key="vts_media_c2_v1_0_video_enc_test" value="/data/local/tmp/vts_media_c2_v1_0_video_enc_test" />
+
+        <!-- Files used for video testing -->
+        <option name="push-file" key="bbb_352x288_420p_30fps_32frames.yuv" value="/data/local/tmp/media/bbb_352x288_420p_30fps_32frames.yuv" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="vts_media_c2_v1_0_video_enc_test" />
+        <option name="native-test-flag" value="-P /data/local/tmp/media/" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h b/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h
index e37ca38..d3a693b 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/functional/video/media_c2_video_hidl_test_common.h
@@ -29,5 +29,4 @@
  * Common video utils
  */
 
-
 #endif  // MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index cc132de..01d106f 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1948,6 +1948,13 @@
             inputSurface->getHalInterface()));
 }
 
+static void MaybeLogUnrecognizedName(const char *func, const std::string &name) {
+    thread_local std::set<std::string> sLogged{};
+    if (sLogged.insert(name).second) {
+        ALOGW("%s: Unrecognized interface name: %s", func, name.c_str());
+    }
+}
+
 static status_t GetCommonAllocatorIds(
         const std::vector<std::string> &names,
         C2Allocator::type_t type,
@@ -1961,26 +1968,33 @@
     if (names.empty()) {
         return OK;
     }
-    std::shared_ptr<Codec2Client::Interface> intf{
-        Codec2Client::CreateInterfaceByName(names[0].c_str())};
-    std::vector<std::unique_ptr<C2Param>> params;
-    c2_status_t err = intf->query(
-            {}, {C2PortAllocatorsTuning::input::PARAM_TYPE}, C2_MAY_BLOCK, &params);
-    if (err == C2_OK && params.size() == 1u) {
-        C2PortAllocatorsTuning::input *allocators =
-            C2PortAllocatorsTuning::input::From(params[0].get());
-        if (allocators && allocators->flexCount() > 0) {
-            ids->insert(allocators->m.values, allocators->m.values + allocators->flexCount());
+    bool firstIteration = true;
+    for (const std::string &name : names) {
+        std::shared_ptr<Codec2Client::Interface> intf{
+            Codec2Client::CreateInterfaceByName(name.c_str())};
+        if (!intf) {
+            MaybeLogUnrecognizedName(__FUNCTION__, name);
+            continue;
         }
-    }
-    if (ids->empty()) {
-        // The component does not advertise allocators. Use default.
-        ids->insert(defaultAllocatorId);
-    }
-    for (size_t i = 1; i < names.size(); ++i) {
-        intf = Codec2Client::CreateInterfaceByName(names[i].c_str());
-        err = intf->query(
+        std::vector<std::unique_ptr<C2Param>> params;
+        c2_status_t err = intf->query(
                 {}, {C2PortAllocatorsTuning::input::PARAM_TYPE}, C2_MAY_BLOCK, &params);
+        if (firstIteration) {
+            firstIteration = false;
+            if (err == C2_OK && params.size() == 1u) {
+                C2PortAllocatorsTuning::input *allocators =
+                    C2PortAllocatorsTuning::input::From(params[0].get());
+                if (allocators && allocators->flexCount() > 0) {
+                    ids->insert(allocators->m.values,
+                                allocators->m.values + allocators->flexCount());
+                }
+            }
+            if (ids->empty()) {
+                // The component does not advertise allocators. Use default.
+                ids->insert(defaultAllocatorId);
+            }
+            continue;
+        }
         bool filtered = false;
         if (err == C2_OK && params.size() == 1u) {
             C2PortAllocatorsTuning::input *allocators =
@@ -2033,6 +2047,10 @@
     for (const std::string &name : names) {
         std::shared_ptr<Codec2Client::Interface> intf{
             Codec2Client::CreateInterfaceByName(name.c_str())};
+        if (!intf) {
+            MaybeLogUnrecognizedName(__FUNCTION__, name);
+            continue;
+        }
         std::vector<C2FieldSupportedValuesQuery> fields;
         fields.push_back(C2FieldSupportedValuesQuery::Possible(
                 C2ParamField{&sUsage, &sUsage.value}));
diff --git a/media/codec2/vndk/util/C2InterfaceUtils.cpp b/media/codec2/vndk/util/C2InterfaceUtils.cpp
index 61ec911..0c1729b 100644
--- a/media/codec2/vndk/util/C2InterfaceUtils.cpp
+++ b/media/codec2/vndk/util/C2InterfaceUtils.cpp
@@ -216,9 +216,14 @@
     if (limit.contains(minMask) && contains(minMask)) {
         values[0] = minMask;
         // keep only flags that are covered by limit
-        std::remove_if(values.begin(), values.end(), [&limit, minMask](const C2Value::Primitive &v) -> bool {
-            T value = v.ref<ValueType>() | minMask;
-            return value == minMask || !limit.contains(value); });
+        values.erase(std::remove_if(values.begin(), values.end(),
+                                    [&limit, minMask](
+                                        const C2Value::Primitive &v) -> bool {
+                                      T value = v.ref<ValueType>() | minMask;
+                                      return value == minMask ||
+                                             !limit.contains(value);
+                                    }),
+                     values.end());
         // we also need to do it vice versa
         for (const C2Value::Primitive &v : _mValues) {
             T value = v.ref<ValueType>() | minMask;
@@ -264,24 +269,33 @@
 template<typename T>
 C2SupportedValueSet<T> C2SupportedValueSet<T>::limitedTo(const C2SupportedValueSet<T> &limit) const {
     std::vector<C2Value::Primitive> values = _mValues; // make a copy
-    std::remove_if(values.begin(), values.end(), [&limit](const C2Value::Primitive &v) -> bool {
-        return !limit.contains(v.ref<ValueType>()); });
+    values.erase(std::remove_if(values.begin(), values.end(),
+                                [&limit](const C2Value::Primitive &v) -> bool {
+                                  return !limit.contains(v.ref<ValueType>());
+                                }),
+                 values.end());
     return C2SupportedValueSet(std::move(values));
 }
 
 template<typename T>
 C2SupportedValueSet<T> C2SupportedValueSet<T>::limitedTo(const C2SupportedRange<T> &limit) const {
     std::vector<C2Value::Primitive> values = _mValues; // make a copy
-    std::remove_if(values.begin(), values.end(), [&limit](const C2Value::Primitive &v) -> bool {
-        return !limit.contains(v.ref<ValueType>()); });
+    values.erase(std::remove_if(values.begin(), values.end(),
+                                [&limit](const C2Value::Primitive &v) -> bool {
+                                  return !limit.contains(v.ref<ValueType>());
+                                }),
+                 values.end());
     return C2SupportedValueSet(std::move(values));
 }
 
 template<typename T>
 C2SupportedValueSet<T> C2SupportedValueSet<T>::limitedTo(const C2SupportedFlags<T> &limit) const {
     std::vector<C2Value::Primitive> values = _mValues; // make a copy
-    std::remove_if(values.begin(), values.end(), [&limit](const C2Value::Primitive &v) -> bool {
-        return !limit.contains(v.ref<ValueType>()); });
+    values.erase(std::remove_if(values.begin(), values.end(),
+                                [&limit](const C2Value::Primitive &v) -> bool {
+                                  return !limit.contains(v.ref<ValueType>());
+                                }),
+                 values.end());
     return C2SupportedValueSet(std::move(values));
 }
 
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 1cb81a6..39f5bb6 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -1906,11 +1906,15 @@
             //ALOGV("\tReverb_command cmdCode Case: "
             //        "EFFECT_CMD_GET_PARAM start");
             effect_param_t *p = (effect_param_t *)pCmdData;
+            if (pCmdData == nullptr) {
+                ALOGW("\tLVM_ERROR : pCmdData is NULL");
+                return -EINVAL;
+            }
             if (SIZE_MAX - sizeof(effect_param_t) < (size_t)p->psize) {
                 android_errorWriteLog(0x534e4554, "26347509");
                 return -EINVAL;
             }
-            if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) ||
+            if (cmdSize < sizeof(effect_param_t) ||
                     cmdSize < (sizeof(effect_param_t) + p->psize) ||
                     pReplyData == NULL || replySize == NULL ||
                     *replySize < (sizeof(effect_param_t) + p->psize)) {
diff --git a/media/libmediametrics/MediaMetricsItem.cpp b/media/libmediametrics/MediaMetricsItem.cpp
index 4371668..7cdbe5f 100644
--- a/media/libmediametrics/MediaMetricsItem.cpp
+++ b/media/libmediametrics/MediaMetricsItem.cpp
@@ -25,6 +25,7 @@
 #include <set>
 
 #include <binder/Parcel.h>
+#include <cutils/properties.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/SortedVector.h>
diff --git a/media/libmediametrics/include/media/MediaMetricsItem.h b/media/libmediametrics/include/media/MediaMetricsItem.h
index 8477f8d..303343f 100644
--- a/media/libmediametrics/include/media/MediaMetricsItem.h
+++ b/media/libmediametrics/include/media/MediaMetricsItem.h
@@ -27,12 +27,8 @@
 #include <variant>
 
 #include <binder/Parcel.h>
-#include <cutils/properties.h>
 #include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-#include <utils/StrongPointer.h>
-#include <utils/Timers.h>
+#include <utils/Timers.h> // nsecs_t
 
 namespace android {
 
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 425468f..e97f6eb 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -107,20 +107,6 @@
     }
 }
 
-ID3::ID3(DataSourceBase *source, bool ignoreV1, off64_t offset)
-    : mIsValid(false),
-      mData(NULL),
-      mSize(0),
-      mFirstFrameOffset(0),
-      mVersion(ID3_UNKNOWN),
-      mRawSize(0) {
-    mIsValid = parseV2(source, offset);
-
-    if (!mIsValid && !ignoreV1) {
-        mIsValid = parseV1(source);
-    }
-}
-
 ID3::ID3(const uint8_t *data, size_t size, bool ignoreV1)
     : mIsValid(false),
       mData(NULL),
@@ -247,44 +233,14 @@
         return false;
     }
 
-    if (header.version_major == 4) {
-        void *copy = malloc(size);
-        if (copy == NULL) {
-            free(mData);
-            mData = NULL;
-            ALOGE("b/24623447, no more memory");
-            return false;
-        }
-
-        memcpy(copy, mData, size);
-
-        bool success = removeUnsynchronizationV2_4(false /* iTunesHack */);
-        if (!success) {
-            memcpy(mData, copy, size);
-            mSize = size;
-
-            success = removeUnsynchronizationV2_4(true /* iTunesHack */);
-
-            if (success) {
-                ALOGV("Had to apply the iTunes hack to parse this ID3 tag");
-            }
-        }
-
-        free(copy);
-        copy = NULL;
-
-        if (!success) {
-            free(mData);
-            mData = NULL;
-
-            return false;
-        }
-    } else if (header.flags & 0x80) {
+    // first handle global unsynchronization
+    if (header.flags & 0x80) {
         ALOGV("removing unsynchronization");
 
         removeUnsynchronization();
     }
 
+    // handle extended header, if present
     mFirstFrameOffset = 0;
     if (header.version_major == 3 && (header.flags & 0x40)) {
         // Version 2.3 has an optional extended header.
@@ -296,6 +252,7 @@
             return false;
         }
 
+        // v2.3 does not have syncsafe integers
         size_t extendedHeaderSize = U32_AT(&mData[0]);
         if (extendedHeaderSize > SIZE_MAX - 4) {
             free(mData);
@@ -367,6 +324,48 @@
         mFirstFrameOffset = ext_size;
     }
 
+    // Handle any v2.4 per-frame unsynchronization
+    // The id3 spec isn't clear about what should happen if the global
+    // unsynchronization flag is combined with per-frame unsynchronization,
+    // or whether that's even allowed, so this code assumes id3 writing
+    // tools do the right thing and not apply double-unsynchronization,
+    // but will honor the flags if they are set.
+    if (header.version_major == 4) {
+        void *copy = malloc(size);
+        if (copy == NULL) {
+            free(mData);
+            mData = NULL;
+            ALOGE("b/24623447, no more memory");
+            return false;
+        }
+
+        memcpy(copy, mData, size);
+
+        bool success = removeUnsynchronizationV2_4(false /* iTunesHack */);
+        if (!success) {
+            memcpy(mData, copy, size);
+            mSize = size;
+
+            success = removeUnsynchronizationV2_4(true /* iTunesHack */);
+
+            if (success) {
+                ALOGV("Had to apply the iTunes hack to parse this ID3 tag");
+            }
+        }
+
+        free(copy);
+        copy = NULL;
+
+        if (!success) {
+            free(mData);
+            mData = NULL;
+
+            return false;
+        }
+    }
+
+
+
     if (header.version_major == 2) {
         mVersion = ID3_V2_2;
     } else if (header.version_major == 3) {
@@ -411,7 +410,7 @@
 bool ID3::removeUnsynchronizationV2_4(bool iTunesHack) {
     size_t oldSize = mSize;
 
-    size_t offset = 0;
+    size_t offset = mFirstFrameOffset;
     while (mSize >= 10 && offset <= mSize - 10) {
         if (!memcmp(&mData[offset], "\0\0\0\0", 4)) {
             break;
@@ -445,7 +444,7 @@
         }
 
         if ((flags & 2) && (dataSize >= 2)) {
-            // This file has "unsynchronization", so we have to replace occurrences
+            // This frame has "unsynchronization", so we have to replace occurrences
             // of 0xff 0x00 with just 0xff in order to get the real data.
 
             size_t readOffset = offset + 11;
diff --git a/media/libstagefright/id3/test/ID3Test.cpp b/media/libstagefright/id3/test/ID3Test.cpp
index a8f1470..cd5cd9e 100644
--- a/media/libstagefright/id3/test/ID3Test.cpp
+++ b/media/libstagefright/id3/test/ID3Test.cpp
@@ -24,6 +24,7 @@
 #include <datasource/FileSource.h>
 
 #include <media/stagefright/foundation/hexdump.h>
+#include <media/MediaExtractorPluginHelper.h>
 #include <ID3.h>
 
 #include "ID3TestEnvironment.h"
@@ -42,7 +43,8 @@
     string path = gEnv->getRes() + GetParam();
     sp<FileSource> file = new FileSource(path.c_str());
     ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
-    ID3 tag(file.get());
+    DataSourceHelper helper(file->wrap());
+    ID3 tag(&helper);
     ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
 
     ID3::Iterator it(tag, nullptr);
@@ -61,7 +63,8 @@
     sp<android::FileSource> file = new FileSource(path.c_str());
     ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
 
-    ID3 tag(file.get());
+    DataSourceHelper helper(file->wrap());
+    ID3 tag(&helper);
     ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
     ASSERT_TRUE(tag.version() >= versionNumber)
             << "Expected version: " << tag.version() << " Found version: " << versionNumber;
@@ -73,7 +76,8 @@
     sp<android::FileSource> file = new FileSource(path.c_str());
     ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
 
-    ID3 tag(file.get());
+    DataSourceHelper helper(file->wrap());
+    ID3 tag(&helper);
     ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
     int countTextFrames = 0;
     ID3::Iterator it(tag, nullptr);
@@ -99,7 +103,8 @@
     sp<android::FileSource> file = new FileSource(path.c_str());
     ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
 
-    ID3 tag(file.get());
+    DataSourceHelper helper(file->wrap());
+    ID3 tag(&helper);
     ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
     size_t dataSize;
     String8 mime;
@@ -124,7 +129,8 @@
     sp<android::FileSource> file = new FileSource(path.c_str());
     ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
 
-    ID3 tag(file.get());
+    DataSourceHelper helper(file->wrap());
+    ID3 tag(&helper);
     ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
     int count = 0;
     ID3::Iterator it(tag, nullptr);
diff --git a/media/libstagefright/id3/testid3.cpp b/media/libstagefright/id3/testid3.cpp
index 9984d85..5cd51cf 100644
--- a/media/libstagefright/id3/testid3.cpp
+++ b/media/libstagefright/id3/testid3.cpp
@@ -24,6 +24,7 @@
 #include <binder/ProcessState.h>
 #include <datasource/FileSource.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/MediaExtractorPluginHelper.h>
 
 #define MAXPATHLEN 256
 
@@ -72,7 +73,8 @@
     sp<FileSource> file = new FileSource(path);
     CHECK_EQ(file->initCheck(), (status_t)OK);
 
-    ID3 tag(file.get());
+    DataSourceHelper helper(file->wrap());
+    ID3 tag(&helper);
     if (!tag.isValid()) {
         printf("FAIL %s\n", path);
     } else {
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index 2843a7a..0be5896 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -37,7 +37,6 @@
     };
 
     explicit ID3(DataSourceHelper *source, bool ignoreV1 = false, off64_t offset = 0);
-    explicit ID3(DataSourceBase *source, bool ignoreV1 = false, off64_t offset = 0);
     ID3(const uint8_t *data, size_t size, bool ignoreV1 = false);
     ~ID3();
 
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index a720bc9..8c186c9 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -34,12 +34,7 @@
     const char *mRole;
 
 } kComponents[] = {
-    // two choices for aac decoding.
-    // configurable in media/libstagefright/data/media_codecs_google_audio.xml
-    // default implementation
     { "OMX.google.aac.decoder", "aacdec", "audio_decoder.aac" },
-    // alternate implementation
-    { "OMX.google.xaac.decoder", "xaacdec", "audio_decoder.aac" },
     { "OMX.google.aac.encoder", "aacenc", "audio_encoder.aac" },
     { "OMX.google.amrnb.decoder", "amrdec", "audio_decoder.amrnb" },
     { "OMX.google.amrnb.encoder", "amrnbenc", "audio_encoder.amrnb" },
diff --git a/media/libstagefright/tests/extractorFactory/Android.bp b/media/libstagefright/tests/extractorFactory/Android.bp
new file mode 100644
index 0000000..e3e61d7
--- /dev/null
+++ b/media/libstagefright/tests/extractorFactory/Android.bp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+cc_test {
+    name: "ExtractorFactoryTest",
+    gtest: true,
+
+    srcs: [
+        "ExtractorFactoryTest.cpp",
+    ],
+
+    shared_libs: [
+        "liblog",
+        "libbase",
+        "libutils",
+        "libmedia",
+        "libbinder",
+        "libcutils",
+        "libdl_android",
+        "libdatasource",
+        "libmediametrics",
+    ],
+
+    static_libs: [
+        "libstagefright",
+        "libstagefright_foundation",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libstagefright",
+    ],
+
+    // TODO: (b/150181583)
+    compile_multilib: "first",
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    sanitize: {
+        cfi: true,
+        misc_undefined: [
+            "unsigned-integer-overflow",
+            "signed-integer-overflow",
+        ],
+    },
+}
diff --git a/media/libstagefright/tests/extractorFactory/AndroidTest.xml b/media/libstagefright/tests/extractorFactory/AndroidTest.xml
new file mode 100644
index 0000000..3aa6392
--- /dev/null
+++ b/media/libstagefright/tests/extractorFactory/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for extractor factory unit tests">
+    <option name="test-suite-tag" value="ExtractorFactoryTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="ExtractorFactoryTest->/data/local/tmp/ExtractorFactoryTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor.zip?unzip=true"
+            value="/data/local/tmp/ExtractorFactoryTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="ExtractorFactoryTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/ExtractorFactoryTestRes/" />
+    </test>
+</configuration>
diff --git a/media/libstagefright/tests/extractorFactory/ExtractorFactoryTest.cpp b/media/libstagefright/tests/extractorFactory/ExtractorFactoryTest.cpp
new file mode 100644
index 0000000..d155caa
--- /dev/null
+++ b/media/libstagefright/tests/extractorFactory/ExtractorFactoryTest.cpp
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ExtractorFactoryTest"
+#include <utils/Log.h>
+
+#include <binder/ProcessState.h>
+
+#include <datasource/FileSource.h>
+#include <media/stagefright/MediaExtractorFactory.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+
+#include "ExtractorFactoryTestEnvironment.h"
+
+#define OUTPUT_FILE_NAME "/data/local/tmp/exFactoryLogs"
+
+using namespace android;
+
+static ExtractorFactoryTestEnvironment *gEnv = nullptr;
+
+class ExtractorFactoryTest : public ::testing::TestWithParam<pair<string, string>> {
+  public:
+    ExtractorFactoryTest() : mDataSource(nullptr), mExtractor(nullptr) {}
+
+    ~ExtractorFactoryTest() {
+        if (mDataSource) {
+            mDataSource.clear();
+            mDataSource = nullptr;
+        }
+        if (mExtractor) {
+            mExtractor.clear();
+            mExtractor = nullptr;
+        }
+    }
+
+    int32_t createDataSource(string inputFileName);
+    int32_t createExtractor(bool createFromService, string inputMime);
+
+    sp<DataSource> mDataSource;
+    sp<IMediaExtractor> mExtractor;
+};
+
+int32_t ExtractorFactoryTest::createDataSource(string inputFileName) {
+    FILE *mInputFp = fopen(inputFileName.c_str(), "rb");
+    if (!mInputFp) {
+        ALOGE("Unable to open input file : %s for reading", inputFileName.c_str());
+        return -1;
+    }
+    struct stat buf;
+    int32_t status = stat(inputFileName.c_str(), &buf);
+    if (status != 0) {
+        ALOGE("Failed to read file properties for input file : %s", inputFileName.c_str());
+        return -1;
+    }
+    int32_t fd = fileno(mInputFp);
+    if (fd < 0) {
+        ALOGE("Invalid file descriptor for input file : %s", inputFileName.c_str());
+        return -1;
+    }
+    mDataSource = new FileSource(dup(fd), 0, buf.st_size);
+    if (!mDataSource) return -1;
+    return 0;
+}
+
+int32_t ExtractorFactoryTest::createExtractor(bool createFromService, string inputMime) {
+    ALOGV("Creating extractor for mime : %s", inputMime.c_str());
+    if (createFromService) {
+        mExtractor = MediaExtractorFactory::CreateFromService(mDataSource, inputMime.c_str());
+    } else {
+        mExtractor = MediaExtractorFactory::Create(mDataSource);
+    }
+    if (mExtractor == nullptr) return -1;
+    return 0;
+}
+
+TEST_F(ExtractorFactoryTest, ListExtractorsTest) {
+    MediaExtractorFactory::LoadExtractors();
+    vector<std::string> supportedTypes = MediaExtractorFactory::getSupportedTypes();
+    ASSERT_GT(supportedTypes.size(), 0) << " MediaExtractorFactory doesn't suuport any extractor";
+
+    FILE *outputLog = fopen(OUTPUT_FILE_NAME, "wb");
+    ASSERT_NE(outputLog, nullptr) << "Unable to open output file - " << OUTPUT_FILE_NAME
+                                  << " for writing";
+
+    int32_t fd = fileno(outputLog);
+    ASSERT_GE(fd, 0);
+
+    Vector<String16> args;
+    int32_t status = MediaExtractorFactory::dump(fd, args);
+    ASSERT_EQ(status, OK) << "MediaExtractorFactory dump failed";
+    fclose(outputLog);
+}
+
+TEST_P(ExtractorFactoryTest, ExtractorFactoryApiTest) {
+    string inputMime = GetParam().second;
+    string inputFileName = gEnv->getRes() + GetParam().first;
+
+    MediaExtractorFactory::LoadExtractors();
+    bool createMode[] = {true, false};
+    for (bool createFromService : createMode) {
+        int32_t status = createDataSource(inputFileName);
+        ASSERT_EQ(status, 0) << "create data source failed";
+
+        status = createExtractor(createFromService, inputMime);
+        ASSERT_EQ(status, 0) << "Extractor creation failed for input: " << inputFileName;
+
+        int32_t numTracks = mExtractor->countTracks();
+        ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
+
+        sp<MetaData> meta = mExtractor->getMetaData();
+        ASSERT_NE(meta, nullptr) << "getMetaData returned null";
+
+        const char *mime;
+        bool valueFound = meta->findCString(kKeyMIMEType, &mime);
+        ASSERT_TRUE(valueFound) << "Extractor did not provide MIME type";
+        ASSERT_EQ(mime, inputMime) << "Extractor factory returned invalid mime type";
+        mExtractor.clear();
+        mDataSource.clear();
+    }
+}
+
+// TODO: (b/150111966)
+// Replace mime strings with appropriate definitions
+INSTANTIATE_TEST_SUITE_P(
+        ExtractorFactoryTestAll, ExtractorFactoryTest,
+        ::testing::Values(make_pair("loudsoftaac.aac", MEDIA_MIMETYPE_AUDIO_AAC_ADTS),
+                          make_pair("testamr.amr", "audio/amr"),
+                          make_pair("amrwb.wav", MEDIA_MIMETYPE_AUDIO_AMR_WB),
+                          make_pair("john_cage.ogg", MEDIA_MIMETYPE_CONTAINER_OGG),
+                          make_pair("monotestgsm.wav", MEDIA_MIMETYPE_CONTAINER_WAV),
+                          make_pair("segment000001.ts", MEDIA_MIMETYPE_CONTAINER_MPEG2TS),
+                          make_pair("sinesweepflac.flac", MEDIA_MIMETYPE_AUDIO_FLAC),
+                          make_pair("testopus.opus", MEDIA_MIMETYPE_CONTAINER_OGG),
+                          make_pair("midi_a.mid", MEDIA_MIMETYPE_AUDIO_MIDI),
+                          make_pair("sinesweepvorbis.mkv", MEDIA_MIMETYPE_CONTAINER_MATROSKA),
+                          make_pair("sinesweepoggmp4.mp4", "audio/mp4"),
+                          make_pair("sinesweepmp3lame.mp3", MEDIA_MIMETYPE_AUDIO_MPEG),
+                          make_pair("swirl_144x136_vp9.webm", "video/webm"),
+                          make_pair("swirl_144x136_vp8.webm", "video/webm"),
+                          make_pair("swirl_132x130_mpeg4.mp4", MEDIA_MIMETYPE_CONTAINER_MPEG4)));
+
+int main(int argc, char **argv) {
+    ProcessState::self()->startThreadPool();
+    gEnv = new ExtractorFactoryTestEnvironment();
+    ::testing::AddGlobalTestEnvironment(gEnv);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = gEnv->initFromOptions(argc, argv);
+    if (status == 0) {
+        status = RUN_ALL_TESTS();
+        ALOGV("Test result = %d\n", status);
+    }
+    return status;
+}
diff --git a/media/libstagefright/tests/extractorFactory/ExtractorFactoryTestEnvironment.h b/media/libstagefright/tests/extractorFactory/ExtractorFactoryTestEnvironment.h
new file mode 100644
index 0000000..0fad4d3
--- /dev/null
+++ b/media/libstagefright/tests/extractorFactory/ExtractorFactoryTestEnvironment.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef __EXTRACTOR_FACTORY_TEST_ENVIRONMENT_H__
+#define __EXTRACTOR_FACTORY_TEST_ENVIRONMENT_H__
+
+#include <gtest/gtest.h>
+
+#include <getopt.h>
+
+using namespace std;
+
+class ExtractorFactoryTestEnvironment : public ::testing::Environment {
+  public:
+    ExtractorFactoryTestEnvironment() : res("/data/local/tmp/") {}
+
+    // Parses the command line arguments
+    int initFromOptions(int argc, char **argv);
+
+    void setRes(const char *_res) { res = _res; }
+
+    const string getRes() const { return res; }
+
+  private:
+    string res;
+};
+
+int ExtractorFactoryTestEnvironment::initFromOptions(int argc, char **argv) {
+    static struct option options[] = {{"res", required_argument, 0, 'P'}, {0, 0, 0, 0}};
+
+    while (true) {
+        int index = 0;
+        int c = getopt_long(argc, argv, "P:", options, &index);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+            case 'P':
+                setRes(optarg);
+                break;
+            default:
+                break;
+        }
+    }
+
+    if (optind < argc) {
+        fprintf(stderr,
+                "unrecognized option: %s\n\n"
+                "usage: %s <gtest options> <test options>\n\n"
+                "test options are:\n\n"
+                "-P, --path: Resource files directory location\n",
+                argv[optind ?: 1], argv[0]);
+        return 2;
+    }
+    return 0;
+}
+
+#endif  // __EXTRACTOR_FACTORY_TEST_ENVIRONMENT_H__
diff --git a/media/libstagefright/tests/extractorFactory/README.md b/media/libstagefright/tests/extractorFactory/README.md
new file mode 100644
index 0000000..aaa71aa
--- /dev/null
+++ b/media/libstagefright/tests/extractorFactory/README.md
@@ -0,0 +1,37 @@
+## Media Testing ##
+---
+#### Writer :
+The Writer Test Suite validates the writers available in libstagefright.
+
+Run the following steps to build the test suite:
+```
+mmm frameworks/av/media/libstagefright/tests/writer/
+```
+
+The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/
+The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/
+
+To test 64-bit binary push binaries from nativetest64.
+
+adb push ${OUT}/data/nativetest64/ExtractorFactoryTest/ExtractorFactoryTest /data/local/tmp/
+
+To test 32-bit binary push binaries from nativetest.
+
+adb push ${OUT}/data/nativetest/ExtractorFactoryTest/ExtractorFactoryTest /data/local/tmp/
+
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor.zip).
+Download, unzip and push these files into device for testing.
+
+```
+adb push extractor /data/local/tmp/
+```
+
+usage: ExtractorFactoryTest -P \<path_to_res_folder\>
+```
+adb shell /data/local/tmp/ExtractorFactoryTest -P /data/local/tmp/extractor/
+```
+Alternatively, the test can also be run using atest command.
+
+```
+atest ExtractorFactoryTest -- --enable-module-dynamic-download=true
+```
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 03c16f3..de7ae40 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -135,7 +135,7 @@
 
 static sp<os::IExternalVibratorService> getExternalVibratorService() {
     if (sExternalVibratorService == 0) {
-        sp <IBinder> binder = defaultServiceManager()->getService(
+        sp<IBinder> binder = defaultServiceManager()->getService(
             String16("external_vibrator_service"));
         if (binder != 0) {
             sExternalVibratorService =
@@ -411,6 +411,7 @@
 
 status_t AudioFlinger::addEffectToHal(audio_port_handle_t deviceId,
         audio_module_handle_t hwModuleId, sp<EffectHalInterface> effect) {
+    AutoMutex lock(mHardwareLock);
     AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(hwModuleId);
     if (audioHwDevice == nullptr) {
         return NO_INIT;
@@ -420,6 +421,7 @@
 
 status_t AudioFlinger::removeEffectFromHal(audio_port_handle_t deviceId,
         audio_module_handle_t hwModuleId, sp<EffectHalInterface> effect) {
+    AutoMutex lock(mHardwareLock);
     AudioHwDevice *audioHwDevice = mAudioHwDevs.valueFor(hwModuleId);
     if (audioHwDevice == nullptr) {
         return NO_INIT;
@@ -439,6 +441,7 @@
 {
     // if module is 0, the request comes from an old policy manager and we should load
     // well known modules
+    AutoMutex lock(mHardwareLock);
     if (module == 0) {
         ALOGW("findSuitableHwDev_l() loading well know audio hw modules");
         for (size_t i = 0; i < arraysize(audio_interfaces); i++) {
@@ -1079,17 +1082,18 @@
     mMasterVolume = value;
 
     // Set master volume in the HALs which support it.
-    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+    {
         AutoMutex lock(mHardwareLock);
-        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
+        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+            AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
 
-        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
-        if (dev->canSetMasterVolume()) {
-            dev->hwDevice()->setMasterVolume(value);
+            mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+            if (dev->canSetMasterVolume()) {
+                dev->hwDevice()->setMasterVolume(value);
+            }
+            mHardwareStatus = AUDIO_HW_IDLE;
         }
-        mHardwareStatus = AUDIO_HW_IDLE;
     }
-
     // Now set the master volume in each playback thread.  Playback threads
     // assigned to HALs which do not have master volume support will apply
     // master volume during the mix operation.  Threads with HALs which do
@@ -1156,6 +1160,9 @@
 
     { // scope for the lock
         AutoMutex lock(mHardwareLock);
+        if (mPrimaryHardwareDev == nullptr) {
+            return INVALID_OPERATION;
+        }
         sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
         mHardwareStatus = AUDIO_HW_SET_MODE;
         ret = dev->setMode(mode);
@@ -1185,6 +1192,9 @@
     }
 
     AutoMutex lock(mHardwareLock);
+    if (mPrimaryHardwareDev == nullptr) {
+        return INVALID_OPERATION;
+    }
     sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev->hwDevice();
     if (primaryDev == nullptr) {
         ALOGW("%s: no primary HAL device", __func__);
@@ -1210,6 +1220,9 @@
         return false;
     }
     AutoMutex lock(mHardwareLock);
+    if (mPrimaryHardwareDev == nullptr) {
+        return false;
+    }
     sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev->hwDevice();
     if (primaryDev == nullptr) {
         ALOGW("%s: no primary HAL device", __func__);
@@ -1252,15 +1265,17 @@
     mMasterMute = muted;
 
     // Set master mute in the HALs which support it.
-    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+    {
         AutoMutex lock(mHardwareLock);
-        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
+        for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+            AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
 
-        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
-        if (dev->canSetMasterMute()) {
-            dev->hwDevice()->setMasterMute(muted);
+            mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
+            if (dev->canSetMasterMute()) {
+                dev->hwDevice()->setMasterMute(muted);
+            }
+            mHardwareStatus = AUDIO_HW_IDLE;
         }
-        mHardwareStatus = AUDIO_HW_IDLE;
     }
 
     // Now set the master mute in each playback thread.  Playback threads
@@ -1591,16 +1606,13 @@
     if (ioHandle == AUDIO_IO_HANDLE_NONE) {
         String8 out_s8;
 
+        AutoMutex lock(mHardwareLock);
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
             String8 s;
-            status_t result;
-            {
-            AutoMutex lock(mHardwareLock);
             mHardwareStatus = AUDIO_HW_GET_PARAMETER;
             sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
-            result = dev->getParameters(keys, &s);
+            status_t result = dev->getParameters(keys, &s);
             mHardwareStatus = AUDIO_HW_IDLE;
-            }
             if (result == OK) out_s8 += s;
         }
         return out_s8;
@@ -1633,6 +1645,9 @@
     }
 
     AutoMutex lock(mHardwareLock);
+    if (mPrimaryHardwareDev == nullptr) {
+        return 0;
+    }
     mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
 
     sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
@@ -1718,6 +1733,9 @@
     }
 
     AutoMutex lock(mHardwareLock);
+    if (mPrimaryHardwareDev == nullptr) {
+        return INVALID_OPERATION;
+    }
     sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
     mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
     ret = dev->setVoiceVolume(value);
@@ -2126,10 +2144,11 @@
         return AUDIO_MODULE_HANDLE_NONE;
     }
     Mutex::Autolock _l(mLock);
+    AutoMutex lock(mHardwareLock);
     return loadHwModule_l(name);
 }
 
-// loadHwModule_l() must be called with AudioFlinger::mLock held
+// loadHwModule_l() must be called with AudioFlinger::mLock and AudioFlinger::mHardwareLock held
 audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
 {
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
@@ -2161,44 +2180,49 @@
     // master mute and volume settings.
 
     AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
-    {  // scope for auto-lock pattern
-        AutoMutex lock(mHardwareLock);
-
-        if (0 == mAudioHwDevs.size()) {
-            mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
-            float mv;
-            if (OK == dev->getMasterVolume(&mv)) {
-                mMasterVolume = mv;
-            }
-
-            mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
-            bool mm;
-            if (OK == dev->getMasterMute(&mm)) {
-                mMasterMute = mm;
-            }
+    if (0 == mAudioHwDevs.size()) {
+        mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
+        float mv;
+        if (OK == dev->getMasterVolume(&mv)) {
+            mMasterVolume = mv;
         }
 
-        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
-        if (OK == dev->setMasterVolume(mMasterVolume)) {
-            flags = static_cast<AudioHwDevice::Flags>(flags |
-                    AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
+        mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
+        bool mm;
+        if (OK == dev->getMasterMute(&mm)) {
+            mMasterMute = mm;
         }
-
-        mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
-        if (OK == dev->setMasterMute(mMasterMute)) {
-            flags = static_cast<AudioHwDevice::Flags>(flags |
-                    AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
-        }
-
-        mHardwareStatus = AUDIO_HW_IDLE;
     }
+
+    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+    if (OK == dev->setMasterVolume(mMasterVolume)) {
+        flags = static_cast<AudioHwDevice::Flags>(flags |
+                AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
+    }
+
+    mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
+    if (OK == dev->setMasterMute(mMasterMute)) {
+        flags = static_cast<AudioHwDevice::Flags>(flags |
+                AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
+    }
+
+    mHardwareStatus = AUDIO_HW_IDLE;
+
     if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
         // An MSD module is inserted before hardware modules in order to mix encoded streams.
         flags = static_cast<AudioHwDevice::Flags>(flags | AudioHwDevice::AHWD_IS_INSERT);
     }
 
     audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
-    mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
+    AudioHwDevice *audioDevice = new AudioHwDevice(handle, name, dev, flags);
+    if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
+        mPrimaryHardwareDev = audioDevice;
+        mHardwareStatus = AUDIO_HW_SET_MODE;
+        mPrimaryHardwareDev->hwDevice()->setMode(mMode);
+        mHardwareStatus = AUDIO_HW_IDLE;
+    }
+
+    mAudioHwDevs.add(handle, audioDevice);
 
     ALOGI("loadHwModule() Loaded %s audio interface, handle %d", name, handle);
 
@@ -2284,6 +2308,7 @@
     }
 
     Mutex::Autolock _l(mLock);
+    AutoMutex lock(mHardwareLock);
     ssize_t index = mAudioHwDevs.indexOfKey(module);
     if (index < 0) {
         ALOGW("%s() bad hw module %d", __func__, module);
@@ -2305,8 +2330,15 @@
         return mHwAvSyncIds.valueAt(index);
     }
 
-    sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
-    if (dev == NULL) {
+    sp<DeviceHalInterface> dev;
+    {
+        AutoMutex lock(mHardwareLock);
+        if (mPrimaryHardwareDev == nullptr) {
+            return AUDIO_HW_SYNC_INVALID;
+        }
+        dev = mPrimaryHardwareDev->hwDevice();
+    }
+    if (dev == nullptr) {
         return AUDIO_HW_SYNC_INVALID;
     }
     String8 reply;
@@ -2374,8 +2406,21 @@
 status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfo> *microphones)
 {
     AutoMutex lock(mHardwareLock);
-    sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
-    status_t status = dev->getMicrophones(microphones);
+    status_t status = INVALID_OPERATION;
+
+    for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+        std::vector<media::MicrophoneInfo> mics;
+        AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
+        mHardwareStatus = AUDIO_HW_GET_MICROPHONES;
+        status_t devStatus = dev->hwDevice()->getMicrophones(&mics);
+        mHardwareStatus = AUDIO_HW_IDLE;
+        if (devStatus == NO_ERROR) {
+            microphones->insert(microphones->begin(), mics.begin(), mics.end());
+            // report success if at least one HW module supports the function.
+            status = NO_ERROR;
+        }
+    }
+
     return status;
 }
 
@@ -2522,12 +2567,13 @@
             // notify client processes of the new output creation
             playbackThread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
 
-            // the first primary output opened designates the primary hw device
-            if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
+            // the first primary output opened designates the primary hw device if no HW module
+            // named "primary" was already loaded.
+            AutoMutex lock(mHardwareLock);
+            if ((mPrimaryHardwareDev == nullptr) && (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
                 ALOGI("Using module %d as the primary audio interface", module);
                 mPrimaryHardwareDev = playbackThread->getOutput()->audioHwDev;
 
-                AutoMutex lock(mHardwareLock);
                 mHardwareStatus = AUDIO_HW_SET_MODE;
                 mPrimaryHardwareDev->hwDevice()->setMode(mMode);
                 mHardwareStatus = AUDIO_HW_IDLE;
@@ -3196,6 +3242,10 @@
 
 AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
 {
+    AutoMutex lock(mHardwareLock);
+    if (mPrimaryHardwareDev == nullptr) {
+        return nullptr;
+    }
     for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
         PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
         if(thread->isDuplicating()) {
@@ -3206,7 +3256,7 @@
             return thread;
         }
     }
-    return NULL;
+    return nullptr;
 }
 
 DeviceTypeSet AudioFlinger::primaryOutputDevice_l() const
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 5c20a2d..6afbd4f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -835,10 +835,11 @@
                 // NOTE: If both mLock and mHardwareLock mutexes must be held,
                 // always take mLock before mHardwareLock
 
-                // These two fields are immutable after onFirstRef(), so no lock needed to access
-                AudioHwDevice*                      mPrimaryHardwareDev; // mAudioHwDevs[0] or NULL
+                // guarded by mHardwareLock
+                AudioHwDevice* mPrimaryHardwareDev;
                 DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>  mAudioHwDevs;
 
+                // These two fields are immutable after onFirstRef(), so no lock needed to access
                 sp<DevicesFactoryHalInterface> mDevicesFactoryHal;
                 sp<DevicesFactoryHalCallback> mDevicesFactoryHalCallback;
 
@@ -865,6 +866,7 @@
         AUDIO_HW_GET_PARAMETER,         // get_parameters
         AUDIO_HW_SET_MASTER_MUTE,       // set_master_mute
         AUDIO_HW_GET_MASTER_MUTE,       // get_master_mute
+        AUDIO_HW_GET_MICROPHONES,       // getMicrophones
     };
 
     mutable     hardware_call_state                 mHardwareStatus;    // for dump only
diff --git a/services/mediametrics/TimeMachine.h b/services/mediametrics/TimeMachine.h
index b138233..6861c78 100644
--- a/services/mediametrics/TimeMachine.h
+++ b/services/mediametrics/TimeMachine.h
@@ -138,7 +138,7 @@
             if (timeSequence.empty()           // no elements
                     || property.back() == AMEDIAMETRICS_PROP_SUFFIX_CHAR_DUPLICATES_ALLOWED
                     || timeSequence.rbegin()->second != el) { // value changed
-                timeSequence.emplace(time, std::move(el));
+                timeSequence.emplace_hint(timeSequence.end(), time, std::move(el));
 
                 if (timeSequence.size() > kTimeSequenceMaxElements) {
                     ALOGV("%s: restricting maximum elements (discarding oldest) for %s",
diff --git a/services/mediametrics/TransactionLog.h b/services/mediametrics/TransactionLog.h
index d64acf3..8a22826 100644
--- a/services/mediametrics/TransactionLog.h
+++ b/services/mediametrics/TransactionLog.h
@@ -94,8 +94,8 @@
         std::lock_guard lock(mLock);
 
         (void)gc(garbage);
-        mLog.emplace(time, item);
-        mItemMap[key].emplace(time, item);
+        mLog.emplace_hint(mLog.end(), time, item);
+        mItemMap[key].emplace_hint(mItemMap[key].end(), time, item);
         return NO_ERROR;  // no errors for now.
     }