From 6bda6397cca97745482bd72fd94f3eedf630d533 Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Tue, 26 May 2020 19:00:46 -0700 Subject: [PATCH] Move testing ts on Cuttlefish under /data/ directory /data directory is a proper place for test pusher to adb push the ts during run time. It saves image size comparing to bundle the ts during compiling. Files under the /data directory could only be passed around by fd instead of directly opening. This CL also changes the way the DVR VTS reads the ts. Also for virtual frontend, to read the shell data file, we need the DVR playback to input the data when testing frontend. This CL also changes the way default implementation reads the data - from the dvr playback fmq. Test: atest VtsHalTvTunerV1_0TargetTest Bug: 153366959 Change-Id: I72a98e4c4c0328206da106fb1c3459745c1644b7 --- tv/tuner/1.0/default/Demux.cpp | 136 ++++++------ tv/tuner/1.0/default/Demux.h | 31 +-- tv/tuner/1.0/default/Dvr.cpp | 69 +++--- tv/tuner/1.0/default/Dvr.h | 13 +- tv/tuner/1.0/default/Filter.cpp | 14 +- tv/tuner/1.0/default/Filter.h | 2 + tv/tuner/1.0/default/Frontend.cpp | 4 - tv/tuner/1.0/default/Frontend.h | 1 - tv/tuner/1.0/vts/functional/DvrTests.cpp | 199 +++++++++++++----- tv/tuner/1.0/vts/functional/DvrTests.h | 45 ++-- tv/tuner/1.0/vts/functional/FrontendTests.cpp | 27 ++- tv/tuner/1.0/vts/functional/FrontendTests.h | 30 ++- .../VtsHalTvTunerV1_0TargetTest.cpp | 45 ++-- .../functional/VtsHalTvTunerV1_0TargetTest.h | 5 +- .../VtsHalTvTunerV1_0TestConfigurations.h | 17 +- 15 files changed, 394 insertions(+), 244 deletions(-) diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp index b74f6eca20..5a49590a8d 100644 --- a/tv/tuner/1.0/default/Demux.cpp +++ b/tv/tuner/1.0/default/Demux.cpp @@ -48,8 +48,6 @@ Return Demux::setFrontendDataSource(uint32_t frontendId) { return Result::INVALID_STATE; } - mFrontendSourceFile = mFrontend->getSourceFile(); - mTunerService->setFrontendAsDemuxSource(frontendId, mDemuxId); return Result::SUCCESS; @@ -62,8 +60,6 @@ Return Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize, uint32_t filterId; filterId = ++mLastUsedFilterId; - mUsedFilterIds.insert(filterId); - if (cb == nullptr) { ALOGW("[Demux] callback can't be null"); _hidl_cb(Result::INVALID_ARGUMENT, new Filter()); @@ -82,8 +78,13 @@ Return Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize, mPcrFilterIds.insert(filterId); } bool result = true; - if (mDvr != nullptr && mDvr->getType() == DvrType::PLAYBACK) { - result = mDvr->addPlaybackFilter(filter); + if (!filter->isRecordFilter()) { + // Only save non-record filters for now. Record filters are saved when the + // IDvr.attacheFilter is called. + mPlaybackFilterIds.insert(filterId); + if (mDvrPlayback != nullptr) { + result = mDvrPlayback->addPlaybackFilter(filterId, filter); + } } _hidl_cb(result ? Result::SUCCESS : Result::INVALID_ARGUMENT, filter); @@ -154,7 +155,13 @@ Return Demux::getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_ Return Demux::close() { ALOGV("%s", __FUNCTION__); - mUsedFilterIds.clear(); + set::iterator it; + for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) { + mDvrPlayback->removePlaybackFilter(*it); + } + mPlaybackFilterIds.clear(); + mRecordFilterIds.clear(); + mFilters.clear(); mLastUsedFilterId = -1; return Result::SUCCESS; @@ -170,15 +177,38 @@ Return Demux::openDvr(DvrType type, uint32_t bufferSize, const sp::iterator it; + switch (type) { + case DvrType::PLAYBACK: + mDvrPlayback = new Dvr(type, bufferSize, cb, this); + if (!mDvrPlayback->createDvrMQ()) { + _hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback); + return Void(); + } - if (!mDvr->createDvrMQ()) { - _hidl_cb(Result::UNKNOWN_ERROR, mDvr); - return Void(); + for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) { + if (!mDvrPlayback->addPlaybackFilter(*it, mFilters[*it])) { + ALOGE("[Demux] Can't get filter info for DVR playback"); + _hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback); + return Void(); + } + } + + _hidl_cb(Result::SUCCESS, mDvrPlayback); + return Void(); + case DvrType::RECORD: + mDvrRecord = new Dvr(type, bufferSize, cb, this); + if (!mDvrRecord->createDvrMQ()) { + _hidl_cb(Result::UNKNOWN_ERROR, mDvrRecord); + return Void(); + } + + _hidl_cb(Result::SUCCESS, mDvrRecord); + return Void(); + default: + _hidl_cb(Result::INVALID_ARGUMENT, nullptr); + return Void(); } - - _hidl_cb(Result::SUCCESS, mDvr); - return Void(); } Return Demux::connectCiCam(uint32_t ciCamId) { @@ -198,8 +228,10 @@ Return Demux::disconnectCiCam() { Result Demux::removeFilter(uint32_t filterId) { ALOGV("%s", __FUNCTION__); - // resetFilterRecords(filterId); - mUsedFilterIds.erase(filterId); + if (mDvrPlayback != nullptr) { + mDvrPlayback->removePlaybackFilter(filterId); + } + mPlaybackFilterIds.erase(filterId); mRecordFilterIds.erase(filterId); mFilters.erase(filterId); @@ -212,7 +244,7 @@ void Demux::startBroadcastTsFilter(vector data) { if (DEBUG_DEMUX) { ALOGW("[Demux] start ts filter pid: %d", pid); } - for (it = mUsedFilterIds.begin(); it != mUsedFilterIds.end(); it++) { + for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) { if (pid == mFilters[*it]->getTpid()) { mFilters[*it]->updateFilterOutput(data); } @@ -233,7 +265,7 @@ bool Demux::startBroadcastFilterDispatcher() { set::iterator it; // Handle the output data per filter type - for (it = mUsedFilterIds.begin(); it != mUsedFilterIds.end(); it++) { + for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) { if (mFilters[*it]->startFilterHandler() != Result::SUCCESS) { return false; } @@ -280,58 +312,27 @@ void* Demux::__threadLoopFrontend(void* user) { void Demux::frontendInputThreadLoop() { std::lock_guard lock(mFrontendInputThreadLock); mFrontendInputThreadRunning = true; - mKeepFetchingDataFromFrontend = true; - - // open the stream and get its length - std::ifstream inputData(mFrontendSourceFile, std::ifstream::binary); - // TODO take the packet size from the frontend setting - int packetSize = 188; - int writePacketAmount = 6; - char* buffer = new char[packetSize]; - ALOGW("[Demux] Frontend input thread loop start %s", mFrontendSourceFile.c_str()); - if (!inputData.is_open()) { - mFrontendInputThreadRunning = false; - ALOGW("[Demux] Error %s", strerror(errno)); - } while (mFrontendInputThreadRunning) { - // move the stream pointer for packet size * 6 every read until the end - while (mKeepFetchingDataFromFrontend) { - for (int i = 0; i < writePacketAmount; i++) { - inputData.read(buffer, packetSize); - if (!inputData) { - mKeepFetchingDataFromFrontend = false; - mFrontendInputThreadRunning = false; - break; - } - // filter and dispatch filter output - vector byteBuffer; - byteBuffer.resize(packetSize); - for (int index = 0; index < byteBuffer.size(); index++) { - byteBuffer[index] = static_cast(buffer[index]); - } - if (mIsRecording) { - // Feed the data into the Dvr recording input - sendFrontendInputToRecord(byteBuffer); - } else { - // Feed the data into the broadcast demux filter - startBroadcastTsFilter(byteBuffer); - } - } - if (mIsRecording) { - // Dispatch the data into the broadcasting filters. - startRecordFilterDispatcher(); - } else { - // Dispatch the data into the broadcasting filters. - startBroadcastFilterDispatcher(); - } - usleep(100); + uint32_t efState = 0; + status_t status = mDvrPlayback->getDvrEventFlag()->wait( + static_cast(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT, + true /* retry on spurious wake */); + if (status != OK) { + ALOGD("[Demux] wait for data ready on the playback FMQ"); + continue; + } + // 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) || + !mDvrPlayback->startFilterDispatcher(true /*isVirtualFrontend*/, mIsRecording)) { + ALOGE("[Demux] playback data failed to be filtered. Ending thread"); + break; } } + mFrontendInputThreadRunning = false; ALOGW("[Demux] Frontend Input thread end."); - delete[] buffer; - inputData.close(); } void Demux::stopFrontendInput() { @@ -346,18 +347,19 @@ void Demux::setIsRecording(bool isRecording) { } bool Demux::attachRecordFilter(int filterId) { - if (mFilters[filterId] == nullptr || mDvr == nullptr) { + if (mFilters[filterId] == nullptr || mDvrRecord == nullptr || + !mFilters[filterId]->isRecordFilter()) { return false; } mRecordFilterIds.insert(filterId); - mFilters[filterId]->attachFilterToRecord(mDvr); + mFilters[filterId]->attachFilterToRecord(mDvrRecord); return true; } bool Demux::detachRecordFilter(int filterId) { - if (mFilters[filterId] == nullptr || mDvr == nullptr) { + if (mFilters[filterId] == nullptr || mDvrRecord == nullptr) { return false; } diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h index 6c46b0dbdd..e3062b57ba 100644 --- a/tv/tuner/1.0/default/Demux.h +++ b/tv/tuner/1.0/default/Demux.h @@ -91,13 +91,23 @@ class Demux : public IDemux { void setIsRecording(bool isRecording); void startFrontendInputLoop(); + /** + * A dispatcher to read and dispatch input data to all the started filters. + * Each filter handler handles the data filtering/output writing/filterEvent updating. + * Note that recording filters are not included. + */ + bool startBroadcastFilterDispatcher(); + void startBroadcastTsFilter(vector data); + + void sendFrontendInputToRecord(vector data); + bool startRecordFilterDispatcher(); + private: // Tuner service sp mTunerService; // Frontend source sp mFrontend; - string mFrontendSourceFile; // A struct that passes the arguments to a newly created filter thread struct ThreadArgs { @@ -117,16 +127,6 @@ class Demux : public IDemux { */ void deleteEventFlag(); bool readDataFromMQ(); - /** - * A dispatcher to read and dispatch input data to all the started filters. - * Each filter handler handles the data filtering/output writing/filterEvent updating. - * Note that recording filters are not included. - */ - bool startBroadcastFilterDispatcher(); - void startBroadcastTsFilter(vector data); - - void sendFrontendInputToRecord(vector data); - bool startRecordFilterDispatcher(); uint32_t mDemuxId; uint32_t mCiCamId; @@ -137,17 +137,17 @@ class Demux : public IDemux { */ uint32_t mLastUsedFilterId = -1; /** - * Record all the used filter Ids. + * Record all the used playback filter Ids. * Any removed filter id should be removed from this set. */ - set mUsedFilterIds; + set mPlaybackFilterIds; /** * Record all the attached record filter Ids. * Any removed filter id should be removed from this set. */ set mRecordFilterIds; /** - * A list of created FilterMQ ptrs. + * A list of created Filter sp. * The array number is the filter ID. */ std::map> mFilters; @@ -155,7 +155,8 @@ class Demux : public IDemux { /** * Local reference to the opened DVR object. */ - sp mDvr; + sp mDvrPlayback; + sp mDvrRecord; // Thread handlers pthread_t mFrontendInputThread; diff --git a/tv/tuner/1.0/default/Dvr.cpp b/tv/tuner/1.0/default/Dvr.cpp index adb263553e..68e175c17d 100644 --- a/tv/tuner/1.0/default/Dvr.cpp +++ b/tv/tuner/1.0/default/Dvr.cpp @@ -70,8 +70,7 @@ Return Dvr::attachFilter(const sp& filter) { return status; } - // check if the attached filter is a record filter - mFilters[filterId] = filter; + // TODO check if the attached filter is a record filter if (!mDemux->attachRecordFilter(filterId)) { return Result::INVALID_ARGUMENT; } @@ -94,19 +93,8 @@ Return Dvr::detachFilter(const sp& filter) { return status; } - std::map>::iterator it; - - it = mFilters.find(filterId); - if (it != mFilters.end()) { - mFilters.erase(filterId); - if (!mDemux->detachRecordFilter(filterId)) { - return Result::INVALID_ARGUMENT; - } - } - - // If all the filters are detached, record can't be started - if (mFilters.empty()) { - mIsRecordFilterAttached = false; + if (!mDemux->detachRecordFilter(filterId)) { + return Result::INVALID_ARGUMENT; } return Result::SUCCESS; @@ -183,6 +171,10 @@ bool Dvr::createDvrMQ() { return true; } +EventFlag* Dvr::getDvrEventFlag() { + return mDvrEventFlag; +} + void* Dvr::__threadLoopPlayback(void* user) { Dvr* const self = static_cast(user); self->playbackThreadLoop(); @@ -205,8 +197,9 @@ void Dvr::playbackThreadLoop() { } // Our current implementation filter the data and write it into the filter FMQ immediately // after the DATA_READY from the VTS/framework - if (!readPlaybackFMQ() || !startFilterDispatcher()) { - ALOGD("[Dvr] playback data failed to be filtered. Ending thread"); + if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) || + !startFilterDispatcher(false /*isVirtualFrontend*/, false /*isRecording*/)) { + ALOGE("[Dvr] playback data failed to be filtered. Ending thread"); break; } @@ -245,7 +238,7 @@ PlaybackStatus Dvr::checkPlaybackStatusChange(uint32_t availableToWrite, uint32_ return mPlaybackStatus; } -bool Dvr::readPlaybackFMQ() { +bool Dvr::readPlaybackFMQ(bool isVirtualFrontend, bool isRecording) { // Read playback data from the input FMQ int size = mDvrMQ->availableToRead(); int playbackPacketSize = mDvrSettings.playback().packetSize; @@ -256,7 +249,15 @@ bool Dvr::readPlaybackFMQ() { if (!mDvrMQ->read(dataOutputBuffer.data(), playbackPacketSize)) { return false; } - startTpidFilter(dataOutputBuffer); + if (isVirtualFrontend) { + if (isRecording) { + mDemux->sendFrontendInputToRecord(dataOutputBuffer); + } else { + mDemux->startBroadcastTsFilter(dataOutputBuffer); + } + } else { + startTpidFilter(dataOutputBuffer); + } } return true; @@ -275,7 +276,15 @@ void Dvr::startTpidFilter(vector data) { } } -bool Dvr::startFilterDispatcher() { +bool Dvr::startFilterDispatcher(bool isVirtualFrontend, bool isRecording) { + if (isVirtualFrontend) { + if (isRecording) { + return mDemux->startRecordFilterDispatcher(); + } else { + return mDemux->startBroadcastFilterDispatcher(); + } + } + std::map>::iterator it; // Handle the output data per filter type for (it = mFilters.begin(); it != mFilters.end(); it++) { @@ -329,27 +338,15 @@ RecordStatus Dvr::checkRecordStatusChange(uint32_t availableToWrite, uint32_t av return mRecordStatus; } -bool Dvr::addPlaybackFilter(sp filter) { - uint32_t filterId; - Result status; - - filter->getId([&](Result result, uint32_t id) { - filterId = id; - status = result; - }); - - if (status != Result::SUCCESS) { - return false; - } - +bool Dvr::addPlaybackFilter(uint32_t filterId, sp filter) { mFilters[filterId] = filter; return true; } -DvrType Dvr::getType() { - return mType; +bool Dvr::removePlaybackFilter(uint32_t filterId) { + mFilters.erase(filterId); + return true; } - } // namespace implementation } // namespace V1_0 } // namespace tuner diff --git a/tv/tuner/1.0/default/Dvr.h b/tv/tuner/1.0/default/Dvr.h index 08afd5dc83..a63a25670c 100644 --- a/tv/tuner/1.0/default/Dvr.h +++ b/tv/tuner/1.0/default/Dvr.h @@ -81,8 +81,11 @@ class Dvr : public IDvr { bool createDvrMQ(); void sendBroadcastInputToDvrRecord(vector byteBuffer); bool writeRecordFMQ(const std::vector& data); - DvrType getType(); - bool addPlaybackFilter(sp filter); + bool addPlaybackFilter(uint32_t filterId, sp filter); + bool removePlaybackFilter(uint32_t filterId); + bool readPlaybackFMQ(bool isVirtualFrontend, bool isRecording); + bool startFilterDispatcher(bool isVirtualFrontend, bool isRecording); + EventFlag* getDvrEventFlag(); private: // Demux service @@ -105,9 +108,7 @@ class Dvr : public IDvr { * A dispatcher to read and dispatch input data to all the started filters. * Each filter handler handles the data filtering/output writing/filterEvent updating. */ - bool readPlaybackFMQ(); void startTpidFilter(vector data); - bool startFilterDispatcher(); static void* __threadLoopPlayback(void* user); static void* __threadLoopRecord(void* user); void playbackThreadLoop(); @@ -123,7 +124,6 @@ class Dvr : public IDvr { // Thread handlers pthread_t mDvrThread; - pthread_t mBroadcastInputThread; // FMQ status local records PlaybackStatus mPlaybackStatus; @@ -132,7 +132,6 @@ class Dvr : public IDvr { * If a specific filter's writing loop is still running */ bool mDvrThreadRunning; - bool mBroadcastInputThreadRunning; bool mKeepFetchingDataFromFrontend; /** * Lock to protect writes to the FMQs @@ -143,7 +142,6 @@ class Dvr : public IDvr { */ std::mutex mPlaybackStatusLock; std::mutex mRecordStatusLock; - std::mutex mBroadcastInputThreadLock; std::mutex mDvrThreadLock; const bool DEBUG_DVR = false; @@ -151,7 +149,6 @@ class Dvr : public IDvr { // Booleans to check if recording is running. // Recording is ready when both of the following are set to true. bool mIsRecordStarted = false; - bool mIsRecordFilterAttached = false; }; } // namespace implementation diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp index 8bca70ce5f..30b19c0b07 100644 --- a/tv/tuner/1.0/default/Filter.cpp +++ b/tv/tuner/1.0/default/Filter.cpp @@ -47,12 +47,18 @@ Filter::Filter(DemuxFilterType type, uint32_t filterId, uint32_t bufferSize, if (mType.subType.tsFilterType() == DemuxTsFilterType::PCR) { mIsPcrFilter = true; } + if (mType.subType.tsFilterType() == DemuxTsFilterType::RECORD) { + mIsRecordFilter = true; + } break; case DemuxFilterMainType::MMTP: if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO || mType.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) { mIsMediaFilter = true; } + if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::RECORD) { + mIsRecordFilter = true; + } break; case DemuxFilterMainType::IP: break; @@ -535,12 +541,6 @@ Result Filter::startMediaFilterHandler() { } Result Filter::startRecordFilterHandler() { - /*DemuxFilterTsRecordEvent tsRecordEvent; - tsRecordEvent.pid.tPid(0); - tsRecordEvent.indexMask.tsIndexMask(0x01); - mFilterEvent.events.resize(1); - mFilterEvent.events[0].tsRecord(tsRecordEvent); -*/ std::lock_guard lock(mRecordFilterOutputLock); if (mRecordFilterOutput.empty()) { return Result::SUCCESS; @@ -567,7 +567,7 @@ Result Filter::startTemiFilterHandler() { bool Filter::writeSectionsAndCreateEvent(vector data) { // TODO check how many sections has been read - ALOGD("[Filter] section hander"); + ALOGD("[Filter] section handler"); std::lock_guard lock(mFilterEventLock); if (!writeDataToFilterMQ(data)) { return false; diff --git a/tv/tuner/1.0/default/Filter.h b/tv/tuner/1.0/default/Filter.h index 09e9604850..9386dca1a2 100644 --- a/tv/tuner/1.0/default/Filter.h +++ b/tv/tuner/1.0/default/Filter.h @@ -91,6 +91,7 @@ class Filter : public IFilter { void freeAvHandle(); bool isMediaFilter() { return mIsMediaFilter; }; bool isPcrFilter() { return mIsPcrFilter; }; + bool isRecordFilter() { return mIsRecordFilter; }; private: // Tuner service @@ -107,6 +108,7 @@ class Filter : public IFilter { DemuxFilterType mType; bool mIsMediaFilter = false; bool mIsPcrFilter = false; + bool mIsRecordFilter = false; DemuxFilterSettings mFilterSettings; uint16_t mTpid; diff --git a/tv/tuner/1.0/default/Frontend.cpp b/tv/tuner/1.0/default/Frontend.cpp index 61bbbf8193..f42e592a58 100644 --- a/tv/tuner/1.0/default/Frontend.cpp +++ b/tv/tuner/1.0/default/Frontend.cpp @@ -268,10 +268,6 @@ FrontendId Frontend::getFrontendId() { return mId; } -string Frontend::getSourceFile() { - return FRONTEND_STREAM_FILE; -} - bool Frontend::supportsSatellite() { return mType == FrontendType::DVBS || mType == FrontendType::ISDBS || mType == FrontendType::ISDBS3; diff --git a/tv/tuner/1.0/default/Frontend.h b/tv/tuner/1.0/default/Frontend.h index c0d1613cfa..c09b897eae 100644 --- a/tv/tuner/1.0/default/Frontend.h +++ b/tv/tuner/1.0/default/Frontend.h @@ -77,7 +77,6 @@ class Frontend : public IFrontend { FrontendId mId = 0; bool mIsLocked = false; - const string FRONTEND_STREAM_FILE = "/vendor/etc/segment000000.ts"; std::ifstream mFrontendData; }; diff --git a/tv/tuner/1.0/vts/functional/DvrTests.cpp b/tv/tuner/1.0/vts/functional/DvrTests.cpp index 7e7f8e6da8..0dfc032d19 100644 --- a/tv/tuner/1.0/vts/functional/DvrTests.cpp +++ b/tv/tuner/1.0/vts/functional/DvrTests.cpp @@ -49,49 +49,73 @@ void DvrCallback::playbackThreadLoop() { EXPECT_TRUE(EventFlag::createEventFlag(mPlaybackMQ->getEventFlagWord(), &playbackMQEventFlag) == android::OK); - // open the stream and get its length - std::ifstream inputData(mInputDataFile.c_str(), std::ifstream::binary); - int writeSize = mPlaybackSettings.packetSize * 6; - char* buffer = new char[writeSize]; - ALOGW("[vts] playback thread loop start %s!", mInputDataFile.c_str()); - if (!inputData.is_open()) { + int fd = open(mInputDataFile.c_str(), O_RDONLY | O_LARGEFILE); + int readBytes; + uint32_t regionSize = 0; + uint8_t* buffer; + ALOGW("[vts] playback thread loop start %s", mInputDataFile.c_str()); + if (fd < 0) { mPlaybackThreadRunning = false; ALOGW("[vts] Error %s", strerror(errno)); } while (mPlaybackThreadRunning) { - // move the stream pointer for packet size * 6 every read until the end while (mKeepWritingPlaybackFMQ) { - inputData.read(buffer, writeSize); - if (!inputData) { - int leftSize = inputData.gcount(); - if (leftSize == 0) { - mPlaybackThreadRunning = false; - break; - } - inputData.clear(); - inputData.read(buffer, leftSize); - // Write the left over of the input data and quit the thread - if (leftSize > 0) { - EXPECT_TRUE(mPlaybackMQ->write((unsigned char*)&buffer[0], leftSize)); - playbackMQEventFlag->wake( - static_cast(DemuxQueueNotifyBits::DATA_READY)); - } + int totalWrite = mPlaybackMQ->availableToWrite(); + if (totalWrite * 4 < mPlaybackMQ->getQuantumCount()) { + // Wait for the HAL implementation to read more data then write. + continue; + } + MessageQueue::MemTransaction memTx; + if (!mPlaybackMQ->beginWrite(totalWrite, &memTx)) { + ALOGW("[vts] Fail to write into Playback fmq."); + mPlaybackThreadRunning = false; + break; + } + auto first = memTx.getFirstRegion(); + buffer = first.getAddress(); + regionSize = first.getLength(); + + if (regionSize > 0) { + readBytes = read(fd, buffer, regionSize); + if (readBytes <= 0) { + if (readBytes < 0) { + ALOGW("[vts] Read from %s failed.", mInputDataFile.c_str()); + } else { + ALOGW("[vts] playback input EOF."); + } + mPlaybackThreadRunning = false; + break; + } + } + if (regionSize == 0 || (readBytes == regionSize && regionSize < totalWrite)) { + auto second = memTx.getSecondRegion(); + buffer = second.getAddress(); + regionSize = second.getLength(); + int ret = read(fd, buffer, regionSize); + if (ret <= 0) { + if (ret < 0) { + ALOGW("[vts] Read from %s failed.", mInputDataFile.c_str()); + } else { + ALOGW("[vts] playback input EOF."); + } + mPlaybackThreadRunning = false; + break; + } + readBytes += ret; + } + if (!mPlaybackMQ->commitWrite(readBytes)) { + ALOGW("[vts] Failed to commit write playback fmq."); mPlaybackThreadRunning = false; break; } - // Write input FMQ and notify the Tuner Implementation - EXPECT_TRUE(mPlaybackMQ->write((unsigned char*)&buffer[0], writeSize)); playbackMQEventFlag->wake(static_cast(DemuxQueueNotifyBits::DATA_READY)); - inputData.seekg(writeSize, inputData.cur); - sleep(1); } } + mPlaybackThreadRunning = false; ALOGW("[vts] Playback thread end."); - - delete[] buffer; - inputData.close(); + close(fd); } void DvrCallback::testRecordOutput() { @@ -186,32 +210,65 @@ AssertionResult DvrTests::openDvrInDemux(DvrType type, uint32_t bufferSize) { EXPECT_TRUE(mDemux) << "Test with openDemux first."; // Create dvr callback - mDvrCallback = new DvrCallback(); + if (type == DvrType::PLAYBACK) { + mDvrPlaybackCallback = new DvrCallback(); + mDemux->openDvr(type, bufferSize, mDvrPlaybackCallback, + [&](Result result, const sp& dvr) { + mDvrPlayback = dvr; + status = result; + }); + if (status == Result::SUCCESS) { + mDvrPlaybackCallback->setDvr(mDvrPlayback); + } + } - mDemux->openDvr(type, bufferSize, mDvrCallback, [&](Result result, const sp& dvr) { - mDvr = dvr; + if (type == DvrType::RECORD) { + mDvrRecordCallback = new DvrCallback(); + mDemux->openDvr(type, bufferSize, mDvrRecordCallback, + [&](Result result, const sp& dvr) { + mDvrRecord = dvr; + status = result; + }); + if (status == Result::SUCCESS) { + mDvrRecordCallback->setDvr(mDvrRecord); + } + } + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::configDvrPlayback(DvrSettings setting) { + Result status = mDvrPlayback->configure(setting); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::configDvrRecord(DvrSettings setting) { + Result status = mDvrRecord->configure(setting); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::getDvrPlaybackMQDescriptor() { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first."; + + mDvrPlayback->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) { + mDvrPlaybackMQDescriptor = dvrMQDesc; status = result; }); - if (status == Result::SUCCESS) { - mDvrCallback->setDvr(mDvr); - } return AssertionResult(status == Result::SUCCESS); } -AssertionResult DvrTests::configDvr(DvrSettings setting) { - Result status = mDvr->configure(setting); - - return AssertionResult(status == Result::SUCCESS); -} - -AssertionResult DvrTests::getDvrMQDescriptor() { +AssertionResult DvrTests::getDvrRecordMQDescriptor() { Result status; EXPECT_TRUE(mDemux) << "Test with openDemux first."; - EXPECT_TRUE(mDvr) << "Test with openDvr first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; - mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) { - mDvrMQDescriptor = dvrMQDesc; + mDvrRecord->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) { + mDvrRecordMQDescriptor = dvrMQDesc; status = result; }); @@ -221,9 +278,9 @@ AssertionResult DvrTests::getDvrMQDescriptor() { AssertionResult DvrTests::attachFilterToDvr(sp filter) { Result status; EXPECT_TRUE(mDemux) << "Test with openDemux first."; - EXPECT_TRUE(mDvr) << "Test with openDvr first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; - status = mDvr->attachFilter(filter); + status = mDvrRecord->attachFilter(filter); return AssertionResult(status == Result::SUCCESS); } @@ -231,35 +288,61 @@ AssertionResult DvrTests::attachFilterToDvr(sp filter) { AssertionResult DvrTests::detachFilterToDvr(sp filter) { Result status; EXPECT_TRUE(mDemux) << "Test with openDemux first."; - EXPECT_TRUE(mDvr) << "Test with openDvr first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; - status = mDvr->detachFilter(filter); + status = mDvrRecord->detachFilter(filter); return AssertionResult(status == Result::SUCCESS); } -AssertionResult DvrTests::startDvr() { +AssertionResult DvrTests::startDvrPlayback() { Result status; EXPECT_TRUE(mDemux) << "Test with openDemux first."; - EXPECT_TRUE(mDvr) << "Test with openDvr first."; + EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first."; - status = mDvr->start(); + status = mDvrPlayback->start(); return AssertionResult(status == Result::SUCCESS); } -AssertionResult DvrTests::stopDvr() { +AssertionResult DvrTests::stopDvrPlayback() { Result status; EXPECT_TRUE(mDemux) << "Test with openDemux first."; - EXPECT_TRUE(mDvr) << "Test with openDvr first."; + EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first."; - status = mDvr->stop(); + status = mDvrPlayback->stop(); return AssertionResult(status == Result::SUCCESS); } -void DvrTests::closeDvr() { +void DvrTests::closeDvrPlayback() { ASSERT_TRUE(mDemux); - ASSERT_TRUE(mDvr); - ASSERT_TRUE(mDvr->close() == Result::SUCCESS); + ASSERT_TRUE(mDvrPlayback); + ASSERT_TRUE(mDvrPlayback->close() == Result::SUCCESS); +} + +AssertionResult DvrTests::startDvrRecord() { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; + + status = mDvrRecord->start(); + + return AssertionResult(status == Result::SUCCESS); +} + +AssertionResult DvrTests::stopDvrRecord() { + Result status; + EXPECT_TRUE(mDemux) << "Test with openDemux first."; + EXPECT_TRUE(mDvrRecord) << "Test with openDvr first."; + + status = mDvrRecord->stop(); + + return AssertionResult(status == Result::SUCCESS); +} + +void DvrTests::closeDvrRecord() { + ASSERT_TRUE(mDemux); + ASSERT_TRUE(mDvrRecord); + ASSERT_TRUE(mDvrRecord->close() == Result::SUCCESS); } diff --git a/tv/tuner/1.0/vts/functional/DvrTests.h b/tv/tuner/1.0/vts/functional/DvrTests.h index dd00c27431..3997839eab 100644 --- a/tv/tuner/1.0/vts/functional/DvrTests.h +++ b/tv/tuner/1.0/vts/functional/DvrTests.h @@ -14,14 +14,15 @@ * limitations under the License. */ -#include -#include #include #include #include #include #include +#include #include +#include +#include #include #include #include @@ -52,6 +53,8 @@ using android::hardware::tv::tuner::V1_0::RecordSettings; using android::hardware::tv::tuner::V1_0::RecordStatus; using android::hardware::tv::tuner::V1_0::Result; +using namespace std; + #define WAIT_TIMEOUT 3000000000 class DvrCallback : public IDvrCallback { @@ -149,25 +152,31 @@ class DvrTests { void setDemux(sp demux) { mDemux = demux; } void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings) { - mDvrCallback->startPlaybackInputThread(dataInputFile, settings, mDvrMQDescriptor); + mDvrPlaybackCallback->startPlaybackInputThread(dataInputFile, settings, + mDvrPlaybackMQDescriptor); }; void startRecordOutputThread(RecordSettings settings) { - mDvrCallback->startRecordOutputThread(settings, mDvrMQDescriptor); + mDvrRecordCallback->startRecordOutputThread(settings, mDvrRecordMQDescriptor); }; - void stopPlaybackThread() { mDvrCallback->stopPlaybackThread(); } - void testRecordOutput() { mDvrCallback->testRecordOutput(); } - void stopRecordThread() { mDvrCallback->stopPlaybackThread(); } + void stopPlaybackThread() { mDvrPlaybackCallback->stopPlaybackThread(); } + void testRecordOutput() { mDvrRecordCallback->testRecordOutput(); } + void stopRecordThread() { mDvrRecordCallback->stopRecordThread(); } AssertionResult openDvrInDemux(DvrType type, uint32_t bufferSize); - AssertionResult configDvr(DvrSettings setting); - AssertionResult getDvrMQDescriptor(); + AssertionResult configDvrPlayback(DvrSettings setting); + AssertionResult configDvrRecord(DvrSettings setting); + AssertionResult getDvrPlaybackMQDescriptor(); + AssertionResult getDvrRecordMQDescriptor(); AssertionResult attachFilterToDvr(sp filter); AssertionResult detachFilterToDvr(sp filter); - AssertionResult stopDvr(); - AssertionResult startDvr(); - void closeDvr(); + AssertionResult stopDvrPlayback(); + AssertionResult startDvrPlayback(); + AssertionResult stopDvrRecord(); + AssertionResult startDvrRecord(); + void closeDvrPlayback(); + void closeDvrRecord(); protected: static AssertionResult failure() { return ::testing::AssertionFailure(); } @@ -175,11 +184,11 @@ class DvrTests { static AssertionResult success() { return ::testing::AssertionSuccess(); } sp mService; - sp mDvr; + sp mDvrPlayback; + sp mDvrRecord; sp mDemux; - sp mDvrCallback; - MQDesc mDvrMQDescriptor; - - pthread_t mPlaybackshread; - bool mPlaybackThreadRunning; + sp mDvrPlaybackCallback; + sp mDvrRecordCallback; + MQDesc mDvrPlaybackMQDescriptor; + MQDesc mDvrRecordMQDescriptor; }; diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp index d094510bbc..45951d2b20 100644 --- a/tv/tuner/1.0/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp @@ -360,13 +360,28 @@ void FrontendTests::verifyFrontendStatus(vector statusTypes, ASSERT_TRUE(status == Result::SUCCESS); } -AssertionResult FrontendTests::tuneFrontend(FrontendConfig config) { +AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWithDemux) { EXPECT_TRUE(mFrontendCallback) << "test with openFrontendById/setFrontendCallback/getFrontendInfo first."; EXPECT_TRUE(mFrontendInfo.type == config.type) << "FrontendConfig does not match the frontend info of the given id."; + 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.getDvrPlaybackMQDescriptor() == success(); + mDvrTests.startPlaybackInputThread(dvrConfig.playbackInputFile, + dvrConfig.settings.playback()); + if (!result) { + ALOGW("[vts] Software frontend dvr configure failed."); + return failure(); + } + } mFrontendCallback->tuneTestOnLock(mFrontend, config.settings); return AssertionResult(true); } @@ -379,10 +394,14 @@ AssertionResult FrontendTests::setLnb(uint32_t lnbId) { return AssertionResult(mFrontend->setLnb(lnbId) == Result::SUCCESS); } -AssertionResult FrontendTests::stopTuneFrontend() { +AssertionResult FrontendTests::stopTuneFrontend(bool testWithDemux) { EXPECT_TRUE(mFrontend) << "Test with openFrontendById first."; Result status; status = mFrontend->stopTune(); + if (mIsSoftwareFe && testWithDemux) { + mDvrTests.stopPlaybackThread(); + mDvrTests.closeDvrPlayback(); + } return AssertionResult(status == Result::SUCCESS); } @@ -415,9 +434,9 @@ void FrontendTests::tuneTest(FrontendConfig frontendConf) { ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(openFrontendById(feId)); ASSERT_TRUE(setFrontendCallback()); - ASSERT_TRUE(tuneFrontend(frontendConf)); + ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/)); verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses); - ASSERT_TRUE(stopTuneFrontend()); + ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/)); ASSERT_TRUE(closeFrontend()); } diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.h b/tv/tuner/1.0/vts/functional/FrontendTests.h index b8b9f476ca..c536325126 100644 --- a/tv/tuner/1.0/vts/functional/FrontendTests.h +++ b/tv/tuner/1.0/vts/functional/FrontendTests.h @@ -31,6 +31,7 @@ #include #include +#include "DvrTests.h" #include "VtsHalTvTunerV1_0TestConfigurations.h" #define WAIT_TIMEOUT 3000000000 @@ -100,7 +101,10 @@ class FrontendTests { public: sp mService; - void setService(sp tuner) { mService = tuner; } + void setService(sp tuner) { + mService = tuner; + mDvrTests.setService(tuner); + } AssertionResult getFrontendIds(); AssertionResult getFrontendInfo(uint32_t frontendId); @@ -108,23 +112,43 @@ class FrontendTests { AssertionResult setFrontendCallback(); AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type); AssertionResult stopScanFrontend(); - AssertionResult tuneFrontend(FrontendConfig config); + AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux); AssertionResult setLnb(uint32_t lnbId); void verifyFrontendStatus(vector statusTypes, vector expectStatuses); - AssertionResult stopTuneFrontend(); + AssertionResult stopTuneFrontend(bool testWithDemux); AssertionResult closeFrontend(); void getFrontendIdByType(FrontendType feType, uint32_t& feId); void tuneTest(FrontendConfig frontendConf); void scanTest(FrontendConfig frontend, FrontendScanType type); + void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; } + void setDemux(sp demux) { mDvrTests.setDemux(demux); } + protected: static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult success() { return ::testing::AssertionSuccess(); } + void getSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) { + PlaybackSettings playbackSettings{ + .statusMask = 0xf, + .lowThreshold = 0x1000, + .highThreshold = 0x07fff, + .dataFormat = DataFormat::TS, + .packetSize = 188, + }; + dvrConfig.type = DvrType::PLAYBACK; + dvrConfig.playbackInputFile = "/data/local/tmp/segment000000.ts"; + dvrConfig.bufferSize = FMQ_SIZE_4M; + dvrConfig.settings.playback(playbackSettings); + } + sp mFrontend; FrontendInfo mFrontendInfo; sp mFrontendCallback; hidl_vec mFeIds; + + DvrTests mDvrTests; + bool mIsSoftwareFe = false; }; diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp index 732090e769..a49000d452 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -77,6 +77,7 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf, } ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + mFrontendTests.setDemux(demux); mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); @@ -84,9 +85,9 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test - ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf)); + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); - ASSERT_TRUE(mFrontendTests.stopTuneFrontend()); + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); @@ -122,21 +123,21 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv mFilterTests.setDemux(demux); mDvrTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); - ASSERT_TRUE(mDvrTests.configDvr(dvrConf.settings)); - ASSERT_TRUE(mDvrTests.getDvrMQDescriptor()); + ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrConf.settings)); + ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId)); mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback()); - ASSERT_TRUE(mDvrTests.startDvr()); + ASSERT_TRUE(mDvrTests.startDvrPlayback()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); mDvrTests.stopPlaybackThread(); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); - ASSERT_TRUE(mDvrTests.stopDvr()); + ASSERT_TRUE(mDvrTests.stopDvrPlayback()); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); - mDvrTests.closeDvr(); + mDvrTests.closeDvrPlayback(); ASSERT_TRUE(mDemuxTests.closeDemux()); } @@ -159,9 +160,10 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); mDvrTests.setDemux(demux); + mFrontendTests.setDvrTests(mDvrTests); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); - ASSERT_TRUE(mDvrTests.configDvr(dvrConf.settings)); - ASSERT_TRUE(mDvrTests.getDvrMQDescriptor()); + ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); + ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); @@ -170,17 +172,17 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf, ASSERT_TRUE(filter != nullptr); mDvrTests.startRecordOutputThread(dvrConf.settings.record()); ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); - ASSERT_TRUE(mDvrTests.startDvr()); + ASSERT_TRUE(mDvrTests.startDvrRecord()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); - ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf)); + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); mDvrTests.testRecordOutput(); mDvrTests.stopRecordThread(); - ASSERT_TRUE(mFrontendTests.stopTuneFrontend()); + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); - ASSERT_TRUE(mDvrTests.stopDvr()); + ASSERT_TRUE(mDvrTests.stopDvrRecord()); ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); - mDvrTests.closeDvr(); + mDvrTests.closeDvrRecord(); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } @@ -223,8 +225,8 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC mFilterTests.setDemux(demux); mDvrTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); - ASSERT_TRUE(mDvrTests.configDvr(dvrConf.settings)); - ASSERT_TRUE(mDvrTests.getDvrMQDescriptor()); + ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); + ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); @@ -232,13 +234,13 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC filter = mFilterTests.getFilterById(filterId); ASSERT_TRUE(filter != nullptr); ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); - ASSERT_TRUE(mDvrTests.startDvr()); + ASSERT_TRUE(mDvrTests.startDvrRecord()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); - ASSERT_TRUE(mDvrTests.stopDvr()); + ASSERT_TRUE(mDvrTests.stopDvrRecord()); ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); - mDvrTests.closeDvr(); + mDvrTests.closeDvrRecord(); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } @@ -266,6 +268,7 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); + mFrontendTests.setDemux(demux); for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); @@ -289,9 +292,9 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set m ASSERT_TRUE(mFilterTests.startFilter(*id)); } // tune test - ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf)); + ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); - ASSERT_TRUE(mFrontendTests.stopTuneFrontend()); + ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.stopFilter(*id)); } diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h index d71222bb3d..284f78b194 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h @@ -16,7 +16,6 @@ #include "DemuxTests.h" #include "DescramblerTests.h" -#include "DvrTests.h" #include "FrontendTests.h" #include "LnbTests.h" @@ -145,6 +144,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam { mDemuxTests.setService(mService); mFilterTests.setService(mService); mLnbTests.setService(mService); + mDvrTests.setService(mService); } protected: @@ -157,6 +157,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam { DemuxTests mDemuxTests; FilterTests mFilterTests; LnbTests mLnbTests; + DvrTests mDvrTests; AssertionResult filterDataOutputTest(vector goldenOutputFiles); @@ -245,6 +246,7 @@ class TunerDescramblerHidlTest : public testing::TestWithParam { mFrontendTests.setService(mService); mDemuxTests.setService(mService); + mDvrTests.setService(mService); mDescramblerTests.setService(mService); mDescramblerTests.setCasService(mCasService); } @@ -264,5 +266,6 @@ class TunerDescramblerHidlTest : public testing::TestWithParam { DemuxTests mDemuxTests; FilterTests mFilterTests; DescramblerTests mDescramblerTests; + DvrTests mDvrTests; }; } // namespace diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h index 1d47636e1e..856a3edcfb 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -116,6 +116,7 @@ typedef enum { typedef enum { DVR_RECORD0, DVR_PLAYBACK0, + DVR_SOFTWARE_FE, DVR_MAX, } Dvr; @@ -133,6 +134,7 @@ struct FilterConfig { }; struct FrontendConfig { + bool isSoftwareFe; FrontendType type; FrontendSettings settings; vector tuneStatusTypes; @@ -202,7 +204,9 @@ inline void initFrontendConfig() { statuses.push_back(status); frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].expectTuneStatuses = statuses; + frontendArray[DVBT].isSoftwareFe = true; frontendArray[DVBS].type = FrontendType::DVBS; + frontendArray[DVBS].isSoftwareFe = true; }; /** Configuration array for the frontend scan test */ @@ -338,9 +342,20 @@ inline void initDvrConfig() { .packetSize = 188, }; dvrArray[DVR_PLAYBACK0].type = DvrType::PLAYBACK; - dvrArray[DVR_PLAYBACK0].playbackInputFile = "/vendor/etc/segment000000.ts"; + 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 */