diff --git a/media/omx/1.0/vts/functional/README.md b/media/omx/1.0/vts/functional/README.md
index fa88811..acffc42 100644
--- a/media/omx/1.0/vts/functional/README.md
+++ b/media/omx/1.0/vts/functional/README.md
@@ -9,7 +9,7 @@
 usage: VtsHalMediaOmxV1\_0TargetMasterTest -I default
 
 #### component :
-This folder includes test fixtures that tests aspects common to all omx compatible components. For instance, port enabling/disabling, enumerating port formats, state transitions, flush, ..., stay common to all components irrespective of the service they offer. Test fixtures are directed towards testing the omx core. Every standard OMX compatible component is expected to pass these tests.
+This folder includes test fixtures that tests aspects common to all omx compatible components. For instance, port enabling/disabling, enumerating port formats, state transitions, flush, ..., stay common to all components irrespective of the service they offer. Test fixtures here are directed towards testing these (omx core). Every standard OMX compatible component is expected to pass these tests.
 
 usage: VtsHalMediaOmxV1\_0TargetComponentTest -I default -C <comp name> -R <comp role>
 
@@ -31,3 +31,4 @@
 
 VtsHalMediaOmxV1\_0TargetVideoEncTest -I default -C <comp name> -R video_encoder.<comp class> -P /sdcard/media/
 
+While tesing audio/video encoder, decoder components, test fixtures require input files. These input are files are present in the folder 'res'. Before running the tests all the files in 'res' have to be placed in '/media/sdcard/' or a path of your choice and this path needs to be provided as an argument to the test application
\ No newline at end of file
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
index 30344a1..01d7751 100755
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
@@ -425,8 +425,15 @@
         Message msg;
         status =
             observer->dequeueMessage(&msg, DEFAULT_TIMEOUT, iBuffer, oBuffer);
-        EXPECT_EQ(status,
-                  android::hardware::media::omx::V1_0::Status::TIMED_OUT);
+        if (status == android::hardware::media::omx::V1_0::Status::OK) {
+            if (msg.data.eventData.event == OMX_EventBufferFlag) {
+                // soft omx components donot send this, we will just ignore it
+                // for now
+            } else {
+                // something unexpected happened
+                EXPECT_TRUE(false);
+            }
+        }
         if (eosFlag == true) break;
     }
     // test for flag
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
index 8caf697..8ab01b5 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoDecTest.cpp
@@ -214,7 +214,7 @@
                                strlen(gEnv->getComponent().c_str()) - suffixLen,
                            ".secure");
         if (isSecure) disableTest = true;
-        if (disableTest) std::cerr << "[          ] Warning !  Test Disabled\n";
+        if (disableTest) std::cout << "[          ] Warning !  Test Disabled\n";
     }
 
     virtual void TearDown() override {
@@ -257,7 +257,7 @@
                             EXPECT_EQ(tsHit, true)
                                 << "TimeStamp not recognized";
                         } else {
-                            std::cerr
+                            std::cout
                                 << "[          ] Warning ! Received non-zero "
                                    "output / TimeStamp not recognized \n";
                         }
@@ -478,7 +478,8 @@
 
     if (msg.data.eventData.event == OMX_EventPortSettingsChanged) {
         ASSERT_EQ(msg.data.eventData.data1, kPortIndexOutput);
-        if (msg.data.eventData.data2 == 0) {
+        if (msg.data.eventData.data2 == OMX_IndexParamPortDefinition ||
+            msg.data.eventData.data2 == 0) {
             status = omxNode->sendCommand(
                 toRawCommandType(OMX_CommandPortDisable), kPortIndexOutput);
             ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
@@ -532,6 +533,20 @@
 
                 allocatePortBuffers(omxNode, oBuffer, kPortIndexOutput,
                                     oPortMode);
+                if (oPortMode != PortMode::PRESET_BYTE_BUFFER) {
+                    OMX_PARAM_PORTDEFINITIONTYPE portDef;
+
+                    status = getPortParam(omxNode, OMX_IndexParamPortDefinition,
+                                          kPortIndexOutput, &portDef);
+                    ASSERT_EQ(
+                        status,
+                        ::android::hardware::media::omx::V1_0::Status::OK);
+                    allocateGraphicBuffers(omxNode, kPortIndexOutput, oBuffer,
+                                           portDef.format.video.nFrameWidth,
+                                           portDef.format.video.nFrameHeight,
+                                           &portDef.format.video.nStride,
+                                           portDef.nBufferCountActual);
+                }
                 status = observer->dequeueMessage(&msg, DEFAULT_TIMEOUT,
                                                   iBuffer, oBuffer);
                 ASSERT_EQ(status,
@@ -549,16 +564,19 @@
             }
         } else if (msg.data.eventData.data2 ==
                    OMX_IndexConfigCommonOutputCrop) {
-            std::cerr << "[          ] Warning ! OMX_EventPortSettingsChanged/ "
+            std::cout << "[          ] Warning ! OMX_EventPortSettingsChanged/ "
                          "OMX_IndexConfigCommonOutputCrop not handled \n";
         } else if (msg.data.eventData.data2 == OMX_IndexVendorStartUnused + 3) {
-            std::cerr << "[          ] Warning ! OMX_EventPortSettingsChanged/ "
+            std::cout << "[          ] Warning ! OMX_EventPortSettingsChanged/ "
                          "kDescribeColorAspectsIndex not handled \n";
         }
     } else if (msg.data.eventData.event == OMX_EventError) {
-        std::cerr << "[          ] Warning ! OMX_EventError/ "
+        std::cout << "[          ] Warning ! OMX_EventError/ "
                      "Decode Frame Call might be failed \n";
         return;
+    } else if (msg.data.eventData.event == OMX_EventBufferFlag) {
+        // soft omx components donot send this, we will just ignore it
+        // for now
     } else {
         // something unexpected happened
         ASSERT_TRUE(false);
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
index 6bc95ca..7a57430 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
@@ -27,6 +27,7 @@
 #include <android/hardware/graphics/mapper/2.0/types.h>
 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
 #include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
 #include <android/hardware/media/omx/1.0/types.h>
@@ -39,6 +40,7 @@
 using ::android::hardware::graphics::common::V1_0::BufferUsage;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
 using ::android::hardware::media::omx::V1_0::IGraphicBufferSource;
+using ::android::hardware::media::omx::V1_0::IOmxBufferSource;
 using ::android::hardware::media::omx::V1_0::IOmx;
 using ::android::hardware::media::omx::V1_0::IOmxObserver;
 using ::android::hardware::media::omx::V1_0::IOmxNode;
@@ -345,6 +347,82 @@
     android::Mutex bufferLock;
 };
 
+// Mock IOmxBufferSource class. GraphicBufferSource.cpp in libstagefright/omx/
+// implements this class. Below is dummy class introduced to test if callback
+// functions are actually being called or not
+struct DummyBufferSource : public IOmxBufferSource {
+   public:
+    DummyBufferSource(sp<IOmxNode> node) {
+        callback = 0;
+        executing = false;
+        omxNode = node;
+    }
+    virtual Return<void> onOmxExecuting();
+    virtual Return<void> onOmxIdle();
+    virtual Return<void> onOmxLoaded();
+    virtual Return<void> onInputBufferAdded(uint32_t buffer);
+    virtual Return<void> onInputBufferEmptied(
+        uint32_t buffer, const ::android::hardware::hidl_handle& fence);
+
+    int callback;
+    bool executing;
+    sp<IOmxNode> omxNode;
+    android::Vector<BufferInfo> iBuffer, oBuffer;
+};
+
+Return<void> DummyBufferSource::onOmxExecuting() {
+    executing = true;
+    callback |= 0x1;
+    size_t index;
+    // Fetch a client owned input buffer and send an EOS
+    if ((index = getEmptyBufferID(&iBuffer)) < iBuffer.size()) {
+        android::hardware::media::omx::V1_0::Status status;
+        CodecBuffer t = iBuffer[index].omxBuffer;
+        t.type = CodecBuffer::Type::ANW_BUFFER;
+        native_handle_t* fenceNh = native_handle_create(0, 0);
+        EXPECT_NE(fenceNh, nullptr);
+        status = omxNode->emptyBuffer(iBuffer[index].id, t, OMX_BUFFERFLAG_EOS,
+                                      0, fenceNh);
+        native_handle_close(fenceNh);
+        native_handle_delete(fenceNh);
+        EXPECT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+        iBuffer.editItemAt(index).owner = component;
+    }
+    return Void();
+};
+
+Return<void> DummyBufferSource::onOmxIdle() {
+    callback |= 0x2;
+    executing = false;
+    return Void();
+};
+
+Return<void> DummyBufferSource::onOmxLoaded() {
+    callback |= 0x4;
+    return Void();
+};
+
+Return<void> DummyBufferSource::onInputBufferAdded(uint32_t buffer) {
+    (void)buffer;
+    EXPECT_EQ(executing, false);
+    callback |= 0x8;
+    return Void();
+};
+
+Return<void> DummyBufferSource::onInputBufferEmptied(
+    uint32_t buffer, const ::android::hardware::hidl_handle& fence) {
+    (void)fence;
+    callback |= 0x10;
+    size_t i;
+    for (i = 0; i < iBuffer.size(); i++) {
+        if (iBuffer[i].id == buffer) {
+            iBuffer.editItemAt(i).owner = client;
+            break;
+        }
+    }
+    return Void();
+};
+
 // request VOP refresh
 void requestIDR(sp<IOmxNode> omxNode, OMX_U32 portIndex) {
     android::hardware::media::omx::V1_0::Status status;
@@ -419,6 +497,27 @@
         std::cerr << "[          ] Warning ! unable to set Refresh Period \n";
 }
 
+void setLatency(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t latency) {
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_PARAM_U32TYPE param;
+    param.nU32 = (OMX_U32)latency;
+    status = setPortConfig(omxNode, (OMX_INDEXTYPE)OMX_IndexConfigLatency,
+                           portIndex, &param);
+    if (status != ::android::hardware::media::omx::V1_0::Status::OK)
+        std::cerr << "[          ] Warning ! unable to set latency\n";
+}
+
+void getLatency(sp<IOmxNode> omxNode, OMX_U32 portIndex, uint32_t* latency) {
+    android::hardware::media::omx::V1_0::Status status;
+    OMX_PARAM_U32TYPE param;
+    status = getPortConfig(omxNode, (OMX_INDEXTYPE)OMX_IndexConfigLatency,
+                           portIndex, &param);
+    if (status != ::android::hardware::media::omx::V1_0::Status::OK)
+        std::cerr << "[          ] Warning ! unable to get latency\n";
+    else
+        *latency = param.nU32;
+}
+
 // Set Default port param.
 void setDefaultPortParam(sp<IOmxNode> omxNode, OMX_U32 portIndex,
                          OMX_VIDEO_CODINGTYPE eCompressionFormat,
@@ -586,7 +685,7 @@
                   android::hardware::graphics::mapper::V2_0::Error::NONE);
         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
             return 1;
-    } else if (format == PixelFormat::YCBCR_420_888) {
+    } else {
         void* data;
         mapper->lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
                      [&](android::hardware::graphics::mapper::V2_0::Error _e,
@@ -599,32 +698,75 @@
         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
             return 1;
 
-        ycbcrLayout.chromaStep = 1;
-        ycbcrLayout.yStride = buffer->omxBuffer.attr.anwBuffer.stride;
-        ycbcrLayout.cStride = ycbcrLayout.yStride >> 1;
-        ycbcrLayout.y = data;
-        ycbcrLayout.cb = static_cast<char*>(ycbcrLayout.y) +
-                         (ycbcrLayout.yStride * rect.height);
-        ycbcrLayout.cr = static_cast<char*>(ycbcrLayout.cb) +
-                         ((ycbcrLayout.yStride * rect.height) >> 2);
+        if (format == PixelFormat::YCBCR_420_888) {
+            ycbcrLayout.chromaStep = 1;
+            ycbcrLayout.yStride = buffer->omxBuffer.attr.anwBuffer.stride;
+            ycbcrLayout.cStride = ycbcrLayout.yStride >> 1;
+            ycbcrLayout.y = data;
+            ycbcrLayout.cb = static_cast<char*>(ycbcrLayout.y) +
+                             (ycbcrLayout.yStride * rect.height);
+            ycbcrLayout.cr = static_cast<char*>(ycbcrLayout.cb) +
+                             ((ycbcrLayout.yStride * rect.height) >> 2);
 
-        char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
-        for (size_t y = rect.height; y > 0; --y) {
-            eleStream.read(ipBuffer, rect.width);
-            if (eleStream.gcount() != rect.width) return 1;
-            ipBuffer += ycbcrLayout.yStride;
-        }
-        ipBuffer = static_cast<char*>(ycbcrLayout.cb);
-        for (size_t y = rect.height >> 1; y > 0; --y) {
-            eleStream.read(ipBuffer, rect.width >> 1);
-            if (eleStream.gcount() != rect.width >> 1) return 1;
-            ipBuffer += ycbcrLayout.cStride;
-        }
-        ipBuffer = static_cast<char*>(ycbcrLayout.cr);
-        for (size_t y = rect.height >> 1; y > 0; --y) {
-            eleStream.read(ipBuffer, rect.width >> 1);
-            if (eleStream.gcount() != rect.width >> 1) return 1;
-            ipBuffer += ycbcrLayout.cStride;
+            char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
+            for (size_t y = rect.height; y > 0; --y) {
+                eleStream.read(ipBuffer, rect.width);
+                if (eleStream.gcount() != rect.width) return 1;
+                ipBuffer += ycbcrLayout.yStride;
+            }
+            ipBuffer = static_cast<char*>(ycbcrLayout.cb);
+            for (size_t y = rect.height >> 1; y > 0; --y) {
+                eleStream.read(ipBuffer, rect.width >> 1);
+                if (eleStream.gcount() != rect.width >> 1) return 1;
+                ipBuffer += ycbcrLayout.cStride;
+            }
+            ipBuffer = static_cast<char*>(ycbcrLayout.cr);
+            for (size_t y = rect.height >> 1; y > 0; --y) {
+                eleStream.read(ipBuffer, rect.width >> 1);
+                if (eleStream.gcount() != rect.width >> 1) return 1;
+                ipBuffer += ycbcrLayout.cStride;
+            }
+        } else if (format == PixelFormat::YCRCB_420_SP) {
+            ycbcrLayout.chromaStep = 2;
+            ycbcrLayout.yStride = buffer->omxBuffer.attr.anwBuffer.stride;
+            ycbcrLayout.cStride = ycbcrLayout.yStride;
+            ycbcrLayout.y = data;
+            ycbcrLayout.cr = static_cast<char*>(ycbcrLayout.y) +
+                             (ycbcrLayout.yStride * rect.height);
+            ycbcrLayout.cb = static_cast<char*>(ycbcrLayout.cr) + 1;
+
+            char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
+            for (size_t y = rect.height; y > 0; --y) {
+                eleStream.read(ipBuffer, rect.width);
+                if (eleStream.gcount() != rect.width) return 1;
+                ipBuffer += ycbcrLayout.yStride;
+            }
+            ipBuffer = static_cast<char*>(ycbcrLayout.cb);
+            for (size_t y = rect.height >> 1; y > 0; --y) {
+                for (int32_t x = 0; x<rect.width>> 1; ++x) {
+                    eleStream.read(&ipBuffer[2 * x], 1);
+                    if (eleStream.gcount() != 1) return 1;
+                }
+                ipBuffer += ycbcrLayout.cStride;
+            }
+            ipBuffer = static_cast<char*>(ycbcrLayout.cr);
+            for (size_t y = rect.height >> 1; y > 0; --y) {
+                for (int32_t x = 0; x<rect.width>> 1; ++x) {
+                    eleStream.read(&ipBuffer[2 * x], 1);
+                    if (eleStream.gcount() != 1) return 1;
+                }
+                ipBuffer += ycbcrLayout.cStride;
+            }
+        } else if (format == PixelFormat::BGRA_8888) {
+            char* ipBuffer = static_cast<char*>(data);
+            for (size_t y = rect.height; y > 0; --y) {
+                eleStream.read(ipBuffer, rect.width * 4);
+                if (eleStream.gcount() != rect.width * 4) return 1;
+                ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
+            }
+        } else {
+            EXPECT_TRUE(false) << "un expected pixel format";
+            return 1;
         }
 
         mapper->unlock(buff,
@@ -637,9 +779,6 @@
                   android::hardware::graphics::mapper::V2_0::Error::NONE);
         if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
             return 1;
-    } else {
-        EXPECT_TRUE(false) << "un expected pixel format";
-        return 1;
     }
 
     return 0;
@@ -959,6 +1098,63 @@
     EXPECT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
 }
 
+// Test IOmxBufferSource CallBacks
+TEST_F(VideoEncHidlTest, BufferSourceCallBacks) {
+    description("Test IOmxBufferSource CallBacks");
+    if (disableTest) return;
+    android::hardware::media::omx::V1_0::Status status;
+    uint32_t kPortIndexInput = 0, kPortIndexOutput = 1;
+    status = setRole(omxNode, gEnv->getRole().c_str());
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    OMX_PORT_PARAM_TYPE params;
+    status = getParam(omxNode, OMX_IndexParamVideoInit, &params);
+    if (status == ::android::hardware::media::omx::V1_0::Status::OK) {
+        ASSERT_EQ(params.nPorts, 2U);
+        kPortIndexInput = params.nStartPortNumber;
+        kPortIndexOutput = kPortIndexInput + 1;
+    }
+
+    // Configure input port
+    uint32_t nFrameWidth = 352;
+    uint32_t nFrameHeight = 288;
+    uint32_t xFramerate = (30U << 16);
+    OMX_COLOR_FORMATTYPE eColorFormat = OMX_COLOR_FormatAndroidOpaque;
+    setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
+                 xFramerate, eColorFormat);
+
+    sp<DummyBufferSource> buffersource = new DummyBufferSource(omxNode);
+    EXPECT_NE(buffersource, nullptr);
+    status = omxNode->setInputSurface(buffersource);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+    // set port mode
+    PortMode portMode[2];
+    portMode[0] = PortMode::DYNAMIC_ANW_BUFFER;
+    portMode[1] = PortMode::PRESET_BYTE_BUFFER;
+    status = omxNode->setPortMode(kPortIndexInput, portMode[0]);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+    status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
+    // set state to idle
+    changeStateLoadedtoIdle(omxNode, observer, &buffersource->iBuffer,
+                            &buffersource->oBuffer, kPortIndexInput,
+                            kPortIndexOutput, portMode);
+    // set state to executing
+    changeStateIdletoExecute(omxNode, observer);
+    testEOS(omxNode, observer, &buffersource->iBuffer, &buffersource->oBuffer,
+            false, eosFlag);
+    // set state to idle
+    changeStateExecutetoIdle(omxNode, observer, &buffersource->iBuffer,
+                             &buffersource->oBuffer);
+    // set state to executing
+    changeStateIdletoLoaded(omxNode, observer, &buffersource->iBuffer,
+                            &buffersource->oBuffer, kPortIndexInput,
+                            kPortIndexOutput);
+    // test for callbacks
+    EXPECT_EQ(buffersource->callback, 31);
+}
+
 // test raw stream encode (input is byte buffers)
 TEST_F(VideoEncHidlTest, EncodeTest) {
     description("Test Encode");
@@ -1023,6 +1219,10 @@
     status = omxNode->setPortMode(kPortIndexOutput, portMode[1]);
     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
 
+    uint32_t latency = 0;
+    setLatency(omxNode, kPortIndexInput, latency);
+    getLatency(omxNode, kPortIndexInput, &latency);
+
     android::Vector<BufferInfo> iBuffer, oBuffer;
 
     // set state to idle
@@ -1086,12 +1286,6 @@
     ASSERT_NE(producer, nullptr);
     ASSERT_NE(source, nullptr);
 
-    // Do setInputSurface()
-    // enable MetaMode on input port
-    status = source->configure(
-        omxNode, android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN);
-    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
-
     // setMaxDequeuedBufferCount
     int32_t returnval;
     int32_t value;
@@ -1125,6 +1319,12 @@
                           kPortIndexInput, &portDef);
     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
 
+    // Do setInputSurface()
+    // enable MetaMode on input port
+    status = source->configure(
+        omxNode, android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
     // set port mode
     PortMode portMode[2];
     portMode[0] = PortMode::DYNAMIC_ANW_BUFFER;
@@ -1138,6 +1338,10 @@
     strcpy(mURL, gEnv->getRes().c_str());
     GetURLForComponent(mURL);
 
+    uint32_t latency = 0;
+    setLatency(omxNode, kPortIndexInput, latency);
+    getLatency(omxNode, kPortIndexInput, &latency);
+
     std::ifstream eleStream;
 
     status = source->setSuspend(false, 0);
@@ -1232,12 +1436,6 @@
     ASSERT_NE(producer, nullptr);
     ASSERT_NE(source, nullptr);
 
-    // Do setInputSurface()
-    // enable MetaMode on input port
-    status = source->configure(
-        omxNode, android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN);
-    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
-
     // setMaxDequeuedBufferCount
     int32_t returnval;
     int32_t value;
@@ -1271,6 +1469,12 @@
                           kPortIndexInput, &portDef);
     ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
 
+    // Do setInputSurface()
+    // enable MetaMode on input port
+    status = source->configure(
+        omxNode, android::hardware::graphics::common::V1_0::Dataspace::UNKNOWN);
+    ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);
+
     // set port mode
     PortMode portMode[2];
     portMode[0] = PortMode::DYNAMIC_ANW_BUFFER;
