Upstream changes from Codec2 MTS

This includes changes up to commit
b3c2c12135ad6e96ca3cfa258bba24eb7b7b92ca.

Test: Builds

Bug: 112362730
Bug: 119853704
Change-Id: I97adbe52258d72d18446f12a9698462174e89b19
diff --git a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
index 6fd9200..1e87f38 100644
--- a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
@@ -156,63 +156,31 @@
     // callback function to process onWorkDone received by Listener
     void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
         for (std::unique_ptr<C2Work>& work : workItems) {
-            // handle configuration changes in work done
-            if (!work->worklets.empty() &&
-                (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::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() == C2StreamSampleRateInfo::output::PARAM_TYPE) ||
-                        (param->index() == C2StreamChannelCountInfo::output::PARAM_TYPE)) {
-                        configParam.push_back(param);
+            if (!work->worklets.empty()) {
+                // For decoder components current timestamp always exceeds
+                // previous timestamp
+                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();
+                    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);
                     }
                 }
-                mComponent->config(configParam, C2_DONT_BLOCK, &failures);
-                ASSERT_EQ(failures.size(), 0u);
-            }
-            mFramesReceived++;
-            mEos = (work->worklets.front()->output.flags &
-                    C2FrameData::FLAG_END_OF_STREAM) != 0;
-            auto frameIndexIt =
-                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
-                          work->input.ordinal.frameIndex.peeku());
-            ALOGV("WorkDone: frameID received %d",
-                (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
-
-            // For decoder components current timestamp always exceeds
-            // previous timestamp
-            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();
-                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);
-                }
-            }
-
-            work->input.buffers.clear();
-            work->worklets.clear();
-            {
-                typedef std::unique_lock<std::mutex> ULock;
-                ULock l(mQueueLock);
-                mWorkQueue.push_back(std::move(work));
-                if (!mFlushedIndices.empty()) {
-                    mFlushedIndices.erase(frameIndexIt);
-                }
-                mQueueCondition.notify_all();
+                bool mCsd = false;
+                workDone(mComponent, work, mFlushedIndices, mQueueLock,
+                         mQueueCondition, mWorkQueue, mEos, mCsd,
+                         mFramesReceived);
+                (void)mCsd;
             }
         }
     }
@@ -418,11 +386,11 @@
     }
 }
 
-void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
-                   std::mutex &queueLock, std::condition_variable &queueCondition,
-                   std::list<std::unique_ptr<C2Work>> &workQueue,
-                   std::list<uint64_t> &flushedIndices,
-                   std::shared_ptr<C2BlockPool> &linearPool,
+void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+                   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) {
@@ -462,34 +430,37 @@
         }
         int size = (*Info)[frameID].bytesCount;
         char* data = (char*)malloc(size);
+        ASSERT_NE(data, nullptr);
 
         eleStream.read(data, size);
         ASSERT_EQ(eleStream.gcount(), size);
 
-        std::shared_ptr<C2LinearBlock> block;
-        ASSERT_EQ(C2_OK,
-                  linearPool->fetchLinearBlock(
-                      size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
-                      &block));
-        ASSERT_TRUE(block);
-
-        // Write View
-        C2WriteView view = block->map().get();
-        if (view.error() != C2_OK) {
-            fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
-            break;
-        }
-        ASSERT_EQ((size_t)size, view.capacity());
-        ASSERT_EQ(0u, view.offset());
-        ASSERT_EQ((size_t)size, view.size());
-
-        memcpy(view.base(), data, size);
-
         work->input.buffers.clear();
-        work->input.buffers.emplace_back(new LinearBuffer(block));
+        if (size) {
+            std::shared_ptr<C2LinearBlock> block;
+            ASSERT_EQ(C2_OK,
+                    linearPool->fetchLinearBlock(
+                        size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+                        &block));
+            ASSERT_TRUE(block);
+
+            // Write View
+            C2WriteView view = block->map().get();
+            if (view.error() != C2_OK) {
+                fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+                break;
+            }
+            ASSERT_EQ((size_t)size, view.capacity());
+            ASSERT_EQ(0u, view.offset());
+            ASSERT_EQ((size_t)size, view.size());
+
+            memcpy(view.base(), data, size);
+
+            work->input.buffers.emplace_back(new LinearBuffer(block));
+            free(data);
+        }
         work->worklets.clear();
         work->worklets.emplace_back(new C2Worklet);
-        free(data);
 
         std::list<std::unique_ptr<C2Work>> items;
         items.push_back(std::move(work));
@@ -502,29 +473,6 @@
     }
 }
 
-void waitOnInputConsumption(std::mutex& queueLock,
-                            std::condition_variable& queueCondition,
-                            std::list<std::unique_ptr<C2Work>>& workQueue,
-                            size_t bufferCount = MAX_INPUT_BUFFERS) {
-    typedef std::unique_lock<std::mutex> ULock;
-    uint32_t queueSize;
-    uint32_t maxRetry = 0;
-    {
-        ULock l(queueLock);
-        queueSize = workQueue.size();
-    }
-    while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
-        ULock l(queueLock);
-        if (queueSize != workQueue.size()) {
-            queueSize = workQueue.size();
-            maxRetry = 0;
-        } else {
-            queueCondition.wait_for(l, TIME_OUT);
-            maxRetry++;
-        }
-    }
-}
-
 TEST_F(Codec2AudioDecHidlTest, validateCompName) {
     if (mDisableTest) return;
     ALOGV("Checks if the given component is a valid audio component");
@@ -718,7 +666,6 @@
     ASSERT_EQ(mComponent->queue(&items), C2_OK);
 
     {
-        typedef std::unique_lock<std::mutex> ULock;
         ULock l(mQueueLock);
         if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
             mQueueCondition.wait_for(l, TIME_OUT);
@@ -729,46 +676,6 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2AudioDecHidlTest, EmptyBufferTest) {
-    description("Tests empty input buffer");
-    if (mDisableTest) return;
-    typedef std::unique_lock<std::mutex> ULock;
-    ASSERT_EQ(mComponent->start(), C2_OK);
-    std::unique_ptr<C2Work> work;
-    // Prepare C2Work
-    {
-        ULock l(mQueueLock);
-        if (!mWorkQueue.empty()) {
-            work.swap(mWorkQueue.front());
-            mWorkQueue.pop_front();
-        } else {
-            ASSERT_TRUE(false) << "mWorkQueue Empty at the start of test";
-        }
-    }
-    ASSERT_NE(work, nullptr);
-
-    work->input.flags = (C2FrameData::flags_t)0;
-    work->input.ordinal.timestamp = 0;
-    work->input.ordinal.frameIndex = 0;
-    work->input.buffers.clear();
-    work->worklets.clear();
-    work->worklets.emplace_back(new C2Worklet);
-
-    std::list<std::unique_ptr<C2Work>> items;
-    items.push_back(std::move(work));
-    ASSERT_EQ(mComponent->queue(&items), C2_OK);
-
-    {
-        typedef std::unique_lock<std::mutex> ULock;
-        ULock l(mQueueLock);
-        if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
-            mQueueCondition.wait_for(l, TIME_OUT);
-        }
-    }
-    ASSERT_EQ(mWorkQueue.size(), (size_t)MAX_INPUT_BUFFERS);
-    ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
 TEST_F(Codec2AudioDecHidlTest, FlushTest) {
     description("Tests Flush calls");
     if (mDisableTest) return;
@@ -891,6 +798,72 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
+TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) {
+    description("Decode with multiple empty input frames");
+    if (mDisableTest) return;
+
+    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());
+    GetURLForComponent(mCompName, mURL, info);
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t frameId = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    bool codecConfig = false;
+    // This test introduces empty CSD after every 20th frame
+    // and empty input frames at an interval of 5 frames.
+    while (1) {
+        if (!(frameId % 5)) {
+            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;
+        }
+        Info.push_back({bytesCount, flags, timestamp});
+        frameId++;
+    }
+    eleInfo.close();
+
+    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()));
+
+    // 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));
+    }
+
+    eleStream.close();
+    if (mFramesReceived != Info.size()) {
+        ALOGE("Input buffer count and Output buffer count mismatch");
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+              Info.size());
+        ASSERT_TRUE(false);
+    }
+
+    ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
 }  // anonymous namespace
 
 int main(int argc, char** argv) {
diff --git a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
index 4f86aad..5d66ee5 100644
--- a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
@@ -96,6 +96,7 @@
         const StringToName kStringToName[] = {
             {"aac", aac},
             {"flac", flac},
+            {"opus", opus},
             {"amrnb", amrnb},
             {"amrwb", amrwb},
         };
@@ -135,45 +136,17 @@
     // callback function to process onWorkDone received by Listener
     void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
         for (std::unique_ptr<C2Work>& work : workItems) {
-            // handle configuration changes in work done
-            if (!work->worklets.empty() &&
-                (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::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() == C2StreamCsdInfo::output::PARAM_TYPE) {
-                        mCsd = true;
-                    }
-                }
-            }
-            mFramesReceived++;
-            mEos = (work->worklets.front()->output.flags &
-                    C2FrameData::FLAG_END_OF_STREAM) != 0;
-            auto frameIndexIt =
-                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
-                          work->input.ordinal.frameIndex.peeku());
-            ALOGV("WorkDone: frameID received %d",
-                (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
-            work->input.buffers.clear();
-            work->worklets.clear();
-            {
-                typedef std::unique_lock<std::mutex> ULock;
-                ULock l(mQueueLock);
-                mWorkQueue.push_back(std::move(work));
-                if (!mFlushedIndices.empty()) {
-                    mFlushedIndices.erase(frameIndexIt);
-                }
-                mQueueCondition.notify_all();
+            if (!work->worklets.empty()) {
+                workDone(mComponent, work, mFlushedIndices, mQueueLock,
+                         mQueueCondition, mWorkQueue, mEos, mCsd,
+                         mFramesReceived);
             }
         }
     }
     enum standardComp {
         aac,
         flac,
+        opus,
         amrnb,
         amrwb,
         unknown_comp,
@@ -275,6 +248,8 @@
          "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) {
@@ -285,11 +260,11 @@
     }
 }
 
-void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
-                   std::mutex &queueLock, std::condition_variable &queueCondition,
-                   std::list<std::unique_ptr<C2Work>> &workQueue,
-                   std::list<uint64_t> &flushedIndices,
-                   std::shared_ptr<C2BlockPool> &linearPool,
+void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+                   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,
@@ -334,6 +309,7 @@
             flushedIndices.emplace_back(frameID);
         }
         char* data = (char*)malloc(bytesCount);
+        ASSERT_NE(data, nullptr);
         eleStream.read(data, bytesCount);
         ASSERT_EQ(eleStream.gcount(), bytesCount);
         std::shared_ptr<C2LinearBlock> block;
@@ -372,29 +348,6 @@
     }
 }
 
-void waitOnInputConsumption(std::mutex& queueLock,
-                            std::condition_variable& queueCondition,
-                            std::list<std::unique_ptr<C2Work>>& workQueue,
-                            size_t bufferCount = MAX_INPUT_BUFFERS) {
-    typedef std::unique_lock<std::mutex> ULock;
-    uint32_t queueSize;
-    uint32_t maxRetry = 0;
-    {
-        ULock l(queueLock);
-        queueSize = workQueue.size();
-    }
-    while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
-        ULock l(queueLock);
-        if (queueSize != workQueue.size()) {
-            queueSize = workQueue.size();
-            maxRetry = 0;
-        } else {
-            queueCondition.wait_for(l, TIME_OUT);
-            maxRetry++;
-        }
-    }
-}
-
 TEST_F(Codec2AudioEncHidlTest, validateCompName) {
     if (mDisableTest) return;
     ALOGV("Checks if the given component is a valid audio component");
@@ -425,6 +378,11 @@
             nSampleRate = 48000;
             samplesPerFrame = 1152;
             break;
+        case opus:
+            nChannels = 2;
+            nSampleRate = 48000;
+            samplesPerFrame = 960;
+            break;
         case amrnb:
             nChannels = 1;
             nSampleRate = 8000;
@@ -458,7 +416,7 @@
         ALOGE("framesReceived : %d inputFrames : %u", mFramesReceived, numFrames);
         ASSERT_TRUE(false);
     }
-    if ((mCompName == flac || mCompName == aac)) {
+    if ((mCompName == flac || mCompName == opus || mCompName == aac)) {
         if (!mCsd) {
             ALOGE("CSD buffer missing");
             ASSERT_TRUE(false);
@@ -508,46 +466,6 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2AudioEncHidlTest, EmptyBufferTest) {
-    description("Tests empty input buffer");
-    if (mDisableTest) return;
-    ASSERT_EQ(mComponent->start(), C2_OK);
-
-    typedef std::unique_lock<std::mutex> ULock;
-    std::unique_ptr<C2Work> work;
-    {
-        ULock l(mQueueLock);
-        if (!mWorkQueue.empty()) {
-            work.swap(mWorkQueue.front());
-            mWorkQueue.pop_front();
-        } else {
-            ALOGE("mWorkQueue Empty is not expected at the start of the test");
-            ASSERT_TRUE(false);
-        }
-    }
-    ASSERT_NE(work, nullptr);
-    work->input.flags = (C2FrameData::flags_t)0;
-    work->input.ordinal.timestamp = 0;
-    work->input.ordinal.frameIndex = 0;
-    work->input.buffers.clear();
-    work->worklets.clear();
-    work->worklets.emplace_back(new C2Worklet);
-
-    std::list<std::unique_ptr<C2Work>> items;
-    items.push_back(std::move(work));
-    ASSERT_EQ(mComponent->queue(&items), C2_OK);
-    uint32_t queueSize;
-    {
-        ULock l(mQueueLock);
-        queueSize = mWorkQueue.size();
-        if (queueSize < MAX_INPUT_BUFFERS) {
-            mQueueCondition.wait_for(l, TIME_OUT);
-        }
-    }
-    ASSERT_EQ(mWorkQueue.size(), (uint32_t)MAX_INPUT_BUFFERS);
-    ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
 TEST_F(Codec2AudioEncHidlTest, FlushTest) {
     description("Test Request for flush");
     if (mDisableTest) return;
@@ -574,6 +492,11 @@
             nSampleRate = 48000;
             samplesPerFrame = 1152;
             break;
+        case opus:
+            nChannels = 2;
+            nSampleRate = 48000;
+            samplesPerFrame = 960;
+            break;
         case amrnb:
             nChannels = 1;
             nSampleRate = 8000;
diff --git a/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h b/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h
index 89eb69e..4d773ce 100644
--- a/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h
@@ -17,8 +17,5 @@
 #ifndef MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
 #define MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
 
-#define MAX_RETRY 20
-#define TIME_OUT 200ms
-#define MAX_INPUT_BUFFERS 8
 
 #endif  // MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp
index fdccdbb..64a458c 100644
--- a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp
+++ b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp
@@ -14,39 +14,115 @@
  * limitations under the License.
  */
 
+// #define LOG_NDEBUG 0
 #define LOG_TAG "media_c2_hidl_test_common"
 #include <stdio.h>
 
 #include "media_c2_hidl_test_common.h"
-using ::android::hardware::media::c2::V1_0::FieldSupportedValues;
 
-void dumpFSV(const FieldSupportedValues& sv) {
-    ALOGD("Dumping FSV data");
-    using namespace std;
-    if (sv.type == FieldSupportedValues::Type::EMPTY) {
-        ALOGD("FSV Value is Empty");
-    }
-    if (sv.type == FieldSupportedValues::Type::RANGE) {
-        ALOGD("Dumping FSV range");
-        cout << ".range(" << sv.range.min;
-        if (sv.range.step != 0) {
-            cout << ":" << sv.range.step;
+// 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) {
+    std::unique_ptr<C2Work> work;
+    {
+        typedef std::unique_lock<std::mutex> ULock;
+        ULock l(queueLock);
+        if (!workQueue.empty()) {
+            work.swap(workQueue.front());
+            workQueue.pop_front();
+        } else {
+            ASSERT_TRUE(false) << "workQueue Empty at the start of test";
         }
-        if (sv.range.num != 1 || sv.range.denom != 1) {
-            cout << ":" << sv.range.num << "/" << sv.range.denom;
-        }
-        cout << " " << sv.range.max << ")";
     }
-    if (sv.values.size()) {
-        ALOGD("Dumping FSV value");
-        cout << (sv.type == FieldSupportedValues::Type::FLAGS ? ".flags("
-                                                              : ".list(");
-        const char* sep = "";
-        for (const auto& p : sv.values) {
-            cout << sep << p;
-            sep = ",";
-        }
-        cout << ")";
+    ASSERT_NE(work, nullptr);
+
+    work->input.flags = (C2FrameData::flags_t)flags;
+    work->input.ordinal.timestamp = 0;
+    work->input.ordinal.frameIndex = 0;
+    work->input.buffers.clear();
+    if (isNullBuffer) {
+        work->input.buffers.emplace_back(nullptr);
     }
-    cout << endl;
+    work->worklets.clear();
+    work->worklets.emplace_back(new C2Worklet);
+
+    std::list<std::unique_ptr<C2Work>> items;
+    items.push_back(std::move(work));
+    ASSERT_EQ(component->queue(&items), C2_OK);
 }
+
+// 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) {
+    typedef std::unique_lock<std::mutex> ULock;
+    uint32_t queueSize;
+    uint32_t maxRetry = 0;
+    {
+        ULock l(queueLock);
+        queueSize = workQueue.size();
+    }
+    while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
+        ULock l(queueLock);
+        if (queueSize != workQueue.size()) {
+            queueSize = workQueue.size();
+            maxRetry = 0;
+        } else {
+            queueCondition.wait_for(l, TIME_OUT);
+            maxRetry++;
+        }
+    }
+}
+
+// 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) {
+    // 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::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() == C2StreamCsdInfo::output::PARAM_TYPE) {
+                csd = true;
+            } else if ((param->index() ==
+                        C2StreamSampleRateInfo::output::PARAM_TYPE) ||
+                       (param->index() ==
+                        C2StreamChannelCountInfo::output::PARAM_TYPE) ||
+                       (param->index() ==
+                        C2VideoSizeStreamInfo::output::PARAM_TYPE)) {
+                configParam.push_back(param);
+            }
+        }
+        component->config(configParam, C2_DONT_BLOCK, &failures);
+        ASSERT_EQ(failures.size(), 0u);
+    }
+    framesReceived++;
+    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",
+          (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
+    work->input.buffers.clear();
+    work->worklets.clear();
+    {
+        typedef std::unique_lock<std::mutex> ULock;
+        ULock l(queueLock);
+        workQueue.push_back(std::move(work));
+        if (!flushedIndices.empty()) {
+            flushedIndices.erase(frameIndexIt);
+        }
+        queueCondition.notify_all();
+    }
+}
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h
index f765baa..a688530 100644
--- a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h
@@ -22,6 +22,7 @@
 #include <android/hardware/media/c2/1.0/types.h>
 
 #include <C2Component.h>
+#include <C2Config.h>
 #include <getopt.h>
 #include <hidl/HidlSupport.h>
 #include <media/stagefright/foundation/ALooper.h>
@@ -38,6 +39,10 @@
 
 #include <VtsHalHidlTargetTestEnvBase.h>
 
+#define MAX_RETRY 20
+#define TIME_OUT 400ms
+#define MAX_INPUT_BUFFERS 8
+
 /*
  * Handle Callback functions onWorkDone(), onTripped(),
  * onError(), onDeath(), onFramesRendered()
@@ -176,5 +181,21 @@
 /*
  * common functions declarations
  */
-void dumpFSV(const FieldSupportedValues& sv);
+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,
+                            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);
+
 #endif  // MEDIA_C2_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp
index b7fb655..ec803d7 100644
--- a/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp
+++ b/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp
@@ -38,14 +38,21 @@
    public:
     virtual void SetUp() override {
         Super::SetUp();
+        mEos = false;
         mClient = android::Codec2Client::CreateFromService(
             gEnv->getInstance().c_str());
         ASSERT_NE(mClient, nullptr);
-        mListener.reset(new CodecListener());
+        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);
         ASSERT_NE(mComponent, nullptr);
+        for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
+            mWorkQueue.emplace_back(new C2Work);
+        }
     }
 
     virtual void TearDown() override {
@@ -59,6 +66,23 @@
         }
         Super::TearDown();
     }
+    // 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()) {
+                bool mCsd = false;
+                uint32_t mFramesReceived = 0;
+                std::list<uint64_t> mFlushedIndices;
+                workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition,
+                         mWorkQueue, mEos, mCsd, mFramesReceived);
+            }
+        }
+    }
+
+    bool mEos;
+    std::mutex mQueueLock;
+    std::condition_variable mQueueCondition;
+    std::list<std::unique_ptr<C2Work>> mWorkQueue;
 
     std::shared_ptr<android::Codec2Client> mClient;
     std::shared_ptr<android::Codec2Client::Listener> mListener;
@@ -135,8 +159,6 @@
     ALOGV("Multiple Start Stop and Reset Test");
     c2_status_t err = C2_OK;
 
-#define MAX_RETRY 16
-
     for (size_t i = 0; i < MAX_RETRY; i++) {
         err = mComponent->start();
         ASSERT_EQ(err, C2_OK);
@@ -184,13 +206,44 @@
     ASSERT_EQ(err, C2_OK);
     ASSERT_EQ(failures.size(), 0u);
 
-#define MAX_RETRY 16
     for (size_t i = 0; i < MAX_RETRY; i++) {
         err = mComponent->release();
         ASSERT_EQ(err, C2_OK);
     }
 }
 
+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)));
+
 }  // anonymous namespace
 
 // TODO: Add test for Invalid work,
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.av1 b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.av1
new file mode 100644
index 0000000..1d67af9
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.av1
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.info b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.info
new file mode 100644
index 0000000..cc51168
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.info
@@ -0,0 +1,300 @@
+6027 1 0
+6879 0 33000
+5 0 66000
+532 0 100000
+5 0 133000
+2458 0 166000
+5 0 200000
+475 0 233000
+5 0 266000
+1262 0 300000
+5 0 333000
+554 0 366000
+27 0 400000
+6971 0 433000
+5 0 466000
+601 0 500000
+5 0 533000
+3276 0 566000
+5 0 600000
+658 0 633000
+5 0 666000
+1680 0 700000
+5 0 733000
+610 0 766000
+24 0 800000
+6728 0 833000
+5 0 866000
+764 0 900000
+5 0 933000
+2656 0 966000
+5 0 1000000
+462 0 1033000
+5 0 1066000
+1459 0 1100000
+5 0 1133000
+608 0 1166000
+24 0 1200000
+7038 0 1233000
+5 0 1266000
+721 0 1300000
+5 0 1333000
+3102 0 1366000
+5 0 1400000
+752 0 1433000
+5 0 1466000
+1815 0 1500000
+5 0 1533000
+755 0 1566000
+25 0 1600000
+7657 0 1633000
+5 0 1666000
+852 0 1700000
+5 0 1733000
+3537 0 1766000
+5 0 1800000
+673 0 1833000
+5 0 1866000
+1774 0 1900000
+5 0 1933000
+554 0 1966000
+24 0 2000000
+8028 0 2033000
+5 0 2066000
+715 0 2100000
+5 0 2133000
+3395 0 2166000
+5 0 2200000
+736 0 2233000
+5 0 2266000
+1759 0 2300000
+5 0 2333000
+605 0 2366000
+23 0 2400000
+7651 0 2433000
+5 0 2466000
+619 0 2500000
+5 0 2533000
+2788 0 2566000
+5 0 2600000
+556 0 2633000
+5 0 2666000
+1335 0 2700000
+5 0 2733000
+521 0 2766000
+24 0 2800000
+2274 0 2833000
+676 0 2866000
+25 0 2900000
+6224 0 2933000
+5798 0 2966000
+5 0 3000000
+448 0 3033000
+5 0 3066000
+1950 0 3100000
+5 0 3133000
+386 0 3166000
+5 0 3200000
+1218 0 3233000
+5 0 3266000
+1316 0 3300000
+5 0 3333000
+580 0 3366000
+26 0 3400000
+6673 0 3433000
+5 0 3466000
+473 0 3500000
+5 0 3533000
+2467 0 3566000
+5 0 3600000
+429 0 3633000
+5 0 3666000
+1420 0 3700000
+5 0 3733000
+583 0 3766000
+29 0 3800000
+8492 0 3833000
+5 0 3866000
+720 0 3900000
+5 0 3933000
+3635 0 3966000
+5 0 4000000
+621 0 4033000
+5 0 4066000
+1969 0 4100000
+5 0 4133000
+49 0 4166000
+25 0 4200000
+7416 0 4233000
+5 0 4266000
+947 0 4300000
+5 0 4333000
+3713 0 4366000
+5 0 4400000
+714 0 4433000
+5 0 4466000
+2003 0 4500000
+5 0 4533000
+750 0 4566000
+25 0 4600000
+8470 0 4633000
+5 0 4666000
+737 0 4700000
+5 0 4733000
+4094 0 4766000
+5 0 4800000
+1019 0 4833000
+5 0 4866000
+2160 0 4900000
+5 0 4933000
+828 0 4966000
+24 0 5000000
+9282 0 5033000
+5 0 5066000
+655 0 5100000
+5 0 5133000
+3491 0 5166000
+5 0 5200000
+651 0 5233000
+5 0 5266000
+1906 0 5300000
+5 0 5333000
+662 0 5366000
+24 0 5400000
+9724 0 5433000
+5 0 5466000
+617 0 5500000
+5 0 5533000
+3145 0 5566000
+5 0 5600000
+578 0 5633000
+5 0 5666000
+1592 0 5700000
+5 0 5733000
+569 0 5766000
+25 0 5800000
+10015 0 5833000
+5 0 5866000
+609 0 5900000
+5 0 5933000
+3618 0 5966000
+5 0 6000000
+734 0 6033000
+5 0 6066000
+1748 0 6100000
+5 0 6133000
+550 0 6166000
+24 0 6200000
+8806 0 6233000
+5 0 6266000
+498 0 6300000
+5 0 6333000
+2913 0 6366000
+5 0 6400000
+597 0 6433000
+5 0 6466000
+1235 0 6500000
+5 0 6533000
+362 0 6566000
+24 0 6600000
+6592 0 6633000
+5 0 6666000
+468 0 6700000
+5 0 6733000
+1920 0 6766000
+5 0 6800000
+419 0 6833000
+5 0 6866000
+843 0 6900000
+5 0 6933000
+237 0 6966000
+24 0 7000000
+2687 0 7033000
+5 0 7066000
+399 0 7100000
+5 0 7133000
+200 0 7166000
+143 0 7200000
+25 0 7233000
+12603 0 7266000
+1139 0 7300000
+5 0 7333000
+56 0 7366000
+5 0 7400000
+273 0 7433000
+5 0 7466000
+48 0 7500000
+5 0 7533000
+102 0 7566000
+5 0 7600000
+39 0 7633000
+24 0 7666000
+3635 0 7700000
+5 0 7733000
+46 0 7766000
+5 0 7800000
+647 0 7833000
+5 0 7866000
+61 0 7900000
+5 0 7933000
+824 0 7966000
+5 0 8000000
+691 0 8033000
+27 0 8066000
+4573 0 8100000
+5 0 8133000
+473 0 8166000
+5 0 8200000
+1637 0 8233000
+5 0 8266000
+451 0 8300000
+5 0 8333000
+969 0 8366000
+5 0 8400000
+234 0 8433000
+24 0 8466000
+3361 0 8500000
+5 0 8533000
+168 0 8566000
+5 0 8600000
+662 0 8633000
+5 0 8666000
+129 0 8700000
+5 0 8733000
+443 0 8766000
+5 0 8800000
+183 0 8833000
+23 0 8866000
+2769 0 8900000
+5 0 8933000
+182 0 8966000
+5 0 9000000
+890 0 9033000
+5 0 9066000
+171 0 9100000
+5 0 9133000
+599 0 9166000
+5 0 9200000
+236 0 9233000
+23 0 9266000
+2316 0 9300000
+5 0 9333000
+333 0 9366000
+5 0 9400000
+759 0 9433000
+5 0 9466000
+210 0 9500000
+5 0 9533000
+324 0 9566000
+5 0 9600000
+98 0 9633000
+23 0 9666000
+1107 0 9700000
+5 0 9733000
+42 0 9766000
+5 0 9800000
+145 0 9833000
+5 0 9866000
+109 0 9900000
+89 0 9933000
+24 0 9966000
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.av1 b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.av1
new file mode 100644
index 0000000..529bace
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.av1
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.info b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.info
new file mode 100644
index 0000000..fca7833
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.info
@@ -0,0 +1,167 @@
+12571 1 0
+9881 0 33000
+5 0 66000
+544 0 100000
+5 0 133000
+2642 0 166000
+5 0 200000
+531 0 233000
+5 0 266000
+1359 0 300000
+5 0 333000
+551 0 366000
+28 0 400000
+10791 0 433000
+5 0 466000
+655 0 500000
+5 0 533000
+3769 0 566000
+5 0 600000
+711 0 633000
+5 0 666000
+2004 0 700000
+5 0 733000
+657 0 766000
+26 0 800000
+8969 0 833000
+5 0 866000
+630 0 900000
+5 0 933000
+2787 0 966000
+5 0 1000000
+404 0 1033000
+5 0 1066000
+1518 0 1100000
+5 0 1133000
+493 0 1166000
+26 0 1200000
+9900 0 1233000
+5 0 1266000
+620 0 1300000
+5 0 1333000
+3072 0 1366000
+5 0 1400000
+668 0 1433000
+5 0 1466000
+1821 0 1500000
+5 0 1533000
+682 0 1566000
+26 0 1600000
+9560 0 1633000
+5 0 1666000
+667 0 1700000
+5 0 1733000
+3249 0 1766000
+5 0 1800000
+589 0 1833000
+5 0 1866000
+1816 0 1900000
+5 0 1933000
+548 0 1966000
+26 0 2000000
+9916 0 2033000
+5 0 2066000
+628 0 2100000
+5 0 2133000
+3034 0 2166000
+5 0 2200000
+590 0 2233000
+5 0 2266000
+1581 0 2300000
+5 0 2333000
+524 0 2366000
+26 0 2400000
+8182 0 2433000
+5 0 2466000
+552 0 2500000
+5 0 2533000
+2412 0 2566000
+5 0 2600000
+489 0 2633000
+5 0 2666000
+1227 0 2700000
+5 0 2733000
+432 0 2766000
+26 0 2800000
+2017 0 2833000
+516 0 2866000
+26 0 2900000
+16619 0 2933000
+6710 0 2966000
+5 0 3000000
+425 0 3033000
+5 0 3066000
+1964 0 3100000
+5 0 3133000
+386 0 3166000
+5 0 3200000
+1129 0 3233000
+5 0 3266000
+1156 0 3300000
+5 0 3333000
+486 0 3366000
+28 0 3400000
+10304 0 3433000
+5 0 3466000
+412 0 3500000
+5 0 3533000
+2608 0 3566000
+5 0 3600000
+397 0 3633000
+5 0 3666000
+1514 0 3700000
+5 0 3733000
+533 0 3766000
+26 0 3800000
+11698 0 3833000
+5 0 3866000
+542 0 3900000
+5 0 3933000
+3334 0 3966000
+5 0 4000000
+547 0 4033000
+5 0 4066000
+1809 0 4100000
+5 0 4133000
+55 0 4166000
+26 0 4200000
+9496 0 4233000
+5 0 4266000
+658 0 4300000
+5 0 4333000
+3232 0 4366000
+5 0 4400000
+600 0 4433000
+5 0 4466000
+1766 0 4500000
+5 0 4533000
+550 0 4566000
+25 0 4600000
+9951 0 4633000
+5 0 4666000
+624 0 4700000
+5 0 4733000
+3617 0 4766000
+5 0 4800000
+644 0 4833000
+5 0 4866000
+1841 0 4900000
+5 0 4933000
+649 0 4966000
+25 0 5000000
+9901 0 5033000
+5 0 5066000
+515 0 5100000
+5 0 5133000
+2814 0 5166000
+5 0 5200000
+511 0 5233000
+5 0 5266000
+1521 0 5300000
+5 0 5333000
+509 0 5366000
+26 0 5400000
+10579 0 5433000
+5 0 5466000
+575 0 5500000
+5 0 5533000
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
index 8420cab..9a42d72 100644
--- a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
@@ -101,7 +101,7 @@
 
         const StringToName kStringToName[] = {
             {"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
-            {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
+            {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9}, {"av1", av1},
         };
 
         const size_t kNumStringToName =
@@ -142,79 +142,48 @@
     // callback function to process onWorkDone received by Listener
     void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
         for (std::unique_ptr<C2Work>& work : workItems) {
-            // handle configuration changes in work done
-            if (!work->worklets.empty() &&
-                (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::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() ==
-                        C2VideoSizeStreamInfo::output::PARAM_TYPE) {
-                        ALOGV("Received C2VideoSizeStreamInfo");
-                        configParam.push_back(param);
-                    }
-                }
-                mComponent->config(configParam, C2_DONT_BLOCK, &failures);
-                ASSERT_EQ(failures.size(), 0u);
-            }
+            if (!work->worklets.empty()) {
+                // For decoder components current timestamp always exceeds
+                // previous timestamp
+                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();
 
-            mFramesReceived++;
-            mEos = (work->worklets.front()->output.flags &
-                    C2FrameData::FLAG_END_OF_STREAM) != 0;
-            auto frameIndexIt =
-                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
-                          work->input.ordinal.frameIndex.peeku());
-
-            // For decoder components current timestamp always exceeds
-            // previous timestamp
-            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();
-
-                ULock l(mQueueLock);
-                if (mTimestampDevTest) {
-                    bool tsHit = false;
-                    std::list<uint64_t>::iterator it = mTimestampUslist.begin();
-                    while (it != mTimestampUslist.end()) {
-                        if (*it == mTimestampUs) {
-                            mTimestampUslist.erase(it);
-                            tsHit = true;
-                            break;
+                    ULock l(mQueueLock);
+                    if (mTimestampDevTest) {
+                        bool tsHit = false;
+                        std::list<uint64_t>::iterator it = mTimestampUslist.begin();
+                        while (it != mTimestampUslist.end()) {
+                            if (*it == mTimestampUs) {
+                                mTimestampUslist.erase(it);
+                                tsHit = true;
+                                break;
+                            }
+                            it++;
                         }
-                        it++;
-                    }
-                    if (tsHit == false) {
-                        if (mTimestampUslist.empty() == false) {
-                            EXPECT_EQ(tsHit, true)
-                                << "TimeStamp not recognized";
-                        } else {
-                            std::cout << "[   INFO   ] Received non-zero "
-                                         "output / TimeStamp not recognized \n";
+                        if (tsHit == false) {
+                            if (mTimestampUslist.empty() == false) {
+                                EXPECT_EQ(tsHit, true)
+                                    << "TimeStamp not recognized";
+                            } else {
+                                std::cout << "[   INFO   ] Received non-zero "
+                                             "output / TimeStamp not recognized \n";
+                            }
                         }
                     }
                 }
-            }
-
-            work->input.buffers.clear();
-            work->worklets.clear();
-            {
-                ULock l(mQueueLock);
-                mWorkQueue.push_back(std::move(work));
-                if (!mFlushedIndices.empty()) {
-                    mFlushedIndices.erase(frameIndexIt);
-                }
-                mQueueCondition.notify_all();
+                bool mCsd;
+                workDone(mComponent, work, mFlushedIndices, mQueueLock,
+                         mQueueCondition, mWorkQueue, mEos, mCsd,
+                         mFramesReceived);
+                (void)mCsd;
             }
         }
     }
@@ -227,6 +196,7 @@
         hevc,
         vp8,
         vp9,
+        av1,
         unknown_comp,
     };
 
@@ -341,6 +311,11 @@
           "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) {
@@ -352,11 +327,11 @@
     }
 }
 
-void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
-                   std::mutex &queueLock, std::condition_variable &queueCondition,
-                   std::list<std::unique_ptr<C2Work>> &workQueue,
-                   std::list<uint64_t> &flushedIndices,
-                   std::shared_ptr<C2BlockPool> &linearPool,
+void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+                   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) {
@@ -397,35 +372,37 @@
 
         int size = (*Info)[frameID].bytesCount;
         char* data = (char*)malloc(size);
+        ASSERT_NE(data, nullptr);
 
         eleStream.read(data, size);
         ASSERT_EQ(eleStream.gcount(), size);
 
-        std::shared_ptr<C2LinearBlock> block;
-        ASSERT_EQ(C2_OK,
-                  linearPool->fetchLinearBlock(
-                      size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
-                      &block));
-        ASSERT_TRUE(block);
-
-        // Write View
-        C2WriteView view = block->map().get();
-        if (view.error() != C2_OK) {
-            fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
-            break;
-        }
-        ASSERT_EQ((size_t)size, view.capacity());
-        ASSERT_EQ(0u, view.offset());
-        ASSERT_EQ((size_t)size, view.size());
-
-        memcpy(view.base(), data, size);
-
         work->input.buffers.clear();
-        work->input.buffers.emplace_back(new LinearBuffer(block));
+        if (size) {
+            std::shared_ptr<C2LinearBlock> block;
+            ASSERT_EQ(C2_OK,
+                    linearPool->fetchLinearBlock(
+                        size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+                        &block));
+            ASSERT_TRUE(block);
+
+            // Write View
+            C2WriteView view = block->map().get();
+            if (view.error() != C2_OK) {
+                fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+                break;
+            }
+            ASSERT_EQ((size_t)size, view.capacity());
+            ASSERT_EQ(0u, view.offset());
+            ASSERT_EQ((size_t)size, view.size());
+
+            memcpy(view.base(), data, size);
+
+            work->input.buffers.emplace_back(new LinearBuffer(block));
+            free(data);
+        }
         work->worklets.clear();
         work->worklets.emplace_back(new C2Worklet);
-        free(data);
-
         std::list<std::unique_ptr<C2Work>> items;
         items.push_back(std::move(work));
 
@@ -437,29 +414,6 @@
     }
 }
 
-void waitOnInputConsumption(std::mutex& queueLock,
-                            std::condition_variable& queueCondition,
-                            std::list<std::unique_ptr<C2Work>>& workQueue,
-                            size_t bufferCount = MAX_INPUT_BUFFERS) {
-    typedef std::unique_lock<std::mutex> ULock;
-    uint32_t queueSize;
-    uint32_t maxRetry = 0;
-    {
-        ULock l(queueLock);
-        queueSize = workQueue.size();
-    }
-    while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
-        ULock l(queueLock);
-        if (queueSize != workQueue.size()) {
-            queueSize = workQueue.size();
-            maxRetry = 0;
-        } else {
-            queueCondition.wait_for(l, TIME_OUT);
-            maxRetry++;
-        }
-    }
-}
-
 TEST_F(Codec2VideoDecHidlTest, validateCompName) {
     if (mDisableTest) return;
     ALOGV("Checks if the given component is a valid video component");
@@ -678,8 +632,8 @@
         EXPECT_GE(mFramesReceived, 1U);
         ASSERT_EQ(mEos, true);
         ASSERT_EQ(mComponent->stop(), C2_OK);
-        ASSERT_EQ(mComponent->release(), C2_OK);
     }
+    ASSERT_EQ(mComponent->release(), C2_OK);
 }
 
 TEST_F(Codec2VideoDecHidlTest, EOSTest) {
@@ -712,7 +666,6 @@
     ASSERT_EQ(mComponent->queue(&items), C2_OK);
 
     {
-        typedef std::unique_lock<std::mutex> ULock;
         ULock l(mQueueLock);
         if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
             mQueueCondition.wait_for(l, TIME_OUT);
@@ -723,46 +676,6 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2VideoDecHidlTest, EmptyBufferTest) {
-    description("Tests empty input buffer");
-    if (mDisableTest) return;
-    typedef std::unique_lock<std::mutex> ULock;
-    ASSERT_EQ(mComponent->start(), C2_OK);
-    std::unique_ptr<C2Work> work;
-    // Prepare C2Work
-    {
-        ULock l(mQueueLock);
-        if (!mWorkQueue.empty()) {
-            work.swap(mWorkQueue.front());
-            mWorkQueue.pop_front();
-        } else {
-            ASSERT_TRUE(false) << "mWorkQueue Empty at the start of test";
-        }
-    }
-    ASSERT_NE(work, nullptr);
-
-    work->input.flags = (C2FrameData::flags_t)0;
-    work->input.ordinal.timestamp = 0;
-    work->input.ordinal.frameIndex = 0;
-    work->input.buffers.clear();
-    work->worklets.clear();
-    work->worklets.emplace_back(new C2Worklet);
-
-    std::list<std::unique_ptr<C2Work>> items;
-    items.push_back(std::move(work));
-    ASSERT_EQ(mComponent->queue(&items), C2_OK);
-
-    {
-        typedef std::unique_lock<std::mutex> ULock;
-        ULock l(mQueueLock);
-        if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
-            mQueueCondition.wait_for(l, TIME_OUT);
-        }
-    }
-    ASSERT_EQ(mWorkQueue.size(), (size_t)MAX_INPUT_BUFFERS);
-    ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
 TEST_F(Codec2VideoDecHidlTest, FlushTest) {
     description("Tests Flush calls");
     if (mDisableTest) return;
@@ -874,6 +787,69 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
+TEST_F(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) {
+    description("Decode with multiple empty input frames");
+    if (mDisableTest) return;
+
+    char mURL[512], info[512];
+    std::ifstream eleStream, eleInfo;
+
+    strcpy(mURL, gEnv->getRes().c_str());
+    strcpy(info, gEnv->getRes().c_str());
+    GetURLForComponent(mCompName, mURL, info);
+
+    eleInfo.open(info);
+    ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+    android::Vector<FrameInfo> Info;
+    int bytesCount = 0;
+    uint32_t frameId = 0;
+    uint32_t flags = 0;
+    uint32_t timestamp = 0;
+    bool codecConfig = false;
+    // This test introduces empty CSD after every 20th frame
+    // and empty input frames at an interval of 5 frames.
+    while (1) {
+        if (!(frameId % 5)) {
+            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;
+        }
+        Info.push_back({bytesCount, flags, timestamp});
+        frameId++;
+    }
+    eleInfo.close();
+
+    ASSERT_EQ(mComponent->start(), C2_OK);
+    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()));
+
+    // 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));
+    }
+
+    eleStream.close();
+    if (mFramesReceived != Info.size()) {
+        ALOGE("Input buffer count and Output buffer count mismatch");
+        ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+              Info.size());
+        ASSERT_TRUE(false);
+    }
+}
+
 }  // anonymous namespace
 
 // TODO : Video specific configuration Test
diff --git a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
index 87b7902..8585c87 100644
--- a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
@@ -139,40 +139,11 @@
     // callback function to process onWorkDone received by Listener
     void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
         for (std::unique_ptr<C2Work>& work : workItems) {
-            // handle configuration changes in work done
-            if (!work->worklets.empty() &&
-                (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::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() == C2StreamCsdInfo::output::PARAM_TYPE) {
-                        mCsd = true;
-                    }
-                }
-            }
-            mFramesReceived++;
-            if (work->result != C2_OK) mFailedWorkReceived++;
-            mEos = (work->worklets.front()->output.flags &
-                    C2FrameData::FLAG_END_OF_STREAM) != 0;
-            auto frameIndexIt =
-                std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
-                          work->input.ordinal.frameIndex.peeku());
-            ALOGV("WorkDone: frameID received %d",
-                (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
-            work->input.buffers.clear();
-            work->worklets.clear();
-            {
-                typedef std::unique_lock<std::mutex> ULock;
-                ULock l(mQueueLock);
-                mWorkQueue.push_back(std::move(work));
-                if (!mFlushedIndices.empty()) {
-                    mFlushedIndices.erase(frameIndexIt);
-                }
-                mQueueCondition.notify_all();
+            if (!work->worklets.empty()) {
+                if (work->result != C2_OK) mFailedWorkReceived++;
+                workDone(mComponent, work, mFlushedIndices, mQueueLock,
+                         mQueueCondition, mWorkQueue, mEos, mCsd,
+                         mFramesReceived);
             }
         }
     }
@@ -272,11 +243,11 @@
     strcat(URL, "bbb_352x288_420p_30fps_32frames.yuv");
 }
 
-void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
-                   std::mutex &queueLock, std::condition_variable &queueCondition,
-                   std::list<std::unique_ptr<C2Work>> &workQueue,
-                   std::list<uint64_t> &flushedIndices,
-                   std::shared_ptr<C2BlockPool> &graphicPool,
+void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+                   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, uint32_t frameID,
                    uint32_t nFrames, uint32_t nWidth, int32_t nHeight,
                    bool flushed = false,bool signalEOS = true) {
@@ -319,6 +290,7 @@
             flushedIndices.emplace_back(frameID);
         }
         char* data = (char*)malloc(bytesCount);
+        ASSERT_NE(data, nullptr);
         memset(data, 0, bytesCount);
         if (eleStream.is_open()) {
             eleStream.read(data, bytesCount);
@@ -365,30 +337,6 @@
     }
 }
 
-void waitOnInputConsumption(std::mutex &queueLock,
-                            std::condition_variable &queueCondition,
-                            std::list<std::unique_ptr<C2Work>> &workQueue,
-                            size_t bufferCount = MAX_INPUT_BUFFERS) {
-    typedef std::unique_lock<std::mutex> ULock;
-    uint32_t queueSize;
-    int maxRetry = 0;
-    {
-        ULock l(queueLock);
-        queueSize = workQueue.size();
-    }
-    while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
-        ULock l(queueLock);
-        if (queueSize != workQueue.size()) {
-            queueSize = workQueue.size();
-            maxRetry = 0;
-        } else {
-            queueCondition.wait_for(l, TIME_OUT);
-            maxRetry++;
-        }
-    }
-}
-
-
 TEST_F(Codec2VideoEncHidlTest, validateCompName) {
     if (mDisableTest) return;
     ALOGV("Checks if the given component is a valid video component");
@@ -488,46 +436,6 @@
     ASSERT_EQ(mComponent->stop(), C2_OK);
 }
 
-TEST_F(Codec2VideoEncHidlTest, EmptyBufferTest) {
-    description("Tests empty input buffer");
-    if (mDisableTest) return;
-    ASSERT_EQ(mComponent->start(), C2_OK);
-
-    typedef std::unique_lock<std::mutex> ULock;
-    std::unique_ptr<C2Work> work;
-    {
-        ULock l(mQueueLock);
-        if (!mWorkQueue.empty()) {
-            work.swap(mWorkQueue.front());
-            mWorkQueue.pop_front();
-        } else {
-            ALOGE("mWorkQueue Empty is not expected at the start of the test");
-            ASSERT_TRUE(false);
-        }
-    }
-    ASSERT_NE(work, nullptr);
-    work->input.flags = (C2FrameData::flags_t)0;
-    work->input.ordinal.timestamp = 0;
-    work->input.ordinal.frameIndex = 0;
-    work->input.buffers.clear();
-    work->worklets.clear();
-    work->worklets.emplace_back(new C2Worklet);
-
-    std::list<std::unique_ptr<C2Work>> items;
-    items.push_back(std::move(work));
-    ASSERT_EQ(mComponent->queue(&items), C2_OK);
-    uint32_t queueSize;
-    {
-        ULock l(mQueueLock);
-        queueSize = mWorkQueue.size();
-        if (queueSize < MAX_INPUT_BUFFERS) {
-            mQueueCondition.wait_for(l, TIME_OUT);
-        }
-    }
-    ASSERT_EQ(mWorkQueue.size(), (uint32_t)MAX_INPUT_BUFFERS);
-    ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
 TEST_F(Codec2VideoEncHidlTest, FlushTest) {
     description("Test Request for flush");
     if (mDisableTest) return;
diff --git a/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h b/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h
index 1215b13..dd45557 100644
--- a/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h
@@ -17,9 +17,6 @@
 #ifndef MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
 #define MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
 
-#define MAX_RETRY 20
-#define TIME_OUT 400ms
-#define MAX_INPUT_BUFFERS 8
 #define ENCODER_TIMESTAMP_INCREMENT 40000
 #define ENC_NUM_FRAMES 32
 #define ENC_DEFAULT_FRAME_WIDTH 352