2 * MPEG-H Part 2 / HEVC / H.265 HW decode acceleration through VDPAU
4 * Copyright (c) 2013 Philip Langdale
6 * This file is part of FFmpeg.
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.
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.
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
23 #include <vdpau/vdpau.h>
30 #include "vdpau_internal.h"
32 static int vdpau_hevc_start_frame(AVCodecContext *avctx,
33 const uint8_t *buffer, uint32_t size)
35 HEVCContext *h = avctx->priv_data;
36 HEVCFrame *pic = h->ref;
37 struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
39 VdpPictureInfoHEVC *info = &pic_ctx->info.hevc;
41 const HEVCSPS *sps = h->ps.sps;
42 const HEVCPPS *pps = h->ps.pps;
43 const SliceHeader *sh = &h->sh;
44 const ScalingList *sl = pps->scaling_list_data_present_flag ?
45 &pps->scaling_list : &sps->scaling_list;
47 /* init VdpPictureInfoHEVC */
50 info->chroma_format_idc = sps->chroma_format_idc;
51 info->separate_colour_plane_flag = sps->separate_colour_plane_flag;
52 info->pic_width_in_luma_samples = sps->width;
53 info->pic_height_in_luma_samples = sps->height;
54 info->bit_depth_luma_minus8 = sps->bit_depth - 8;
55 info->bit_depth_chroma_minus8 = sps->bit_depth - 8;
56 info->log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4;
57 /* Provide the value corresponding to the nuh_temporal_id of the frame
59 info->sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
60 info->log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3;
61 info->log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size;
62 info->log2_min_transform_block_size_minus2 = sps->log2_min_tb_size - 2;
63 info->log2_diff_max_min_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size;
64 info->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
65 info->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
66 info->scaling_list_enabled_flag = sps->scaling_list_enable_flag;
67 /* Scaling lists, in diagonal order, to be used for this frame. */
68 for (size_t i = 0; i < 6; i++) {
69 for (size_t j = 0; j < 16; j++) {
70 /* Scaling List for 4x4 quantization matrix,
71 indexed as ScalingList4x4[matrixId][i]. */
72 uint8_t pos = 4 * ff_hevc_diag_scan4x4_y[j] + ff_hevc_diag_scan4x4_x[j];
73 info->ScalingList4x4[i][j] = sl->sl[0][i][pos];
75 for (size_t j = 0; j < 64; j++) {
76 uint8_t pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
77 /* Scaling List for 8x8 quantization matrix,
78 indexed as ScalingList8x8[matrixId][i]. */
79 info->ScalingList8x8[i][j] = sl->sl[1][i][pos];
80 /* Scaling List for 16x16 quantization matrix,
81 indexed as ScalingList16x16[matrixId][i]. */
82 info->ScalingList16x16[i][j] = sl->sl[2][i][pos];
84 /* Scaling List for 32x32 quantization matrix,
85 indexed as ScalingList32x32[matrixId][i]. */
86 info->ScalingList32x32[i][j] = sl->sl[3][i * 3][pos];
89 /* Scaling List DC Coefficients for 16x16,
90 indexed as ScalingListDCCoeff16x16[matrixId]. */
91 info->ScalingListDCCoeff16x16[i] = sl->sl_dc[0][i];
93 /* Scaling List DC Coefficients for 32x32,
94 indexed as ScalingListDCCoeff32x32[matrixId]. */
95 info->ScalingListDCCoeff32x32[i] = sl->sl_dc[1][i * 3];
98 info->amp_enabled_flag = sps->amp_enabled_flag;
99 info->sample_adaptive_offset_enabled_flag = sps->sao_enabled;
100 info->pcm_enabled_flag = sps->pcm_enabled_flag;
101 if (info->pcm_enabled_flag) {
102 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
103 info->pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1;
104 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
105 info->pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1;
106 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
107 info->log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3;
108 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
109 info->log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size;
110 /* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
111 info->pcm_loop_filter_disabled_flag = sps->pcm.loop_filter_disable_flag;
113 /* Per spec, when zero, assume short_term_ref_pic_set_sps_flag
115 info->num_short_term_ref_pic_sets = sps->nb_st_rps;
116 info->long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag;
117 /* Only needed if long_term_ref_pics_present_flag is set. Ignored
119 info->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
120 info->sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag;
121 info->strong_intra_smoothing_enabled_flag = sps->sps_strong_intra_smoothing_enable_flag;
123 /* Copy the HEVC Picture Parameter Set bitstream fields. */
124 info->dependent_slice_segments_enabled_flag = pps->dependent_slice_segments_enabled_flag;
125 info->output_flag_present_flag = pps->output_flag_present_flag;
126 info->num_extra_slice_header_bits = pps->num_extra_slice_header_bits;
127 info->sign_data_hiding_enabled_flag = pps->sign_data_hiding_flag;
128 info->cabac_init_present_flag = pps->cabac_init_present_flag;
129 info->num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1;
130 info->num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1;
131 info->init_qp_minus26 = pps->pic_init_qp_minus26;
132 info->constrained_intra_pred_flag = pps->constrained_intra_pred_flag;
133 info->transform_skip_enabled_flag = pps->transform_skip_enabled_flag;
134 info->cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag;
135 /* Only needed if cu_qp_delta_enabled_flag is set. Ignored otherwise. */
136 info->diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth;
137 info->pps_cb_qp_offset = pps->cb_qp_offset;
138 info->pps_cr_qp_offset = pps->cr_qp_offset;
139 info->pps_slice_chroma_qp_offsets_present_flag = pps->pic_slice_level_chroma_qp_offsets_present_flag;
140 info->weighted_pred_flag = pps->weighted_pred_flag;
141 info->weighted_bipred_flag = pps->weighted_bipred_flag;
142 info->transquant_bypass_enabled_flag = pps->transquant_bypass_enable_flag;
143 info->tiles_enabled_flag = pps->tiles_enabled_flag;
144 info->entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag;
145 if (info->tiles_enabled_flag) {
146 /* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
147 info->num_tile_columns_minus1 = pps->num_tile_columns - 1;
148 /* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
149 info->num_tile_rows_minus1 = pps->num_tile_rows - 1;
150 /* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
151 info->uniform_spacing_flag = pps->uniform_spacing_flag;
152 /* Only need to set 0..num_tile_columns_minus1. The struct
153 definition reserves up to the maximum of 20. Invalid values are
155 for (ssize_t i = 0; i < pps->num_tile_columns; i++) {
156 info->column_width_minus1[i] = pps->column_width[i] - 1;
158 /* Only need to set 0..num_tile_rows_minus1. The struct
159 definition reserves up to the maximum of 22. Invalid values are
161 for (ssize_t i = 0; i < pps->num_tile_rows; i++) {
162 info->row_height_minus1[i] = pps->row_height[i] - 1;
164 /* Only needed if tiles_enabled_flag is set. Invalid values are
166 info->loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag;
168 info->pps_loop_filter_across_slices_enabled_flag = pps->seq_loop_filter_across_slices_enabled_flag;
169 info->deblocking_filter_control_present_flag = pps->deblocking_filter_control_present_flag;
170 /* Only valid if deblocking_filter_control_present_flag is set. Ignored
172 info->deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag;
173 /* Only valid if deblocking_filter_control_present_flag is set. Ignored
175 info->pps_deblocking_filter_disabled_flag = pps->disable_dbf;
176 /* Only valid if deblocking_filter_control_present_flag is set and
177 pps_deblocking_filter_disabled_flag is not set. Ignored otherwise.*/
178 info->pps_beta_offset_div2 = pps->beta_offset / 2;
179 /* Only valid if deblocking_filter_control_present_flag is set and
180 pps_deblocking_filter_disabled_flag is not set. Ignored otherwise. */
181 info->pps_tc_offset_div2 = pps->tc_offset / 2;
182 info->lists_modification_present_flag = pps->lists_modification_present_flag;
183 info->log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2;
184 info->slice_segment_header_extension_present_flag = pps->slice_header_extension_present_flag;
186 /* Set to 1 if nal_unit_type is equal to IDR_W_RADL or IDR_N_LP.
187 Set to zero otherwise. */
188 info->IDRPicFlag = IS_IDR(h);
189 /* Set to 1 if nal_unit_type in the range of BLA_W_LP to
190 RSV_IRAP_VCL23, inclusive. Set to zero otherwise.*/
191 info->RAPPicFlag = IS_IRAP(h);
192 /* See section 7.4.7.1 of the specification. */
193 info->CurrRpsIdx = sps->nb_st_rps;
194 if (sh->short_term_ref_pic_set_sps_flag == 1) {
195 for (size_t i = 0; i < sps->nb_st_rps; i++) {
196 if (sh->short_term_rps == &sps->st_rps[i]) {
197 info->CurrRpsIdx = i;
202 /* See section 7.4.7.2 of the specification. */
203 info->NumPocTotalCurr = ff_hevc_frame_nb_refs(h);
204 if (sh->short_term_ref_pic_set_sps_flag == 0 && sh->short_term_rps) {
205 /* Corresponds to specification field, NumDeltaPocs[RefRpsIdx].
206 Only applicable when short_term_ref_pic_set_sps_flag == 0.
207 Implementations will ignore this value in other cases. See 7.4.8. */
208 info->NumDeltaPocsOfRefRpsIdx = sh->short_term_rps->rps_idx_num_delta_pocs;
210 /* Section 7.6.3.1 of the H.265/HEVC Specification defines the syntax of
211 the slice_segment_header. This header contains information that
212 some VDPAU implementations may choose to skip. The VDPAU API
213 requires client applications to track the number of bits used in the
214 slice header for structures associated with short term and long term
215 reference pictures. First, VDPAU requires the number of bits used by
216 the short_term_ref_pic_set array in the slice_segment_header. */
217 info->NumShortTermPictureSliceHeaderBits = sh->short_term_ref_pic_set_size;
218 /* Second, VDPAU requires the number of bits used for long term reference
219 pictures in the slice_segment_header. This is equal to the number
220 of bits used for the contents of the block beginning with
221 "if(long_term_ref_pics_present_flag)". */
222 info->NumLongTermPictureSliceHeaderBits = sh->long_term_ref_pic_set_size;
224 /* The value of PicOrderCntVal of the picture in the access unit
225 containing the SEI message. The picture being decoded. */
226 info->CurrPicOrderCntVal = h->poc;
228 /* Slice Decoding Process - Reference Picture Sets */
229 for (size_t i = 0; i < 16; i++) {
230 info->RefPics[i] = VDP_INVALID_HANDLE;
231 info->PicOrderCntVal[i] = 0;
232 info->IsLongTerm[i] = 0;
234 for (size_t i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
235 const HEVCFrame *frame = &h->DPB[i];
236 if (frame != h->ref && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF |
237 HEVC_FRAME_FLAG_SHORT_REF))) {
239 av_log(avctx, AV_LOG_WARNING,
240 "VDPAU only supports up to 16 references in the DPB. "
241 "This frame may not be decoded correctly.\n");
244 /* Array of video reference surfaces.
245 Set any unused positions to VDP_INVALID_HANDLE. */
246 info->RefPics[j] = ff_vdpau_get_surface_id(frame->frame);
247 /* Array of picture order counts. These correspond to positions
248 in the RefPics array. */
249 info->PicOrderCntVal[j] = frame->poc;
250 /* Array used to specify whether a particular RefPic is
251 a long term reference. A value of "1" indicates a long-term
253 // XXX: Setting this caused glitches in the nvidia implementation
254 // Always setting it to zero, produces correct results
255 //info->IsLongTerm[j] = frame->flags & HEVC_FRAME_FLAG_LONG_REF;
256 info->IsLongTerm[j] = 0;
260 /* Copy of specification field, see Section 8.3.2 of the
261 H.265/HEVC Specification. */
262 info->NumPocStCurrBefore = h->rps[ST_CURR_BEF].nb_refs;
263 if (info->NumPocStCurrBefore > 8) {
264 av_log(avctx, AV_LOG_WARNING,
265 "VDPAU only supports up to 8 references in StCurrBefore. "
266 "This frame may not be decoded correctly.\n");
267 info->NumPocStCurrBefore = 8;
269 /* Copy of specification field, see Section 8.3.2 of the
270 H.265/HEVC Specification. */
271 info->NumPocStCurrAfter = h->rps[ST_CURR_AFT].nb_refs;
272 if (info->NumPocStCurrAfter > 8) {
273 av_log(avctx, AV_LOG_WARNING,
274 "VDPAU only supports up to 8 references in StCurrAfter. "
275 "This frame may not be decoded correctly.\n");
276 info->NumPocStCurrAfter = 8;
278 /* Copy of specification field, see Section 8.3.2 of the
279 H.265/HEVC Specification. */
280 info->NumPocLtCurr = h->rps[LT_CURR].nb_refs;
281 if (info->NumPocLtCurr > 8) {
282 av_log(avctx, AV_LOG_WARNING,
283 "VDPAU only supports up to 8 references in LtCurr. "
284 "This frame may not be decoded correctly.\n");
285 info->NumPocLtCurr = 8;
287 /* Reference Picture Set list, one of the short-term RPS. These
288 correspond to positions in the RefPics array. */
289 for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) {
290 HEVCFrame *frame = h->rps[ST_CURR_BEF].ref[i];
293 uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
294 for (size_t k = 0; k < 16; k++) {
295 if (id == info->RefPics[k]) {
296 info->RefPicSetStCurrBefore[j] = k;
303 av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
307 av_log(avctx, AV_LOG_WARNING, "missing STR Before frame: %zd\n", i);
310 /* Reference Picture Set list, one of the short-term RPS. These
311 correspond to positions in the RefPics array. */
312 for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) {
313 HEVCFrame *frame = h->rps[ST_CURR_AFT].ref[i];
316 uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
317 for (size_t k = 0; k < 16; k++) {
318 if (id == info->RefPics[k]) {
319 info->RefPicSetStCurrAfter[j] = k;
326 av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
330 av_log(avctx, AV_LOG_WARNING, "missing STR After frame: %zd\n", i);
333 /* Reference Picture Set list, one of the long-term RPS. These
334 correspond to positions in the RefPics array. */
335 for (ssize_t i = 0, j = 0; i < h->rps[LT_CURR].nb_refs; i++) {
336 HEVCFrame *frame = h->rps[LT_CURR].ref[i];
339 uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
340 for (size_t k = 0; k < 16; k++) {
341 if (id == info->RefPics[k]) {
342 info->RefPicSetLtCurr[j] = k;
349 av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
353 av_log(avctx, AV_LOG_WARNING, "missing LTR frame: %zd\n", i);
357 return ff_vdpau_common_start_frame(pic_ctx, buffer, size);
360 static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
362 static int vdpau_hevc_decode_slice(AVCodecContext *avctx,
363 const uint8_t *buffer, uint32_t size)
365 HEVCContext *h = avctx->priv_data;
366 struct vdpau_picture_context *pic_ctx = h->ref->hwaccel_picture_private;
369 val = ff_vdpau_add_buffer(pic_ctx, start_code_prefix, 3);
373 val = ff_vdpau_add_buffer(pic_ctx, buffer, size);
380 static int vdpau_hevc_end_frame(AVCodecContext *avctx)
382 HEVCContext *h = avctx->priv_data;
383 struct vdpau_picture_context *pic_ctx = h->ref->hwaccel_picture_private;
386 val = ff_vdpau_common_end_frame(avctx, h->ref->frame, pic_ctx);
393 static int vdpau_hevc_init(AVCodecContext *avctx)
395 VdpDecoderProfile profile;
396 uint32_t level = avctx->level;
398 switch (avctx->profile) {
399 case FF_PROFILE_HEVC_MAIN:
400 profile = VDP_DECODER_PROFILE_HEVC_MAIN;
402 case FF_PROFILE_HEVC_MAIN_10:
403 profile = VDP_DECODER_PROFILE_HEVC_MAIN_10;
405 case FF_PROFILE_HEVC_MAIN_STILL_PICTURE:
406 profile = VDP_DECODER_PROFILE_HEVC_MAIN_STILL;
409 return AVERROR(ENOTSUP);
412 return ff_vdpau_common_init(avctx, profile, level);
415 AVHWAccel ff_hevc_vdpau_hwaccel = {
416 .name = "hevc_vdpau",
417 .type = AVMEDIA_TYPE_VIDEO,
418 .id = AV_CODEC_ID_HEVC,
419 .pix_fmt = AV_PIX_FMT_VDPAU,
420 .start_frame = vdpau_hevc_start_frame,
421 .end_frame = vdpau_hevc_end_frame,
422 .decode_slice = vdpau_hevc_decode_slice,
423 .frame_priv_data_size = sizeof(struct vdpau_picture_context),
424 .init = vdpau_hevc_init,
425 .uninit = ff_vdpau_common_uninit,
426 .priv_data_size = sizeof(VDPAUContext),
427 .caps_internal = HWACCEL_CAP_ASYNC_SAFE,