Diff of /src/demuxers/demux_ts.c [0824f6] .. [687e49] Maximize Restore

  Switch to side-by-side view

--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.c
@@ -270,6 +270,7 @@
   int64_t          pts;
   buf_element_t   *buf;
   unsigned int     counter;
+  unsigned int     numPreview;
   uint16_t         descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */
   int              corrupted_pes;
   uint32_t         buffered_bytes;
@@ -362,8 +363,6 @@
 
   uint8_t buf[BUF_SIZE]; /* == PKT_SIZE * NPKT_PER_READ */
 
-  int numPreview;
-
 } demux_ts_t;
 
 typedef struct {
@@ -640,7 +639,7 @@
    */
   program_count = 0;
   for (program = pkt + 13;
-       program < pkt + 13 + section_length - 9;
+       (program < pkt + 13 + section_length - 9) && (program_count < MAX_PMTS);
        program += 4) {
     program_number = ((unsigned int)program[0] << 8) | program[1];
     pmt_pid = (((unsigned int)program[2] & 0x1f) << 8) | program[3];
@@ -652,18 +651,14 @@
       continue;
 
     /*
-     * If we have yet to learn our program number, then learn it,
-     * use this loop to eventually add support for dynamically changing
-     * PATs.
+     * Add the program number to the table if we haven't already
+     * seen it. The order of the program numbers is assumed not
+     * to change between otherwise identical PATs.
      */
-    program_count = 0;
-
-    while ((this->program_number[program_count] != INVALID_PROGRAM) &&
-           (this->program_number[program_count] != program_number)  &&
-           (program_count+1 < MAX_PMTS ) ) {
-      program_count++;
-    }
-    this->program_number[program_count] = program_number;
+    if (this->program_number[program_count] != program_number) {
+      this->program_number[program_count] = program_number;
+      this->pmt_pid[program_count] = INVALID_PID;
+    }
 
     /* force PMT reparsing when pmt_pid changes */
     if (this->pmt_pid[program_count] != pmt_pid) {
@@ -687,6 +682,14 @@
               this->program_number[program_count],
               this->pmt_pid[program_count]);
 #endif
+
+    ++program_count;
+  }
+
+  /* Add "end of table" markers. */
+  if (program_count < MAX_PMTS) {
+    this->program_number[program_count] = INVALID_PROGRAM;
+    this->pmt_pid[program_count] = INVALID_PID;
   }
 }
 
@@ -951,6 +954,14 @@
 
 
 /*
+ * Track how many of these types of packets we have seen in this stream.
+ */
+static inline unsigned get_preview_frame_number(unsigned *numPreview, unsigned limit) {
+  unsigned preview = *numPreview;
+  return (preview < limit) ? ++(*numPreview) : preview;
+}
+
+/*
  *  buffer arriving pes data
  */
 static void demux_ts_buffer_pes(demux_ts_t*this, unsigned char *ts,
@@ -980,26 +991,45 @@
   m->counter++;
 
   if (pus) { /* new PES packet */
-
     if (m->buffered_bytes) {
+      unsigned previewLimit = 0;
+
       m->buf->content = m->buf->mem;
       m->buf->size = m->buffered_bytes;
       m->buf->type = m->type;
-      if( (m->buf->type & 0xffff0000) == BUF_SPU_DVD ) {
-        m->buf->decoder_flags |= BUF_FLAG_SPECIAL;
-        m->buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE;
-        m->buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE;
+
+      switch (m->type & BUF_MAJOR_MASK) {
+      case BUF_SPU_BASE:
+        if( (m->buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK)) == BUF_SPU_DVB ) {
+            /* TODO: DVBSUB handling needed? */
+        }
+        break;
+
+      case BUF_VIDEO_BASE:
+        previewLimit = 5;
+        break;
+
+      case BUF_AUDIO_BASE:
+        previewLimit = 2;
+        break;
+
+      default:
+        break;
       }
-      else {
-        if (this->numPreview<5)
-	  ++this->numPreview;
-	if ( this->numPreview==1 )
-	  m->buf->decoder_flags=BUF_FLAG_HEADER | BUF_FLAG_FRAME_END;
-	else if ( this->numPreview<5 )
-	  m->buf->decoder_flags=BUF_FLAG_PREVIEW;
-	else
-	  m->buf->decoder_flags |= BUF_FLAG_FRAME_END;
+
+      if (previewLimit != 0) {
+        unsigned numPreview;
+
+        numPreview = get_preview_frame_number(&m->numPreview, previewLimit);
+
+        if (numPreview == 1)
+          m->buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_END;
+        else if (numPreview < previewLimit)
+          m->buf->decoder_flags = BUF_FLAG_PREVIEW;
+        else
+          m->buf->decoder_flags |= BUF_FLAG_FRAME_END;
       }
+
       m->buf->pts = m->pts;
       m->buf->decoder_info[0] = 1;
 
@@ -1080,6 +1110,7 @@
   if (m->buf != NULL) m->buf->free_buffer(m->buf);
   m->buf = NULL;
   m->counter = INVALID_CC;
+  m->numPreview = 0;
   m->descriptor_tag = descriptor;
   m->corrupted_pes = 1;
   m->buffered_bytes = 0;
@@ -2404,8 +2435,6 @@
   this->pkt_offset = (hdmv > 0) ? 4 : 0;
   this->pkt_size   = PKT_SIZE + this->pkt_offset;
 
-  this->numPreview=0;
-
   return &this->demux_plugin;
 }