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