| Line | Branch | Exec | Source | 
|---|---|---|---|
| 1 | /* | ||
| 2 | * VVC HW decode acceleration through VA API | ||
| 3 | * | ||
| 4 | * Copyright (c) 2024 Intel Corporation | ||
| 5 | * | ||
| 6 | * This file is part of FFmpeg. | ||
| 7 | * | ||
| 8 | * FFmpeg is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU Lesser General Public | ||
| 10 | * License as published by the Free Software Foundation; either | ||
| 11 | * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | * | ||
| 13 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | * Lesser General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU Lesser General Public | ||
| 19 | * License along with FFmpeg; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <va/va.h> | ||
| 24 | #include <va/va_dec_vvc.h> | ||
| 25 | |||
| 26 | #include "vvc/dec.h" | ||
| 27 | #include "vvc/refs.h" | ||
| 28 | #include "hwaccel_internal.h" | ||
| 29 | #include "vaapi_decode.h" | ||
| 30 | |||
| 31 | typedef struct VAAPIDecodePictureVVC { | ||
| 32 | VAAPIDecodePicture pic; | ||
| 33 | VAPictureParameterBufferVVC pic_param; | ||
| 34 | VASliceParameterBufferVVC slice_param; | ||
| 35 | int decode_issued; | ||
| 36 | } VAAPIDecodePictureVVC; | ||
| 37 | |||
| 38 | ✗ | static void init_vaapi_pic(VAPictureVVC *va_pic) | |
| 39 | { | ||
| 40 | ✗ | va_pic->picture_id = VA_INVALID_ID; | |
| 41 | ✗ | va_pic->flags = VA_PICTURE_VVC_INVALID; | |
| 42 | ✗ | va_pic->pic_order_cnt = 0; | |
| 43 | ✗ | } | |
| 44 | |||
| 45 | ✗ | static void fill_vaapi_pic(VAPictureVVC *va_pic, const VVCFrame *pic) | |
| 46 | { | ||
| 47 | ✗ | va_pic->picture_id = ff_vaapi_get_surface_id(pic->frame); | |
| 48 | ✗ | va_pic->pic_order_cnt = pic->poc; | |
| 49 | ✗ | va_pic->flags = 0; | |
| 50 | |||
| 51 | ✗ | if (pic->flags & VVC_FRAME_FLAG_LONG_REF) | |
| 52 | ✗ | va_pic->flags |= VA_PICTURE_VVC_LONG_TERM_REFERENCE; | |
| 53 | ✗ | } | |
| 54 | |||
| 55 | ✗ | static void fill_vaapi_reference_frames(const VVCFrameContext *h, VAPictureParameterBufferVVC *pp) | |
| 56 | { | ||
| 57 | ✗ | const VVCFrame *current_picture = h->ref; | |
| 58 | int i, j; | ||
| 59 | |||
| 60 | ✗ | for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->ReferenceFrames); i++) { | |
| 61 | ✗ | const VVCFrame *frame = NULL; | |
| 62 | |||
| 63 | ✗ | while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) { | |
| 64 | ✗ | if ((&h->DPB[j] != current_picture ) && | |
| 65 | ✗ | (h->DPB[j].flags & (VVC_FRAME_FLAG_LONG_REF | VVC_FRAME_FLAG_SHORT_REF))) | |
| 66 | ✗ | frame = &h->DPB[j]; | |
| 67 | ✗ | j++; | |
| 68 | } | ||
| 69 | |||
| 70 | ✗ | init_vaapi_pic(&pp->ReferenceFrames[i]); | |
| 71 | |||
| 72 | ✗ | if (frame) { | |
| 73 | VAAPIDecodePictureVVC *pic; | ||
| 74 | ✗ | fill_vaapi_pic(&pp->ReferenceFrames[i], frame); | |
| 75 | ✗ | pic = frame->hwaccel_picture_private; | |
| 76 | ✗ | if (!pic->decode_issued) | |
| 77 | ✗ | pp->ReferenceFrames[i].flags |= VA_PICTURE_VVC_UNAVAILABLE_REFERENCE; | |
| 78 | } | ||
| 79 | } | ||
| 80 | ✗ | } | |
| 81 | |||
| 82 | ✗ | static int vaapi_vvc_start_frame(AVCodecContext *avctx, | |
| 83 | av_unused const AVBufferRef *buffer_ref, | ||
| 84 | av_unused const uint8_t *buffer, | ||
| 85 | av_unused uint32_t size) | ||
| 86 | { | ||
| 87 | ✗ | const VVCContext *h = avctx->priv_data; | |
| 88 | ✗ | VVCFrameContext *fc = &h->fcs[(h->nb_frames + h->nb_fcs) % h->nb_fcs]; | |
| 89 | ✗ | const H266RawSPS *sps = fc->ps.sps->r; | |
| 90 | ✗ | const H266RawPPS *pps = fc->ps.pps->r; | |
| 91 | ✗ | const H266RawPictureHeader *ph = fc->ps.ph.r; | |
| 92 | ✗ | VAAPIDecodePictureVVC *pic = fc->ref->hwaccel_picture_private; | |
| 93 | ✗ | VAPictureParameterBufferVVC *pic_param = &pic->pic_param; | |
| 94 | ✗ | uint16_t tile_dim, exp_slice_height_in_ctus[VVC_MAX_SLICES] = {0}; | |
| 95 | int i, j, k, err; | ||
| 96 | |||
| 97 | ✗ | pic->pic.output_surface = ff_vaapi_get_surface_id(fc->ref->frame); | |
| 98 | |||
| 99 | ✗ | *pic_param = (VAPictureParameterBufferVVC) { | |
| 100 | ✗ | .pps_pic_width_in_luma_samples = pps->pps_pic_width_in_luma_samples, | |
| 101 | ✗ | .pps_pic_height_in_luma_samples = pps->pps_pic_height_in_luma_samples, | |
| 102 | ✗ | .sps_num_subpics_minus1 = sps->sps_num_subpics_minus1, | |
| 103 | ✗ | .sps_chroma_format_idc = sps->sps_chroma_format_idc, | |
| 104 | ✗ | .sps_bitdepth_minus8 = sps->sps_bitdepth_minus8, | |
| 105 | ✗ | .sps_log2_ctu_size_minus5 = sps->sps_log2_ctu_size_minus5, | |
| 106 | ✗ | .sps_log2_min_luma_coding_block_size_minus2 = sps->sps_log2_min_luma_coding_block_size_minus2, | |
| 107 | ✗ | .sps_log2_transform_skip_max_size_minus2 = sps->sps_log2_transform_skip_max_size_minus2, | |
| 108 | ✗ | .sps_six_minus_max_num_merge_cand = sps->sps_six_minus_max_num_merge_cand, | |
| 109 | ✗ | .sps_five_minus_max_num_subblock_merge_cand = sps->sps_five_minus_max_num_subblock_merge_cand, | |
| 110 | ✗ | .sps_max_num_merge_cand_minus_max_num_gpm_cand = sps->sps_max_num_merge_cand_minus_max_num_gpm_cand, | |
| 111 | ✗ | .sps_log2_parallel_merge_level_minus2 = sps->sps_log2_parallel_merge_level_minus2, | |
| 112 | ✗ | .sps_min_qp_prime_ts = sps->sps_min_qp_prime_ts, | |
| 113 | ✗ | .sps_six_minus_max_num_ibc_merge_cand = sps->sps_six_minus_max_num_ibc_merge_cand, | |
| 114 | ✗ | .sps_num_ladf_intervals_minus2 = sps->sps_num_ladf_intervals_minus2, | |
| 115 | ✗ | .sps_ladf_lowest_interval_qp_offset = sps->sps_ladf_lowest_interval_qp_offset, | |
| 116 | .sps_flags.bits = { | ||
| 117 | ✗ | .sps_subpic_info_present_flag = sps->sps_subpic_info_present_flag, | |
| 118 | ✗ | .sps_independent_subpics_flag = sps->sps_independent_subpics_flag, | |
| 119 | ✗ | .sps_subpic_same_size_flag = sps->sps_subpic_same_size_flag, | |
| 120 | ✗ | .sps_entropy_coding_sync_enabled_flag = sps->sps_entropy_coding_sync_enabled_flag, | |
| 121 | ✗ | .sps_qtbtt_dual_tree_intra_flag = sps->sps_qtbtt_dual_tree_intra_flag, | |
| 122 | ✗ | .sps_max_luma_transform_size_64_flag = sps->sps_max_luma_transform_size_64_flag, | |
| 123 | ✗ | .sps_transform_skip_enabled_flag = sps->sps_transform_skip_enabled_flag, | |
| 124 | ✗ | .sps_bdpcm_enabled_flag = sps->sps_bdpcm_enabled_flag, | |
| 125 | ✗ | .sps_mts_enabled_flag = sps->sps_mts_enabled_flag, | |
| 126 | ✗ | .sps_explicit_mts_intra_enabled_flag = sps->sps_explicit_mts_intra_enabled_flag, | |
| 127 | ✗ | .sps_explicit_mts_inter_enabled_flag = sps->sps_explicit_mts_inter_enabled_flag, | |
| 128 | ✗ | .sps_lfnst_enabled_flag = sps->sps_lfnst_enabled_flag, | |
| 129 | ✗ | .sps_joint_cbcr_enabled_flag = sps->sps_joint_cbcr_enabled_flag, | |
| 130 | ✗ | .sps_same_qp_table_for_chroma_flag = sps->sps_same_qp_table_for_chroma_flag, | |
| 131 | ✗ | .sps_sao_enabled_flag = sps->sps_sao_enabled_flag, | |
| 132 | ✗ | .sps_alf_enabled_flag = sps->sps_alf_enabled_flag, | |
| 133 | ✗ | .sps_ccalf_enabled_flag = sps->sps_ccalf_enabled_flag, | |
| 134 | ✗ | .sps_lmcs_enabled_flag = sps->sps_lmcs_enabled_flag, | |
| 135 | ✗ | .sps_sbtmvp_enabled_flag = sps->sps_sbtmvp_enabled_flag, | |
| 136 | ✗ | .sps_amvr_enabled_flag = sps->sps_amvr_enabled_flag, | |
| 137 | ✗ | .sps_smvd_enabled_flag = sps->sps_smvd_enabled_flag, | |
| 138 | ✗ | .sps_mmvd_enabled_flag = sps->sps_mmvd_enabled_flag, | |
| 139 | ✗ | .sps_sbt_enabled_flag = sps->sps_sbt_enabled_flag, | |
| 140 | ✗ | .sps_affine_enabled_flag = sps->sps_affine_enabled_flag, | |
| 141 | ✗ | .sps_6param_affine_enabled_flag = sps->sps_6param_affine_enabled_flag, | |
| 142 | ✗ | .sps_affine_amvr_enabled_flag = sps->sps_affine_amvr_enabled_flag, | |
| 143 | ✗ | .sps_affine_prof_enabled_flag = sps->sps_affine_prof_enabled_flag, | |
| 144 | ✗ | .sps_bcw_enabled_flag = sps->sps_bcw_enabled_flag, | |
| 145 | ✗ | .sps_ciip_enabled_flag = sps->sps_ciip_enabled_flag, | |
| 146 | ✗ | .sps_gpm_enabled_flag = sps->sps_gpm_enabled_flag, | |
| 147 | ✗ | .sps_isp_enabled_flag = sps->sps_isp_enabled_flag, | |
| 148 | ✗ | .sps_mrl_enabled_flag = sps->sps_mrl_enabled_flag, | |
| 149 | ✗ | .sps_mip_enabled_flag = sps->sps_mip_enabled_flag, | |
| 150 | ✗ | .sps_cclm_enabled_flag = sps->sps_cclm_enabled_flag, | |
| 151 | ✗ | .sps_chroma_horizontal_collocated_flag = sps->sps_chroma_horizontal_collocated_flag, | |
| 152 | ✗ | .sps_chroma_vertical_collocated_flag = sps->sps_chroma_vertical_collocated_flag, | |
| 153 | ✗ | .sps_palette_enabled_flag = sps->sps_palette_enabled_flag, | |
| 154 | ✗ | .sps_act_enabled_flag = sps->sps_act_enabled_flag, | |
| 155 | ✗ | .sps_ibc_enabled_flag = sps->sps_ibc_enabled_flag, | |
| 156 | ✗ | .sps_ladf_enabled_flag = sps->sps_ladf_enabled_flag, | |
| 157 | ✗ | .sps_explicit_scaling_list_enabled_flag = sps->sps_explicit_scaling_list_enabled_flag, | |
| 158 | ✗ | .sps_scaling_matrix_for_lfnst_disabled_flag = sps->sps_scaling_matrix_for_lfnst_disabled_flag, | |
| 159 | ✗ | .sps_scaling_matrix_for_alternative_colour_space_disabled_flag = sps->sps_scaling_matrix_for_alternative_colour_space_disabled_flag, | |
| 160 | ✗ | .sps_scaling_matrix_designated_colour_space_flag = sps->sps_scaling_matrix_designated_colour_space_flag, | |
| 161 | ✗ | .sps_virtual_boundaries_enabled_flag = sps->sps_virtual_boundaries_enabled_flag, | |
| 162 | ✗ | .sps_virtual_boundaries_present_flag = sps->sps_virtual_boundaries_present_flag, | |
| 163 | }, | ||
| 164 | ✗ | .NumVerVirtualBoundaries = sps->sps_virtual_boundaries_present_flag ? | |
| 165 | sps->sps_num_ver_virtual_boundaries : | ||
| 166 | ph->ph_num_ver_virtual_boundaries, | ||
| 167 | ✗ | .NumHorVirtualBoundaries = sps->sps_virtual_boundaries_present_flag ? | |
| 168 | sps->sps_num_hor_virtual_boundaries : | ||
| 169 | ph->ph_num_hor_virtual_boundaries, | ||
| 170 | ✗ | .pps_scaling_win_left_offset = pps->pps_scaling_win_left_offset, | |
| 171 | ✗ | .pps_scaling_win_right_offset = pps->pps_scaling_win_right_offset, | |
| 172 | ✗ | .pps_scaling_win_top_offset = pps->pps_scaling_win_top_offset, | |
| 173 | ✗ | .pps_scaling_win_bottom_offset = pps->pps_scaling_win_bottom_offset, | |
| 174 | ✗ | .pps_num_exp_tile_columns_minus1 = pps->pps_num_exp_tile_columns_minus1, | |
| 175 | ✗ | .pps_num_exp_tile_rows_minus1 = pps->pps_num_exp_tile_rows_minus1, | |
| 176 | ✗ | .pps_num_slices_in_pic_minus1 = pps->pps_num_slices_in_pic_minus1, | |
| 177 | ✗ | .pps_pic_width_minus_wraparound_offset = pps->pps_pic_width_minus_wraparound_offset, | |
| 178 | ✗ | .pps_cb_qp_offset = pps->pps_cb_qp_offset, | |
| 179 | ✗ | .pps_cr_qp_offset = pps->pps_cr_qp_offset, | |
| 180 | ✗ | .pps_joint_cbcr_qp_offset_value = pps->pps_joint_cbcr_qp_offset_value, | |
| 181 | ✗ | .pps_chroma_qp_offset_list_len_minus1 = pps->pps_chroma_qp_offset_list_len_minus1, | |
| 182 | .pps_flags.bits = { | ||
| 183 | ✗ | .pps_loop_filter_across_tiles_enabled_flag = pps->pps_loop_filter_across_tiles_enabled_flag, | |
| 184 | ✗ | .pps_rect_slice_flag = pps->pps_rect_slice_flag, | |
| 185 | ✗ | .pps_single_slice_per_subpic_flag = pps->pps_single_slice_per_subpic_flag, | |
| 186 | ✗ | .pps_loop_filter_across_slices_enabled_flag = pps->pps_loop_filter_across_slices_enabled_flag, | |
| 187 | ✗ | .pps_weighted_pred_flag = pps->pps_weighted_pred_flag, | |
| 188 | ✗ | .pps_weighted_bipred_flag = pps->pps_weighted_bipred_flag, | |
| 189 | ✗ | .pps_ref_wraparound_enabled_flag = pps->pps_ref_wraparound_enabled_flag, | |
| 190 | ✗ | .pps_cu_qp_delta_enabled_flag = pps->pps_cu_qp_delta_enabled_flag, | |
| 191 | ✗ | .pps_cu_chroma_qp_offset_list_enabled_flag = pps->pps_cu_chroma_qp_offset_list_enabled_flag, | |
| 192 | ✗ | .pps_deblocking_filter_override_enabled_flag = pps->pps_deblocking_filter_override_enabled_flag, | |
| 193 | ✗ | .pps_deblocking_filter_disabled_flag = pps->pps_deblocking_filter_disabled_flag, | |
| 194 | ✗ | .pps_dbf_info_in_ph_flag = pps->pps_dbf_info_in_ph_flag, | |
| 195 | ✗ | .pps_sao_info_in_ph_flag = pps->pps_sao_info_in_ph_flag, | |
| 196 | ✗ | .pps_alf_info_in_ph_flag = pps->pps_alf_info_in_ph_flag, | |
| 197 | }, | ||
| 198 | ✗ | .ph_lmcs_aps_id = ph->ph_lmcs_aps_id, | |
| 199 | ✗ | .ph_scaling_list_aps_id = ph->ph_scaling_list_aps_id, | |
| 200 | ✗ | .ph_log2_diff_min_qt_min_cb_intra_slice_luma = ph->ph_log2_diff_min_qt_min_cb_intra_slice_luma, | |
| 201 | ✗ | .ph_max_mtt_hierarchy_depth_intra_slice_luma = ph->ph_max_mtt_hierarchy_depth_intra_slice_luma, | |
| 202 | ✗ | .ph_log2_diff_max_bt_min_qt_intra_slice_luma = ph->ph_log2_diff_max_bt_min_qt_intra_slice_luma, | |
| 203 | ✗ | .ph_log2_diff_max_tt_min_qt_intra_slice_luma = ph->ph_log2_diff_max_tt_min_qt_intra_slice_luma, | |
| 204 | ✗ | .ph_log2_diff_min_qt_min_cb_intra_slice_chroma = ph->ph_log2_diff_min_qt_min_cb_intra_slice_chroma, | |
| 205 | ✗ | .ph_max_mtt_hierarchy_depth_intra_slice_chroma = ph->ph_max_mtt_hierarchy_depth_intra_slice_chroma, | |
| 206 | ✗ | .ph_log2_diff_max_bt_min_qt_intra_slice_chroma = ph->ph_log2_diff_max_bt_min_qt_intra_slice_chroma, | |
| 207 | ✗ | .ph_log2_diff_max_tt_min_qt_intra_slice_chroma = ph->ph_log2_diff_max_tt_min_qt_intra_slice_chroma, | |
| 208 | ✗ | .ph_cu_qp_delta_subdiv_intra_slice = ph->ph_cu_qp_delta_subdiv_intra_slice, | |
| 209 | ✗ | .ph_cu_chroma_qp_offset_subdiv_intra_slice = ph->ph_cu_chroma_qp_offset_subdiv_intra_slice, | |
| 210 | ✗ | .ph_log2_diff_min_qt_min_cb_inter_slice = ph->ph_log2_diff_min_qt_min_cb_inter_slice, | |
| 211 | ✗ | .ph_max_mtt_hierarchy_depth_inter_slice = ph->ph_max_mtt_hierarchy_depth_inter_slice, | |
| 212 | ✗ | .ph_log2_diff_max_bt_min_qt_inter_slice = ph->ph_log2_diff_max_bt_min_qt_inter_slice, | |
| 213 | ✗ | .ph_log2_diff_max_tt_min_qt_inter_slice = ph->ph_log2_diff_max_tt_min_qt_inter_slice, | |
| 214 | ✗ | .ph_cu_qp_delta_subdiv_inter_slice = ph->ph_cu_qp_delta_subdiv_inter_slice, | |
| 215 | ✗ | .ph_cu_chroma_qp_offset_subdiv_inter_slice = ph->ph_cu_chroma_qp_offset_subdiv_inter_slice, | |
| 216 | .ph_flags.bits= { | ||
| 217 | ✗ | .ph_non_ref_pic_flag = ph->ph_non_ref_pic_flag, | |
| 218 | ✗ | .ph_alf_enabled_flag = ph->ph_alf_enabled_flag, | |
| 219 | ✗ | .ph_alf_cb_enabled_flag = ph->ph_alf_cb_enabled_flag, | |
| 220 | ✗ | .ph_alf_cr_enabled_flag = ph->ph_alf_cr_enabled_flag, | |
| 221 | ✗ | .ph_alf_cc_cb_enabled_flag = ph->ph_alf_cc_cb_enabled_flag, | |
| 222 | ✗ | .ph_alf_cc_cr_enabled_flag = ph->ph_alf_cc_cr_enabled_flag, | |
| 223 | ✗ | .ph_lmcs_enabled_flag = ph->ph_lmcs_enabled_flag, | |
| 224 | ✗ | .ph_chroma_residual_scale_flag = ph->ph_chroma_residual_scale_flag, | |
| 225 | ✗ | .ph_explicit_scaling_list_enabled_flag = ph->ph_explicit_scaling_list_enabled_flag, | |
| 226 | ✗ | .ph_virtual_boundaries_present_flag = ph->ph_virtual_boundaries_present_flag, | |
| 227 | ✗ | .ph_temporal_mvp_enabled_flag = ph->ph_temporal_mvp_enabled_flag, | |
| 228 | ✗ | .ph_mmvd_fullpel_only_flag = ph->ph_mmvd_fullpel_only_flag, | |
| 229 | ✗ | .ph_mvd_l1_zero_flag = ph->ph_mvd_l1_zero_flag, | |
| 230 | ✗ | .ph_bdof_disabled_flag = ph->ph_bdof_disabled_flag, | |
| 231 | ✗ | .ph_dmvr_disabled_flag = ph->ph_dmvr_disabled_flag, | |
| 232 | ✗ | .ph_prof_disabled_flag = ph->ph_prof_disabled_flag, | |
| 233 | ✗ | .ph_joint_cbcr_sign_flag = ph->ph_joint_cbcr_sign_flag, | |
| 234 | ✗ | .ph_sao_luma_enabled_flag = ph->ph_sao_luma_enabled_flag, | |
| 235 | ✗ | .ph_sao_chroma_enabled_flag = ph->ph_sao_chroma_enabled_flag, | |
| 236 | ✗ | .ph_deblocking_filter_disabled_flag = ph->ph_deblocking_filter_disabled_flag, | |
| 237 | }, | ||
| 238 | .PicMiscFlags.fields = { | ||
| 239 | ✗ | .IntraPicFlag = pps->pps_mixed_nalu_types_in_pic_flag ? 0 : IS_IRAP(h) ? 1 : 0, | |
| 240 | } | ||
| 241 | }; | ||
| 242 | |||
| 243 | ✗ | fill_vaapi_pic(&pic_param->CurrPic, fc->ref); | |
| 244 | ✗ | fill_vaapi_reference_frames(fc, pic_param); | |
| 245 | |||
| 246 | ✗ | for (i = 0; i < VVC_MAX_SAMPLE_ARRAYS; i++) | |
| 247 | ✗ | for (j = 0; j < VVC_MAX_POINTS_IN_QP_TABLE; j++) | |
| 248 | ✗ | pic_param->ChromaQpTable[i][j] = fc->ps.sps->chroma_qp_table[i][j]; | |
| 249 | ✗ | for (i = 0; i < 4; i++) { | |
| 250 | ✗ | pic_param->sps_ladf_qp_offset[i] = sps->sps_ladf_qp_offset[i]; | |
| 251 | ✗ | pic_param->sps_ladf_delta_threshold_minus1[i] = sps->sps_ladf_delta_threshold_minus1[i]; | |
| 252 | } | ||
| 253 | |||
| 254 | ✗ | for (i = 0; i < (sps->sps_virtual_boundaries_present_flag ? sps->sps_num_ver_virtual_boundaries : ph->ph_num_ver_virtual_boundaries); i++) { | |
| 255 | ✗ | pic_param->VirtualBoundaryPosX[i] = (sps->sps_virtual_boundaries_present_flag ? | |
| 256 | ✗ | (sps->sps_virtual_boundary_pos_x_minus1[i] + 1) : | |
| 257 | ✗ | (ph->ph_virtual_boundary_pos_x_minus1[i] + 1)) * 8; | |
| 258 | } | ||
| 259 | |||
| 260 | ✗ | for (i = 0; i < (sps->sps_virtual_boundaries_present_flag ? sps->sps_num_hor_virtual_boundaries : ph->ph_num_hor_virtual_boundaries); i++) { | |
| 261 | ✗ | pic_param->VirtualBoundaryPosY[i] = (sps->sps_virtual_boundaries_present_flag ? | |
| 262 | ✗ | (sps->sps_virtual_boundary_pos_y_minus1[i] + 1) : | |
| 263 | ✗ | (ph->ph_virtual_boundary_pos_y_minus1[i] + 1)) * 8; | |
| 264 | } | ||
| 265 | |||
| 266 | ✗ | for (i = 0; i < 6; i++) { | |
| 267 | ✗ | pic_param->pps_cb_qp_offset_list[i] = pps->pps_cb_qp_offset_list[i]; | |
| 268 | ✗ | pic_param->pps_cr_qp_offset_list[i] = pps->pps_cr_qp_offset_list[i]; | |
| 269 | ✗ | pic_param->pps_joint_cbcr_qp_offset_list[i] = pps->pps_joint_cbcr_qp_offset_list[i]; | |
| 270 | } | ||
| 271 | |||
| 272 | ✗ | err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, | |
| 273 | VAPictureParameterBufferType, | ||
| 274 | ✗ | &pic->pic_param, sizeof(VAPictureParameterBufferVVC)); | |
| 275 | ✗ | if (err < 0) | |
| 276 | ✗ | goto fail; | |
| 277 | |||
| 278 | ✗ | for (i = 0; i <= sps->sps_num_subpics_minus1 && sps->sps_subpic_info_present_flag; i++) { | |
| 279 | ✗ | VASubPicVVC subpic_param = { | |
| 280 | ✗ | .sps_subpic_ctu_top_left_x = sps->sps_subpic_ctu_top_left_x[i], | |
| 281 | ✗ | .sps_subpic_ctu_top_left_y = sps->sps_subpic_ctu_top_left_y[i], | |
| 282 | ✗ | .sps_subpic_width_minus1 = sps->sps_subpic_width_minus1[i], | |
| 283 | ✗ | .sps_subpic_height_minus1 = sps->sps_subpic_height_minus1[i], | |
| 284 | ✗ | .SubpicIdVal = pps->sub_pic_id_val[i], | |
| 285 | .subpic_flags.bits = { | ||
| 286 | ✗ | .sps_subpic_treated_as_pic_flag = sps->sps_subpic_treated_as_pic_flag[i], | |
| 287 | ✗ | .sps_loop_filter_across_subpic_enabled_flag = sps->sps_loop_filter_across_subpic_enabled_flag[i], | |
| 288 | } | ||
| 289 | }; | ||
| 290 | ✗ | err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, | |
| 291 | VASubPicBufferType, | ||
| 292 | &subpic_param, sizeof(VASubPicVVC)); | ||
| 293 | ✗ | if (err < 0) | |
| 294 | ✗ | goto fail; | |
| 295 | } | ||
| 296 | |||
| 297 | ✗ | for (i = 0; i < VVC_MAX_ALF_COUNT; i++) { | |
| 298 | ✗ | const VVCALF *alf_list = h->ps.alf_list[i]; | |
| 299 | ✗ | if (alf_list) { | |
| 300 | ✗ | const H266RawAPS *alf = alf_list->r; | |
| 301 | ✗ | VAAlfDataVVC alf_param = { | |
| 302 | .aps_adaptation_parameter_set_id = i, | ||
| 303 | ✗ | .alf_luma_num_filters_signalled_minus1 = alf->alf_luma_num_filters_signalled_minus1, | |
| 304 | ✗ | .alf_chroma_num_alt_filters_minus1 = alf->alf_chroma_num_alt_filters_minus1, | |
| 305 | ✗ | .alf_cc_cb_filters_signalled_minus1 = alf->alf_cc_cb_filters_signalled_minus1, | |
| 306 | ✗ | .alf_cc_cr_filters_signalled_minus1 = alf->alf_cc_cr_filters_signalled_minus1, | |
| 307 | .alf_flags.bits = { | ||
| 308 | ✗ | .alf_luma_filter_signal_flag = alf->alf_luma_filter_signal_flag, | |
| 309 | ✗ | .alf_chroma_filter_signal_flag = alf->alf_chroma_filter_signal_flag, | |
| 310 | ✗ | .alf_cc_cb_filter_signal_flag = alf->alf_cc_cb_filter_signal_flag, | |
| 311 | ✗ | .alf_cc_cr_filter_signal_flag = alf->alf_cc_cr_filter_signal_flag, | |
| 312 | ✗ | .alf_luma_clip_flag = alf->alf_luma_clip_flag, | |
| 313 | ✗ | .alf_chroma_clip_flag = alf->alf_chroma_clip_flag, | |
| 314 | } | ||
| 315 | }; | ||
| 316 | |||
| 317 | ✗ | for (j = 0; j < 25; j++) | |
| 318 | ✗ | alf_param.alf_luma_coeff_delta_idx[j] = alf->alf_luma_coeff_delta_idx[j]; | |
| 319 | |||
| 320 | ✗ | for (j = 0; j < 25; j++) { | |
| 321 | ✗ | for (k = 0; k < 12; k++) { | |
| 322 | ✗ | alf_param.filtCoeff[j][k] = alf->alf_luma_coeff_abs[j][k] * (1 - 2 * alf->alf_luma_coeff_sign[j][k]); | |
| 323 | ✗ | alf_param.alf_luma_clip_idx[j][k] = alf->alf_luma_clip_idx[j][k]; | |
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | ✗ | for (j = 0; j < 8; j++) { | |
| 328 | ✗ | for (k = 0; k < 6; k++) { | |
| 329 | ✗ | alf_param.AlfCoeffC[j][k] = alf->alf_chroma_coeff_abs[j][k] * (1 - 2 * alf->alf_chroma_coeff_sign[j][k]); | |
| 330 | ✗ | alf_param.alf_chroma_clip_idx[j][k] = alf->alf_chroma_clip_idx[j][k]; | |
| 331 | } | ||
| 332 | } | ||
| 333 | |||
| 334 | ✗ | for (j = 0; j < 4; j++) { | |
| 335 | ✗ | for (k = 0; k < 7; k++) { | |
| 336 | ✗ | if (alf->alf_cc_cb_mapped_coeff_abs[j][k]) | |
| 337 | ✗ | 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)); | |
| 338 | ✗ | if (alf->alf_cc_cr_mapped_coeff_abs[j][k]) | |
| 339 | ✗ | 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)); | |
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | ✗ | err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, | |
| 344 | VAAlfBufferType, | ||
| 345 | &alf_param, sizeof(VAAlfDataVVC)); | ||
| 346 | ✗ | if (err < 0) | |
| 347 | ✗ | goto fail; | |
| 348 | } | ||
| 349 | } | ||
| 350 | |||
| 351 | ✗ | for (i = 0; i < VVC_MAX_LMCS_COUNT; i++) { | |
| 352 | ✗ | const H266RawAPS *lmcs = h->ps.lmcs_list[i]; | |
| 353 | ✗ | if (lmcs) { | |
| 354 | ✗ | VALmcsDataVVC lmcs_param = { | |
| 355 | .aps_adaptation_parameter_set_id = i, | ||
| 356 | ✗ | .lmcs_min_bin_idx = lmcs->lmcs_min_bin_idx, | |
| 357 | ✗ | .lmcs_delta_max_bin_idx = lmcs->lmcs_delta_max_bin_idx, | |
| 358 | ✗ | .lmcsDeltaCrs = (1 - 2 * lmcs->lmcs_delta_sign_crs_flag) * lmcs->lmcs_delta_abs_crs, | |
| 359 | }; | ||
| 360 | |||
| 361 | ✗ | for (j = lmcs->lmcs_min_bin_idx; j <= 15 - lmcs->lmcs_delta_max_bin_idx; j++) | |
| 362 | ✗ | lmcs_param.lmcsDeltaCW[j] = (1 - 2 * lmcs->lmcs_delta_sign_cw_flag[j]) * lmcs->lmcs_delta_abs_cw[j]; | |
| 363 | |||
| 364 | ✗ | err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, | |
| 365 | VALmcsBufferType, | ||
| 366 | &lmcs_param, sizeof(VALmcsDataVVC)); | ||
| 367 | ✗ | if (err < 0) | |
| 368 | ✗ | goto fail; | |
| 369 | } | ||
| 370 | } | ||
| 371 | |||
| 372 | ✗ | for (i = 0; i < VVC_MAX_SL_COUNT; i++) { | |
| 373 | ✗ | const VVCScalingList *sl = h->ps.scaling_list[i]; | |
| 374 | ✗ | if (sl) { | |
| 375 | int l; | ||
| 376 | |||
| 377 | ✗ | VAScalingListVVC sl_param = { | |
| 378 | .aps_adaptation_parameter_set_id = i, | ||
| 379 | }; | ||
| 380 | |||
| 381 | ✗ | for (j = 0; j < 14; j++) | |
| 382 | ✗ | sl_param.ScalingMatrixDCRec[j] = sl->scaling_matrix_dc_rec[j]; | |
| 383 | |||
| 384 | ✗ | for (j = 0; j < 2; j++) | |
| 385 | ✗ | for (k = 0; k < 2; k++) | |
| 386 | ✗ | for (l = 0; l < 2; l++) | |
| 387 | ✗ | sl_param.ScalingMatrixRec2x2[j][k][l] = sl->scaling_matrix_rec[j][l * 2 + k]; | |
| 388 | |||
| 389 | ✗ | for (j = 2; j < 8; j++) | |
| 390 | ✗ | for (k = 0; k < 4; k++) | |
| 391 | ✗ | for (l = 0; l < 4; l++) | |
| 392 | ✗ | sl_param.ScalingMatrixRec4x4[j - 2][k][l] = sl->scaling_matrix_rec[j][l * 4 + k]; | |
| 393 | |||
| 394 | ✗ | for (j = 8; j < 28; j++) | |
| 395 | ✗ | for (k = 0; k < 8; k++) | |
| 396 | ✗ | for (l = 0; l < 8; l++) | |
| 397 | ✗ | sl_param.ScalingMatrixRec8x8[j - 8][k][l] = sl->scaling_matrix_rec[j][l * 8 + k]; | |
| 398 | |||
| 399 | ✗ | err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, | |
| 400 | VAIQMatrixBufferType, | ||
| 401 | &sl_param, sizeof(VAScalingListVVC)); | ||
| 402 | ✗ | if (err < 0) | |
| 403 | ✗ | goto fail; | |
| 404 | } | ||
| 405 | } | ||
| 406 | |||
| 407 | ✗ | for (i = 0; i <= pps->pps_num_exp_tile_columns_minus1; i++) { | |
| 408 | ✗ | tile_dim = pps->pps_tile_column_width_minus1[i]; | |
| 409 | ✗ | err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, | |
| 410 | VATileBufferType, | ||
| 411 | &tile_dim, sizeof(tile_dim)); | ||
| 412 | ✗ | if (err < 0) | |
| 413 | ✗ | goto fail; | |
| 414 | } | ||
| 415 | |||
| 416 | ✗ | for (i = 0; i <= pps->pps_num_exp_tile_rows_minus1; i++) { | |
| 417 | ✗ | tile_dim = pps->pps_tile_row_height_minus1[i]; | |
| 418 | ✗ | err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, | |
| 419 | VATileBufferType, | ||
| 420 | &tile_dim, sizeof(tile_dim)); | ||
| 421 | ✗ | if (err < 0) | |
| 422 | ✗ | goto fail; | |
| 423 | } | ||
| 424 | |||
| 425 | ✗ | if (!pps->pps_no_pic_partition_flag && pps->pps_rect_slice_flag && !pps->pps_single_slice_per_subpic_flag) { | |
| 426 | ✗ | for (i = 0; i <= pps->pps_num_slices_in_pic_minus1; i++) { | |
| 427 | ✗ | for (j = 0; j < pps->pps_num_exp_slices_in_tile[i]; j++) { | |
| 428 | ✗ | exp_slice_height_in_ctus[i + j] = pps->pps_exp_slice_height_in_ctus_minus1[i][j] + 1; | |
| 429 | } | ||
| 430 | } | ||
| 431 | ✗ | for (i = 0; i <= pps->pps_num_slices_in_pic_minus1; i++) { | |
| 432 | ✗ | VASliceStructVVC ss_param = { | |
| 433 | ✗ | .SliceTopLeftTileIdx = pps->slice_top_left_tile_idx[i], | |
| 434 | ✗ | .pps_slice_width_in_tiles_minus1 = pps->pps_slice_width_in_tiles_minus1[i], | |
| 435 | ✗ | .pps_slice_height_in_tiles_minus1 = pps->pps_slice_height_in_tiles_minus1[i], | |
| 436 | }; | ||
| 437 | |||
| 438 | ✗ | if (pps->pps_slice_width_in_tiles_minus1[i] > 0 || pps->pps_slice_height_in_tiles_minus1[i] > 0) | |
| 439 | ✗ | ss_param.pps_exp_slice_height_in_ctus_minus1 = 0; | |
| 440 | else { | ||
| 441 | ✗ | if (pps->num_slices_in_tile[i] == 1) | |
| 442 | ✗ | 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; | |
| 443 | ✗ | else if (exp_slice_height_in_ctus[i]) | |
| 444 | ✗ | ss_param.pps_exp_slice_height_in_ctus_minus1 = exp_slice_height_in_ctus[i] - 1; | |
| 445 | else | ||
| 446 | ✗ | continue; | |
| 447 | } | ||
| 448 | |||
| 449 | ✗ | err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic, | |
| 450 | VASliceStructBufferType, | ||
| 451 | &ss_param, sizeof(VASliceStructVVC)); | ||
| 452 | ✗ | if (err < 0) | |
| 453 | ✗ | goto fail; | |
| 454 | } | ||
| 455 | } | ||
| 456 | |||
| 457 | ✗ | return 0; | |
| 458 | |||
| 459 | ✗ | fail: | |
| 460 | ✗ | ff_vaapi_decode_cancel(avctx, &pic->pic); | |
| 461 | ✗ | return err; | |
| 462 | } | ||
| 463 | |||
| 464 | ✗ | static uint8_t get_ref_pic_index(const VVCContext *h, const VVCFrame *frame) | |
| 465 | { | ||
| 466 | ✗ | VVCFrameContext *fc = &h->fcs[(h->nb_frames + h->nb_fcs) % h->nb_fcs]; | |
| 467 | ✗ | VAAPIDecodePictureVVC *pic = fc->ref->hwaccel_picture_private; | |
| 468 | ✗ | VAPictureParameterBufferVVC *pp = (VAPictureParameterBufferVVC *)&pic->pic_param; | |
| 469 | uint8_t i; | ||
| 470 | |||
| 471 | ✗ | if (!frame) | |
| 472 | ✗ | return 0xFF; | |
| 473 | |||
| 474 | ✗ | for (i = 0; i < FF_ARRAY_ELEMS(pp->ReferenceFrames); i++) { | |
| 475 | ✗ | VASurfaceID pid = pp->ReferenceFrames[i].picture_id; | |
| 476 | ✗ | int poc = pp->ReferenceFrames[i].pic_order_cnt; | |
| 477 | ✗ | if (pid != VA_INVALID_ID && pid == ff_vaapi_get_surface_id(frame->frame) && poc == frame->poc) | |
| 478 | ✗ | return i; | |
| 479 | } | ||
| 480 | |||
| 481 | ✗ | return 0xFF; | |
| 482 | } | ||
| 483 | |||
| 484 | ✗ | static int get_slice_data_byte_offset(const uint8_t *buffer, uint32_t size, const SliceContext* sc) | |
| 485 | { | ||
| 486 | ✗ | const H266RawSlice *slice = sc->ref; | |
| 487 | ✗ | int num_identical_bytes = slice->data_size < 32 ? slice->data_size : 32; | |
| 488 | |||
| 489 | ✗ | for (int i = 0; i < size; i++) { | |
| 490 | ✗ | int skip_bytes = 0; | |
| 491 | ✗ | if (i >=2 && buffer[i] == 0x03 && !buffer[i - 1] && !buffer[i - 2]) | |
| 492 | ✗ | continue; | |
| 493 | |||
| 494 | ✗ | for (int j = 0; j < num_identical_bytes; j++) { | |
| 495 | ✗ | if (i >= 2 && buffer[i + j + skip_bytes] == 0x03 && !buffer[i + j + skip_bytes - 1] && !buffer[i + j + skip_bytes - 2]) | |
| 496 | ✗ | skip_bytes++; | |
| 497 | |||
| 498 | ✗ | if (buffer[i + j + skip_bytes] != slice->data[j]) | |
| 499 | ✗ | break; | |
| 500 | |||
| 501 | ✗ | if (j + 1 == num_identical_bytes) | |
| 502 | ✗ | return i; | |
| 503 | } | ||
| 504 | } | ||
| 505 | |||
| 506 | ✗ | return 0; | |
| 507 | } | ||
| 508 | |||
| 509 | ✗ | static int vaapi_vvc_decode_slice(AVCodecContext *avctx, | |
| 510 | const uint8_t *buffer, | ||
| 511 | uint32_t size) | ||
| 512 | { | ||
| 513 | ✗ | const VVCContext *h = avctx->priv_data; | |
| 514 | ✗ | VVCFrameContext *fc = &h->fcs[(h->nb_frames + h->nb_fcs) % h->nb_fcs]; | |
| 515 | ✗ | const SliceContext *sc = fc->slices[fc->nb_slices]; | |
| 516 | ✗ | const H266RawPPS *pps = fc->ps.pps->r; | |
| 517 | ✗ | const H266RawPictureHeader *ph = fc->ps.ph.r; | |
| 518 | ✗ | const H266RawSliceHeader *sh = sc->sh.r; | |
| 519 | ✗ | VAAPIDecodePictureVVC *pic = fc->ref->hwaccel_picture_private; | |
| 520 | ✗ | VASliceParameterBufferVVC *slice_param = &pic->slice_param; | |
| 521 | int nb_list, i, err; | ||
| 522 | |||
| 523 | ✗ | *slice_param = (VASliceParameterBufferVVC) { | |
| 524 | .slice_data_size = size, | ||
| 525 | .slice_data_offset = 0, | ||
| 526 | .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, | ||
| 527 | ✗ | .slice_data_byte_offset = get_slice_data_byte_offset(buffer, size, sc), | |
| 528 | ✗ | .sh_subpic_id = sh->sh_subpic_id, | |
| 529 | ✗ | .sh_slice_address = sh->sh_slice_address, | |
| 530 | ✗ | .sh_num_tiles_in_slice_minus1 = sh->sh_num_tiles_in_slice_minus1, | |
| 531 | ✗ | .sh_slice_type = sh->sh_slice_type, | |
| 532 | ✗ | .sh_num_alf_aps_ids_luma = sh->sh_num_alf_aps_ids_luma, | |
| 533 | ✗ | .sh_alf_aps_id_chroma = sh->sh_alf_aps_id_chroma, | |
| 534 | ✗ | .sh_alf_cc_cb_aps_id = sh->sh_alf_cc_cb_aps_id, | |
| 535 | ✗ | .sh_alf_cc_cr_aps_id = sh->sh_alf_cc_cr_aps_id, | |
| 536 | ✗ | .NumRefIdxActive[0] = sh->num_ref_idx_active[0], | |
| 537 | ✗ | .NumRefIdxActive[1] = sh->num_ref_idx_active[1], | |
| 538 | ✗ | .sh_collocated_ref_idx = sh->sh_collocated_ref_idx, | |
| 539 | ✗ | .SliceQpY = pps->pps_qp_delta_info_in_ph_flag ? | |
| 540 | ✗ | 26 + pps->pps_init_qp_minus26 + ph->ph_qp_delta : | |
| 541 | ✗ | 26 + pps->pps_init_qp_minus26 + sh->sh_qp_delta, | |
| 542 | ✗ | .sh_cb_qp_offset = sh->sh_cb_qp_offset, | |
| 543 | ✗ | .sh_cr_qp_offset = sh->sh_cr_qp_offset, | |
| 544 | ✗ | .sh_joint_cbcr_qp_offset = sh->sh_joint_cbcr_qp_offset, | |
| 545 | ✗ | .sh_luma_beta_offset_div2 = sh->sh_luma_beta_offset_div2, | |
| 546 | ✗ | .sh_luma_tc_offset_div2 = sh->sh_luma_tc_offset_div2, | |
| 547 | ✗ | .sh_cb_beta_offset_div2 = sh->sh_cb_beta_offset_div2, | |
| 548 | ✗ | .sh_cb_tc_offset_div2 = sh->sh_cb_tc_offset_div2, | |
| 549 | ✗ | .sh_cr_beta_offset_div2 = sh->sh_cr_beta_offset_div2, | |
| 550 | ✗ | .sh_cr_tc_offset_div2 = sh->sh_cr_tc_offset_div2, | |
| 551 | .WPInfo = { | ||
| 552 | ✗ | .luma_log2_weight_denom = sh->sh_pred_weight_table.luma_log2_weight_denom, | |
| 553 | ✗ | .delta_chroma_log2_weight_denom = sh->sh_pred_weight_table.delta_chroma_log2_weight_denom, | |
| 554 | ✗ | .num_l0_weights = sh->sh_pred_weight_table.num_l0_weights, | |
| 555 | ✗ | .num_l1_weights = sh->sh_pred_weight_table.num_l1_weights, | |
| 556 | }, | ||
| 557 | .sh_flags.bits = { | ||
| 558 | ✗ | .sh_alf_enabled_flag = sh->sh_alf_enabled_flag, | |
| 559 | ✗ | .sh_alf_cb_enabled_flag = sh->sh_alf_cb_enabled_flag, | |
| 560 | ✗ | .sh_alf_cr_enabled_flag = sh->sh_alf_cr_enabled_flag, | |
| 561 | ✗ | .sh_alf_cc_cb_enabled_flag = sh->sh_alf_cc_cb_enabled_flag, | |
| 562 | ✗ | .sh_alf_cc_cr_enabled_flag = sh->sh_alf_cc_cr_enabled_flag, | |
| 563 | ✗ | .sh_lmcs_used_flag = sh->sh_lmcs_used_flag, | |
| 564 | ✗ | .sh_explicit_scaling_list_used_flag = sh->sh_explicit_scaling_list_used_flag, | |
| 565 | ✗ | .sh_cabac_init_flag = sh->sh_cabac_init_flag, | |
| 566 | ✗ | .sh_collocated_from_l0_flag = sh->sh_collocated_from_l0_flag, | |
| 567 | ✗ | .sh_cu_chroma_qp_offset_enabled_flag = sh->sh_cu_chroma_qp_offset_enabled_flag, | |
| 568 | ✗ | .sh_sao_luma_used_flag = sh->sh_sao_luma_used_flag, | |
| 569 | ✗ | .sh_sao_chroma_used_flag = sh->sh_sao_chroma_used_flag, | |
| 570 | ✗ | .sh_deblocking_filter_disabled_flag = sh->sh_deblocking_filter_disabled_flag, | |
| 571 | ✗ | .sh_dep_quant_used_flag = sh->sh_dep_quant_used_flag, | |
| 572 | ✗ | .sh_sign_data_hiding_used_flag = sh->sh_sign_data_hiding_used_flag, | |
| 573 | ✗ | .sh_ts_residual_coding_disabled_flag = sh->sh_ts_residual_coding_disabled_flag, | |
| 574 | }, | ||
| 575 | }; | ||
| 576 | |||
| 577 | ✗ | memset(&slice_param->RefPicList, 0xFF, sizeof(slice_param->RefPicList)); | |
| 578 | |||
| 579 | ✗ | nb_list = (sh->sh_slice_type == VVC_SLICE_TYPE_B) ? | |
| 580 | ✗ | 2 : (sh->sh_slice_type == VVC_SLICE_TYPE_I ? 0 : 1); | |
| 581 | ✗ | for (int list_idx = 0; list_idx < nb_list; list_idx++) { | |
| 582 | ✗ | RefPicList *rpl = &sc->rpl[list_idx]; | |
| 583 | |||
| 584 | ✗ | for (i = 0; i < rpl->nb_refs; i++) | |
| 585 | ✗ | slice_param->RefPicList[list_idx][i] = get_ref_pic_index(h, rpl->refs[i].ref); | |
| 586 | } | ||
| 587 | |||
| 588 | ✗ | for (i = 0; i < 7; i++) | |
| 589 | ✗ | slice_param->sh_alf_aps_id_luma[i] = sh->sh_alf_aps_id_luma[i]; | |
| 590 | |||
| 591 | ✗ | for (i = 0; i < 15; i++) { | |
| 592 | ✗ | slice_param->WPInfo.luma_weight_l0_flag[i] = sh->sh_pred_weight_table.luma_weight_l0_flag[i]; | |
| 593 | ✗ | slice_param->WPInfo.chroma_weight_l0_flag[i] = sh->sh_pred_weight_table.chroma_weight_l0_flag[i]; | |
| 594 | ✗ | slice_param->WPInfo.delta_luma_weight_l0[i] = sh->sh_pred_weight_table.delta_luma_weight_l0[i]; | |
| 595 | ✗ | slice_param->WPInfo.luma_offset_l0[i] = sh->sh_pred_weight_table.luma_offset_l0[i]; | |
| 596 | ✗ | slice_param->WPInfo.luma_weight_l1_flag[i] = sh->sh_pred_weight_table.luma_weight_l1_flag[i]; | |
| 597 | ✗ | slice_param->WPInfo.chroma_weight_l1_flag[i] = sh->sh_pred_weight_table.chroma_weight_l1_flag[i]; | |
| 598 | ✗ | slice_param->WPInfo.delta_luma_weight_l1[i] = sh->sh_pred_weight_table.delta_luma_weight_l1[i]; | |
| 599 | ✗ | slice_param->WPInfo.luma_offset_l1[i] = sh->sh_pred_weight_table.luma_offset_l1[i]; | |
| 600 | } | ||
| 601 | |||
| 602 | ✗ | for (i = 0; i < 15; i++) { | |
| 603 | ✗ | for (int j = 0; j < 2; j++) { | |
| 604 | ✗ | slice_param->WPInfo.delta_chroma_weight_l0[i][j] = sh->sh_pred_weight_table.delta_chroma_weight_l0[i][j]; | |
| 605 | ✗ | slice_param->WPInfo.delta_chroma_offset_l0[i][j] = sh->sh_pred_weight_table.delta_chroma_offset_l0[i][j]; | |
| 606 | ✗ | slice_param->WPInfo.delta_chroma_weight_l1[i][j] = sh->sh_pred_weight_table.delta_chroma_weight_l1[i][j]; | |
| 607 | ✗ | slice_param->WPInfo.delta_chroma_offset_l1[i][j] = sh->sh_pred_weight_table.delta_chroma_offset_l1[i][j]; | |
| 608 | } | ||
| 609 | } | ||
| 610 | |||
| 611 | ✗ | err = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic, | |
| 612 | ✗ | &pic->slice_param, 1, | |
| 613 | sizeof(VASliceParameterBufferVVC), | ||
| 614 | buffer, size); | ||
| 615 | ✗ | if (err) { | |
| 616 | ✗ | ff_vaapi_decode_cancel(avctx, &pic->pic); | |
| 617 | ✗ | return err; | |
| 618 | } | ||
| 619 | |||
| 620 | ✗ | return 0; | |
| 621 | } | ||
| 622 | |||
| 623 | ✗ | static int vaapi_vvc_end_frame(AVCodecContext *avctx) | |
| 624 | { | ||
| 625 | |||
| 626 | ✗ | const VVCContext *h = avctx->priv_data; | |
| 627 | ✗ | VVCFrameContext *fc = &h->fcs[(h->nb_frames + h->nb_fcs) % h->nb_fcs]; | |
| 628 | ✗ | VAAPIDecodePictureVVC *pic = fc->ref->hwaccel_picture_private; | |
| 629 | int ret; | ||
| 630 | |||
| 631 | ✗ | ret = ff_vaapi_decode_issue(avctx, &pic->pic); | |
| 632 | ✗ | if (ret < 0) | |
| 633 | ✗ | goto fail; | |
| 634 | |||
| 635 | ✗ | pic->decode_issued = 1; | |
| 636 | |||
| 637 | ✗ | return 0; | |
| 638 | |||
| 639 | ✗ | fail: | |
| 640 | ✗ | ff_vaapi_decode_cancel(avctx, &pic->pic); | |
| 641 | ✗ | return ret; | |
| 642 | } | ||
| 643 | |||
| 644 | const FFHWAccel ff_vvc_vaapi_hwaccel = { | ||
| 645 | .p.name = "vvc_vaapi", | ||
| 646 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
| 647 | .p.id = AV_CODEC_ID_VVC, | ||
| 648 | .p.pix_fmt = AV_PIX_FMT_VAAPI, | ||
| 649 | .start_frame = &vaapi_vvc_start_frame, | ||
| 650 | .end_frame = &vaapi_vvc_end_frame, | ||
| 651 | .decode_slice = &vaapi_vvc_decode_slice, | ||
| 652 | .frame_priv_data_size = sizeof(VAAPIDecodePictureVVC), | ||
| 653 | .init = &ff_vaapi_decode_init, | ||
| 654 | .uninit = &ff_vaapi_decode_uninit, | ||
| 655 | .frame_params = &ff_vaapi_common_frame_params, | ||
| 656 | .priv_data_size = sizeof(VAAPIDecodeContext), | ||
| 657 | .caps_internal = HWACCEL_CAP_ASYNC_SAFE, | ||
| 658 | }; | ||
| 659 |