[Mesa-dev] [PATCH 2/7] st/omx/dec/h265: add sequence parameter sets

Leo Liu leo.liu at amd.com
Wed Aug 31 13:51:24 UTC 2016


Specified by subclause 7.3.2.2

Signed-off-by: Leo Liu <leo.liu at amd.com>
---
 src/gallium/state_trackers/omx/vid_dec.h      |   2 +
 src/gallium/state_trackers/omx/vid_dec_h265.c | 295 ++++++++++++++++++++++++++
 2 files changed, 297 insertions(+)

diff --git a/src/gallium/state_trackers/omx/vid_dec.h b/src/gallium/state_trackers/omx/vid_dec.h
index 4568e6d..20b5958 100644
--- a/src/gallium/state_trackers/omx/vid_dec.h
+++ b/src/gallium/state_trackers/omx/vid_dec.h
@@ -95,7 +95,9 @@ DERIVEDCLASS(vid_dec_PrivateType, omx_base_filter_PrivateType)
          unsigned dpb_num; \
       } h264; \
       struct { \
+         unsigned temporal_id; \
          unsigned level_idc; \
+         void *ref_pic_set_list; \
          struct pipe_h265_sps sps[16]; \
          struct pipe_h265_pps pps[64]; \
          struct list_head dpb_list; \
diff --git a/src/gallium/state_trackers/omx/vid_dec_h265.c b/src/gallium/state_trackers/omx/vid_dec_h265.c
index 49936b0..293bdd2 100644
--- a/src/gallium/state_trackers/omx/vid_dec_h265.c
+++ b/src/gallium/state_trackers/omx/vid_dec_h265.c
@@ -34,6 +34,28 @@
 #include "vid_dec.h"
 
 #define DPB_MAX_SIZE 16
+#define MAX_NUM_REF_PICS 16
+
+enum {
+   NAL_UNIT_TYPE_TRAIL_N = 0,
+   NAL_UNIT_TYPE_TRAIL_R = 1,
+   NAL_UNIT_TYPE_TSA_N = 2,
+   NAL_UNIT_TYPE_TSA_R = 3,
+   NAL_UNIT_TYPE_STSA_N = 4,
+   NAL_UNIT_TYPE_STSA_R = 5,
+   NAL_UNIT_TYPE_RADL_N = 6,
+   NAL_UNIT_TYPE_RADL_R = 7,
+   NAL_UNIT_TYPE_RASL_N = 8,
+   NAL_UNIT_TYPE_RASL_R = 9,
+   NAL_UNIT_TYPE_BLA_W_LP = 16,
+   NAL_UNIT_TYPE_BLA_W_RADL = 17,
+   NAL_UNIT_TYPE_BLA_N_LP =  18,
+   NAL_UNIT_TYPE_IDR_W_RADL = 19,
+   NAL_UNIT_TYPE_IDR_N_LP = 20,
+   NAL_UNIT_TYPE_CRA = 21,
+   NAL_UNIT_TYPE_SPS = 33,
+   NAL_UNIT_TYPE_PPS = 34,
+};
 
 struct dpb_list {
    struct list_head list;
@@ -41,6 +63,230 @@ struct dpb_list {
    unsigned poc;
 };
 
+struct ref_pic_set {
+  unsigned  num_pics;
+  unsigned  num_neg_pics;
+  unsigned  num_pos_pics;
+  unsigned  num_delta_poc;
+  int  delta_poc[MAX_NUM_REF_PICS];
+  bool used[MAX_NUM_REF_PICS];
+};
+
+/* random access point picture */
+static bool is_rap_picture(unsigned nal_unit_type)
+{
+   return (nal_unit_type >= NAL_UNIT_TYPE_BLA_W_LP &&
+           nal_unit_type <= NAL_UNIT_TYPE_CRA);
+}
+
+static bool is_slice_picture(unsigned nal_unit_type)
+{
+   return (nal_unit_type <= NAL_UNIT_TYPE_RASL_R ||
+           is_rap_picture(nal_unit_type));
+}
+
+static void profile_tier(struct vl_rbsp *rbsp)
+{
+   int i;
+
+   /* general_profile_space */
+   vl_rbsp_u(rbsp, 2);
+
+   /* general_tier_flag */
+   vl_rbsp_u(rbsp, 1);
+
+   /* general_profile_idc */
+   vl_rbsp_u(rbsp, 5);
+
+   /* general_profile_compatibility_flag */
+   for(i = 0; i < 32; ++i)
+      vl_rbsp_u(rbsp, 1);
+
+   /* general_progressive_source_flag */
+   vl_rbsp_u(rbsp, 1);
+
+   /* general_interlaced_source_flag */
+   vl_rbsp_u(rbsp, 1);
+
+   /* general_non_packed_constraint_flag */
+   vl_rbsp_u(rbsp, 1);
+
+   /* general_frame_only_constraint_flag */
+   vl_rbsp_u(rbsp, 1);
+
+   /* general_reserved_zero_44bits */
+   vl_rbsp_u(rbsp, 16);
+   vl_rbsp_u(rbsp, 16);
+   vl_rbsp_u(rbsp, 12);
+}
+
+static unsigned profile_tier_level(struct vl_rbsp *rbsp,
+                                   int max_sublayers_minus1)
+{
+   bool sub_layer_profile_present_flag[6];
+   bool sub_layer_level_present_flag[6];
+   unsigned level_idc;
+   int i;
+
+   profile_tier(rbsp);
+
+   /* general_level_idc */
+   level_idc = vl_rbsp_u(rbsp, 8);
+
+   for (i = 0; i < max_sublayers_minus1; ++i) {
+      sub_layer_profile_present_flag[i] = vl_rbsp_u(rbsp, 1);
+      sub_layer_level_present_flag[i] = vl_rbsp_u(rbsp, 1);
+   }
+
+   if (max_sublayers_minus1 > 0)
+      for (i = max_sublayers_minus1; i < 8; ++i)
+         /* reserved_zero_2bits */
+         vl_rbsp_u(rbsp, 2);
+
+   for (i = 0; i < max_sublayers_minus1; ++i) {
+      if (sub_layer_profile_present_flag[i])
+         profile_tier(rbsp);
+
+      if (sub_layer_level_present_flag[i])
+         /* sub_layer_level_idc */
+         vl_rbsp_u(rbsp, 8);
+   }
+
+   return level_idc;
+}
+
+static void scaling_list_data(void)
+{
+   /* TODO */
+   assert(0);
+}
+
+static void st_ref_pic_set(void)
+{
+   /* TODO */
+}
+
+static struct pipe_h265_sps *seq_parameter_set_id(vid_dec_PrivateType *priv,
+                                                  struct vl_rbsp *rbsp)
+{
+   unsigned id = vl_rbsp_ue(rbsp);
+
+   if (id >= ARRAY_SIZE(priv->codec_data.h265.sps))
+      return NULL;
+
+   return &priv->codec_data.h265.sps[id];
+}
+
+static void seq_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp)
+{
+   struct pipe_h265_sps *sps;
+   int sps_max_sub_layers_minus1;
+   unsigned i;
+
+   /* sps_video_parameter_set_id */
+   vl_rbsp_u(rbsp, 4);
+
+   /* sps_max_sub_layers_minus1 */
+   sps_max_sub_layers_minus1 = vl_rbsp_u(rbsp, 3);
+
+   assert(sps_max_sub_layers_minus1 <= 6);
+
+   /* sps_temporal_id_nesting_flag */
+   vl_rbsp_u(rbsp, 1);
+
+   priv->codec_data.h265.level_idc =
+      profile_tier_level(rbsp, sps_max_sub_layers_minus1);
+
+   sps = seq_parameter_set_id(priv, rbsp);
+   if (!sps)
+      return;
+
+   memset(sps, 0, sizeof(*sps));
+
+   sps->chroma_format_idc = vl_rbsp_ue(rbsp);
+
+   if (sps->chroma_format_idc == 3)
+      sps->separate_colour_plane_flag = vl_rbsp_u(rbsp, 1);
+
+   sps->pic_width_in_luma_samples = vl_rbsp_ue(rbsp);
+
+   sps->pic_height_in_luma_samples = vl_rbsp_ue(rbsp);
+
+   /* conformance_window_flag */
+   if (vl_rbsp_u(rbsp, 1)) {
+      /* conf_win_left_offset */
+      vl_rbsp_ue(rbsp);
+      /* conf_win_right_offset */
+      vl_rbsp_ue(rbsp);
+      /* conf_win_top_offset */
+      vl_rbsp_ue(rbsp);
+      /* conf_win_bottom_offset */
+      vl_rbsp_ue(rbsp);
+   }
+
+   sps->bit_depth_luma_minus8 = vl_rbsp_ue(rbsp);
+   sps->bit_depth_chroma_minus8 = vl_rbsp_ue(rbsp);
+   sps->log2_max_pic_order_cnt_lsb_minus4 = vl_rbsp_ue(rbsp);
+
+   /* sps_sub_layer_ordering_info_present_flag */
+   i  = vl_rbsp_u(rbsp, 1) ? 0 : sps_max_sub_layers_minus1;
+   for (; i <= sps_max_sub_layers_minus1; ++i) {
+      sps->sps_max_dec_pic_buffering_minus1 = vl_rbsp_ue(rbsp);
+      /* sps_max_num_reorder_pics */
+      vl_rbsp_ue(rbsp);
+      /* sps_max_latency_increase_plus */
+      vl_rbsp_ue(rbsp);
+   }
+
+   sps->log2_min_luma_coding_block_size_minus3 = vl_rbsp_ue(rbsp);
+   sps->log2_diff_max_min_luma_coding_block_size = vl_rbsp_ue(rbsp);
+   sps->log2_min_transform_block_size_minus2 = vl_rbsp_ue(rbsp);
+   sps->log2_diff_max_min_transform_block_size = vl_rbsp_ue(rbsp);
+   sps->max_transform_hierarchy_depth_inter = vl_rbsp_ue(rbsp);
+   sps->max_transform_hierarchy_depth_intra = vl_rbsp_ue(rbsp);
+
+   sps->scaling_list_enabled_flag = vl_rbsp_u(rbsp, 1);
+   if (sps->scaling_list_enabled_flag)
+      /* sps_scaling_list_data_present_flag */
+      if (vl_rbsp_u(rbsp, 1))
+         scaling_list_data();
+
+   sps->amp_enabled_flag = vl_rbsp_u(rbsp, 1);
+   sps->sample_adaptive_offset_enabled_flag = vl_rbsp_u(rbsp, 1);
+   sps->pcm_enabled_flag = vl_rbsp_u(rbsp, 1);
+   if (sps->pcm_enabled_flag) {
+      sps->pcm_sample_bit_depth_luma_minus1 = vl_rbsp_u(rbsp, 4);
+      sps->pcm_sample_bit_depth_chroma_minus1 = vl_rbsp_u(rbsp, 4);
+      sps->log2_min_pcm_luma_coding_block_size_minus3 = vl_rbsp_ue(rbsp);
+      sps->log2_diff_max_min_pcm_luma_coding_block_size = vl_rbsp_ue(rbsp);
+      sps->pcm_loop_filter_disabled_flag = vl_rbsp_u(rbsp, 1);
+   }
+
+   sps->num_short_term_ref_pic_sets = vl_rbsp_ue(rbsp);
+
+   for (i = 0; i < sps->num_short_term_ref_pic_sets; ++i) {
+      struct ref_pic_set *rps;
+
+      rps = (struct ref_pic_set *)
+         priv->codec_data.h265.ref_pic_set_list + i;
+      st_ref_pic_set();
+   }
+
+   sps->long_term_ref_pics_present_flag = vl_rbsp_u(rbsp, 1);
+   if (sps->long_term_ref_pics_present_flag) {
+      sps->num_long_term_ref_pics_sps = vl_rbsp_ue(rbsp);
+      for (i = 0; i < sps->num_long_term_ref_pics_sps; ++i) {
+         /* lt_ref_pic_poc_lsb_sps */
+         vl_rbsp_u(rbsp, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
+         /* used_by_curr_pic_lt_sps_flag */
+         vl_rbsp_u(rbsp, 1);
+      }
+   }
+
+   sps->sps_temporal_mvp_enabled_flag = vl_rbsp_u(rbsp, 1);
+   sps->strong_intra_smoothing_enabled_flag = vl_rbsp_u(rbsp, 1);
+}
+
 static void vid_dec_h265_BeginFrame(vid_dec_PrivateType *priv)
 {
    if (priv->frame_started)
@@ -130,6 +376,55 @@ static void vid_dec_h265_Decode(vid_dec_PrivateType *priv,
                                 struct vl_vlc *vlc,
                                 unsigned min_bits_left)
 {
+   unsigned nal_unit_type;
+   unsigned nuh_layer_id;
+   unsigned nuh_temporal_id_plus1;
+
+   if (!vl_vlc_search_byte(vlc, vl_vlc_bits_left(vlc) - min_bits_left, 0x00))
+      return;
+
+   if (vl_vlc_peekbits(vlc, 24) != 0x000001) {
+      vl_vlc_eatbits(vlc, 8);
+      return;
+   }
+
+   if (priv->slice) {
+      unsigned bytes = priv->bytes_left - (vl_vlc_bits_left(vlc) / 8);
+
+      priv->codec->decode_bitstream(priv->codec, priv->target,
+                                    &priv->picture.base, 1,
+                                    &priv->slice, &bytes);
+      priv->slice = NULL;
+   }
+
+   vl_vlc_eatbits(vlc, 24);
+
+   /* forbidden_zero_bit */
+   vl_vlc_eatbits(vlc, 1);
+
+   if (vl_vlc_valid_bits(vlc) < 15)
+      vl_vlc_fillbits(vlc);
+
+   nal_unit_type = vl_vlc_get_uimsbf(vlc, 6);
+
+   /* nuh_layer_id */
+   nuh_layer_id = vl_vlc_get_uimsbf(vlc, 6);
+
+   /* nuh_temporal_id_plus1 */
+   nuh_temporal_id_plus1 = vl_vlc_get_uimsbf(vlc, 3);
+   priv->codec_data.h265.temporal_id = nuh_temporal_id_plus1 - 1;
+
+   if (!is_slice_picture(nal_unit_type))
+      vid_dec_h265_EndFrame(priv);
+
+   if (nal_unit_type == NAL_UNIT_TYPE_SPS) {
+      struct vl_rbsp rbsp;
+
+      vl_rbsp_init(&rbsp, vlc, ~0);
+      seq_parameter_set(priv, &rbsp);
+
+   }
+
    /* TODO */
 
    /* resync to byte boundary */
-- 
2.7.4



More information about the mesa-dev mailing list