diff options
author | jstebbins <[email protected]> | 2011-09-19 15:35:46 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2011-09-19 15:35:46 +0000 |
commit | d36f10c33b9f9f85134f70fc785e2523177b2444 (patch) | |
tree | e6906a5b917569d17da651ab6b897865609994d3 /libhb/decavcodec.c | |
parent | d145ee9d9ed7be65b83124afbf0cc71b60adddc6 (diff) |
Fix corrupt first frame in BD point-to-point
Seek point may be a recovery point which will not be a complete clean
frame. So consume frames till we reach the recovery frame count.
Patches Libav so it can tell us when the recovery point has been
reached.
Also improves detection of recovery points in TS files.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4231 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/decavcodec.c')
-rw-r--r-- | libhb/decavcodec.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index fcd3ce032..478934b3b 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -93,6 +93,7 @@ struct hb_work_private_s struct SwsContext *sws_context; // if we have to rescale or convert color space hb_downmix_t *downmix; int cadence[12]; + int wait_for_keyframe; }; static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *data, int size, int64_t pts ); @@ -170,6 +171,7 @@ static int decavcodecaInit( hb_work_object_t * w, hb_job_t * job ) hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) ); w->private_data = pv; + pv->wait_for_keyframe = 60; pv->job = job; if ( job ) pv->title = job->title; @@ -702,8 +704,9 @@ static void checkCadence( int * cadence, uint16_t flags, int64_t start ) * until enough packets have been decoded so that the timestamps can be * correctly rewritten, if this is necessary. */ -static int decodeFrame( hb_work_private_t *pv, uint8_t *data, int size, int sequence, int64_t pts, int64_t dts ) +static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequence, int64_t pts, int64_t dts ) { + hb_work_private_t *pv = w->private_data; int got_picture, oldlevel = 0; AVFrame frame; AVPacket avp; @@ -727,6 +730,23 @@ static int decodeFrame( hb_work_private_t *pv, uint8_t *data, int size, int sequ { av_log_set_level( oldlevel ); } + if( got_picture && pv->wait_for_keyframe > 0 ) + { + // Libav is inconsistant about how it flags keyframes. For many + // codecs it simply sets frame.key_frame. But for others, it only + // sets frame.pict_type. And for yet others neither gets set at all + // (qtrle). + int key = frame.key_frame || + ( w->codec_param != CODEC_ID_H264 && + ( frame.pict_type == AV_PICTURE_TYPE_I || + frame.pict_type == 0 ) ); + if( !key ) + { + pv->wait_for_keyframe--; + return 0; + } + pv->wait_for_keyframe = 0; + } if( got_picture ) { uint16_t flags = 0; @@ -894,14 +914,14 @@ static void decodeVideo( hb_work_object_t *w, uint8_t *data, int size, int seque if ( pout_len > 0 ) { - decodeFrame( pv, pout, pout_len, sequence, parser_pts, parser_dts ); + decodeFrame( w, pout, pout_len, sequence, parser_pts, parser_dts ); } } while ( pos < size ); /* the stuff above flushed the parser, now flush the decoder */ if ( size <= 0 ) { - while ( decodeFrame( pv, NULL, 0, sequence, AV_NOPTS_VALUE, AV_NOPTS_VALUE ) ) + while ( decodeFrame( w, NULL, 0, sequence, AV_NOPTS_VALUE, AV_NOPTS_VALUE ) ) { } flushDelayQueue( pv ); @@ -1303,6 +1323,7 @@ static void decavcodecvFlush( hb_work_object_t *w ) avcodec_flush_buffers( pv->context ); } } + pv->wait_for_keyframe = 60; } hb_work_object_t hb_decavcodecv = |