diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp index 7e1f5ac55c..67eff1bd63 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 582c107814..7f282b250f 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; @@ -160,7 +160,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 1083f25129..6819659915 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp @@ -94,6 +94,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)); @@ -101,9 +102,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()); @@ -139,21 +140,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()); } @@ -176,9 +177,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)); @@ -187,17 +189,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()); } @@ -240,8 +242,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)); @@ -249,13 +251,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()); } @@ -283,6 +285,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)); @@ -306,9 +309,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 a270f696b2..6804f3c55f 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" @@ -147,6 +146,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam { mDemuxTests.setService(mService); mFilterTests.setService(mService); mLnbTests.setService(mService); + mDvrTests.setService(mService); } protected: @@ -159,6 +159,7 @@ class TunerBroadcastHidlTest : public testing::TestWithParam { DemuxTests mDemuxTests; FilterTests mFilterTests; LnbTests mLnbTests; + DvrTests mDvrTests; AssertionResult filterDataOutputTest(vector goldenOutputFiles); @@ -247,6 +248,7 @@ class TunerDescramblerHidlTest : public testing::TestWithParam { mFrontendTests.setService(mService); mDemuxTests.setService(mService); + mDvrTests.setService(mService); mDescramblerTests.setService(mService); mDescramblerTests.setCasService(mCasService); } @@ -266,5 +268,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 a944d02ede..6c68e3588e 100644 --- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h +++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h @@ -121,6 +121,7 @@ typedef enum { typedef enum { DVR_RECORD0, DVR_PLAYBACK0, + DVR_SOFTWARE_FE, DVR_MAX, } Dvr; @@ -143,6 +144,7 @@ struct TimeFilterConfig { }; struct FrontendConfig { + bool isSoftwareFe; FrontendType type; FrontendSettings settings; vector tuneStatusTypes; @@ -213,7 +215,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 */ @@ -355,9 +359,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 */