FFmpeg coverage


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