summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/reader.c16
-rw-r--r--libhb/sync.c25
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;
}