Index: libhb/reader.c =================================================================== --- libhb/reader.c (revision 991) +++ libhb/reader.c (working copy) @@ -15,6 +15,8 @@ hb_dvd_t * dvd; hb_buffer_t * ps; hb_stream_t * stream; + + uint sequence; } hb_reader_t; @@ -38,6 +40,7 @@ r->job = job; r->title = job->title; r->die = job->die; + r->sequence = 0; return hb_thread_init( "reader", ReaderFunc, r, HB_NORMAL_PRIORITY ); @@ -153,6 +156,7 @@ { hb_snooze( 50 ); } + buf->sequence = r->sequence++; hb_fifo_push( fifo, buf ); } else Index: libhb/decsub.c =================================================================== --- libhb/decsub.c (revision 991) +++ libhb/decsub.c (working copy) @@ -95,6 +95,11 @@ /* We got a complete subtitle, decode it */ *buf_out = Decode( w ); + if( *buf_out ) + { + (*buf_out)->sequence = in->sequence; + } + /* Wait for the next one */ pv->size_sub = 0; pv->size_got = 0; Index: libhb/decmpeg2.c =================================================================== --- libhb/decmpeg2.c (revision 991) +++ libhb/decmpeg2.c (working copy) @@ -151,6 +151,8 @@ buf = hb_buffer_init( m->width * m->height * 3 / 2 ); data = buf->data; + buf->sequence = buf_es->sequence; + // Was a good break point found? if( chap_break ) { Index: libhb/sync.c =================================================================== --- libhb/sync.c (revision 991) +++ libhb/sync.c (working copy) @@ -301,12 +301,29 @@ hb_log( "Sync: Video PTS discontinuity (current buffer start=%lld, next buffer start=%lld), trash Video", cur->start, next->start ); - /* Trash all subtitles */ + /* + * Do we need to trash the subtitle, is it from the next->start period + * or is it from our old position. If the latter then trash it. + */ if( pv->subtitle ) { - while( ( sub = hb_fifo_get( pv->subtitle->fifo_raw ) ) ) + while( ( sub = hb_fifo_see( pv->subtitle->fifo_raw ) ) ) { - hb_buffer_close( &sub ); + if( ( sub->start > ( cur->start - PTS_DISCONTINUITY_TOLERANCE ) ) && + ( sub->start < ( cur->start + PTS_DISCONTINUITY_TOLERANCE ) ) ) + { + /* + * The subtitle is from our current time region which we are + * jumping from. So trash it as we are about to jump backwards + * or forwards and don't want it blocking the subtitle fifo. + */ + hb_log("Trashing subtitle 0x%x due to PTS discontinuity", sub); + sub = hb_fifo_get( pv->subtitle->fifo_raw ); + hb_buffer_close( &sub ); + } else { + hb_log("NOT trashing subtitle 0x%x", sub); + break; + } } } @@ -336,20 +353,115 @@ if( sub2 && sub->stop > sub2->start ) sub->stop = sub2->start; - if( sub->stop > cur->start ) + hb_log("0x%x: video seq: %lld subtitle sequence: %lld", + sub, cur->sequence, sub->sequence); + + if( sub->sequence > cur->sequence ) + { + /* + * The video is behind where we are, so wait until it catches + * up to the same reader point on the DVD. Then our PTS should + * be in the same region as the video. + */ + hb_log("0x%x: Subtitle not at read point yet, defer", sub); + sub = NULL; break; + } + if( sub->stop > cur->start ) { + /* + * The stop time is in the future + */ + hb_log("0x%x: Video is at %lld substart=%lld substop=%lld, applying subtitle", + sub, cur->start, sub->start, sub->stop); + break; + } + else + { + /* + * The stop time is in the past. But is it due to it having been + * played already, or has the PTS been reset to 0? + */ + if( ( cur->start - sub->stop ) > PTS_DISCONTINUITY_TOLERANCE ) { + /* + * There is a lot of time between our current video and where + * this subtitle is ending, assume that we are about to reset + * the PTS and do not throw away this subtitle. + */ + hb_log("0x%x: Video is at %lld substart=%lld substop=%lld, Sub in the past, PTS reset?", + sub, cur->start, sub->start, sub->stop); + break; + } + } + + hb_log("0x%x: *** Video is at %lld substart=%lld substop=%lld, trashing subtitle", + sub, cur->start, sub->start, sub->stop); + /* The subtitle is older than this picture, trash it */ sub = hb_fifo_get( pv->subtitle->fifo_raw ); hb_buffer_close( &sub ); } - /* If we have subtitles left in the fifo, check if we should - apply the first one to the current frame or if we should - keep it for later */ - if( sub && sub->start > cur->start ) + if( sub ) { - sub = NULL; + if( sub->stop > sub->start) + { + /* + * Normal subtitle which ends after it starts, check to + * see that the current video is between the start and end. + */ + if( cur->start > sub->start && + cur->start < sub->stop ) + { + /* + * We should be playing this, so leave the subtitle in place. + */ + } + else + { + /* + * Defer until the play point is within the subtitle + */ + hb_log("0x%x: Normal subtitle too early, wait", sub); + sub = NULL; + } + } + else + { + /* + * The end of the subtitle is less than the start, this is a + * sign of a PTS discontinuity. + */ + if( sub->start > cur->start ) + { + /* + * we haven't reached the start time yet, or we have jumped + * backwards after having already started this subtitle. + */ + if( cur->start < sub->stop ) + { + /* + * We have jumped backwards and so should continue displaying + * this subtitle. + */ + hb_log("0x%x: Discontinuity end play this subtitle", sub); + } + else + { + /* + * Defer until the play point is within the subtitle + */ + hb_log("0x%x: Discontinuity subtitle too early, wait", sub); + sub = NULL; + } + } else { + /* + * Play this subtitle as the start is greater than our + * video point. + */ + hb_log("0x%x: Discontinuity start play this subtitle", sub); + } + } } } @@ -510,10 +622,13 @@ hb_log("Sync: Audio is way out of sync, attempt to reconverge from current video PTS"); /* - * It wasn't from the old place, so we must be from the new, but just too far out. So attempt to - * reconverge by resetting the point we want to be to where we are currently wanting to be. + * It wasn't from the old place, so we must be from + * the new, but just too far out. So attempt to + * reconverge by resetting the point we want to be to + * where we are currently wanting to be. */ pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate; + start = pts_expected - pv->pts_offset; } else { /* Use the older offset */ start = pts_expected - pv->pts_offset_old; Index: libhb/internal.h =================================================================== --- libhb/internal.h (revision 991) +++ libhb/internal.h (working copy) @@ -35,6 +35,8 @@ uint8_t * data; int cur; + int64_t sequence; + int id; int64_t start; int64_t stop; Index: libhb/common.c =================================================================== --- libhb/common.c (revision 991) +++ libhb/common.c (working copy) @@ -522,7 +522,7 @@ strcat( string, "\n" ); /* Print it */ - fprintf( stderr, "%s", string ); + fprintf( stdout, "%s", string ); } /**********************************************************************