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