summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/vaapi_encode.c253
-rw-r--r--libavcodec/vaapi_encode.h96
-rw-r--r--libavcodec/vaapi_encode_h264.c253
-rw-r--r--libavcodec/vaapi_encode_h265.c208
-rw-r--r--libavcodec/vaapi_encode_mjpeg.c45
5 files changed, 418 insertions, 437 deletions
diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index cdda48583f..41d1a6ed17 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -922,7 +922,7 @@ fail:
return err;
}
-static av_cold int vaapi_encode_check_config(AVCodecContext *avctx)
+static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx)
{
VAAPIEncodeContext *ctx = avctx->priv_data;
VAStatus vas;
@@ -930,6 +930,7 @@ static av_cold int vaapi_encode_check_config(AVCodecContext *avctx)
VAProfile *profiles = NULL;
VAEntrypoint *entrypoints = NULL;
VAConfigAttrib attr[] = {
+ { VAConfigAttribRTFormat },
{ VAConfigAttribRateControl },
{ VAConfigAttribEncMaxRefFrames },
};
@@ -1001,13 +1002,33 @@ static av_cold int vaapi_encode_check_config(AVCodecContext *avctx)
continue;
}
switch (attr[i].type) {
+ case VAConfigAttribRTFormat:
+ if (!(ctx->va_rt_format & attr[i].value)) {
+ av_log(avctx, AV_LOG_ERROR, "Surface RT format %#x "
+ "is not supported (mask %#x).\n",
+ ctx->va_rt_format, attr[i].value);
+ err = AVERROR(EINVAL);
+ goto fail;
+ }
+ ctx->config_attributes[ctx->nb_config_attributes++] =
+ (VAConfigAttrib) {
+ .type = VAConfigAttribRTFormat,
+ .value = ctx->va_rt_format,
+ };
+ break;
case VAConfigAttribRateControl:
if (!(ctx->va_rc_mode & attr[i].value)) {
- av_log(avctx, AV_LOG_ERROR, "Rate control mode is not "
- "supported: %x\n", attr[i].value);
+ av_log(avctx, AV_LOG_ERROR, "Rate control mode %#x "
+ "is not supported (mask: %#x).\n",
+ ctx->va_rc_mode, attr[i].value);
err = AVERROR(EINVAL);
goto fail;
}
+ ctx->config_attributes[ctx->nb_config_attributes++] =
+ (VAConfigAttrib) {
+ .type = VAConfigAttribRateControl,
+ .value = ctx->va_rc_mode,
+ };
break;
case VAConfigAttribEncMaxRefFrames:
{
@@ -1016,18 +1037,20 @@ static av_cold int vaapi_encode_check_config(AVCodecContext *avctx)
if (avctx->gop_size > 1 && ref_l0 < 1) {
av_log(avctx, AV_LOG_ERROR, "P frames are not "
- "supported (%x).\n", attr[i].value);
+ "supported (%#x).\n", attr[i].value);
err = AVERROR(EINVAL);
goto fail;
}
if (avctx->max_b_frames > 0 && ref_l1 < 1) {
av_log(avctx, AV_LOG_ERROR, "B frames are not "
- "supported (%x).\n", attr[i].value);
+ "supported (%#x).\n", attr[i].value);
err = AVERROR(EINVAL);
goto fail;
}
}
break;
+ default:
+ av_assert0(0 && "Unexpected config attribute.");
}
}
@@ -1038,6 +1061,48 @@ fail:
return err;
}
+static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
+{
+ VAAPIEncodeContext *ctx = avctx->priv_data;
+ int hrd_buffer_size;
+ int hrd_initial_buffer_fullness;
+
+ if (avctx->rc_buffer_size)
+ hrd_buffer_size = avctx->rc_buffer_size;
+ else
+ hrd_buffer_size = avctx->bit_rate;
+ if (avctx->rc_initial_buffer_occupancy)
+ hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
+ else
+ hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
+
+ ctx->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
+ ctx->rc_params.rc = (VAEncMiscParameterRateControl) {
+ .bits_per_second = avctx->bit_rate,
+ .target_percentage = 66,
+ .window_size = 1000,
+ .initial_qp = (avctx->qmax >= 0 ? avctx->qmax : 40),
+ .min_qp = (avctx->qmin >= 0 ? avctx->qmin : 18),
+ .basic_unit_size = 0,
+ };
+ ctx->global_params[ctx->nb_global_params] =
+ &ctx->rc_params.misc;
+ ctx->global_params_size[ctx->nb_global_params++] =
+ sizeof(ctx->rc_params);
+
+ ctx->hrd_params.misc.type = VAEncMiscParameterTypeHRD;
+ ctx->hrd_params.hrd = (VAEncMiscParameterHRD) {
+ .initial_buffer_fullness = hrd_initial_buffer_fullness,
+ .buffer_size = hrd_buffer_size,
+ };
+ ctx->global_params[ctx->nb_global_params] =
+ &ctx->hrd_params.misc;
+ ctx->global_params_size[ctx->nb_global_params++] =
+ sizeof(ctx->hrd_params);
+
+ return 0;
+}
+
static void vaapi_encode_free_output_buffer(void *opaque,
uint8_t *data)
{
@@ -1067,7 +1132,7 @@ static AVBufferRef *vaapi_encode_alloc_output_buffer(void *opaque,
// bound on that.
vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
VAEncCodedBufferType,
- 3 * ctx->aligned_width * ctx->aligned_height +
+ 3 * ctx->surface_width * ctx->surface_height +
(1 << 16), 1, 0, &buffer_id);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
@@ -1089,69 +1154,14 @@ static AVBufferRef *vaapi_encode_alloc_output_buffer(void *opaque,
return ref;
}
-av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
- const VAAPIEncodeType *type)
+static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
{
VAAPIEncodeContext *ctx = avctx->priv_data;
- AVVAAPIFramesContext *recon_hwctx = NULL;
AVVAAPIHWConfig *hwconfig = NULL;
AVHWFramesConstraints *constraints = NULL;
enum AVPixelFormat recon_format;
- VAStatus vas;
int err, i;
- if (!avctx->hw_frames_ctx) {
- av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
- "required to associate the encoding device.\n");
- return AVERROR(EINVAL);
- }
-
- ctx->codec = type;
- ctx->codec_options = ctx->codec_options_data;
-
- ctx->va_config = VA_INVALID_ID;
- ctx->va_context = VA_INVALID_ID;
-
- ctx->priv_data = av_mallocz(type->priv_data_size);
- if (!ctx->priv_data) {
- err = AVERROR(ENOMEM);
- goto fail;
- }
-
- ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
- if (!ctx->input_frames_ref) {
- err = AVERROR(ENOMEM);
- goto fail;
- }
- ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
-
- ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
- if (!ctx->device_ref) {
- err = AVERROR(ENOMEM);
- goto fail;
- }
- ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
- ctx->hwctx = ctx->device->hwctx;
-
- err = ctx->codec->init(avctx);
- if (err < 0)
- goto fail;
-
- err = vaapi_encode_check_config(avctx);
- if (err < 0)
- goto fail;
-
- vas = vaCreateConfig(ctx->hwctx->display,
- ctx->va_profile, ctx->va_entrypoint,
- ctx->config_attributes, ctx->nb_config_attributes,
- &ctx->va_config);
- if (vas != VA_STATUS_SUCCESS) {
- av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
- "configuration: %d (%s).\n", vas, vaErrorStr(vas));
- err = AVERROR(EIO);
- goto fail;
- }
-
hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
if (!hwconfig) {
err = AVERROR(ENOMEM);
@@ -1190,13 +1200,13 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
"reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
- if (ctx->aligned_width < constraints->min_width ||
- ctx->aligned_height < constraints->min_height ||
- ctx->aligned_width > constraints->max_width ||
- ctx->aligned_height > constraints->max_height) {
+ if (ctx->surface_width < constraints->min_width ||
+ ctx->surface_height < constraints->min_height ||
+ ctx->surface_width > constraints->max_width ||
+ ctx->surface_height > constraints->max_height) {
av_log(avctx, AV_LOG_ERROR, "Hardware does not support encoding at "
"size %dx%d (constraints: width %d-%d height %d-%d).\n",
- ctx->aligned_width, ctx->aligned_height,
+ ctx->surface_width, ctx->surface_height,
constraints->min_width, constraints->max_width,
constraints->min_height, constraints->max_height);
err = AVERROR(EINVAL);
@@ -1215,9 +1225,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
ctx->recon_frames->sw_format = recon_format;
- ctx->recon_frames->width = ctx->aligned_width;
- ctx->recon_frames->height = ctx->aligned_height;
- ctx->recon_frames->initial_pool_size = ctx->nb_recon_frames;
+ ctx->recon_frames->width = ctx->surface_width;
+ ctx->recon_frames->height = ctx->surface_height;
+ ctx->recon_frames->initial_pool_size =
+ avctx->max_b_frames + 3;
err = av_hwframe_ctx_init(ctx->recon_frames_ref);
if (err < 0) {
@@ -1225,10 +1236,75 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
"frame context: %d.\n", err);
goto fail;
}
- recon_hwctx = ctx->recon_frames->hwctx;
+ err = 0;
+ fail:
+ av_freep(&hwconfig);
+ av_hwframe_constraints_free(&constraints);
+ return err;
+}
+
+av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
+{
+ VAAPIEncodeContext *ctx = avctx->priv_data;
+ AVVAAPIFramesContext *recon_hwctx = NULL;
+ VAStatus vas;
+ int err;
+
+ if (!avctx->hw_frames_ctx) {
+ av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
+ "required to associate the encoding device.\n");
+ return AVERROR(EINVAL);
+ }
+
+ ctx->codec_options = ctx->codec_options_data;
+
+ ctx->va_config = VA_INVALID_ID;
+ ctx->va_context = VA_INVALID_ID;
+
+ ctx->priv_data = av_mallocz(ctx->codec->priv_data_size);
+ if (!ctx->priv_data) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
+ if (!ctx->input_frames_ref) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+ ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
+
+ ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
+ if (!ctx->device_ref) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+ ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
+ ctx->hwctx = ctx->device->hwctx;
+
+ err = vaapi_encode_config_attributes(avctx);
+ if (err < 0)
+ goto fail;
+
+ vas = vaCreateConfig(ctx->hwctx->display,
+ ctx->va_profile, ctx->va_entrypoint,
+ ctx->config_attributes, ctx->nb_config_attributes,
+ &ctx->va_config);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create encode pipeline "
+ "configuration: %d (%s).\n", vas, vaErrorStr(vas));
+ err = AVERROR(EIO);
+ goto fail;
+ }
+
+ err = vaapi_encode_create_recon_frames(avctx);
+ if (err < 0)
+ goto fail;
+
+ recon_hwctx = ctx->recon_frames->hwctx;
vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
- ctx->aligned_width, ctx->aligned_height,
+ ctx->surface_width, ctx->surface_height,
VA_PROGRESSIVE,
recon_hwctx->surface_ids,
recon_hwctx->nb_surfaces,
@@ -1240,6 +1316,26 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
goto fail;
}
+ ctx->output_buffer_pool =
+ av_buffer_pool_init2(sizeof(VABufferID), avctx,
+ &vaapi_encode_alloc_output_buffer, NULL);
+ if (!ctx->output_buffer_pool) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if (ctx->va_rc_mode & ~VA_RC_CQP) {
+ err = vaapi_encode_init_rate_control(avctx);
+ if (err < 0)
+ goto fail;
+ }
+
+ if (ctx->codec->configure) {
+ err = ctx->codec->configure(avctx);
+ if (err < 0)
+ goto fail;
+ }
+
ctx->input_order = 0;
ctx->output_delay = avctx->max_b_frames;
ctx->decode_delay = 1;
@@ -1271,14 +1367,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
}
}
- ctx->output_buffer_pool =
- av_buffer_pool_init2(sizeof(VABufferID), avctx,
- &vaapi_encode_alloc_output_buffer, NULL);
- if (!ctx->output_buffer_pool) {
- err = AVERROR(ENOMEM);
- goto fail;
- }
-
// All I are IDR for now.
ctx->i_per_idr = 0;
ctx->p_per_i = ((avctx->gop_size + avctx->max_b_frames) /
@@ -1292,8 +1380,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx,
return 0;
fail:
- av_freep(&hwconfig);
- av_hwframe_constraints_free(&constraints);
ff_vaapi_encode_close(avctx);
return err;
}
@@ -1318,9 +1404,6 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
ctx->va_config = VA_INVALID_ID;
}
- if (ctx->codec->close)
- ctx->codec->close(avctx);
-
av_buffer_pool_uninit(&ctx->output_buffer_pool);
av_freep(&ctx->codec_sequence_params);
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index eede73ca97..71f608751b 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -48,15 +48,6 @@ enum {
PICTURE_TYPE_B = 3,
};
-enum {
- // All encode operations are done independently.
- ISSUE_MODE_SERIALISE_EVERYTHING = 0,
- // Overlap as many operations as possible.
- ISSUE_MODE_MAXIMISE_THROUGHPUT,
- // Overlap operations only when satisfying parallel dependencies.
- ISSUE_MODE_MINIMISE_LATENCY,
-};
-
typedef struct VAAPIEncodeSlice {
void *priv_data;
void *codec_slice_params;
@@ -102,43 +93,65 @@ typedef struct VAAPIEncodeContext {
// Codec-specific hooks.
const struct VAAPIEncodeType *codec;
+ // Encoding profile (VAProfileXXX).
+ VAProfile va_profile;
+ // Encoding entrypoint (usually VAEntryointEncSlice).
+ VAEntrypoint va_entrypoint;
+ // Surface colour/sampling format (usually VA_RT_FORMAT_YUV420).
+ unsigned int va_rt_format;
+ // Rate control mode.
+ unsigned int va_rc_mode;
+
+ // The required size of surfaces. This is probably the input
+ // size (AVCodecContext.width|height) aligned up to whatever
+ // block size is required by the codec.
+ int surface_width;
+ int surface_height;
+
+ // Everything above this point must be set before calling
+ // ff_vaapi_encode_init().
+
// Codec-specific state.
void *priv_data;
- VAProfile va_profile;
- VAEntrypoint va_entrypoint;
+ // Configuration attributes to use when creating va_config.
+ VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES];
+ int nb_config_attributes;
+
VAConfigID va_config;
VAContextID va_context;
- int va_rc_mode;
-
AVBufferRef *device_ref;
AVHWDeviceContext *device;
AVVAAPIDeviceContext *hwctx;
+ // The hardware frame context containing the input frames.
AVBufferRef *input_frames_ref;
AVHWFramesContext *input_frames;
- // Input size, set from input frames.
- int input_width;
- int input_height;
- // Aligned size, set by codec init, becomes hwframe size.
- int aligned_width;
- int aligned_height;
-
- int nb_recon_frames;
+ // The hardware frame context containing the reconstructed frames.
AVBufferRef *recon_frames_ref;
AVHWFramesContext *recon_frames;
+ // Pool of (reusable) bitstream output buffers.
AVBufferPool *output_buffer_pool;
- VAConfigAttrib config_attributes[MAX_CONFIG_ATTRIBUTES];
- int nb_config_attributes;
-
+ // Global parameters which will be applied at the start of the
+ // sequence (includes rate control parameters below).
VAEncMiscParameterBuffer *global_params[MAX_GLOBAL_PARAMS];
size_t global_params_size[MAX_GLOBAL_PARAMS];
int nb_global_params;
+ // Rate control parameters.
+ struct {
+ VAEncMiscParameterBuffer misc;
+ VAEncMiscParameterRateControl rc;
+ } rc_params;
+ struct {
+ VAEncMiscParameterBuffer misc;
+ VAEncMiscParameterHRD hrd;
+ } hrd_params;
+
// Per-sequence parameter structure (VAEncSequenceParameterBuffer*).
void *codec_sequence_params;
@@ -158,7 +171,15 @@ typedef struct VAAPIEncodeContext {
// Next output order index (encode order).
int64_t output_order;
- int issue_mode;
+ enum {
+ // All encode operations are done independently (synchronise
+ // immediately after every operation).
+ ISSUE_MODE_SERIALISE_EVERYTHING = 0,
+ // Overlap as many operations as possible.
+ ISSUE_MODE_MAXIMISE_THROUGHPUT,
+ // Overlap operations only when satisfying parallel dependencies.
+ ISSUE_MODE_MINIMISE_LATENCY,
+ } issue_mode;
// Timestamp handling.
int64_t first_pts;
@@ -183,15 +204,20 @@ typedef struct VAAPIEncodeContext {
typedef struct VAAPIEncodeType {
- size_t priv_data_size;
+ size_t priv_data_size;
- int (*init)(AVCodecContext *avctx);
- int (*close)(AVCodecContext *avctx);
+ // Perform any extra codec-specific configuration after the
+ // codec context is initialised (set up the private data and
+ // add any necessary global parameters).
+ int (*configure)(AVCodecContext *avctx);
+ // The size of the parameter structures:
+ // sizeof(VAEnc{type}ParameterBuffer{codec}).
size_t sequence_params_size;
size_t picture_params_size;
size_t slice_params_size;
+ // Fill the parameter structures.
int (*init_sequence_params)(AVCodecContext *avctx);
int (*init_picture_params)(AVCodecContext *avctx,
VAAPIEncodePicture *pic);
@@ -199,10 +225,13 @@ typedef struct VAAPIEncodeType {
VAAPIEncodePicture *pic,
VAAPIEncodeSlice *slice);
+ // The type used by the packed header: this should look like
+ // VAEncPackedHeader{something}.
int sequence_header_type;
int picture_header_type;
int slice_header_type;
+ // Write the packed header data to the provided buffer.
int (*write_sequence_header)(AVCodecContext *avctx,
char *data, size_t *data_len);
int (*write_picture_header)(AVCodecContext *avctx,
@@ -213,10 +242,18 @@ typedef struct VAAPIEncodeType {
VAAPIEncodeSlice *slice,
char *data, size_t *data_len);
+ // Fill an extra parameter structure, which will then be
+ // passed to vaRenderPicture(). Will be called repeatedly
+ // with increasing index argument until AVERROR_EOF is
+ // returned.
int (*write_extra_buffer)(AVCodecContext *avctx,
VAAPIEncodePicture *pic,
int index, int *type,
char *data, size_t *data_len);
+
+ // Write an extra packed header. Will be called repeatedly
+ // with increasing index argument until AVERROR_EOF is
+ // returned.
int (*write_extra_header)(AVCodecContext *avctx,
VAAPIEncodePicture *pic,
int index, int *type,
@@ -227,8 +264,7 @@ typedef struct VAAPIEncodeType {
int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *input_image, int *got_packet);
-int ff_vaapi_encode_init(AVCodecContext *avctx,
- const VAAPIEncodeType *type);
+int ff_vaapi_encode_init(AVCodecContext *avctx);
int ff_vaapi_encode_close(AVCodecContext *avctx);
#endif /* AVCODEC_VAAPI_ENCODE_H */
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index 9d6ff27a96..d9b186816a 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -148,14 +148,6 @@ typedef struct VAAPIEncodeH264Context {
// Rate control configuration.
int send_timing_sei;
- struct {
- VAEncMiscParameterBuffer misc;
- VAEncMiscParameterRateControl rc;
- } rc_params;
- struct {
- VAEncMiscParameterBuffer misc;
- VAEncMiscParameterHRD hrd;
- } hrd_params;
#if VA_CHECK_VERSION(0, 36, 0)
// Speed-quality tradeoff setting.
@@ -797,16 +789,16 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
vseq->seq_fields.bits.log2_max_frame_num_minus4 = 4;
vseq->seq_fields.bits.pic_order_cnt_type = 0;
- if (ctx->input_width != ctx->aligned_width ||
- ctx->input_height != ctx->aligned_height) {
+ if (avctx->width != ctx->surface_width ||
+ avctx->height != ctx->surface_height) {
vseq->frame_cropping_flag = 1;
vseq->frame_crop_left_offset = 0;
vseq->frame_crop_right_offset =
- (ctx->aligned_width - ctx->input_width) / 2;
+ (ctx->surface_width - avctx->width) / 2;
vseq->frame_crop_top_offset = 0;
vseq->frame_crop_bottom_offset =
- (ctx->aligned_height - ctx->input_height) / 2;
+ (ctx->surface_height - avctx->height) / 2;
} else {
vseq->frame_cropping_flag = 0;
}
@@ -866,9 +858,9 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
(avctx->bit_rate >> mseq->bit_rate_scale + 6) - 1;
mseq->cpb_size_scale =
- av_clip_uintp2(av_log2(priv->hrd_params.hrd.buffer_size) - 15 - 4, 4);
+ av_clip_uintp2(av_log2(ctx->hrd_params.hrd.buffer_size) - 15 - 4, 4);
mseq->cpb_size_value_minus1[0] =
- (priv->hrd_params.hrd.buffer_size >> mseq->cpb_size_scale + 4) - 1;
+ (ctx->hrd_params.hrd.buffer_size >> mseq->cpb_size_scale + 4) - 1;
// CBR mode isn't actually available here, despite naming.
mseq->cbr_flag[0] = 0;
@@ -880,8 +872,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
// This calculation can easily overflow 32 bits.
mseq->initial_cpb_removal_delay = 90000 *
- (uint64_t)priv->hrd_params.hrd.initial_buffer_fullness /
- priv->hrd_params.hrd.buffer_size;
+ (uint64_t)ctx->hrd_params.hrd.initial_buffer_fullness /
+ ctx->hrd_params.hrd.buffer_size;
mseq->initial_cpb_removal_delay_offset = 0;
} else {
@@ -1083,94 +1075,94 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
return 0;
}
-static av_cold int vaapi_encode_h264_init_constant_bitrate(AVCodecContext *avctx)
+static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
{
VAAPIEncodeContext *ctx = avctx->priv_data;
VAAPIEncodeH264Context *priv = ctx->priv_data;
- int hrd_buffer_size;
- int hrd_initial_buffer_fullness;
+ VAAPIEncodeH264Options *opt = ctx->codec_options;
- if (avctx->rc_buffer_size)
- hrd_buffer_size = avctx->rc_buffer_size;
- else
- hrd_buffer_size = avctx->bit_rate;
- if (avctx->rc_initial_buffer_occupancy)
- hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
- else
- hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
-
- priv->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
- priv->rc_params.rc = (VAEncMiscParameterRateControl) {
- .bits_per_second = avctx->bit_rate,
- .target_percentage = 66,
- .window_size = 1000,
- .initial_qp = (avctx->qmax >= 0 ? avctx->qmax : 40),
- .min_qp = (avctx->qmin >= 0 ? avctx->qmin : 18),
- .basic_unit_size = 0,
- };
- ctx->global_params[ctx->nb_global_params] =
- &priv->rc_params.misc;
- ctx->global_params_size[ctx->nb_global_params++] =
- sizeof(priv->rc_params);
-
- priv->hrd_params.misc.type = VAEncMiscParameterTypeHRD;
- priv->hrd_params.hrd = (VAEncMiscParameterHRD) {
- .initial_buffer_fullness = hrd_initial_buffer_fullness,
- .buffer_size = hrd_buffer_size,
- };
- ctx->global_params[ctx->nb_global_params] =
- &priv->hrd_params.misc;
- ctx->global_params_size[ctx->nb_global_params++] =
- sizeof(priv->hrd_params);
-
- // These still need to be set for pic_init_qp/slice_qp_delta.
- priv->fixed_qp_idr = 26;
- priv->fixed_qp_p = 26;
- priv->fixed_qp_b = 26;
-
- av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n",
- avctx->bit_rate);
- return 0;
-}
+ priv->mb_width = FFALIGN(avctx->width, 16) / 16;
+ priv->mb_height = FFALIGN(avctx->height, 16) / 16;
+
+ if (ctx->va_rc_mode == VA_RC_CQP) {
+ priv->fixed_qp_p = opt->qp;
+ if (avctx->i_quant_factor > 0.0)
+ priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor +
+ avctx->i_quant_offset) + 0.5);
+ else
+ priv->fixed_qp_idr = priv->fixed_qp_p;
+ if (avctx->b_quant_factor > 0.0)
+ priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor +
+ avctx->b_quant_offset) + 0.5);
+ else
+ priv->fixed_qp_b = priv->fixed_qp_p;
+
+ av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = "
+ "%d / %d / %d for IDR- / P- / B-frames.\n",
+ priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b);
+
+ } else if (ctx->va_rc_mode == VA_RC_CBR) {
+ // These still need to be set for pic_init_qp/slice_qp_delta.
+ priv->fixed_qp_idr = 26;
+ priv->fixed_qp_p = 26;
+ priv->fixed_qp_b = 26;
+
+ av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n",
+ avctx->bit_rate);
-static av_cold int vaapi_encode_h264_init_fixed_qp(AVCodecContext *avctx)
-{
- VAAPIEncodeContext *ctx = avctx->priv_data;
- VAAPIEncodeH264Context *priv = ctx->priv_data;
- VAAPIEncodeH264Options *opt = ctx->codec_options;
+ } else {
+ av_assert0(0 && "Invalid RC mode.");
+ }
- priv->fixed_qp_p = opt->qp;
- if (avctx->i_quant_factor > 0.0)
- priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor +
- avctx->i_quant_offset) + 0.5);
- else
- priv->fixed_qp_idr = priv->fixed_qp_p;
- if (avctx->b_quant_factor > 0.0)
- priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor +
- avctx->b_quant_offset) + 0.5);
- else
- priv->fixed_qp_b = priv->fixed_qp_p;
+ if (opt->quality > 0) {
+#if VA_CHECK_VERSION(0, 36, 0)
+ priv->quality_params.misc.type =
+ VAEncMiscParameterTypeQualityLevel;
+ priv->quality_params.quality.quality_level = opt->quality;
+
+ ctx->global_params[ctx->nb_global_params] =
+ &priv->quality_params.misc;
+ ctx->global_params_size[ctx->nb_global_params++] =
+ sizeof(priv->quality_params);
+#else
+ av_log(avctx, AV_LOG_WARNING, "The encode quality option is not "
+ "supported with this VAAPI version.\n");
+#endif
+ }
- av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = "
- "%d / %d / %d for IDR- / P- / B-frames.\n",
- priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b);
return 0;
}
-static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx)
+static const VAAPIEncodeType vaapi_encode_type_h264 = {
+ .priv_data_size = sizeof(VAAPIEncodeH264Context),
+
+ .configure = &vaapi_encode_h264_configure,
+
+ .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264),
+ .init_sequence_params = &vaapi_encode_h264_init_sequence_params,
+
+ .picture_params_size = sizeof(VAEncPictureParameterBufferH264),
+ .init_picture_params = &vaapi_encode_h264_init_picture_params,
+
+ .slice_params_size = sizeof(VAEncSliceParameterBufferH264),
+ .init_slice_params = &vaapi_encode_h264_init_slice_params,
+
+ .sequence_header_type = VAEncPackedHeaderSequence,
+ .write_sequence_header = &vaapi_encode_h264_write_sequence_header,
+
+ .slice_header_type = VAEncPackedHeaderH264_Slice,
+ .write_slice_header = &vaapi_encode_h264_write_slice_header,
+
+ .write_extra_header = &vaapi_encode_h264_write_extra_header,
+};
+
+static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
{
- static const VAConfigAttrib default_config_attributes[] = {
- { .type = VAConfigAttribRTFormat,
- .value = VA_RT_FORMAT_YUV420 },
- { .type = VAConfigAttribEncPackedHeaders,
- .value = (VA_ENC_PACKED_HEADER_SEQUENCE |
- VA_ENC_PACKED_HEADER_SLICE) },
- };
+ VAAPIEncodeContext *ctx = avctx->priv_data;
+ VAAPIEncodeH264Options *opt =
+ (VAAPIEncodeH264Options*)ctx->codec_options_data;
- VAAPIEncodeContext *ctx = avctx->priv_data;
- VAAPIEncodeH264Context *priv = ctx->priv_data;
- VAAPIEncodeH264Options *opt = ctx->codec_options;
- int i, err;
+ ctx->codec = &vaapi_encode_type_h264;
switch (avctx->profile) {
case FF_PROFILE_H264_CONSTRAINED_BASELINE:
@@ -1210,7 +1202,7 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx)
return AVERROR(EINVAL);
}
if (opt->low_power) {
-#if VA_CHECK_VERSION(0, 39, 1)
+#if VA_CHECK_VERSION(0, 39, 2)
ctx->va_entrypoint = VAEntrypointEncSliceLP;
#else
av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not "
@@ -1221,80 +1213,19 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx)
ctx->va_entrypoint = VAEntrypointEncSlice;
}
- ctx->input_width = avctx->width;
- ctx->input_height = avctx->height;
- ctx->aligned_width = FFALIGN(ctx->input_width, 16);
- ctx->aligned_height = FFALIGN(ctx->input_height, 16);
- priv->mb_width = ctx->aligned_width / 16;
- priv->mb_height = ctx->aligned_height / 16;
-
- for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) {
- ctx->config_attributes[ctx->nb_config_attributes++] =
- default_config_attributes[i];
- }
+ // Only 8-bit encode is supported.
+ ctx->va_rt_format = VA_RT_FORMAT_YUV420;
- if (avctx->bit_rate > 0) {
+ if (avctx->bit_rate > 0)
ctx->va_rc_mode = VA_RC_CBR;
- err = vaapi_encode_h264_init_constant_bitrate(avctx);
- } else {
+ else
ctx->va_rc_mode = VA_RC_CQP;
- err = vaapi_encode_h264_init_fixed_qp(avctx);
- }
- if (err < 0)
- return err;
-
- ctx->config_attributes[ctx->nb_config_attributes++] = (VAConfigAttrib) {
- .type = VAConfigAttribRateControl,
- .value = ctx->va_rc_mode,
- };
- if (opt->quality > 0) {
-#if VA_CHECK_VERSION(0, 36, 0)
- priv->quality_params.misc.type =
- VAEncMiscParameterTypeQualityLevel;
- priv->quality_params.quality.quality_level = opt->quality;
- ctx->global_params[ctx->nb_global_params] =
- &priv->quality_params.misc;
- ctx->global_params_size[ctx->nb_global_params++] =
- sizeof(priv->quality_params);
-#else
- av_log(avctx, AV_LOG_WARNING, "The encode quality option is not "
- "supported with this VAAPI version.\n");
-#endif
- }
+ ctx->surface_width = FFALIGN(avctx->width, 16);
+ ctx->surface_height = FFALIGN(avctx->height, 16);
- ctx->nb_recon_frames = 20;
-
- return 0;
-}
-
-static VAAPIEncodeType vaapi_encode_type_h264 = {
- .priv_data_size = sizeof(VAAPIEncodeH264Context),
-
- .init = &vaapi_encode_h264_init_internal,
-
- .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264),
- .init_sequence_params = &vaapi_encode_h264_init_sequence_params,
-
- .picture_params_size = sizeof(VAEncPictureParameterBufferH264),
- .init_picture_params = &vaapi_encode_h264_init_picture_params,
-
- .slice_params_size = sizeof(VAEncSliceParameterBufferH264),
- .init_slice_params = &vaapi_encode_h264_init_slice_params,
-
- .sequence_header_type = VAEncPackedHeaderSequence,
- .write_sequence_header = &vaapi_encode_h264_write_sequence_header,
-
- .slice_header_type = VAEncPackedHeaderH264_Slice,
- .write_slice_header = &vaapi_encode_h264_write_slice_header,
-
- .write_extra_header = &vaapi_encode_h264_write_extra_header,
-};
-
-static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
-{
- return ff_vaapi_encode_init(avctx, &vaapi_encode_type_h264);
+ return ff_vaapi_encode_init(avctx);
}
#define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 010db9293b..f5e29443ef 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -798,8 +798,8 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
vseq->intra_idr_period = 0;
vseq->ip_period = 0;
- vseq->pic_width_in_luma_samples = ctx->aligned_width;
- vseq->pic_height_in_luma_samples = ctx->aligned_height;
+ vseq->pic_width_in_luma_samples = ctx->surface_width;
+ vseq->pic_height_in_luma_samples = ctx->surface_height;
vseq->seq_fields.bits.chroma_format_idc = 1; // 4:2:0.
vseq->seq_fields.bits.separate_colour_plane_flag = 0;
@@ -911,15 +911,15 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
mseq->vps_poc_proportional_to_timing_flag = 1;
mseq->vps_num_ticks_poc_diff_minus1 = 0;
- if (ctx->input_width != ctx->aligned_width ||
- ctx->input_height != ctx->aligned_height) {
+ if (avctx->width != ctx->surface_width ||
+ avctx->height != ctx->surface_height) {
mseq->conformance_window_flag = 1;
mseq->conf_win_left_offset = 0;
mseq->conf_win_right_offset =
- (ctx->aligned_width - ctx->input_width) / 2;
+ (ctx->surface_width - avctx->width) / 2;
mseq->conf_win_top_offset = 0;
mseq->conf_win_bottom_offset =
- (ctx->aligned_height - ctx->input_height) / 2;
+ (ctx->surface_height - avctx->height) / 2;
} else {
mseq->conformance_window_flag = 0;
}
@@ -1154,93 +1154,78 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
return 0;
}
-static av_cold int vaapi_encode_h265_init_constant_bitrate(AVCodecContext *avctx)
+static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx)
{
VAAPIEncodeContext *ctx = avctx->priv_data;
VAAPIEncodeH265Context *priv = ctx->priv_data;
- int hrd_buffer_size;
- int hrd_initial_buffer_fullness;
+ VAAPIEncodeH265Options *opt = ctx->codec_options;
+
+ priv->ctu_width = FFALIGN(ctx->surface_width, 32) / 32;
+ priv->ctu_height = FFALIGN(ctx->surface_height, 32) / 32;
+
+ av_log(avctx, AV_LOG_VERBOSE, "Input %ux%u -> Surface %ux%u -> CTU %ux%u.\n",
+ avctx->width, avctx->height, ctx->surface_width,
+ ctx->surface_height, priv->ctu_width, priv->ctu_height);
+
+ if (ctx->va_rc_mode == VA_RC_CQP) {
+ priv->fixed_qp_p = opt->qp;
+ if (avctx->i_quant_factor > 0.0)
+ priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor +
+ avctx->i_quant_offset) + 0.5);
+ else
+ priv->fixed_qp_idr = priv->fixed_qp_p;
+ if (avctx->b_quant_factor > 0.0)
+ priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor +
+ avctx->b_quant_offset) + 0.5);
+ else
+ priv->fixed_qp_b = priv->fixed_qp_p;
+
+ av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = "
+ "%d / %d / %d for IDR- / P- / B-frames.\n",
+ priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b);
+
+ } else if (ctx->va_rc_mode == VA_RC_CBR) {
+ // These still need to be set for pic_init_qp/slice_qp_delta.
+ priv->fixed_qp_idr = 30;
+ priv->fixed_qp_p = 30;
+ priv->fixed_qp_b = 30;
+
+ av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n",
+ avctx->bit_rate);
+
+ } else {
+ av_assert0(0 && "Invalid RC mode.");
+ }
- if (avctx->rc_buffer_size)
- hrd_buffer_size = avctx->rc_buffer_size;
- else
- hrd_buffer_size = avctx->bit_rate;
- if (avctx->rc_initial_buffer_occupancy)
- hrd_initial_buffer_fullness = avctx->rc_initial_buffer_occupancy;
- else
- hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
-
- priv->rc_params.misc.type = VAEncMiscParameterTypeRateControl;
- priv->rc_params.rc = (VAEncMiscParameterRateControl) {
- .bits_per_second = avctx->bit_rate,
- .target_percentage = 66,
- .window_size = 1000,
- .initial_qp = (avctx->qmax >= 0 ? avctx->qmax : 40),
- .min_qp = (avctx->qmin >= 0 ? avctx->qmin : 20),
- .basic_unit_size = 0,
- };
- ctx->global_params[ctx->nb_global_params] =
- &priv->rc_params.misc;
- ctx->global_params_size[ctx->nb_global_params++] =
- sizeof(priv->rc_params);
-
- priv->hrd_params.misc.type = VAEncMiscParameterTypeHRD;
- priv->hrd_params.hrd = (VAEncMiscParameterHRD) {
- .initial_buffer_fullness = hrd_initial_buffer_fullness,
- .buffer_size = hrd_buffer_size,
- };
- ctx->global_params[ctx->nb_global_params] =
- &priv->hrd_params.misc;
- ctx->global_params_size[ctx->nb_global_params++] =
- sizeof(priv->hrd_params);
-
- // These still need to be set for pic_init_qp/slice_qp_delta.
- priv->fixed_qp_idr = 30;
- priv->fixed_qp_p = 30;
- priv->fixed_qp_b = 30;
-
- av_log(avctx, AV_LOG_DEBUG, "Using constant-bitrate = %d bps.\n",
- avctx->bit_rate);
return 0;
}
-static av_cold int vaapi_encode_h265_init_fixed_qp(AVCodecContext *avctx)
-{
- VAAPIEncodeContext *ctx = avctx->priv_data;
- VAAPIEncodeH265Context *priv = ctx->priv_data;
- VAAPIEncodeH265Options *opt = ctx->codec_options;
+static const VAAPIEncodeType vaapi_encode_type_h265 = {
+ .priv_data_size = sizeof(VAAPIEncodeH265Context),
- priv->fixed_qp_p = opt->qp;
- if (avctx->i_quant_factor > 0.0)
- priv->fixed_qp_idr = (int)((priv->fixed_qp_p * avctx->i_quant_factor +
- avctx->i_quant_offset) + 0.5);
- else
- priv->fixed_qp_idr = priv->fixed_qp_p;
- if (avctx->b_quant_factor > 0.0)
- priv->fixed_qp_b = (int)((priv->fixed_qp_p * avctx->b_quant_factor +
- avctx->b_quant_offset) + 0.5);
- else
- priv->fixed_qp_b = priv->fixed_qp_p;
+ .configure = &vaapi_encode_h265_configure,
- av_log(avctx, AV_LOG_DEBUG, "Using fixed QP = "
- "%d / %d / %d for IDR- / P- / B-frames.\n",
- priv->fixed_qp_idr, priv->fixed_qp_p, priv->fixed_qp_b);
- return 0;
-}
+ .sequence_params_size = sizeof(VAEncSequenceParameterBufferHEVC),
+ .init_sequence_params = &vaapi_encode_h265_init_sequence_params,
-static av_cold int vaapi_encode_h265_init_internal(AVCodecContext *avctx)
+ .picture_params_size = sizeof(VAEncPictureParameterBufferHEVC),
+ .init_picture_params = &vaapi_encode_h265_init_picture_params,
+
+ .slice_params_size = sizeof(VAEncSliceParameterBufferHEVC),
+ .init_slice_params = &vaapi_encode_h265_init_slice_params,
+
+ .sequence_header_type = VAEncPackedHeaderSequence,
+ .write_sequence_header = &vaapi_encode_h265_write_sequence_header,
+
+ .slice_header_type = VAEncPackedHeaderHEVC_Slice,
+ .write_slice_header = &vaapi_encode_h265_write_slice_header,
+};
+
+static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
{
- static const VAConfigAttrib default_config_attributes[] = {
- { .type = VAConfigAttribRTFormat,
- .value = VA_RT_FORMAT_YUV420 },
- { .type = VAConfigAttribEncPackedHeaders,
- .value = (VA_ENC_PACKED_HEADER_SEQUENCE |
- VA_ENC_PACKED_HEADER_SLICE) },
- };
+ VAAPIEncodeContext *ctx = avctx->priv_data;
- VAAPIEncodeContext *ctx = avctx->priv_data;
- VAAPIEncodeH265Context *priv = ctx->priv_data;
- int i, err;
+ ctx->codec = &vaapi_encode_type_h265;
switch (avctx->profile) {
case FF_PROFILE_HEVC_MAIN:
@@ -1258,66 +1243,19 @@ static av_cold int vaapi_encode_h265_init_internal(AVCodecContext *avctx)
}
ctx->va_entrypoint = VAEntrypointEncSlice;
- ctx->input_width = avctx->width;
- ctx->input_height = avctx->height;
- ctx->aligned_width = FFALIGN(ctx->input_width, 16);
- ctx->aligned_height = FFALIGN(ctx->input_height, 16);
- priv->ctu_width = FFALIGN(ctx->aligned_width, 32) / 32;
- priv->ctu_height = FFALIGN(ctx->aligned_height, 32) / 32;
-
- av_log(avctx, AV_LOG_VERBOSE, "Input %ux%u -> Aligned %ux%u -> CTU %ux%u.\n",
- ctx->input_width, ctx->input_height, ctx->aligned_width,
- ctx->aligned_height, priv->ctu_width, priv->ctu_height);
+ // This will be dependent on profile when 10-bit is supported.
+ ctx->va_rt_format = VA_RT_FORMAT_YUV420;
- for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) {
- ctx->config_attributes[ctx->nb_config_attributes++] =
- default_config_attributes[i];
- }
-
- if (avctx->bit_rate > 0) {
+ if (avctx->bit_rate > 0)
ctx->va_rc_mode = VA_RC_CBR;
- err = vaapi_encode_h265_init_constant_bitrate(avctx);
- } else {
+ else
ctx->va_rc_mode = VA_RC_CQP;
- err = vaapi_encode_h265_init_fixed_qp(avctx);
- }
- if (err < 0)
- return err;
- ctx->config_attributes[ctx->nb_config_attributes++] = (VAConfigAttrib) {
- .type = VAConfigAttribRateControl,
- .value = ctx->va_rc_mode,
- };
- ctx->nb_recon_frames = 20;
+ ctx->surface_width = FFALIGN(avctx->width, 16);
+ ctx->surface_height = FFALIGN(avctx->height, 16);
- return 0;
-}
-
-static VAAPIEncodeType vaapi_encode_type_h265 = {
- .priv_data_size = sizeof(VAAPIEncodeH265Context),
-
- .init = &vaapi_encode_h265_init_internal,
-
- .sequence_params_size = sizeof(VAEncSequenceParameterBufferHEVC),
- .init_sequence_params = &vaapi_encode_h265_init_sequence_params,
-
- .picture_params_size = sizeof(VAEncPictureParameterBufferHEVC),
- .init_picture_params = &vaapi_encode_h265_init_picture_params,
-
- .slice_params_size = sizeof(VAEncSliceParameterBufferHEVC),
- .init_slice_params = &vaapi_encode_h265_init_slice_params,
-
- .sequence_header_type = VAEncPackedHeaderSequence,
- .write_sequence_header = &vaapi_encode_h265_write_sequence_header,
-
- .slice_header_type = VAEncPackedHeaderHEVC_Slice,
- .write_slice_header = &vaapi_encode_h265_write_slice_header,
-};
-
-static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
-{
- return ff_vaapi_encode_init(avctx, &vaapi_encode_type_h265);
+ return ff_vaapi_encode_init(avctx);
}
#define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c
index e3bf191884..8866dfba62 100644
--- a/libavcodec/vaapi_encode_mjpeg.c
+++ b/libavcodec/vaapi_encode_mjpeg.c
@@ -277,8 +277,8 @@ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,
vpic->reconstructed_picture = pic->recon_surface;
vpic->coded_buf = pic->output_buffer;
- vpic->picture_width = ctx->input_width;
- vpic->picture_height = ctx->input_height;
+ vpic->picture_width = avctx->width;
+ vpic->picture_height = avctx->height;
vpic->pic_flags.bits.profile = 0;
vpic->pic_flags.bits.progressive = 0;
@@ -333,31 +333,10 @@ static int vaapi_encode_mjpeg_init_slice_params(AVCodecContext *avctx,
return 0;
}
-static av_cold int vaapi_encode_mjpeg_init_internal(AVCodecContext *avctx)
+static av_cold int vaapi_encode_mjpeg_configure(AVCodecContext *avctx)
{
- static const VAConfigAttrib default_config_attributes[] = {
- { .type = VAConfigAttribRTFormat,
- .value = VA_RT_FORMAT_YUV420 },
- { .type = VAConfigAttribEncPackedHeaders,
- .value = VA_ENC_PACKED_HEADER_SEQUENCE },
- };
-
VAAPIEncodeContext *ctx = avctx->priv_data;
VAAPIEncodeMJPEGContext *priv = ctx->priv_data;
- int i;
-
- ctx->va_profile = VAProfileJPEGBaseline;
- ctx->va_entrypoint = VAEntrypointEncPicture;
-
- ctx->input_width = avctx->width;
- ctx->input_height = avctx->height;
- ctx->aligned_width = FFALIGN(ctx->input_width, 8);
- ctx->aligned_height = FFALIGN(ctx->input_height, 8);
-
- for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) {
- ctx->config_attributes[ctx->nb_config_attributes++] =
- default_config_attributes[i];
- }
priv->quality = avctx->global_quality;
if (priv->quality < 1 || priv->quality > 100) {
@@ -374,7 +353,7 @@ static av_cold int vaapi_encode_mjpeg_init_internal(AVCodecContext *avctx)
static VAAPIEncodeType vaapi_encode_type_mjpeg = {
.priv_data_size = sizeof(VAAPIEncodeMJPEGContext),
- .init = &vaapi_encode_mjpeg_init_internal,
+ .configure = &vaapi_encode_mjpeg_configure,
.picture_params_size = sizeof(VAEncPictureParameterBufferJPEG),
.init_picture_params = &vaapi_encode_mjpeg_init_picture_params,
@@ -390,7 +369,21 @@ static VAAPIEncodeType vaapi_encode_type_mjpeg = {
static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx)
{
- return ff_vaapi_encode_init(avctx, &vaapi_encode_type_mjpeg);
+ VAAPIEncodeContext *ctx = avctx->priv_data;
+
+ ctx->codec = &vaapi_encode_type_mjpeg;
+
+ ctx->va_profile = VAProfileJPEGBaseline;
+ ctx->va_entrypoint = VAEntrypointEncPicture;
+
+ ctx->va_rt_format = VA_RT_FORMAT_YUV420;
+
+ ctx->va_rc_mode = VA_RC_CQP;
+
+ ctx->surface_width = FFALIGN(avctx->width, 8);
+ ctx->surface_height = FFALIGN(avctx->height, 8);
+
+ return ff_vaapi_encode_init(avctx);
}
static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = {