libs: h265: dec: Add extension flags setting.

Use VAPictureParameterBufferHEVCExtension&
VASliceParameterBufferHEVCExtension to pass extension setting from
some extension profile clips which may include these information.
The hevc extension setting only supported after libva release 2.2.0
(API 1.2.0).
This commit is contained in:
Wangfei 2019-04-29 09:52:39 +08:00 committed by Víctor Manuel Jáquez Leal
parent be496a66c5
commit 47d256b24c

View file

@ -251,15 +251,6 @@ gst_vaapi_picture_h265_create (GstVaapiPictureH265 * picture,
return TRUE;
}
static inline GstVaapiPictureH265 *
gst_vaapi_picture_h265_new (GstVaapiDecoderH265 * decoder)
{
return (GstVaapiPictureH265 *)
gst_vaapi_codec_object_new (&GstVaapiPictureH265Class,
GST_VAAPI_CODEC_BASE (decoder), NULL,
sizeof (VAPictureParameterBufferHEVC), NULL, 0, 0);
}
static inline void
gst_vaapi_picture_h265_set_reference (GstVaapiPictureH265 * picture,
guint reference_flags)
@ -535,6 +526,36 @@ nal_is_ref (guint8 nal_type)
return ret;
}
static gboolean
is_range_extension_profile (GstVaapiProfile profile)
{
if (profile == GST_VAAPI_PROFILE_H265_MAIN_422_10
|| profile == GST_VAAPI_PROFILE_H265_MAIN_444
|| profile == GST_VAAPI_PROFILE_H265_MAIN_444_10)
return TRUE;
return FALSE;
}
static inline GstVaapiPictureH265 *
gst_vaapi_picture_h265_new (GstVaapiDecoderH265 * decoder)
{
GstVaapiDecoderH265Private *const priv = &decoder->priv;
if (is_range_extension_profile (priv->profile)) {
#if VA_CHECK_VERSION(1,2,0)
return (GstVaapiPictureH265 *)
gst_vaapi_codec_object_new (&GstVaapiPictureH265Class,
GST_VAAPI_CODEC_BASE (decoder), NULL,
sizeof (VAPictureParameterBufferHEVCExtension), NULL, 0, 0);
#endif
return NULL;
} else {
return (GstVaapiPictureH265 *)
gst_vaapi_codec_object_new (&GstVaapiPictureH265Class,
GST_VAAPI_CODEC_BASE (decoder), NULL,
sizeof (VAPictureParameterBufferHEVC), NULL, 0, 0);
}
}
/* Activates the supplied PPS */
static GstH265PPS *
ensure_pps (GstVaapiDecoderH265 * decoder, GstH265PPS * pps)
@ -1814,9 +1835,18 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
GstVaapiPicture *const base_picture = &picture->base;
GstH265PPS *const pps = get_pps (decoder);
GstH265SPS *const sps = get_sps (decoder);
VAPictureParameterBufferHEVC *const pic_param = base_picture->param;
VAPictureParameterBufferHEVC *pic_param = base_picture->param;
guint i, n;
#if VA_CHECK_VERSION(1,2,0)
VAPictureParameterBufferHEVCRext *pic_rext_param = NULL;
if (is_range_extension_profile (priv->profile)) {
VAPictureParameterBufferHEVCExtension *param = base_picture->param;
pic_param = &param->base;
pic_rext_param = &param->rext;
}
#endif
pic_param->pic_fields.value = 0;
pic_param->slice_parsing_fields.value = 0;
@ -1928,6 +1958,56 @@ fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
/* FIXME: Set correct value as mentioned in va_dec_hevc.h */
pic_param->st_rps_bits = 0;
#if VA_CHECK_VERSION(1,2,0)
if (pic_rext_param) {
pic_rext_param->range_extension_pic_fields.value = 0;
#define COPY_REXT_FIELD(s, f) \
pic_rext_param->f = s.f
#define COPY_REXT_BFM(a, s, f) \
pic_rext_param->a.bits.f = s.f
COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params,
transform_skip_rotation_enabled_flag);
COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params,
transform_skip_context_enabled_flag);
COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params,
implicit_rdpcm_enabled_flag);
COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params,
explicit_rdpcm_enabled_flag);
COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params,
extended_precision_processing_flag);
COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params,
intra_smoothing_disabled_flag);
COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params,
high_precision_offsets_enabled_flag);
COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params,
persistent_rice_adaptation_enabled_flag);
COPY_REXT_BFM (range_extension_pic_fields, sps->sps_extnsion_params,
cabac_bypass_alignment_enabled_flag);
COPY_REXT_BFM (range_extension_pic_fields, pps->pps_extension_params,
cross_component_prediction_enabled_flag);
COPY_REXT_BFM (range_extension_pic_fields, pps->pps_extension_params,
chroma_qp_offset_list_enabled_flag);
COPY_REXT_FIELD (pps->pps_extension_params, diff_cu_chroma_qp_offset_depth);
COPY_REXT_FIELD (pps->pps_extension_params,
chroma_qp_offset_list_len_minus1);
COPY_REXT_FIELD (pps->pps_extension_params, log2_sao_offset_scale_luma);
COPY_REXT_FIELD (pps->pps_extension_params, log2_sao_offset_scale_chroma);
COPY_REXT_FIELD (pps->pps_extension_params,
log2_max_transform_skip_block_size_minus2);
memcpy (pic_rext_param->cb_qp_offset_list,
pps->pps_extension_params.cb_qp_offset_list,
sizeof (pic_rext_param->cb_qp_offset_list));
memcpy (pic_rext_param->cr_qp_offset_list,
pps->pps_extension_params.cr_qp_offset_list,
sizeof (pic_rext_param->cr_qp_offset_list));
}
#endif
return TRUE;
}
@ -2302,13 +2382,22 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder,
GstVaapiSlice * slice, GstH265SliceHdr * slice_hdr)
{
GstVaapiDecoderH265Private *const priv = &decoder->priv;
VASliceParameterBufferHEVC *const slice_param = slice->param;
VASliceParameterBufferHEVC *slice_param = slice->param;
GstH265PPS *const pps = get_pps (decoder);
GstH265SPS *const sps = get_sps (decoder);
GstH265PredWeightTable *const w = &slice_hdr->pred_weight_table;
gint chroma_weight, chroma_log2_weight_denom;
gint i, j;
#if VA_CHECK_VERSION(1,2,0)
VASliceParameterBufferHEVCRext *slice_rext_param = NULL;
if (is_range_extension_profile (priv->profile)) {
VASliceParameterBufferHEVCExtension *param = slice->param;
slice_param = &param->base;
slice_rext_param = &param->rext;
}
#endif
slice_param->luma_log2_weight_denom = 0;
slice_param->delta_chroma_log2_weight_denom = 0;
@ -2333,6 +2422,19 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder,
memset (slice_param->ChromaOffsetL1, 0,
sizeof (slice_param->ChromaOffsetL1));
#if VA_CHECK_VERSION(1,2,0)
if (slice_rext_param) {
memset (slice_rext_param->luma_offset_l0, 0,
sizeof (slice_rext_param->luma_offset_l0));
memset (slice_rext_param->luma_offset_l1, 0,
sizeof (slice_rext_param->luma_offset_l1));
memset (slice_rext_param->ChromaOffsetL0, 0,
sizeof (slice_rext_param->ChromaOffsetL0));
memset (slice_rext_param->ChromaOffsetL1, 0,
sizeof (slice_rext_param->ChromaOffsetL1));
}
#endif
slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
if (sps->chroma_array_type != 0)
slice_param->delta_chroma_log2_weight_denom =
@ -2346,6 +2448,10 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder,
if (slice_hdr->pred_weight_table.luma_weight_l0_flag[i]) {
slice_param->delta_luma_weight_l0[i] = w->delta_luma_weight_l0[i];
slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
#if VA_CHECK_VERSION(1,2,0)
if (slice_rext_param)
slice_rext_param->luma_offset_l0[i] = w->luma_offset_l0[i];
#endif
}
if (slice_hdr->pred_weight_table.chroma_weight_l0_flag[i]) {
for (j = 0; j < 2; j++) {
@ -2360,6 +2466,14 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder,
((priv->WpOffsetHalfRangeC *
chroma_weight) >> chroma_log2_weight_denom)),
-priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1);
#if VA_CHECK_VERSION(1,2,0)
if (slice_rext_param)
slice_rext_param->ChromaOffsetL0[i][j] = CLAMP (
(priv->WpOffsetHalfRangeC + w->delta_chroma_offset_l0[i][j] -
((priv->WpOffsetHalfRangeC *
chroma_weight) >> chroma_log2_weight_denom)),
-priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1);
#endif
}
}
}
@ -2369,6 +2483,10 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder,
if (slice_hdr->pred_weight_table.luma_weight_l1_flag[i]) {
slice_param->delta_luma_weight_l1[i] = w->delta_luma_weight_l1[i];
slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
#if VA_CHECK_VERSION(1,2,0)
if (slice_rext_param)
slice_rext_param->luma_offset_l1[i] = w->luma_offset_l1[i];
#endif
}
if (slice_hdr->pred_weight_table.chroma_weight_l1_flag[i]) {
for (j = 0; j < 2; j++) {
@ -2385,6 +2503,15 @@ fill_pred_weight_table (GstVaapiDecoderH265 * decoder,
((priv->WpOffsetHalfRangeC *
chroma_weight) >> chroma_log2_weight_denom)),
-priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1);
#if VA_CHECK_VERSION(1,2,0)
if (slice_rext_param)
slice_rext_param->ChromaOffsetL1[i][j] =
CLAMP ((priv->WpOffsetHalfRangeC +
w->delta_chroma_offset_l1[i][j] -
((priv->WpOffsetHalfRangeC *
chroma_weight) >> chroma_log2_weight_denom)),
-priv->WpOffsetHalfRangeC, priv->WpOffsetHalfRangeC - 1);
#endif
}
}
}
@ -2450,8 +2577,18 @@ fill_slice (GstVaapiDecoderH265 * decoder,
GstVaapiPictureH265 * picture, GstVaapiSlice * slice,
GstVaapiParserInfoH265 * pi, GstVaapiDecoderUnit * unit)
{
VASliceParameterBufferHEVC *const slice_param = slice->param;
GstH265SliceHdr *slice_hdr = &pi->data.slice_hdr;
VASliceParameterBufferHEVC *slice_param = slice->param;
#if VA_CHECK_VERSION(1,2,0)
GstVaapiDecoderH265Private *const priv = &decoder->priv;
VASliceParameterBufferHEVCRext *slice_rext_param = NULL;
if (is_range_extension_profile (priv->profile)) {
VASliceParameterBufferHEVCExtension *param = slice->param;
slice_param = &param->base;
slice_rext_param = &param->rext;
}
#endif
/* Fill in VASliceParameterBufferH265 */
slice_param->LongSliceFlags.value = 0;
@ -2505,6 +2642,12 @@ fill_slice (GstVaapiDecoderH265 * decoder,
slice_param->five_minus_max_num_merge_cand =
slice_hdr->five_minus_max_num_merge_cand;
#if VA_CHECK_VERSION(1,2,0)
if (slice_rext_param)
slice_rext_param->slice_ext_flags.bits.cu_chroma_qp_offset_enabled_flag =
slice_hdr->cu_chroma_qp_offset_enabled_flag;
#endif
if (!fill_RefPicList (decoder, picture, slice, slice_hdr))
return FALSE;
@ -2521,7 +2664,7 @@ decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
GstVaapiParserInfoH265 *const pi = unit->parsed_info;
GstVaapiPictureH265 *const picture = priv->current_picture;
GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
GstVaapiSlice *slice;
GstVaapiSlice *slice = NULL;
GstBuffer *const buffer =
GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer;
GstMapInfo map_info;
@ -2554,9 +2697,15 @@ decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END)
GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END);
slice = GST_VAAPI_SLICE_NEW (HEVC, decoder,
(map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size);
if (is_range_extension_profile (priv->profile)) {
#if VA_CHECK_VERSION(1,2,0)
slice = GST_VAAPI_SLICE_NEW (HEVCExtension, decoder,
(map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size);
#endif
} else {
slice = GST_VAAPI_SLICE_NEW (HEVC, decoder,
(map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size);
}
gst_buffer_unmap (buffer, &map_info);
if (!slice) {
GST_ERROR ("failed to allocate slice");