GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/vdpau_hevc.c Lines: 0 287 0.0 %
Date: 2020-09-25 14:59:26 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
};