Index: libhb/sync.c =================================================================== --- libhb/sync.c (revision 1022) +++ libhb/sync.c (working copy) @@ -52,6 +52,11 @@ uint64_t st_counts[4]; uint64_t st_dates[4]; uint64_t st_first; + + /* Throttle message flags */ + int trashing_audio; + int inserting_silence; + int way_out_of_sync; }; /*********************************************************************** @@ -85,6 +90,10 @@ pv->pts_offset_old = INT64_MIN; pv->count_frames = 0; + pv->trashing_audio = 0; + pv->inserting_silence = 0; + pv->way_out_of_sync = 0; + /* Calculate how many video frames we are expecting */ duration = 0; for( i = job->chapter_start; i <= job->chapter_end; i++ ) @@ -313,8 +322,8 @@ if( next->start < cur->start - PTS_DISCONTINUITY_TOLERANCE || next->start > cur->start + PTS_DISCONTINUITY_TOLERANCE ) { - hb_log( "Sync: Video PTS discontinuity (current buffer start=%lld, next buffer start=%lld), trash Video", - cur->start, next->start ); + //hb_log( "Sync: Video PTS discontinuity (current buffer start=%lld, next buffer start=%lld), trash Video", + // cur->start, next->start ); /* * Do we need to trash the subtitle, is it from the next->start period @@ -607,28 +616,39 @@ pts_expected = pv->pts_offset + sync->count_frames * 90000 / rate; // hb_log("Video Sequence: %lld, Audio Sequence: %lld", pv->video_sequence, buf->sequence); + /* * Using the same logic as the Video have we crossed a VOB * boundary as detected by the expected PTS and the PTS of our * audio being out by more than the tolerance value. */ - if( ( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE || - buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) && - pv->pts_offset_old > INT64_MIN ) + if( buf->start > pts_expected + PTS_DISCONTINUITY_TOLERANCE || + buf->start < pts_expected - PTS_DISCONTINUITY_TOLERANCE ) { /* * Useful debug, but too verbose for normal use. - */ + * hb_log("Sync: Audio discontinuity (sequence: vid %lld aud %lld) (pts %lld < %lld < %lld)", pv->video_sequence, buf->sequence, pts_expected - PTS_DISCONTINUITY_TOLERANCE, buf->start, pts_expected + PTS_DISCONTINUITY_TOLERANCE ); + */ /* There has been a PTS discontinuity, and this frame might be from before the discontinuity*/ - pts_expected = pv->pts_offset_old + sync->count_frames * - 90000 / rate; + if( pv->pts_offset_old > INT64_MIN ) + { + pts_expected = pv->pts_offset_old + sync->count_frames * + 90000 / rate; + } + else + { + pv->pts_offset_old = pv->pts_offset; + pts_expected = pv->pts_offset_old + sync->count_frames * + 90000 / rate; + } + /* * Is the audio from a valid period given the previous * Video PTS. I.e. has there just been a video PTS @@ -651,7 +671,11 @@ * up diverging even more. We need to hold on to the * audio until the video catches up. */ - hb_log("Sync: Audio is way out of sync, attempt to reconverge from current video PTS"); + if( !pv->way_out_of_sync ) + { + hb_log("Sync: Audio is way out of sync, attempt to reconverge from current video PTS"); + pv->way_out_of_sync = 1; + } /* * It wasn't from the old place, so we must be from @@ -674,9 +698,13 @@ /* Tolerance: 100 ms */ if( buf->start < pts_expected - 9000 ) { - /* Audio is behind the Video, trash it, can't use it now. */ - hb_log( "Sync: Audio PTS (%lld) < Video PTS (%lld) by greater than 100ms, trashing audio to reconverge", - buf->start, pts_expected); + if( !pv->trashing_audio ) + { + /* Audio is behind the Video, trash it, can't use it now. */ + hb_log( "Sync: Audio PTS (%lld) < Video PTS (%lld) by greater than 100ms, trashing audio to reconverge", + buf->start, pts_expected); + pv->trashing_audio = 1; + } buf = hb_fifo_get( audio->fifo_raw ); hb_buffer_close( &buf ); continue; @@ -684,9 +712,28 @@ else if( buf->start > pts_expected + 9000 ) { /* Audio is ahead of the Video, insert silence until we catch up*/ - hb_log("Sync: Audio PTS (%lld) > Video PTS (%lld) by greater than 100ms insert silence until reconverged", buf->start, pts_expected); + if( !pv->inserting_silence ) + { + hb_log("Sync: Audio PTS (%lld) > Video PTS (%lld) by greater than 100ms insert silence until reconverged", buf->start, pts_expected); + pv->inserting_silence = 1; + } InsertSilence( w, i ); continue; + } + else + { + if( pv->trashing_audio || pv->inserting_silence ) + { + hb_log( "Sync: Audio back in Sync at PTS %lld", buf->start ); + pv->trashing_audio = 0; + pv->inserting_silence = 0; + } + if( pv->way_out_of_sync ) + { + hb_log( "Sync: Audio no longer way out of sync at PTS %lld", + buf->start ); + pv->way_out_of_sync = 0; + } } if( job->acodec & HB_ACODEC_AC3 ) @@ -741,6 +788,16 @@ hb_fifo_push( fifo, buf ); } + if( hb_fifo_is_full( fifo ) && + pv->way_out_of_sync ) + { + /* + * Trash the top audio packet to avoid dead lock as we reconverge. + */ + buf = hb_fifo_get( audio->fifo_raw ); + hb_buffer_close( &buf ); + } + if( NeedSilence( w, audio ) ) { InsertSilence( w, i ); @@ -818,8 +875,6 @@ buf->stop = buf->start + 90000 / 20; memset( buf->data, 0, buf->size ); - hb_log( "sync: adding 50 ms of silence for track %x", - sync->audio->id ); hb_fifo_push( sync->audio->fifo_sync, buf ); sync->count_frames += job->arate / 20;