mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-31 03:29:50 +00:00
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:
parent
be496a66c5
commit
47d256b24c
1 changed files with 165 additions and 16 deletions
|
@ -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 = ¶m->base;
|
||||
pic_rext_param = ¶m->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 = ¶m->base;
|
||||
slice_rext_param = ¶m->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 = ¶m->base;
|
||||
slice_rext_param = ¶m->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");
|
||||
|
|
Loading…
Reference in a new issue