[FFmpeg-devel] [PATCH v4 4/9] avcodec/vaapi_encode: extract rc parameter configuration to base layer
tong1.wu at intel.com
tong1.wu at intel.com
Thu Feb 8 09:38:19 EET 2024
From: Tong Wu <tong1.wu at intel.com>
VAAPI and D3D12VA can share rate control configuration codes. Hence, it
can be moved to base layer for simplification.
Signed-off-by: Tong Wu <tong1.wu at intel.com>
---
libavcodec/hw_base_encode.c | 151 ++++++++++++++++++++++++
libavcodec/hw_base_encode.h | 34 ++++++
libavcodec/vaapi_encode.c | 210 ++++++---------------------------
libavcodec/vaapi_encode.h | 14 +--
libavcodec/vaapi_encode_av1.c | 2 +-
libavcodec/vaapi_encode_h264.c | 2 +-
libavcodec/vaapi_encode_vp9.c | 2 +-
7 files changed, 227 insertions(+), 188 deletions(-)
diff --git a/libavcodec/hw_base_encode.c b/libavcodec/hw_base_encode.c
index f0e4ef9655..c20c47bf55 100644
--- a/libavcodec/hw_base_encode.c
+++ b/libavcodec/hw_base_encode.c
@@ -631,6 +631,157 @@ end:
return 0;
}
+int ff_hw_base_rc_mode_configure(AVCodecContext *avctx, const HWBaseEncodeRCMode *rc_mode,
+ int default_quality, HWBaseEncodeRCConfigure *rc_conf)
+{
+ HWBaseEncodeContext *ctx = avctx->priv_data;
+
+ if (!rc_mode || !rc_conf)
+ return -1;
+
+ if (rc_mode->bitrate) {
+ if (avctx->bit_rate <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
+ "RC mode.\n", rc_mode->name);
+ return AVERROR(EINVAL);
+ }
+
+ if (rc_mode->mode == RC_MODE_AVBR) {
+ // For maximum confusion AVBR is hacked into the existing API
+ // by overloading some of the fields with completely different
+ // meanings.
+
+ // Target percentage does not apply in AVBR mode.
+ rc_conf->rc_bits_per_second = avctx->bit_rate;
+
+ // Accuracy tolerance range for meeting the specified target
+ // bitrate. It's very unclear how this is actually intended
+ // to work - since we do want to get the specified bitrate,
+ // set the accuracy to 100% for now.
+ rc_conf->rc_target_percentage = 100;
+
+ // Convergence period in frames. The GOP size reflects the
+ // user's intended block size for cutting, so reusing that
+ // as the convergence period seems a reasonable default.
+ rc_conf->rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
+
+ } else if (rc_mode->maxrate) {
+ if (avctx->rc_max_rate > 0) {
+ if (avctx->rc_max_rate < avctx->bit_rate) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
+ "bitrate (%"PRId64") must not be greater than "
+ "maxrate (%"PRId64").\n", avctx->bit_rate,
+ avctx->rc_max_rate);
+ return AVERROR(EINVAL);
+ }
+ rc_conf->rc_bits_per_second = avctx->rc_max_rate;
+ rc_conf->rc_target_percentage = (avctx->bit_rate * 100) /
+ avctx->rc_max_rate;
+ } else {
+ // We only have a target bitrate, but this mode requires
+ // that a maximum rate be supplied as well. Since the
+ // user does not want this to be a constraint, arbitrarily
+ // pick a maximum rate of double the target rate.
+ rc_conf->rc_bits_per_second = 2 * avctx->bit_rate;
+ rc_conf->rc_target_percentage = 50;
+ }
+ } else {
+ if (avctx->rc_max_rate > avctx->bit_rate) {
+ av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
+ "in %s RC mode.\n", rc_mode->name);
+ }
+ rc_conf->rc_bits_per_second = avctx->bit_rate;
+ rc_conf->rc_target_percentage = 100;
+ }
+ } else {
+ rc_conf->rc_bits_per_second = 0;
+ rc_conf->rc_target_percentage = 100;
+ }
+
+ if (rc_mode->quality) {
+ if (ctx->explicit_qp) {
+ rc_conf->rc_quality = ctx->explicit_qp;
+ } else if (avctx->global_quality > 0) {
+ rc_conf->rc_quality = avctx->global_quality;
+ } else {
+ rc_conf->rc_quality = default_quality;
+ av_log(avctx, AV_LOG_WARNING, "No quality level set; "
+ "using default (%d).\n", rc_conf->rc_quality);
+ }
+ } else {
+ rc_conf->rc_quality = 0;
+ }
+
+ if (rc_mode->hrd) {
+ if (avctx->rc_buffer_size)
+ rc_conf->hrd_buffer_size = avctx->rc_buffer_size;
+ else if (avctx->rc_max_rate > 0)
+ rc_conf->hrd_buffer_size = avctx->rc_max_rate;
+ else
+ rc_conf->hrd_buffer_size = avctx->bit_rate;
+ if (avctx->rc_initial_buffer_occupancy) {
+ if (avctx->rc_initial_buffer_occupancy > rc_conf->hrd_buffer_size) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
+ "must have initial buffer size (%d) <= "
+ "buffer size (%"PRId64").\n",
+ avctx->rc_initial_buffer_occupancy, rc_conf->hrd_buffer_size);
+ return AVERROR(EINVAL);
+ }
+ rc_conf->hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
+ } else {
+ rc_conf->hrd_initial_buffer_fullness = rc_conf->hrd_buffer_size * 3 / 4;
+ }
+
+ rc_conf->rc_window_size = (rc_conf->hrd_buffer_size * 1000) / rc_conf->rc_bits_per_second;
+ } else {
+ if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
+ av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
+ "in %s RC mode.\n", rc_mode->name);
+ }
+
+ rc_conf->hrd_buffer_size = 0;
+ rc_conf->hrd_initial_buffer_fullness = 0;
+
+ if (rc_mode->mode != RC_MODE_AVBR) {
+ // Already set (with completely different meaning) for AVBR.
+ rc_conf->rc_window_size = 1000;
+ }
+ }
+
+ if (rc_conf->rc_bits_per_second > UINT32_MAX ||
+ rc_conf->hrd_buffer_size > UINT32_MAX ||
+ rc_conf->hrd_initial_buffer_fullness > UINT32_MAX) {
+ av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
+ "greater are not supported by hardware.\n");
+ return AVERROR(EINVAL);
+ }
+
+ av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
+
+ if (rc_mode->quality)
+ av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_conf->rc_quality);
+
+ if (rc_mode->hrd) {
+ av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
+ "initial fullness %"PRId64" bits.\n",
+ rc_conf->hrd_buffer_size, rc_conf->hrd_initial_buffer_fullness);
+ }
+
+ if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
+ av_reduce(&rc_conf->fr_num, &rc_conf->fr_den,
+ avctx->framerate.num, avctx->framerate.den, 65535);
+ else
+ av_reduce(&rc_conf->fr_num, &rc_conf->fr_den,
+ avctx->time_base.den, avctx->time_base.num, 65535);
+
+ av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
+ rc_conf->fr_num, rc_conf->fr_den, (double)rc_conf->fr_num / rc_conf->fr_den);
+
+ ctx->rc_quality = rc_conf->rc_quality;
+
+ return 0;
+}
+
int ff_hw_base_encode_init(AVCodecContext *avctx)
{
HWBaseEncodeContext *ctx = avctx->priv_data;
diff --git a/libavcodec/hw_base_encode.h b/libavcodec/hw_base_encode.h
index d215d6a32b..57cfa12e73 100644
--- a/libavcodec/hw_base_encode.h
+++ b/libavcodec/hw_base_encode.h
@@ -72,6 +72,37 @@ enum {
RC_MODE_MAX = RC_MODE_AVBR,
};
+typedef struct HWBaseEncodeRCMode {
+ // Mode from above enum (RC_MODE_*).
+ int mode;
+ // Name.
+ const char *name;
+ // Uses bitrate parameters.
+ int bitrate;
+ // Supports maxrate distinct from bitrate.
+ int maxrate;
+ // Uses quality value.
+ int quality;
+ // Supports HRD/VBV parameters.
+ int hrd;
+} HWBaseEncodeRCMode;
+
+typedef struct HWBaseEncodeRCConfigure
+{
+ 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;
+ int fr_den;
+} HWBaseEncodeRCConfigure;
+
+
typedef struct HWBaseEncodePicture {
struct HWBaseEncodePicture *next;
@@ -242,6 +273,9 @@ int ff_hw_base_encode_set_output_property(AVCodecContext *avctx, HWBaseEncodePic
int ff_hw_base_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt);
+int ff_hw_base_rc_mode_configure(AVCodecContext *avctx, const HWBaseEncodeRCMode *rc_mode,
+ int default_quality, HWBaseEncodeRCConfigure *rc_conf);
+
int ff_hw_base_encode_init(AVCodecContext *avctx);
int ff_hw_base_encode_close(AVCodecContext *avctx);
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 2d839a1202..30e5deac08 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1164,23 +1164,23 @@ fail:
}
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 },
+ // Bitrate Quality
+ // | Maxrate | HRD/VBV
+ { { 0 } }, // | | | |
+ { { RC_MODE_CQP, "CQP", 0, 0, 1, 0 }, 1, VA_RC_CQP },
+ { { RC_MODE_CBR, "CBR", 1, 0, 0, 1 }, 1, VA_RC_CBR },
+ { { RC_MODE_VBR, "VBR", 1, 1, 0, 1 }, 1, VA_RC_VBR },
#if VA_CHECK_VERSION(1, 1, 0)
- { RC_MODE_ICQ, "ICQ", 1, VA_RC_ICQ, 0, 0, 1, 0 },
+ { { RC_MODE_ICQ, "ICQ", 0, 0, 1, 0 }, 1, VA_RC_ICQ },
#else
- { RC_MODE_ICQ, "ICQ", 0 },
+ { { RC_MODE_ICQ, "ICQ", 0, 0, 1, 0 }, 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 },
+ { { RC_MODE_QVBR, "QVBR", 1, 1, 1, 1 }, 1, VA_RC_QVBR },
+ { { RC_MODE_AVBR, "AVBR", 1, 0, 0, 0 }, 0, VA_RC_AVBR },
#else
- { RC_MODE_QVBR, "QVBR", 0 },
- { RC_MODE_AVBR, "AVBR", 0 },
+ { { RC_MODE_QVBR, "QVBR", 1, 1, 1, 1 }, 0 },
+ { { RC_MODE_AVBR, "AVBR", 1, 0, 0, 0 }, 0 },
#endif
};
@@ -1190,13 +1190,8 @@ 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;
+ HWBaseEncodeRCConfigure rc_conf = { 0 };
+ int err;
VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
VAStatus vas;
char supported_rc_modes_string[64];
@@ -1224,7 +1219,7 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
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 ? "" : ", ", rc_mode->base.name);
first = 0;
if (res < 0) {
*str = 0;
@@ -1258,12 +1253,12 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
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, \
+ "RC mode (supported modes: %s).\n", rc_mode->base.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.\n", rc_mode->base.name); \
rc_mode = NULL; \
} else { \
goto rc_mode_found; \
@@ -1308,129 +1303,15 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
return AVERROR(EINVAL);
rc_mode_found:
- if (rc_mode->bitrate) {
- if (avctx->bit_rate <= 0) {
- av_log(avctx, AV_LOG_ERROR, "Bitrate must be set for %s "
- "RC mode.\n", rc_mode->name);
- return AVERROR(EINVAL);
- }
-
- if (rc_mode->mode == RC_MODE_AVBR) {
- // For maximum confusion AVBR is hacked into the existing API
- // by overloading some of the fields with completely different
- // meanings.
-
- // Target percentage does not apply in AVBR mode.
- rc_bits_per_second = avctx->bit_rate;
-
- // Accuracy tolerance range for meeting the specified target
- // bitrate. It's very unclear how this is actually intended
- // to work - since we do want to get the specified bitrate,
- // set the accuracy to 100% for now.
- rc_target_percentage = 100;
-
- // Convergence period in frames. The GOP size reflects the
- // user's intended block size for cutting, so reusing that
- // as the convergence period seems a reasonable default.
- rc_window_size = avctx->gop_size > 0 ? avctx->gop_size : 60;
-
- } else if (rc_mode->maxrate) {
- if (avctx->rc_max_rate > 0) {
- if (avctx->rc_max_rate < avctx->bit_rate) {
- av_log(avctx, AV_LOG_ERROR, "Invalid bitrate settings: "
- "bitrate (%"PRId64") must not be greater than "
- "maxrate (%"PRId64").\n", avctx->bit_rate,
- avctx->rc_max_rate);
- return AVERROR(EINVAL);
- }
- rc_bits_per_second = avctx->rc_max_rate;
- rc_target_percentage = (avctx->bit_rate * 100) /
- avctx->rc_max_rate;
- } else {
- // We only have a target bitrate, but this mode requires
- // that a maximum rate be supplied as well. Since the
- // user does not want this to be a constraint, arbitrarily
- // pick a maximum rate of double the target rate.
- rc_bits_per_second = 2 * avctx->bit_rate;
- rc_target_percentage = 50;
- }
- } else {
- if (avctx->rc_max_rate > avctx->bit_rate) {
- av_log(avctx, AV_LOG_WARNING, "Max bitrate is ignored "
- "in %s RC mode.\n", rc_mode->name);
- }
- rc_bits_per_second = avctx->bit_rate;
- rc_target_percentage = 100;
- }
- } else {
- rc_bits_per_second = 0;
- rc_target_percentage = 100;
- }
-
- if (rc_mode->quality) {
- if (base_ctx->explicit_qp) {
- rc_quality = base_ctx->explicit_qp;
- } else if (avctx->global_quality > 0) {
- rc_quality = avctx->global_quality;
- } else {
- rc_quality = ctx->codec->default_quality;
- av_log(avctx, AV_LOG_WARNING, "No quality level set; "
- "using default (%d).\n", rc_quality);
- }
- } else {
- rc_quality = 0;
- }
-
- if (rc_mode->hrd) {
- if (avctx->rc_buffer_size)
- hrd_buffer_size = avctx->rc_buffer_size;
- else if (avctx->rc_max_rate > 0)
- hrd_buffer_size = avctx->rc_max_rate;
- else
- hrd_buffer_size = avctx->bit_rate;
- if (avctx->rc_initial_buffer_occupancy) {
- if (avctx->rc_initial_buffer_occupancy > hrd_buffer_size) {
- av_log(avctx, AV_LOG_ERROR, "Invalid RC buffer settings: "
- "must have initial buffer size (%d) <= "
- "buffer size (%"PRId64").\n",
- avctx->rc_initial_buffer_occupancy, hrd_buffer_size);
- return AVERROR(EINVAL);
- }
- hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
- } else {
- hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
- }
-
- rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
- } else {
- if (avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
- av_log(avctx, AV_LOG_WARNING, "Buffering settings are ignored "
- "in %s RC mode.\n", rc_mode->name);
- }
-
- hrd_buffer_size = 0;
- hrd_initial_buffer_fullness = 0;
-
- if (rc_mode->mode != RC_MODE_AVBR) {
- // Already set (with completely different meaning) for AVBR.
- rc_window_size = 1000;
- }
- }
-
- if (rc_bits_per_second > UINT32_MAX ||
- hrd_buffer_size > UINT32_MAX ||
- hrd_initial_buffer_fullness > UINT32_MAX) {
- av_log(avctx, AV_LOG_ERROR, "RC parameters of 2^32 or "
- "greater are not supported by VAAPI.\n");
- return AVERROR(EINVAL);
- }
+ err = ff_hw_base_rc_mode_configure(avctx, (const HWBaseEncodeRCMode*)rc_mode,
+ ctx->codec->default_quality, &rc_conf);
+ if (err < 0)
+ return err;
ctx->rc_mode = rc_mode;
- base_ctx->rc_quality = rc_quality;
ctx->va_rc_mode = rc_mode->va_mode;
- ctx->va_bit_rate = rc_bits_per_second;
+ ctx->va_bit_rate = rc_conf.rc_bits_per_second;
- av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
// This driver does not want the RC mode attribute to be set.
} else {
@@ -1441,34 +1322,31 @@ rc_mode_found:
};
}
- if (rc_mode->quality)
- av_log(avctx, AV_LOG_VERBOSE, "RC quality: %d.\n", rc_quality);
-
if (rc_mode->va_mode != VA_RC_CQP) {
- if (rc_mode->mode == RC_MODE_AVBR) {
+ if (rc_mode->base.mode == RC_MODE_AVBR) {
av_log(avctx, AV_LOG_VERBOSE, "RC target: %"PRId64" bps "
"converging in %d frames with %d%% accuracy.\n",
- rc_bits_per_second, rc_window_size,
- rc_target_percentage);
- } else if (rc_mode->bitrate) {
+ rc_conf.rc_bits_per_second, rc_conf.rc_window_size,
+ rc_conf.rc_target_percentage);
+ } else if (rc_mode->base.bitrate) {
av_log(avctx, AV_LOG_VERBOSE, "RC target: %d%% of "
- "%"PRId64" bps over %d ms.\n", rc_target_percentage,
- rc_bits_per_second, rc_window_size);
+ "%"PRId64" bps over %d ms.\n", rc_conf.rc_target_percentage,
+ rc_conf.rc_bits_per_second, rc_conf.rc_window_size);
}
ctx->rc_params = (VAEncMiscParameterRateControl) {
- .bits_per_second = rc_bits_per_second,
- .target_percentage = rc_target_percentage,
- .window_size = rc_window_size,
+ .bits_per_second = rc_conf.rc_bits_per_second,
+ .target_percentage = rc_conf.rc_target_percentage,
+ .window_size = rc_conf.rc_window_size,
.initial_qp = 0,
.min_qp = (avctx->qmin > 0 ? avctx->qmin : 0),
.basic_unit_size = 0,
#if VA_CHECK_VERSION(1, 1, 0)
- .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
+ .ICQ_quality_factor = av_clip(rc_conf.rc_quality, 1, 51),
.max_qp = (avctx->qmax > 0 ? avctx->qmax : 0),
#endif
#if VA_CHECK_VERSION(1, 3, 0)
- .quality_factor = rc_quality,
+ .quality_factor = rc_conf.rc_quality,
#endif
};
vaapi_encode_add_global_param(avctx,
@@ -1477,14 +1355,10 @@ rc_mode_found:
sizeof(ctx->rc_params));
}
- if (rc_mode->hrd) {
- av_log(avctx, AV_LOG_VERBOSE, "RC buffer: %"PRId64" bits, "
- "initial fullness %"PRId64" bits.\n",
- hrd_buffer_size, hrd_initial_buffer_fullness);
-
+ if (rc_mode->base.hrd) {
ctx->hrd_params = (VAEncMiscParameterHRD) {
- .initial_buffer_fullness = hrd_initial_buffer_fullness,
- .buffer_size = hrd_buffer_size,
+ .initial_buffer_fullness = rc_conf.hrd_initial_buffer_fullness,
+ .buffer_size = rc_conf.hrd_buffer_size,
};
vaapi_encode_add_global_param(avctx,
VAEncMiscParameterTypeHRD,
@@ -1492,18 +1366,8 @@ rc_mode_found:
sizeof(ctx->hrd_params));
}
- if (avctx->framerate.num > 0 && avctx->framerate.den > 0)
- av_reduce(&fr_num, &fr_den,
- avctx->framerate.num, avctx->framerate.den, 65535);
- else
- av_reduce(&fr_num, &fr_den,
- avctx->time_base.den, avctx->time_base.num, 65535);
-
- av_log(avctx, AV_LOG_VERBOSE, "RC framerate: %d/%d (%.2f fps).\n",
- fr_num, fr_den, (double)fr_num / fr_den);
-
ctx->fr_params = (VAEncMiscParameterFrameRate) {
- .framerate = (unsigned int)fr_den << 16 | fr_num,
+ .framerate = (unsigned int)rc_conf.fr_den << 16 | rc_conf.fr_num,
};
#if VA_CHECK_VERSION(0, 40, 0)
vaapi_encode_add_global_param(avctx,
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index 772fb83f5b..c947aca52b 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -110,22 +110,12 @@ typedef struct VAAPIEncodeProfile {
} VAAPIEncodeProfile;
typedef struct VAAPIEncodeRCMode {
- // Mode from above enum (RC_MODE_*).
- int mode;
- // Name.
- const char *name;
+ // Base.
+ HWBaseEncodeRCMode base;
// Supported in the compile-time VAAPI version.
int supported;
// VA mode value (VA_RC_*).
uint32_t va_mode;
- // Uses bitrate parameters.
- int bitrate;
- // Supports maxrate distinct from bitrate.
- int maxrate;
- // Uses quality value.
- int quality;
- // Supports HRD/VBV parameters.
- int hrd;
} VAAPIEncodeRCMode;
typedef struct VAAPIEncodeContext {
diff --git a/libavcodec/vaapi_encode_av1.c b/libavcodec/vaapi_encode_av1.c
index d3785e133c..10fc79783a 100644
--- a/libavcodec/vaapi_encode_av1.c
+++ b/libavcodec/vaapi_encode_av1.c
@@ -134,7 +134,7 @@ static av_cold int vaapi_encode_av1_configure(AVCodecContext *avctx)
priv->cbc->trace_context = ctx;
priv->cbc->trace_write_callback = vaapi_encode_av1_trace_write_log;
- if (ctx->rc_mode->quality) {
+ if (ctx->rc_mode->base.quality) {
priv->q_idx_p = av_clip(base_ctx->rc_quality, 0, AV1_MAX_QUANT);
if (fabs(avctx->i_quant_factor) > 0.0)
priv->q_idx_idr =
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index fe02f75f85..5a1db27690 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -1124,7 +1124,7 @@ static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
priv->fixed_qp_b = 26;
}
- if (!ctx->rc_mode->hrd) {
+ if (!ctx->rc_mode->base.hrd) {
// Timing SEI requires a mode respecting HRD parameters.
priv->sei &= ~SEI_TIMING;
}
diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c
index 85621d7471..a1c0f45e5a 100644
--- a/libavcodec/vaapi_encode_vp9.c
+++ b/libavcodec/vaapi_encode_vp9.c
@@ -205,7 +205,7 @@ static av_cold int vaapi_encode_vp9_configure(AVCodecContext *avctx)
VAAPIEncodeContext *ctx = avctx->priv_data;
VAAPIEncodeVP9Context *priv = avctx->priv_data;
- if (ctx->rc_mode->quality) {
+ if (ctx->rc_mode->base.quality) {
priv->q_idx_p = av_clip(base_ctx->rc_quality, 0, VP9_MAX_QUANT);
if (avctx->i_quant_factor > 0.0)
priv->q_idx_idr =
--
2.41.0.windows.1
More information about the ffmpeg-devel
mailing list