st/omx/dec/h265: add sequence parameter sets

Specified by subclause 7.3.2.2

Signed-off-by: Leo Liu <leo.liu@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
This commit is contained in:
Leo Liu
2016-08-29 13:26:55 -04:00
parent 6d186a79f2
commit b3c1583e17
2 changed files with 297 additions and 0 deletions
+2
View File
@@ -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; \
@@ -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 */