[FFmpeg-devel] [PATCH v2 01/11] vaapi_encode: Support more RC modes
Fu, Linjie
linjie.fu at intel.com
Mon Jan 28 04:19:54 EET 2019
> -----Original Message-----
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf
> Of Mark Thompson
> Sent: Monday, January 28, 2019 07:47
> To: ffmpeg-devel at ffmpeg.org
> Subject: [FFmpeg-devel] [PATCH v2 01/11] vaapi_encode: Support more RC
> modes
>
> Allow setting the mode explicitly, and try to make a sensible choice
> given the available parameters if not.
> ---
> doc/encoders.texi | 24 +++
> libavcodec/vaapi_encode.c | 370 +++++++++++++++++++++++++++---------
> --
> libavcodec/vaapi_encode.h | 65 +++++++
> 3 files changed, 351 insertions(+), 108 deletions(-)
>
> diff --git a/doc/encoders.texi b/doc/encoders.texi
> index e86ae69cc5..29625ba07c 100644
> --- a/doc/encoders.texi
> +++ b/doc/encoders.texi
> @@ -2824,6 +2824,30 @@ Set the B-frame reference depth. When set to
> one (the default), all B-frames
> will refer only to P- or I-frames. When set to greater values multiple layers
> of B-frames will be present, frames in each layer only referring to frames in
> higher layers.
> +
> + at item rc_mode
> +Set the rate control mode to use. A given driver may only support a subset
> of
> +modes.
> +
> +Possible modes:
> + at table @option
> + at item auto
> +Choose the mode automatically based on driver support and the other
> options.
> +This is the default.
> + at item CQP
> +Constant-quality.
> + at item CBR
> +Constant-bitrate.
> + at item VBR
> +Variable-bitrate.
> + at item ICQ
> +Intelligent constant-quality.
> + at item QVBR
> +Quality-defined variable-bitrate.
> + at item AVBR
> +Average variable bitrate.
> + at end table
> +
> @end table
>
> Each encoder also has its own specific options:
> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
> index b4e9fadaee..d0e101b118 100644
> --- a/libavcodec/vaapi_encode.c
> +++ b/libavcodec/vaapi_encode.c
> @@ -1283,17 +1283,42 @@ fail:
> return err;
> }
>
> +static const VAAPIEncodeRCMode vaapi_encode_rc_modes[] = {
> + // Bitrate Quality
> + // | Maxrate | HRD/VBV
> + { 0 }, // | | | |
> + { RC_MODE_CQP, "CQP", 1, VA_RC_CQP, 0, 0, 1, 0 },
> + { RC_MODE_CBR, "CBR", 1, VA_RC_CBR, 1, 0, 0, 1 },
> + { RC_MODE_VBR, "VBR", 1, VA_RC_VBR, 1, 1, 0, 1 },
> +#if VA_CHECK_VERSION(1, 1, 0)
> + { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 },
> +#else
> + { RC_MODE_ICQ, "ICQ", 0 },
> +#endif
> +#if VA_CHECK_VERSION(1, 3, 0)
> + { RC_MODE_QVBR, "QVBR", 1, VA_RC_QVBR, 1, 1, 1, 1 },
> + { RC_MODE_AVBR, "AVBR", 0, VA_RC_AVBR, 1, 0, 0, 0 },
> +#else
> + { RC_MODE_QVBR, "QVBR", 0 },
> + { RC_MODE_AVBR, "AVBR", 0 },
> +#endif
> +};
> +
> static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
> {
> VAAPIEncodeContext *ctx = avctx->priv_data;
> + uint32_t supported_va_rc_modes;
> + const VAAPIEncodeRCMode *rc_mode;
> int64_t rc_bits_per_second;
> int rc_target_percentage;
> int rc_window_size;
> + int rc_quality;
> int64_t hrd_buffer_size;
> int64_t hrd_initial_buffer_fullness;
> int fr_num, fr_den;
> VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
> VAStatus vas;
> + char supported_rc_modes_string[64];
>
> vas = vaGetConfigAttributes(ctx->hwctx->display,
> ctx->va_profile, ctx->va_entrypoint,
> @@ -1303,119 +1328,215 @@ static av_cold int
> vaapi_encode_init_rate_control(AVCodecContext *avctx)
> "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
> return AVERROR_EXTERNAL;
> }
> -
> if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
> av_log(avctx, AV_LOG_VERBOSE, "Driver does not report any "
> - "supported rate control modes: assuming constant-quality.\n");
> - ctx->va_rc_mode = VA_RC_CQP;
> - return 0;
> - }
> - if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY ||
> - avctx->flags & AV_CODEC_FLAG_QSCALE ||
> - avctx->bit_rate <= 0) {
> - if (rc_attr.value & VA_RC_CQP) {
> - av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality mode.\n");
> - ctx->va_rc_mode = VA_RC_CQP;
> - if (avctx->bit_rate > 0 || avctx->rc_max_rate > 0) {
> - av_log(avctx, AV_LOG_WARNING, "Bitrate target parameters "
> - "ignored in constant-quality mode.\n");
> + "supported rate control modes: assuming CQP only.\n");
> + supported_va_rc_modes = VA_RC_CQP;
> + strcpy(supported_rc_modes_string, "unknown");
> + } else {
> + char *str = supported_rc_modes_string;
> + size_t len = sizeof(supported_rc_modes_string);
> + int i, first = 1, res;
> +
> + supported_va_rc_modes = rc_attr.value;
> +
> + first = 1;
Redundant “first” here I think.
> + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_encode_rc_modes); i++) {
> + rc_mode = &vaapi_encode_rc_modes[i];
> + if (supported_va_rc_modes & rc_mode->va_mode) {
> + res = snprintf(str, len, "%s%s",
> + first ? "" : ", ", rc_mode->name);
> + first = 0;
> + if (res < 0) {
> + *str = 0;
> + break;
> + }
> + len -= res;
> + str += res;
> + if (len == 0)
> + break;
> }
> - return 0;
> - } else {
> - av_log(avctx, AV_LOG_ERROR, "Driver does not support "
> - "constant-quality mode (%#x).\n", rc_attr.value);
> - return AVERROR(EINVAL);
> }
> - }
>
> - if (!(rc_attr.value & (VA_RC_CBR | VA_RC_VBR))) {
> - av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
> - "bitrate-targetted rate control modes.\n");
> - return AVERROR(EINVAL);
> + av_log(avctx, AV_LOG_DEBUG, "Driver supports RC modes %s.\n",
> + supported_rc_modes_string);
> + }
> +
> + // Rate control mode selection:
> + // * If the user has set a mode explicitly with the rc_mode option,
> + // use it and fail if it is not available.
> + // * If an explicit QP option has been set, use CQP.
> + // * If the codec is CQ-only, use CQP.
> + // * If the QSCALE avcodec option is set, use CQP.
> + // * If bitrate and quality are both set, try QVBR.
> + // * If quality is set, try ICQ, then CQP.
> + // * If bitrate and maxrate are set and have the same value, try CBR.
> + // * If a bitrate is set, try AVBR, then VBR, then CBR.
> + // * If no bitrate is set, try ICQ, then CQP.
> +
> +#define TRY_RC_MODE(mode, fail) do { \
> + rc_mode = &vaapi_encode_rc_modes[mode]; \
> + if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
> + if (fail) { \
> + av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
> + "RC mode (supported modes: %s).\n", rc_mode->name, \
> + supported_rc_modes_string); \
> + return AVERROR(EINVAL); \
> + } \
> + av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
> + "RC mode.\n", rc_mode->name); \
> + rc_mode = NULL; \
> + } else { \
> + goto rc_mode_found; \
> + } \
> + } while (0)
> +
Will it be better to put the definition of TRY_RC_MODE in the front of this file?
Thanks,
- Linjie
More information about the ffmpeg-devel
mailing list