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