summaryrefslogtreecommitdiffstats
path: root/libhb/decavcodec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhb/decavcodec.c')
-rw-r--r--libhb/decavcodec.c27
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 =