From 4d36883cc216b9b57a4a273981a5ab1b484bf4ff Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sat, 11 Jan 2020 19:01:30 +0000 Subject: [PATCH] Implement radio playback resume --- playerradio.cc | 66 +++++++++++++++++++++++------------------------ playerradio.h | 20 +++++++++----- vradiorec.cc | 11 ++++++-- vradiorec.h | 2 +- vrecordinglist.cc | 2 +- 5 files changed, 57 insertions(+), 44 deletions(-) diff --git a/playerradio.cc b/playerradio.cc index 24cc1c8..cb7e8d7 100644 --- a/playerradio.cc +++ b/playerradio.cc @@ -42,8 +42,8 @@ PlayerRadio::PlayerRadio(MessageQueue* tmessageQueue, void* tmessageReceiver) vdr = VDR::getInstance(); initted = false; lengthBytes = 0; - lengthPackets = 0; - streamPos = 0; + lengthFrames = 0; + currentFrameNumber = 0; state = S_STOP; startPTS = 0; @@ -62,7 +62,7 @@ PlayerRadio::~PlayerRadio() if (initted) shutdown(); } -int PlayerRadio::init(ULLONG tlengthBytes, ULONG tlengthPackets, bool isPesRecording) +int PlayerRadio::init(ULLONG tlengthBytes, ULONG tlengthFrames, bool isPesRecording) { if (initted) return 0; #ifndef WIN32 @@ -88,7 +88,7 @@ int PlayerRadio::init(ULLONG tlengthBytes, ULONG tlengthPackets, bool isPesRecor audio->stop(); lengthBytes = tlengthBytes; - lengthPackets = tlengthPackets; + lengthFrames = tlengthFrames; logger->log("PlayerRadio", Log::DEBUG, "PlayerRadio has received length bytes of %llu", lengthBytes); @@ -176,9 +176,9 @@ int PlayerRadio::shutdown() } -void PlayerRadio::setStartBytes(ULLONG startBytes) +void PlayerRadio::setCurrentFrameNumber(ULONG num) { - streamPos = startBytes; + currentFrameNumber = num; } ULONG PlayerRadio::getLengthSeconds() @@ -252,8 +252,8 @@ void PlayerRadio::jumpToPercent(double percent) { lock(); logger->log("PlayerRadio", Log::DEBUG, "JUMP TO %i%%", percent); - ULONG newPacket = (ULONG)(percent * lengthPackets / 100); - switchState(S_JUMP, newPacket); + ULONG newFrame = (ULONG)(percent * lengthFrames / 100); + switchState(S_JUMP, newFrame); unLock(); } @@ -262,14 +262,14 @@ void PlayerRadio::skipForward(UINT seconds) lock(); logger->log("PlayerRadio", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds); ULONG currentSeconds = getCurrentSeconds(); - ULONG currentPacket = demuxer->getPacketNum(); + ULONG currentFrame = demuxer->getPacketNum(); if (currentSeconds == 0) { unLock(); return; } // div by zero - if (currentPacket == 0) { unLock(); return; } // Current pos from demuxer is not valid + if (currentFrame == 0) { unLock(); return; } // Current pos from demuxer is not valid - ULONG newPacket = currentPacket + (currentPacket * seconds / currentSeconds); - if (newPacket > lengthPackets) { switchState(S_PLAY); unLock(); } - else switchState(S_JUMP, newPacket); + ULONG newFrame = currentFrame + (currentFrame * seconds / currentSeconds); + if (newFrame > lengthFrames) { switchState(S_PLAY); unLock(); } + else switchState(S_JUMP, newFrame); unLock(); } @@ -279,24 +279,24 @@ void PlayerRadio::skipBackward(UINT seconds) logger->log("PlayerRadio", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds); ULONG currentSeconds = getCurrentSeconds(); - ULONG currentPacket = demuxer->getPacketNum(); + ULONG currentFrame = demuxer->getPacketNum(); if (currentSeconds == 0) { unLock(); return; } // div by zero - if (currentPacket == 0) { unLock(); return; } // Current pos from demuxer is not valid + if (currentFrame == 0) { unLock(); return; } // Current pos from demuxer is not valid - ULONG newPacket; + ULONG newFrame; if ((UINT)seconds > currentSeconds) - newPacket = 0; + newFrame = 0; else - newPacket = currentPacket - (currentPacket * seconds / currentSeconds); + newFrame = currentFrame - (currentFrame * seconds / currentSeconds); - switchState(S_JUMP, newPacket); + switchState(S_JUMP, newFrame); unLock(); } // ----------------------------------- Implementations called events -void PlayerRadio::switchState(UCHAR toState, ULONG jumpPacket) +void PlayerRadio::switchState(UCHAR toState, ULONG jumpToFrame) { if (!initted) return; @@ -330,7 +330,7 @@ void PlayerRadio::switchState(UCHAR toState, ULONG jumpPacket) } case S_JUMP: // to S_JUMP { - restartAtPacket(jumpPacket); + restartAtFrame(jumpToFrame); return; } } @@ -364,7 +364,7 @@ void PlayerRadio::switchState(UCHAR toState, ULONG jumpPacket) { state = S_PLAY; audio->unPause(); - restartAtPacket(jumpPacket); + restartAtFrame(jumpToFrame); return; } } @@ -378,13 +378,13 @@ void PlayerRadio::switchState(UCHAR toState, ULONG jumpPacket) startup = true; audio->reset(); - audio->setStreamType(Audio::MPEG2_PES); + audio->setStreamType(Audio::MPEG2_PES); audio->systemMuteOff(); demuxer->reset(); - // FIXME use restartAtPacket here? - if (currentPacketNumber > lengthPackets) currentPacketNumber = 0; - demuxer->setPacketNum(currentPacketNumber); + // FIXME use restartAtFrame here? + if (currentFrameNumber > lengthFrames) currentFrameNumber = 0; + demuxer->setPacketNum(currentFrameNumber); state = S_PLAY; threadStart(); logger->log("PlayerRadio", Log::DEBUG, "Immediate play"); @@ -434,15 +434,15 @@ void PlayerRadio::unLock() #endif } -void PlayerRadio::restartAtPacket(ULONG newPacket) +void PlayerRadio::restartAtFrame(ULONG newFrame) { afeed.stop(); threadStop(); audio->reset(); - audio->setStreamType(Audio::MPEG2_PES); + audio->setStreamType(Audio::MPEG2_PES); demuxer->flush(); - currentPacketNumber = newPacket; - demuxer->setPacketNum(newPacket); + currentFrameNumber = newFrame; + demuxer->setPacketNum(newFrame); afeed.start(); threadStart(); audio->play(); @@ -481,9 +481,9 @@ void PlayerRadio::threadFeedPlay() UINT thisRead, writeLength, thisWrite, askFor; time_t lastRescan = time(NULL); - feedPosition = vdr->positionFromFrameNumber(currentPacketNumber); + feedPosition = vdr->positionFromFrameNumber(currentFrameNumber); if (!vdr->isConnected()) { doConnectionLost(); return; } - logger->log("PlayerRadio", Log::DEBUG, "startFeedPlay: wantedPacket %i goto %llu", currentPacketNumber, feedPosition); + logger->log("PlayerRadio", Log::DEBUG, "startFeedPlay: wantedFrame %i goto %llu", currentFrameNumber, feedPosition); while(1) @@ -497,7 +497,7 @@ void PlayerRadio::threadFeedPlay() // If we havn't rescanned for a while.. if ((lastRescan + 60) < time(NULL)) { - lengthBytes = vdr->rescanRecording(&lengthPackets); + lengthBytes = vdr->rescanRecording(&lengthFrames); if (!vdr->isConnected()) { doConnectionLost(); return; } logger->log("PlayerRadio", Log::DEBUG, "Rescanned and reset length: %llu", lengthBytes); lastRescan = time(NULL); diff --git a/playerradio.h b/playerradio.h index ac370ce..9cf5f70 100644 --- a/playerradio.h +++ b/playerradio.h @@ -41,15 +41,22 @@ class Demuxer; class VDR; class MessageQueue; +/* + * Frames... + * + * VDR tells me there are around 8.3 "frames" per second in radio recordings. + * I don't know where this comes from but things seem to work. + */ + class PlayerRadio : public Thread_TYPE, public Callback { public: PlayerRadio(MessageQueue* messageQueue, void* messageReceiver); virtual ~PlayerRadio(); - int init(ULLONG lengthBytes, ULONG lengthPackets, bool IsPesRecording); + int init(ULLONG lengthBytes, ULONG lengthFrames, bool IsPesRecording); int shutdown(); - void setStartBytes(ULLONG startBytes); + void setCurrentFrameNumber(ULONG num); void play(); void stop(); @@ -81,13 +88,13 @@ class PlayerRadio : public Thread_TYPE, public Callback void threadPostStopCleanup(); private: - void switchState(UCHAR newState, ULONG jumpPacket=0); + void switchState(UCHAR newState, ULONG jumpToFrame=0); void threadFeedPlay(); void threadFeedScan(); void doConnectionLost(); - void restartAtPacket(ULONG newPacket); + void restartAtFrame(ULONG newFrame); bool setLengthSeconds(); MessageQueue* messageQueue; @@ -113,9 +120,8 @@ class PlayerRadio : public Thread_TYPE, public Callback void unLock(); ULLONG lengthBytes; - ULLONG streamPos; - ULONG lengthPackets; - ULONG currentPacketNumber; + ULONG lengthFrames; + ULONG currentFrameNumber; UINT blockSize; UINT startupBlockSize; UCHAR* threadBuffer; diff --git a/vradiorec.cc b/vradiorec.cc index 7837587..99624eb 100644 --- a/vradiorec.cc +++ b/vradiorec.cc @@ -25,6 +25,7 @@ #include "player.h" #include "wsymbol.h" #include "recording.h" +#include "recinfo.h" #include "message.h" #include "vdr.h" #include "video.h" @@ -117,8 +118,14 @@ void VRadioRec::draw() fillColour(transparent); } -void VRadioRec::go() +void VRadioRec::go(bool resume) { + ULONG startFrameNum; + if (resume) + startFrameNum = myRec->recInfo->resumePoint; + else + startFrameNum = 0; + Log::getInstance()->log("VRadioRec", Log::DEBUG, "Starting stream: %s", myRec->getFileName()); ULONG lengthFrames = 0; bool isPesRecording; @@ -132,7 +139,7 @@ void VRadioRec::go() else { doBar(0); - // player->setStartBytes(startBytes); + player->setCurrentFrameNumber(startFrameNum); player->play(); playing = true; } diff --git a/vradiorec.h b/vradiorec.h index 543fb08..a552901 100644 --- a/vradiorec.h +++ b/vradiorec.h @@ -45,7 +45,7 @@ class VRadioRec : public Boxx, public TimerReceiver void draw(); void preDelete(); int handleCommand(int command); - void go(); + void go(bool resume); void timercall(int clientReference); void processMessage(Message* m); diff --git a/vrecordinglist.cc b/vrecordinglist.cc index c9059f7..6c4ca26 100644 --- a/vrecordinglist.cc +++ b/vrecordinglist.cc @@ -223,7 +223,7 @@ int VRecordingList::doPlay(bool resume) radrec->draw(); boxstack->add(radrec); boxstack->update(radrec); - radrec->go(); + radrec->go(resume); toPlay->setNew(false); draw(); -- 2.39.2