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