diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 66adb2a..d272d71 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -34,6 +34,8 @@
 #include <hidlmemory/FrameworkUtils.h>
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
+#include <fstream>
+#include <iostream>
 
 #define WAIT_TIMEOUT 3000000000
 
@@ -53,11 +55,16 @@
 using android::hardware::MQDescriptorSync;
 using android::hardware::Return;
 using android::hardware::Void;
+using android::hardware::tv::tuner::V1_0::DemuxDataFormat;
 using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
 using android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
 using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
 using android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
 using android::hardware::tv::tuner::V1_0::DemuxFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxInputSettings;
+using android::hardware::tv::tuner::V1_0::DemuxInputStatus;
+using android::hardware::tv::tuner::V1_0::DemuxOutputStatus;
 using android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits;
 using android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
 using android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
@@ -77,9 +84,9 @@
 namespace {
 
 using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-using FilterMQDesc = MQDescriptorSync<uint8_t>;
+using MQDesc = MQDescriptorSync<uint8_t>;
 
-const std::vector<uint8_t> goldenDataInputBuffer{
+const std::vector<uint8_t> goldenDataOutputBuffer{
         0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
         0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
         0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
@@ -119,10 +126,21 @@
 };
 
 const uint16_t FMQ_SIZE_4K = 0x1000;
+const uint32_t FMQ_SIZE_1M = 0x100000;
 // Equal to SECTION_WRITE_COUNT on the HAL impl side
 // The HAL impl will repeatedly write to the FMQ the count times
 const uint16_t SECTION_READ_COUNT = 10;
 
+struct FilterConf {
+    DemuxFilterType type;
+    DemuxFilterSettings setting;
+};
+
+struct InputConf {
+    string inputDataFile;
+    DemuxInputSettings setting;
+};
+
 class FrontendCallback : public IFrontendCallback {
   public:
     virtual Return<void> onEvent(FrontendEventType frontendEventType) override {
@@ -184,8 +202,10 @@
 class DemuxCallback : public IDemuxCallback {
   public:
     virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent) override {
+        ALOGW("[VTS] FILTER EVENT %d", filterEvent.filterId);
         android::Mutex::Autolock autoLock(mMsgLock);
         mFilterEventReceived = true;
+        // maybe assemble here??
         mFilterEvent = filterEvent;
         mMsgCondition.signal();
         return Void();
@@ -196,24 +216,53 @@
         return Void();
     }
 
+    virtual Return<void> onOutputStatus(DemuxOutputStatus /*status*/) override { return Void(); }
+
+    virtual Return<void> onInputStatus(DemuxInputStatus status) override {
+        // android::Mutex::Autolock autoLock(mMsgLock);
+        switch (status) {
+            case DemuxInputStatus::SPACE_EMPTY:
+            case DemuxInputStatus::SPACE_ALMOST_EMPTY:
+                mKeepWritingInputFMQ = true;
+                break;
+            case DemuxInputStatus::SPACE_ALMOST_FULL:
+            case DemuxInputStatus::SPACE_FULL:
+                mKeepWritingInputFMQ = false;
+                break;
+        }
+        return Void();
+    }
+
     void testOnFilterEvent(uint32_t filterId);
-    void testOnSectionFilterEvent(sp<IDemux>& demux, uint32_t filterId,
-                                  FilterMQDesc& filterMQDescriptor);
-    void testOnPesFilterEvent(sp<IDemux>& demux, uint32_t filterId,
-                              FilterMQDesc& filterMQDescriptor);
-    void readAndCompareSectionEventData();
-    void readAndComparePesEventData();
+    void testOnSectionFilterEvent(sp<IDemux>& demux, uint32_t filterId, MQDesc& filterMQDescriptor,
+                                  MQDesc& inputMQDescriptor);
+    void startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor);
+    bool readAndCompareSectionEventData();
+
+    static void* __threadLoopInput(void* threadArgs);
+    void inputThreadLoop(InputConf inputConf, bool* keepWritingInputFMQ, MQDesc& inputMQDescriptor);
 
   private:
+    struct InputThreadArgs {
+        DemuxCallback* user;
+        InputConf inputConf;
+        bool* keepWritingInputFMQ;
+        MQDesc& inputMQDesc;
+    };
     bool mFilterEventReceived = false;
     std::vector<uint8_t> mDataOutputBuffer;
     std::unique_ptr<FilterMQ> mFilterMQ;
+    std::unique_ptr<FilterMQ> mInputMQ;
     uint16_t mDataLength = 0;
     DemuxFilterEvent mFilterEvent;
     android::Mutex mMsgLock;
     android::Mutex mReadLock;
     android::Condition mMsgCondition;
     EventFlag* mFilterMQEventFlag;
+    EventFlag* mInputMQEventFlag;
+    bool mKeepWritingInputFMQ;
+    bool mInputThreadRunning;
+    pthread_t mInputThread;
 };
 
 void DemuxCallback::testOnFilterEvent(uint32_t filterId) {
@@ -230,83 +279,138 @@
     EXPECT_TRUE(filterId == mFilterEvent.filterId) << "filter id match";
 }
 
+void DemuxCallback::startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor) {
+    struct InputThreadArgs* threadArgs =
+            (struct InputThreadArgs*)malloc(sizeof(struct InputThreadArgs));
+    threadArgs->user = this;
+    threadArgs->inputConf = inputConf;
+    threadArgs->keepWritingInputFMQ = &mKeepWritingInputFMQ;
+    threadArgs->inputMQDesc = inputMQDescriptor;
+
+    pthread_create(&mInputThread, NULL, __threadLoopInput, (void*)threadArgs);
+    pthread_setname_np(mInputThread, "test_playback_input_loop");
+}
+
+/*void DemuxCallback::testPlaybackDataFlow(bool* keepWritingInputFMQ) {
+    // timeout logic here
+
+    // assemble logic here
+
+
+}*/
+
 void DemuxCallback::testOnSectionFilterEvent(sp<IDemux>& demux, uint32_t filterId,
-                                             FilterMQDesc& filterMQDescriptor) {
+                                             MQDesc& filterMQDescriptor,
+                                             MQDesc& inputMQDescriptor) {
     Result status;
     // Create MQ to read the output into the local buffer
     mFilterMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
     EXPECT_TRUE(mFilterMQ);
+    // Get the MQ to write the input to the HAL
+    mInputMQ = std::make_unique<FilterMQ>(inputMQDescriptor, true /* resetPointers */);
+    EXPECT_TRUE(mInputMQ);
     // Create the EventFlag that is used to signal the HAL impl that data have been
     // read the Filter FMQ
     EXPECT_TRUE(EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag) ==
                 android::OK);
+    // Create the EventFlag that is used to signal the HAL impl that data have been
+    // written into the Input FMQ
+    EXPECT_TRUE(EventFlag::createEventFlag(mInputMQ->getEventFlagWord(), &mInputMQEventFlag) ==
+                android::OK);
     // Start filter
     status = demux->startFilter(filterId);
+    status = demux->startInput();
+
     EXPECT_EQ(status, Result::SUCCESS);
     // Test start filter and receive callback event
     for (int i = 0; i < SECTION_READ_COUNT; i++) {
+        // Write input FMQ and notify the Tuner Implementation
+        EXPECT_TRUE(mInputMQ->write(goldenDataOutputBuffer.data(), goldenDataOutputBuffer.size()));
+        mInputMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
         testOnFilterEvent(filterId);
         // checksum of mDataOutputBuffer and Input golden input
-        readAndCompareSectionEventData();
+        if (readAndCompareSectionEventData() && i < SECTION_READ_COUNT - 1) {
+            mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
+        }
     }
 }
 
-void DemuxCallback::testOnPesFilterEvent(sp<IDemux>& demux, uint32_t filterId,
-                                         FilterMQDesc& filterMQDescriptor) {
-    Result status;
-    // Create MQ to read the output into the local buffer
-    mFilterMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
-    EXPECT_TRUE(mFilterMQ);
-    // Create the EventFlag that is used to signal the HAL impl that data have been
-    // read the Filter FMQ
-    EXPECT_TRUE(EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag) ==
-                android::OK);
-    // Start filter
-    status = demux->startFilter(filterId);
-    EXPECT_EQ(status, Result::SUCCESS);
-    // Test start filter and receive callback event
-    testOnFilterEvent(filterId);
-    // checksum of mDataOutputBuffer and Input golden input
-    readAndComparePesEventData();
-}
-
-void DemuxCallback::readAndCompareSectionEventData() {
+bool DemuxCallback::readAndCompareSectionEventData() {
     bool result = false;
     for (int i = 0; i < mFilterEvent.events.size(); i++) {
         DemuxFilterSectionEvent event = mFilterEvent.events[i].section();
         mDataLength = event.dataLength;
-        EXPECT_TRUE(mDataLength == goldenDataInputBuffer.size()) << "buffer size does not match";
+        EXPECT_TRUE(mDataLength == goldenDataOutputBuffer.size()) << "buffer size does not match";
 
         mDataOutputBuffer.resize(mDataLength);
         result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength);
         EXPECT_TRUE(result) << "can't read from Filter MQ";
 
         for (int i = 0; i < mDataLength; i++) {
-            EXPECT_TRUE(goldenDataInputBuffer[i] == mDataOutputBuffer[i]) << "data does not match";
+            EXPECT_TRUE(goldenDataOutputBuffer[i] == mDataOutputBuffer[i]) << "data does not match";
         }
     }
-    if (result) {
-        mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
-    }
+    return result;
 }
 
-void DemuxCallback::readAndComparePesEventData() {
-    // TODO handle multiple events in one filter callback event
-    DemuxFilterPesEvent event = mFilterEvent.events[0].pes();
-    mDataLength = event.dataLength;
-    EXPECT_TRUE(mDataLength == goldenDataInputBuffer.size()) << "buffer size does not match";
+void* DemuxCallback::__threadLoopInput(void* threadArgs) {
+    DemuxCallback* const self =
+            static_cast<DemuxCallback*>(((struct InputThreadArgs*)threadArgs)->user);
+    self->inputThreadLoop(((struct InputThreadArgs*)threadArgs)->inputConf,
+                          ((struct InputThreadArgs*)threadArgs)->keepWritingInputFMQ,
+                          ((struct InputThreadArgs*)threadArgs)->inputMQDesc);
+    return 0;
+}
 
-    mDataOutputBuffer.resize(mDataLength);
-    bool result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength);
-    EXPECT_TRUE(result) << "can't read from Filter MQ";
+void DemuxCallback::inputThreadLoop(InputConf inputConf, bool* keepWritingInputFMQ,
+                                    MQDesc& inputMQDescriptor) {
+    mInputThreadRunning = true;
 
-    if (result) {
-        mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
+    std::unique_ptr inputMQ =
+            std::make_unique<FilterMQ>(inputMQDescriptor, true /* resetPointers */);
+    EXPECT_TRUE(inputMQ);
+
+    // Create the EventFlag that is used to signal the HAL impl that data have been
+    // written into the Input FMQ
+    EventFlag* inputMQEventFlag;
+    EXPECT_TRUE(EventFlag::createEventFlag(inputMQ->getEventFlagWord(), &inputMQEventFlag) ==
+                android::OK);
+
+    // open the stream and get its length
+    std::ifstream inputData(inputConf.inputDataFile /*"ts/test1.ts"*/, std::ifstream::binary);
+    int writeSize = inputConf.setting.packetSize * 6;
+    char* buffer = new char[writeSize];
+    if (!inputData) {
+        // log
+        mInputThreadRunning = false;
     }
 
-    for (int i = 0; i < mDataLength; i++) {
-        EXPECT_TRUE(goldenDataInputBuffer[i] == mDataOutputBuffer[i]) << "data does not match";
+    while (mInputThreadRunning) {
+        // move the stream pointer for packet size * 2k? every read until end
+        while (*keepWritingInputFMQ) {
+            inputData.read(buffer, writeSize);
+            if (!inputData) {
+                int leftSize = inputData.gcount();
+                inputData.clear();
+                inputData.read(buffer, leftSize);
+                // Write the left over of the input data and quit the thread
+                if (leftSize > 0) {
+                    EXPECT_TRUE(inputMQ->write((unsigned char*)&buffer[0],
+                                               leftSize / inputConf.setting.packetSize));
+                    inputMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+                }
+                mInputThreadRunning = false;
+                break;
+            }
+            // Write input FMQ and notify the Tuner Implementation
+            EXPECT_TRUE(inputMQ->write((unsigned char*)&buffer[0], 6));
+            inputMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+            inputData.seekg(writeSize, inputData.cur);
+        }
     }
+
+    delete[] buffer;
+    inputData.close();
 }
 
 // Test environment for Tuner HIDL HAL.
@@ -341,24 +445,33 @@
     sp<IDescrambler> mDescrambler;
     sp<IDemux> mDemux;
     sp<DemuxCallback> mDemuxCallback;
-    FilterMQDesc mFilterMQDescriptor;
+    MQDesc mFilterMQDescriptor;
+    MQDesc mInputMQDescriptor;
+
     uint32_t mDemuxId;
     uint32_t mFilterId;
 
+    pthread_t mInputThread;
+    bool mInputThreadRunning;
+
     ::testing::AssertionResult createFrontend(int32_t frontendId);
     ::testing::AssertionResult tuneFrontend(int32_t frontendId);
     ::testing::AssertionResult stopTuneFrontend(int32_t frontendId);
     ::testing::AssertionResult closeFrontend(int32_t frontendId);
     ::testing::AssertionResult createDemux();
     ::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId);
+    ::testing::AssertionResult getInputMQDescriptor();
+    ::testing::AssertionResult addInputToDemux(DemuxInputSettings setting);
     ::testing::AssertionResult addSectionFilterToDemux();
-    ::testing::AssertionResult addPesFilterToDemux();
-    ::testing::AssertionResult getFilterMQDescriptor(sp<IDemux>& demux, const uint32_t filterId);
-    ::testing::AssertionResult readSectionFilterDataOutput();
-    ::testing::AssertionResult readPesFilterDataOutput();
+    ::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting);
+    ::testing::AssertionResult getFilterMQDescriptor(const uint32_t filterId);
     ::testing::AssertionResult closeDemux();
     ::testing::AssertionResult createDescrambler();
     ::testing::AssertionResult closeDescrambler();
+
+    ::testing::AssertionResult readSectionFilterDataOutput();
+    ::testing::AssertionResult playbackDataFlowTest(vector<FilterConf> filterConf,
+                                                    InputConf inputConf, string goldenOutput);
 };
 
 ::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) {
@@ -405,7 +518,7 @@
 
 ::testing::AssertionResult TunerHidlTest::stopTuneFrontend(int32_t frontendId) {
     Result status;
-    if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+    if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
         return ::testing::AssertionFailure();
     }
 
@@ -415,11 +528,12 @@
 
 ::testing::AssertionResult TunerHidlTest::closeFrontend(int32_t frontendId) {
     Result status;
-    if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+    if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
         return ::testing::AssertionFailure();
     }
 
     status = mFrontend->close();
+    mFrontend = nullptr;
     return ::testing::AssertionResult(status == Result::SUCCESS);
 }
 
@@ -437,11 +551,11 @@
 ::testing::AssertionResult TunerHidlTest::createDemuxWithFrontend(int32_t frontendId) {
     Result status;
 
-    if (createDemux() == ::testing::AssertionFailure()) {
+    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
         return ::testing::AssertionFailure();
     }
 
-    if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+    if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
         return ::testing::AssertionFailure();
     }
 
@@ -450,111 +564,14 @@
     return ::testing::AssertionResult(status == Result::SUCCESS);
 }
 
-::testing::AssertionResult TunerHidlTest::addSectionFilterToDemux() {
-    Result status;
-
-    if (createDemux() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    // Create demux callback
-    mDemuxCallback = new DemuxCallback();
-
-    // Add section filter to the local demux
-    mDemux->addFilter(DemuxFilterType::SECTION, FMQ_SIZE_4K, mDemuxCallback,
-                      [&](Result result, uint32_t filterId) {
-                          mFilterId = filterId;
-                          status = result;
-                      });
-
-    // Add another section filter to the local demux
-    mDemux->addFilter(DemuxFilterType::SECTION, FMQ_SIZE_4K, mDemuxCallback,
-                      [&](Result result, uint32_t filterId) {
-                          mFilterId = filterId;
-                          status = result;
-                      });
-
-    // TODO Test configure the filter
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::addPesFilterToDemux() {
-    Result status;
-
-    if (createDemux() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    // Create demux callback
-    mDemuxCallback = new DemuxCallback();
-
-    // Add PES filter to the local demux
-    mDemux->addFilter(DemuxFilterType::PES, FMQ_SIZE_4K, mDemuxCallback,
-                      [&](Result result, uint32_t filterId) {
-                          mFilterId = filterId;
-                          status = result;
-                      });
-
-    // Add another PES filter to the local demux
-    mDemux->addFilter(DemuxFilterType::PES, FMQ_SIZE_4K, mDemuxCallback,
-                      [&](Result result, uint32_t filterId) {
-                          mFilterId = filterId;
-                          status = result;
-                      });
-
-    // TODO Test configure the filter
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::getFilterMQDescriptor(sp<IDemux>& demux,
-                                                                const uint32_t filterId) {
-    Result status;
-
-    if (!demux) {
-        return ::testing::AssertionFailure();
-    }
-
-    mDemux->getFilterQueueDesc(filterId, [&](Result result, const FilterMQDesc& filterMQDesc) {
-        mFilterMQDescriptor = filterMQDesc;
-        status = result;
-    });
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::readSectionFilterDataOutput() {
-    if (addSectionFilterToDemux() == ::testing::AssertionFailure() ||
-        getFilterMQDescriptor(mDemux, mFilterId) == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    // Test start filter and read the output data
-    mDemuxCallback->testOnSectionFilterEvent(mDemux, mFilterId, mFilterMQDescriptor);
-
-    return ::testing::AssertionResult(true);
-}
-
-::testing::AssertionResult TunerHidlTest::readPesFilterDataOutput() {
-    if (addPesFilterToDemux() == ::testing::AssertionFailure() ||
-        getFilterMQDescriptor(mDemux, mFilterId) == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    // Test start filter and read the output data
-    mDemuxCallback->testOnPesFilterEvent(mDemux, mFilterId, mFilterMQDescriptor);
-
-    return ::testing::AssertionResult(true);
-}
-
 ::testing::AssertionResult TunerHidlTest::closeDemux() {
     Result status;
-    if (createDemux() == ::testing::AssertionFailure()) {
+    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
         return ::testing::AssertionFailure();
     }
 
     status = mDemux->close();
+    mDemux = nullptr;
     return ::testing::AssertionResult(status == Result::SUCCESS);
 }
 
@@ -569,7 +586,7 @@
         return ::testing::AssertionFailure();
     }
 
-    if (createDemux() == ::testing::AssertionFailure()) {
+    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
         return ::testing::AssertionFailure();
     }
 
@@ -585,14 +602,185 @@
 
 ::testing::AssertionResult TunerHidlTest::closeDescrambler() {
     Result status;
-    if (createDescrambler() == ::testing::AssertionFailure()) {
+    if (!mDescrambler && createDescrambler() == ::testing::AssertionFailure()) {
         return ::testing::AssertionFailure();
     }
 
     status = mDescrambler->close();
+    mDescrambler = nullptr;
     return ::testing::AssertionResult(status == Result::SUCCESS);
 }
 
+::testing::AssertionResult TunerHidlTest::addInputToDemux(DemuxInputSettings setting) {
+    Result status;
+
+    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    // Create demux callback
+    if (!mDemuxCallback) {
+        mDemuxCallback = new DemuxCallback();
+    }
+
+    // Add section filter to the local demux
+    status = mDemux->addInput(FMQ_SIZE_1M, mDemuxCallback);
+
+    if (status != Result::SUCCESS) {
+        return ::testing::AssertionFailure();
+    }
+
+    status = mDemux->configureInput(setting);
+
+    return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::getInputMQDescriptor() {
+    Result status;
+
+    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    mDemux->getInputQueueDesc([&](Result result, const MQDesc& inputMQDesc) {
+        mInputMQDescriptor = inputMQDesc;
+        status = result;
+    });
+
+    return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::addSectionFilterToDemux() {
+    Result status;
+
+    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    // Create demux callback
+    if (!mDemuxCallback) {
+        mDemuxCallback = new DemuxCallback();
+    }
+
+    // Add section filter to the local demux
+    mDemux->addFilter(DemuxFilterType::SECTION, FMQ_SIZE_4K, mDemuxCallback,
+                      [&](Result result, uint32_t filterId) {
+                          mFilterId = filterId;
+                          status = result;
+                      });
+
+    return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::addFilterToDemux(DemuxFilterType type,
+                                                           DemuxFilterSettings setting) {
+    Result status;
+
+    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    // Create demux callback
+    if (!mDemuxCallback) {
+        mDemuxCallback = new DemuxCallback();
+    }
+
+    // Add filter to the local demux
+    mDemux->addFilter(type, FMQ_SIZE_4K, mDemuxCallback, [&](Result result, uint32_t filterId) {
+        // TODO use a map to save all the filter id and FMQ
+        mFilterId = filterId;
+        status = result;
+    });
+
+    if (status != Result::SUCCESS) {
+        return ::testing::AssertionFailure();
+    }
+
+    // Configure the filter
+    status = mDemux->configureFilter(mFilterId, setting);
+
+    return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::getFilterMQDescriptor(const uint32_t filterId) {
+    Result status;
+
+    if (!mDemux) {
+        return ::testing::AssertionFailure();
+    }
+
+    mDemux->getFilterQueueDesc(filterId, [&](Result result, const MQDesc& filterMQDesc) {
+        mFilterMQDescriptor = filterMQDesc;
+        status = result;
+    });
+
+    return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::readSectionFilterDataOutput() {
+    // Filter Configuration Module
+    DemuxInputSettings setting{
+            .statusMask = 0xf,
+            .lowThreshold = 0x1000,
+            .highThreshold = 0x100000,
+            .dataFormat = DemuxDataFormat::TS,
+            .packetSize = 188,
+    };
+    if (addSectionFilterToDemux() == ::testing::AssertionFailure() ||
+        getFilterMQDescriptor(mFilterId) == ::testing::AssertionFailure() ||
+        addInputToDemux(setting) == ::testing::AssertionFailure() ||
+        getInputMQDescriptor() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    // Data Verify Module
+    // Test start filter and read the output data
+    mDemuxCallback->testOnSectionFilterEvent(mDemux, mFilterId, mFilterMQDescriptor,
+                                             mInputMQDescriptor);
+
+    // Clean Up Module
+    return closeDemux();  //::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult TunerHidlTest::playbackDataFlowTest(vector<FilterConf> filterConf,
+                                                               InputConf inputConf,
+                                                               string /*goldenOutput*/) {
+    Result status;
+    // Filter Configuration Module
+    for (int i = 0; i < filterConf.size(); i++) {
+        if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
+                    ::testing::AssertionFailure() ||
+            // TODO use a map to save the FMQs/EvenFlags and pass to callback
+            getFilterMQDescriptor(mFilterId) == ::testing::AssertionFailure()) {
+            return ::testing::AssertionFailure();
+        }
+    }
+
+    // Playback Input Module
+    DemuxInputSettings inputSetting = inputConf.setting;
+    if (addInputToDemux(inputSetting) == ::testing::AssertionFailure() ||
+        getInputMQDescriptor() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+    mDemuxCallback->startPlaybackInputThread(inputConf, mInputMQDescriptor);
+    status = mDemux->startInput();
+    if (status != Result::SUCCESS) {
+        return ::testing::AssertionFailure();
+    }
+
+    // Data Verify Module
+    // golden output, created FMQ to read and EventFlags to DATA_CONSUMED
+    // Maintain each filter's real output (and how to assemble?????)
+    // mDemuxCallback->testPlaybackDataFlow();
+
+    // Clean Up Module
+    // TODO what about remove input, remove filters
+    return closeDemux();
+}
+
+/*
+ * API STATUS TESTS
+ */
 TEST_F(TunerHidlTest, CreateFrontend) {
     Result status;
     hidl_vec<FrontendId> feIds;
@@ -673,12 +861,6 @@
     }
 }
 
-TEST_F(TunerHidlTest, CreateDemux) {
-    description("Create Demux");
-
-    ASSERT_TRUE(createDemux());
-}
-
 TEST_F(TunerHidlTest, CreateDemuxWithFrontend) {
     Result status;
     hidl_vec<FrontendId> feIds;
@@ -699,50 +881,34 @@
     }
 }
 
-TEST_F(TunerHidlTest, AddSectionFilterToDemux) {
-    description("Add a section filter to a created demux");
-    ASSERT_TRUE(addSectionFilterToDemux());
-}
-
-TEST_F(TunerHidlTest, AddPesFilterToDemux) {
-    description("Add a pes filter to a created demux");
-    ASSERT_TRUE(addPesFilterToDemux());
-}
-
-TEST_F(TunerHidlTest, GetFilterMQDescriptor) {
-    description("Get MQ Descriptor from a created filter");
-    ASSERT_TRUE(addSectionFilterToDemux());
-    ASSERT_TRUE(getFilterMQDescriptor(mDemux, mFilterId));
-}
-
-TEST_F(TunerHidlTest, ReadSectionFilterOutput) {
-    description("Read data output from FMQ of a Section Filter");
-    ASSERT_TRUE(readSectionFilterDataOutput());
-}
-
-TEST_F(TunerHidlTest, ReadPesFilterOutput) {
-    description("Read data output from FMQ of a PES Filter");
-    ASSERT_TRUE(readPesFilterDataOutput());
+TEST_F(TunerHidlTest, CreateDemux) {
+    description("Create Demux");
+    ASSERT_TRUE(createDemux());
 }
 
 TEST_F(TunerHidlTest, CloseDemux) {
     description("Close Demux");
-
     ASSERT_TRUE(closeDemux());
 }
 
 TEST_F(TunerHidlTest, CreateDescrambler) {
     description("Create Descrambler");
-
     ASSERT_TRUE(createDescrambler());
 }
 
 TEST_F(TunerHidlTest, CloseDescrambler) {
     description("Close Descrambler");
-
     ASSERT_TRUE(closeDescrambler());
 }
 
+/*
+ * DATA FLOW TESTS
+ */
+TEST_F(TunerHidlTest, ReadSectionFilterOutput) {
+    description("Read data output from FMQ of a Section Filter");
+    ASSERT_TRUE(readSectionFilterDataOutput());
+}
+
 }  // namespace
 
 int main(int argc, char** argv) {
