From 67e87f8050cb8cc61e016cb77be137c18653cbfe Mon Sep 17 00:00:00 2001 From: Sven Dueking Date: Fri, 21 Aug 2015 09:17:35 +0100 Subject: [PATCH] avcodec/qsv : Added look ahead rate control mode Reviewed-by: Ivan Uskov Signed-off-by: Michael Niedermayer --- libavcodec/qsvenc.c | 31 +++++++++++++++++++++++++++++-- libavcodec/qsvenc.h | 8 ++++++++ libavcodec/qsvenc_h264.c | 12 ++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 1532258d49..1aeab03d04 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -107,8 +107,16 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) q->param.mfx.RateControlMethod = MFX_RATECONTROL_CBR; ratecontrol_desc = "constant bitrate (CBR)"; } else if (!avctx->rc_max_rate) { - q->param.mfx.RateControlMethod = MFX_RATECONTROL_AVBR; - ratecontrol_desc = "average variable bitrate (AVBR)"; +#if QSV_VERSION_ATLEAST(1,7) + if (q->look_ahead) { + q->param.mfx.RateControlMethod = MFX_RATECONTROL_LA; + ratecontrol_desc = "lookahead (LA)"; + } else +#endif + { + q->param.mfx.RateControlMethod = MFX_RATECONTROL_AVBR; + ratecontrol_desc = "average variable bitrate (AVBR)"; + } } else { q->param.mfx.RateControlMethod = MFX_RATECONTROL_VBR; ratecontrol_desc = "variable bitrate (VBR)"; @@ -132,6 +140,9 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) break; case MFX_RATECONTROL_AVBR: +#if QSV_VERSION_ATLEAST(1,7) + case MFX_RATECONTROL_LA: +#endif q->param.mfx.TargetKbps = avctx->bit_rate / 1000; q->param.mfx.Convergence = q->avbr_convergence; q->param.mfx.Accuracy = q->avbr_accuracy; @@ -151,6 +162,22 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) q->extparam[0] = (mfxExtBuffer *)&q->extco; +#if QSV_VERSION_ATLEAST(1,6) + q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2; + q->extco2.Header.BufferSz = sizeof(q->extco2); + +#if QSV_VERSION_ATLEAST(1,7) + // valid value range is from 10 to 100 inclusive + // to instruct the encoder to use the default value this should be set to zero + q->extco2.LookAheadDepth = q->look_ahead_depth != 0 ? FFMAX(10, q->look_ahead_depth) : 0; +#endif +#if QSV_VERSION_ATLEAST(1,8) + q->extco2.LookAheadDS = q->look_ahead_downsampling; +#endif + + q->extparam[1] = (mfxExtBuffer *)&q->extco2; + +#endif q->param.ExtParam = q->extparam; q->param.NumExtParam = FF_ARRAY_ELEMS(q->extparam); } diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index 231648821f..2a21f8217d 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -50,7 +50,12 @@ typedef struct QSVEncContext { mfxFrameAllocRequest req; mfxExtCodingOption extco; +#if QSV_VERSION_ATLEAST(1,6) + mfxExtCodingOption2 extco2; + mfxExtBuffer *extparam[2]; +#else mfxExtBuffer *extparam[1]; +#endif AVFifoBuffer *async_fifo; @@ -62,6 +67,9 @@ typedef struct QSVEncContext { int avbr_accuracy; int avbr_convergence; int pic_timing_sei; + int look_ahead; + int look_ahead_depth; + int look_ahead_downsampling; char *load_plugins; } QSVEncContext; diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c index b15f6b2188..b569efe7ad 100644 --- a/libavcodec/qsvenc_h264.c +++ b/libavcodec/qsvenc_h264.c @@ -71,6 +71,18 @@ static const AVOption options[] = { { "avbr_convergence", "Convergence of the AVBR ratecontrol", OFFSET(qsv.avbr_convergence), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, { "pic_timing_sei", "Insert picture timing SEI with pic_struct_syntax element", OFFSET(qsv.pic_timing_sei), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE }, +#if QSV_VERSION_ATLEAST(1,7) + { "look_ahead", "Use VBR algorithm with look ahead", OFFSET(qsv.look_ahead), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE }, + { "look_ahead_depth", "Depth of look ahead in number frames", OFFSET(qsv.look_ahead_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, VE }, +#endif + +#if QSV_VERSION_ATLEAST(1,8) + { "look_ahead_downsampling", NULL, OFFSET(qsv.look_ahead_downsampling), AV_OPT_TYPE_INT, { .i64 = MFX_LOOKAHEAD_DS_UNKNOWN }, MFX_LOOKAHEAD_DS_UNKNOWN, MFX_LOOKAHEAD_DS_2x, VE, "look_ahead_downsampling" }, + { "unknown" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_UNKNOWN }, INT_MIN, INT_MAX, VE, "look_ahead_downsampling" }, + { "off" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_OFF }, INT_MIN, INT_MAX, VE, "look_ahead_downsampling" }, + { "2x" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_2x }, INT_MIN, INT_MAX, VE, "look_ahead_downsampling" }, +#endif + { "profile", NULL, OFFSET(qsv.profile), AV_OPT_TYPE_INT, { .i64 = MFX_PROFILE_UNKNOWN }, 0, INT_MAX, VE, "profile" }, { "unknown" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, VE, "profile" }, { "baseline", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_AVC_BASELINE }, INT_MIN, INT_MAX, VE, "profile" },