OSDN Git Service

fix a couple transport stream issues
authorjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 23 Oct 2009 02:20:47 +0000 (02:20 +0000)
committerjstebbins <jstebbins@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Fri, 23 Oct 2009 02:20:47 +0000 (02:20 +0000)
when the first packet seen is audio, the stream timing for the audio
must be initialized a little different then when it follows video

add a more thorough check for duplicate packets.
a ts stream that is the result of splicing multiple clips together can
have duplicate continuity count values.  usually this means that a duplicate
packet exists and the duplicate is dropped.  but in the case of spliced
clips, the packet should not be dropped.

git-svn-id: svn://localhost/HandBrake/trunk@2895 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/reader.c
libhb/stream.c

index 11cb23b..1dda826 100644 (file)
@@ -141,7 +141,10 @@ static stream_timing_t *id_to_st( hb_reader_t *r, const hb_buffer_t *buf )
         }
         st->id = buf->id;
         st->average = 30.*90.;
-        st->last = buf->renderOffset - st->average;
+        if ( r->saw_video )
+            st->last = buf->renderOffset - st->average;
+        else
+            st->last = -st->average;
         if ( ( st->is_audio = is_audio( r, buf->id ) ) != 0 )
         {
             r->saw_audio = 1;
index c6376a1..26b6a7c 100644 (file)
@@ -114,6 +114,7 @@ struct hb_stream_s
     int     ts_pos[kMaxNumberDecodeStreams];
     int8_t  ts_skipbad[kMaxNumberDecodeStreams];
     int8_t  ts_streamcont[kMaxNumberDecodeStreams];
+    uint8_t ts_pkt_summary[kMaxNumberDecodeStreams][8];
 
     hb_buffer_t *fwrite_buf;      /* PS buffer (set by hb_ts_stream_decode) */
 
@@ -2274,11 +2275,31 @@ static int hb_ts_stream_decode( hb_stream_t *stream, hb_buffer_t *obuf )
             int continuity = (buf[3] & 0xF);
             if ( continuity == stream->ts_streamcont[curstream] )
             {
-                // we got a duplicate packet (usually used to introduce
-                // a PCR when one is needed). The only thing that can
-                // change in the dup is the PCR which we grabbed above
-                // so ignore the rest.
-                continue;
+                // Spliced transport streams can have duplicate 
+                // continuity counts at the splice boundary.
+                // Test to see if the packet is really a duplicate
+                // by comparing packet summaries to see if they
+                // match.
+                uint8_t summary[8];
+
+                summary[0] = adaption;
+                summary[1] = adapt_len;
+                if (adapt_len + 4 + 6 + 9 <= 188)
+                {
+                    memcpy(&summary[2], buf+4+adapt_len+9, 6);
+                }
+                else
+                {
+                    memset(&summary[2], 0, 6);
+                }
+                if ( memcmp( summary, stream->ts_pkt_summary[curstream], 8 ) == 0 )
+                {
+                    // we got a duplicate packet (usually used to introduce
+                    // a PCR when one is needed). The only thing that can
+                    // change in the dup is the PCR which we grabbed above
+                    // so ignore the rest.
+                    continue;
+                }
             }
             if ( !start && (stream->ts_streamcont[curstream] != -1) &&
                  !stream->ts_skipbad[curstream] &&
@@ -2288,10 +2309,26 @@ static int hb_ts_stream_decode( hb_stream_t *stream, hb_buffer_t *obuf )
                         (int)continuity,
                         (stream->ts_streamcont[curstream] + 1) & 0xf );
                 stream->ts_streamcont[curstream] = continuity;
-                               continue;
-                       }
-                       stream->ts_streamcont[curstream] = continuity;
-               }
+                continue;
+            }
+            stream->ts_streamcont[curstream] = continuity;
+
+            // Save a summary of this packet for later duplicate
+            // testing.  The summary includes some header information
+            // and payload bytes.  Should be enough to detect 
+            // non-duplicates.
+            stream->ts_pkt_summary[curstream][0] = adaption;
+            stream->ts_pkt_summary[curstream][1] = adapt_len;
+            if (adapt_len + 4 + 6 + 9 <= 188)
+            {
+                memcpy(&stream->ts_pkt_summary[curstream][2], 
+                        buf+4+adapt_len+9, 6);
+            }
+            else
+            {
+                memset(&stream->ts_pkt_summary[curstream][2], 0, 6);
+            }
+        }
 
         /* If we get here the packet is valid - process its data */