diff options
-rw-r--r-- | libhb/reader.c | 16 | ||||
-rw-r--r-- | libhb/sync.c | 25 |
2 files changed, 39 insertions, 2 deletions
diff --git a/libhb/reader.c b/libhb/reader.c index d506719d4..ec05a4798 100644 --- a/libhb/reader.c +++ b/libhb/reader.c @@ -35,6 +35,7 @@ typedef struct uint8_t saw_audio; // != 0 if we've seen audio int start_found; // found pts_to_start point + int64_t pts_to_start; uint64_t st_first; } hb_reader_t; @@ -72,6 +73,13 @@ hb_thread_t * hb_reader_init( hb_job_t * job ) if ( !job->pts_to_start ) r->start_found = 1; + else + { + // The frame at the actual start time may not be an i-frame + // so can't be decoded without starting a little early. + // sync.c will drop early frames. + r->pts_to_start = MAX(0, job->pts_to_start - 180000); + } return hb_thread_init( "reader", ReaderFunc, r, HB_NORMAL_PRIORITY ); @@ -265,6 +273,8 @@ static void ReaderFunc( void * _r ) } else if ( r->job->pts_to_start ) { + // Note, bd seeks always put us to an i-frame. no need + // to start decoding early using r->pts_to_start hb_bd_seek_pts( r->bd, r->job->pts_to_start ); r->job->pts_to_start = 0; r->start_found = 1; @@ -334,7 +344,11 @@ static void ReaderFunc( void * _r ) if ( hb_stream_read( r->stream, ps ) ) { if ( ps->start > 0 ) + { pts_to_start += ps->start; + r->pts_to_start += ps->start; + r->job->pts_to_start += ps->start; + } } if ( hb_stream_seek_ts( r->stream, pts_to_start ) >= 0 ) @@ -519,7 +533,7 @@ static void ReaderFunc( void * _r ) UpdateState( r, start ); if ( !r->start_found && - start >= r->job->pts_to_start ) + start >= r->pts_to_start ) { // pts_to_start point found r->start_found = 1; diff --git a/libhb/sync.c b/libhb/sync.c index bceeb10b5..6d7a778a5 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -914,7 +914,30 @@ static int syncAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in, while ( !pv->common->start_found && buf->start >= pv->common->audio_pts_thresh ) { - hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 200 ); + hb_cond_timedwait( pv->common->next_frame, pv->common->mutex, 10 ); + // There is an unfortunate unavoidable deadlock that can occur. + // Since we need to wait for a specific frame in syncVideoWork, + // syncAudioWork can be stalled indefinitely. The video decoder + // often drops multiple of the initial frames after starting + // because they require references that have not been decoded yet. + // This allows a lot of audio to be queued in the fifo and the + // audio fifo fills before we get a single video frame. So we + // must drop some audio to unplug the pipeline and allow the first + // video frame to be decoded. + if ( hb_fifo_is_full(w->fifo_in) ) + { + hb_buffer_t *tmp; + tmp = buf = hb_fifo_get( w->fifo_in ); + while ( tmp ) + { + tmp = hb_fifo_get( w->fifo_in ); + if ( tmp ) + { + hb_buffer_close( &buf ); + buf = tmp; + } + } + } } start = buf->start - pv->common->audio_pts_slip; } |