From 058e343f8d0c99a219037b281a42dabc75774bfb Mon Sep 17 00:00:00 2001 From: Amy Date: Mon, 7 Oct 2019 17:28:23 -0700 Subject: [PATCH] Adding a Broadcast data flow test with a PES filter Test: atest Bug: 135708935 Change-Id: I64166ae5113a7c0bfd834a85c722a860c1d16694 (cherry picked from commit 4bad0f9840dd1fcf4e57fe736af07af09240a263) --- .../VtsHalTvTunerV1_0TargetTest.cpp | 122 ++++++++++++++++-- 1 file changed, 113 insertions(+), 9 deletions(-) diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 30fe08a188..7936185af5 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -254,6 +254,7 @@ class DemuxCallback : public IDemuxCallback { void testOnFilterEvent(uint32_t filterId); void testFilterDataOutput(); + void stopInputThread(); void startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor); void startFilterEventThread(DemuxFilterEvent event); @@ -290,6 +291,7 @@ class DemuxCallback : public IDemuxCallback { android::Mutex mMsgLock; android::Mutex mFilterOutputLock; + android::Mutex mInputThreadLock; android::Condition mMsgCondition; android::Condition mFilterOutputCondition; @@ -326,15 +328,21 @@ void DemuxCallback::startFilterEventThread(DemuxFilterEvent event) { void DemuxCallback::testFilterDataOutput() { android::Mutex::Autolock autoLock(mMsgLock); - while (mPidFilterOutputCount < 3) { + while (mPidFilterOutputCount < 1) { if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) { EXPECT_TRUE(false) << "filter output matching pid does not output within timeout"; return; } } + mPidFilterOutputCount = 0; ALOGW("[vts] pass and stop"); +} + +void DemuxCallback::stopInputThread() { mInputThreadRunning = false; mKeepWritingInputFMQ = false; + + android::Mutex::Autolock autoLock(mInputThreadLock); } void DemuxCallback::updateFilterMQ(uint32_t filterId, MQDesc& filterMQDescriptor) { @@ -358,6 +366,7 @@ void* DemuxCallback::__threadLoopInput(void* threadArgs) { } void DemuxCallback::inputThreadLoop(InputConf* inputConf, bool* keepWritingInputFMQ) { + android::Mutex::Autolock autoLock(mInputThreadLock); mInputThreadRunning = true; // Create the EventFlag that is used to signal the HAL impl that data have been @@ -372,13 +381,12 @@ void DemuxCallback::inputThreadLoop(InputConf* inputConf, bool* keepWritingInput char* buffer = new char[writeSize]; ALOGW("[vts] input thread loop start %s", inputConf->inputDataFile.c_str()); if (!inputData.is_open()) { - // log mInputThreadRunning = false; ALOGW("[vts] Error %s", strerror(errno)); } while (mInputThreadRunning) { - // move the stream pointer for packet size * 100 every read until the end + // move the stream pointer for packet size * 6 every read until the end while (*keepWritingInputFMQ) { inputData.read(buffer, writeSize); if (!inputData) { @@ -502,7 +510,8 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { ::testing::AssertionResult stopTuneFrontend(int32_t frontendId); ::testing::AssertionResult closeFrontend(int32_t frontendId); ::testing::AssertionResult createDemux(); - ::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId); + ::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId, + FrontendSettings settings); ::testing::AssertionResult getInputMQDescriptor(); ::testing::AssertionResult addInputToDemux(DemuxInputSettings setting); ::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting); @@ -514,6 +523,8 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { ::testing::AssertionResult playbackDataFlowTest(vector filterConf, InputConf inputConf, vector goldenOutputFiles); + ::testing::AssertionResult broadcastDataFlowTest(vector filterConf, + vector goldenOutputFiles); }; ::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) { @@ -588,7 +599,8 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { return ::testing::AssertionResult(status == Result::SUCCESS); } -::testing::AssertionResult TunerHidlTest::createDemuxWithFrontend(int32_t frontendId) { +::testing::AssertionResult TunerHidlTest::createDemuxWithFrontend(int32_t frontendId, + FrontendSettings settings) { Result status; if (!mDemux && createDemux() == ::testing::AssertionFailure()) { @@ -599,6 +611,8 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { return ::testing::AssertionFailure(); } + mFrontendCallback->testOnEvent(mFrontend, settings); + status = mDemux->setFrontendDataSource(frontendId); return ::testing::AssertionResult(status == Result::SUCCESS); @@ -772,6 +786,7 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { // Data Verify Module mDemuxCallback->testFilterDataOutput(); + mDemuxCallback->stopInputThread(); // Clean Up Module for (int i = 0; i <= filterIdsSize; i++) { @@ -785,6 +800,65 @@ class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase { return closeDemux(); } +::testing::AssertionResult TunerHidlTest::broadcastDataFlowTest( + vector filterConf, vector /*goldenOutputFiles*/) { + Result status; + hidl_vec feIds; + + mService->getFrontendIds([&](Result result, const hidl_vec& frontendIds) { + status = result; + feIds = frontendIds; + }); + + if (feIds.size() == 0) { + ALOGW("[ WARN ] Frontend isn't available"); + return ::testing::AssertionFailure(); + } + + FrontendDvbtSettings dvbt{ + .frequency = 1000, + }; + FrontendSettings settings; + settings.dvbt(dvbt); + + if (createDemuxWithFrontend(feIds[0], settings) != ::testing::AssertionSuccess()) { + return ::testing::AssertionFailure(); + } + + int filterIdsSize; + // 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(); + } + filterIdsSize = mUsedFilterIds.size(); + mUsedFilterIds.resize(filterIdsSize + 1); + mUsedFilterIds[filterIdsSize] = mFilterId; + mDemuxCallback->updateFilterMQ(mFilterId, mFilterMQDescriptor); + status = mDemux->startFilter(mFilterId); + if (status != Result::SUCCESS) { + return ::testing::AssertionFailure(); + } + } + + // Data Verify Module + mDemuxCallback->testFilterDataOutput(); + + // Clean Up Module + for (int i = 0; i <= filterIdsSize; i++) { + if (mDemux->stopFilter(mUsedFilterIds[i]) != Result::SUCCESS) { + return ::testing::AssertionFailure(); + } + } + if (mFrontend->stopTune() != Result::SUCCESS) { + return ::testing::AssertionFailure(); + } + return closeDemux(); +} + /* * API STATUS TESTS */ @@ -868,7 +942,7 @@ TEST_F(TunerHidlTest, CloseFrontend) { } } -TEST_F(TunerHidlTest, CreateDemuxWithFrontend) { +/*TEST_F(TunerHidlTest, CreateDemuxWithFrontend) { Result status; hidl_vec feIds; @@ -883,10 +957,17 @@ TEST_F(TunerHidlTest, CreateDemuxWithFrontend) { return; } + FrontendDvbtSettings dvbt{ + .frequency = 1000, + }; + FrontendSettings settings; + settings.dvbt(dvbt); + for (size_t i = 0; i < feIds.size(); i++) { - ASSERT_TRUE(createDemuxWithFrontend(feIds[i])); + ASSERT_TRUE(createDemuxWithFrontend(feIds[i], settings)); + mFrontend->stopTune(); } -} +}*/ TEST_F(TunerHidlTest, CreateDemux) { description("Create Demux"); @@ -920,7 +1001,7 @@ TEST_F(TunerHidlTest, PlaybackDataFlowWithPesFilterTest) { DemuxFilterSettings filterSetting; DemuxFilterPesDataSettings pesFilterSetting{ - .tpid = 4720, + .tpid = 18, }; filterSetting.pesData(pesFilterSetting); FilterConf pesFilterConf{ @@ -947,6 +1028,29 @@ TEST_F(TunerHidlTest, PlaybackDataFlowWithPesFilterTest) { ASSERT_TRUE(playbackDataFlowTest(filterConf, inputConf, goldenOutputFiles)); } +TEST_F(TunerHidlTest, BroadcastDataFlowWithPesFilterTest) { + description("Feed ts data from frontend and test with PES filter"); + + // todo modulize the filter conf parser + vector filterConf; + filterConf.resize(1); + + DemuxFilterSettings filterSetting; + DemuxFilterPesDataSettings pesFilterSetting{ + .tpid = 18, + }; + filterSetting.pesData(pesFilterSetting); + FilterConf pesFilterConf{ + .type = DemuxFilterType::PES, + .setting = filterSetting, + }; + filterConf[0] = pesFilterConf; + + vector goldenOutputFiles; + + ASSERT_TRUE(broadcastDataFlowTest(filterConf, goldenOutputFiles)); +} + } // namespace int main(int argc, char** argv) {