diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp index 67eff1bd63..b122a05017 100644 --- a/tv/tuner/1.0/default/Demux.cpp +++ b/tv/tuner/1.0/default/Demux.cpp @@ -294,6 +294,11 @@ void Demux::updateFilterOutput(uint16_t filterId, vector data) { mFilters[filterId]->updateFilterOutput(data); } +void Demux::updateMediaFilterOutput(uint16_t filterId, vector data, uint64_t pts) { + updateFilterOutput(filterId, data); + mFilters[filterId]->updatePts(pts); +} + uint16_t Demux::getFilterTpid(uint32_t filterId) { return mFilters[filterId]->getTpid(); } @@ -322,6 +327,12 @@ void Demux::frontendInputThreadLoop() { ALOGD("[Demux] wait for data ready on the playback FMQ"); continue; } + if (mDvrPlayback->getSettings().playback().dataFormat == DataFormat::ES) { + if (!mDvrPlayback->processEsDataOnPlayback(true /*isVirtualFrontend*/, mIsRecording)) { + ALOGE("[Demux] playback es data failed to be filtered. Ending thread"); + break; + } + } // Our current implementation filter the data and write it into the filter FMQ immediately // after the DATA_READY from the VTS/framework if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) || diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h index 7f282b250f..6e93ea32f8 100644 --- a/tv/tuner/1.0/default/Demux.h +++ b/tv/tuner/1.0/default/Demux.h @@ -87,6 +87,7 @@ class Demux : public IDemux { bool detachRecordFilter(int filterId); Result startFilterHandler(uint32_t filterId); void updateFilterOutput(uint16_t filterId, vector data); + void updateMediaFilterOutput(uint16_t filterId, vector data, uint64_t pts); uint16_t getFilterTpid(uint32_t filterId); void setIsRecording(bool isRecording); void startFrontendInputLoop(); diff --git a/tv/tuner/1.0/default/Dvr.cpp b/tv/tuner/1.0/default/Dvr.cpp index 68e175c17d..bb3b087ceb 100644 --- a/tv/tuner/1.0/default/Dvr.cpp +++ b/tv/tuner/1.0/default/Dvr.cpp @@ -129,7 +129,7 @@ Return Dvr::stop() { mDvrThreadRunning = false; - std::lock_guard lock(mDvrThreadLock); + lock_guard lock(mDvrThreadLock); mIsRecordStarted = false; mDemux->setIsRecording(false); @@ -155,14 +155,13 @@ bool Dvr::createDvrMQ() { ALOGV("%s", __FUNCTION__); // Create a synchronized FMQ that supports blocking read/write - std::unique_ptr tmpDvrMQ = - std::unique_ptr(new (std::nothrow) DvrMQ(mBufferSize, true)); + unique_ptr tmpDvrMQ = unique_ptr(new (nothrow) DvrMQ(mBufferSize, true)); if (!tmpDvrMQ->isValid()) { ALOGW("[Dvr] Failed to create FMQ of DVR"); return false; } - mDvrMQ = std::move(tmpDvrMQ); + mDvrMQ = move(tmpDvrMQ); if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != OK) { return false; @@ -183,7 +182,7 @@ void* Dvr::__threadLoopPlayback(void* user) { void Dvr::playbackThreadLoop() { ALOGD("[Dvr] playback threadLoop start."); - std::lock_guard lock(mDvrThreadLock); + lock_guard lock(mDvrThreadLock); mDvrThreadRunning = true; while (mDvrThreadRunning) { @@ -195,6 +194,14 @@ void Dvr::playbackThreadLoop() { ALOGD("[Dvr] wait for data ready on the playback FMQ"); continue; } + + if (mDvrSettings.playback().dataFormat == DataFormat::ES) { + if (!processEsDataOnPlayback(false /*isVirtualFrontend*/, false /*isRecording*/)) { + ALOGE("[Dvr] playback es data failed to be filtered. Ending thread"); + break; + } + maySendPlaybackStatusCallback(); + } // Our current implementation filter the data and write it into the filter FMQ immediately // after the DATA_READY from the VTS/framework if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) || @@ -211,7 +218,7 @@ void Dvr::playbackThreadLoop() { } void Dvr::maySendPlaybackStatusCallback() { - std::lock_guard lock(mPlaybackStatusLock); + lock_guard lock(mPlaybackStatusLock); int availableToRead = mDvrMQ->availableToRead(); int availableToWrite = mDvrMQ->availableToWrite(); @@ -263,8 +270,128 @@ bool Dvr::readPlaybackFMQ(bool isVirtualFrontend, bool isRecording) { return true; } +bool Dvr::processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording) { + // Read ES from the DVR FMQ + // Note that currently we only provides ES with metaData in a specific format to be parsed. + // The ES size should be smaller than the Playback FMQ size to avoid reading truncated data. + int size = mDvrMQ->availableToRead(); + vector dataOutputBuffer; + dataOutputBuffer.resize(size); + if (!mDvrMQ->read(dataOutputBuffer.data(), size)) { + return false; + } + + int metaDataSize = size; + int totalFrames = 0; + int videoEsDataSize = 0; + int audioEsDataSize = 0; + int audioPid = 0; + int videoPid = 0; + + vector esMeta; + int videoReadPointer = 0; + int audioReadPointer = 0; + int frameCount = 0; + // Get meta data from the es + for (int i = 0; i < metaDataSize; i++) { + switch (dataOutputBuffer[i]) { + case 'm': + metaDataSize = 0; + getMetaDataValue(i, dataOutputBuffer.data(), metaDataSize); + videoReadPointer = metaDataSize; + continue; + case 'l': + getMetaDataValue(i, dataOutputBuffer.data(), totalFrames); + esMeta.resize(totalFrames); + continue; + case 'V': + getMetaDataValue(i, dataOutputBuffer.data(), videoEsDataSize); + audioReadPointer = metaDataSize + videoEsDataSize; + continue; + case 'A': + getMetaDataValue(i, dataOutputBuffer.data(), audioEsDataSize); + continue; + case 'p': + if (dataOutputBuffer[++i] == 'a') { + getMetaDataValue(i, dataOutputBuffer.data(), audioPid); + } else if (dataOutputBuffer[i] == 'v') { + getMetaDataValue(i, dataOutputBuffer.data(), videoPid); + } + continue; + case 'v': + case 'a': + if (dataOutputBuffer[i + 1] != ',') { + ALOGE("[Dvr] Invalid format meta data."); + return false; + } + esMeta[frameCount] = { + .isAudio = dataOutputBuffer[i] == 'a' ? true : false, + }; + i += 5; // Move to Len + getMetaDataValue(i, dataOutputBuffer.data(), esMeta[frameCount].len); + if (esMeta[frameCount].isAudio) { + esMeta[frameCount].startIndex = audioReadPointer; + audioReadPointer += esMeta[frameCount].len; + } else { + esMeta[frameCount].startIndex = videoReadPointer; + videoReadPointer += esMeta[frameCount].len; + } + i += 4; // move to PTS + getMetaDataValue(i, dataOutputBuffer.data(), esMeta[frameCount].pts); + frameCount++; + continue; + default: + continue; + } + } + + if (frameCount != totalFrames) { + ALOGE("[Dvr] Invalid meta data, frameCount=%d, totalFrames reported=%d", frameCount, + totalFrames); + return false; + } + + if (metaDataSize + audioEsDataSize + videoEsDataSize != size) { + ALOGE("[Dvr] Invalid meta data, metaSize=%d, videoSize=%d, audioSize=%d, totolSize=%d", + metaDataSize, videoEsDataSize, audioEsDataSize, size); + return false; + } + + // Read es raw data from the FMQ per meta data built previously + vector frameData; + map>::iterator it; + int pid = 0; + for (int i = 0; i < totalFrames; i++) { + frameData.resize(esMeta[i].len); + pid = esMeta[i].isAudio ? audioPid : videoPid; + memcpy(dataOutputBuffer.data() + esMeta[i].startIndex, frameData.data(), esMeta[i].len); + // Send to the media filter + if (isVirtualFrontend && isRecording) { + // TODO validate record + mDemux->sendFrontendInputToRecord(frameData); + } else { + for (it = mFilters.begin(); it != mFilters.end(); it++) { + if (pid == mDemux->getFilterTpid(it->first)) { + mDemux->updateMediaFilterOutput(it->first, frameData, + static_cast(esMeta[i].pts)); + startFilterDispatcher(isVirtualFrontend, isRecording); + } + } + } + } + + return true; +} + +void Dvr::getMetaDataValue(int& index, uint8_t* dataOutputBuffer, int& value) { + index += 2; // Move the pointer across the ":" to the value + while (dataOutputBuffer[index] != ',' && dataOutputBuffer[index] != '\n') { + value = ((dataOutputBuffer[index++] - 48) + value * 10); + } +} + void Dvr::startTpidFilter(vector data) { - std::map>::iterator it; + map>::iterator it; for (it = mFilters.begin(); it != mFilters.end(); it++) { uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff)); if (DEBUG_DVR) { @@ -285,7 +412,7 @@ bool Dvr::startFilterDispatcher(bool isVirtualFrontend, bool isRecording) { } } - std::map>::iterator it; + map>::iterator it; // Handle the output data per filter type for (it = mFilters.begin(); it != mFilters.end(); it++) { if (mDemux->startFilterHandler(it->first) != Result::SUCCESS) { @@ -296,8 +423,8 @@ bool Dvr::startFilterDispatcher(bool isVirtualFrontend, bool isRecording) { return true; } -bool Dvr::writeRecordFMQ(const std::vector& data) { - std::lock_guard lock(mWriteLock); +bool Dvr::writeRecordFMQ(const vector& data) { + lock_guard lock(mWriteLock); if (mRecordStatus == RecordStatus::OVERFLOW) { ALOGW("[Dvr] stops writing and wait for the client side flushing."); return true; @@ -313,7 +440,7 @@ bool Dvr::writeRecordFMQ(const std::vector& data) { } void Dvr::maySendRecordStatusCallback() { - std::lock_guard lock(mRecordStatusLock); + lock_guard lock(mRecordStatusLock); int availableToRead = mDvrMQ->availableToRead(); int availableToWrite = mDvrMQ->availableToWrite(); diff --git a/tv/tuner/1.0/default/Dvr.h b/tv/tuner/1.0/default/Dvr.h index a63a25670c..30695866ca 100644 --- a/tv/tuner/1.0/default/Dvr.h +++ b/tv/tuner/1.0/default/Dvr.h @@ -44,6 +44,13 @@ using ::android::hardware::tv::tuner::V1_0::Result; using DvrMQ = MessageQueue; +struct MediaEsMetaData { + bool isAudio; + int startIndex; + int len; + int pts; +}; + class Demux; class Filter; class Frontend; @@ -84,8 +91,10 @@ class Dvr : public IDvr { bool addPlaybackFilter(uint32_t filterId, sp filter); bool removePlaybackFilter(uint32_t filterId); bool readPlaybackFMQ(bool isVirtualFrontend, bool isRecording); + bool processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording); bool startFilterDispatcher(bool isVirtualFrontend, bool isRecording); EventFlag* getDvrEventFlag(); + DvrSettings getSettings() { return mDvrSettings; } private: // Demux service @@ -98,6 +107,7 @@ class Dvr : public IDvr { void deleteEventFlag(); bool readDataFromMQ(); + void getMetaDataValue(int& index, uint8_t* dataOutputBuffer, int& value); void maySendPlaybackStatusCallback(); void maySendRecordStatusCallback(); PlaybackStatus checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead, diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp index 30b19c0b07..ce748e5098 100644 --- a/tv/tuner/1.0/default/Filter.cpp +++ b/tv/tuner/1.0/default/Filter.cpp @@ -317,6 +317,11 @@ void Filter::updateFilterOutput(vector data) { mFilterOutput.insert(mFilterOutput.end(), data.begin(), data.end()); } +void Filter::updatePts(uint64_t pts) { + std::lock_guard lock(mFilterOutputLock); + mPts = pts; +} + void Filter::updateRecordOutput(vector data) { std::lock_guard lock(mRecordFilterOutputLock); mRecordFilterOutput.insert(mRecordFilterOutput.end(), data.begin(), data.end()); @@ -460,6 +465,11 @@ Result Filter::startMediaFilterHandler() { if (mFilterOutput.empty()) { return Result::SUCCESS; } + + if (mPts) { + return createMediaFilterEventWithIon(mFilterOutput); + } + for (int i = 0; i < mFilterOutput.size(); i += 188) { if (mPesSizeLeft == 0) { uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) | @@ -493,46 +503,7 @@ Result Filter::startMediaFilterHandler() { continue; } - int av_fd = createAvIonFd(mPesOutput.size()); - if (av_fd == -1) { - return Result::UNKNOWN_ERROR; - } - // copy the filtered data to the buffer - uint8_t* avBuffer = getIonBuffer(av_fd, mPesOutput.size()); - if (avBuffer == NULL) { - return Result::UNKNOWN_ERROR; - } - memcpy(avBuffer, mPesOutput.data(), mPesOutput.size() * sizeof(uint8_t)); - - native_handle_t* nativeHandle = createNativeHandle(av_fd); - if (nativeHandle == NULL) { - return Result::UNKNOWN_ERROR; - } - hidl_handle handle; - handle.setTo(nativeHandle, /*shouldOwn=*/true); - - // Create a dataId and add a pair into the dataId2Avfd map - uint64_t dataId = mLastUsedDataId++ /*createdUID*/; - mDataId2Avfd[dataId] = dup(av_fd); - - // Create mediaEvent and send callback - DemuxFilterMediaEvent mediaEvent; - mediaEvent = { - .avMemory = std::move(handle), - .dataLength = static_cast(mPesOutput.size()), - .avDataId = dataId, - }; - int size = mFilterEvent.events.size(); - mFilterEvent.events.resize(size + 1); - mFilterEvent.events[size].media(mediaEvent); - - // Clear and log - mPesOutput.clear(); - mAvBufferCopyCount = 0; - ::close(av_fd); - if (DEBUG_FILTER) { - ALOGD("[Filter] assembled av data length %d", mediaEvent.dataLength); - } + createMediaFilterEventWithIon(mPesOutput); } mFilterOutput.clear(); @@ -540,6 +511,54 @@ Result Filter::startMediaFilterHandler() { return Result::SUCCESS; } +Result Filter::createMediaFilterEventWithIon(vector output) { + int av_fd = createAvIonFd(output.size()); + if (av_fd == -1) { + return Result::UNKNOWN_ERROR; + } + // copy the filtered data to the buffer + uint8_t* avBuffer = getIonBuffer(av_fd, output.size()); + if (avBuffer == NULL) { + return Result::UNKNOWN_ERROR; + } + memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t)); + + native_handle_t* nativeHandle = createNativeHandle(av_fd); + if (nativeHandle == NULL) { + return Result::UNKNOWN_ERROR; + } + hidl_handle handle; + handle.setTo(nativeHandle, /*shouldOwn=*/true); + + // Create a dataId and add a pair into the dataId2Avfd map + uint64_t dataId = mLastUsedDataId++ /*createdUID*/; + mDataId2Avfd[dataId] = dup(av_fd); + + // Create mediaEvent and send callback + DemuxFilterMediaEvent mediaEvent; + mediaEvent = { + .avMemory = std::move(handle), + .dataLength = static_cast(output.size()), + .avDataId = dataId, + }; + if (mPts) { + mediaEvent.pts = mPts; + mPts = 0; + } + int size = mFilterEvent.events.size(); + mFilterEvent.events.resize(size + 1); + mFilterEvent.events[size].media(mediaEvent); + + // Clear and log + output.clear(); + mAvBufferCopyCount = 0; + ::close(av_fd); + if (DEBUG_FILTER) { + ALOGD("[Filter] av data length %d", mediaEvent.dataLength); + } + return Result::SUCCESS; +} + Result Filter::startRecordFilterHandler() { std::lock_guard lock(mRecordFilterOutputLock); if (mRecordFilterOutput.empty()) { diff --git a/tv/tuner/1.0/default/Filter.h b/tv/tuner/1.0/default/Filter.h index 9386dca1a2..9b18a66c07 100644 --- a/tv/tuner/1.0/default/Filter.h +++ b/tv/tuner/1.0/default/Filter.h @@ -84,6 +84,7 @@ class Filter : public IFilter { uint16_t getTpid(); void updateFilterOutput(vector data); void updateRecordOutput(vector data); + void updatePts(uint64_t pts); Result startFilterHandler(); Result startRecordFilterHandler(); void attachFilterToRecord(const sp dvr); @@ -116,6 +117,7 @@ class Filter : public IFilter { bool mIsDataSourceDemux = true; vector mFilterOutput; vector mRecordFilterOutput; + uint64_t mPts = 0; unique_ptr mFilterMQ; bool mIsUsingFMQ = false; EventFlag* mFilterEventFlag; @@ -172,6 +174,7 @@ class Filter : public IFilter { int createAvIonFd(int size); uint8_t* getIonBuffer(int fd, int size); native_handle_t* createNativeHandle(int fd); + Result createMediaFilterEventWithIon(vector output); /** * Lock to protect writes to the FMQs diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp index 45951d2b20..b35d11220d 100644 --- a/tv/tuner/1.0/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp @@ -370,13 +370,11 @@ AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWith mIsSoftwareFe = config.isSoftwareFe; bool result = true; if (mIsSoftwareFe && testWithDemux) { - DvrConfig dvrConfig; - getSoftwareFrontendPlaybackConfig(dvrConfig); - result &= mDvrTests.openDvrInDemux(dvrConfig.type, dvrConfig.bufferSize) == success(); - result &= mDvrTests.configDvrPlayback(dvrConfig.settings) == success(); + result &= mDvrTests.openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) == success(); + result &= mDvrTests.configDvrPlayback(mDvrConfig.settings) == success(); result &= mDvrTests.getDvrPlaybackMQDescriptor() == success(); - mDvrTests.startPlaybackInputThread(dvrConfig.playbackInputFile, - dvrConfig.settings.playback()); + mDvrTests.startPlaybackInputThread(mDvrConfig.playbackInputFile, + mDvrConfig.settings.playback()); if (!result) { ALOGW("[vts] Software frontend dvr configure failed."); return failure(); diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.h b/tv/tuner/1.0/vts/functional/FrontendTests.h index c536325126..4974ff351e 100644 --- a/tv/tuner/1.0/vts/functional/FrontendTests.h +++ b/tv/tuner/1.0/vts/functional/FrontendTests.h @@ -104,6 +104,7 @@ class FrontendTests { void setService(sp tuner) { mService = tuner; mDvrTests.setService(tuner); + getDefaultSoftwareFrontendPlaybackConfig(mDvrConfig); } AssertionResult getFrontendIds(); @@ -125,12 +126,13 @@ class FrontendTests { void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; } void setDemux(sp demux) { mDvrTests.setDemux(demux); } + void setSoftwareFrontendDvrConfig(DvrConfig conf) { mDvrConfig = conf; } protected: static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult success() { return ::testing::AssertionSuccess(); } - void getSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) { + void getDefaultSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) { PlaybackSettings playbackSettings{ .statusMask = 0xf, .lowThreshold = 0x1000, @@ -151,4 +153,5 @@ class FrontendTests { DvrTests mDvrTests; bool mIsSoftwareFe = false; + DvrConfig mDvrConfig; }; diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 6819659915..9318bc4d70 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -486,6 +486,62 @@ TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) { broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[DVBS]); } +TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) { + description("Test Meida Filters functionality in Broadcast use case with ES input."); + uint32_t feId; + uint32_t demuxId; + sp demux; + uint32_t filterId; + + mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId); + if (feId == INVALID_ID) { + // TODO broadcast test on Cuttlefish needs licensed ts input, + // these tests are runnable on vendor device with real frontend module + // or with manual ts installing and use DVBT frontend. + return; + } + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFrontendTests.setDemux(demux); + mFilterTests.setDemux(demux); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_AUDIO1].type, + filterArray[TS_AUDIO1].bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_AUDIO1].settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.startFilter(filterId)); + ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type, + filterArray[TS_VIDEO1].bufferSize)); + ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); + ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, filterId)); + ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); + ASSERT_TRUE(mFilterTests.startFilter(filterId)); + // tune test + PlaybackSettings playbackSettings{ + .statusMask = 0xf, + .lowThreshold = 0x1000, + .highThreshold = 0x07fff, + .dataFormat = DataFormat::ES, + .packetSize = 188, + }; + DvrConfig dvrConfig{ + .type = DvrType::PLAYBACK, + .playbackInputFile = "/data/local/tmp/test.es", + .bufferSize = FMQ_SIZE_4M, + }; + dvrConfig.settings.playback(playbackSettings); + mFrontendTests.setSoftwareFrontendDvrConfig(dvrConfig); + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendArray[DVBT], true /*testWithDemux*/)); + ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); + ASSERT_TRUE(mFilterTests.stopFilter(filterId)); + ASSERT_TRUE(mFilterTests.closeFilter(filterId)); + ASSERT_TRUE(mDemuxTests.closeDemux()); + ASSERT_TRUE(mFrontendTests.closeFrontend()); +} + TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) { description("Feed ts data from playback and configure Ts section filter to get output"); playbackSingleFilterTest(filterArray[TS_SECTION0], dvrArray[DVR_PLAYBACK0]); diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index 6c68e3588e..27c65931b8 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -77,6 +77,7 @@ typedef enum { TS_VIDEO0, TS_VIDEO1, TS_AUDIO0, + TS_AUDIO1, TS_PES0, TS_PCR0, TS_SECTION0, @@ -121,7 +122,6 @@ typedef enum { typedef enum { DVR_RECORD0, DVR_PLAYBACK0, - DVR_SOFTWARE_FE, DVR_MAX, } Dvr; @@ -274,6 +274,11 @@ inline void initFilterConfig() { filterArray[TS_AUDIO0].bufferSize = FMQ_SIZE_16M; filterArray[TS_AUDIO0].settings.ts().tpid = 256; filterArray[TS_AUDIO0].settings.ts().filterSettings.av({.isPassthrough = false}); + filterArray[TS_AUDIO1].type.mainType = DemuxFilterMainType::TS; + filterArray[TS_AUDIO1].type.subType.tsFilterType(DemuxTsFilterType::AUDIO); + filterArray[TS_AUDIO1].bufferSize = FMQ_SIZE_16M; + filterArray[TS_AUDIO1].settings.ts().tpid = 257; + filterArray[TS_AUDIO1].settings.ts().filterSettings.av({.isPassthrough = false}); // TS PES filter setting filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS; filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES); @@ -362,17 +367,6 @@ inline void initDvrConfig() { dvrArray[DVR_PLAYBACK0].playbackInputFile = "/data/local/tmp/segment000000.ts"; dvrArray[DVR_PLAYBACK0].bufferSize = FMQ_SIZE_4M; dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings); - PlaybackSettings softwareFePlaybackSettings{ - .statusMask = 0xf, - .lowThreshold = 0x1000, - .highThreshold = 0x07fff, - .dataFormat = DataFormat::TS, - .packetSize = 188, - }; - dvrArray[DVR_SOFTWARE_FE].type = DvrType::PLAYBACK; - dvrArray[DVR_SOFTWARE_FE].playbackInputFile = "/data/local/tmp/segment000000.ts"; - dvrArray[DVR_SOFTWARE_FE].bufferSize = FMQ_SIZE_4M; - dvrArray[DVR_SOFTWARE_FE].settings.playback(softwareFePlaybackSettings); }; /** Configuration array for the descrambler test */