From 9d5289fa065c3ffa20314276ab91f569c4dd9b1c Mon Sep 17 00:00:00 2001 From: Amy Zhang Date: Thu, 18 Feb 2021 13:56:45 -0800 Subject: [PATCH] Wait for all the thread loop to exit to finish the filter/dvr/frontend close/stop API Call Test: atest android.media.tv.tuner.cts Bug: 180641600 Change-Id: I0925e8ffe5604d2c6a48871897871f5ac51c572e --- tv/tuner/1.1/default/Demux.cpp | 11 ++++++++--- tv/tuner/1.1/default/Dvr.cpp | 13 ++++++++++--- tv/tuner/1.1/default/Filter.cpp | 24 ++++++++++++++++-------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp index 66c95dc3c2..f4e4a919de 100644 --- a/tv/tuner/1.1/default/Demux.cpp +++ b/tv/tuner/1.1/default/Demux.cpp @@ -27,12 +27,16 @@ namespace V1_0 { namespace implementation { #define WAIT_TIMEOUT 3000000000 + Demux::Demux(uint32_t demuxId, sp tuner) { mDemuxId = demuxId; mTunerService = tuner; } -Demux::~Demux() {} +Demux::~Demux() { + mFrontendInputThreadRunning = false; + std::lock_guard lock(mFrontendInputThreadLock); +} Return Demux::setFrontendDataSource(uint32_t frontendId) { ALOGV("%s", __FUNCTION__); @@ -171,6 +175,8 @@ Return Demux::close() { mFilters.clear(); mLastUsedFilterId = -1; mTunerService->removeDemux(mDemuxId); + mFrontendInputThreadRunning = false; + std::lock_guard lock(mFrontendInputThreadLock); return Result::SUCCESS; } @@ -322,6 +328,7 @@ uint16_t Demux::getFilterTpid(uint64_t filterId) { } void Demux::startFrontendInputLoop() { + mFrontendInputThreadRunning = true; pthread_create(&mFrontendInputThread, NULL, __threadLoopFrontend, this); pthread_setname_np(mFrontendInputThread, "frontend_input_thread"); } @@ -334,8 +341,6 @@ void* Demux::__threadLoopFrontend(void* user) { void Demux::frontendInputThreadLoop() { std::lock_guard lock(mFrontendInputThreadLock); - mFrontendInputThreadRunning = true; - if (!mDvrPlayback) { ALOGW("[Demux] No software Frontend input configured. Ending Frontend thread loop."); mFrontendInputThreadRunning = false; diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp index 3a4ef1bee7..93bb6a875b 100644 --- a/tv/tuner/1.1/default/Dvr.cpp +++ b/tv/tuner/1.1/default/Dvr.cpp @@ -37,7 +37,10 @@ Dvr::Dvr(DvrType type, uint32_t bufferSize, const sp& cb, sp lock(mDvrThreadLock); +} Return Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) { ALOGV("%s", __FUNCTION__); @@ -118,6 +121,9 @@ Return Dvr::detachFilter(const sp& filter) { Return Dvr::start() { ALOGV("%s", __FUNCTION__); + if (mDvrThreadRunning) { + return Result::SUCCESS; + } if (!mCallback) { return Result::NOT_INITIALIZED; @@ -128,6 +134,7 @@ Return Dvr::start() { } if (mType == DvrType::PLAYBACK) { + mDvrThreadRunning = true; pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this); pthread_setname_np(mDvrThread, "playback_waiting_loop"); } else if (mType == DvrType::RECORD) { @@ -144,7 +151,6 @@ Return Dvr::stop() { ALOGV("%s", __FUNCTION__); mDvrThreadRunning = false; - lock_guard lock(mDvrThreadLock); mIsRecordStarted = false; @@ -164,6 +170,8 @@ Return Dvr::flush() { Return Dvr::close() { ALOGV("%s", __FUNCTION__); + mDvrThreadRunning = false; + lock_guard lock(mDvrThreadLock); return Result::SUCCESS; } @@ -199,7 +207,6 @@ void* Dvr::__threadLoopPlayback(void* user) { void Dvr::playbackThreadLoop() { ALOGD("[Dvr] playback threadLoop start."); lock_guard lock(mDvrThreadLock); - mDvrThreadRunning = true; while (mDvrThreadRunning) { uint32_t efState = 0; diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp index 6b2413c97e..2e29aa9696 100644 --- a/tv/tuner/1.1/default/Filter.cpp +++ b/tv/tuner/1.1/default/Filter.cpp @@ -77,7 +77,10 @@ Filter::Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize, } } -Filter::~Filter() {} +Filter::~Filter() { + mFilterThreadRunning = false; + std::lock_guard lock(mFilterThreadLock); +} Return Filter::getId64Bit(getId64Bit_cb _hidl_cb) { ALOGV("%s", __FUNCTION__); @@ -137,15 +140,14 @@ Return Filter::configure(const DemuxFilterSettings& settings) { Return Filter::start() { ALOGV("%s", __FUNCTION__); - + mFilterThreadRunning = true; return startFilterLoop(); } Return Filter::stop() { ALOGV("%s", __FUNCTION__); - mFilterThreadRunning = false; - + std::lock_guard lock(mFilterThreadLock); return Result::SUCCESS; } @@ -185,6 +187,8 @@ Return Filter::releaseAvHandle(const hidl_handle& avMemory, uint64_t avD Return Filter::close() { ALOGV("%s", __FUNCTION__); + mFilterThreadRunning = false; + std::lock_guard lock(mFilterThreadLock); return mDemux->removeFilter(mFilterId); } @@ -331,9 +335,11 @@ void* Filter::__threadLoopFilter(void* user) { } void Filter::filterThreadLoop() { - ALOGD("[Filter] filter %" PRIu64 " threadLoop start.", mFilterId); + if (!mFilterThreadRunning) { + return; + } std::lock_guard lock(mFilterThreadLock); - mFilterThreadRunning = true; + ALOGD("[Filter] filter %" PRIu64 " threadLoop start.", mFilterId); // For the first time of filter output, implementation needs to send the filter // Event Callback without waiting for the DATA_CONSUMED to init the process. @@ -382,6 +388,9 @@ void Filter::filterThreadLoop() { // We do not wait for the last round of written data to be read to finish the thread // because the VTS can verify the reading itself. for (int i = 0; i < SECTION_WRITE_COUNT; i++) { + if (!mFilterThreadRunning) { + break; + } while (mFilterThreadRunning && mIsUsingFMQ) { status_t status = mFilterEventFlag->wait( static_cast(DemuxQueueNotifyBits::DATA_CONSUMED), &efState, @@ -417,9 +426,8 @@ void Filter::filterThreadLoop() { break; } } - mFilterThreadRunning = false; + break; } - ALOGD("[Filter] filter thread ended."); }