diff options
author | Mark Thompson <sw@jkqxz.net> | 2016-12-12 21:25:28 +0000 |
---|---|---|
committer | Mark Thompson <sw@jkqxz.net> | 2017-01-11 23:03:58 +0000 |
commit | a3c3a5eac20a51d402c332cdf5220fff40a7943f (patch) | |
tree | 5e2649d698d8a9078ab15996363bf53047a6ad3a | |
parent | 37fab0661a760b2a9d727939d72e629acee1a6ef (diff) | |
download | ffmpeg-a3c3a5eac20a51d402c332cdf5220fff40a7943f.tar.gz |
vaapi_encode: Support forcing IDR frames via AVFrame.pict_type
-rw-r--r-- | libavcodec/vaapi_encode.c | 27 | ||||
-rw-r--r-- | libavcodec/vaapi_encode.h | 1 |
2 files changed, 24 insertions, 4 deletions
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index c670ae62df..c93bfcc0b1 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -590,6 +590,10 @@ static int vaapi_encode_step(AVCodecContext *avctx, } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) { int activity; + // Run through the list of all available pictures repeatedly + // and issue the first one found which has all dependencies + // available (including previously-issued but not necessarily + // completed pictures). do { activity = 0; for (pic = ctx->pic_start; pic; pic = pic->next) { @@ -605,9 +609,15 @@ static int vaapi_encode_step(AVCodecContext *avctx, if (err < 0) return err; activity = 1; + // Start again from the beginning of the list, + // because issuing this picture may have satisfied + // forward dependencies of earlier ones. + break; } } while(activity); + // If we had a defined target for this step then it will + // always have been issued by now. if (target) { av_assert0(target->encode_issued && "broken dependencies?"); } @@ -639,8 +649,10 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, if (!pic) return AVERROR(ENOMEM); - if (ctx->input_order == 0 || ctx->gop_counter >= avctx->gop_size) { + if (ctx->input_order == 0 || ctx->force_idr || + ctx->gop_counter >= avctx->gop_size) { pic->type = PICTURE_TYPE_IDR; + ctx->force_idr = 0; ctx->gop_counter = 1; ctx->p_counter = 0; } else if (ctx->p_counter >= ctx->p_per_i) { @@ -722,7 +734,7 @@ fail: return AVERROR(ENOMEM); } -static int vaapi_encode_mangle_end(AVCodecContext *avctx) +static int vaapi_encode_truncate_gop(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodePicture *pic, *last_pic, *next; @@ -772,7 +784,7 @@ static int vaapi_encode_mangle_end(AVCodecContext *avctx) // mangle anything. } - av_log(avctx, AV_LOG_DEBUG, "Pictures at end of stream:"); + av_log(avctx, AV_LOG_DEBUG, "Pictures ending truncated GOP:"); for (pic = ctx->pic_start; pic; pic = pic->next) { av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")", picture_type_name[pic->type], @@ -826,6 +838,13 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n", input_image->width, input_image->height, input_image->pts); + if (input_image->pict_type == AV_PICTURE_TYPE_I) { + err = vaapi_encode_truncate_gop(avctx); + if (err < 0) + goto fail; + ctx->force_idr = 1; + } + err = vaapi_encode_get_next(avctx, &pic); if (err) { av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err); @@ -854,7 +873,7 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt, } else { if (!ctx->end_of_stream) { - err = vaapi_encode_mangle_end(avctx); + err = vaapi_encode_truncate_gop(avctx); if (err < 0) goto fail; ctx->end_of_stream = 1; diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index e8ed4fdb4e..2a72510b83 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -192,6 +192,7 @@ typedef struct VAAPIEncodeContext { // Frame type decision. int p_per_i; int b_per_p; + int force_idr; int gop_counter; int p_counter; int end_of_stream; |