[FFmpeg-devel] [PATCH v7 02/12] avcodec/vaapi_encode: introduce a base layer for vaapi encode
Xiang, Haihao
haihao.xiang at intel.com
Mon Apr 15 10:29:26 EEST 2024
On Do, 2024-03-14 at 16:14 +0800, tong1.wu-at-intel.com at ffmpeg.org wrote:
> From: Tong Wu <tong1.wu at intel.com>
>
> Since VAAPI and future D3D12VA implementation may share some common
> parameters,
> a base layer encode context is introduced as vaapi context's base.
>
> Signed-off-by: Tong Wu <tong1.wu at intel.com>
> ---
> libavcodec/hw_base_encode.h | 241 ++++++++++++++++++++
> libavcodec/vaapi_encode.c | 392 +++++++++++++++++---------------
> libavcodec/vaapi_encode.h | 198 +---------------
> libavcodec/vaapi_encode_av1.c | 69 +++---
> libavcodec/vaapi_encode_h264.c | 197 ++++++++--------
> libavcodec/vaapi_encode_h265.c | 159 ++++++-------
> libavcodec/vaapi_encode_mjpeg.c | 20 +-
> libavcodec/vaapi_encode_mpeg2.c | 49 ++--
> libavcodec/vaapi_encode_vp8.c | 24 +-
> libavcodec/vaapi_encode_vp9.c | 66 +++---
> 10 files changed, 764 insertions(+), 651 deletions(-)
> create mode 100644 libavcodec/hw_base_encode.h
>
> diff --git a/libavcodec/hw_base_encode.h b/libavcodec/hw_base_encode.h
> new file mode 100644
> index 0000000000..41b68aa073
> --- /dev/null
> +++ b/libavcodec/hw_base_encode.h
> @@ -0,0 +1,241 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA
> + */
> +
> +#ifndef AVCODEC_HW_BASE_ENCODE_H
> +#define AVCODEC_HW_BASE_ENCODE_H
> +
> +#include "libavutil/hwcontext.h"
> +#include "libavutil/fifo.h"
> +
> +#include "avcodec.h"
> +
> +#define MAX_DPB_SIZE 16
> +#define MAX_PICTURE_REFERENCES 2
> +#define MAX_REORDER_DELAY 16
> +#define MAX_ASYNC_DEPTH 64
> +#define MAX_REFERENCE_LIST_NUM 2
> +
> +static inline const char *ff_hw_base_encode_get_pictype_name(const int type)
> {
> + const char * const picture_type_name[] = { "IDR", "I", "P", "B" };
> + return picture_type_name[type];
> +}
> +
> +enum {
> + PICTURE_TYPE_IDR = 0,
> + PICTURE_TYPE_I = 1,
> + PICTURE_TYPE_P = 2,
> + PICTURE_TYPE_B = 3,
> +};
> +
> +enum {
> + // Codec supports controlling the subdivision of pictures into slices.
> + FLAG_SLICE_CONTROL = 1 << 0,
> + // Codec only supports constant quality (no rate control).
> + FLAG_CONSTANT_QUALITY_ONLY = 1 << 1,
> + // Codec is intra-only.
> + FLAG_INTRA_ONLY = 1 << 2,
> + // Codec supports B-pictures.
> + FLAG_B_PICTURES = 1 << 3,
> + // Codec supports referencing B-pictures.
> + FLAG_B_PICTURE_REFERENCES = 1 << 4,
> + // Codec supports non-IDR key pictures (that is, key pictures do
> + // not necessarily empty the DPB).
> + FLAG_NON_IDR_KEY_PICTURES = 1 << 5,
> +};
> +
> +typedef struct HWBaseEncodePicture {
> + struct HWBaseEncodePicture *next;
> +
> + int64_t display_order;
> + int64_t encode_order;
> + int64_t pts;
> + int64_t duration;
> + int force_idr;
> +
> + void *opaque;
> + AVBufferRef *opaque_ref;
> +
> + int type;
> + int b_depth;
> + int encode_issued;
> + int encode_complete;
> +
> + AVFrame *input_image;
> + AVFrame *recon_image;
> +
> + void *priv_data;
> +
> + // Whether this picture is a reference picture.
> + int is_reference;
> +
> + // The contents of the DPB after this picture has been decoded.
> + // This will contain the picture itself if it is a reference picture,
> + // but not if it isn't.
> + int nb_dpb_pics;
> + struct HWBaseEncodePicture *dpb[MAX_DPB_SIZE];
> + // The reference pictures used in decoding this picture. If they are
> + // used by later pictures they will also appear in the DPB. ref[0][] for
> + // previous reference frames. ref[1][] for future reference frames.
> + int nb_refs[MAX_REFERENCE_LIST_NUM];
> + struct HWBaseEncodePicture
> *refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES];
> + // The previous reference picture in encode order. Must be in at least
> + // one of the reference list and DPB list.
> + struct HWBaseEncodePicture *prev;
> + // Reference count for other pictures referring to this one through
> + // the above pointers, directly from incomplete pictures and indirectly
> + // through completed pictures.
> + int ref_count[2];
> + int ref_removed[2];
> +} HWBaseEncodePicture;
> +
> +typedef struct HWEncodePictureOperation {
> + // Alloc memory for the picture structure.
> + HWBaseEncodePicture * (*alloc)(AVCodecContext *avctx, const AVFrame
> *frame);
> + // Issue the picture structure, which will send the frame surface to HW
> Encode API.
> + int (*issue)(AVCodecContext *avctx, const HWBaseEncodePicture *base_pic);
> + // Get the output AVPacket.
> + int (*output)(AVCodecContext *avctx, const HWBaseEncodePicture *base_pic,
> AVPacket *pkt);
> + // Free the picture structure.
> + int (*free)(AVCodecContext *avctx, HWBaseEncodePicture *base_pic);
> +} HWEncodePictureOperation;
> +
> +typedef struct HWBaseEncodeContext {
> + const AVClass *class;
> +
> + // Hardware-specific hooks.
> + const struct HWEncodePictureOperation *op;
> +
> + // Global options.
> +
> + // Number of I frames between IDR frames.
> + int idr_interval;
> +
> + // Desired B frame reference depth.
> + int desired_b_depth;
> +
> + // Explicitly set RC mode (otherwise attempt to pick from
> + // available modes).
> + int explicit_rc_mode;
> +
> + // Explicitly-set QP, for use with the "qp" options.
> + // (Forces CQP mode when set, overriding everything else.)
> + int explicit_qp;
> +
> + // 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;
> +
> + // The block size for slice calculations.
> + int slice_block_width;
> + int slice_block_height;
> +
> + // RC quality level - meaning depends on codec and RC mode.
> + // In CQP mode this sets the fixed quantiser value.
> + int rc_quality;
> +
> + AVBufferRef *device_ref;
> + AVHWDeviceContext *device;
> +
> + // The hardware frame context containing the input frames.
> + AVBufferRef *input_frames_ref;
> + AVHWFramesContext *input_frames;
> +
> + // The hardware frame context containing the reconstructed frames.
> + AVBufferRef *recon_frames_ref;
> + AVHWFramesContext *recon_frames;
> +
> + // Current encoding window, in display (input) order.
> + HWBaseEncodePicture *pic_start, *pic_end;
> + // The next picture to use as the previous reference picture in
> + // encoding order. Order from small to large in encoding order.
> + HWBaseEncodePicture *next_prev[MAX_PICTURE_REFERENCES];
> + int nb_next_prev;
> +
> + // Next input order index (display order).
> + int64_t input_order;
> + // Number of frames that output is behind input.
> + int64_t output_delay;
> + // Next encode order index.
> + int64_t encode_order;
> + // Number of frames decode output will need to be delayed.
> + int64_t decode_delay;
> + // Next output order index (in encode order).
> + int64_t output_order;
> +
> + // Timestamp handling.
> + int64_t first_pts;
> + int64_t dts_pts_diff;
> + int64_t ts_ring[MAX_REORDER_DELAY * 3 +
> + MAX_ASYNC_DEPTH];
> +
> + // Frame type decision.
> + int gop_size;
> + int closed_gop;
> + int gop_per_idr;
> + int p_per_i;
> + int max_b_depth;
> + int b_per_p;
> + int force_idr;
> + int idr_counter;
> + int gop_counter;
> + int end_of_stream;
> + int p_to_gpb;
> +
> + // Whether the driver supports ROI at all.
> + int roi_allowed;
> +
> + // The encoder does not support cropping information, so warn about
> + // it the first time we encounter any nonzero crop fields.
> + int crop_warned;
> + // If the driver does not support ROI then warn the first time we
> + // encounter a frame with ROI side data.
> + int roi_warned;
> +
> + AVFrame *frame;
Could you add more comments for members in base structures ?
Thanks
Haihao
> +
> + // Whether the HW supports sync buffer function.
> + // If supported, encode_fifo/async_depth will be used together.
> + // Used for output buffer synchronization.
> + int async_encode;
> +
> + // Store buffered pic
> + AVFifo *encode_fifo;
> + // Max number of frame buffered in encoder.
> + int async_depth;
> +
> + /** Tail data of a pic, now only used for av1 repeat frame header. */
> + AVPacket *tail_pkt;
> +} HWBaseEncodeContext;
> +
> +#define HW_BASE_ENCODE_COMMON_OPTIONS \
> + { "idr_interval", \
> + "Distance (in I-frames) between key frames", \
> + OFFSET(common.base.idr_interval), AV_OPT_TYPE_INT, \
> + { .i64 = 0 }, 0, INT_MAX, FLAGS }, \
> + { "b_depth", \
> + "Maximum B-frame reference depth", \
> + OFFSET(common.base.desired_b_depth), AV_OPT_TYPE_INT, \
> + { .i64 = 1 }, 1, INT_MAX, FLAGS }, \
> + { "async_depth", "Maximum processing parallelism. " \
> + "Increase this to improve single channel performance.", \
> + OFFSET(common.base.async_depth), AV_OPT_TYPE_INT, \
> + { .i64 = 2 }, 1, MAX_ASYNC_DEPTH, FLAGS }
> +
> +#endif /* AVCODEC_HW_BASE_ENCODE_H */
> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
> index bd29dbf0b4..4350960248 100644
> --- a/libavcodec/vaapi_encode.c
> +++ b/libavcodec/vaapi_encode.c
> @@ -37,8 +37,6 @@ const AVCodecHWConfigInternal *const
> ff_vaapi_encode_hw_configs[] = {
> NULL,
> };
>
> -static const char * const picture_type_name[] = { "IDR", "I", "P", "B" };
> -
> static int vaapi_encode_make_packed_header(AVCodecContext *avctx,
> VAAPIEncodePicture *pic,
> int type, char *data, size_t
> bit_len)
> @@ -139,22 +137,24 @@ static int
> vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx,
> static int vaapi_encode_wait(AVCodecContext *avctx,
> VAAPIEncodePicture *pic)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture*)pic;
> VAStatus vas;
>
> - av_assert0(pic->encode_issued);
> + av_assert0(base_pic->encode_issued);
>
> - if (pic->encode_complete) {
> + if (base_pic->encode_complete) {
> // Already waited for this picture.
> return 0;
> }
>
> av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" "
> - "(input surface %#x).\n", pic->display_order,
> - pic->encode_order, pic->input_surface);
> + "(input surface %#x).\n", base_pic->display_order,
> + base_pic->encode_order, pic->input_surface);
>
> #if VA_CHECK_VERSION(1, 9, 0)
> - if (ctx->has_sync_buffer_func) {
> + if (base_ctx->async_encode) {
> vas = vaSyncBuffer(ctx->hwctx->display,
> pic->output_buffer,
> VA_TIMEOUT_INFINITE);
> @@ -175,9 +175,9 @@ static int vaapi_encode_wait(AVCodecContext *avctx,
> }
>
> // Input is definitely finished with now.
> - av_frame_free(&pic->input_image);
> + av_frame_free(&base_pic->input_image);
>
> - pic->encode_complete = 1;
> + base_pic->encode_complete = 1;
> return 0;
> }
>
> @@ -264,9 +264,11 @@ static int vaapi_encode_make_tile_slice(AVCodecContext
> *avctx,
> }
>
> static int vaapi_encode_issue(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic)
> + HWBaseEncodePicture *base_pic)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic;
> VAAPIEncodeSlice *slice;
> VAStatus vas;
> int err, i;
> @@ -275,52 +277,52 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
> av_unused AVFrameSideData *sd;
>
> av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" "
> - "as type %s.\n", pic->display_order, pic->encode_order,
> - picture_type_name[pic->type]);
> - if (pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0) {
> + "as type %s.\n", base_pic->display_order, base_pic->encode_order,
> + ff_hw_base_encode_get_pictype_name(base_pic->type));
> + if (base_pic->nb_refs[0] == 0 && base_pic->nb_refs[1] == 0) {
> av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n");
> } else {
> av_log(avctx, AV_LOG_DEBUG, "L0 refers to");
> - for (i = 0; i < pic->nb_refs[0]; i++) {
> + for (i = 0; i < base_pic->nb_refs[0]; i++) {
> av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
> - pic->refs[0][i]->display_order, pic->refs[0][i]-
> >encode_order);
> + base_pic->refs[0][i]->display_order, base_pic->refs[0][i]-
> >encode_order);
> }
> av_log(avctx, AV_LOG_DEBUG, ".\n");
>
> - if (pic->nb_refs[1]) {
> + if (base_pic->nb_refs[1]) {
> av_log(avctx, AV_LOG_DEBUG, "L1 refers to");
> - for (i = 0; i < pic->nb_refs[1]; i++) {
> + for (i = 0; i < base_pic->nb_refs[1]; i++) {
> av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64,
> - pic->refs[1][i]->display_order, pic->refs[1][i]-
> >encode_order);
> + base_pic->refs[1][i]->display_order, base_pic-
> >refs[1][i]->encode_order);
> }
> av_log(avctx, AV_LOG_DEBUG, ".\n");
> }
> }
>
> - av_assert0(!pic->encode_issued);
> - for (i = 0; i < pic->nb_refs[0]; i++) {
> - av_assert0(pic->refs[0][i]);
> - av_assert0(pic->refs[0][i]->encode_issued);
> + av_assert0(!base_pic->encode_issued);
> + for (i = 0; i < base_pic->nb_refs[0]; i++) {
> + av_assert0(base_pic->refs[0][i]);
> + av_assert0(base_pic->refs[0][i]->encode_issued);
> }
> - for (i = 0; i < pic->nb_refs[1]; i++) {
> - av_assert0(pic->refs[1][i]);
> - av_assert0(pic->refs[1][i]->encode_issued);
> + for (i = 0; i < base_pic->nb_refs[1]; i++) {
> + av_assert0(base_pic->refs[1][i]);
> + av_assert0(base_pic->refs[1][i]->encode_issued);
> }
>
> av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic-
> >input_surface);
>
> - pic->recon_image = av_frame_alloc();
> - if (!pic->recon_image) {
> + base_pic->recon_image = av_frame_alloc();
> + if (!base_pic->recon_image) {
> err = AVERROR(ENOMEM);
> goto fail;
> }
>
> - err = av_hwframe_get_buffer(ctx->recon_frames_ref, pic->recon_image, 0);
> + err = av_hwframe_get_buffer(base_ctx->recon_frames_ref, base_pic-
> >recon_image, 0);
> if (err < 0) {
> err = AVERROR(ENOMEM);
> goto fail;
> }
> - pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3];
> + pic->recon_surface = (VASurfaceID)(uintptr_t)base_pic->recon_image-
> >data[3];
> av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic-
> >recon_surface);
>
> pic->output_buffer_ref = ff_refstruct_pool_get(ctx->output_buffer_pool);
> @@ -344,7 +346,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
>
> pic->nb_param_buffers = 0;
>
> - if (pic->type == PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) {
> + if (base_pic->type == PICTURE_TYPE_IDR && ctx->codec-
> >init_sequence_params) {
> err = vaapi_encode_make_param_buffer(avctx, pic,
>
> VAEncSequenceParameterBufferType,
> ctx->codec_sequence_params,
> @@ -353,7 +355,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
> goto fail;
> }
>
> - if (pic->type == PICTURE_TYPE_IDR) {
> + if (base_pic->type == PICTURE_TYPE_IDR) {
> for (i = 0; i < ctx->nb_global_params; i++) {
> err = vaapi_encode_make_misc_param_buffer(avctx, pic,
> ctx-
> >global_params_type[i],
> @@ -390,7 +392,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
> }
> #endif
>
> - if (pic->type == PICTURE_TYPE_IDR) {
> + if (base_pic->type == PICTURE_TYPE_IDR) {
> if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
> ctx->codec->write_sequence_header) {
> bit_len = 8 * sizeof(data);
> @@ -530,9 +532,9 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
> }
>
> #if VA_CHECK_VERSION(1, 0, 0)
> - sd = av_frame_get_side_data(pic->input_image,
> + sd = av_frame_get_side_data(base_pic->input_image,
> AV_FRAME_DATA_REGIONS_OF_INTEREST);
> - if (sd && ctx->roi_allowed) {
> + if (sd && base_ctx->roi_allowed) {
> const AVRegionOfInterest *roi;
> uint32_t roi_size;
> VAEncMiscParameterBufferROI param_roi;
> @@ -543,11 +545,11 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
> av_assert0(roi_size && sd->size % roi_size == 0);
> nb_roi = sd->size / roi_size;
> if (nb_roi > ctx->roi_max_regions) {
> - if (!ctx->roi_warned) {
> + if (!base_ctx->roi_warned) {
> av_log(avctx, AV_LOG_WARNING, "More ROIs set than "
> "supported by driver (%d > %d).\n",
> nb_roi, ctx->roi_max_regions);
> - ctx->roi_warned = 1;
> + base_ctx->roi_warned = 1;
> }
> nb_roi = ctx->roi_max_regions;
> }
> @@ -640,7 +642,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
> }
> }
>
> - pic->encode_issued = 1;
> + base_pic->encode_issued = 1;
>
> return 0;
>
> @@ -658,17 +660,18 @@ fail_at_end:
> av_freep(&pic->param_buffers);
> av_freep(&pic->slices);
> av_freep(&pic->roi);
> - av_frame_free(&pic->recon_image);
> + av_frame_free(&base_pic->recon_image);
> ff_refstruct_unref(&pic->output_buffer_ref);
> pic->output_buffer = VA_INVALID_ID;
> return err;
> }
>
> static int vaapi_encode_set_output_property(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic,
> + HWBaseEncodePicture *pic,
> AVPacket *pkt)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
>
> if (pic->type == PICTURE_TYPE_IDR)
> pkt->flags |= AV_PKT_FLAG_KEY;
> @@ -689,16 +692,16 @@ static int
> vaapi_encode_set_output_property(AVCodecContext *avctx,
> return 0;
> }
>
> - if (ctx->output_delay == 0) {
> + if (base_ctx->output_delay == 0) {
> pkt->dts = pkt->pts;
> - } else if (pic->encode_order < ctx->decode_delay) {
> - if (ctx->ts_ring[pic->encode_order] < INT64_MIN + ctx->dts_pts_diff)
> + } else if (pic->encode_order < base_ctx->decode_delay) {
> + if (base_ctx->ts_ring[pic->encode_order] < INT64_MIN + base_ctx-
> >dts_pts_diff)
> pkt->dts = INT64_MIN;
> else
> - pkt->dts = ctx->ts_ring[pic->encode_order] - ctx->dts_pts_diff;
> + pkt->dts = base_ctx->ts_ring[pic->encode_order] - base_ctx-
> >dts_pts_diff;
> } else {
> - pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) %
> - (3 * ctx->output_delay + ctx->async_depth)];
> + pkt->dts = base_ctx->ts_ring[(pic->encode_order - base_ctx-
> >decode_delay) %
> + (3 * base_ctx->output_delay + base_ctx-
> >async_depth)];
> }
>
> return 0;
> @@ -817,9 +820,11 @@ end:
> }
>
> static int vaapi_encode_output(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic, AVPacket *pkt)
> + HWBaseEncodePicture *base_pic, AVPacket *pkt)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic;
> AVPacket *pkt_ptr = pkt;
> int err;
>
> @@ -832,17 +837,17 @@ static int vaapi_encode_output(AVCodecContext *avctx,
> ctx->coded_buffer_ref = ff_refstruct_ref(pic->output_buffer_ref);
>
> if (pic->tail_size) {
> - if (ctx->tail_pkt->size) {
> + if (base_ctx->tail_pkt->size) {
> err = AVERROR_BUG;
> goto end;
> }
>
> - err = ff_get_encode_buffer(avctx, ctx->tail_pkt, pic->tail_size,
> 0);
> + err = ff_get_encode_buffer(avctx, base_ctx->tail_pkt, pic-
> >tail_size, 0);
> if (err < 0)
> goto end;
>
> - memcpy(ctx->tail_pkt->data, pic->tail_data, pic->tail_size);
> - pkt_ptr = ctx->tail_pkt;
> + memcpy(base_ctx->tail_pkt->data, pic->tail_data, pic->tail_size);
> + pkt_ptr = base_ctx->tail_pkt;
> }
> } else {
> err = vaapi_encode_get_coded_data(avctx, pic, pkt);
> @@ -851,9 +856,9 @@ static int vaapi_encode_output(AVCodecContext *avctx,
> }
>
> av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n",
> - pic->display_order, pic->encode_order);
> + base_pic->display_order, base_pic->encode_order);
>
> - vaapi_encode_set_output_property(avctx, pic, pkt_ptr);
> + vaapi_encode_set_output_property(avctx, base_pic, pkt_ptr);
>
> end:
> ff_refstruct_unref(&pic->output_buffer_ref);
> @@ -864,12 +869,13 @@ end:
> static int vaapi_encode_discard(AVCodecContext *avctx,
> VAAPIEncodePicture *pic)
> {
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture*)pic;
> vaapi_encode_wait(avctx, pic);
>
> if (pic->output_buffer_ref) {
> av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
> "%"PRId64"/%"PRId64".\n",
> - pic->display_order, pic->encode_order);
> + base_pic->display_order, base_pic->encode_order);
>
> ff_refstruct_unref(&pic->output_buffer_ref);
> pic->output_buffer = VA_INVALID_ID;
> @@ -878,8 +884,8 @@ static int vaapi_encode_discard(AVCodecContext *avctx,
> return 0;
> }
>
> -static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx,
> - const AVFrame *frame)
> +static HWBaseEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx,
> + const AVFrame *frame)
> {
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAAPIEncodePicture *pic;
> @@ -889,8 +895,8 @@ static VAAPIEncodePicture
> *vaapi_encode_alloc(AVCodecContext *avctx,
> return NULL;
>
> if (ctx->codec->picture_priv_data_size > 0) {
> - pic->priv_data = av_mallocz(ctx->codec->picture_priv_data_size);
> - if (!pic->priv_data) {
> + pic->base.priv_data = av_mallocz(ctx->codec->picture_priv_data_size);
> + if (!pic->base.priv_data) {
> av_freep(&pic);
> return NULL;
> }
> @@ -900,15 +906,16 @@ static VAAPIEncodePicture
> *vaapi_encode_alloc(AVCodecContext *avctx,
> pic->recon_surface = VA_INVALID_ID;
> pic->output_buffer = VA_INVALID_ID;
>
> - return pic;
> + return (HWBaseEncodePicture*)pic;
> }
>
> static int vaapi_encode_free(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic)
> + HWBaseEncodePicture *base_pic)
> {
> + VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic;
> int i;
>
> - if (pic->encode_issued)
> + if (base_pic->encode_issued)
> vaapi_encode_discard(avctx, pic);
>
> if (pic->slices) {
> @@ -916,17 +923,17 @@ static int vaapi_encode_free(AVCodecContext *avctx,
> av_freep(&pic->slices[i].codec_slice_params);
> }
>
> - av_frame_free(&pic->input_image);
> - av_frame_free(&pic->recon_image);
> + av_frame_free(&base_pic->input_image);
> + av_frame_free(&base_pic->recon_image);
>
> - av_buffer_unref(&pic->opaque_ref);
> + av_buffer_unref(&base_pic->opaque_ref);
>
> av_freep(&pic->param_buffers);
> av_freep(&pic->slices);
> // Output buffer should already be destroyed.
> av_assert0(pic->output_buffer == VA_INVALID_ID);
>
> - av_freep(&pic->priv_data);
> + av_freep(&base_pic->priv_data);
> av_freep(&pic->codec_picture_params);
> av_freep(&pic->roi);
>
> @@ -936,8 +943,8 @@ static int vaapi_encode_free(AVCodecContext *avctx,
> }
>
> static void vaapi_encode_add_ref(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic,
> - VAAPIEncodePicture *target,
> + HWBaseEncodePicture *pic,
> + HWBaseEncodePicture *target,
> int is_ref, int in_dpb, int prev)
> {
> int refs = 0;
> @@ -970,7 +977,7 @@ static void vaapi_encode_add_ref(AVCodecContext *avctx,
> }
>
> static void vaapi_encode_remove_refs(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic,
> + HWBaseEncodePicture *pic,
> int level)
> {
> int i;
> @@ -1006,14 +1013,14 @@ static void vaapi_encode_remove_refs(AVCodecContext
> *avctx,
> }
>
> static void vaapi_encode_set_b_pictures(AVCodecContext *avctx,
> - VAAPIEncodePicture *start,
> - VAAPIEncodePicture *end,
> - VAAPIEncodePicture *prev,
> + HWBaseEncodePicture *start,
> + HWBaseEncodePicture *end,
> + HWBaseEncodePicture *prev,
> int current_depth,
> - VAAPIEncodePicture **last)
> + HWBaseEncodePicture **last)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodePicture *pic, *next, *ref;
> + HWBaseEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodePicture *pic, *next, *ref;
> int i, len;
>
> av_assert0(start && end && start != end && start->next != end);
> @@ -1070,9 +1077,9 @@ static void vaapi_encode_set_b_pictures(AVCodecContext
> *avctx,
> }
>
> static void vaapi_encode_add_next_prev(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic)
> + HWBaseEncodePicture *pic)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *ctx = avctx->priv_data;
> int i;
>
> if (!pic)
> @@ -1103,10 +1110,10 @@ static void vaapi_encode_add_next_prev(AVCodecContext
> *avctx,
> }
>
> static int vaapi_encode_pick_next(AVCodecContext *avctx,
> - VAAPIEncodePicture **pic_out)
> + HWBaseEncodePicture **pic_out)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodePicture *pic = NULL, *prev = NULL, *next, *start;
> + HWBaseEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodePicture *pic = NULL, *prev = NULL, *next, *start;
> int i, b_counter, closed_gop_end;
>
> // If there are any B-frames already queued, the next one to encode
> @@ -1256,8 +1263,8 @@ static int vaapi_encode_pick_next(AVCodecContext *avctx,
>
> static int vaapi_encode_clear_old(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodePicture *pic, *prev, *next;
> + HWBaseEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodePicture *pic, *prev, *next;
>
> av_assert0(ctx->pic_start);
>
> @@ -1295,7 +1302,7 @@ static int vaapi_encode_clear_old(AVCodecContext *avctx)
> static int vaapi_encode_check_frame(AVCodecContext *avctx,
> const AVFrame *frame)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *ctx = avctx->priv_data;
>
> if ((frame->crop_top || frame->crop_bottom ||
> frame->crop_left || frame->crop_right) && !ctx->crop_warned) {
> @@ -1320,8 +1327,8 @@ static int vaapi_encode_check_frame(AVCodecContext
> *avctx,
>
> static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodePicture *pic;
> + HWBaseEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodePicture *pic;
> int err;
>
> if (frame) {
> @@ -1395,15 +1402,15 @@ fail:
>
> int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodePicture *pic = NULL;
> + HWBaseEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodePicture *pic = NULL;
> AVFrame *frame = ctx->frame;
> int err;
>
> start:
> /** if no B frame before repeat P frame, sent repeat P frame out. */
> if (ctx->tail_pkt->size) {
> - for (VAAPIEncodePicture *tmp = ctx->pic_start; tmp; tmp = tmp->next)
> {
> + for (HWBaseEncodePicture *tmp = ctx->pic_start; tmp; tmp = tmp->next)
> {
> if (tmp->type == PICTURE_TYPE_B && tmp->pts < ctx->tail_pkt->pts)
> break;
> else if (!tmp->next) {
> @@ -1431,7 +1438,7 @@ start:
> return AVERROR(EAGAIN);
> }
>
> - if (ctx->has_sync_buffer_func) {
> + if (ctx->async_encode) {
> if (av_fifo_can_write(ctx->encode_fifo)) {
> err = vaapi_encode_pick_next(avctx, &pic);
> if (!err) {
> @@ -1551,9 +1558,10 @@ static const VAEntrypoint
> vaapi_encode_entrypoints_low_power[] = {
>
> static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAProfile *va_profiles = NULL;
> - VAEntrypoint *va_entrypoints = NULL;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAProfile *va_profiles = NULL;
> + VAEntrypoint *va_entrypoints = NULL;
> VAStatus vas;
> const VAEntrypoint *usable_entrypoints;
> const VAAPIEncodeProfile *profile;
> @@ -1576,10 +1584,10 @@ static av_cold int
> vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
> usable_entrypoints = vaapi_encode_entrypoints_normal;
> }
>
> - desc = av_pix_fmt_desc_get(ctx->input_frames->sw_format);
> + desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format);
> if (!desc) {
> av_log(avctx, AV_LOG_ERROR, "Invalid input pixfmt (%d).\n",
> - ctx->input_frames->sw_format);
> + base_ctx->input_frames->sw_format);
> return AVERROR(EINVAL);
> }
> depth = desc->comp[0].depth;
> @@ -1772,7 +1780,8 @@ static const VAAPIEncodeRCMode vaapi_encode_rc_modes[] =
> {
>
> static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> uint32_t supported_va_rc_modes;
> const VAAPIEncodeRCMode *rc_mode;
> int64_t rc_bits_per_second;
> @@ -1855,10 +1864,10 @@ static av_cold int
> vaapi_encode_init_rate_control(AVCodecContext *avctx)
> } \
> } while (0)
>
> - if (ctx->explicit_rc_mode)
> - TRY_RC_MODE(ctx->explicit_rc_mode, 1);
> + if (base_ctx->explicit_rc_mode)
> + TRY_RC_MODE(base_ctx->explicit_rc_mode, 1);
>
> - if (ctx->explicit_qp)
> + if (base_ctx->explicit_qp)
> TRY_RC_MODE(RC_MODE_CQP, 1);
>
> if (ctx->codec->flags & FLAG_CONSTANT_QUALITY_ONLY)
> @@ -1953,8 +1962,8 @@ rc_mode_found:
> }
>
> if (rc_mode->quality) {
> - if (ctx->explicit_qp) {
> - rc_quality = ctx->explicit_qp;
> + if (base_ctx->explicit_qp) {
> + rc_quality = base_ctx->explicit_qp;
> } else if (avctx->global_quality > 0) {
> rc_quality = avctx->global_quality;
> } else {
> @@ -2010,10 +2019,10 @@ rc_mode_found:
> return AVERROR(EINVAL);
> }
>
> - ctx->rc_mode = rc_mode;
> - ctx->rc_quality = rc_quality;
> - ctx->va_rc_mode = rc_mode->va_mode;
> - ctx->va_bit_rate = rc_bits_per_second;
> + 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;
>
> av_log(avctx, AV_LOG_VERBOSE, "RC mode: %s.\n", rc_mode->name);
> if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
> @@ -2159,7 +2168,8 @@ static av_cold int
> vaapi_encode_init_max_frame_size(AVCodecContext *avctx)
>
> static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> VAStatus vas;
> VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
> uint32_t ref_l0, ref_l1;
> @@ -2182,7 +2192,7 @@ static av_cold int
> vaapi_encode_init_gop_structure(AVCodecContext *avctx)
> ref_l1 = attr.value >> 16 & 0xffff;
> }
>
> - ctx->p_to_gpb = 0;
> + base_ctx->p_to_gpb = 0;
> prediction_pre_only = 0;
>
> #if VA_CHECK_VERSION(1, 9, 0)
> @@ -2218,7 +2228,7 @@ static av_cold int
> vaapi_encode_init_gop_structure(AVCodecContext *avctx)
>
> if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
> if (ref_l0 > 0 && ref_l1 > 0) {
> - ctx->p_to_gpb = 1;
> + base_ctx->p_to_gpb = 1;
> av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-
> frames, "
> "replacing them with B-frames.\n");
> }
> @@ -2230,7 +2240,7 @@ static av_cold int
> vaapi_encode_init_gop_structure(AVCodecContext *avctx)
> if (ctx->codec->flags & FLAG_INTRA_ONLY ||
> avctx->gop_size <= 1) {
> av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n");
> - ctx->gop_size = 1;
> + base_ctx->gop_size = 1;
> } else if (ref_l0 < 1) {
> av_log(avctx, AV_LOG_ERROR, "Driver does not support any "
> "reference frames.\n");
> @@ -2238,41 +2248,41 @@ static av_cold int
> vaapi_encode_init_gop_structure(AVCodecContext *avctx)
> } else if (!(ctx->codec->flags & FLAG_B_PICTURES) ||
> ref_l1 < 1 || avctx->max_b_frames < 1 ||
> prediction_pre_only) {
> - if (ctx->p_to_gpb)
> + if (base_ctx->p_to_gpb)
> av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
> "(supported references: %d / %d).\n",
> ref_l0, ref_l1);
> else
> av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames "
> "(supported references: %d / %d).\n", ref_l0, ref_l1);
> - ctx->gop_size = avctx->gop_size;
> - ctx->p_per_i = INT_MAX;
> - ctx->b_per_p = 0;
> + base_ctx->gop_size = avctx->gop_size;
> + base_ctx->p_per_i = INT_MAX;
> + base_ctx->b_per_p = 0;
> } else {
> - if (ctx->p_to_gpb)
> + if (base_ctx->p_to_gpb)
> av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames "
> "(supported references: %d / %d).\n",
> ref_l0, ref_l1);
> else
> av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames "
> "(supported references: %d / %d).\n", ref_l0, ref_l1);
> - ctx->gop_size = avctx->gop_size;
> - ctx->p_per_i = INT_MAX;
> - ctx->b_per_p = avctx->max_b_frames;
> + base_ctx->gop_size = avctx->gop_size;
> + base_ctx->p_per_i = INT_MAX;
> + base_ctx->b_per_p = avctx->max_b_frames;
> if (ctx->codec->flags & FLAG_B_PICTURE_REFERENCES) {
> - ctx->max_b_depth = FFMIN(ctx->desired_b_depth,
> - av_log2(ctx->b_per_p) + 1);
> + base_ctx->max_b_depth = FFMIN(base_ctx->desired_b_depth,
> + av_log2(base_ctx->b_per_p) + 1);
> } else {
> - ctx->max_b_depth = 1;
> + base_ctx->max_b_depth = 1;
> }
> }
>
> if (ctx->codec->flags & FLAG_NON_IDR_KEY_PICTURES) {
> - ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
> - ctx->gop_per_idr = ctx->idr_interval + 1;
> + base_ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP);
> + base_ctx->gop_per_idr = base_ctx->idr_interval + 1;
> } else {
> - ctx->closed_gop = 1;
> - ctx->gop_per_idr = 1;
> + base_ctx->closed_gop = 1;
> + base_ctx->gop_per_idr = 1;
> }
>
> return 0;
> @@ -2386,6 +2396,7 @@ static av_cold int
> vaapi_encode_init_tile_slice_structure(AVCodecContext *avctx,
>
> static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
> { VAConfigAttribEncSliceStructure },
> @@ -2405,12 +2416,12 @@ static av_cold int
> vaapi_encode_init_slice_structure(AVCodecContext *avctx)
> return 0;
> }
>
> - av_assert0(ctx->slice_block_height > 0 && ctx->slice_block_width > 0);
> + av_assert0(base_ctx->slice_block_height > 0 && base_ctx-
> >slice_block_width > 0);
>
> - ctx->slice_block_rows = (avctx->height + ctx->slice_block_height - 1) /
> - ctx->slice_block_height;
> - ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
> - ctx->slice_block_width;
> + ctx->slice_block_rows = (avctx->height + base_ctx->slice_block_height -
> 1) /
> + base_ctx->slice_block_height;
> + ctx->slice_block_cols = (avctx->width + base_ctx->slice_block_width -
> 1) /
> + base_ctx->slice_block_width;
>
> if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) {
> ctx->nb_slices = 1;
> @@ -2585,7 +2596,8 @@ static av_cold int
> vaapi_encode_init_quality(AVCodecContext *avctx)
> static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
> {
> #if VA_CHECK_VERSION(1, 0, 0)
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> VAStatus vas;
> VAConfigAttrib attr = { VAConfigAttribEncROI };
>
> @@ -2600,14 +2612,14 @@ static av_cold int
> vaapi_encode_init_roi(AVCodecContext *avctx)
> }
>
> if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
> - ctx->roi_allowed = 0;
> + base_ctx->roi_allowed = 0;
> } else {
> VAConfigAttribValEncROI roi = {
> .value = attr.value,
> };
>
> ctx->roi_max_regions = roi.bits.num_roi_regions;
> - ctx->roi_allowed = ctx->roi_max_regions > 0 &&
> + base_ctx->roi_allowed = ctx->roi_max_regions > 0 &&
> (ctx->va_rc_mode == VA_RC_CQP ||
> roi.bits.roi_rc_qp_delta_support);
> }
> @@ -2631,7 +2643,8 @@ static void
> vaapi_encode_free_output_buffer(FFRefStructOpaque opaque,
> static int vaapi_encode_alloc_output_buffer(FFRefStructOpaque opaque, void
> *obj)
> {
> AVCodecContext *avctx = opaque.nc;
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> VABufferID *buffer_id = obj;
> VAStatus vas;
>
> @@ -2641,7 +2654,7 @@ static int
> vaapi_encode_alloc_output_buffer(FFRefStructOpaque opaque, void *obj)
> // bound on that.
> vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
> VAEncCodedBufferType,
> - 3 * ctx->surface_width * ctx->surface_height +
> + 3 * base_ctx->surface_width * base_ctx-
> >surface_height +
> (1 << 16), 1, 0, buffer_id);
> if (vas != VA_STATUS_SUCCESS) {
> av_log(avctx, AV_LOG_ERROR, "Failed to create bitstream "
> @@ -2656,20 +2669,21 @@ static int
> vaapi_encode_alloc_output_buffer(FFRefStructOpaque opaque, void *obj)
>
> static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> AVVAAPIHWConfig *hwconfig = NULL;
> AVHWFramesConstraints *constraints = NULL;
> enum AVPixelFormat recon_format;
> int err, i;
>
> - hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
> + hwconfig = av_hwdevice_hwconfig_alloc(base_ctx->device_ref);
> if (!hwconfig) {
> err = AVERROR(ENOMEM);
> goto fail;
> }
> hwconfig->config_id = ctx->va_config;
>
> - constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
> + constraints = av_hwdevice_get_hwframe_constraints(base_ctx->device_ref,
> hwconfig);
> if (!constraints) {
> err = AVERROR(ENOMEM);
> @@ -2682,9 +2696,9 @@ static av_cold int
> vaapi_encode_create_recon_frames(AVCodecContext *avctx)
> recon_format = AV_PIX_FMT_NONE;
> if (constraints->valid_sw_formats) {
> for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++)
> {
> - if (ctx->input_frames->sw_format ==
> + if (base_ctx->input_frames->sw_format ==
> constraints->valid_sw_formats[i]) {
> - recon_format = ctx->input_frames->sw_format;
> + recon_format = base_ctx->input_frames->sw_format;
> break;
> }
> }
> @@ -2695,18 +2709,18 @@ static av_cold int
> vaapi_encode_create_recon_frames(AVCodecContext *avctx)
> }
> } else {
> // No idea what to use; copy input format.
> - recon_format = ctx->input_frames->sw_format;
> + recon_format = base_ctx->input_frames->sw_format;
> }
> av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
> "reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
>
> - 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) {
> + if (base_ctx->surface_width < constraints->min_width ||
> + base_ctx->surface_height < constraints->min_height ||
> + base_ctx->surface_width > constraints->max_width ||
> + base_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->surface_width, ctx->surface_height,
> + base_ctx->surface_width, base_ctx->surface_height,
> constraints->min_width, constraints->max_width,
> constraints->min_height, constraints->max_height);
> err = AVERROR(EINVAL);
> @@ -2716,19 +2730,19 @@ static av_cold int
> vaapi_encode_create_recon_frames(AVCodecContext *avctx)
> av_freep(&hwconfig);
> av_hwframe_constraints_free(&constraints);
>
> - ctx->recon_frames_ref = av_hwframe_ctx_alloc(ctx->device_ref);
> - if (!ctx->recon_frames_ref) {
> + base_ctx->recon_frames_ref = av_hwframe_ctx_alloc(base_ctx->device_ref);
> + if (!base_ctx->recon_frames_ref) {
> err = AVERROR(ENOMEM);
> goto fail;
> }
> - ctx->recon_frames = (AVHWFramesContext*)ctx->recon_frames_ref->data;
> + base_ctx->recon_frames = (AVHWFramesContext*)base_ctx->recon_frames_ref-
> >data;
>
> - ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
> - ctx->recon_frames->sw_format = recon_format;
> - ctx->recon_frames->width = ctx->surface_width;
> - ctx->recon_frames->height = ctx->surface_height;
> + base_ctx->recon_frames->format = AV_PIX_FMT_VAAPI;
> + base_ctx->recon_frames->sw_format = recon_format;
> + base_ctx->recon_frames->width = base_ctx->surface_width;
> + base_ctx->recon_frames->height = base_ctx->surface_height;
>
> - err = av_hwframe_ctx_init(ctx->recon_frames_ref);
> + err = av_hwframe_ctx_init(base_ctx->recon_frames_ref);
> if (err < 0) {
> av_log(avctx, AV_LOG_ERROR, "Failed to initialise reconstructed "
> "frame context: %d.\n", err);
> @@ -2744,7 +2758,8 @@ static av_cold int
> vaapi_encode_create_recon_frames(AVCodecContext *avctx)
>
> av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> AVVAAPIFramesContext *recon_hwctx = NULL;
> VAStatus vas;
> int err;
> @@ -2754,8 +2769,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
>
> /* If you add something that can fail above this av_frame_alloc(),
> * modify ff_vaapi_encode_close() accordingly. */
> - ctx->frame = av_frame_alloc();
> - if (!ctx->frame) {
> + base_ctx->frame = av_frame_alloc();
> + if (!base_ctx->frame) {
> return AVERROR(ENOMEM);
> }
>
> @@ -2765,23 +2780,23 @@ av_cold int ff_vaapi_encode_init(AVCodecContext
> *avctx)
> return AVERROR(EINVAL);
> }
>
> - ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
> - if (!ctx->input_frames_ref) {
> + base_ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
> + if (!base_ctx->input_frames_ref) {
> err = AVERROR(ENOMEM);
> goto fail;
> }
> - ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
> + base_ctx->input_frames = (AVHWFramesContext*)base_ctx->input_frames_ref-
> >data;
>
> - ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
> - if (!ctx->device_ref) {
> + base_ctx->device_ref = av_buffer_ref(base_ctx->input_frames->device_ref);
> + if (!base_ctx->device_ref) {
> err = AVERROR(ENOMEM);
> goto fail;
> }
> - ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
> - ctx->hwctx = ctx->device->hwctx;
> + base_ctx->device = (AVHWDeviceContext*)base_ctx->device_ref->data;
> + ctx->hwctx = base_ctx->device->hwctx;
>
> - ctx->tail_pkt = av_packet_alloc();
> - if (!ctx->tail_pkt) {
> + base_ctx->tail_pkt = av_packet_alloc();
> + if (!base_ctx->tail_pkt) {
> err = AVERROR(ENOMEM);
> goto fail;
> }
> @@ -2796,11 +2811,11 @@ av_cold int ff_vaapi_encode_init(AVCodecContext
> *avctx)
> goto fail;
> } else {
> // Assume 16x16 blocks.
> - ctx->surface_width = FFALIGN(avctx->width, 16);
> - ctx->surface_height = FFALIGN(avctx->height, 16);
> + base_ctx->surface_width = FFALIGN(avctx->width, 16);
> + base_ctx->surface_height = FFALIGN(avctx->height, 16);
> if (ctx->codec->flags & FLAG_SLICE_CONTROL) {
> - ctx->slice_block_width = 16;
> - ctx->slice_block_height = 16;
> + base_ctx->slice_block_width = 16;
> + base_ctx->slice_block_height = 16;
> }
> }
>
> @@ -2851,9 +2866,9 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
> if (err < 0)
> goto fail;
>
> - recon_hwctx = ctx->recon_frames->hwctx;
> + recon_hwctx = base_ctx->recon_frames->hwctx;
> vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
> - ctx->surface_width, ctx->surface_height,
> + base_ctx->surface_width, base_ctx->surface_height,
> VA_PROGRESSIVE,
> recon_hwctx->surface_ids,
> recon_hwctx->nb_surfaces,
> @@ -2880,8 +2895,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
> goto fail;
> }
>
> - ctx->output_delay = ctx->b_per_p;
> - ctx->decode_delay = ctx->max_b_depth;
> + base_ctx->output_delay = base_ctx->b_per_p;
> + base_ctx->decode_delay = base_ctx->max_b_depth;
>
> if (ctx->codec->sequence_params_size > 0) {
> ctx->codec_sequence_params =
> @@ -2936,11 +2951,11 @@ av_cold int ff_vaapi_encode_init(AVCodecContext
> *avctx)
> // check vaSyncBuffer function
> vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0);
> if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
> - ctx->has_sync_buffer_func = 1;
> - ctx->encode_fifo = av_fifo_alloc2(ctx->async_depth,
> - sizeof(VAAPIEncodePicture *),
> - 0);
> - if (!ctx->encode_fifo)
> + base_ctx->async_encode = 1;
> + base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth,
> + sizeof(VAAPIEncodePicture*),
> + 0);
> + if (!base_ctx->encode_fifo)
> return AVERROR(ENOMEM);
> }
> #endif
> @@ -2953,15 +2968,16 @@ fail:
>
> av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodePicture *pic, *next;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodePicture *pic, *next;
>
> /* We check ctx->frame to know whether ff_vaapi_encode_init()
> * has been called and va_config/va_context initialized. */
> - if (!ctx->frame)
> + if (!base_ctx->frame)
> return 0;
>
> - for (pic = ctx->pic_start; pic; pic = next) {
> + for (pic = base_ctx->pic_start; pic; pic = next) {
> next = pic->next;
> vaapi_encode_free(avctx, pic);
> }
> @@ -2978,16 +2994,16 @@ av_cold int ff_vaapi_encode_close(AVCodecContext
> *avctx)
> ctx->va_config = VA_INVALID_ID;
> }
>
> - av_frame_free(&ctx->frame);
> - av_packet_free(&ctx->tail_pkt);
> + av_frame_free(&base_ctx->frame);
> + av_packet_free(&base_ctx->tail_pkt);
>
> av_freep(&ctx->codec_sequence_params);
> av_freep(&ctx->codec_picture_params);
> - av_fifo_freep2(&ctx->encode_fifo);
> + av_fifo_freep2(&base_ctx->encode_fifo);
>
> - av_buffer_unref(&ctx->recon_frames_ref);
> - av_buffer_unref(&ctx->input_frames_ref);
> - av_buffer_unref(&ctx->device_ref);
> + av_buffer_unref(&base_ctx->recon_frames_ref);
> + av_buffer_unref(&base_ctx->input_frames_ref);
> + av_buffer_unref(&base_ctx->device_ref);
>
> return 0;
> }
> diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
> index 6964055b93..8eee455881 100644
> --- a/libavcodec/vaapi_encode.h
> +++ b/libavcodec/vaapi_encode.h
> @@ -29,38 +29,30 @@
>
> #include "libavutil/hwcontext.h"
> #include "libavutil/hwcontext_vaapi.h"
> -#include "libavutil/fifo.h"
>
> #include "avcodec.h"
> #include "hwconfig.h"
> +#include "hw_base_encode.h"
>
> struct VAAPIEncodeType;
> struct VAAPIEncodePicture;
>
> +// Codec output packet without timestamp delay, which means the
> +// output packet has same PTS and DTS.
> +#define FLAG_TIMESTAMP_NO_DELAY 1 << 6
> +
> enum {
> MAX_CONFIG_ATTRIBUTES = 4,
> MAX_GLOBAL_PARAMS = 4,
> - MAX_DPB_SIZE = 16,
> - MAX_PICTURE_REFERENCES = 2,
> - MAX_REORDER_DELAY = 16,
> MAX_PARAM_BUFFER_SIZE = 1024,
> // A.4.1: table A.6 allows at most 22 tile rows for any level.
> MAX_TILE_ROWS = 22,
> // A.4.1: table A.6 allows at most 20 tile columns for any level.
> MAX_TILE_COLS = 20,
> - MAX_ASYNC_DEPTH = 64,
> - MAX_REFERENCE_LIST_NUM = 2,
> };
>
> extern const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[];
>
> -enum {
> - PICTURE_TYPE_IDR = 0,
> - PICTURE_TYPE_I = 1,
> - PICTURE_TYPE_P = 2,
> - PICTURE_TYPE_B = 3,
> -};
> -
> typedef struct VAAPIEncodeSlice {
> int index;
> int row_start;
> @@ -71,16 +63,7 @@ typedef struct VAAPIEncodeSlice {
> } VAAPIEncodeSlice;
>
> typedef struct VAAPIEncodePicture {
> - struct VAAPIEncodePicture *next;
> -
> - int64_t display_order;
> - int64_t encode_order;
> - int64_t pts;
> - int64_t duration;
> - int force_idr;
> -
> - void *opaque;
> - AVBufferRef *opaque_ref;
> + HWBaseEncodePicture base;
>
> #if VA_CHECK_VERSION(1, 0, 0)
> // ROI regions.
> @@ -89,15 +72,7 @@ typedef struct VAAPIEncodePicture {
> void *roi;
> #endif
>
> - int type;
> - int b_depth;
> - int encode_issued;
> - int encode_complete;
> -
> - AVFrame *input_image;
> VASurfaceID input_surface;
> -
> - AVFrame *recon_image;
> VASurfaceID recon_surface;
>
> int nb_param_buffers;
> @@ -107,34 +82,10 @@ typedef struct VAAPIEncodePicture {
> VABufferID *output_buffer_ref;
> VABufferID output_buffer;
>
> - void *priv_data;
> void *codec_picture_params;
>
> - // Whether this picture is a reference picture.
> - int is_reference;
> -
> - // The contents of the DPB after this picture has been decoded.
> - // This will contain the picture itself if it is a reference picture,
> - // but not if it isn't.
> - int nb_dpb_pics;
> - struct VAAPIEncodePicture *dpb[MAX_DPB_SIZE];
> - // The reference pictures used in decoding this picture. If they are
> - // used by later pictures they will also appear in the DPB. ref[0][] for
> - // previous reference frames. ref[1][] for future reference frames.
> - int nb_refs[MAX_REFERENCE_LIST_NUM];
> - struct VAAPIEncodePicture
> *refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES];
> - // The previous reference picture in encode order. Must be in at least
> - // one of the reference list and DPB list.
> - struct VAAPIEncodePicture *prev;
> - // Reference count for other pictures referring to this one through
> - // the above pointers, directly from incomplete pictures and indirectly
> - // through completed pictures.
> - int ref_count[2];
> - int ref_removed[2];
> -
> int nb_slices;
> VAAPIEncodeSlice *slices;
> -
> /**
> * indicate if current frame is an independent frame that the coded data
> * can be pushed to downstream directly. Coded of non-independent frame
> @@ -193,57 +144,26 @@ typedef struct VAAPIEncodeRCMode {
> } VAAPIEncodeRCMode;
>
> typedef struct VAAPIEncodeContext {
> - const AVClass *class;
> + // Base.
> + HWBaseEncodeContext base;
>
> // Codec-specific hooks.
> const struct VAAPIEncodeType *codec;
>
> - // Global options.
> -
> // Use low power encoding mode.
> int low_power;
>
> - // Number of I frames between IDR frames.
> - int idr_interval;
> -
> - // Desired B frame reference depth.
> - int desired_b_depth;
> -
> // Max Frame Size
> int max_frame_size;
>
> - // Explicitly set RC mode (otherwise attempt to pick from
> - // available modes).
> - int explicit_rc_mode;
> -
> - // Explicitly-set QP, for use with the "qp" options.
> - // (Forces CQP mode when set, overriding everything else.)
> - int explicit_qp;
> -
> // Desired packed headers.
> unsigned int desired_packed_headers;
>
> - // 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;
> -
> - // The block size for slice calculations.
> - int slice_block_width;
> - int slice_block_height;
> -
> - // Everything above this point must be set before calling
> - // ff_vaapi_encode_init().
> -
> // Chosen encoding profile details.
> const VAAPIEncodeProfile *profile;
>
> // Chosen rate control mode details.
> const VAAPIEncodeRCMode *rc_mode;
> - // RC quality level - meaning depends on codec and RC mode.
> - // In CQP mode this sets the fixed quantiser value.
> - int rc_quality;
>
> // Encoding profile (VAProfile*).
> VAProfile va_profile;
> @@ -263,18 +183,8 @@ typedef struct VAAPIEncodeContext {
> VAConfigID va_config;
> VAContextID va_context;
>
> - AVBufferRef *device_ref;
> - AVHWDeviceContext *device;
> AVVAAPIDeviceContext *hwctx;
>
> - // The hardware frame context containing the input frames.
> - AVBufferRef *input_frames_ref;
> - AVHWFramesContext *input_frames;
> -
> - // The hardware frame context containing the reconstructed frames.
> - AVBufferRef *recon_frames_ref;
> - AVHWFramesContext *recon_frames;
> -
> // Pool of (reusable) bitstream output buffers.
> struct FFRefStructPool *output_buffer_pool;
>
> @@ -301,30 +211,6 @@ typedef struct VAAPIEncodeContext {
> // structure (VAEncPictureParameterBuffer*).
> void *codec_picture_params;
>
> - // Current encoding window, in display (input) order.
> - VAAPIEncodePicture *pic_start, *pic_end;
> - // The next picture to use as the previous reference picture in
> - // encoding order. Order from small to large in encoding order.
> - VAAPIEncodePicture *next_prev[MAX_PICTURE_REFERENCES];
> - int nb_next_prev;
> -
> - // Next input order index (display order).
> - int64_t input_order;
> - // Number of frames that output is behind input.
> - int64_t output_delay;
> - // Next encode order index.
> - int64_t encode_order;
> - // Number of frames decode output will need to be delayed.
> - int64_t decode_delay;
> - // Next output order index (in encode order).
> - int64_t output_order;
> -
> - // Timestamp handling.
> - int64_t first_pts;
> - int64_t dts_pts_diff;
> - int64_t ts_ring[MAX_REORDER_DELAY * 3 +
> - MAX_ASYNC_DEPTH];
> -
> // Slice structure.
> int slice_block_rows;
> int slice_block_cols;
> @@ -343,43 +229,12 @@ typedef struct VAAPIEncodeContext {
> // Location of the i-th tile row boundary.
> int row_bd[MAX_TILE_ROWS + 1];
>
> - // Frame type decision.
> - int gop_size;
> - int closed_gop;
> - int gop_per_idr;
> - int p_per_i;
> - int max_b_depth;
> - int b_per_p;
> - int force_idr;
> - int idr_counter;
> - int gop_counter;
> - int end_of_stream;
> - int p_to_gpb;
> -
> - // Whether the driver supports ROI at all.
> - int roi_allowed;
> // Maximum number of regions supported by the driver.
> int roi_max_regions;
> // Quantisation range for offset calculations. Set by codec-specific
> // code, as it may change based on parameters.
> int roi_quant_range;
>
> - // The encoder does not support cropping information, so warn about
> - // it the first time we encounter any nonzero crop fields.
> - int crop_warned;
> - // If the driver does not support ROI then warn the first time we
> - // encounter a frame with ROI side data.
> - int roi_warned;
> -
> - AVFrame *frame;
> -
> - // Whether the driver support vaSyncBuffer
> - int has_sync_buffer_func;
> - // Store buffered pic
> - AVFifo *encode_fifo;
> - // Max number of frame buffered in encoder.
> - int async_depth;
> -
> /** Head data for current output pkt, used only for AV1. */
> //void *header_data;
> //size_t header_data_size;
> @@ -389,30 +244,8 @@ typedef struct VAAPIEncodeContext {
> * This is a RefStruct reference.
> */
> VABufferID *coded_buffer_ref;
> -
> - /** Tail data of a pic, now only used for av1 repeat frame header. */
> - AVPacket *tail_pkt;
> } VAAPIEncodeContext;
>
> -enum {
> - // Codec supports controlling the subdivision of pictures into slices.
> - FLAG_SLICE_CONTROL = 1 << 0,
> - // Codec only supports constant quality (no rate control).
> - FLAG_CONSTANT_QUALITY_ONLY = 1 << 1,
> - // Codec is intra-only.
> - FLAG_INTRA_ONLY = 1 << 2,
> - // Codec supports B-pictures.
> - FLAG_B_PICTURES = 1 << 3,
> - // Codec supports referencing B-pictures.
> - FLAG_B_PICTURE_REFERENCES = 1 << 4,
> - // Codec supports non-IDR key pictures (that is, key pictures do
> - // not necessarily empty the DPB).
> - FLAG_NON_IDR_KEY_PICTURES = 1 << 5,
> - // Codec output packet without timestamp delay, which means the
> - // output packet has same PTS and DTS.
> - FLAG_TIMESTAMP_NO_DELAY = 1 << 6,
> -};
> -
> typedef struct VAAPIEncodeType {
> // List of supported profiles and corresponding VAAPI profiles.
> // (Must end with AV_PROFILE_UNKNOWN.)
> @@ -505,19 +338,6 @@ int ff_vaapi_encode_close(AVCodecContext *avctx);
> "may not support all encoding features)", \
> OFFSET(common.low_power), AV_OPT_TYPE_BOOL, \
> { .i64 = 0 }, 0, 1, FLAGS }, \
> - { "idr_interval", \
> - "Distance (in I-frames) between IDR frames", \
> - OFFSET(common.idr_interval), AV_OPT_TYPE_INT, \
> - { .i64 = 0 }, 0, INT_MAX, FLAGS }, \
> - { "b_depth", \
> - "Maximum B-frame reference depth", \
> - OFFSET(common.desired_b_depth), AV_OPT_TYPE_INT, \
> - { .i64 = 1 }, 1, INT_MAX, FLAGS }, \
> - { "async_depth", "Maximum processing parallelism. " \
> - "Increase this to improve single channel performance. This option " \
> - "doesn't work if driver doesn't implement vaSyncBuffer function.", \
> - OFFSET(common.async_depth), AV_OPT_TYPE_INT, \
> - { .i64 = 2 }, 1, MAX_ASYNC_DEPTH, FLAGS }, \
> { "max_frame_size", \
> "Maximum frame size (in bytes)",\
> OFFSET(common.max_frame_size), AV_OPT_TYPE_INT, \
> @@ -529,7 +349,7 @@ int ff_vaapi_encode_close(AVCodecContext *avctx);
> #define VAAPI_ENCODE_RC_OPTIONS \
> { "rc_mode",\
> "Set rate control mode", \
> - OFFSET(common.explicit_rc_mode), AV_OPT_TYPE_INT, \
> + OFFSET(common.base.explicit_rc_mode), AV_OPT_TYPE_INT, \
> { .i64 = RC_MODE_AUTO }, RC_MODE_AUTO, RC_MODE_MAX, FLAGS, .unit =
> "rc_mode" }, \
> { "auto", "Choose mode automatically based on other parameters", \
> 0, AV_OPT_TYPE_CONST, { .i64 = RC_MODE_AUTO }, 0, 0, FLAGS, .unit =
> "rc_mode" }, \
> diff --git a/libavcodec/vaapi_encode_av1.c b/libavcodec/vaapi_encode_av1.c
> index a46b882ab9..512b4e3733 100644
> --- a/libavcodec/vaapi_encode_av1.c
> +++ b/libavcodec/vaapi_encode_av1.c
> @@ -109,20 +109,21 @@ static void vaapi_encode_av1_trace_write_log(void *ctx,
>
> static av_cold int vaapi_encode_av1_get_encoder_caps(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodeAV1Context *priv = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeAV1Context *priv = avctx->priv_data;
>
> // Surfaces must be aligned to superblock boundaries.
> - ctx->surface_width = FFALIGN(avctx->width, priv->use_128x128_superblock
> ? 128 : 64);
> - ctx->surface_height = FFALIGN(avctx->height, priv->use_128x128_superblock
> ? 128 : 64);
> + base_ctx->surface_width = FFALIGN(avctx->width, priv-
> >use_128x128_superblock ? 128 : 64);
> + base_ctx->surface_height = FFALIGN(avctx->height, priv-
> >use_128x128_superblock ? 128 : 64);
>
> return 0;
> }
>
> static av_cold int vaapi_encode_av1_configure(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodeAV1Context *priv = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodeAV1Context *priv = avctx->priv_data;
> int ret;
>
> ret = ff_cbs_init(&priv->cbc, AV_CODEC_ID_AV1, avctx);
> @@ -134,7 +135,7 @@ static av_cold int
> vaapi_encode_av1_configure(AVCodecContext *avctx)
> priv->cbc->trace_write_callback = vaapi_encode_av1_trace_write_log;
>
> if (ctx->rc_mode->quality) {
> - priv->q_idx_p = av_clip(ctx->rc_quality, 0, AV1_MAX_QUANT);
> + 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 =
> av_clip((fabs(avctx->i_quant_factor) * priv->q_idx_p +
> @@ -355,6 +356,7 @@ static int
> vaapi_encode_av1_write_sequence_header(AVCodecContext *avctx,
>
> static int vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAAPIEncodeAV1Context *priv = avctx->priv_data;
> AV1RawOBU *sh_obu = &priv->sh;
> @@ -367,7 +369,7 @@ static int
> vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx)
> memset(sh_obu, 0, sizeof(*sh_obu));
> sh_obu->header.obu_type = AV1_OBU_SEQUENCE_HEADER;
>
> - desc = av_pix_fmt_desc_get(priv->common.input_frames->sw_format);
> + desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format);
> av_assert0(desc);
>
> sh->seq_profile = avctx->profile;
> @@ -419,7 +421,7 @@ static int
> vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx)
> framerate = 0;
>
> level = ff_av1_guess_level(avctx->bit_rate, priv->tier,
> - ctx->surface_width, ctx->surface_height,
> + base_ctx->surface_width, base_ctx-
> >surface_height,
> priv->tile_rows * priv->tile_cols,
> priv->tile_cols, framerate);
> if (level) {
> @@ -436,8 +438,8 @@ static int
> vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx)
> vseq->seq_level_idx = sh->seq_level_idx[0];
> vseq->seq_tier = sh->seq_tier[0];
> vseq->order_hint_bits_minus_1 = sh->order_hint_bits_minus_1;
> - vseq->intra_period = ctx->gop_size;
> - vseq->ip_period = ctx->b_per_p + 1;
> + vseq->intra_period = base_ctx->gop_size;
> + vseq->ip_period = base_ctx->b_per_p + 1;
>
> vseq->seq_fields.bits.enable_order_hint = sh->enable_order_hint;
>
> @@ -464,12 +466,13 @@ static int
> vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
> {
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAAPIEncodeAV1Context *priv = avctx->priv_data;
> - VAAPIEncodeAV1Picture *hpic = pic->priv_data;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> + VAAPIEncodeAV1Picture *hpic = base_pic->priv_data;
> AV1RawOBU *fh_obu = &priv->fh;
> AV1RawFrameHeader *fh = &fh_obu->obu.frame.header;
> VAEncPictureParameterBufferAV1 *vpic = pic->codec_picture_params;
> CodedBitstreamFragment *obu = &priv->current_obu;
> - VAAPIEncodePicture *ref;
> + HWBaseEncodePicture *ref;
> VAAPIEncodeAV1Picture *href;
> int slot, i;
> int ret;
> @@ -478,24 +481,24 @@ static int
> vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
>
> memset(fh_obu, 0, sizeof(*fh_obu));
> pic->nb_slices = priv->tile_groups;
> - pic->non_independent_frame = pic->encode_order < pic->display_order;
> + pic->non_independent_frame = base_pic->encode_order < base_pic-
> >display_order;
> fh_obu->header.obu_type = AV1_OBU_FRAME_HEADER;
> fh_obu->header.obu_has_size_field = 1;
>
> - switch (pic->type) {
> + switch (base_pic->type) {
> case PICTURE_TYPE_IDR:
> - av_assert0(pic->nb_refs[0] == 0 || pic->nb_refs[1]);
> + av_assert0(base_pic->nb_refs[0] == 0 || base_pic->nb_refs[1]);
> fh->frame_type = AV1_FRAME_KEY;
> fh->refresh_frame_flags = 0xFF;
> fh->base_q_idx = priv->q_idx_idr;
> hpic->slot = 0;
> - hpic->last_idr_frame = pic->display_order;
> + hpic->last_idr_frame = base_pic->display_order;
> break;
> case PICTURE_TYPE_P:
> - av_assert0(pic->nb_refs[0]);
> + av_assert0(base_pic->nb_refs[0]);
> fh->frame_type = AV1_FRAME_INTER;
> fh->base_q_idx = priv->q_idx_p;
> - ref = pic->refs[0][pic->nb_refs[0] - 1];
> + ref = base_pic->refs[0][base_pic->nb_refs[0] - 1];
> href = ref->priv_data;
> hpic->slot = !href->slot;
> hpic->last_idr_frame = href->last_idr_frame;
> @@ -510,8 +513,8 @@ static int
> vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
> vpic->ref_frame_ctrl_l0.fields.search_idx0 = AV1_REF_FRAME_LAST;
>
> /** set the 2nd nearest frame in L0 as Golden frame. */
> - if (pic->nb_refs[0] > 1) {
> - ref = pic->refs[0][pic->nb_refs[0] - 2];
> + if (base_pic->nb_refs[0] > 1) {
> + ref = base_pic->refs[0][base_pic->nb_refs[0] - 2];
> href = ref->priv_data;
> fh->ref_frame_idx[3] = href->slot;
> fh->ref_order_hint[href->slot] = ref->display_order - href-
> >last_idr_frame;
> @@ -519,7 +522,7 @@ static int
> vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
> }
> break;
> case PICTURE_TYPE_B:
> - av_assert0(pic->nb_refs[0] && pic->nb_refs[1]);
> + av_assert0(base_pic->nb_refs[0] && base_pic->nb_refs[1]);
> fh->frame_type = AV1_FRAME_INTER;
> fh->base_q_idx = priv->q_idx_b;
> fh->refresh_frame_flags = 0x0;
> @@ -532,7 +535,7 @@ static int
> vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
> vpic->ref_frame_ctrl_l0.fields.search_idx0 = AV1_REF_FRAME_LAST;
> vpic->ref_frame_ctrl_l1.fields.search_idx0 = AV1_REF_FRAME_BWDREF;
>
> - ref = pic->refs[0][pic->nb_refs[0] - 1];
> + ref = base_pic->refs[0][base_pic-
> >nb_refs[0] - 1];
> href = ref->priv_data;
> hpic->last_idr_frame = href->last_idr_frame;
> fh->primary_ref_frame = href->slot;
> @@ -541,7 +544,7 @@ static int
> vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
> fh->ref_frame_idx[i] = href->slot;
> }
>
> - ref = pic->refs[1][pic->nb_refs[1] - 1];
> + ref = base_pic->refs[1][base_pic-
> >nb_refs[1] - 1];
> href = ref->priv_data;
> fh->ref_order_hint[href->slot] = ref->display_order - href-
> >last_idr_frame;
> for (i = AV1_REF_FRAME_GOLDEN; i < AV1_REFS_PER_FRAME; i++) {
> @@ -552,13 +555,13 @@ static int
> vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
> av_assert0(0 && "invalid picture type");
> }
>
> - fh->show_frame = pic->display_order <= pic->encode_order;
> + fh->show_frame = base_pic->display_order <= base_pic-
> >encode_order;
> fh->showable_frame = fh->frame_type != AV1_FRAME_KEY;
> fh->frame_width_minus_1 = avctx->width - 1;
> fh->frame_height_minus_1 = avctx->height - 1;
> fh->render_width_minus_1 = fh->frame_width_minus_1;
> fh->render_height_minus_1 = fh->frame_height_minus_1;
> - fh->order_hint = pic->display_order - hpic-
> >last_idr_frame;
> + fh->order_hint = base_pic->display_order - hpic-
> >last_idr_frame;
> fh->tile_cols = priv->tile_cols;
> fh->tile_rows = priv->tile_rows;
> fh->tile_cols_log2 = priv->tile_cols_log2;
> @@ -624,13 +627,13 @@ static int
> vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
> vpic->reference_frames[i] = VA_INVALID_SURFACE;
>
> for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
> - for (int j = 0; j < pic->nb_refs[i]; j++) {
> - VAAPIEncodePicture *ref_pic = pic->refs[i][j];
> + for (int j = 0; j < base_pic->nb_refs[i]; j++) {
> + HWBaseEncodePicture *ref_pic = base_pic->refs[i][j];
>
> slot = ((VAAPIEncodeAV1Picture*)ref_pic->priv_data)->slot;
> av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE);
>
> - vpic->reference_frames[slot] = ref_pic->recon_surface;
> + vpic->reference_frames[slot] = ((VAAPIEncodePicture *)ref_pic)-
> >recon_surface;
> }
> }
>
> @@ -651,7 +654,7 @@ static int
> vaapi_encode_av1_init_picture_params(AVCodecContext *avctx,
> vpic->bit_offset_cdef_params = priv->cdef_start_offset;
> vpic->size_in_bits_cdef_params = priv->cdef_param_size;
> vpic->size_in_bits_frame_hdr_obu = priv->fh_data_len;
> - vpic->byte_offset_frame_hdr_obu_size = (((pic->type ==
> PICTURE_TYPE_IDR) ?
> + vpic->byte_offset_frame_hdr_obu_size = (((base_pic->type ==
> PICTURE_TYPE_IDR) ?
> priv->sh_data_len / 8 : 0) +
> (fh_obu-
> >header.obu_extension_flag ?
> 2 : 1));
> @@ -693,14 +696,15 @@ static int
> vaapi_encode_av1_write_picture_header(AVCodecContext *avctx,
> CodedBitstreamAV1Context *cbctx = priv->cbc->priv_data;
> AV1RawOBU *fh_obu = &priv->fh;
> AV1RawFrameHeader *rep_fh = &fh_obu->obu.frame_header;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> VAAPIEncodeAV1Picture *href;
> int ret = 0;
>
> pic->tail_size = 0;
> /** Pack repeat frame header. */
> - if (pic->display_order > pic->encode_order) {
> + if (base_pic->display_order > base_pic->encode_order) {
> memset(fh_obu, 0, sizeof(*fh_obu));
> - href = pic->refs[0][pic->nb_refs[0] - 1]->priv_data;
> + href = base_pic->refs[0][base_pic->nb_refs[0] - 1]->priv_data;
> fh_obu->header.obu_type = AV1_OBU_FRAME_HEADER;
> fh_obu->header.obu_has_size_field = 1;
>
> @@ -862,6 +866,7 @@ static av_cold int vaapi_encode_av1_close(AVCodecContext
> *avctx)
> #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
>
> static const AVOption vaapi_encode_av1_options[] = {
> + HW_BASE_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_RC_OPTIONS,
> { "profile", "Set profile (seq_profile)",
> diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
> index 37df9103ae..aa011ba307 100644
> --- a/libavcodec/vaapi_encode_h264.c
> +++ b/libavcodec/vaapi_encode_h264.c
> @@ -234,7 +234,7 @@ static int
> vaapi_encode_h264_write_extra_header(AVCodecContext *avctx,
> goto fail;
> }
> if (priv->sei_needed & SEI_TIMING) {
> - if (pic->type == PICTURE_TYPE_IDR) {
> + if (pic->base.type == PICTURE_TYPE_IDR) {
> err = ff_cbs_sei_add_message(priv->cbc, au, 1,
> SEI_TYPE_BUFFERING_PERIOD,
> &priv->sei_buffering_period,
> NULL);
> @@ -296,6 +296,7 @@ fail:
>
> static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAAPIEncodeH264Context *priv = avctx->priv_data;
> H264RawSPS *sps = &priv->raw_sps;
> @@ -308,7 +309,7 @@ static int
> vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
> memset(sps, 0, sizeof(*sps));
> memset(pps, 0, sizeof(*pps));
>
> - desc = av_pix_fmt_desc_get(priv->common.input_frames->sw_format);
> + desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format);
> av_assert0(desc);
> if (desc->nb_components == 1 || desc->log2_chroma_w != 1 || desc-
> >log2_chroma_h != 1) {
> av_log(avctx, AV_LOG_ERROR, "Chroma format of input pixel format "
> @@ -327,18 +328,18 @@ static int
> vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
> sps->constraint_set1_flag = 1;
>
> if (avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile ==
> AV_PROFILE_H264_HIGH_10)
> - sps->constraint_set3_flag = ctx->gop_size == 1;
> + sps->constraint_set3_flag = base_ctx->gop_size == 1;
>
> if (avctx->profile == AV_PROFILE_H264_MAIN ||
> avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile ==
> AV_PROFILE_H264_HIGH_10) {
> sps->constraint_set4_flag = 1;
> - sps->constraint_set5_flag = ctx->b_per_p == 0;
> + sps->constraint_set5_flag = base_ctx->b_per_p == 0;
> }
>
> - if (ctx->gop_size == 1)
> + if (base_ctx->gop_size == 1)
> priv->dpb_frames = 0;
> else
> - priv->dpb_frames = 1 + ctx->max_b_depth;
> + priv->dpb_frames = 1 + base_ctx->max_b_depth;
>
> if (avctx->level != AV_LEVEL_UNKNOWN) {
> sps->level_idc = avctx->level;
> @@ -375,7 +376,7 @@ static int
> vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
> sps->bit_depth_chroma_minus8 = bit_depth - 8;
>
> sps->log2_max_frame_num_minus4 = 4;
> - sps->pic_order_cnt_type = ctx->max_b_depth ? 0 : 2;
> + sps->pic_order_cnt_type = base_ctx->max_b_depth ? 0 : 2;
> if (sps->pic_order_cnt_type == 0) {
> sps->log2_max_pic_order_cnt_lsb_minus4 = 4;
> }
> @@ -502,8 +503,8 @@ static int
> vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
> sps->vui.motion_vectors_over_pic_boundaries_flag = 1;
> sps->vui.log2_max_mv_length_horizontal = 15;
> sps->vui.log2_max_mv_length_vertical = 15;
> - sps->vui.max_num_reorder_frames = ctx->max_b_depth;
> - sps->vui.max_dec_frame_buffering = ctx->max_b_depth + 1;
> + sps->vui.max_num_reorder_frames = base_ctx->max_b_depth;
> + sps->vui.max_dec_frame_buffering = base_ctx->max_b_depth + 1;
>
> pps->nal_unit_header.nal_ref_idc = 3;
> pps->nal_unit_header.nal_unit_type = H264_NAL_PPS;
> @@ -536,9 +537,9 @@ static int
> vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
> *vseq = (VAEncSequenceParameterBufferH264) {
> .seq_parameter_set_id = sps->seq_parameter_set_id,
> .level_idc = sps->level_idc,
> - .intra_period = ctx->gop_size,
> - .intra_idr_period = ctx->gop_size,
> - .ip_period = ctx->b_per_p + 1,
> + .intra_period = base_ctx->gop_size,
> + .intra_idr_period = base_ctx->gop_size,
> + .ip_period = base_ctx->b_per_p + 1,
>
> .bits_per_second = ctx->va_bit_rate,
> .max_num_ref_frames = sps->max_num_ref_frames,
> @@ -622,19 +623,20 @@ static int
> vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)
> static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
> VAAPIEncodePicture *pic)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeH264Context *priv = avctx->priv_data;
> - VAAPIEncodeH264Picture *hpic = pic->priv_data;
> - VAAPIEncodePicture *prev = pic->prev;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> + VAAPIEncodeH264Picture *hpic = base_pic->priv_data;
> + HWBaseEncodePicture *prev = base_pic->prev;
> VAAPIEncodeH264Picture *hprev = prev ? prev->priv_data : NULL;
> VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params;
> int i, j = 0;
>
> - if (pic->type == PICTURE_TYPE_IDR) {
> - av_assert0(pic->display_order == pic->encode_order);
> + if (base_pic->type == PICTURE_TYPE_IDR) {
> + av_assert0(base_pic->display_order == base_pic->encode_order);
>
> hpic->frame_num = 0;
> - hpic->last_idr_frame = pic->display_order;
> + hpic->last_idr_frame = base_pic->display_order;
> hpic->idr_pic_id = hprev ? hprev->idr_pic_id + 1 : 0;
>
> hpic->primary_pic_type = 0;
> @@ -647,10 +649,10 @@ static int
> vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
> hpic->last_idr_frame = hprev->last_idr_frame;
> hpic->idr_pic_id = hprev->idr_pic_id;
>
> - if (pic->type == PICTURE_TYPE_I) {
> + if (base_pic->type == PICTURE_TYPE_I) {
> hpic->slice_type = 7;
> hpic->primary_pic_type = 0;
> - } else if (pic->type == PICTURE_TYPE_P) {
> + } else if (base_pic->type == PICTURE_TYPE_P) {
> hpic->slice_type = 5;
> hpic->primary_pic_type = 1;
> } else {
> @@ -658,13 +660,13 @@ static int
> vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
> hpic->primary_pic_type = 2;
> }
> }
> - hpic->pic_order_cnt = pic->display_order - hpic->last_idr_frame;
> + hpic->pic_order_cnt = base_pic->display_order - hpic->last_idr_frame;
> if (priv->raw_sps.pic_order_cnt_type == 2) {
> hpic->pic_order_cnt *= 2;
> }
>
> - hpic->dpb_delay = pic->display_order - pic->encode_order + ctx-
> >max_b_depth;
> - hpic->cpb_delay = pic->encode_order - hpic->last_idr_frame;
> + hpic->dpb_delay = base_pic->display_order - base_pic->encode_order +
> base_ctx->max_b_depth;
> + hpic->cpb_delay = base_pic->encode_order - hpic->last_idr_frame;
>
> if (priv->aud) {
> priv->aud_needed = 1;
> @@ -680,7 +682,7 @@ static int
> vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
>
> priv->sei_needed = 0;
>
> - if (priv->sei & SEI_IDENTIFIER && pic->encode_order == 0)
> + if (priv->sei & SEI_IDENTIFIER && base_pic->encode_order == 0)
> priv->sei_needed |= SEI_IDENTIFIER;
> #if !CONFIG_VAAPI_1
> if (ctx->va_rc_mode == VA_RC_CBR)
> @@ -696,11 +698,11 @@ static int
> vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
> priv->sei_needed |= SEI_TIMING;
> }
>
> - if (priv->sei & SEI_RECOVERY_POINT && pic->type == PICTURE_TYPE_I) {
> + if (priv->sei & SEI_RECOVERY_POINT && base_pic->type == PICTURE_TYPE_I) {
> priv->sei_recovery_point = (H264RawSEIRecoveryPoint) {
> .recovery_frame_cnt = 0,
> .exact_match_flag = 1,
> - .broken_link_flag = ctx->b_per_p > 0,
> + .broken_link_flag = base_ctx->b_per_p > 0,
> };
>
> priv->sei_needed |= SEI_RECOVERY_POINT;
> @@ -710,7 +712,7 @@ static int
> vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
> int err;
> size_t sei_a53cc_len;
> av_freep(&priv->sei_a53cc_data);
> - err = ff_alloc_a53_sei(pic->input_image, 0, &priv->sei_a53cc_data,
> &sei_a53cc_len);
> + err = ff_alloc_a53_sei(base_pic->input_image, 0, &priv-
> >sei_a53cc_data, &sei_a53cc_len);
> if (err < 0)
> return err;
> if (priv->sei_a53cc_data != NULL) {
> @@ -730,15 +732,15 @@ static int
> vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
> .BottomFieldOrderCnt = hpic->pic_order_cnt,
> };
> for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) {
> - for (i = 0; i < pic->nb_refs[k]; i++) {
> - VAAPIEncodePicture *ref = pic->refs[k][i];
> + for (i = 0; i < base_pic->nb_refs[k]; i++) {
> + HWBaseEncodePicture *ref = base_pic->refs[k][i];
> VAAPIEncodeH264Picture *href;
>
> - av_assert0(ref && ref->encode_order < pic->encode_order);
> + av_assert0(ref && ref->encode_order < base_pic->encode_order);
> href = ref->priv_data;
>
> vpic->ReferenceFrames[j++] = (VAPictureH264) {
> - .picture_id = ref->recon_surface,
> + .picture_id = ((VAAPIEncodePicture *)ref)-
> >recon_surface,
> .frame_idx = href->frame_num,
> .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE,
> .TopFieldOrderCnt = href->pic_order_cnt,
> @@ -758,8 +760,8 @@ static int
> vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
>
> vpic->frame_num = hpic->frame_num;
>
> - vpic->pic_fields.bits.idr_pic_flag = (pic->type ==
> PICTURE_TYPE_IDR);
> - vpic->pic_fields.bits.reference_pic_flag = (pic->type != PICTURE_TYPE_B);
> + vpic->pic_fields.bits.idr_pic_flag = (base_pic->type ==
> PICTURE_TYPE_IDR);
> + vpic->pic_fields.bits.reference_pic_flag = (base_pic->type !=
> PICTURE_TYPE_B);
>
> return 0;
> }
> @@ -770,31 +772,32 @@ static void
> vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx,
> VAAPIEncodePicture **rpl1,
> int *rpl_size)
> {
> - VAAPIEncodePicture *prev;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> + HWBaseEncodePicture *prev;
> VAAPIEncodeH264Picture *hp, *hn, *hc;
> int i, j, n = 0;
>
> - prev = pic->prev;
> + prev = base_pic->prev;
> av_assert0(prev);
> - hp = pic->priv_data;
> + hp = base_pic->priv_data;
>
> - for (i = 0; i < pic->prev->nb_dpb_pics; i++) {
> + for (i = 0; i < base_pic->prev->nb_dpb_pics; i++) {
> hn = prev->dpb[i]->priv_data;
> av_assert0(hn->frame_num < hp->frame_num);
>
> - if (pic->type == PICTURE_TYPE_P) {
> + if (base_pic->type == PICTURE_TYPE_P) {
> for (j = n; j > 0; j--) {
> - hc = rpl0[j - 1]->priv_data;
> + hc = rpl0[j - 1]->base.priv_data;
> av_assert0(hc->frame_num != hn->frame_num);
> if (hc->frame_num > hn->frame_num)
> break;
> rpl0[j] = rpl0[j - 1];
> }
> - rpl0[j] = prev->dpb[i];
> + rpl0[j] = (VAAPIEncodePicture *)prev->dpb[i];
>
> - } else if (pic->type == PICTURE_TYPE_B) {
> + } else if (base_pic->type == PICTURE_TYPE_B) {
> for (j = n; j > 0; j--) {
> - hc = rpl0[j - 1]->priv_data;
> + hc = rpl0[j - 1]->base.priv_data;
> av_assert0(hc->pic_order_cnt != hp->pic_order_cnt);
> if (hc->pic_order_cnt < hp->pic_order_cnt) {
> if (hn->pic_order_cnt > hp->pic_order_cnt ||
> @@ -806,10 +809,10 @@ static void
> vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx,
> }
> rpl0[j] = rpl0[j - 1];
> }
> - rpl0[j] = prev->dpb[i];
> + rpl0[j] = (VAAPIEncodePicture *)prev->dpb[i];
>
> for (j = n; j > 0; j--) {
> - hc = rpl1[j - 1]->priv_data;
> + hc = rpl1[j - 1]->base.priv_data;
> av_assert0(hc->pic_order_cnt != hp->pic_order_cnt);
> if (hc->pic_order_cnt > hp->pic_order_cnt) {
> if (hn->pic_order_cnt < hp->pic_order_cnt ||
> @@ -821,13 +824,13 @@ static void
> vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx,
> }
> rpl1[j] = rpl1[j - 1];
> }
> - rpl1[j] = prev->dpb[i];
> + rpl1[j] = (VAAPIEncodePicture *)prev->dpb[i];
> }
>
> ++n;
> }
>
> - if (pic->type == PICTURE_TYPE_B) {
> + if (base_pic->type == PICTURE_TYPE_B) {
> for (i = 0; i < n; i++) {
> if (rpl0[i] != rpl1[i])
> break;
> @@ -836,22 +839,22 @@ static void
> vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx,
> FFSWAP(VAAPIEncodePicture*, rpl1[0], rpl1[1]);
> }
>
> - if (pic->type == PICTURE_TYPE_P ||
> - pic->type == PICTURE_TYPE_B) {
> + if (base_pic->type == PICTURE_TYPE_P ||
> + base_pic->type == PICTURE_TYPE_B) {
> av_log(avctx, AV_LOG_DEBUG, "Default RefPicList0 for fn=%d/poc=%d:",
> hp->frame_num, hp->pic_order_cnt);
> for (i = 0; i < n; i++) {
> - hn = rpl0[i]->priv_data;
> + hn = rpl0[i]->base.priv_data;
> av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d",
> hn->frame_num, hn->pic_order_cnt);
> }
> av_log(avctx, AV_LOG_DEBUG, "\n");
> }
> - if (pic->type == PICTURE_TYPE_B) {
> + if (base_pic->type == PICTURE_TYPE_B) {
> av_log(avctx, AV_LOG_DEBUG, "Default RefPicList1 for fn=%d/poc=%d:",
> hp->frame_num, hp->pic_order_cnt);
> for (i = 0; i < n; i++) {
> - hn = rpl1[i]->priv_data;
> + hn = rpl1[i]->base.priv_data;
> av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d",
> hn->frame_num, hn->pic_order_cnt);
> }
> @@ -866,8 +869,9 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
> VAAPIEncodeSlice *slice)
> {
> VAAPIEncodeH264Context *priv = avctx->priv_data;
> - VAAPIEncodeH264Picture *hpic = pic->priv_data;
> - VAAPIEncodePicture *prev = pic->prev;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> + VAAPIEncodeH264Picture *hpic = base_pic->priv_data;
> + HWBaseEncodePicture *prev = base_pic->prev;
> H264RawSPS *sps = &priv->raw_sps;
> H264RawPPS *pps = &priv->raw_pps;
> H264RawSliceHeader *sh = &priv->raw_slice.header;
> @@ -875,12 +879,12 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
> VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params;
> int i, j;
>
> - if (pic->type == PICTURE_TYPE_IDR) {
> + if (base_pic->type == PICTURE_TYPE_IDR) {
> sh->nal_unit_header.nal_unit_type = H264_NAL_IDR_SLICE;
> sh->nal_unit_header.nal_ref_idc = 3;
> } else {
> sh->nal_unit_header.nal_unit_type = H264_NAL_SLICE;
> - sh->nal_unit_header.nal_ref_idc = pic->is_reference;
> + sh->nal_unit_header.nal_ref_idc = base_pic->is_reference;
> }
>
> sh->first_mb_in_slice = slice->block_start;
> @@ -896,25 +900,25 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
>
> sh->direct_spatial_mv_pred_flag = 1;
>
> - if (pic->type == PICTURE_TYPE_B)
> + if (base_pic->type == PICTURE_TYPE_B)
> sh->slice_qp_delta = priv->fixed_qp_b - (pps->pic_init_qp_minus26 +
> 26);
> - else if (pic->type == PICTURE_TYPE_P)
> + else if (base_pic->type == PICTURE_TYPE_P)
> sh->slice_qp_delta = priv->fixed_qp_p - (pps->pic_init_qp_minus26 +
> 26);
> else
> sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 +
> 26);
>
> - if (pic->is_reference && pic->type != PICTURE_TYPE_IDR) {
> - VAAPIEncodePicture *discard_list[MAX_DPB_SIZE];
> + if (base_pic->is_reference && base_pic->type != PICTURE_TYPE_IDR) {
> + HWBaseEncodePicture *discard_list[MAX_DPB_SIZE];
> int discard = 0, keep = 0;
>
> // Discard everything which is in the DPB of the previous frame but
> // not in the DPB of this one.
> for (i = 0; i < prev->nb_dpb_pics; i++) {
> - for (j = 0; j < pic->nb_dpb_pics; j++) {
> - if (prev->dpb[i] == pic->dpb[j])
> + for (j = 0; j < base_pic->nb_dpb_pics; j++) {
> + if (prev->dpb[i] == base_pic->dpb[j])
> break;
> }
> - if (j == pic->nb_dpb_pics) {
> + if (j == base_pic->nb_dpb_pics) {
> discard_list[discard] = prev->dpb[i];
> ++discard;
> } else {
> @@ -940,7 +944,7 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
>
> // If the intended references are not the first entries of RefPicListN
> // by default, use ref-pic-list-modification to move them there.
> - if (pic->type == PICTURE_TYPE_P || pic->type == PICTURE_TYPE_B) {
> + if (base_pic->type == PICTURE_TYPE_P || base_pic->type == PICTURE_TYPE_B)
> {
> VAAPIEncodePicture *def_l0[MAX_DPB_SIZE], *def_l1[MAX_DPB_SIZE];
> VAAPIEncodeH264Picture *href;
> int n;
> @@ -948,19 +952,19 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
> vaapi_encode_h264_default_ref_pic_list(avctx, pic,
> def_l0, def_l1, &n);
>
> - if (pic->type == PICTURE_TYPE_P) {
> + if (base_pic->type == PICTURE_TYPE_P) {
> int need_rplm = 0;
> - for (i = 0; i < pic->nb_refs[0]; i++) {
> - av_assert0(pic->refs[0][i]);
> - if (pic->refs[0][i] != def_l0[i])
> + for (i = 0; i < base_pic->nb_refs[0]; i++) {
> + av_assert0(base_pic->refs[0][i]);
> + if (base_pic->refs[0][i] != (HWBaseEncodePicture *)def_l0[i])
> need_rplm = 1;
> }
>
> sh->ref_pic_list_modification_flag_l0 = need_rplm;
> if (need_rplm) {
> int pic_num = hpic->frame_num;
> - for (i = 0; i < pic->nb_refs[0]; i++) {
> - href = pic->refs[0][i]->priv_data;
> + for (i = 0; i < base_pic->nb_refs[0]; i++) {
> + href = base_pic->refs[0][i]->priv_data;
> av_assert0(href->frame_num != pic_num);
> if (href->frame_num < pic_num) {
> sh->rplm_l0[i].modification_of_pic_nums_idc = 0;
> @@ -979,20 +983,20 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
> } else {
> int need_rplm_l0 = 0, need_rplm_l1 = 0;
> int n0 = 0, n1 = 0;
> - for (i = 0; i < pic->nb_refs[0]; i++) {
> - av_assert0(pic->refs[0][i]);
> - href = pic->refs[0][i]->priv_data;
> + for (i = 0; i < base_pic->nb_refs[0]; i++) {
> + av_assert0(base_pic->refs[0][i]);
> + href = base_pic->refs[0][i]->priv_data;
> av_assert0(href->pic_order_cnt < hpic->pic_order_cnt);
> - if (pic->refs[0][i] != def_l0[n0])
> + if (base_pic->refs[0][i] != (HWBaseEncodePicture
> *)def_l0[n0])
> need_rplm_l0 = 1;
> ++n0;
> }
>
> - for (i = 0; i < pic->nb_refs[1]; i++) {
> - av_assert0(pic->refs[1][i]);
> - href = pic->refs[1][i]->priv_data;
> + for (i = 0; i < base_pic->nb_refs[1]; i++) {
> + av_assert0(base_pic->refs[1][i]);
> + href = base_pic->refs[1][i]->priv_data;
> av_assert0(href->pic_order_cnt > hpic->pic_order_cnt);
> - if (pic->refs[1][i] != def_l1[n1])
> + if (base_pic->refs[1][i] != (HWBaseEncodePicture
> *)def_l1[n1])
> need_rplm_l1 = 1;
> ++n1;
> }
> @@ -1000,8 +1004,8 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
> sh->ref_pic_list_modification_flag_l0 = need_rplm_l0;
> if (need_rplm_l0) {
> int pic_num = hpic->frame_num;
> - for (i = j = 0; i < pic->nb_refs[0]; i++) {
> - href = pic->refs[0][i]->priv_data;
> + for (i = j = 0; i < base_pic->nb_refs[0]; i++) {
> + href = base_pic->refs[0][i]->priv_data;
> av_assert0(href->frame_num != pic_num);
> if (href->frame_num < pic_num) {
> sh->rplm_l0[j].modification_of_pic_nums_idc = 0;
> @@ -1022,8 +1026,8 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
> sh->ref_pic_list_modification_flag_l1 = need_rplm_l1;
> if (need_rplm_l1) {
> int pic_num = hpic->frame_num;
> - for (i = j = 0; i < pic->nb_refs[1]; i++) {
> - href = pic->refs[1][i]->priv_data;
> + for (i = j = 0; i < base_pic->nb_refs[1]; i++) {
> + href = base_pic->refs[1][i]->priv_data;
> av_assert0(href->frame_num != pic_num);
> if (href->frame_num < pic_num) {
> sh->rplm_l1[j].modification_of_pic_nums_idc = 0;
> @@ -1063,15 +1067,15 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
> vslice->RefPicList1[i].flags = VA_PICTURE_H264_INVALID;
> }
>
> - if (pic->nb_refs[0]) {
> + if (base_pic->nb_refs[0]) {
> // Backward reference for P- or B-frame.
> - av_assert0(pic->type == PICTURE_TYPE_P ||
> - pic->type == PICTURE_TYPE_B);
> + av_assert0(base_pic->type == PICTURE_TYPE_P ||
> + base_pic->type == PICTURE_TYPE_B);
> vslice->RefPicList0[0] = vpic->ReferenceFrames[0];
> }
> - if (pic->nb_refs[1]) {
> + if (base_pic->nb_refs[1]) {
> // Forward reference for B-frame.
> - av_assert0(pic->type == PICTURE_TYPE_B);
> + av_assert0(base_pic->type == PICTURE_TYPE_B);
> vslice->RefPicList1[0] = vpic->ReferenceFrames[1];
> }
>
> @@ -1082,8 +1086,9 @@ static int
> vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
>
> static av_cold int vaapi_encode_h264_configure(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodeH264Context *priv = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodeH264Context *priv = avctx->priv_data;
> int err;
>
> err = ff_cbs_init(&priv->cbc, AV_CODEC_ID_H264, avctx);
> @@ -1094,7 +1099,7 @@ static av_cold int
> vaapi_encode_h264_configure(AVCodecContext *avctx)
> priv->mb_height = FFALIGN(avctx->height, 16) / 16;
>
> if (ctx->va_rc_mode == VA_RC_CQP) {
> - priv->fixed_qp_p = av_clip(ctx->rc_quality, 1, 51);
> + priv->fixed_qp_p = av_clip(base_ctx->rc_quality, 1, 51);
> if (avctx->i_quant_factor > 0.0)
> priv->fixed_qp_idr =
> av_clip((avctx->i_quant_factor * priv->fixed_qp_p +
> @@ -1202,8 +1207,9 @@ static const VAAPIEncodeType vaapi_encode_type_h264 = {
>
> static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodeH264Context *priv = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodeH264Context *priv = avctx->priv_data;
>
> ctx->codec = &vaapi_encode_type_h264;
>
> @@ -1251,13 +1257,13 @@ static av_cold int
> vaapi_encode_h264_init(AVCodecContext *avctx)
> VA_ENC_PACKED_HEADER_SLICE | // Slice headers.
> VA_ENC_PACKED_HEADER_MISC; // SEI.
>
> - ctx->surface_width = FFALIGN(avctx->width, 16);
> - ctx->surface_height = FFALIGN(avctx->height, 16);
> + base_ctx->surface_width = FFALIGN(avctx->width, 16);
> + base_ctx->surface_height = FFALIGN(avctx->height, 16);
>
> - ctx->slice_block_height = ctx->slice_block_width = 16;
> + base_ctx->slice_block_height = base_ctx->slice_block_width = 16;
>
> if (priv->qp > 0)
> - ctx->explicit_qp = priv->qp;
> + base_ctx->explicit_qp = priv->qp;
>
> return ff_vaapi_encode_init(avctx);
> }
> @@ -1277,6 +1283,7 @@ static av_cold int
> vaapi_encode_h264_close(AVCodecContext *avctx)
> #define OFFSET(x) offsetof(VAAPIEncodeH264Context, x)
> #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
> static const AVOption vaapi_encode_h264_options[] = {
> + HW_BASE_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_RC_OPTIONS,
>
> diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
> index c4aabbf5ed..4f5d8fc76f 100644
> --- a/libavcodec/vaapi_encode_h265.c
> +++ b/libavcodec/vaapi_encode_h265.c
> @@ -260,6 +260,7 @@ fail:
>
> static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAAPIEncodeH265Context *priv = avctx->priv_data;
> H265RawVPS *vps = &priv->raw_vps;
> @@ -278,7 +279,7 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> memset(pps, 0, sizeof(*pps));
>
>
> - desc = av_pix_fmt_desc_get(priv->common.input_frames->sw_format);
> + desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format);
> av_assert0(desc);
> if (desc->nb_components == 1) {
> chroma_format = 0;
> @@ -341,7 +342,7 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> ptl->general_max_420chroma_constraint_flag = chroma_format <= 1;
> ptl->general_max_monochrome_constraint_flag = chroma_format == 0;
>
> - ptl->general_intra_constraint_flag = ctx->gop_size == 1;
> + ptl->general_intra_constraint_flag = base_ctx->gop_size == 1;
> ptl->general_one_picture_only_constraint_flag = 0;
>
> ptl->general_lower_bit_rate_constraint_flag = 1;
> @@ -352,9 +353,9 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> const H265LevelDescriptor *level;
>
> level = ff_h265_guess_level(ptl, avctx->bit_rate,
> - ctx->surface_width, ctx->surface_height,
> + base_ctx->surface_width, base_ctx-
> >surface_height,
> ctx->nb_slices, ctx->tile_rows, ctx-
> >tile_cols,
> - (ctx->b_per_p > 0) + 1);
> + (base_ctx->b_per_p > 0) + 1);
> if (level) {
> av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
> ptl->general_level_idc = level->level_idc;
> @@ -368,8 +369,8 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> }
>
> vps->vps_sub_layer_ordering_info_present_flag = 0;
> - vps->vps_max_dec_pic_buffering_minus1[0] = ctx->max_b_depth + 1;
> - vps->vps_max_num_reorder_pics[0] = ctx->max_b_depth;
> + vps->vps_max_dec_pic_buffering_minus1[0] = base_ctx->max_b_depth +
> 1;
> + vps->vps_max_num_reorder_pics[0] = base_ctx->max_b_depth;
> vps->vps_max_latency_increase_plus1[0] = 0;
>
> vps->vps_max_layer_id = 0;
> @@ -410,18 +411,18 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> sps->chroma_format_idc = chroma_format;
> sps->separate_colour_plane_flag = 0;
>
> - sps->pic_width_in_luma_samples = ctx->surface_width;
> - sps->pic_height_in_luma_samples = ctx->surface_height;
> + sps->pic_width_in_luma_samples = base_ctx->surface_width;
> + sps->pic_height_in_luma_samples = base_ctx->surface_height;
>
> - if (avctx->width != ctx->surface_width ||
> - avctx->height != ctx->surface_height) {
> + if (avctx->width != base_ctx->surface_width ||
> + avctx->height != base_ctx->surface_height) {
> sps->conformance_window_flag = 1;
> sps->conf_win_left_offset = 0;
> sps->conf_win_right_offset =
> - (ctx->surface_width - avctx->width) >> desc->log2_chroma_w;
> + (base_ctx->surface_width - avctx->width) >> desc->log2_chroma_w;
> sps->conf_win_top_offset = 0;
> sps->conf_win_bottom_offset =
> - (ctx->surface_height - avctx->height) >> desc->log2_chroma_h;
> + (base_ctx->surface_height - avctx->height) >> desc-
> >log2_chroma_h;
> } else {
> sps->conformance_window_flag = 0;
> }
> @@ -643,9 +644,9 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> .general_level_idc = vps->profile_tier_level.general_level_idc,
> .general_tier_flag = vps->profile_tier_level.general_tier_flag,
>
> - .intra_period = ctx->gop_size,
> - .intra_idr_period = ctx->gop_size,
> - .ip_period = ctx->b_per_p + 1,
> + .intra_period = base_ctx->gop_size,
> + .intra_idr_period = base_ctx->gop_size,
> + .ip_period = base_ctx->b_per_p + 1,
> .bits_per_second = ctx->va_bit_rate,
>
> .pic_width_in_luma_samples = sps->pic_width_in_luma_samples,
> @@ -758,18 +759,19 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
> VAAPIEncodePicture *pic)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeH265Context *priv = avctx->priv_data;
> - VAAPIEncodeH265Picture *hpic = pic->priv_data;
> - VAAPIEncodePicture *prev = pic->prev;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> + VAAPIEncodeH265Picture *hpic = base_pic->priv_data;
> + HWBaseEncodePicture *prev = base_pic->prev;
> VAAPIEncodeH265Picture *hprev = prev ? prev->priv_data : NULL;
> VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params;
> int i, j = 0;
>
> - if (pic->type == PICTURE_TYPE_IDR) {
> - av_assert0(pic->display_order == pic->encode_order);
> + if (base_pic->type == PICTURE_TYPE_IDR) {
> + av_assert0(base_pic->display_order == base_pic->encode_order);
>
> - hpic->last_idr_frame = pic->display_order;
> + hpic->last_idr_frame = base_pic->display_order;
>
> hpic->slice_nal_unit = HEVC_NAL_IDR_W_RADL;
> hpic->slice_type = HEVC_SLICE_I;
> @@ -778,23 +780,23 @@ static int
> vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
> av_assert0(prev);
> hpic->last_idr_frame = hprev->last_idr_frame;
>
> - if (pic->type == PICTURE_TYPE_I) {
> + if (base_pic->type == PICTURE_TYPE_I) {
> hpic->slice_nal_unit = HEVC_NAL_CRA_NUT;
> hpic->slice_type = HEVC_SLICE_I;
> hpic->pic_type = 0;
> - } else if (pic->type == PICTURE_TYPE_P) {
> - av_assert0(pic->refs[0]);
> + } else if (base_pic->type == PICTURE_TYPE_P) {
> + av_assert0(base_pic->refs[0]);
> hpic->slice_nal_unit = HEVC_NAL_TRAIL_R;
> hpic->slice_type = HEVC_SLICE_P;
> hpic->pic_type = 1;
> } else {
> - VAAPIEncodePicture *irap_ref;
> - av_assert0(pic->refs[0][0] && pic->refs[1][0]);
> - for (irap_ref = pic; irap_ref; irap_ref = irap_ref->refs[1][0]) {
> + HWBaseEncodePicture *irap_ref;
> + av_assert0(base_pic->refs[0][0] && base_pic->refs[1][0]);
> + for (irap_ref = base_pic; irap_ref; irap_ref = irap_ref-
> >refs[1][0]) {
> if (irap_ref->type == PICTURE_TYPE_I)
> break;
> }
> - if (pic->b_depth == ctx->max_b_depth) {
> + if (base_pic->b_depth == base_ctx->max_b_depth) {
> hpic->slice_nal_unit = irap_ref ? HEVC_NAL_RASL_N
> : HEVC_NAL_TRAIL_N;
> } else {
> @@ -805,7 +807,7 @@ static int
> vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
> hpic->pic_type = 2;
> }
> }
> - hpic->pic_order_cnt = pic->display_order - hpic->last_idr_frame;
> + hpic->pic_order_cnt = base_pic->display_order - hpic->last_idr_frame;
>
> if (priv->aud) {
> priv->aud_needed = 1;
> @@ -827,9 +829,9 @@ static int
> vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
> // may force an IDR frame on the output where the medadata gets
> // changed on the input frame.
> if ((priv->sei & SEI_MASTERING_DISPLAY) &&
> - (pic->type == PICTURE_TYPE_I || pic->type == PICTURE_TYPE_IDR)) {
> + (base_pic->type == PICTURE_TYPE_I || base_pic->type ==
> PICTURE_TYPE_IDR)) {
> AVFrameSideData *sd =
> - av_frame_get_side_data(pic->input_image,
> + av_frame_get_side_data(base_pic->input_image,
> AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
>
> if (sd) {
> @@ -875,9 +877,9 @@ static int
> vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
> }
>
> if ((priv->sei & SEI_CONTENT_LIGHT_LEVEL) &&
> - (pic->type == PICTURE_TYPE_I || pic->type == PICTURE_TYPE_IDR)) {
> + (base_pic->type == PICTURE_TYPE_I || base_pic->type ==
> PICTURE_TYPE_IDR)) {
> AVFrameSideData *sd =
> - av_frame_get_side_data(pic->input_image,
> + av_frame_get_side_data(base_pic->input_image,
> AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
>
> if (sd) {
> @@ -897,7 +899,7 @@ static int
> vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
> int err;
> size_t sei_a53cc_len;
> av_freep(&priv->sei_a53cc_data);
> - err = ff_alloc_a53_sei(pic->input_image, 0, &priv->sei_a53cc_data,
> &sei_a53cc_len);
> + err = ff_alloc_a53_sei(base_pic->input_image, 0, &priv-
> >sei_a53cc_data, &sei_a53cc_len);
> if (err < 0)
> return err;
> if (priv->sei_a53cc_data != NULL) {
> @@ -916,19 +918,19 @@ static int
> vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
> };
>
> for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) {
> - for (i = 0; i < pic->nb_refs[k]; i++) {
> - VAAPIEncodePicture *ref = pic->refs[k][i];
> + for (i = 0; i < base_pic->nb_refs[k]; i++) {
> + HWBaseEncodePicture *ref = base_pic->refs[k][i];
> VAAPIEncodeH265Picture *href;
>
> - av_assert0(ref && ref->encode_order < pic->encode_order);
> + av_assert0(ref && ref->encode_order < base_pic->encode_order);
> href = ref->priv_data;
>
> vpic->reference_frames[j++] = (VAPictureHEVC) {
> - .picture_id = ref->recon_surface,
> + .picture_id = ((VAAPIEncodePicture *)ref)->recon_surface,
> .pic_order_cnt = href->pic_order_cnt,
> - .flags = (ref->display_order < pic->display_order ?
> + .flags = (ref->display_order < base_pic->display_order ?
> VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) |
> - (ref->display_order > pic->display_order ?
> + (ref->display_order > base_pic->display_order ?
> VA_PICTURE_HEVC_RPS_ST_CURR_AFTER : 0),
> };
> }
> @@ -945,7 +947,7 @@ static int
> vaapi_encode_h265_init_picture_params(AVCodecContext *avctx,
>
> vpic->nal_unit_type = hpic->slice_nal_unit;
>
> - switch (pic->type) {
> + switch (base_pic->type) {
> case PICTURE_TYPE_IDR:
> vpic->pic_fields.bits.idr_pic_flag = 1;
> vpic->pic_fields.bits.coding_type = 1;
> @@ -977,9 +979,10 @@ static int
> vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
> VAAPIEncodePicture *pic,
> VAAPIEncodeSlice *slice)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeH265Context *priv = avctx->priv_data;
> - VAAPIEncodeH265Picture *hpic = pic->priv_data;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> + VAAPIEncodeH265Picture *hpic = base_pic->priv_data;
> const H265RawSPS *sps = &priv->raw_sps;
> const H265RawPPS *pps = &priv->raw_pps;
> H265RawSliceHeader *sh = &priv->raw_slice.header;
> @@ -1000,13 +1003,13 @@ static int
> vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
>
> sh->slice_type = hpic->slice_type;
>
> - if (sh->slice_type == HEVC_SLICE_P && ctx->p_to_gpb)
> + if (sh->slice_type == HEVC_SLICE_P && base_ctx->p_to_gpb)
> sh->slice_type = HEVC_SLICE_B;
>
> sh->slice_pic_order_cnt_lsb = hpic->pic_order_cnt &
> (1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4)) - 1;
>
> - if (pic->type != PICTURE_TYPE_IDR) {
> + if (base_pic->type != PICTURE_TYPE_IDR) {
> H265RawSTRefPicSet *rps;
> const VAAPIEncodeH265Picture *strp;
> int rps_poc[MAX_DPB_SIZE];
> @@ -1020,33 +1023,33 @@ static int
> vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
>
> rps_pics = 0;
> for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
> - for (j = 0; j < pic->nb_refs[i]; j++) {
> - strp = pic->refs[i][j]->priv_data;
> + for (j = 0; j < base_pic->nb_refs[i]; j++) {
> + strp = base_pic->refs[i][j]->priv_data;
> rps_poc[rps_pics] = strp->pic_order_cnt;
> rps_used[rps_pics] = 1;
> ++rps_pics;
> }
> }
>
> - for (i = 0; i < pic->nb_dpb_pics; i++) {
> - if (pic->dpb[i] == pic)
> + for (i = 0; i < base_pic->nb_dpb_pics; i++) {
> + if (base_pic->dpb[i] == base_pic)
> continue;
>
> - for (j = 0; j < pic->nb_refs[0]; j++) {
> - if (pic->dpb[i] == pic->refs[0][j])
> + for (j = 0; j < base_pic->nb_refs[0]; j++) {
> + if (base_pic->dpb[i] == base_pic->refs[0][j])
> break;
> }
> - if (j < pic->nb_refs[0])
> + if (j < base_pic->nb_refs[0])
> continue;
>
> - for (j = 0; j < pic->nb_refs[1]; j++) {
> - if (pic->dpb[i] == pic->refs[1][j])
> + for (j = 0; j < base_pic->nb_refs[1]; j++) {
> + if (base_pic->dpb[i] == base_pic->refs[1][j])
> break;
> }
> - if (j < pic->nb_refs[1])
> + if (j < base_pic->nb_refs[1])
> continue;
>
> - strp = pic->dpb[i]->priv_data;
> + strp = base_pic->dpb[i]->priv_data;
> rps_poc[rps_pics] = strp->pic_order_cnt;
> rps_used[rps_pics] = 0;
> ++rps_pics;
> @@ -1113,9 +1116,9 @@ static int
> vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
> sh->slice_sao_luma_flag = sh->slice_sao_chroma_flag =
> sps->sample_adaptive_offset_enabled_flag;
>
> - if (pic->type == PICTURE_TYPE_B)
> + if (base_pic->type == PICTURE_TYPE_B)
> sh->slice_qp_delta = priv->fixed_qp_b - (pps->init_qp_minus26 + 26);
> - else if (pic->type == PICTURE_TYPE_P)
> + else if (base_pic->type == PICTURE_TYPE_P)
> sh->slice_qp_delta = priv->fixed_qp_p - (pps->init_qp_minus26 + 26);
> else
> sh->slice_qp_delta = priv->fixed_qp_idr - (pps->init_qp_minus26 +
> 26);
> @@ -1170,22 +1173,22 @@ static int
> vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
> vslice->ref_pic_list1[i].flags = VA_PICTURE_HEVC_INVALID;
> }
>
> - if (pic->nb_refs[0]) {
> + if (base_pic->nb_refs[0]) {
> // Backward reference for P- or B-frame.
> - av_assert0(pic->type == PICTURE_TYPE_P ||
> - pic->type == PICTURE_TYPE_B);
> + av_assert0(base_pic->type == PICTURE_TYPE_P ||
> + base_pic->type == PICTURE_TYPE_B);
> vslice->ref_pic_list0[0] = vpic->reference_frames[0];
> - if (ctx->p_to_gpb && pic->type == PICTURE_TYPE_P)
> + if (base_ctx->p_to_gpb && base_pic->type == PICTURE_TYPE_P)
> // Reference for GPB B-frame, L0 == L1
> vslice->ref_pic_list1[0] = vpic->reference_frames[0];
> }
> - if (pic->nb_refs[1]) {
> + if (base_pic->nb_refs[1]) {
> // Forward reference for B-frame.
> - av_assert0(pic->type == PICTURE_TYPE_B);
> + av_assert0(base_pic->type == PICTURE_TYPE_B);
> vslice->ref_pic_list1[0] = vpic->reference_frames[1];
> }
>
> - if (pic->type == PICTURE_TYPE_P && ctx->p_to_gpb) {
> + if (base_pic->type == PICTURE_TYPE_P && base_ctx->p_to_gpb) {
> vslice->slice_type = HEVC_SLICE_B;
> for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) {
> vslice->ref_pic_list1[i].picture_id = vslice-
> >ref_pic_list0[i].picture_id;
> @@ -1198,8 +1201,9 @@ static int
> vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
>
> static av_cold int vaapi_encode_h265_get_encoder_caps(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodeH265Context *priv = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodeH265Context *priv = avctx->priv_data;
>
> #if VA_CHECK_VERSION(1, 13, 0)
> {
> @@ -1250,18 +1254,19 @@ static av_cold int
> vaapi_encode_h265_get_encoder_caps(AVCodecContext *avctx)
> "min CB size %dx%d.\n", priv->ctu_size, priv->ctu_size,
> priv->min_cb_size, priv->min_cb_size);
>
> - ctx->surface_width = FFALIGN(avctx->width, priv->min_cb_size);
> - ctx->surface_height = FFALIGN(avctx->height, priv->min_cb_size);
> + base_ctx->surface_width = FFALIGN(avctx->width, priv->min_cb_size);
> + base_ctx->surface_height = FFALIGN(avctx->height, priv->min_cb_size);
>
> - ctx->slice_block_width = ctx->slice_block_height = priv->ctu_size;
> + base_ctx->slice_block_width = base_ctx->slice_block_height = priv-
> >ctu_size;
>
> return 0;
> }
>
> static av_cold int vaapi_encode_h265_configure(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodeH265Context *priv = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodeH265Context *priv = avctx->priv_data;
> int err;
>
> err = ff_cbs_init(&priv->cbc, AV_CODEC_ID_HEVC, avctx);
> @@ -1273,7 +1278,7 @@ static av_cold int
> vaapi_encode_h265_configure(AVCodecContext *avctx)
> // therefore always bounded below by 1, even in 10-bit mode where
> // it should go down to -12.
>
> - priv->fixed_qp_p = av_clip(ctx->rc_quality, 1, 51);
> + priv->fixed_qp_p = av_clip(base_ctx->rc_quality, 1, 51);
> if (avctx->i_quant_factor > 0.0)
> priv->fixed_qp_idr =
> av_clip((avctx->i_quant_factor * priv->fixed_qp_p +
> @@ -1357,8 +1362,9 @@ static const VAAPIEncodeType vaapi_encode_type_h265 = {
>
> static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodeH265Context *priv = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodeH265Context *priv = avctx->priv_data;
>
> ctx->codec = &vaapi_encode_type_h265;
>
> @@ -1379,7 +1385,7 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext
> *avctx)
> VA_ENC_PACKED_HEADER_MISC; // SEI
>
> if (priv->qp > 0)
> - ctx->explicit_qp = priv->qp;
> + base_ctx->explicit_qp = priv->qp;
>
> return ff_vaapi_encode_init(avctx);
> }
> @@ -1398,6 +1404,7 @@ static av_cold int
> vaapi_encode_h265_close(AVCodecContext *avctx)
> #define OFFSET(x) offsetof(VAAPIEncodeH265Context, x)
> #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
> static const AVOption vaapi_encode_h265_options[] = {
> + HW_BASE_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_RC_OPTIONS,
>
> diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c
> index c17747e3a9..91829b1e0e 100644
> --- a/libavcodec/vaapi_encode_mjpeg.c
> +++ b/libavcodec/vaapi_encode_mjpeg.c
> @@ -222,7 +222,9 @@ static int
> vaapi_encode_mjpeg_write_extra_buffer(AVCodecContext *avctx,
> static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,
> VAAPIEncodePicture *pic)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeMJPEGContext *priv = avctx->priv_data;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> JPEGRawFrameHeader *fh = &priv->frame_header;
> JPEGRawScanHeader *sh = &priv->scan.header;
> VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params;
> @@ -232,9 +234,9 @@ static int
> vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,
> const uint8_t *components;
> int t, i, quant_scale, len;
>
> - av_assert0(pic->type == PICTURE_TYPE_IDR);
> + av_assert0(base_pic->type == PICTURE_TYPE_IDR);
>
> - desc = av_pix_fmt_desc_get(priv->common.input_frames->sw_format);
> + desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format);
> av_assert0(desc);
> if (desc->flags & AV_PIX_FMT_FLAG_RGB)
> components = components_rgb;
> @@ -261,7 +263,7 @@ static int
> vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx,
> // JFIF header.
> if (priv->jfif) {
> JPEGRawApplicationData *app = &priv->jfif_header;
> - AVRational sar = pic->input_image->sample_aspect_ratio;
> + AVRational sar = base_pic->input_image->sample_aspect_ratio;
> int sar_w, sar_h;
> PutByteContext pbc;
>
> @@ -436,25 +438,26 @@ static int
> vaapi_encode_mjpeg_init_slice_params(AVCodecContext *avctx,
>
> static av_cold int vaapi_encode_mjpeg_get_encoder_caps(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> const AVPixFmtDescriptor *desc;
>
> - desc = av_pix_fmt_desc_get(ctx->input_frames->sw_format);
> + desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format);
> av_assert0(desc);
>
> - ctx->surface_width = FFALIGN(avctx->width, 8 << desc->log2_chroma_w);
> - ctx->surface_height = FFALIGN(avctx->height, 8 << desc->log2_chroma_h);
> + base_ctx->surface_width = FFALIGN(avctx->width, 8 << desc-
> >log2_chroma_w);
> + base_ctx->surface_height = FFALIGN(avctx->height, 8 << desc-
> >log2_chroma_h);
>
> return 0;
> }
>
> static av_cold int vaapi_encode_mjpeg_configure(AVCodecContext *avctx)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAAPIEncodeMJPEGContext *priv = avctx->priv_data;
> int err;
>
> - priv->quality = ctx->rc_quality;
> + priv->quality = base_ctx->rc_quality;
> if (priv->quality < 1 || priv->quality > 100) {
> av_log(avctx, AV_LOG_ERROR, "Invalid quality value %d "
> "(must be 1-100).\n", priv->quality);
> @@ -540,6 +543,7 @@ static av_cold int vaapi_encode_mjpeg_close(AVCodecContext
> *avctx)
> #define OFFSET(x) offsetof(VAAPIEncodeMJPEGContext, x)
> #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
> static const AVOption vaapi_encode_mjpeg_options[] = {
> + HW_BASE_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_COMMON_OPTIONS,
>
> { "jfif", "Include JFIF header",
> diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c
> index c9b16fbcfc..aa8e6d6bdf 100644
> --- a/libavcodec/vaapi_encode_mpeg2.c
> +++ b/libavcodec/vaapi_encode_mpeg2.c
> @@ -166,6 +166,7 @@ fail:
>
> static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
> MPEG2RawSequenceHeader *sh = &priv->sequence_header;
> @@ -281,7 +282,7 @@ static int
> vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)
>
> se->bit_rate_extension = priv->bit_rate >> 18;
> se->vbv_buffer_size_extension = priv->vbv_buffer_size >> 10;
> - se->low_delay = ctx->b_per_p == 0;
> + se->low_delay = base_ctx->b_per_p == 0;
>
> se->frame_rate_extension_n = ext_n;
> se->frame_rate_extension_d = ext_d;
> @@ -353,8 +354,8 @@ static int
> vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)
>
>
> *vseq = (VAEncSequenceParameterBufferMPEG2) {
> - .intra_period = ctx->gop_size,
> - .ip_period = ctx->b_per_p + 1,
> + .intra_period = base_ctx->gop_size,
> + .ip_period = base_ctx->b_per_p + 1,
>
> .picture_width = avctx->width,
> .picture_height = avctx->height,
> @@ -417,30 +418,31 @@ static int
> vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx)
> }
>
> static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic)
> + VAAPIEncodePicture *pic)
> {
> VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> MPEG2RawPictureHeader *ph = &priv->picture_header;
> MPEG2RawPictureCodingExtension *pce = &priv-
> >picture_coding_extension.data.picture_coding;
> VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params;
>
> - if (pic->type == PICTURE_TYPE_IDR || pic->type == PICTURE_TYPE_I) {
> + if (base_pic->type == PICTURE_TYPE_IDR || base_pic->type ==
> PICTURE_TYPE_I) {
> ph->temporal_reference = 0;
> ph->picture_coding_type = 1;
> - priv->last_i_frame = pic->display_order;
> + priv->last_i_frame = base_pic->display_order;
> } else {
> - ph->temporal_reference = pic->display_order - priv->last_i_frame;
> - ph->picture_coding_type = pic->type == PICTURE_TYPE_B ? 3 : 2;
> + ph->temporal_reference = base_pic->display_order - priv-
> >last_i_frame;
> + ph->picture_coding_type = base_pic->type == PICTURE_TYPE_B ? 3 : 2;
> }
>
> - if (pic->type == PICTURE_TYPE_P || pic->type == PICTURE_TYPE_B) {
> + if (base_pic->type == PICTURE_TYPE_P || base_pic->type == PICTURE_TYPE_B)
> {
> pce->f_code[0][0] = priv->f_code_horizontal;
> pce->f_code[0][1] = priv->f_code_vertical;
> } else {
> pce->f_code[0][0] = 15;
> pce->f_code[0][1] = 15;
> }
> - if (pic->type == PICTURE_TYPE_B) {
> + if (base_pic->type == PICTURE_TYPE_B) {
> pce->f_code[1][0] = priv->f_code_horizontal;
> pce->f_code[1][1] = priv->f_code_vertical;
> } else {
> @@ -451,19 +453,19 @@ static int
> vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx,
> vpic->reconstructed_picture = pic->recon_surface;
> vpic->coded_buf = pic->output_buffer;
>
> - switch (pic->type) {
> + switch (base_pic->type) {
> case PICTURE_TYPE_IDR:
> case PICTURE_TYPE_I:
> vpic->picture_type = VAEncPictureTypeIntra;
> break;
> case PICTURE_TYPE_P:
> vpic->picture_type = VAEncPictureTypePredictive;
> - vpic->forward_reference_picture = pic->refs[0][0]->recon_surface;
> + vpic->forward_reference_picture = ((VAAPIEncodePicture *)base_pic-
> >refs[0][0])->recon_surface;
> break;
> case PICTURE_TYPE_B:
> vpic->picture_type = VAEncPictureTypeBidirectional;
> - vpic->forward_reference_picture = pic->refs[0][0]->recon_surface;
> - vpic->backward_reference_picture = pic->refs[1][0]->recon_surface;
> + vpic->forward_reference_picture = ((VAAPIEncodePicture *)base_pic-
> >refs[0][0])->recon_surface;
> + vpic->backward_reference_picture = ((VAAPIEncodePicture *)base_pic-
> >refs[1][0])->recon_surface;
> break;
> default:
> av_assert0(0 && "invalid picture type");
> @@ -479,17 +481,18 @@ static int
> vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx,
> }
>
> static int vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx,
> - VAAPIEncodePicture *pic,
> - VAAPIEncodeSlice *slice)
> + VAAPIEncodePicture *pic,
> + VAAPIEncodeSlice *slice)
> {
> - VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
> - VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> + VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
> + VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params;
> int qp;
>
> vslice->macroblock_address = slice->block_start;
> vslice->num_macroblocks = slice->block_size;
>
> - switch (pic->type) {
> + switch (base_pic->type) {
> case PICTURE_TYPE_IDR:
> case PICTURE_TYPE_I:
> qp = priv->quant_i;
> @@ -505,14 +508,15 @@ static int
> vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx,
> }
>
> vslice->quantiser_scale_code = qp;
> - vslice->is_intra_slice = (pic->type == PICTURE_TYPE_IDR ||
> - pic->type == PICTURE_TYPE_I);
> + vslice->is_intra_slice = (base_pic->type == PICTURE_TYPE_IDR ||
> + base_pic->type == PICTURE_TYPE_I);
>
> return 0;
> }
>
> static av_cold int vaapi_encode_mpeg2_configure(AVCodecContext *avctx)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAAPIEncodeMPEG2Context *priv = avctx->priv_data;
> int err;
> @@ -522,7 +526,7 @@ static av_cold int
> vaapi_encode_mpeg2_configure(AVCodecContext *avctx)
> return err;
>
> if (ctx->va_rc_mode == VA_RC_CQP) {
> - priv->quant_p = av_clip(ctx->rc_quality, 1, 31);
> + priv->quant_p = av_clip(base_ctx->rc_quality, 1, 31);
> if (avctx->i_quant_factor > 0.0)
> priv->quant_i =
> av_clip((avctx->i_quant_factor * priv->quant_p +
> @@ -639,6 +643,7 @@ static av_cold int vaapi_encode_mpeg2_close(AVCodecContext
> *avctx)
> #define OFFSET(x) offsetof(VAAPIEncodeMPEG2Context, x)
> #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
> static const AVOption vaapi_encode_mpeg2_options[] = {
> + HW_BASE_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_RC_OPTIONS,
>
> diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c
> index 8a557b967e..c8203dcbc9 100644
> --- a/libavcodec/vaapi_encode_vp8.c
> +++ b/libavcodec/vaapi_encode_vp8.c
> @@ -52,6 +52,7 @@ typedef struct VAAPIEncodeVP8Context {
>
> static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAEncSequenceParameterBufferVP8 *vseq = ctx->codec_sequence_params;
>
> @@ -66,7 +67,7 @@ static int
> vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx)
>
> if (!(ctx->va_rc_mode & VA_RC_CQP)) {
> vseq->bits_per_second = ctx->va_bit_rate;
> - vseq->intra_period = ctx->gop_size;
> + vseq->intra_period = base_ctx->gop_size;
> }
>
> return 0;
> @@ -75,6 +76,7 @@ static int
> vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx)
> static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx,
> VAAPIEncodePicture *pic)
> {
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> VAAPIEncodeVP8Context *priv = avctx->priv_data;
> VAEncPictureParameterBufferVP8 *vpic = pic->codec_picture_params;
> int i;
> @@ -83,10 +85,10 @@ static int
> vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx,
>
> vpic->coded_buf = pic->output_buffer;
>
> - switch (pic->type) {
> + switch (base_pic->type) {
> case PICTURE_TYPE_IDR:
> case PICTURE_TYPE_I:
> - av_assert0(pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0);
> + av_assert0(base_pic->nb_refs[0] == 0 && base_pic->nb_refs[1] == 0);
> vpic->ref_flags.bits.force_kf = 1;
> vpic->ref_last_frame =
> vpic->ref_gf_frame =
> @@ -94,20 +96,20 @@ static int
> vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx,
> VA_INVALID_SURFACE;
> break;
> case PICTURE_TYPE_P:
> - av_assert0(!pic->nb_refs[1]);
> + av_assert0(!base_pic->nb_refs[1]);
> vpic->ref_flags.bits.no_ref_last = 0;
> vpic->ref_flags.bits.no_ref_gf = 1;
> vpic->ref_flags.bits.no_ref_arf = 1;
> vpic->ref_last_frame =
> vpic->ref_gf_frame =
> vpic->ref_arf_frame =
> - pic->refs[0][0]->recon_surface;
> + ((VAAPIEncodePicture *)base_pic->refs[0][0])->recon_surface;
> break;
> default:
> av_assert0(0 && "invalid picture type");
> }
>
> - vpic->pic_flags.bits.frame_type = (pic->type != PICTURE_TYPE_IDR);
> + vpic->pic_flags.bits.frame_type = (base_pic->type != PICTURE_TYPE_IDR);
> vpic->pic_flags.bits.show_frame = 1;
>
> vpic->pic_flags.bits.refresh_last = 1;
> @@ -145,7 +147,7 @@ static int
> vaapi_encode_vp8_write_quant_table(AVCodecContext *avctx,
>
> memset(&quant, 0, sizeof(quant));
>
> - if (pic->type == PICTURE_TYPE_P)
> + if (pic->base.type == PICTURE_TYPE_P)
> q = priv->q_index_p;
> else
> q = priv->q_index_i;
> @@ -161,10 +163,11 @@ static int
> vaapi_encode_vp8_write_quant_table(AVCodecContext *avctx,
>
> static av_cold int vaapi_encode_vp8_configure(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodeVP8Context *priv = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodeVP8Context *priv = avctx->priv_data;
>
> - priv->q_index_p = av_clip(ctx->rc_quality, 0, VP8_MAX_QUANT);
> + priv->q_index_p = av_clip(base_ctx->rc_quality, 0, VP8_MAX_QUANT);
> if (avctx->i_quant_factor > 0.0)
> priv->q_index_i =
> av_clip((avctx->i_quant_factor * priv->q_index_p +
> @@ -216,6 +219,7 @@ static av_cold int vaapi_encode_vp8_init(AVCodecContext
> *avctx)
> #define OFFSET(x) offsetof(VAAPIEncodeVP8Context, x)
> #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
> static const AVOption vaapi_encode_vp8_options[] = {
> + HW_BASE_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_RC_OPTIONS,
>
> diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c
> index c2a8dec71b..7a0cb0c7fc 100644
> --- a/libavcodec/vaapi_encode_vp9.c
> +++ b/libavcodec/vaapi_encode_vp9.c
> @@ -53,6 +53,7 @@ typedef struct VAAPIEncodeVP9Context {
>
> static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx)
> {
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeContext *ctx = avctx->priv_data;
> VAEncSequenceParameterBufferVP9 *vseq = ctx->codec_sequence_params;
> VAEncPictureParameterBufferVP9 *vpic = ctx->codec_picture_params;
> @@ -64,7 +65,7 @@ static int
> vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx)
>
> if (!(ctx->va_rc_mode & VA_RC_CQP)) {
> vseq->bits_per_second = ctx->va_bit_rate;
> - vseq->intra_period = ctx->gop_size;
> + vseq->intra_period = base_ctx->gop_size;
> }
>
> vpic->frame_width_src = avctx->width;
> @@ -78,9 +79,10 @@ static int
> vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx)
> static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx,
> VAAPIEncodePicture *pic)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> VAAPIEncodeVP9Context *priv = avctx->priv_data;
> - VAAPIEncodeVP9Picture *hpic = pic->priv_data;
> + HWBaseEncodePicture *base_pic = (HWBaseEncodePicture *)pic;
> + VAAPIEncodeVP9Picture *hpic = base_pic->priv_data;
> VAEncPictureParameterBufferVP9 *vpic = pic->codec_picture_params;
> int i;
> int num_tile_columns;
> @@ -94,20 +96,20 @@ static int
> vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx,
> num_tile_columns = (vpic->frame_width_src + VP9_MAX_TILE_WIDTH - 1) /
> VP9_MAX_TILE_WIDTH;
> vpic->log2_tile_columns = num_tile_columns == 1 ? 0 :
> av_log2(num_tile_columns - 1) + 1;
>
> - switch (pic->type) {
> + switch (base_pic->type) {
> case PICTURE_TYPE_IDR:
> - av_assert0(pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0);
> + av_assert0(base_pic->nb_refs[0] == 0 && base_pic->nb_refs[1] == 0);
> vpic->ref_flags.bits.force_kf = 1;
> vpic->refresh_frame_flags = 0xff;
> hpic->slot = 0;
> break;
> case PICTURE_TYPE_P:
> - av_assert0(!pic->nb_refs[1]);
> + av_assert0(!base_pic->nb_refs[1]);
> {
> - VAAPIEncodeVP9Picture *href = pic->refs[0][0]->priv_data;
> + VAAPIEncodeVP9Picture *href = base_pic->refs[0][0]->priv_data;
> av_assert0(href->slot == 0 || href->slot == 1);
>
> - if (ctx->max_b_depth > 0) {
> + if (base_ctx->max_b_depth > 0) {
> hpic->slot = !href->slot;
> vpic->refresh_frame_flags = 1 << hpic->slot | 0xfc;
> } else {
> @@ -120,20 +122,20 @@ static int
> vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx,
> }
> break;
> case PICTURE_TYPE_B:
> - av_assert0(pic->nb_refs[0] && pic->nb_refs[1]);
> + av_assert0(base_pic->nb_refs[0] && base_pic->nb_refs[1]);
> {
> - VAAPIEncodeVP9Picture *href0 = pic->refs[0][0]->priv_data,
> - *href1 = pic->refs[1][0]->priv_data;
> - av_assert0(href0->slot < pic->b_depth + 1 &&
> - href1->slot < pic->b_depth + 1);
> + VAAPIEncodeVP9Picture *href0 = base_pic->refs[0][0]->priv_data,
> + *href1 = base_pic->refs[1][0]->priv_data;
> + av_assert0(href0->slot < base_pic->b_depth + 1 &&
> + href1->slot < base_pic->b_depth + 1);
>
> - if (pic->b_depth == ctx->max_b_depth) {
> + if (base_pic->b_depth == base_ctx->max_b_depth) {
> // Unreferenced frame.
> vpic->refresh_frame_flags = 0x00;
> hpic->slot = 8;
> } else {
> - vpic->refresh_frame_flags = 0xfe << pic->b_depth & 0xff;
> - hpic->slot = 1 + pic->b_depth;
> + vpic->refresh_frame_flags = 0xfe << base_pic->b_depth & 0xff;
> + hpic->slot = 1 + base_pic->b_depth;
> }
> vpic->ref_flags.bits.ref_frame_ctrl_l0 = 1;
> vpic->ref_flags.bits.ref_frame_ctrl_l1 = 2;
> @@ -148,31 +150,31 @@ static int
> vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx,
> }
> if (vpic->refresh_frame_flags == 0x00) {
> av_log(avctx, AV_LOG_DEBUG, "Pic %"PRId64" not stored.\n",
> - pic->display_order);
> + base_pic->display_order);
> } else {
> av_log(avctx, AV_LOG_DEBUG, "Pic %"PRId64" stored in slot %d.\n",
> - pic->display_order, hpic->slot);
> + base_pic->display_order, hpic->slot);
> }
>
> for (i = 0; i < FF_ARRAY_ELEMS(vpic->reference_frames); i++)
> vpic->reference_frames[i] = VA_INVALID_SURFACE;
>
> for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) {
> - for (int j = 0; j < pic->nb_refs[i]; j++) {
> - VAAPIEncodePicture *ref_pic = pic->refs[i][j];
> + for (int j = 0; j < base_pic->nb_refs[i]; j++) {
> + HWBaseEncodePicture *ref_pic = base_pic->refs[i][j];
> int slot;
> slot = ((VAAPIEncodeVP9Picture*)ref_pic->priv_data)->slot;
> av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE);
> - vpic->reference_frames[slot] = ref_pic->recon_surface;
> + vpic->reference_frames[slot] = ((VAAPIEncodePicture *)ref_pic)-
> >recon_surface;
> }
> }
>
> - vpic->pic_flags.bits.frame_type = (pic->type != PICTURE_TYPE_IDR);
> - vpic->pic_flags.bits.show_frame = pic->display_order <= pic-
> >encode_order;
> + vpic->pic_flags.bits.frame_type = (base_pic->type != PICTURE_TYPE_IDR);
> + vpic->pic_flags.bits.show_frame = base_pic->display_order <= base_pic-
> >encode_order;
>
> - if (pic->type == PICTURE_TYPE_IDR)
> + if (base_pic->type == PICTURE_TYPE_IDR)
> vpic->luma_ac_qindex = priv->q_idx_idr;
> - else if (pic->type == PICTURE_TYPE_P)
> + else if (base_pic->type == PICTURE_TYPE_P)
> vpic->luma_ac_qindex = priv->q_idx_p;
> else
> vpic->luma_ac_qindex = priv->q_idx_b;
> @@ -188,22 +190,23 @@ static int
> vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx,
>
> static av_cold int vaapi_encode_vp9_get_encoder_caps(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
>
> // Surfaces must be aligned to 64x64 superblock boundaries.
> - ctx->surface_width = FFALIGN(avctx->width, 64);
> - ctx->surface_height = FFALIGN(avctx->height, 64);
> + base_ctx->surface_width = FFALIGN(avctx->width, 64);
> + base_ctx->surface_height = FFALIGN(avctx->height, 64);
>
> return 0;
> }
>
> static av_cold int vaapi_encode_vp9_configure(AVCodecContext *avctx)
> {
> - VAAPIEncodeContext *ctx = avctx->priv_data;
> - VAAPIEncodeVP9Context *priv = avctx->priv_data;
> + HWBaseEncodeContext *base_ctx = avctx->priv_data;
> + VAAPIEncodeContext *ctx = avctx->priv_data;
> + VAAPIEncodeVP9Context *priv = avctx->priv_data;
>
> if (ctx->rc_mode->quality) {
> - priv->q_idx_p = av_clip(ctx->rc_quality, 0, VP9_MAX_QUANT);
> + 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 =
> av_clip((avctx->i_quant_factor * priv->q_idx_p +
> @@ -273,6 +276,7 @@ static av_cold int vaapi_encode_vp9_init(AVCodecContext
> *avctx)
> #define OFFSET(x) offsetof(VAAPIEncodeVP9Context, x)
> #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
> static const AVOption vaapi_encode_vp9_options[] = {
> + HW_BASE_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_COMMON_OPTIONS,
> VAAPI_ENCODE_RC_OPTIONS,
>
More information about the ffmpeg-devel
mailing list