[FFmpeg-devel] [PATCH v1 7/7] lavc/vaapi_dec: Add VVC decoder
Wang, Fei W
fei.w.wang at intel.com
Wed Apr 3 06:31:22 EEST 2024
On Tue, 2024-04-02 at 20:48 +0800, Nuo Mi wrote:
>
>
> On Thu, Mar 28, 2024 at 9:27 AM <fei.w.wang-at-intel.com at ffmpeg.org>
> wrote:
> > From: Fei Wang <fei.w.wang at intel.com>
> >
> > Signed-off-by: Fei Wang <fei.w.wang at intel.com>
> > ---
> > Changelog | 4 +
> > configure | 3 +
> > libavcodec/Makefile | 1 +
> > libavcodec/hwaccels.h | 1 +
> > libavcodec/vaapi_decode.c | 7 +
> > libavcodec/vaapi_vvc.c | 657
> > ++++++++++++++++++++++++++++++++++++++
> > libavcodec/version.h | 2 +-
> > libavcodec/vvc/vvcdec.c | 15 +-
> > 8 files changed, 688 insertions(+), 2 deletions(-)
> > create mode 100644 libavcodec/vaapi_vvc.c
> >
> > diff --git a/Changelog b/Changelog
> > index e83a00e35c..3108e65558 100644
> > --- a/Changelog
> > +++ b/Changelog
> > @@ -1,6 +1,10 @@
> > Entries are sorted chronologically from oldest to youngest within
> > each release,
> > releases are sorted from youngest to oldest.
> >
> > +version <next>:
> > +- VVC VAAPI decoder
> > +
> > +
> > version 7.0:
> > - DXV DXT1 encoder
> > - LEAD MCMP decoder
> > diff --git a/configure b/configure
> > index 2a1d22310b..d902c9adc8 100755
> > --- a/configure
> > +++ b/configure
> > @@ -3258,6 +3258,8 @@ vp9_vdpau_hwaccel_deps="vdpau
> > VdpPictureInfoVP9"
> > vp9_vdpau_hwaccel_select="vp9_decoder"
> > vp9_videotoolbox_hwaccel_deps="videotoolbox"
> > vp9_videotoolbox_hwaccel_select="vp9_decoder"
> > +vvc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferVVC"
> > +vvc_vaapi_hwaccel_select="vvc_decoder"
> > wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel"
> > wmv3_d3d11va2_hwaccel_select="vc1_d3d11va2_hwaccel"
> > wmv3_d3d12va_hwaccel_select="vc1_d3d12va_hwaccel"
> > @@ -7250,6 +7252,7 @@ if enabled vaapi; then
> > check_cpp_condition vaapi_1 "va/va.h" "VA_CHECK_VERSION(1, 0,
> > 0)"
> >
> > check_type "va/va.h va/va_dec_hevc.h"
> > "VAPictureParameterBufferHEVC"
> > + check_type "va/va.h va/va_dec_vvc.h"
> > "VAPictureParameterBufferVVC"
> > check_struct "va/va.h" "VADecPictureParameterBufferVP9"
> > bit_depth
> > check_struct "va/va.h" "VADecPictureParameterBufferAV1"
> > bit_depth_idx
> > check_type "va/va.h va/va_vpp.h"
> > "VAProcFilterParameterBufferHDRToneMapping"
> > diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> > index 9ce6d445c1..343b037636 100644
> > --- a/libavcodec/Makefile
> > +++ b/libavcodec/Makefile
> > @@ -1054,6 +1054,7 @@ OBJS-$(CONFIG_VP9_VAAPI_HWACCEL) +=
> > vaapi_vp9.o
> > OBJS-$(CONFIG_VP9_VDPAU_HWACCEL) += vdpau_vp9.o
> > OBJS-$(CONFIG_VP9_VIDEOTOOLBOX_HWACCEL) += videotoolbox_vp9.o
> > OBJS-$(CONFIG_VP8_QSV_HWACCEL) += qsvdec.o
> > +OBJS-$(CONFIG_VVC_VAAPI_HWACCEL) += vaapi_vvc.o
> >
> > # Objects duplicated from other libraries for shared builds
> > SHLIBOBJS += log2_tab.o reverse.o
> > diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h
> > index 5171e4c7d7..88d6b9a9b5 100644
> > --- a/libavcodec/hwaccels.h
> > +++ b/libavcodec/hwaccels.h
> > @@ -82,6 +82,7 @@ extern const struct FFHWAccel
> > ff_vp9_nvdec_hwaccel;
> > extern const struct FFHWAccel ff_vp9_vaapi_hwaccel;
> > extern const struct FFHWAccel ff_vp9_vdpau_hwaccel;
> > extern const struct FFHWAccel ff_vp9_videotoolbox_hwaccel;
> > +extern const struct FFHWAccel ff_vvc_vaapi_hwaccel;
> > extern const struct FFHWAccel ff_wmv3_d3d11va_hwaccel;
> > extern const struct FFHWAccel ff_wmv3_d3d11va2_hwaccel;
> > extern const struct FFHWAccel ff_wmv3_d3d12va_hwaccel;
> > diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
> > index 1b1972a2a9..ceeb1f1a12 100644
> > --- a/libavcodec/vaapi_decode.c
> > +++ b/libavcodec/vaapi_decode.c
> > @@ -455,6 +455,9 @@ static const struct {
> > MAP(AV1, AV1_MAIN, AV1Profile0),
> > MAP(AV1, AV1_HIGH, AV1Profile1),
> > #endif
> > +#if VA_CHECK_VERSION(1, 22, 0)
> > + MAP(H266, VVC_MAIN_10, VVCMain10),
> > +#endif
> >
> > #undef MAP
> > };
> > @@ -627,6 +630,10 @@ static int
> > vaapi_decode_make_config(AVCodecContext *avctx,
> > case AV_CODEC_ID_VP8:
> > frames->initial_pool_size += 3;
> > break;
> > + case AV_CODEC_ID_H266:
> > + // Add additional 16 for maximum 16 frames delay in
> > vvc native decode.
> > + frames->initial_pool_size += 32;
>
> One frame of 8k YUV444, 10 bits, is about 200MB. Thirty-two frames
> amount to approximately 6GB.Can we dynamically allocate the buffer
> pool?
It's processing in other thread:
https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=11316
>
> The software decoder requires a delay of 16 frames to ensure full
> utilization of CPUs. In the future, we may consider increasing this
> to 32 or even 64 frames.
> However, for hardware decoding, given that all processing occurs on
> the GPU, we do not require any delay.
The delay can avoid sync hardware task immediately once it is
submitted, which can avoid hardware switch tasks frequently and drop
performance. If the number will increase, I'd prefer to set it as an
option and diff the default value for hardware with software.
Thanks
Fei
>
> > + break;
> > default:
> > frames->initial_pool_size += 2;
> > }
> > diff --git a/libavcodec/vaapi_vvc.c b/libavcodec/vaapi_vvc.c
> > new file mode 100644
> > index 0000000000..6141005688
> > --- /dev/null
> > +++ b/libavcodec/vaapi_vvc.c
> > @@ -0,0 +1,657 @@
> > +/*
> > + * VVC HW decode acceleration through VA API
> > + *
> > + * Copyright (c) 2024 Intel Corporation
> > + *
> > + * 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
> > + */
> > +
> > +#include <va/va.h>
> > +#include <va/va_dec_vvc.h>
> > +
> > +#include "vvc/vvcdec.h"
> > +#include "vvc/vvc_refs.h"
> > +#include "hwaccel_internal.h"
> > +#include "vaapi_decode.h"
> > +
> > +typedef struct VAAPIDecodePictureVVC {
> > + VAAPIDecodePicture pic;
> > + VAPictureParameterBufferVVC pic_param;
> > + VASliceParameterBufferVVC slice_param;
> > + int decode_issued;
> > +} VAAPIDecodePictureVVC;
> > +
> > +static void init_vaapi_pic(VAPictureVVC *va_pic)
> > +{
> > + va_pic->picture_id = VA_INVALID_ID;
> > + va_pic->flags = VA_PICTURE_VVC_INVALID;
> > + va_pic->pic_order_cnt = 0;
> > +}
> > +
> > +static void fill_vaapi_pic(VAPictureVVC *va_pic, const VVCFrame
> > *pic)
> > +{
> > + va_pic->picture_id = ff_vaapi_get_surface_id(pic->frame);
> > + va_pic->pic_order_cnt = pic->poc;
> > + va_pic->flags = 0;
> > +
> > + if (pic->flags & VVC_FRAME_FLAG_LONG_REF)
> > + va_pic->flags |= VA_PICTURE_VVC_LONG_TERM_REFERENCE;
> > +}
> > +
> > +static void fill_vaapi_reference_frames(const VVCFrameContext *h,
> > VAPictureParameterBufferVVC *pp)
> > +{
> > + const VVCFrame *current_picture = h->ref;
> > + int i, j;
> > +
> > + for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->ReferenceFrames);
> > i++) {
> > + const VVCFrame *frame = NULL;
> > +
> > + while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) {
> > + if ((&h->DPB[j] != current_picture ) &&
> > + (h->DPB[j].flags & (VVC_FRAME_FLAG_LONG_REF |
> > VVC_FRAME_FLAG_SHORT_REF)))
> > + frame = &h->DPB[j];
> > + j++;
> > + }
> > +
> > + init_vaapi_pic(&pp->ReferenceFrames[i]);
> > +
> > + if (frame) {
> > + VAAPIDecodePictureVVC *pic;
> > + fill_vaapi_pic(&pp->ReferenceFrames[i], frame);
> > + pic = frame->hwaccel_picture_private;
> > + if (!pic->decode_issued)
> > + pp->ReferenceFrames[i].flags |=
> > VA_PICTURE_VVC_UNAVAILABLE_REFERENCE;
> > + }
> > + }
> > +}
> > +
> > +static int vaapi_vvc_start_frame(AVCodecContext *avctx,
> > + av_unused const uint8_t *buffer,
> > + av_unused uint32_t size)
> > +{
> > + const VVCContext *h = avctx->priv_data;
> > + VVCFrameContext *fc = &h->fcs[(h->nb_frames
> > + h->nb_fcs) % h->nb_fcs];
> > + const H266RawSPS *sps = fc->ps.sps->r;
> > + const H266RawPPS *pps = fc->ps.pps->r;
> > + const H266RawPictureHeader *ph = fc->ps.ph.r;
> > + VAAPIDecodePictureVVC *pic = fc->ref-
> > >hwaccel_picture_private;
> > + VAPictureParameterBufferVVC *pic_param = &pic->pic_param;
> > + uint16_t tile_dim, exp_slice_height_in_ctus[VVC_MAX_SLICES] =
> > {0};
> > + int i, j, k, err;
> > +
> > + pic->pic.output_surface = ff_vaapi_get_surface_id(fc->ref-
> > >frame);
> > +
> > + *pic_param = (VAPictureParameterBufferVVC) {
> > + .pps_pic_width_in_luma_samples = pps-
> > >pps_pic_width_in_luma_samples,
> > + .pps_pic_height_in_luma_samples = pps-
> > >pps_pic_height_in_luma_samples,
> > + .sps_num_subpics_minus1 = sps-
> > >sps_num_subpics_minus1,
> > + .sps_chroma_format_idc = sps-
> > >sps_chroma_format_idc,
> > + .sps_bitdepth_minus8 = sps-
> > >sps_bitdepth_minus8,
> > + .sps_log2_ctu_size_minus5 = sps-
> > >sps_log2_ctu_size_minus5,
> > + .sps_log2_min_luma_coding_block_size_minus2 = sps-
> > >sps_log2_min_luma_coding_block_size_minus2,
> > + .sps_log2_transform_skip_max_size_minus2 = sps-
> > >sps_log2_transform_skip_max_size_minus2,
> > + .sps_six_minus_max_num_merge_cand = sps-
> > >sps_six_minus_max_num_merge_cand,
> > + .sps_five_minus_max_num_subblock_merge_cand = sps-
> > >sps_five_minus_max_num_subblock_merge_cand,
> > + .sps_max_num_merge_cand_minus_max_num_gpm_cand = sps-
> > >sps_max_num_merge_cand_minus_max_num_gpm_cand,
> > + .sps_log2_parallel_merge_level_minus2 = sps-
> > >sps_log2_parallel_merge_level_minus2,
> > + .sps_min_qp_prime_ts = sps-
> > >sps_min_qp_prime_ts,
> > + .sps_six_minus_max_num_ibc_merge_cand = sps-
> > >sps_six_minus_max_num_ibc_merge_cand,
> > + .sps_num_ladf_intervals_minus2 = sps-
> > >sps_num_ladf_intervals_minus2,
> > + .sps_ladf_lowest_interval_qp_offset = sps-
> > >sps_ladf_lowest_interval_qp_offset,
> > + .sps_flags.bits = {
> > + .sps_subpic_info_present_flag
> > = sps->sps_subpic_info_present_flag,
> > + .sps_independent_subpics_flag
> > = sps->sps_independent_subpics_flag,
> > + .sps_subpic_same_size_flag
> > = sps->sps_subpic_same_size_flag,
> > + .sps_entropy_coding_sync_enabled_flag
> > = sps->sps_entropy_coding_sync_enabled_flag,
> > + .sps_qtbtt_dual_tree_intra_flag
> > = sps->sps_qtbtt_dual_tree_intra_flag,
> > + .sps_max_luma_transform_size_64_flag
> > = sps->sps_max_luma_transform_size_64_flag,
> > + .sps_transform_skip_enabled_flag
> > = sps->sps_transform_skip_enabled_flag,
> > + .sps_bdpcm_enabled_flag
> > = sps->sps_bdpcm_enabled_flag,
> > + .sps_mts_enabled_flag
> > = sps->sps_mts_enabled_flag,
> > + .sps_explicit_mts_intra_enabled_flag
> > = sps->sps_explicit_mts_intra_enabled_flag,
> > + .sps_explicit_mts_inter_enabled_flag
> > = sps->sps_explicit_mts_inter_enabled_flag,
> > + .sps_lfnst_enabled_flag
> > = sps->sps_lfnst_enabled_flag,
> > + .sps_joint_cbcr_enabled_flag
> > = sps->sps_joint_cbcr_enabled_flag,
> > + .sps_same_qp_table_for_chroma_flag
> > = sps->sps_same_qp_table_for_chroma_flag,
> > + .sps_sao_enabled_flag
> > = sps->sps_sao_enabled_flag,
> > + .sps_alf_enabled_flag
> > = sps->sps_alf_enabled_flag,
> > + .sps_ccalf_enabled_flag
> > = sps->sps_alf_enabled_flag,
> > + .sps_lmcs_enabled_flag
> > = sps->sps_lmcs_enabled_flag,
> > + .sps_sbtmvp_enabled_flag
> > = sps->sps_sbtmvp_enabled_flag,
> > + .sps_amvr_enabled_flag
> > = sps->sps_amvr_enabled_flag,
> > + .sps_smvd_enabled_flag
> > = sps->sps_smvd_enabled_flag,
> > + .sps_mmvd_enabled_flag
> > = sps->sps_mmvd_enabled_flag,
> > + .sps_sbt_enabled_flag
> > = sps->sps_sbt_enabled_flag,
> > + .sps_affine_enabled_flag
> > = sps->sps_affine_enabled_flag,
> > + .sps_6param_affine_enabled_flag
> > = sps->sps_6param_affine_enabled_flag,
> > + .sps_affine_amvr_enabled_flag
> > = sps->sps_affine_amvr_enabled_flag,
> > + .sps_affine_prof_enabled_flag
> > = sps->sps_affine_prof_enabled_flag,
> > + .sps_bcw_enabled_flag
> > = sps->sps_bcw_enabled_flag,
> > + .sps_ciip_enabled_flag
> > = sps->sps_ciip_enabled_flag,
> > + .sps_gpm_enabled_flag
> > = sps->sps_gpm_enabled_flag,
> > + .sps_isp_enabled_flag
> > = sps->sps_isp_enabled_flag,
> > + .sps_mrl_enabled_flag
> > = sps->sps_mrl_enabled_flag,
> > + .sps_mip_enabled_flag
> > = sps->sps_mip_enabled_flag,
> > + .sps_cclm_enabled_flag
> > = sps->sps_cclm_enabled_flag,
> > + .sps_chroma_horizontal_collocated_flag
> > = sps->sps_chroma_horizontal_collocated_flag,
> > + .sps_chroma_vertical_collocated_flag
> > = sps->sps_chroma_vertical_collocated_flag,
> > + .sps_palette_enabled_flag
> > = sps->sps_palette_enabled_flag,
> > + .sps_act_enabled_flag
> > = sps->sps_act_enabled_flag,
> > + .sps_ibc_enabled_flag
> > = sps->sps_ibc_enabled_flag,
> > + .sps_ladf_enabled_flag
> > = sps->sps_ladf_enabled_flag,
> > + .sps_explicit_scaling_list_enabled_flag
> > = sps->sps_explicit_scaling_list_enabled_flag,
> > + .sps_scaling_matrix_for_lfnst_disabled_flag
> > = sps->sps_scaling_matrix_for_lfnst_disabled_flag,
> > +
> > .sps_scaling_matrix_for_alternative_colour_space_disabled_flag =
> > sps->sps_scaling_matrix_for_alternative_colour_space_disabled_flag,
> > + .sps_scaling_matrix_designated_colour_space_flag
> > = sps->sps_scaling_matrix_designated_colour_space_flag,
> > + .sps_virtual_boundaries_enabled_flag
> > = sps->sps_virtual_boundaries_enabled_flag,
> > + .sps_virtual_boundaries_present_flag
> > = sps->sps_virtual_boundaries_present_flag,
> > + },
> > + .NumVerVirtualBoundaries = sps-
> > >sps_virtual_boundaries_present_flag ?
> > + sps-
> > >sps_num_ver_virtual_boundaries :
> > + ph-
> > >ph_num_ver_virtual_boundaries,
> > + .NumHorVirtualBoundaries = sps-
> > >sps_virtual_boundaries_present_flag ?
> > + sps-
> > >sps_num_hor_virtual_boundaries :
> > + ph-
> > >ph_num_hor_virtual_boundaries,
> > + .pps_scaling_win_left_offset = pps-
> > >pps_scaling_win_left_offset,
> > + .pps_scaling_win_right_offset = pps-
> > >pps_scaling_win_right_offset,
> > + .pps_scaling_win_top_offset = pps-
> > >pps_scaling_win_top_offset,
> > + .pps_scaling_win_bottom_offset = pps-
> > >pps_scaling_win_bottom_offset,
> > + .pps_num_exp_tile_columns_minus1 = pps-
> > >pps_num_exp_tile_columns_minus1,
> > + .pps_num_exp_tile_rows_minus1 = pps-
> > >pps_num_exp_tile_rows_minus1,
> > + .pps_num_slices_in_pic_minus1 = pps-
> > >pps_num_slices_in_pic_minus1,
> > + .pps_pic_width_minus_wraparound_offset = pps-
> > >pps_pic_width_minus_wraparound_offset,
> > + .pps_cb_qp_offset = pps-
> > >pps_cb_qp_offset,
> > + .pps_cr_qp_offset = pps-
> > >pps_cr_qp_offset,
> > + .pps_joint_cbcr_qp_offset_value = pps-
> > >pps_joint_cbcr_qp_offset_value,
> > + .pps_chroma_qp_offset_list_len_minus1 = pps-
> > >pps_chroma_qp_offset_list_len_minus1,
> > + .pps_flags.bits = {
> > + .pps_loop_filter_across_tiles_enabled_flag = pps-
> > >pps_loop_filter_across_tiles_enabled_flag,
> > + .pps_rect_slice_flag = pps-
> > >pps_rect_slice_flag,
> > + .pps_single_slice_per_subpic_flag = pps-
> > >pps_single_slice_per_subpic_flag,
> > + .pps_loop_filter_across_slices_enabled_flag = pps-
> > >pps_loop_filter_across_slices_enabled_flag,
> > + .pps_weighted_pred_flag = pps-
> > >pps_weighted_pred_flag,
> > + .pps_weighted_bipred_flag = pps-
> > >pps_weighted_bipred_flag,
> > + .pps_ref_wraparound_enabled_flag = pps-
> > >pps_ref_wraparound_enabled_flag,
> > + .pps_cu_qp_delta_enabled_flag = pps-
> > >pps_cu_qp_delta_enabled_flag,
> > + .pps_cu_chroma_qp_offset_list_enabled_flag = pps-
> > >pps_cu_chroma_qp_offset_list_enabled_flag,
> > + .pps_deblocking_filter_override_enabled_flag = pps-
> > >pps_deblocking_filter_override_enabled_flag,
> > + .pps_deblocking_filter_disabled_flag = pps-
> > >pps_deblocking_filter_disabled_flag,
> > + .pps_dbf_info_in_ph_flag = pps-
> > >pps_dbf_info_in_ph_flag,
> > + .pps_sao_info_in_ph_flag = pps-
> > >pps_sao_info_in_ph_flag,
> > + .pps_alf_info_in_ph_flag = pps-
> > >pps_alf_info_in_ph_flag,
> > + },
> > + .ph_lmcs_aps_id = ph-
> > >ph_lmcs_aps_id,
> > + .ph_scaling_list_aps_id = ph-
> > >ph_scaling_list_aps_id,
> > + .ph_log2_diff_min_qt_min_cb_intra_slice_luma = ph-
> > >ph_log2_diff_min_qt_min_cb_intra_slice_luma,
> > + .ph_max_mtt_hierarchy_depth_intra_slice_luma = ph-
> > >ph_max_mtt_hierarchy_depth_intra_slice_luma,
> > + .ph_log2_diff_max_bt_min_qt_intra_slice_luma = ph-
> > >ph_log2_diff_max_bt_min_qt_intra_slice_luma,
> > + .ph_log2_diff_max_tt_min_qt_intra_slice_luma = ph-
> > >ph_log2_diff_max_tt_min_qt_intra_slice_luma,
> > + .ph_log2_diff_min_qt_min_cb_intra_slice_chroma = ph-
> > >ph_log2_diff_min_qt_min_cb_intra_slice_chroma,
> > + .ph_max_mtt_hierarchy_depth_intra_slice_chroma = ph-
> > >ph_max_mtt_hierarchy_depth_intra_slice_chroma,
> > + .ph_log2_diff_max_bt_min_qt_intra_slice_chroma = ph-
> > >ph_log2_diff_max_bt_min_qt_intra_slice_chroma,
> > + .ph_log2_diff_max_tt_min_qt_intra_slice_chroma = ph-
> > >ph_log2_diff_max_tt_min_qt_intra_slice_chroma,
> > + .ph_cu_qp_delta_subdiv_intra_slice = ph-
> > >ph_cu_qp_delta_subdiv_intra_slice,
> > + .ph_cu_chroma_qp_offset_subdiv_intra_slice = ph-
> > >ph_cu_chroma_qp_offset_subdiv_intra_slice,
> > + .ph_log2_diff_min_qt_min_cb_inter_slice = ph-
> > >ph_log2_diff_min_qt_min_cb_inter_slice,
> > + .ph_max_mtt_hierarchy_depth_inter_slice = ph-
> > >ph_max_mtt_hierarchy_depth_inter_slice,
> > + .ph_log2_diff_max_bt_min_qt_inter_slice = ph-
> > >ph_log2_diff_max_bt_min_qt_inter_slice,
> > + .ph_log2_diff_max_tt_min_qt_inter_slice = ph-
> > >ph_log2_diff_max_tt_min_qt_inter_slice,
> > + .ph_cu_qp_delta_subdiv_inter_slice = ph-
> > >ph_cu_qp_delta_subdiv_inter_slice,
> > + .ph_cu_chroma_qp_offset_subdiv_inter_slice = ph-
> > >ph_cu_chroma_qp_offset_subdiv_inter_slice,
> > + .ph_flags.bits= {
> > + .ph_non_ref_pic_flag = ph-
> > >ph_non_ref_pic_flag,
> > + .ph_alf_enabled_flag = ph-
> > >ph_alf_enabled_flag,
> > + .ph_alf_cb_enabled_flag = ph-
> > >ph_alf_cb_enabled_flag,
> > + .ph_alf_cr_enabled_flag = ph-
> > >ph_alf_cr_enabled_flag,
> > + .ph_alf_cc_cb_enabled_flag = ph-
> > >ph_alf_cc_cb_enabled_flag,
> > + .ph_alf_cc_cr_enabled_flag = ph-
> > >ph_alf_cc_cr_enabled_flag,
> > + .ph_lmcs_enabled_flag = ph-
> > >ph_lmcs_enabled_flag,
> > + .ph_chroma_residual_scale_flag = ph-
> > >ph_chroma_residual_scale_flag,
> > + .ph_explicit_scaling_list_enabled_flag = ph-
> > >ph_explicit_scaling_list_enabled_flag,
> > + .ph_virtual_boundaries_present_flag = ph-
> > >ph_virtual_boundaries_present_flag,
> > + .ph_temporal_mvp_enabled_flag = ph-
> > >ph_temporal_mvp_enabled_flag,
> > + .ph_mmvd_fullpel_only_flag = ph-
> > >ph_mmvd_fullpel_only_flag,
> > + .ph_mvd_l1_zero_flag = ph-
> > >ph_mvd_l1_zero_flag,
> > + .ph_bdof_disabled_flag = ph-
> > >ph_bdof_disabled_flag,
> > + .ph_dmvr_disabled_flag = ph-
> > >ph_dmvr_disabled_flag,
> > + .ph_prof_disabled_flag = ph-
> > >ph_prof_disabled_flag,
> > + .ph_joint_cbcr_sign_flag = ph-
> > >ph_joint_cbcr_sign_flag,
> > + .ph_sao_luma_enabled_flag = ph-
> > >ph_sao_luma_enabled_flag,
> > + .ph_sao_chroma_enabled_flag = ph-
> > >ph_sao_chroma_enabled_flag,
> > + .ph_deblocking_filter_disabled_flag = ph-
> > >ph_deblocking_filter_disabled_flag,
> > + },
> > + .PicMiscFlags.fields = {
> > + .IntraPicFlag = pps->pps_mixed_nalu_types_in_pic_flag
> > ? 0 : IS_IRAP(h) ? 1 : 0,
> > + }
> > + };
> > +
> > + fill_vaapi_pic(&pic_param->CurrPic, fc->ref);
> > + fill_vaapi_reference_frames(fc, pic_param);
> > +
> > + for (i = 0; i < VVC_MAX_SAMPLE_ARRAYS; i++)
> > + for (j = 0; j < VVC_MAX_POINTS_IN_QP_TABLE; j++)
> > + pic_param->ChromaQpTable[i][j] = fc->ps.sps-
> > >chroma_qp_table[i][j];
> > + for (i = 0; i < 4; i++) {
> > + pic_param->sps_ladf_qp_offset[i] = sps-
> > >sps_ladf_qp_offset[i];
> > + pic_param->sps_ladf_delta_threshold_minus1[i] = sps-
> > >sps_ladf_delta_threshold_minus1[i];
> > + }
> > +
> > + for (i = 0; i < (sps->sps_virtual_boundaries_present_flag ?
> > sps->sps_num_ver_virtual_boundaries : ph-
> > >ph_num_ver_virtual_boundaries); i++) {
> > + pic_param->VirtualBoundaryPosX[i] = (sps-
> > >sps_virtual_boundaries_present_flag ?
> > + (sps-
> > >sps_virtual_boundary_pos_x_minus1[ i ] + 1) :
> > + (ph-
> > >ph_virtual_boundary_pos_x_minus1[i] + 1)) * 8;
> > + }
> > +
> > + for (i = 0; i < (sps->sps_virtual_boundaries_present_flag ?
> > sps->sps_num_hor_virtual_boundaries : ph-
> > >ph_num_hor_virtual_boundaries); i++) {
> > + pic_param->VirtualBoundaryPosY[i] = (sps-
> > >sps_virtual_boundaries_present_flag ?
> > + (sps-
> > >sps_virtual_boundary_pos_y_minus1[ i ] + 1) :
> > + (ph-
> > >ph_virtual_boundary_pos_y_minus1[i] + 1)) * 8;
> > + }
> > +
> > + for (i = 0; i < 6; i++) {
> > + pic_param->pps_cb_qp_offset_list[i] = pps-
> > >pps_cb_qp_offset_list[i];
> > + pic_param->pps_cr_qp_offset_list[i] = pps-
> > >pps_cr_qp_offset_list[i];
> > + pic_param->pps_joint_cbcr_qp_offset_list[i] = pps-
> > >pps_joint_cbcr_qp_offset_list[i];
> > + }
> > +
> > + err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic,
> > +
> > VAPictureParameterBufferType,
> > + &pic->pic_param,
> > sizeof(VAPictureParameterBufferVVC));
> > + if (err < 0)
> > + goto fail;
> > +
> > + for (i = 0; i <= sps->sps_num_subpics_minus1 && sps-
> > >sps_subpic_info_present_flag; i++) {
> > + VASubPicVVC subpic_param = {
> > + .sps_subpic_ctu_top_left_x = sps-
> > >sps_subpic_ctu_top_left_x[i],
> > + .sps_subpic_ctu_top_left_y = sps-
> > >sps_subpic_ctu_top_left_y[i],
> > + .sps_subpic_width_minus1 = sps-
> > >sps_subpic_width_minus1[i],
> > + .sps_subpic_height_minus1 = sps-
> > >sps_subpic_height_minus1[i],
> > + .SubpicIdVal = pps->sub_pic_id_val[i],
> > + .subpic_flags.bits = {
> > + .sps_subpic_treated_as_pic_flag = sps-
> > >sps_subpic_treated_as_pic_flag[i],
> > + .sps_loop_filter_across_subpic_enabled_flag = sps-
> > >sps_loop_filter_across_subpic_enabled_flag[i],
> > + }
> > + };
> > + err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic,
> > +
> > VASubPicBufferType,
> > + &subpic_param,
> > sizeof(VASubPicVVC));
> > + if (err < 0)
> > + goto fail;
> > + }
> > +
> > + for (i = 0; i < VVC_MAX_ALF_COUNT; i++) {
> > + const VVCALF *alf_list = h->ps.alf_list[i];
> > + if (alf_list) {
> > + const H266RawAPS *alf = alf_list->r;
> > + VAAlfDataVVC alf_param = {
> > + .aps_adaptation_parameter_set_id = i,
> > + .alf_luma_num_filters_signalled_minus1 = alf-
> > >alf_luma_num_filters_signalled_minus1,
> > + .alf_chroma_num_alt_filters_minus1 = alf-
> > >alf_chroma_num_alt_filters_minus1,
> > + .alf_cc_cb_filters_signalled_minus1 = alf-
> > >alf_cc_cb_filters_signalled_minus1,
> > + .alf_cc_cr_filters_signalled_minus1 = alf-
> > >alf_cc_cr_filters_signalled_minus1,
> > + .alf_flags.bits = {
> > + .alf_luma_filter_signal_flag = alf-
> > >alf_luma_filter_signal_flag,
> > + .alf_chroma_filter_signal_flag = alf-
> > >alf_chroma_filter_signal_flag,
> > + .alf_cc_cb_filter_signal_flag = alf-
> > >alf_cc_cb_filter_signal_flag,
> > + .alf_cc_cr_filter_signal_flag = alf-
> > >alf_cc_cr_filter_signal_flag,
> > + .alf_luma_clip_flag = alf-
> > >alf_luma_clip_flag,
> > + .alf_chroma_clip_flag = alf-
> > >alf_chroma_clip_flag,
> > + }
> > + };
> > +
> > + for (j = 0; j < 25; j++)
> > + alf_param.alf_luma_coeff_delta_idx[j] = alf-
> > >alf_luma_coeff_delta_idx[j];
> > +
> > + for (j = 0; j < 25; j++) {
> > + for (k = 0; k < 12; k++) {
> > + alf_param.filtCoeff[j][k] = alf-
> > >alf_luma_coeff_abs[j][k] * (1 - 2 * alf-
> > >alf_luma_coeff_sign[j][k]);
> > + alf_param.alf_luma_clip_idx[j][k] = alf-
> > >alf_luma_clip_idx[j][k];
> > + }
> > + }
> > +
> > + for (j = 0; j < 8; j++) {
> > + for (k = 0; k < 6; k++) {
> > + alf_param.AlfCoeffC[j][k] = alf-
> > >alf_chroma_coeff_abs[j][k] * (1 - 2 * alf-
> > >alf_chroma_coeff_sign[j][k]);
> > + alf_param.alf_chroma_clip_idx[j][k] = alf-
> > >alf_chroma_clip_idx[j][k];
> > + }
> > + }
> > +
> > + for (j = 0; j < 4; j++) {
> > + for (k = 0; k < 7; k++) {
> > + if (alf->alf_cc_cb_mapped_coeff_abs[j][k])
> > + alf_param.CcAlfApsCoeffCb[j][k] = (1 - 2 *
> > alf->alf_cc_cb_coeff_sign[j][k]) * (1 << (alf-
> > >alf_cc_cb_mapped_coeff_abs[j][k] - 1));
> > + if (alf->alf_cc_cr_mapped_coeff_abs[j][k])
> > + alf_param.CcAlfApsCoeffCr[j][k] = (1 - 2 *
> > alf->alf_cc_cr_coeff_sign[j][k]) * (1 << (alf-
> > >alf_cc_cr_mapped_coeff_abs[j][k] - 1));
> > + }
> > + }
> > +
> > + err = ff_vaapi_decode_make_param_buffer(avctx, &pic-
> > >pic,
> > +
> > VAAlfBufferType,
> > + &alf_param,
> > sizeof(VAAlfDataVVC));
> > + if (err < 0)
> > + goto fail;
> > + }
> > + }
> > +
> > + for (i = 0; i < VVC_MAX_LMCS_COUNT; i++) {
> > + const H266RawAPS *lmcs = h->ps.lmcs_list[i];
> > + if (lmcs) {
> > + VALmcsDataVVC lmcs_param = {
> > + .aps_adaptation_parameter_set_id = i,
> > + .lmcs_min_bin_idx = lmcs-
> > >lmcs_min_bin_idx,
> > + .lmcs_delta_max_bin_idx = lmcs-
> > >lmcs_delta_max_bin_idx,
> > + .lmcsDeltaCrs = (1 - 2 * lmcs-
> > >lmcs_delta_sign_crs_flag) * lmcs->lmcs_delta_abs_crs,
> > + };
> > +
> > + for (j = lmcs->lmcs_min_bin_idx; j <= 15 - lmcs-
> > >lmcs_delta_max_bin_idx; j++)
> > + lmcs_param.lmcsDeltaCW[j] = (1 - 2 * lmcs-
> > >lmcs_delta_sign_cw_flag[j]) * lmcs->lmcs_delta_abs_cw[j];
> > +
> > + err = ff_vaapi_decode_make_param_buffer(avctx, &pic-
> > >pic,
> > +
> > VALmcsBufferType,
> > + &lmcs_param,
> > sizeof(VALmcsDataVVC));
> > + if (err < 0)
> > + goto fail;
> > + }
> > + }
> > +
> > + for (i = 0; i < VVC_MAX_SL_COUNT; i++) {
> > + const VVCScalingList *sl = h->ps.scaling_list[i];
> > + if (sl) {
> > + int l;
> > +
> > + VAScalingListVVC sl_param = {
> > + .aps_adaptation_parameter_set_id = i,
> > + };
> > +
> > + for (j = 0; j < 14; j++)
> > + sl_param.ScalingMatrixDCRec[j] = sl-
> > >scaling_matrix_dc_rec[j];
> > +
> > + for (j = 0; j < 2; j++)
> > + for (k = 0; k < 2; k++)
> > + for (l = 0; l < 2; l++)
> > + sl_param.ScalingMatrixRec2x2[j][k][l] =
> > sl->scaling_matrix_rec[j][l * 2 + k];
> > +
> > + for (j = 2; j < 8; j++)
> > + for (k = 0; k < 4; k++)
> > + for (l = 0; l < 4; l++)
> > + sl_param.ScalingMatrixRec4x4[j - 2][k][l]
> > = sl->scaling_matrix_rec[j][l * 4 + k];
> > +
> > + for (j = 8; j < 28; j++)
> > + for (k = 0; k < 8; k++)
> > + for (l = 0; l < 8; l++)
> > + sl_param.ScalingMatrixRec8x8[j - 8][k][l]
> > = sl->scaling_matrix_rec[j][l * 8 + k];
> > +
> > + err = ff_vaapi_decode_make_param_buffer(avctx, &pic-
> > >pic,
> > +
> > VAIQMatrixBufferType,
> > + &sl_param,
> > sizeof(VAScalingListVVC));
> > + if (err < 0)
> > + goto fail;
> > + }
> > + }
> > +
> > + for (i = 0; i <= pps->pps_num_exp_tile_columns_minus1; i++) {
> > + tile_dim = pps->pps_tile_column_width_minus1[i];
> > + err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic,
> > + VATileBufferType,
> > + &tile_dim,
> > sizeof(tile_dim));
> > + if (err < 0)
> > + goto fail;
> > + }
> > +
> > + for (i = 0; i <= pps->pps_num_exp_tile_rows_minus1; i++) {
> > + tile_dim = pps->pps_tile_row_height_minus1[i];
> > + err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic,
> > + VATileBufferType,
> > + &tile_dim,
> > sizeof(tile_dim));
> > + if (err < 0)
> > + goto fail;
> > + }
> > +
> > + if (!pps->pps_no_pic_partition_flag && pps-
> > >pps_rect_slice_flag && !pps->pps_single_slice_per_subpic_flag) {
> > + for (i = 0; i <= pps->pps_num_slices_in_pic_minus1; i++) {
> > + for (j = 0; j < pps->pps_num_exp_slices_in_tile[i];
> > j++) {
> > + exp_slice_height_in_ctus[i + j] = pps-
> > >pps_exp_slice_height_in_ctus_minus1[i][j] + 1;
> > + }
> > + }
> > + for (i = 0; i <= pps->pps_num_slices_in_pic_minus1; i++) {
> > + VASliceStructVVC ss_param = {
> > + .SliceTopLeftTileIdx = pps-
> > >slice_top_left_tile_idx[i],
> > + .pps_slice_width_in_tiles_minus1 = pps-
> > >pps_slice_width_in_tiles_minus1[i],
> > + .pps_slice_height_in_tiles_minus1 = pps-
> > >pps_slice_height_in_tiles_minus1[i],
> > + };
> > +
> > + if (pps->pps_slice_width_in_tiles_minus1[i] > 0 ||
> > pps->pps_slice_height_in_tiles_minus1[i] > 0)
> > + ss_param.pps_exp_slice_height_in_ctus_minus1 = 0;
> > + else {
> > + if (pps->num_slices_in_tile[i] == 1)
> > + ss_param.pps_exp_slice_height_in_ctus_minus1 =
> > pps->row_height_val[pps->slice_top_left_tile_idx[i] / pps-
> > >num_tile_columns] - 1;
> > + else if (exp_slice_height_in_ctus[i])
> > + ss_param.pps_exp_slice_height_in_ctus_minus1 =
> > exp_slice_height_in_ctus[i] - 1;
> > + else
> > + continue;
> > + }
> > +
> > + err = ff_vaapi_decode_make_param_buffer(avctx, &pic-
> > >pic,
> > +
> > VASliceStructBufferType,
> > + &ss_param,
> > sizeof(VASliceStructVVC));
> > + if (err < 0)
> > + goto fail;
> > + }
> > + }
> > +
> > + return 0;
> > +
> > +fail:
> > + ff_vaapi_decode_cancel(avctx, &pic->pic);
> > + return err;
> > +}
> > +
> > +static uint8_t get_ref_pic_index(const VVCContext *h, const
> > VVCFrame *frame)
> > +{
> > + VVCFrameContext *fc = &h->fcs[(h->nb_frames + h-
> > >nb_fcs) % h->nb_fcs];
> > + VAAPIDecodePictureVVC *pic = fc->ref-
> > >hwaccel_picture_private;
> > + VAPictureParameterBufferVVC *pp = (VAPictureParameterBufferVVC
> > *)&pic->pic_param;
> > + uint8_t i;
> > +
> > + if (!frame)
> > + return 0xFF;
> > +
> > + for (i = 0; i < FF_ARRAY_ELEMS(pp->ReferenceFrames); i++) {
> > + VASurfaceID pid = pp->ReferenceFrames[i].picture_id;
> > + int poc = pp->ReferenceFrames[i].pic_order_cnt;
> > + if (pid != VA_INVALID_ID && pid ==
> > ff_vaapi_get_surface_id(frame->frame) && poc == frame->poc)
> > + return i;
> > + }
> > +
> > + return 0xFF;
> > +}
> > +
> > +static int get_slice_data_offset(const uint8_t *buffer, uint32_t
> > size, const SliceContext* sc)
> > +{
> > + const H266RawSlice *slice = sc->ref;
> > + int num_identical_bytes = slice->data_size < 32 ? slice-
> > >data_size : 32;
> > +
> > + for (int i = 0; i < size; i++) {
> > + int skip_bytes = 0;
> > + if (i >=2 && buffer[i] == 0x03 && !buffer[i - 1] &&
> > !buffer[i - 2])
> > + continue;
> > +
> > + for (int j = 0; j < num_identical_bytes; j++) {
> > + if (i >= 2 && buffer[i + j + skip_bytes] == 0x03 &&
> > !buffer[i + j + skip_bytes - 1] && !buffer[i + j + skip_bytes - 2])
> > + skip_bytes++;
> > +
> > + if (buffer[i + j + skip_bytes] != slice->data[j])
> > + break;
> > +
> > + if (j + 1 == num_identical_bytes)
> > + return i;
> > + }
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int vaapi_vvc_decode_slice(AVCodecContext *avctx,
> > + const uint8_t *buffer,
> > + uint32_t size)
> > +{
> > + const VVCContext *h = avctx->priv_data;
> > + VVCFrameContext *fc = &h->fcs[(h->nb_frames
> > + h->nb_fcs) % h->nb_fcs];
> > + const SliceContext *sc = fc->slices[fc-
> > >nb_slices];
> > + const H266RawPPS *pps = fc->ps.pps->r;
> > + const H266RawPictureHeader *ph = fc->ps.ph.r;
> > + const H266RawSliceHeader *sh = sc->sh.r;
> > + VAAPIDecodePictureVVC *pic = fc->ref-
> > >hwaccel_picture_private;
> > + VASliceParameterBufferVVC *slice_param = &pic->slice_param;
> > + int nb_list, i, err;
> > +
> > + *slice_param = (VASliceParameterBufferVVC) {
> > + .slice_data_size = size,
> > + .slice_data_offset = 0,
> > + .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
> > + .slice_data_byte_offset =
> > get_slice_data_offset(buffer, size, sc),
> > + .sh_subpic_id = sh->sh_subpic_id,
> > + .sh_slice_address = sh->sh_slice_address,
> > + .sh_num_tiles_in_slice_minus1 = sh-
> > >sh_num_tiles_in_slice_minus1,
> > + .sh_slice_type = sh->sh_slice_type,
> > + .sh_num_alf_aps_ids_luma = sh-
> > >sh_num_alf_aps_ids_luma,
> > + .sh_alf_aps_id_chroma = sh-
> > >sh_alf_aps_id_chroma,
> > + .sh_alf_cc_cb_aps_id = sh-
> > >sh_alf_cc_cb_aps_id,
> > + .sh_alf_cc_cr_aps_id = sh-
> > >sh_alf_cc_cr_aps_id,
> > + .NumRefIdxActive[0] = sh-
> > >num_ref_idx_active[0],
> > + .NumRefIdxActive[1] = sh-
> > >num_ref_idx_active[1],
> > + .sh_collocated_ref_idx = sh-
> > >sh_collocated_ref_idx,
> > + .SliceQpY = pps-
> > >pps_qp_delta_info_in_ph_flag ?
> > + 26 + pps-
> > >pps_init_qp_minus26 + ph->ph_qp_delta :
> > + 26 + pps-
> > >pps_init_qp_minus26 + sh->sh_qp_delta,
> > + .sh_cb_qp_offset = sh->sh_cb_qp_offset,
> > + .sh_cr_qp_offset = sh->sh_cr_qp_offset,
> > + .sh_joint_cbcr_qp_offset = sh-
> > >sh_joint_cbcr_qp_offset,
> > + .sh_luma_beta_offset_div2 = sh-
> > >sh_luma_beta_offset_div2,
> > + .sh_luma_tc_offset_div2 = sh-
> > >sh_luma_tc_offset_div2,
> > + .sh_cb_beta_offset_div2 = sh-
> > >sh_cb_beta_offset_div2,
> > + .sh_cb_tc_offset_div2 = sh-
> > >sh_cb_tc_offset_div2,
> > + .sh_cr_beta_offset_div2 = sh-
> > >sh_cr_beta_offset_div2,
> > + .sh_cr_tc_offset_div2 = sh-
> > >sh_cr_tc_offset_div2,
> > + .WPInfo = {
> > + .luma_log2_weight_denom = sh-
> > >sh_pred_weight_table.luma_log2_weight_denom,
> > + .delta_chroma_log2_weight_denom = sh-
> > >sh_pred_weight_table.delta_chroma_log2_weight_denom,
> > + .num_l0_weights = sh-
> > >sh_pred_weight_table.num_l0_weights,
> > + .num_l1_weights = sh-
> > >sh_pred_weight_table.num_l1_weights,
> > + },
> > + .sh_flags.bits = {
> > + .sh_alf_enabled_flag = sh-
> > >sh_alf_enabled_flag,
> > + .sh_alf_cb_enabled_flag = sh-
> > >sh_alf_cb_enabled_flag,
> > + .sh_alf_cr_enabled_flag = sh-
> > >sh_alf_cr_enabled_flag,
> > + .sh_alf_cc_cb_enabled_flag = sh-
> > >sh_alf_cc_cb_enabled_flag,
> > + .sh_alf_cc_cr_enabled_flag = sh-
> > >sh_alf_cc_cr_enabled_flag,
> > + .sh_lmcs_used_flag = sh-
> > >sh_lmcs_used_flag,
> > + .sh_explicit_scaling_list_used_flag = sh-
> > >sh_explicit_scaling_list_used_flag,
> > + .sh_cabac_init_flag = sh-
> > >sh_cabac_init_flag,
> > + .sh_collocated_from_l0_flag = sh-
> > >sh_collocated_from_l0_flag,
> > + .sh_cu_chroma_qp_offset_enabled_flag = sh-
> > >sh_cu_chroma_qp_offset_enabled_flag,
> > + .sh_sao_luma_used_flag = sh-
> > >sh_sao_luma_used_flag,
> > + .sh_sao_chroma_used_flag = sh-
> > >sh_sao_chroma_used_flag,
> > + .sh_deblocking_filter_disabled_flag = sh-
> > >sh_deblocking_filter_disabled_flag,
> > + .sh_dep_quant_used_flag = sh-
> > >sh_dep_quant_used_flag,
> > + .sh_sign_data_hiding_used_flag = sh-
> > >sh_sign_data_hiding_used_flag,
> > + .sh_ts_residual_coding_disabled_flag = sh-
> > >sh_ts_residual_coding_disabled_flag,
> > + },
> > + };
> > +
> > + memset(&slice_param->RefPicList, 0xFF, sizeof(slice_param-
> > >RefPicList));
> > +
> > + nb_list = (sh->sh_slice_type == VVC_SLICE_TYPE_B) ?
> > + 2 : (sh->sh_slice_type == VVC_SLICE_TYPE_I ? 0 : 1);
> > + for (int list_idx = 0; list_idx < nb_list; list_idx++) {
> > + RefPicList *rpl = &sc->rpl[list_idx];
> > +
> > + for (i = 0; i < rpl->nb_refs; i++)
> > + slice_param->RefPicList[list_idx][i] =
> > get_ref_pic_index(h, rpl->ref[i]);
> > + }
> > +
> > + for (i = 0; i < 7; i++)
> > + slice_param->sh_alf_aps_id_luma[i] = sh-
> > >sh_alf_aps_id_luma[i];
> > +
> > + for (i = 0; i < 15; i++) {
> > + slice_param->WPInfo.luma_weight_l0_flag[i] = sh-
> > >sh_pred_weight_table.luma_weight_l0_flag[i];
> > + slice_param->WPInfo.chroma_weight_l0_flag[i] = sh-
> > >sh_pred_weight_table.chroma_weight_l0_flag[i];
> > + slice_param->WPInfo.delta_luma_weight_l0[i] = sh-
> > >sh_pred_weight_table.delta_luma_weight_l0[i];
> > + slice_param->WPInfo.luma_offset_l0[i] = sh-
> > >sh_pred_weight_table.luma_offset_l0[i];
> > + slice_param->WPInfo.luma_weight_l1_flag[i] = sh-
> > >sh_pred_weight_table.luma_weight_l1_flag[i];
> > + slice_param->WPInfo.chroma_weight_l1_flag[i] = sh-
> > >sh_pred_weight_table.chroma_weight_l1_flag[i];
> > + slice_param->WPInfo.delta_luma_weight_l1[i] = sh-
> > >sh_pred_weight_table.delta_luma_weight_l1[i];
> > + slice_param->WPInfo.luma_offset_l1[i] = sh-
> > >sh_pred_weight_table.luma_offset_l1[i];
> > + }
> > +
> > + for (i = 0; i < 15; i++) {
> > + for (int j = 0; j < 2; j++) {
> > + slice_param->WPInfo.delta_chroma_weight_l0[i][j] = sh-
> > >sh_pred_weight_table.delta_chroma_weight_l0[i][j];
> > + slice_param->WPInfo.delta_chroma_offset_l0[i][j] = sh-
> > >sh_pred_weight_table.delta_chroma_offset_l0[i][j];
> > + slice_param->WPInfo.delta_chroma_weight_l1[i][j] = sh-
> > >sh_pred_weight_table.delta_chroma_weight_l1[i][j];
> > + slice_param->WPInfo.delta_chroma_offset_l1[i][j] = sh-
> > >sh_pred_weight_table.delta_chroma_offset_l1[i][j];
> > + }
> > + }
> > +
> > + err = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
> > + &pic->slice_param,
> > +
> > sizeof(VASliceParameterBufferVVC),
> > + buffer, size);
> > + if (err) {
> > + ff_vaapi_decode_cancel(avctx, &pic->pic);
> > + return err;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int vaapi_vvc_end_frame(AVCodecContext *avctx)
> > +{
> > +
> > + const VVCContext *h = avctx->priv_data;
> > + VVCFrameContext *fc = &h->fcs[(h->nb_frames + h-
> > >nb_fcs) % h->nb_fcs];
> > + VAAPIDecodePictureVVC *pic = fc->ref->hwaccel_picture_private;
> > + int ret;
> > +
> > + ret = ff_vaapi_decode_issue(avctx, &pic->pic);
> > + if (ret < 0)
> > + goto fail;
> > +
> > + pic->decode_issued = 1;
> > +
> > + return 0;
> > +
> > +fail:
> > + ff_vaapi_decode_cancel(avctx, &pic->pic);
> > + return ret;
> > +}
> > +
> > +const FFHWAccel ff_vvc_vaapi_hwaccel = {
> > + .p.name = "vvc_vaapi",
> > + .p.type = AVMEDIA_TYPE_VIDEO,
> > + .p.id = AV_CODEC_ID_VVC,
> > + .p.pix_fmt = AV_PIX_FMT_VAAPI,
> > + .start_frame = &vaapi_vvc_start_frame,
> > + .end_frame = &vaapi_vvc_end_frame,
> > + .decode_slice = &vaapi_vvc_decode_slice,
> > + .frame_priv_data_size = sizeof(VAAPIDecodePictureVVC),
> > + .init = &ff_vaapi_decode_init,
> > + .uninit = &ff_vaapi_decode_uninit,
> > + .frame_params = &ff_vaapi_common_frame_params,
> > + .priv_data_size = sizeof(VAAPIDecodeContext),
> > + .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
> > +};
> > diff --git a/libavcodec/version.h b/libavcodec/version.h
> > index 06631ffa8c..7aa95fc3f1 100644
> > --- a/libavcodec/version.h
> > +++ b/libavcodec/version.h
> > @@ -29,7 +29,7 @@
> >
> > #include "version_major.h"
> >
> > -#define LIBAVCODEC_VERSION_MINOR 4
> > +#define LIBAVCODEC_VERSION_MINOR 5
> > #define LIBAVCODEC_VERSION_MICRO 100
> >
> > #define LIBAVCODEC_VERSION_INT
> > AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
> > diff --git a/libavcodec/vvc/vvcdec.c b/libavcodec/vvc/vvcdec.c
> > index f2e269ce76..b204a0c73a 100644
> > --- a/libavcodec/vvc/vvcdec.c
> > +++ b/libavcodec/vvc/vvcdec.c
> > @@ -29,6 +29,7 @@
> > #include "libavutil/cpu.h"
> > #include "libavutil/thread.h"
> >
> > +#include "config_components.h"
> > #include "vvcdec.h"
> > #include "vvc_ctu.h"
> > #include "vvc_data.h"
> > @@ -724,14 +725,20 @@ static int slice_start(SliceContext *sc,
> > VVCContext *s, VVCFrameContext *fc,
> >
> > static enum AVPixelFormat get_format(AVCodecContext *avctx, const
> > VVCSPS *sps)
> > {
> > -#define HWACCEL_MAX 0
> > +#define HWACCEL_MAX CONFIG_VVC_VAAPI_HWACCEL
> >
> > enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts;
> >
> > switch (sps->pix_fmt) {
> > case AV_PIX_FMT_YUV420P:
> > +#if CONFIG_VVC_VAAPI_HWACCEL
> > + *fmt++ = AV_PIX_FMT_VAAPI;
> > +#endif
> > break;
> > case AV_PIX_FMT_YUV420P10:
> > +#if CONFIG_VVC_VAAPI_HWACCEL
> > + *fmt++ = AV_PIX_FMT_VAAPI;
> > +#endif
> > break;
> > }
> >
> > @@ -1100,4 +1107,10 @@ const FFCodec ff_vvc_decoder = {
> > .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING |
> > FF_CODEC_CAP_INIT_CLEANUP |
> > FF_CODEC_CAP_AUTO_THREADS,
> > .p.profiles = NULL_IF_CONFIG_SMALL(ff_vvc_profiles),
> > + .hw_configs = (const AVCodecHWConfigInternal *const []) {
> > +#if CONFIG_VVC_VAAPI_HWACCEL
> > + HWACCEL_VAAPI(vvc),
> > +#endif
> > + NULL
> > + },
> > };
More information about the ffmpeg-devel
mailing list