diff options
author | jstebbins <[email protected]> | 2011-04-10 17:39:24 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2011-04-10 17:39:24 +0000 |
commit | 48e2cd87978fc0e26044b0d686f1a9857dcf619d (patch) | |
tree | 810159e659320b125bf8a00b1ad1da8b53bb5b9a /libhb/sync.c | |
parent | 9cc5c63d8d1d72240a50dd12f9c5f367b6321983 (diff) |
Fix a deadlock that can happen with p-to-p encoding
With p-to-p, the audio sync thread waits for the video sync thread to
reach the designated start point. There is a possibility that the video
decoder will drop so many frames that the audio sync fifo fills before
any frames reach the video sync thread. When this happens, drop some
audio to unplug the pipeline.
Also, to make this less likely to happen, start sending data to the video
decoder 2 seconds before the actual desired start point. This will allow
the decoder to find an initial i-frame before the audio stalls since the
audio sync thread drops any audio that is before the designated start point.
A side effect of this is our start time now more accurate since the decoder
is only dropping frames before the start point instead of after.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3917 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/sync.c')
-rw-r--r-- | libhb/sync.c | 25 |
1 files changed, 24 insertions, 1 deletions
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; } |