]> git.vomp.tv Git - vompclient.git/commitdiff
Slight improvement to subtitles crossing a PTS rollover
authorChris Tallon <chris@vomp.tv>
Thu, 23 May 2024 20:19:42 +0000 (20:19 +0000)
committerChris Tallon <chris@vomp.tv>
Thu, 23 May 2024 20:19:42 +0000 (20:19 +0000)
src/dvbsubtitles.cc
src/dvbsubtitles.h

index 61fe197ae7a0d899d4802f9639f19fc454fc3234..ce24ea2a0c9f925e73907657e58b78415bfc882e 100644 (file)
@@ -31,6 +31,7 @@
 
 #ifdef DVBSDEBUG
 #include <stdio.h>
+#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);
index 96c3fcf2e833895ab8316c85eb353df9abe74fdd..93886e0bb11eb61df81dce29ee3027f3be80eab1 100644 (file)
@@ -151,7 +151,7 @@ class DVBSubtitles
     bool signalStop{};
     bool signalPause{};
 
-//    FILE* DBG;
+  //  FILE* DBG;
 };
 
 #endif