From ed475e2009392f8e18956c2fa51fbc5e86ce944c Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Wed, 18 Mar 2020 17:39:03 +0000 Subject: [PATCH] Convert PlayerRadioRec to std::thread --- dvbsubtitles.cc | 1 + playerradiorec.cc | 114 +++++++++++++++++++++++---------------------- playerradiorec.h | 33 ++++++------- playervideolive.cc | 6 +-- playervideorec.cc | 6 +-- 5 files changed, 79 insertions(+), 81 deletions(-) diff --git a/dvbsubtitles.cc b/dvbsubtitles.cc index 5a1b740..3d2ff97 100644 --- a/dvbsubtitles.cc +++ b/dvbsubtitles.cc @@ -918,6 +918,7 @@ void DVBSubtitles::threadMethod() { #ifdef DVBSDEBUG + // FIXME dvbsubsdebug // TEMP DEBUG - re-enable nowPTS below when this goes ULLONG nowPTS = Video::getInstance()->getCurrentTimestamp(); fprintf(DBG, "\033[H\033[2J"); diff --git a/playerradiorec.cc b/playerradiorec.cc index 5ecd8cd..96df42b 100644 --- a/playerradiorec.cc +++ b/playerradiorec.cc @@ -17,6 +17,12 @@ along with VOMP. If not, see . */ +#include +#ifndef WIN32 +#include +#endif +#include + #include "log.h" #include "audio.h" #include "video.h" @@ -126,13 +132,9 @@ bool PlayerRadioRec::setLengthSeconds() } if (startPTS < endPTS) - { lengthSeconds = static_cast((endPTS - startPTS) / 90000); - } else - { lengthSeconds = static_cast((startPTS - endPTS) / 90000); - } return true; } @@ -149,6 +151,14 @@ int PlayerRadioRec::shutdown() return 1; } +void PlayerRadioRec::threadStop() +{ + playerThreadMutex.lock(); + threadReqQuit = true; + playerThreadCond.notify_one(); + playerThreadMutex.unlock(); + playerThread.join(); +} void PlayerRadioRec::setCurrentFrameNumber(ULONG num) { @@ -182,16 +192,14 @@ void PlayerRadioRec::play() stateLock.unlock(); } - void PlayerRadioRec::playpause() { if (!initted) return; stateLock.lock(); - if (state==S_PLAY) { - switchState(S_PAUSE_P); - } else { - switchState(S_PLAY); - } + if (state == S_PLAY) + switchState(S_PAUSE_P); + else + switchState(S_PLAY); stateLock.unlock(); } @@ -211,13 +219,9 @@ void PlayerRadioRec::pause() stateLock.lock(); if (state == S_PAUSE_P) - { switchState(S_PLAY); - } else - { switchState(S_PAUSE_P); - } stateLock.unlock(); } @@ -233,30 +237,28 @@ void PlayerRadioRec::jumpToPercent(double percent) void PlayerRadioRec::skipForward(UINT seconds) { - stateLock.lock(); + std::lock_guard lg(stateLock); logger->log("PlayerRadioRec", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds); ULONG currentSeconds = getCurrentSeconds(); ULONG currentFrame = demuxer->getPacketNum(); - if (currentSeconds == 0) { stateLock.unlock(); return; } // div by zero - if (currentFrame == 0) { stateLock.unlock(); return; } // Current pos from demuxer is not valid + if (currentSeconds == 0) return; // div by zero + if (currentFrame == 0) return; // Current pos from demuxer is not valid ULONG newFrame = currentFrame + (currentFrame * seconds / currentSeconds); - if (newFrame > lengthFrames) { switchState(S_PLAY); stateLock.unlock(); } + if (newFrame > lengthFrames) switchState(S_PLAY); else switchState(S_JUMP, newFrame); - stateLock.unlock(); } void PlayerRadioRec::skipBackward(UINT seconds) { - stateLock.lock(); + std::lock_guard lg(stateLock); logger->log("PlayerRadioRec", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds); - ULONG currentSeconds = getCurrentSeconds(); ULONG currentFrame = demuxer->getPacketNum(); - if (currentSeconds == 0) { stateLock.unlock(); return; } // div by zero - if (currentFrame == 0) { stateLock.unlock(); return; } // Current pos from demuxer is not valid + if (currentSeconds == 0) return; // div by zero + if (currentFrame == 0) return; // Current pos from demuxer is not valid ULONG newFrame; if (seconds > currentSeconds) @@ -265,7 +267,6 @@ void PlayerRadioRec::skipBackward(UINT seconds) newFrame = currentFrame - (currentFrame * seconds / currentSeconds); switchState(S_JUMP, newFrame); - stateLock.unlock(); } // ----------------------------------- Implementations called events @@ -352,21 +353,7 @@ void PlayerRadioRec::switchState(UCHAR toState, ULONG jumpToFrame) case S_PLAY: // to S_PLAY { startup = true; - - audio->reset(); - audio->setStreamType(Audio::MPEG2_PES); - audio->systemMuteOff(); - demuxer->reset(); - - // FIXME use restartAtFrame here? - if (currentFrameNumber > lengthFrames) currentFrameNumber = 0; - demuxer->setPacketNum(currentFrameNumber); - state = S_PLAY; - threadStart(); - logger->log("PlayerRadioRec", Log::DEBUG, "Immediate play"); - afeed.start(); - audio->play(); - + restartAtFrame(currentFrameNumber); return; } case S_PAUSE_P: // to S_PAUSE_P @@ -391,15 +378,31 @@ void PlayerRadioRec::switchState(UCHAR toState, ULONG jumpToFrame) void PlayerRadioRec::restartAtFrame(ULONG newFrame) { - afeed.stop(); - threadStop(); + if (state != S_STOP) + { + afeed.stop(); + threadStop(); + } + audio->reset(); audio->setStreamType(Audio::MPEG2_PES); demuxer->flush(); currentFrameNumber = newFrame; demuxer->setPacketNum(newFrame); + + state = S_PLAY; + + playerThreadMutex.lock(); + threadReqQuit = false; + playerThread = std::thread([this] + { + playerThreadMutex.lock(); + playerThreadMutex.unlock(); + threadMethod(); + }); + playerThreadMutex.unlock(); + afeed.start(); - threadStart(); audio->play(); audio->systemMuteOff(); audio->doMuting(); @@ -420,18 +423,16 @@ void PlayerRadioRec::doConnectionLost() void PlayerRadioRec::call(void* /*caller*/) { - threadSignalNoLock(); + // No thread sync + playerThreadCond.notify_one(); } // ----------------------------------- Feed thread void PlayerRadioRec::threadMethod() { - if (state == S_PLAY) threadFeedPlay(); -} + if (state != S_PLAY) return; -void PlayerRadioRec::threadFeedPlay() -{ ULLONG feedPosition; UINT thisRead, writeLength, thisWrite, askFor; time_t lastRescan = time(NULL); @@ -443,13 +444,15 @@ void PlayerRadioRec::threadFeedPlay() Buffer threadBuffer; + std::unique_lock ul(playerThreadMutex, std::defer_lock); + while(1) { thisRead = 0; writeLength = 0; thisWrite = 0; - threadCheckExit(); + if (threadReqQuit) return; // If we havn't rescanned for a while.. if ((lastRescan + 60) < time(NULL)) @@ -502,7 +505,7 @@ void PlayerRadioRec::threadFeedPlay() startup = false; } - threadCheckExit(); + if (threadReqQuit) return; while(writeLength < thisRead) { @@ -512,12 +515,14 @@ void PlayerRadioRec::threadFeedPlay() if (!thisWrite) { // demuxer is full and can't take anymore - threadLock(); - threadWaitForSignal(); - threadUnlock(); + + ul.lock(); + if (threadReqQuit) { ul.unlock(); return; } + playerThreadCond.wait(ul); + ul.unlock(); } - threadCheckExit(); + if (threadReqQuit) return; } threadBuffer.release(); @@ -526,7 +531,7 @@ void PlayerRadioRec::threadFeedPlay() // end of recording logger->log("PlayerRadioRec", Log::DEBUG, "Recording playback ends"); - threadCheckExit(); + if (threadReqQuit) return; Message* m = new Message(); // Must be done after this thread finishes, and must break into master mutex @@ -537,4 +542,3 @@ void PlayerRadioRec::threadFeedPlay() logger->log("PlayerRadioRec", Log::DEBUG, "Posting message to %p...", messageQueue); messageQueue->postMessage(m); } - diff --git a/playerradiorec.h b/playerradiorec.h index 0c498a9..585a7a1 100644 --- a/playerradiorec.h +++ b/playerradiorec.h @@ -1,5 +1,5 @@ /* - Copyright 2004-2006 Chris Tallon + Copyright 2004-2020 Chris Tallon This file is part of VOMP. @@ -14,26 +14,18 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with VOMP; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + along with VOMP. If not, see . */ #ifndef PLAYERRADIOREC_H #define PLAYERRADIOREC_H -#include -#include -#ifndef WIN32 -#include -#endif -#include - +#include #include +#include -#include "threadsystem.h" - -#include "callback.h" #include "defines.h" +#include "callback.h" #include "afeed.h" class Log; @@ -50,7 +42,7 @@ class MessageQueue; * I don't know where this comes from but things seem to work. */ -class PlayerRadioRec : public Thread_TYPE, public Callback +class PlayerRadioRec : public Callback { public: PlayerRadioRec(MessageQueue* messageQueue, void* messageReceiver); @@ -86,14 +78,9 @@ class PlayerRadioRec : public Thread_TYPE, public Callback const static UCHAR STOP_PLAYBACK = 2; const static UCHAR STREAM_END = 3; - protected: - void threadMethod(); - private: void switchState(UCHAR newState, ULONG jumpToFrame=0); - - void threadFeedPlay(); - void threadFeedScan(); + void threadMethod(); void doConnectionLost(); void restartAtFrame(ULONG newFrame); @@ -115,6 +102,12 @@ class PlayerRadioRec : public Thread_TYPE, public Callback std::mutex stateLock; + std::thread playerThread; + std::mutex playerThreadMutex; + std::condition_variable playerThreadCond; + bool threadReqQuit; + void threadStop(); + ULLONG lengthBytes{}; ULONG lengthFrames{}; ULONG currentFrameNumber{}; diff --git a/playervideolive.cc b/playervideolive.cc index 38e928f..ea17eac 100644 --- a/playervideolive.cc +++ b/playervideolive.cc @@ -877,10 +877,10 @@ void PlayerVideoLive::threadMethod() } //logger->log("PlayerVideoLive", Log::DEBUG, "wait for signal %d", streamChunks.size()); - playerThreadMutex.lock(); - if (!instructions.empty()) { playerThreadMutex.unlock(); continue; } + ul.lock(); + if (!instructions.empty()) { ul.unlock(); continue; } playerThreadCond.wait(ul); - playerThreadMutex.unlock(); + ul.unlock(); //logger->log("PlayerVideoLive", Log::DEBUG, "wait for signal2 %d",streamChunks.size()); } diff --git a/playervideorec.cc b/playervideorec.cc index 75df889..74e22f2 100644 --- a/playervideorec.cc +++ b/playervideorec.cc @@ -1166,10 +1166,10 @@ void PlayerVideoRec::threadFeedPlay() if (!thisWrite) { // demuxer is full and can't take anymore - playerThreadMutex.lock(); - if (threadReqQuit) { playerThreadMutex.unlock(); return; } + ul.lock(); + if (threadReqQuit) { ul.unlock(); return; } playerThreadCond.wait(ul); - playerThreadMutex.unlock(); + ul.unlock(); } if (threadReqQuit) return; -- 2.39.2