OSDN Git Service

x264 bump to r1339-82b80ef
[handbrake-jp/handbrake-jp-git.git] / libhb / stream.c
index c6376a1..538353e 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) */
 
@@ -1694,7 +1695,7 @@ static void decode_element_descriptors(hb_stream_t* stream, int esindx,
         switch (dp[0])
         {
             case 5:    // Registration descriptor
-                stream->ts_format_id[esindx] = (dp[2] << 24) | (dp[3] << 16) |
+                stream->ts_format_id[esindx+1] = (dp[2] << 24) | (dp[3] << 16) |
                                                (dp[4] << 8)  | dp[5];
                 break;
 
@@ -1769,33 +1770,35 @@ int decode_program_map(hb_stream_t* stream)
 
         if ( index_of_pid( elementary_PID, stream ) < 0 )
         {
-            // already have this pid - do nothing
-        }
-        if (stream->ts_number_video_pids == 0 && st2codec[stream_type].kind == V )
-        {
-            stream->ts_video_pids[0] = elementary_PID;
-            stream->ts_stream_type[0] = stream_type;
-            stream->ts_number_video_pids = 1;
-        }
-        else
-        {
-            // Defined audio stream types are 0x81 for AC-3/A52 audio and 0x03
-            // for mpeg audio. But content producers seem to use other
-            // values (0x04 and 0x06 have both been observed) so at this point
-            // we say everything that isn't a video pid is audio then at the end
-            // of hb_stream_title_scan we'll figure out which are really audio
-            // by looking at the PES headers.
-            i = stream->ts_number_audio_pids;
-            if (i < kMaxNumberAudioPIDS)
+            // don't have this pid yet
+            if (stream->ts_number_video_pids == 0 && 
+                st2codec[stream_type].kind == V )
+            {
+                stream->ts_video_pids[0] = elementary_PID;
+                stream->ts_stream_type[0] = stream_type;
+                stream->ts_number_video_pids = 1;
+            }
+            else
             {
-                stream->ts_audio_pids[i] = elementary_PID;
-                stream->ts_stream_type[1 + i] = stream_type;
-                if (ES_info_length > 0)
+                // Defined audio stream types are 0x81 for AC-3/A52 audio 
+                // and 0x03 for mpeg audio. But content producers seem to 
+                // use other values (0x04 and 0x06 have both been observed) 
+                // so at this point we say everything that isn't a video 
+                // pid is audio then at the end of hb_stream_title_scan 
+                // we'll figure out which are really audio by looking at 
+                // the PES headers.
+                i = stream->ts_number_audio_pids;
+                if (i < kMaxNumberAudioPIDS)
                 {
-                    decode_element_descriptors(stream, i, ES_info_buf,
-                                               ES_info_length);
+                    stream->ts_audio_pids[i] = elementary_PID;
+                    stream->ts_stream_type[1 + i] = stream_type;
+                    if (ES_info_length > 0)
+                    {
+                        decode_element_descriptors(stream, i, ES_info_buf,
+                                                ES_info_length);
+                    }
+                    ++stream->ts_number_audio_pids;
                 }
-                ++stream->ts_number_audio_pids;
             }
         }
 
@@ -1804,7 +1807,7 @@ int decode_program_map(hb_stream_t* stream)
         free(ES_info_buf);
 
         if (cur_pos >= section_length - 4 /* stop before the CRC */)
-        done_reading_stream_types = 1;
+            done_reading_stream_types = 1;
     }
 
        free(descriptor_buf);
@@ -2274,11 +2277,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 +2311,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 */