libs: h265: dec: Add extension flags setting.
authorWangfei <fei.w.wang@intel.com>
Mon, 29 Apr 2019 01:52:39 +0000 (09:52 +0800)
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Thu, 9 May 2019 06:27:42 +0000 (06:27 +0000)
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).

gst-libs/gst/vaapi/gstvaapidecoder_h265.c

index 61f508a..6cd61f6 100644 (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");