From 2414566a5bf4b18089f1eb957e135720cec7f2ea Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Tue, 3 Mar 2020 15:39:03 +0000 Subject: [PATCH] WIP: DVBSubtitles new timing loop, std::thread/cond and std::chrono --- boxstack.cc | 6 +- demuxerts.cc | 2 +- dvbsubtitles.cc | 436 ++++++++++++++++++++++++++++++--------- dvbsubtitles.h | 66 +++--- main.cc | 2 +- playerlivetv.cc | 31 ++- playerlivetv.h | 1 + playervideorec.cc | 2 + vdr.cc | 4 +- vrecordinglist.h | 3 + vrecordinglistadvanced.h | 3 + vrecordinglistclassic.h | 3 + vvideorec.cc | 4 +- 13 files changed, 407 insertions(+), 156 deletions(-) diff --git a/boxstack.cc b/boxstack.cc index abfbb91..f145525 100644 --- a/boxstack.cc +++ b/boxstack.cc @@ -224,10 +224,10 @@ void BoxStack::redrawAllBoxes() void BoxStack::update(Boxx* toUpdate, Region* regionToUpdate) { - Log::getInstance()->log("BoxStack", Log::DEBUG, "Update called"); +// Log::getInstance()->log("BoxStack", Log::DEBUG, "Update called"); if (!initted) return; // it is allowed to call this before init boxLock.lock(); - Log::getInstance()->log("BoxStack", Log::DEBUG, "Locked for update"); +// Log::getInstance()->log("BoxStack", Log::DEBUG, "Locked for update"); // Get the z index of the box int z = 0; @@ -286,7 +286,7 @@ void BoxStack::update(Boxx* toUpdate, Region* regionToUpdate) } boxLock.unlock(); - Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for update"); +// Log::getInstance()->log("BoxStack", Log::DEBUG, "Unlocked for update"); } void BoxStack::repaintRevealed(int x, Region r) diff --git a/demuxerts.cc b/demuxerts.cc index 1466fff..7f2d4c1 100644 --- a/demuxerts.cc +++ b/demuxerts.cc @@ -732,7 +732,7 @@ int DemuxerTS::processTS(UCHAR* buf) if (pid == subID && subActive && subPacket.getLength() == subLength) { parsePacketDetails(subPacket); -Log::getInstance()->log("DEMUXERTS", Log::DEBUG, "SUBMITTING A SUBTITLE PACKET %d %x", subLength, subPacket.getSubstream()); +//Log::getInstance()->log("DEMUXERTS", Log::DEBUG, "SUBMITTING A SUBTITLE PACKET %d %x", subLength, subPacket.getSubstream()); submitPacket(subPacket); subActive = false; } diff --git a/dvbsubtitles.cc b/dvbsubtitles.cc index f90a8d6..db440e9 100644 --- a/dvbsubtitles.cc +++ b/dvbsubtitles.cc @@ -1,5 +1,5 @@ /* - Copyright 2008 Mark Calderbank + Copyright 2008 Mark Calderbank, 2020 Chris Tallon This file is part of VOMP. @@ -14,8 +14,7 @@ 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 . */ /* Sections of code and general methods adopted from VDR version 1.6.0 * dvbsubtitle.c (GPL version 2 or later) @@ -26,66 +25,42 @@ /* Reference ETSI EN 300 743 V1.3.1 (2006-11) */ -#include "dvbsubtitles.h" -#include "demuxer.h" -#include "osdreceiver.h" -#include "video.h" -#include "log.h" -// --- cTimeMs --------------------------------------------------------------- -// Borrowed from the vdr tools +#define DVBSDEBUG 0 -cTimeMs::cTimeMs(int Ms) -{ - initted = false; - if (Ms >= 0) - Set(Ms); - else - { - begin = 0; - isFirstCheck = false; - } -} +#ifdef DVBSDEBUG -uint64_t cTimeMs::Now(void) -{ - struct timespec tp; +// DBG +#include +#include +#include +#include - if (getClockRealTime(&tp) == 0) - return (uint64_t(tp.tv_sec)) * 1000 + tp.tv_nsec / 1000000; - else - Log::getInstance()->log("SUBTITLES", Log::ERR, "cTimeMs: clock_gettime(CLOCK_REALTIME) failed"); - return 0; +std::string tp2str(const std::chrono::time_point& tp) +{ + auto tms = std::chrono::time_point_cast(tp); + std::chrono::milliseconds e = tms.time_since_epoch(); + long long c = e.count(); + time_t tt = c / 1000; + int ttm = c % 1000; + auto stm = std::localtime(&tt); + std::stringstream ss; + ss << std::put_time(stm, "%T") << "." << std::setfill('0') << std::setw(3) << ttm; + return ss.str(); } -void cTimeMs::Set(int Ms) -{ - isFirstCheck = true; // Timer set, the first check can be done once - begin = Now() + Ms; +#endif - if (Ms) initted = true; -} -bool cTimeMs::TimedOut(void) -{ - if (isFirstCheck && (Now() >= begin)) - { - isFirstCheck = false; // Timer timed out & the first check is done - return true; - } - else - return false; -} -uint64_t cTimeMs::Elapsed(void) -{ - if (!initted) return 0; - return Now() - begin; -} +#include "demuxer.h" +#include "osdreceiver.h" +#include "video.h" +#include "log.h" -//-------- End of cTimeMs borrowed from the vdr tools -------- +#include "dvbsubtitles.h" DVBSubtitleCLUT::DVBSubtitleCLUT() : version(0xFF), @@ -545,22 +520,31 @@ DVBSubtitles::DVBSubtitles(OSDReceiver* tosd) : osd(tosd), pageOnDisplay(65536), running(false), - showing(false), - threadNudged(false), - SubtitleTimeout(0), - timeout_clear(false) + showing(false) { } void DVBSubtitles::put(const PESPacket& packet) { + // Player object play feed thread comes here, via the demuxer + // input_mutex only used in put() here, start(), stop() and threadMethod() + // So, roll old Thread::mutex/cond into input_mutex? + input_mutex.lock(); if (running) { if (packet.getPTS() != PESPacket::PTS_INVALID) { worklist.push_back(packet); - nudge(); + signalRecalcWLTO = true; + Log::getInstance()->log("DVBSubs", Log::DEBUG, "Received packet: PTS: %llu, size: %u, type: %u", packet.getPTS(), packet.getSize(), packet.getPacketType()); + + + dvbsCond.notify_one(); + } + else + { + Log::getInstance()->log("DVBSubs", Log::DEBUG, "PUT DROPPING INVALID PACKET: PTS: %llu, size: %u, type: %u", packet.getPTS(), packet.getSize(), packet.getPacketType()); } } input_mutex.unlock(); @@ -786,7 +770,7 @@ void DVBSubtitles::finishPage(const DVBSubtitlePage& page) DVBSubtitlePage::RegionMap::const_iterator region_iter; region_iter = page.regions.find(i->first); if (region_iter == page.regions.end()) continue; - Log::getInstance()->log("SUBTITLES", Log::DEBUG, "Clear region %d", i->first); + Log::getInstance()->log("DVBSubs", Log::DEBUG, "Clear region %d", i->first); if (!osdMenuShowing) osd->clearOSDArea(i->second.x, i->second.y, region_iter->second.getWidth(), region_iter->second.getHeight(),dds); } @@ -797,55 +781,74 @@ void DVBSubtitles::finishPage(const DVBSubtitlePage& page) DVBSubtitlePage::RegionMap::const_iterator region_iter; region_iter = page.regions.find(i->first); if (region_iter == page.regions.end()) continue; - Log::getInstance()->log("SUBTITLES", Log::DEBUG, "Display region %d", i->first); + Log::getInstance()->log("DVBSubs", Log::DEBUG, "Display region %d", i->first); if (!osdMenuShowing) osd->drawOSDBitmap(i->second.x, i->second.y, region_iter->second,dds); } // after displaying regions set the page timeout timer - SubtitleTimeout.Set(page.timeout * 1000); - timeout_clear=false; - Log::getInstance()->log("SUBTITLES", Log::DEBUG, "SubtitleTimeout %d", page.timeout); + + subtitleTimeoutPoint = std::chrono::system_clock::now() + std::chrono::seconds(page.timeout); + subtitleTimeoutPointActive = true; + + Log::getInstance()->log("DVBSubs", Log::DEBUG, "SubtitleTimeout %d", page.timeout); } -int DVBSubtitles::start() +void DVBSubtitles::start() { + Log::getInstance()->log("DVBSubs", Log::DEBUG, "subs start"); + +#ifdef DVBSDEBUG + + DBG = fopen("dfifo", "a"); + + fprintf(DBG, "\033[H\033[2J"); + fflush(DBG); + +#endif + input_mutex.lock(); + dds=DVBSubtitleDisplayDefinition(); running = true; + + dvbsThread = std::thread([this] { threadMethod(); }); + input_mutex.unlock(); - return threadStart(); } void DVBSubtitles::stop() { - threadStop(); + Log::getInstance()->log("DVBSubs", Log::DEBUG, "subs stop"); + input_mutex.lock(); - running = false; - worklist.clear(); - input_mutex.unlock(); - output_mutex.lock(); - PageMap::const_iterator pageEntry = pages.find(pageOnDisplay); - if (pageEntry != pages.end()) + if (!running) { - const DVBSubtitlePage& page = pageEntry->second; - DVBSubtitlePage::DisplayMap::const_iterator i; - for (i = page.currentDisplay.begin(); i != page.currentDisplay.end(); ++i) - { - DVBSubtitlePage::RegionMap::const_iterator region_iter; - region_iter = page.regions.find(i->first); - if (region_iter == page.regions.end()) continue; - if (!osdMenuShowing) osd->clearOSDArea(i->second.x, i->second.y, - region_iter->second.getWidth(), region_iter->second.getHeight(),dds); - } + Log::getInstance()->log("DVBSubs", Log::ERR, "STOP called, already dead!"); + input_mutex.unlock(); + return; } - pages.clear(); - pageOnDisplay = 65536; - output_mutex.unlock(); - threadNudged = false; + + running = false; // disables put() + signalStop = true; + dvbsCond.notify_one(); + input_mutex.unlock(); + dvbsThread.join(); + + worklist.clear(); + input_mutex.unlock(); + + clearDisplayedPages(); + + +#ifdef DVBSDEBUG + fclose(DBG); +#endif } void DVBSubtitles::show() { + Log::getInstance()->log("DVBSubs", Log::DEBUG, "subs show"); + output_mutex.lock(); showing = true; output_mutex.unlock(); @@ -853,8 +856,16 @@ void DVBSubtitles::show() void DVBSubtitles::hide() { - output_mutex.lock(); + Log::getInstance()->log("DVBSubs", Log::DEBUG, "subs hide"); + showing = false; + clearDisplayedPages(); +} + +void DVBSubtitles::clearDisplayedPages() +{ + output_mutex.lock(); + PageMap::const_iterator pageEntry = pages.find(pageOnDisplay); if (pageEntry != pages.end()) { @@ -871,26 +882,43 @@ void DVBSubtitles::hide() } pages.clear(); pageOnDisplay = 65536; + output_mutex.unlock(); } -void DVBSubtitles::nudge() +void DVBSubtitles::pause() { -#ifndef WIN32 - pthread_mutex_lock(&threadCondMutex); - threadNudged = true; - pthread_cond_signal(&threadCond); - pthread_mutex_unlock(&threadCondMutex); -#else - WaitForSingleObject(threadCondMutex, INFINITE); - threadNudged = true; - SetEvent(threadCond); - ReleaseMutex(threadCondMutex); -#endif + Log::getInstance()->log("DVBSubs", Log::DEBUG, "subs pause"); + + input_mutex.lock(); + if (!running) + { + Log::getInstance()->log("DVBSubs", Log::ERR, "pause called, already dead!"); + input_mutex.unlock(); + return; + } + + signalPause = true; + dvbsCond.notify_one(); + input_mutex.unlock(); } -#define SUBTITLE_TIMEOUT_MS 750 -// How often do we check if subtitles have been timed out. +void DVBSubtitles::unPause() +{ + Log::getInstance()->log("DVBSubs", Log::DEBUG, "subs pause"); + + input_mutex.lock(); + if (!running) + { + Log::getInstance()->log("DVBSubs", Log::ERR, "pause called, already dead!"); + input_mutex.unlock(); + return; + } + + signalRecalcWLTO = true; + dvbsCond.notify_one(); + input_mutex.unlock(); +} #if WIN32 // FIXME win pragma @@ -899,6 +927,190 @@ void DVBSubtitles::nudge() void DVBSubtitles::threadMethod() { + std::unique_lock ul(input_mutex); // Lock here, force start() to return before this does anything + + bool waitExpireST{}; + bool waitExpireWL{}; + + std::chrono::time_point worklistTimeoutPoint; + bool worklistTimeoutPointActive{}; + + while(1) + { +#ifdef DVBSDEBUG + + // TEMP DEBUG - re-enable nowPTS below when this goes + ULLONG nowPTS = Video::getInstance()->getCurrentTimestamp(); + fprintf(DBG, "\033[H\033[2J"); + fprintf(DBG, "Now: %s %llu\n", tp2str(std::chrono::system_clock::now()).c_str(), Video::getInstance()->getCurrentTimestamp()); + for (auto p : worklist) + { + fprintf(DBG, "packet PTS %llu SIZE %i\tTIME %s\n", p.getPTS(), p.getSize(), + tp2str(std::chrono::system_clock::now() + std::chrono::milliseconds(PTSDifference(p.getPTS(), nowPTS) / 90)).c_str()); + } + fflush(DBG); + +#endif + + + if (signalStop) + { + Log::getInstance()->log("DVBSubs", Log::INFO, "Thread exiting"); + signalStop = false; + return; + } + else if (signalPause) + { + signalPause = false; + subtitleTimeoutPointActive = false; + worklistTimeoutPointActive = false; + } + else if (signalRecalcWLTO) // once per incoming packet, and other times + { + signalRecalcWLTO = false; +#ifndef DVBSDEBUG + ULLONG nowPTS = Video::getInstance()->getCurrentTimestamp(); +#endif + + if (nowPTS == 0) + { + // Video is not started yet. DVBSub packet has come in. Don't set worklistTimeoutPoint, + // just store the packet and allow next signal to start things off + Log::getInstance()->log("DVBSubs", Log::DEBUG, "signalRecalcWLTO but Video PTS == 0"); + } + else + { + worklistTimeoutPointActive = true; + Log::getInstance()->log("DVBSubs", Log::DEBUG, "Calc: Num packets available: %i", worklist.size()); + + ULLONG pktPTS = worklist.front().getPTS(); + ULLONG diff = PTSDifference(pktPTS, nowPTS); + diff /= 90; // convert diff to ms (PTS difference is in 1/90000s) + if (diff < 60 * 1000) + { + worklistTimeoutPoint = std::chrono::system_clock::now() + std::chrono::milliseconds(diff); + } + else + { + // We have a problem. An action so far in the future should have + // been culled. Probably the action is already due and PTSDifference + // wrapped around. Therefore we sleep for a minimal time instead. + + // FIXME check if this still works + worklistTimeoutPoint = std::chrono::system_clock::now(); + } + + Log::getInstance()->log("DVBSubs", Log::DEBUG, "Calc'd new worklistTimeoutPoint"); + } + } + else if (waitExpireST) // do real work - subtitletimeout + { + Log::getInstance()->log("DVBSubs", Log::DEBUG, "Subtitle timeout occurred"); + waitExpireST = false; + subtitleTimeoutPointActive = false; + output_mutex.lock(); + if (showing && !osdMenuShowing) osd->clearOSD(); + output_mutex.unlock(); + } + else if (waitExpireWL) // do real work - worklist - could be multiple packets to do + { + Log::getInstance()->log("DVBSubs", Log::DEBUG, "Something to do"); + + waitExpireWL = false; + worklistTimeoutPointActive = false; + + ULLONG nowPTS = Video::getInstance()->getCurrentTimestamp(); + + // Guaranteed to be at least one packet in the worklist + PESPacket packet = worklist.front(); + ULLONG pktPTS = worklist.front().getPTS(); + + while(1) + { + worklist.pop_front(); + + output_mutex.lock(); + if (showing) decodePacket(packet); + output_mutex.unlock(); + + // Repeat this loop only if there is another packet and it's the same PTS as this one + // Not sure this ever happens. + if (worklist.size() && (worklist.front().getPTS() == pktPTS)) + { + packet = worklist.front(); + continue; + } + else + { + break; + } + } + + if (worklist.size()) + { + signalRecalcWLTO = true; + continue; // restart the loop and force a recalc + } + + + /* + + + if (PTSDifference(nowPTS, pktPTS) < 2*90000 // need this? we should be here exactly on time + || PTSDifference(pktPTS, nowPTS) < 4000) + { // It is due for processing or discarding. + worklist.pop_front(); + + output_mutex.lock(); + if (showing) decodePacket(packet); + output_mutex.unlock(); + } + else if (PTSDifference(pktPTS, nowPTS) >= 60*90000) + { // Seems like a bad or very old entry. Get rid of it. + finished = false; + worklist.pop_front(); + } +*/ + + + // Loop has exited. Either worklist is now empty or the next packet doesn't match the PTSDifference ranges + } + else + { + // Spurious? + } + + // Either: + // 1. sleep until timeout + // 2. sleep until next worklist + // 3. sleep until signalled + + if (!subtitleTimeoutPointActive && !worklistTimeoutPointActive) + { + Log::getInstance()->log("DVBSubs", Log::DEBUG, "No WL or STT. Infinite wait"); + dvbsCond.wait(ul); // Wait until signalled + } + else if (subtitleTimeoutPointActive) + { + if (worklistTimeoutPointActive && (worklistTimeoutPoint < subtitleTimeoutPoint)) + { + Log::getInstance()->log("DVBSubs", Log::DEBUG, "WaitFor: WL"); + if (dvbsCond.wait_until(ul, worklistTimeoutPoint) == std::cv_status::timeout) waitExpireWL = true; + } + else + { + Log::getInstance()->log("DVBSubs", Log::DEBUG, "WaitFor: ST"); + if (dvbsCond.wait_until(ul, subtitleTimeoutPoint) == std::cv_status::timeout) waitExpireST = true; + } + } + else + { + Log::getInstance()->log("DVBSubs", Log::DEBUG, "WaitFor: WL"); + if (dvbsCond.wait_until(ul, worklistTimeoutPoint) == std::cv_status::timeout) waitExpireWL = true; + } + } +/* + struct timespec sleeptime; sleeptime.tv_sec = 0; sleeptime.tv_nsec = 0; @@ -906,8 +1118,13 @@ void DVBSubtitles::threadMethod() timeout_clear=false; while (1) { - if (SubtitleTimeout.TimedOut()) // do we have a subtitle timeout + if (subtitleTimeoutPointActive && (subtitleTimeoutPoint < std::chrono::system_clock::now())) // do we have a subtitle timeout { + subtitleTimeoutPointActive = false; + + +// if (SubtitleTimeout.TimedOut()) // do we have a subtitle timeout +// { output_mutex.lock(); if (showing && !osdMenuShowing) { if (!timeout_clear) { @@ -919,7 +1136,15 @@ void DVBSubtitles::threadMethod() } else if (showing) // if not lets check when will we have it { + // Get milliseconds until the timeout + wakeup = std::chrono::duration_cast(subtitleTimeoutPoint - std::chrono::system_clock::now()).count(); + Log::getInstance()->log("DVBSubs", Log::DEBUG, "A1: %lu", wakeup); + + // now - begin wakeup = -(SubtitleTimeout.Elapsed()); + + Log::getInstance()->log("DVBSubs", Log::DEBUG, "A2: %lu", wakeup); + if (wakeup > 0 && sleeptime.tv_nsec == 0 && sleeptime.tv_sec == 0) // We are not done, we still have a Subtitle Timeout! { @@ -928,18 +1153,23 @@ void DVBSubtitles::threadMethod() timeout_clear=false; } } + + + //if (dvbsThreadStop) return; threadCheckExit(); + + threadLock(); if (!threadNudged) { // We have done the current work and no more has arrived. Sleep. if (sleeptime.tv_sec == 0 && sleeptime.tv_nsec == 0) { - Log::getInstance()->log("SUBTITLES", Log::DEBUG, "Sleeping until nudged."); + Log::getInstance()->log("DVBSubs", Log::DEBUG, "Sleeping until nudged."); threadWaitForSignal(); } else { - Log::getInstance()->log("SUBTITLES", Log::DEBUG, "Sleeping for %d and %d", sleeptime.tv_sec, sleeptime.tv_nsec); + Log::getInstance()->log("DVBSubs", Log::DEBUG, "Sleeping for %d and %d", sleeptime.tv_sec, sleeptime.tv_nsec); struct timespec targetTime; getClockRealTime(&targetTime); @@ -1019,6 +1249,8 @@ void DVBSubtitles::threadMethod() } } } + + */ } void DVBSubtitles::setOSDMenuVisibility(bool visible) diff --git a/dvbsubtitles.h b/dvbsubtitles.h index f3029f2..55bef11 100644 --- a/dvbsubtitles.h +++ b/dvbsubtitles.h @@ -14,43 +14,28 @@ 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 DVBSUBTITLES_H #define DVBSUBTITLES_H -#include "threadsystem.h" - -#include "bitmap.h" -#include "demuxer.h" -#ifndef WIN32 -#include -#else -typedef unsigned long long uint64_t; -#endif #include #include #include #include +#include #include +#include +#include +#ifndef WIN32 +#include +#else +typedef unsigned long long uint64_t; +#endif -class cTimeMs { - private: - uint64_t begin; - bool isFirstCheck; - public: - cTimeMs(int Ms = 0); - ///< Creates a timer with ms resolution and an initial timeout of Ms. - ///< If Ms is negative the timer is not initialized with the current - ///< time. - static uint64_t Now(void); - void Set(int Ms = 0); - bool TimedOut(void); - uint64_t Elapsed(void); - bool initted; -}; +#include "bitmap.h" +#include "demuxer.h" class OSDReceiver; @@ -122,17 +107,20 @@ public: }; -class DVBSubtitles : public Thread_TYPE +class DVBSubtitles { public: DVBSubtitles(OSDReceiver* tosd = NULL); virtual ~DVBSubtitles() {} void put(const PESPacket& packet); - int start(); + void start(); void stop(); void show(); void hide(); + void pause(); + void unPause(); void setOSDMenuVisibility(bool visible); + bool isShowing() { return showing; } private: OSDReceiver* osd; @@ -142,23 +130,27 @@ class DVBSubtitles : public Thread_TYPE UINT pageOnDisplay; bool decodePacket(const PESPacket&); void finishPage(const DVBSubtitlePage&); + void clearDisplayedPages(); DVBSubtitleDisplayDefinition dds; bool osdMenuShowing; bool running; bool showing; - bool threadNudged; - cTimeMs SubtitleTimeout; - bool timeout_clear; - void nudge(); - void lockInput(); - void unlockInput(); - void lockOutput(); - void unlockOutput(); + std::chrono::time_point subtitleTimeoutPoint; + bool subtitleTimeoutPointActive{}; void threadMethod(); - std::mutex input_mutex; + std::mutex input_mutex; // Also use as thread/cond/signal mutex, master loop etc. std::mutex output_mutex; + + std::thread dvbsThread; + std::condition_variable dvbsCond; + + bool signalRecalcWLTO{}; + bool signalStop{}; + bool signalPause{}; + + FILE* DBG; }; #endif diff --git a/main.cc b/main.cc index b727db3..65975a2 100644 --- a/main.cc +++ b/main.cc @@ -508,7 +508,7 @@ long long getTimeMS() return ts.tv_sec * 1000 + ts.tv_nsec / 1000000LL; } -int getClockRealTime(struct timespec *tp) +int getClockRealTime(struct timespec *tp) // FIXME - del if all goes chrono { return clock_gettime(CLOCK_REALTIME, tp); } diff --git a/playerlivetv.cc b/playerlivetv.cc index 6e1e813..62004b0 100644 --- a/playerlivetv.cc +++ b/playerlivetv.cc @@ -702,6 +702,8 @@ void PlayerLiveTV::threadMethod() { logger->log("PlayerLiveTV", Log::DEBUG, "start new stream"); + bool subsRestore = subtitles->isShowing(); + switchState(S_VIDEOSTARTUP); if (!checkError()) @@ -790,14 +792,27 @@ void PlayerLiveTV::threadMethod() } } - if (selected >= 0) { - demuxer->setSubID(chan->spids[selected].pid); - if (command->getSubDefault()) { - turnSubtitlesOn(true); - } else { - turnSubtitlesOn(false); - } - } + if (selected >= 0) + { + demuxer->setSubID(chan->spids[selected].pid); + + if (firstStart) + { + firstStart = false; + + if (command->getSubDefault()) + turnSubtitlesOn(true); + else + turnSubtitlesOn(false); + } + else + { + if (subsRestore) + turnSubtitlesOn(true); + else + turnSubtitlesOn(false); + } + } demuxer->setTID(chan->tpid); teletext->ResetDecoder(); diff --git a/playerlivetv.h b/playerlivetv.h index 028119d..75fe986 100644 --- a/playerlivetv.h +++ b/playerlivetv.h @@ -115,6 +115,7 @@ class PlayerLiveTV : public PlayerLive, public Thread_TYPE, public Callback, pub AFeed afeed; TFeed tfeed; ChannelList* chanList; + bool firstStart{true}; std::queue instructions; const static UCHAR I_SETCHANNEL = 1; diff --git a/playervideorec.cc b/playervideorec.cc index 73a25a7..2f68247 100644 --- a/playervideorec.cc +++ b/playervideorec.cc @@ -455,6 +455,7 @@ void PlayerVideoRec::switchState(UCHAR toState, ULONG jumpFrame) video->pause(); audio->pause(); + subtitles->pause(); state = S_PAUSE_P; return; } @@ -538,6 +539,7 @@ void PlayerVideoRec::switchState(UCHAR toState, ULONG jumpFrame) { video->unPause(); audio->unPause(); + subtitles->unPause(); #ifdef VOMP_PLATFORM_RASPBERRY vfeed.start(); diff --git a/vdr.cc b/vdr.cc index 11e9b56..bb97ca4 100644 --- a/vdr.cc +++ b/vdr.cc @@ -366,7 +366,7 @@ void VDR::threadMethod() { if (lastKArecv < (timeNow - 5)) { - logger->log("VDR", Log::DEBUG, "Sending KA packet"); + //logger->log("VDR", Log::DEBUG, "Sending KA packet"); if (!sendKA(timeNow)) { logger->log("VDR", Log::DEBUG, "Could not send KA, calling connectionDied"); @@ -456,7 +456,7 @@ void VDR::threadMethod() { lastKAsent = 0; lastKArecv = KAreply; - logger->log("VDR", Log::DEBUG, "Rxd correct KA reply"); + //logger->log("VDR", Log::DEBUG, "Rxd correct KA reply"); } } else diff --git a/vrecordinglist.h b/vrecordinglist.h index f9ec04e..67659dd 100644 --- a/vrecordinglist.h +++ b/vrecordinglist.h @@ -42,9 +42,12 @@ class VRecordingList : public TBBoxx VRecordingList(); virtual ~VRecordingList(); +/* #ifndef WIN32 using TBBoxx::draw; // Signal the compiler we are intentionally overriding the draw() virtual with different args #endif +*/ + virtual void draw(bool doIndexPop = false)=0; int handleCommand(int command); diff --git a/vrecordinglistadvanced.h b/vrecordinglistadvanced.h index f9dc189..d629af1 100644 --- a/vrecordinglistadvanced.h +++ b/vrecordinglistadvanced.h @@ -30,9 +30,12 @@ class VRecordingListAdvanced : public VRecordingList VRecordingListAdvanced(); virtual ~VRecordingListAdvanced(); +/* #ifndef WIN32 using TBBoxx::draw; // Signal the compiler we are intentionally overriding the draw() virtual with different args #endif +*/ + void draw(bool doIndexPop = false); bool load(); diff --git a/vrecordinglistclassic.h b/vrecordinglistclassic.h index ebd9156..f917b0f 100644 --- a/vrecordinglistclassic.h +++ b/vrecordinglistclassic.h @@ -28,9 +28,12 @@ class VRecordingListClassic : public VRecordingList VRecordingListClassic(); virtual ~VRecordingListClassic(); +/* #ifndef WIN32 using TBBoxx::draw; // Signal the compiler we are intentionally overriding the draw() virtual with different args #endif +*/ + void draw(bool doIndexPop = false); bool load(); diff --git a/vvideorec.cc b/vvideorec.cc index e71fa0d..bd080d3 100644 --- a/vvideorec.cc +++ b/vvideorec.cc @@ -768,8 +768,8 @@ void VVideoRec::doAudioSelector() void VVideoRec::doBar(int action_in) { - if (player->isSubtitlesOn()) clearOSD(); // remove dvbsubtitles - player->tellSubtitlesOSDVisible(true); + // if (player->isSubtitlesOn()) clearOSD(); // remove dvbsubtitles + // player->tellSubtitlesOSDVisible(true); barShowing = true; int action = action_in; -- 2.39.2