FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/vdpau_hevc.c
Date: 2026-09-26 05:01:43
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