FFmpeg coverage


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