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