From 1bb131d7143ae79c443943ef4215d37756c932fb Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Thu, 23 May 2024 20:19:42 +0000 Subject: [PATCH] Slight improvement to subtitles crossing a PTS rollover --- src/dvbsubtitles.cc | 78 +++++++++++++++++++++++++++++++++++++-------- src/dvbsubtitles.h | 2 +- 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/dvbsubtitles.cc b/src/dvbsubtitles.cc index 61fe197..ce24ea2 100644 --- a/src/dvbsubtitles.cc +++ b/src/dvbsubtitles.cc @@ -31,6 +31,7 @@ #ifdef DVBSDEBUG #include +#include "util.h" #endif #include "defines.h" @@ -497,6 +498,16 @@ static u8 PTSDifference(u8 pts1, u8 pts2) return (1LL<<33) + pts1 - pts2; } +static i8 PTSDifference2(u8 now, u8 next) +{ + // If next is a bit in the future, return value is small positive + // If next is a bit in the past, return value is small negative + // If PTS has wrapped then now will be massive, next will be very small + // The return value will be very large negative + + return (i8)next - (i8)now; +} + DVBSubtitles::DVBSubtitles(OSDReceiver* tosd) : osd(tosd), pageOnDisplay(65536), @@ -528,6 +539,22 @@ void DVBSubtitles::put(const PESPacket& packet) LogNT::getInstance()->debug(TAG, "PUT DROPPING INVALID PACKET: PTS: {}, size: {}, type: {}", packet.getPTS(), packet.getSize(), packet.getPacketType()); } } + + #ifdef DVBSDEBUG + + // FIXME dvbsubsdebug + u8 nowPTS = Video::getInstance()->getCurrentTimestamp(); + fprintf(DBG, "\033[H\033[2J"); + fprintf(DBG, "Now: %s %llu\n", tp2str(std::chrono::system_clock::now()).c_str(), nowPTS); + for (auto p : worklist) + { + i8 diff = PTSDifference2(nowPTS, p.getPTS()); + fprintf(DBG, "packet PTS %llu SIZE %i\tTIME %s \tDIFF %lli\n", p.getPTS(), p.getSize(), + tp2str(std::chrono::system_clock::now() + std::chrono::milliseconds(diff / 90)).c_str(), diff); + } + fflush(DBG); +#endif + input_mutex.unlock(); } @@ -925,22 +952,19 @@ void DVBSubtitles::threadMethod() while(1) { #ifdef DVBSDEBUG - // FIXME dvbsubsdebug - // TEMP DEBUG - re-enable nowPTS below when this goes u8 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()); + fprintf(DBG, "Now: %s %llu\n", tp2str(std::chrono::system_clock::now()).c_str(), nowPTS); 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()); + i8 diff = PTSDifference2(nowPTS, p.getPTS()); + fprintf(DBG, "packet PTS %llu SIZE %i\tTIME %s \tDIFF %lli\n", p.getPTS(), p.getSize(), + tp2str(std::chrono::system_clock::now() + std::chrono::milliseconds(diff / 90)).c_str(), diff); } fflush(DBG); - #endif - if (signalStop) { LogNT::getInstance()->info(TAG, "Thread exiting"); @@ -964,9 +988,9 @@ void DVBSubtitles::threadMethod() } else { - #ifndef DVBSDEBUG + //#ifndef DVBSDEBUG u8 nowPTS = Video::getInstance()->getCurrentTimestamp(); - #endif + //#endif if (nowPTS == 0) { @@ -980,12 +1004,33 @@ void DVBSubtitles::threadMethod() LogNT::getInstance()->debug(TAG, "Calc: Num packets available: {}", worklist.size()); u8 pktPTS = worklist.front().getPTS(); - u8 diff = PTSDifference(pktPTS, nowPTS); + i8 diff = PTSDifference2(nowPTS, pktPTS); + LogNT::getInstance()->debug(TAG, "Calc'd new worklistTimeoutPoint. pktPTS {} nowPTS {} diff {}", pktPTS, nowPTS, diff); diff /= 90; // convert diff to ms (PTS difference is in 1/90000s) - if (diff < 60 * 1000) + + if ((diff > 0) && (diff < (60 * 1000))) // Packet is in the next minute { worklistTimeoutPoint = std::chrono::system_clock::now() + std::chrono::milliseconds(diff); - LogNT::getInstance()->debug(TAG, "Calc'd new worklistTimeoutPoint"); + LogNT::getInstance()->debug(TAG, "Calc'd new worklistTimeoutPoint 1 {}", tp2str(worklistTimeoutPoint)); + } + else if ((diff <= 0) && (diff > -(60 * 1000))) // Packet is in the past minute + { + worklistTimeoutPoint = std::chrono::system_clock::now(); + LogNT::getInstance()->debug(TAG, "Problem packet 1"); + + // try this + waitExpireWL = true; + continue; + } + else if (diff < 95300000) + { + // PTS has wrapped + + u8 newDelay = (1LL<<33) - pktPTS + nowPTS; + newDelay /= 90; + + worklistTimeoutPoint = std::chrono::system_clock::now() + std::chrono::milliseconds(newDelay); + LogNT::getInstance()->debug(TAG, "Calc'd new worklistTimeoutPoint 2 {}", tp2str(worklistTimeoutPoint)); } else { @@ -996,6 +1041,10 @@ void DVBSubtitles::threadMethod() // FIXME check if this still works worklistTimeoutPoint = std::chrono::system_clock::now(); LogNT::getInstance()->debug(TAG, "Problem packet"); + + // try this + waitExpireWL = true; + continue; } } } @@ -1020,11 +1069,14 @@ void DVBSubtitles::threadMethod() //#endif // Guaranteed to be at least one packet in the worklist PESPacket packet = worklist.front(); - u8 pktPTS = worklist.front().getPTS(); + //u8 pktPTS = worklist.front().getPTS(); + u8 pktPTS = packet.getPTS(); while(1) { worklist.pop_front(); + LogNT::getInstance()->debug(TAG, "Consumed packet with PTS {}", pktPTS); + output_mutex.lock(); if (showing) decodePacket(packet); diff --git a/src/dvbsubtitles.h b/src/dvbsubtitles.h index 96c3fcf..93886e0 100644 --- a/src/dvbsubtitles.h +++ b/src/dvbsubtitles.h @@ -151,7 +151,7 @@ class DVBSubtitles bool signalStop{}; bool signalPause{}; -// FILE* DBG; + // FILE* DBG; }; #endif -- 2.39.2