1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-03-28 12:32:17 +02:00

Merge commit '8d34a2f803c9ca9433b5a51bacbbe352e8d327e2'

* commit '8d34a2f803c9ca9433b5a51bacbbe352e8d327e2':
  vdpau: Support for VDPAU accelerated HEVC decoding

Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
This commit is contained in:
Derek Buitenhuis 2016-02-16 20:05:28 +00:00
commit cbe3f28d0a

View File

@ -53,7 +53,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
info->bit_depth_luma_minus8 = sps->bit_depth - 8;
info->bit_depth_chroma_minus8 = sps->bit_depth - 8;
info->log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4;
/** Provides the value corresponding to the nuh_temporal_id of the frame
/* Provide the value corresponding to the nuh_temporal_id of the frame
to be decoded. */
info->sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
info->log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3;
@ -63,33 +63,33 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
info->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
info->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
info->scaling_list_enabled_flag = sps->scaling_list_enable_flag;
/** Scaling lists, in diagonal order, to be used for this frame. */
/* Scaling lists, in diagonal order, to be used for this frame. */
for (size_t i = 0; i < 6; i++) {
for (size_t j = 0; j < 16; j++) {
/** Scaling List for 4x4 quantization matrix,
/* Scaling List for 4x4 quantization matrix,
indexed as ScalingList4x4[matrixId][i]. */
uint8_t pos = 4 * ff_hevc_diag_scan4x4_y[j] + ff_hevc_diag_scan4x4_x[j];
info->ScalingList4x4[i][j] = sl->sl[0][i][pos];
}
for (size_t j = 0; j < 64; j++) {
uint8_t pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
/** Scaling List for 8x8 quantization matrix,
/* Scaling List for 8x8 quantization matrix,
indexed as ScalingList8x8[matrixId][i]. */
info->ScalingList8x8[i][j] = sl->sl[1][i][pos];
/** Scaling List for 16x16 quantization matrix,
/* Scaling List for 16x16 quantization matrix,
indexed as ScalingList16x16[matrixId][i]. */
info->ScalingList16x16[i][j] = sl->sl[2][i][pos];
if (i < 2) {
/** Scaling List for 32x32 quantization matrix,
/* Scaling List for 32x32 quantization matrix,
indexed as ScalingList32x32[matrixId][i]. */
info->ScalingList32x32[i][j] = sl->sl[3][i * 3][pos];
}
}
/** Scaling List DC Coefficients for 16x16,
/* Scaling List DC Coefficients for 16x16,
indexed as ScalingListDCCoeff16x16[matrixId]. */
info->ScalingListDCCoeff16x16[i] = sl->sl_dc[0][i];
if (i < 2) {
/** Scaling List DC Coefficients for 32x32,
/* Scaling List DC Coefficients for 32x32,
indexed as ScalingListDCCoeff32x32[matrixId]. */
info->ScalingListDCCoeff32x32[i] = sl->sl_dc[1][i * 3];
}
@ -98,32 +98,28 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
info->sample_adaptive_offset_enabled_flag = sps->sao_enabled;
info->pcm_enabled_flag = sps->pcm_enabled_flag;
if (info->pcm_enabled_flag) {
/** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
/* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
info->pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1;
/** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
/* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
info->pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1;
/** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
/* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
info->log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3;
/** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
/* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
info->log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size;
/** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
/* Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
info->pcm_loop_filter_disabled_flag = sps->pcm.loop_filter_disable_flag;
}
/** Per spec, when zero, assume short_term_ref_pic_set_sps_flag
/* Per spec, when zero, assume short_term_ref_pic_set_sps_flag
is also zero. */
info->num_short_term_ref_pic_sets = sps->nb_st_rps;
info->long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag;
/** Only needed if long_term_ref_pics_present_flag is set. Ignored
/* Only needed if long_term_ref_pics_present_flag is set. Ignored
otherwise. */
info->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
info->sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag;
info->strong_intra_smoothing_enabled_flag = sps->sps_strong_intra_smoothing_enable_flag;
/** @} */
/** \name HEVC Picture Parameter Set
*
* Copies of the HEVC Picture Parameter Set bitstream fields.
* @{ */
/* Copy the HEVC Picture Parameter Set bitstream fields. */
info->dependent_slice_segments_enabled_flag = pps->dependent_slice_segments_enabled_flag;
info->output_flag_present_flag = pps->output_flag_present_flag;
info->num_extra_slice_header_bits = pps->num_extra_slice_header_bits;
@ -135,7 +131,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
info->constrained_intra_pred_flag = pps->constrained_intra_pred_flag;
info->transform_skip_enabled_flag = pps->transform_skip_enabled_flag;
info->cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag;
/** Only needed if cu_qp_delta_enabled_flag is set. Ignored otherwise. */
/* Only needed if cu_qp_delta_enabled_flag is set. Ignored otherwise. */
info->diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth;
info->pps_cb_qp_offset = pps->cb_qp_offset;
info->pps_cr_qp_offset = pps->cr_qp_offset;
@ -146,58 +142,53 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
info->tiles_enabled_flag = pps->tiles_enabled_flag;
info->entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag;
if (info->tiles_enabled_flag) {
/** Only valid if tiles_enabled_flag is set. Ignored otherwise. */
/* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
info->num_tile_columns_minus1 = pps->num_tile_columns - 1;
/** Only valid if tiles_enabled_flag is set. Ignored otherwise. */
/* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
info->num_tile_rows_minus1 = pps->num_tile_rows - 1;
/** Only valid if tiles_enabled_flag is set. Ignored otherwise. */
/* Only valid if tiles_enabled_flag is set. Ignored otherwise. */
info->uniform_spacing_flag = pps->uniform_spacing_flag;
/** Only need to set 0..num_tile_columns_minus1. The struct
/* Only need to set 0..num_tile_columns_minus1. The struct
definition reserves up to the maximum of 20. Invalid values are
ignored. */
for (ssize_t i = 0; i < pps->num_tile_columns; i++) {
info->column_width_minus1[i] = pps->column_width[i] - 1;
}
/** Only need to set 0..num_tile_rows_minus1. The struct
/* Only need to set 0..num_tile_rows_minus1. The struct
definition reserves up to the maximum of 22. Invalid values are
ignored.*/
for (ssize_t i = 0; i < pps->num_tile_rows; i++) {
info->row_height_minus1[i] = pps->row_height[i] - 1;
}
/** Only needed if tiles_enabled_flag is set. Invalid values are
/* Only needed if tiles_enabled_flag is set. Invalid values are
ignored. */
info->loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag;
}
info->pps_loop_filter_across_slices_enabled_flag = pps->seq_loop_filter_across_slices_enabled_flag;
info->deblocking_filter_control_present_flag = pps->deblocking_filter_control_present_flag;
/** Only valid if deblocking_filter_control_present_flag is set. Ignored
/* Only valid if deblocking_filter_control_present_flag is set. Ignored
otherwise. */
info->deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag;
/** Only valid if deblocking_filter_control_present_flag is set. Ignored
/* Only valid if deblocking_filter_control_present_flag is set. Ignored
otherwise. */
info->pps_deblocking_filter_disabled_flag = pps->disable_dbf;
/** Only valid if deblocking_filter_control_present_flag is set and
/* Only valid if deblocking_filter_control_present_flag is set and
pps_deblocking_filter_disabled_flag is not set. Ignored otherwise.*/
info->pps_beta_offset_div2 = pps->beta_offset / 2;
/** Only valid if deblocking_filter_control_present_flag is set and
/* Only valid if deblocking_filter_control_present_flag is set and
pps_deblocking_filter_disabled_flag is not set. Ignored otherwise. */
info->pps_tc_offset_div2 = pps->tc_offset / 2;
info->lists_modification_present_flag = pps->lists_modification_present_flag;
info->log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2;
info->slice_segment_header_extension_present_flag = pps->slice_header_extension_present_flag;
/** \name HEVC Slice Segment Header
*
* Copies of the HEVC Slice Segment Header bitstream fields and calculated
* values detailed in the specification.
* @{ */
/** Set to 1 if nal_unit_type is equal to IDR_W_RADL or IDR_N_LP.
/* Set to 1 if nal_unit_type is equal to IDR_W_RADL or IDR_N_LP.
Set to zero otherwise. */
info->IDRPicFlag = IS_IDR(h);
/** Set to 1 if nal_unit_type in the range of BLA_W_LP to
/* Set to 1 if nal_unit_type in the range of BLA_W_LP to
RSV_IRAP_VCL23, inclusive. Set to zero otherwise.*/
info->RAPPicFlag = IS_IRAP(h);
/** See section 7.4.7.1 of the specification. */
/* See section 7.4.7.1 of the specification. */
info->CurrRpsIdx = sps->nb_st_rps;
if (sh->short_term_ref_pic_set_sps_flag == 1) {
for (size_t i = 0; i < sps->nb_st_rps; i++) {
@ -207,15 +198,15 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
}
}
}
/** See section 7.4.7.2 of the specification. */
/* See section 7.4.7.2 of the specification. */
info->NumPocTotalCurr = ff_hevc_frame_nb_refs(h);
if (sh->short_term_ref_pic_set_sps_flag == 0 && sh->short_term_rps) {
/** Corresponds to specification field, NumDeltaPocs[RefRpsIdx].
/* Corresponds to specification field, NumDeltaPocs[RefRpsIdx].
Only applicable when short_term_ref_pic_set_sps_flag == 0.
Implementations will ignore this value in other cases. See 7.4.8. */
info->NumDeltaPocsOfRefRpsIdx = sh->short_term_rps->rps_idx_num_delta_pocs;
}
/** Section 7.6.3.1 of the H.265/HEVC Specification defines the syntax of
/* Section 7.6.3.1 of the H.265/HEVC Specification defines the syntax of
the slice_segment_header. This header contains information that
some VDPAU implementations may choose to skip. The VDPAU API
requires client applications to track the number of bits used in the
@ -223,19 +214,17 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
reference pictures. First, VDPAU requires the number of bits used by
the short_term_ref_pic_set array in the slice_segment_header. */
info->NumShortTermPictureSliceHeaderBits = sh->short_term_ref_pic_set_size;
/** Second, VDPAU requires the number of bits used for long term reference
/* Second, VDPAU requires the number of bits used for long term reference
pictures in the slice_segment_header. This is equal to the number
of bits used for the contents of the block beginning with
"if(long_term_ref_pics_present_flag)". */
info->NumLongTermPictureSliceHeaderBits = sh->long_term_ref_pic_set_size;
/** @} */
/** Slice Decoding Process - Picture Order Count */
/** The value of PicOrderCntVal of the picture in the access unit
/* The value of PicOrderCntVal of the picture in the access unit
containing the SEI message. The picture being decoded. */
info->CurrPicOrderCntVal = h->poc;
/** Slice Decoding Process - Reference Picture Sets */
/* Slice Decoding Process - Reference Picture Sets */
for (size_t i = 0; i < 16; i++) {
info->RefPics[i] = VDP_INVALID_HANDLE;
info->PicOrderCntVal[i] = 0;
@ -251,13 +240,13 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
"This frame may not be decoded correctly.\n");
break;
}
/** Array of video reference surfaces.
/* Array of video reference surfaces.
Set any unused positions to VDP_INVALID_HANDLE. */
info->RefPics[j] = ff_vdpau_get_surface_id(frame->frame);
/** Array of picture order counts. These correspond to positions
/* Array of picture order counts. These correspond to positions
in the RefPics array. */
info->PicOrderCntVal[j] = frame->poc;
/** Array used to specify whether a particular RefPic is
/* Array used to specify whether a particular RefPic is
a long term reference. A value of "1" indicates a long-term
reference. */
// XXX: Setting this caused glitches in the nvidia implementation
@ -267,7 +256,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
j++;
}
}
/** Copy of specification field, see Section 8.3.2 of the
/* Copy of specification field, see Section 8.3.2 of the
H.265/HEVC Specification. */
info->NumPocStCurrBefore = h->rps[ST_CURR_BEF].nb_refs;
if (info->NumPocStCurrBefore > 8) {
@ -276,7 +265,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
"This frame may not be decoded correctly.\n");
info->NumPocStCurrBefore = 8;
}
/** Copy of specification field, see Section 8.3.2 of the
/* Copy of specification field, see Section 8.3.2 of the
H.265/HEVC Specification. */
info->NumPocStCurrAfter = h->rps[ST_CURR_AFT].nb_refs;
if (info->NumPocStCurrAfter > 8) {
@ -285,7 +274,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
"This frame may not be decoded correctly.\n");
info->NumPocStCurrAfter = 8;
}
/** Copy of specification field, see Section 8.3.2 of the
/* Copy of specification field, see Section 8.3.2 of the
H.265/HEVC Specification. */
info->NumPocLtCurr = h->rps[LT_CURR].nb_refs;
if (info->NumPocLtCurr > 8) {
@ -294,7 +283,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
"This frame may not be decoded correctly.\n");
info->NumPocLtCurr = 8;
}
/** Reference Picture Set list, one of the short-term RPS. These
/* Reference Picture Set list, one of the short-term RPS. These
correspond to positions in the RefPics array. */
for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) {
HEVCFrame *frame = h->rps[ST_CURR_BEF].ref[i];
@ -317,7 +306,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
av_log(avctx, AV_LOG_WARNING, "missing STR Before frame: %zd\n", i);
}
}
/** Reference Picture Set list, one of the short-term RPS. These
/* Reference Picture Set list, one of the short-term RPS. These
correspond to positions in the RefPics array. */
for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) {
HEVCFrame *frame = h->rps[ST_CURR_AFT].ref[i];
@ -340,7 +329,7 @@ static int vdpau_hevc_start_frame(AVCodecContext *avctx,
av_log(avctx, AV_LOG_WARNING, "missing STR After frame: %zd\n", i);
}
}
/** Reference Picture Set list, one of the long-term RPS. These
/* Reference Picture Set list, one of the long-term RPS. These
correspond to positions in the RefPics array. */
for (ssize_t i = 0, j = 0; i < h->rps[LT_CURR].nb_refs; i++) {
HEVCFrame *frame = h->rps[LT_CURR].ref[i];