Message ID | 20240314081456.379-2-tong1.wu@intel.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,v7,01/12] avcodec/vaapi_encode: move pic->input_surface initialization to encode_alloc | expand |
Context | Check | Description |
---|---|---|
yinshiyou/make_fate_loongarch64 | success | Make fate finished |
yinshiyou/make_loongarch64 | warning | New warnings during build |
andriy/make_fate_x86 | success | Make fate finished |
andriy/make_x86 | warning | New warnings during build |
On Do, 2024-03-14 at 16:14 +0800, tong1.wu-at-intel.com@ffmpeg.org wrote: > From: Tong Wu <tong1.wu@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@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, >
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; + + // 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,