summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2009-10-23 02:20:47 +0000
committerjstebbins <[email protected]>2009-10-23 02:20:47 +0000
commitb3fbe46e0c8282124e0b910072eb5873cb5fa05e (patch)
tree5e6b0cc0d5cdb29355e2d756e51d9351c0fc510d
parent4784d4c2d72a0aa7366d48d3974339c12b0f65af (diff)
fix a couple transport stream issues
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://svn.handbrake.fr/HandBrake/trunk@2895 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/reader.c5
-rw-r--r--libhb/stream.c55
2 files changed, 50 insertions, 10 deletions
diff --git a/libhb/reader.c b/libhb/reader.c
index 11cb23b6f..1dda826d0 100644
--- a/libhb/reader.c
+++ b/libhb/reader.c
@@ -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;
diff --git a/libhb/stream.c b/libhb/stream.c
index c6376a1bf..26b6a7c84 100644
--- a/libhb/stream.c
+++ b/libhb/stream.c
@@ -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 */