]> git.vomp.tv Git - vompclient-marten.git/commitdiff
Count frames properly in VDR demuxer
authorMark Calderbank <mark@vomp.tv>
Wed, 21 Jun 2006 20:53:25 +0000 (20:53 +0000)
committerMark Calderbank <mark@vomp.tv>
Wed, 21 Jun 2006 20:53:25 +0000 (20:53 +0000)
demuxer.cc
demuxer.h
demuxervdr.cc

index e2426d52a1e10c9eab0984e53496c4d37f2fafa5..0b6f2cd293412f26f2e0f8c089dc64687da62e83 100644 (file)
@@ -33,6 +33,8 @@
 #define DEMUXER_SEQ_HEAD 0xB3010000
 #endif
 
+#define DEMUXER_PIC_HEAD 0x00000101
+
 #define SEEK_THRESHOLD 150000 // About 1.5 seconds
 
 const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 };
@@ -237,7 +239,7 @@ void Demuxer::PESPacket::parseDetails()
   if (packetType >= PESTYPE_AUD0 && packetType <= PESTYPE_AUDMAX)
   {
     // Extract audio PTS if it exists
-    if ( data[7] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
+    if ( size >= 14 && (data[7] & 0x80) ) // PTS_DTS_flags indicate PTS
     {
       dx->audio_pts = pts = ( (ULLONG)(data[9] & 0x0E)  << 29 ) |
                             ( (ULLONG)(data[10])        << 22 ) |
@@ -265,7 +267,7 @@ void Demuxer::PESPacket::parseDetails()
   else if (packetType >= PESTYPE_VID0 && packetType <= PESTYPE_VIDMAX)
   {
     // Extract video PTS if it exists
-    if ( data[7] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
+    if ( size >= 14 && (data[7] & 0x80) ) // PTS_DTS_flags indicate PTS
     {
       dx->video_pts = pts = ( (ULLONG)(data[9] & 0x0E)  << 29 ) |
                             ( (ULLONG)(data[10])        << 22 ) |
@@ -310,3 +312,16 @@ void Demuxer::PESPacket::parseDetails()
     }
   }
 }
+
+UINT Demuxer::PESPacket::findPictureHeader()
+{
+  if (size < 12) return 0;
+  UINT pattern = *(UINT*)(data+8);
+  UINT pos = 11;
+  while (pattern != DEMUXER_PIC_HEAD)
+  {
+    if (++pos >= size) return 0;
+    pattern = (pattern << 8) | data[pos];
+  }
+  return pos-3;
+}
index 25b4b35b2118435ecb2a0adfd6498a9b60c29d92..6447f0c388dabb8af0b77f7e826746953f119d52 100644 (file)
--- a/demuxer.h
+++ b/demuxer.h
@@ -60,6 +60,7 @@ protected:
       bool seq_header;
       UINT submitted;
       virtual void parseDetails();
+      UINT findPictureHeader();
       
       static const ULLONG PTS_INVALID;
   };
index b22513e9438f4c7f1dc432922a0d4a7aba5e77ab..cb0a4fdcc14ab8eaf4f9af58a13ff9b5826f0bf2 100644 (file)
 #define __BYTE_ORDER __LITTLE_ENDIAN
 #endif
 
-#if __BYTE_ORDER == __BIG_ENDIAN
-#define DEMUXER_SEQ_HEAD 0x000001B3
-#else
-#define DEMUXER_SEQ_HEAD 0xB3010000
-#endif
-
 #define PTS_JUMP_MARGIN   10000
-#define PTS_ERASE_MARGIN 900000 // Erase PTS record if we get within 10 seconds
 #define PTS_ALLOWANCE 90000
-//#define PTS_UPDATE_FRAMES 2048
-//#define PTS_EXPIRE_FRAMES 2500
 
 // TODO: PTS class to handle wrapping arithmetic & comparisons?
 static ULLONG PTSDistance(ULLONG pts1, ULLONG pts2)
@@ -322,17 +313,14 @@ Log::getInstance()->log("Demuxer", Log::DEBUG, "STILL USING OLD REF");
 
 void DemuxerVDR::PESPacketVDR::parseDetails()
 {
-  // TODO: Currently, we naïvely assume that a packet contains a new frame
-  // if and only if it contains a pts, and that no packet contains more
-  // than one new frame
-
   DemuxerVDR* dx = (DemuxerVDR*)(DemuxerVDR::getInstance());
   PESPacket::parseDetails();
-  if (dx->frameCounting && pts != PTS_INVALID &&
+
+  if (dx->frameCounting && findPictureHeader() &&
       packetType >= PESTYPE_VID0 && packetType <= PESTYPE_VIDMAX)
   {
     ULONG frame_num = (dx->frameNumber)++;
-    if (seq_header)
+    if (seq_header && pts != PTS_INVALID)
     {
       PTSMapEntry me;
       pthread_mutex_lock(&(dx->pts_map_mutex));