FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vdpau_hevc.c
Date: 2024-04-26 14:42:52
Exec Total Coverage
Lines: 0 287 0.0%
Functions: 0 6 0.0%
Branches: 0 123 0.0%

Line Branch Exec Source
1 /*
2 * MPEG-H Part 2 / HEVC / H.265 HW decode acceleration through VDPAU
3 *
4 * Copyright (c) 2013 Philip Langdale
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 Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <vdpau/vdpau.h>
24
25 #include "avcodec.h"
26 #include "hevc_data.h"
27 #include "hevcdec.h"
28 #include "hwaccel_internal.h"
29 #include "vdpau.h"
30 #include "vdpau_internal.h"
31 #include "h265_profile_level.h"
32
33
34 static int vdpau_hevc_start_frame(AVCodecContext *avctx,
35 const uint8_t *buffer, uint32_t size)
36 {
37 HEVCContext *h = avctx->priv_data;
38 HEVCFrame *pic = h->ref;
39 struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
40
41 VdpPictureInfoHEVC *info = &pic_ctx->info.hevc;
42 #ifdef VDP_YCBCR_FORMAT_Y_U_V_444
43 VdpPictureInfoHEVC444 *info2 = &pic_ctx->info.hevc_444;
44 #endif
45
46 const HEVCSPS *sps = h->ps.sps;
47 const HEVCPPS *pps = h->ps.pps;
48 const SliceHeader *sh = &h->sh;
49 const ScalingList *sl = pps->scaling_list_data_present_flag ?
50 &pps->scaling_list : &sps->scaling_list;
51
52 /* init VdpPictureInfoHEVC */
53
54 /* SPS */
55 info->chroma_format_idc = sps->chroma_format_idc;
56 info->separate_colour_plane_flag = sps->separate_colour_plane_flag;
57 info->pic_width_in_luma_samples = sps->width;
58 info->pic_height_in_luma_samples = sps->height;
59 info->bit_depth_luma_minus8 = sps->bit_depth - 8;
60 info->bit_depth_chroma_minus8 = sps->bit_depth - 8;
61 info->log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4;
62 /* Provide the value corresponding to the nuh_temporal_id of the frame
63 to be decoded. */
64 info->sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
65 info->log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3;
66 info->log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size;
67 info->log2_min_transform_block_size_minus2 = sps->log2_min_tb_size - 2;
68 info->log2_diff_max_min_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size;
69 info->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
70 info->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
71 info->scaling_list_enabled_flag = sps->scaling_list_enable_flag;
72 /* Scaling lists, in diagonal order, to be used for this frame. */
73 for (size_t i = 0; i < 6; i++) {
74 for (size_t j = 0; j < 16; j++) {
75 /* Scaling List for 4x4 quantization matrix,
76 indexed as ScalingList4x4[matrixId][i]. */
77 uint8_t pos = 4 * ff_hevc_diag_scan4x4_y[j] + ff_hevc_diag_scan4x4_x[j];
78 info->ScalingList4x4[i][j] = sl->sl[0][i][pos];
79 }
80 for (size_t j = 0; j < 64; j++) {
81 uint8_t pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
82 /* Scaling List for 8x8 quantization matrix,
83 indexed as ScalingList8x8[matrixId][i]. */
84 info->ScalingList8x8[i][j] = sl->sl[1][i][pos];
85 /* Scaling List for 16x16 quantization matrix,
86 indexed as ScalingList16x16[matrixId][i]. */
87 info->ScalingList16x16[i][j] = sl->sl[2][i][pos];
88 if (i < 2) {
89 /* Scaling List for 32x32 quantization matrix,
90 indexed as ScalingList32x32[matrixId][i]. */
91 info->ScalingList32x32[i][j] = sl->sl[3][i * 3][pos];
92 }
93 }
94 /* Scaling List DC Coefficients for 16x16,
95 indexed as ScalingListDCCoeff16x16[matrixId]. */
96 info->ScalingListDCCoeff16x16[i] = sl->sl_dc[0][i];
97 if (i < 2) {
98 /* Scaling List DC Coefficients for 32x32,
99 indexed as ScalingListDCCoeff32x32[matrixId]. */
100 info->ScalingListDCCoeff32x32[i] = sl->sl_dc[1][i * 3];
101 }
102 }
103 info->amp_enabled_flag = sps->amp_enabled_flag;
104 info->sample_adaptive_offset_enabled_flag = sps->sao_enabled;
105 info->pcm_enabled_flag = sps->pcm_enabled_flag;
106 if (info->pcm_enabled_flag) {
107 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
108 info->pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1;
109 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
110 info->pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1;
111 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
112 info->log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3;
113 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
114 info->log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size;
115 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
116 info->pcm_loop_filter_disabled_flag = sps->pcm.loop_filter_disable_flag;
117 }
118 /* Per spec, when zero, assume short_term_ref_pic_set_sps_flag
119 is also zero. */
120 info->num_short_term_ref_pic_sets = sps->nb_st_rps;
121 info->long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag;
122 /* Only needed if long_term_ref_pics_present_flag is set. Ignored
123 otherwise. */
124 info->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
125 info->sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag;
126 info->strong_intra_smoothing_enabled_flag = sps->sps_strong_intra_smoothing_enable_flag;
127
128 /* Copy the HEVC Picture Parameter Set bitstream fields. */
129 info->dependent_slice_segments_enabled_flag = pps->dependent_slice_segments_enabled_flag;
130 info->output_flag_present_flag = pps->output_flag_present_flag;
131 info->num_extra_slice_header_bits = pps->num_extra_slice_header_bits;
132 info->sign_data_hiding_enabled_flag = pps->sign_data_hiding_flag;
133 info->cabac_init_present_flag = pps->cabac_init_present_flag;
134 info->num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1;
135 info->num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1;
136 info->init_qp_minus26 = pps->pic_init_qp_minus26;
137 info->constrained_intra_pred_flag = pps->constrained_intra_pred_flag;
138 info->transform_skip_enabled_flag = pps->transform_skip_enabled_flag;
139 info->cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag;
140 /* Only needed if cu_qp_delta_enabled_flag is set. Ignored otherwise. */
141 info->diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth;
142 info->pps_cb_qp_offset = pps->cb_qp_offset;
143 info->pps_cr_qp_offset = pps->cr_qp_offset;
144 info->pps_slice_chroma_qp_offsets_present_flag = pps->pic_slice_level_chroma_qp_offsets_present_flag;
145 info->weighted_pred_flag = pps->weighted_pred_flag;
146 info->weighted_bipred_flag = pps->weighted_bipred_flag;
147 info->transquant_bypass_enabled_flag = pps->transquant_bypass_enable_flag;
148 info->tiles_enabled_flag = pps->tiles_enabled_flag;
149 info->entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag;
150 if (info->tiles_enabled_flag) {
151 /* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
152 info->num_tile_columns_minus1 = pps->num_tile_columns - 1;
153 /* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
154 info->num_tile_rows_minus1 = pps->num_tile_rows - 1;
155 /* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
156 info->uniform_spacing_flag = pps->uniform_spacing_flag;
157 /* Only need to set 0..num_tile_columns_minus1. The struct
158 definition reserves up to the maximum of 20. Invalid values are
159 ignored. */
160 for (ssize_t i = 0; i < pps->num_tile_columns; i++) {
161 info->column_width_minus1[i] = pps->column_width[i] - 1;
162 }
163 /* Only need to set 0..num_tile_rows_minus1. The struct
164 definition reserves up to the maximum of 22. Invalid values are
165 ignored.*/
166 for (ssize_t i = 0; i < pps->num_tile_rows; i++) {
167 info->row_height_minus1[i] = pps->row_height[i] - 1;
168 }
169 /* Only needed if tiles_enabled_flag is set. Invalid values are
170 ignored. */
171 info->loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag;
172 }
173 info->pps_loop_filter_across_slices_enabled_flag = pps->seq_loop_filter_across_slices_enabled_flag;
174 info->deblocking_filter_control_present_flag = pps->deblocking_filter_control_present_flag;
175 /* Only valid if deblocking_filter_control_present_flag is set. Ignored
176 otherwise. */
177 info->deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag;
178 /* Only valid if deblocking_filter_control_present_flag is set. Ignored
179 otherwise. */
180 info->pps_deblocking_filter_disabled_flag = pps->disable_dbf;
181 /* Only valid if deblocking_filter_control_present_flag is set and
182 pps_deblocking_filter_disabled_flag is not set. Ignored otherwise.*/
183 info->pps_beta_offset_div2 = pps->beta_offset / 2;
184 /* Only valid if deblocking_filter_control_present_flag is set and
185 pps_deblocking_filter_disabled_flag is not set. Ignored otherwise. */
186 info->pps_tc_offset_div2 = pps->tc_offset / 2;
187 info->lists_modification_present_flag = pps->lists_modification_present_flag;
188 info->log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2;
189 info->slice_segment_header_extension_present_flag = pps->slice_header_extension_present_flag;
190
191 /* Set to 1 if nal_unit_type is equal to IDR_W_RADL or IDR_N_LP.
192 Set to zero otherwise. */
193 info->IDRPicFlag = IS_IDR(h);
194 /* Set to 1 if nal_unit_type in the range of BLA_W_LP to
195 RSV_IRAP_VCL23, inclusive. Set to zero otherwise.*/
196 info->RAPPicFlag = IS_IRAP(h);
197 /* See section 7.4.7.1 of the specification. */
198 info->CurrRpsIdx = sps->nb_st_rps;
199 if (sh->short_term_ref_pic_set_sps_flag == 1) {
200 for (size_t i = 0; i < sps->nb_st_rps; i++) {
201 if (sh->short_term_rps == &sps->st_rps[i]) {
202 info->CurrRpsIdx = i;
203 break;
204 }
205 }
206 }
207 /* See section 7.4.7.2 of the specification. */
208 info->NumPocTotalCurr = ff_hevc_frame_nb_refs(h);
209 if (sh->short_term_ref_pic_set_sps_flag == 0 && sh->short_term_rps) {
210 /* Corresponds to specification field, NumDeltaPocs[RefRpsIdx].
211 Only applicable when short_term_ref_pic_set_sps_flag == 0.
212 Implementations will ignore this value in other cases. See 7.4.8. */
213 info->NumDeltaPocsOfRefRpsIdx = sh->short_term_rps->rps_idx_num_delta_pocs;
214 }
215 /* Section 7.6.3.1 of the H.265/HEVC Specification defines the syntax of
216 the slice_segment_header. This header contains information that
217 some VDPAU implementations may choose to skip. The VDPAU API
218 requires client applications to track the number of bits used in the
219 slice header for structures associated with short term and long term
220 reference pictures. First, VDPAU requires the number of bits used by
221 the short_term_ref_pic_set array in the slice_segment_header. */
222 info->NumShortTermPictureSliceHeaderBits = sh->short_term_ref_pic_set_size;
223 /* Second, VDPAU requires the number of bits used for long term reference
224 pictures in the slice_segment_header. This is equal to the number
225 of bits used for the contents of the block beginning with
226 "if(long_term_ref_pics_present_flag)". */
227 info->NumLongTermPictureSliceHeaderBits = sh->long_term_ref_pic_set_size;
228
229 /* The value of PicOrderCntVal of the picture in the access unit
230 containing the SEI message. The picture being decoded. */
231 info->CurrPicOrderCntVal = h->poc;
232
233 /* Slice Decoding Process - Reference Picture Sets */
234 for (size_t i = 0; i < 16; i++) {
235 info->RefPics[i] = VDP_INVALID_HANDLE;
236 info->PicOrderCntVal[i] = 0;
237 info->IsLongTerm[i] = 0;
238 }
239 for (size_t i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
240 const HEVCFrame *frame = &h->DPB[i];
241 if (frame != h->ref && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF |
242 HEVC_FRAME_FLAG_SHORT_REF))) {
243 if (j > 15) {
244 av_log(avctx, AV_LOG_WARNING,
245 "VDPAU only supports up to 16 references in the DPB. "
246 "This frame may not be decoded correctly.\n");
247 break;
248 }
249 /* Array of video reference surfaces.
250 Set any unused positions to VDP_INVALID_HANDLE. */
251 info->RefPics[j] = ff_vdpau_get_surface_id(frame->frame);
252 /* Array of picture order counts. These correspond to positions
253 in the RefPics array. */
254 info->PicOrderCntVal[j] = frame->poc;
255 /* Array used to specify whether a particular RefPic is
256 a long term reference. A value of "1" indicates a long-term
257 reference. */
258 // XXX: Setting this caused glitches in the nvidia implementation
259 // Always setting it to zero, produces correct results
260 //info->IsLongTerm[j] = frame->flags & HEVC_FRAME_FLAG_LONG_REF;
261 info->IsLongTerm[j] = 0;
262 j++;
263 }
264 }
265 /* Copy of specification field, see Section 8.3.2 of the
266 H.265/HEVC Specification. */
267 info->NumPocStCurrBefore = h->rps[ST_CURR_BEF].nb_refs;
268 if (info->NumPocStCurrBefore > 8) {
269 av_log(avctx, AV_LOG_WARNING,
270 "VDPAU only supports up to 8 references in StCurrBefore. "
271 "This frame may not be decoded correctly.\n");
272 info->NumPocStCurrBefore = 8;
273 }
274 /* Copy of specification field, see Section 8.3.2 of the
275 H.265/HEVC Specification. */
276 info->NumPocStCurrAfter = h->rps[ST_CURR_AFT].nb_refs;
277 if (info->NumPocStCurrAfter > 8) {
278 av_log(avctx, AV_LOG_WARNING,
279 "VDPAU only supports up to 8 references in StCurrAfter. "
280 "This frame may not be decoded correctly.\n");
281 info->NumPocStCurrAfter = 8;
282 }
283 /* Copy of specification field, see Section 8.3.2 of the
284 H.265/HEVC Specification. */
285 info->NumPocLtCurr = h->rps[LT_CURR].nb_refs;
286 if (info->NumPocLtCurr > 8) {
287 av_log(avctx, AV_LOG_WARNING,
288 "VDPAU only supports up to 8 references in LtCurr. "
289 "This frame may not be decoded correctly.\n");
290 info->NumPocLtCurr = 8;
291 }
292 /* Reference Picture Set list, one of the short-term RPS. These
293 correspond to positions in the RefPics array. */
294 for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) {
295 HEVCFrame *frame = h->rps[ST_CURR_BEF].ref[i];
296 if (frame) {
297 uint8_t found = 0;
298 uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
299 for (size_t k = 0; k < 16; k++) {
300 if (id == info->RefPics[k]) {
301 info->RefPicSetStCurrBefore[j] = k;
302 j++;
303 found = 1;
304 break;
305 }
306 }
307 if (!found) {
308 av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
309 (void *)id);
310 }
311 } else {
312 av_log(avctx, AV_LOG_WARNING, "missing STR Before frame: %zd\n", i);
313 }
314 }
315 /* Reference Picture Set list, one of the short-term RPS. These
316 correspond to positions in the RefPics array. */
317 for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) {
318 HEVCFrame *frame = h->rps[ST_CURR_AFT].ref[i];
319 if (frame) {
320 uint8_t found = 0;
321 uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
322 for (size_t k = 0; k < 16; k++) {
323 if (id == info->RefPics[k]) {
324 info->RefPicSetStCurrAfter[j] = k;
325 j++;
326 found = 1;
327 break;
328 }
329 }
330 if (!found) {
331 av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
332 (void *)id);
333 }
334 } else {
335 av_log(avctx, AV_LOG_WARNING, "missing STR After frame: %zd\n", i);
336 }
337 }
338 /* Reference Picture Set list, one of the long-term RPS. These
339 correspond to positions in the RefPics array. */
340 for (ssize_t i = 0, j = 0; i < h->rps[LT_CURR].nb_refs; i++) {
341 HEVCFrame *frame = h->rps[LT_CURR].ref[i];
342 if (frame) {
343 uint8_t found = 0;
344 uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
345 for (size_t k = 0; k < 16; k++) {
346 if (id == info->RefPics[k]) {
347 info->RefPicSetLtCurr[j] = k;
348 j++;
349 found = 1;
350 break;
351 }
352 }
353 if (!found) {
354 av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
355 (void *)id);
356 }
357 } else {
358 av_log(avctx, AV_LOG_WARNING, "missing LTR frame: %zd\n", i);
359 }
360 }
361
362 #ifdef VDP_YCBCR_FORMAT_Y_U_V_444
363 if (sps->sps_range_extension_flag) {
364 info2->sps_range_extension_flag = 1;
365 info2->transformSkipRotationEnableFlag = sps->transform_skip_rotation_enabled_flag;
366 info2->transformSkipContextEnableFlag = sps->transform_skip_context_enabled_flag;
367 info2->implicitRdpcmEnableFlag = sps->implicit_rdpcm_enabled_flag;
368 info2->explicitRdpcmEnableFlag = sps->explicit_rdpcm_enabled_flag;
369 info2->extendedPrecisionProcessingFlag = sps->extended_precision_processing_flag;
370 info2->intraSmoothingDisabledFlag = sps->intra_smoothing_disabled_flag;
371 info2->highPrecisionOffsetsEnableFlag = sps->high_precision_offsets_enabled_flag;
372 info2->persistentRiceAdaptationEnableFlag = sps->persistent_rice_adaptation_enabled_flag;
373 info2->cabacBypassAlignmentEnableFlag = sps->cabac_bypass_alignment_enabled_flag;
374 } else {
375 info2->sps_range_extension_flag = 0;
376 }
377 if (pps->pps_range_extensions_flag) {
378 info2->pps_range_extension_flag = 1;
379 info2->log2MaxTransformSkipSize = pps->log2_max_transform_skip_block_size;
380 info2->crossComponentPredictionEnableFlag = pps->cross_component_prediction_enabled_flag;
381 info2->chromaQpAdjustmentEnableFlag = pps->chroma_qp_offset_list_enabled_flag;
382 info2->diffCuChromaQpAdjustmentDepth = pps->diff_cu_chroma_qp_offset_depth;
383 info2->chromaQpAdjustmentTableSize = pps->chroma_qp_offset_list_len_minus1 + 1;
384 info2->log2SaoOffsetScaleLuma = pps->log2_sao_offset_scale_luma;
385 info2->log2SaoOffsetScaleChroma = pps->log2_sao_offset_scale_chroma;
386 for (ssize_t i = 0; i < info2->chromaQpAdjustmentTableSize; i++)
387 {
388 info2->cb_qp_adjustment[i] = pps->cb_qp_offset_list[i];
389 info2->cr_qp_adjustment[i] = pps->cr_qp_offset_list[i];
390 }
391
392 } else {
393 info2->pps_range_extension_flag = 0;
394 }
395 #endif
396
397 return ff_vdpau_common_start_frame(pic_ctx, buffer, size);
398 }
399
400 static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
401
402 static int vdpau_hevc_decode_slice(AVCodecContext *avctx,
403 const uint8_t *buffer, uint32_t size)
404 {
405 HEVCContext *h = avctx->priv_data;
406 struct vdpau_picture_context *pic_ctx = h->ref->hwaccel_picture_private;
407 int val;
408
409 val = ff_vdpau_add_buffer(pic_ctx, start_code_prefix, 3);
410 if (val)
411 return val;
412
413 val = ff_vdpau_add_buffer(pic_ctx, buffer, size);
414 if (val)
415 return val;
416
417 return 0;
418 }
419
420 static int vdpau_hevc_end_frame(AVCodecContext *avctx)
421 {
422 HEVCContext *h = avctx->priv_data;
423 struct vdpau_picture_context *pic_ctx = h->ref->hwaccel_picture_private;
424 int val;
425
426 val = ff_vdpau_common_end_frame(avctx, h->ref->frame, pic_ctx);
427 if (val < 0)
428 return val;
429
430 return 0;
431 }
432
433
434
435 static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel *h265_raw_ptl)
436 {
437 h265_raw_ptl->general_profile_space = general_ptl->profile_space;
438 h265_raw_ptl->general_tier_flag = general_ptl->tier_flag;
439 h265_raw_ptl->general_profile_idc = general_ptl->profile_idc;
440
441 memcpy(h265_raw_ptl->general_profile_compatibility_flag,
442 general_ptl->profile_compatibility_flag, 32 * sizeof(uint8_t));
443
444 #define copy_field(name) h265_raw_ptl->general_ ## name = general_ptl->name
445 copy_field(progressive_source_flag);
446 copy_field(interlaced_source_flag);
447 copy_field(non_packed_constraint_flag);
448 copy_field(frame_only_constraint_flag);
449 copy_field(max_12bit_constraint_flag);
450 copy_field(max_10bit_constraint_flag);
451 copy_field(max_8bit_constraint_flag);
452 copy_field(max_422chroma_constraint_flag);
453 copy_field(max_420chroma_constraint_flag);
454 copy_field(max_monochrome_constraint_flag);
455 copy_field(intra_constraint_flag);
456 copy_field(one_picture_only_constraint_flag);
457 copy_field(lower_bit_rate_constraint_flag);
458 copy_field(max_14bit_constraint_flag);
459 copy_field(inbld_flag);
460 copy_field(level_idc);
461 #undef copy_field
462
463 return 0;
464 }
465
466 /*
467 * Find exact vdpau_profile for HEVC Range Extension
468 */
469 static int vdpau_hevc_parse_rext_profile(AVCodecContext *avctx, VdpDecoderProfile *vdp_profile)
470 {
471 const HEVCContext *h = avctx->priv_data;
472 const HEVCSPS *sps = h->ps.sps;
473 const PTL *ptl = &sps->ptl;
474 const PTLCommon *general_ptl = &ptl->general_ptl;
475 const H265ProfileDescriptor *profile;
476 H265RawProfileTierLevel h265_raw_ptl = {0};
477
478 /* convert PTLCommon to H265RawProfileTierLevel */
479 ptl_convert(general_ptl, &h265_raw_ptl);
480
481 profile = ff_h265_get_profile(&h265_raw_ptl);
482 if (!profile) {
483 av_log(avctx, AV_LOG_WARNING, "HEVC profile is not found.\n");
484 if (avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH) {
485 // Default to selecting Main profile if profile mismatch is allowed
486 *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN;
487 return 0;
488 } else
489 return AVERROR(ENOTSUP);
490 }
491
492 if (!strcmp(profile->name, "Main 12") ||
493 !strcmp(profile->name, "Main 12 Intra"))
494 *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_12;
495 #ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444
496 else if (!strcmp(profile->name, "Main 4:4:4") ||
497 !strcmp(profile->name, "Main 4:4:4 Intra"))
498 *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444;
499 #endif
500 #ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444_10
501 else if (!strcmp(profile->name, "Main 4:4:4 10") ||
502 !strcmp(profile->name, "Main 4:4:4 10 Intra"))
503 *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444_10;
504 else if (!strcmp(profile->name, "Main 4:4:4 12") ||
505 !strcmp(profile->name, "Main 4:4:4 12 Intra"))
506 *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444_12;
507 #endif
508 else
509 return AVERROR(ENOTSUP);
510
511 return 0;
512 }
513
514
515 static int vdpau_hevc_init(AVCodecContext *avctx)
516 {
517 VdpDecoderProfile profile;
518 uint32_t level = avctx->level;
519 int ret;
520
521 switch (avctx->profile) {
522 case AV_PROFILE_HEVC_MAIN:
523 profile = VDP_DECODER_PROFILE_HEVC_MAIN;
524 break;
525 case AV_PROFILE_HEVC_MAIN_10:
526 profile = VDP_DECODER_PROFILE_HEVC_MAIN_10;
527 break;
528 case AV_PROFILE_HEVC_MAIN_STILL_PICTURE:
529 profile = VDP_DECODER_PROFILE_HEVC_MAIN_STILL;
530 break;
531 case AV_PROFILE_HEVC_REXT:
532 ret = vdpau_hevc_parse_rext_profile(avctx, &profile);
533 if (ret)
534 return AVERROR(ENOTSUP);
535 break;
536 default:
537 return AVERROR(ENOTSUP);
538 }
539
540 return ff_vdpau_common_init(avctx, profile, level);
541 }
542
543 const FFHWAccel ff_hevc_vdpau_hwaccel = {
544 .p.name = "hevc_vdpau",
545 .p.type = AVMEDIA_TYPE_VIDEO,
546 .p.id = AV_CODEC_ID_HEVC,
547 .p.pix_fmt = AV_PIX_FMT_VDPAU,
548 .start_frame = vdpau_hevc_start_frame,
549 .end_frame = vdpau_hevc_end_frame,
550 .decode_slice = vdpau_hevc_decode_slice,
551 .frame_priv_data_size = sizeof(struct vdpau_picture_context),
552 .init = vdpau_hevc_init,
553 .uninit = ff_vdpau_common_uninit,
554 .frame_params = ff_vdpau_common_frame_params,
555 .priv_data_size = sizeof(VDPAUContext),
556 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,
557 };
558