[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