diff options
author | Mark Thompson <sw@jkqxz.net> | 2016-12-12 21:25:28 +0000 |
---|---|---|
committer | Mark Thompson <sw@jkqxz.net> | 2017-02-08 19:14:04 +0000 |
commit | c667c0979cbc2e04d1d00964b82ac49746caa43c (patch) | |
tree | 52cfa23f20ed3d8c95674eac31cfad23dd4eacd8 /libavcodec | |
parent | 760f1a7727583e07efb1d4b0d8e28a1dd2c54a93 (diff) | |
download | ffmpeg-streaming-c667c0979cbc2e04d1d00964b82ac49746caa43c.zip ffmpeg-streaming-c667c0979cbc2e04d1d00964b82ac49746caa43c.tar.gz |
vaapi_encode: Support forcing IDR frames via AVFrame.pict_type
(cherry picked from commit a3c3a5eac20a51d402c332cdf5220fff40a7943f)
Diffstat (limited to 'libavcodec')
-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 d050ead..6aaf14a 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 7db2191..ed209c0 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; |