[client] nal: added final SLICE parser features

This commit is contained in:
Geoffrey McRae 2018-01-05 23:09:43 +11:00
parent 5808089fce
commit 80c9e24604
2 changed files with 254 additions and 34 deletions

View file

@ -53,6 +53,10 @@ struct NAL
bool slice_valid; bool slice_valid;
NAL_SLICE slice; NAL_SLICE slice;
NAL_PW_TABLE_L * slice_pred_weight_table_l0;
uint32_t slice_pred_weight_table_l0_size;
NAL_PW_TABLE_L * slice_pred_weight_table_l1;
uint32_t slice_pred_weight_table_l1_size;
}; };
bool nal_initialize(NAL * ptr) bool nal_initialize(NAL * ptr)
@ -64,6 +68,12 @@ bool nal_initialize(NAL * ptr)
void nal_deinitialize(NAL this) void nal_deinitialize(NAL this)
{ {
if (this->slice_pred_weight_table_l1)
free(this->slice_pred_weight_table_l1);
if (this->slice_pred_weight_table_l0)
free(this->slice_pred_weight_table_l0);
if (this->pps_slice_group_id) if (this->pps_slice_group_id)
free(this->pps_slice_group_id); free(this->pps_slice_group_id);
@ -499,6 +509,20 @@ static bool parse_nal_pps(NAL this, const uint8_t * src, size_t size, size_t * c
pps->constrained_intra_pred_flag = get_bit(src, offset); pps->constrained_intra_pred_flag = get_bit(src, offset);
pps->redundant_pic_cnt_present_flag = get_bit(src, offset); pps->redundant_pic_cnt_present_flag = get_bit(src, offset);
if (pps->num_ref_idx_l0_active_minus1 + 1 > this->slice_pred_weight_table_l0_size)
{
this->slice_pred_weight_table_l0_size = pps->num_ref_idx_l0_active_minus1 + 1;
this->slice_pred_weight_table_l0 = realloc(this->slice_pred_weight_table_l0,
this->slice_pred_weight_table_l0_size * sizeof(NAL_PW_TABLE_L));
}
if (pps->num_ref_idx_l1_active_minus1 + 1 > this->slice_pred_weight_table_l1_size)
{
this->slice_pred_weight_table_l1_size = pps->num_ref_idx_l1_active_minus1 + 1;
this->slice_pred_weight_table_l1 = realloc(this->slice_pred_weight_table_l1,
this->slice_pred_weight_table_l1_size * sizeof(NAL_PW_TABLE_L));
}
const bool extraData = get_bit(src, offset) == 0; const bool extraData = get_bit(src, offset) == 0;
--*offset; --*offset;
@ -508,6 +532,7 @@ static bool parse_nal_pps(NAL this, const uint8_t * src, size_t size, size_t * c
pps->pic_scaling_matrix_present_flag = get_bit(src, offset); pps->pic_scaling_matrix_present_flag = get_bit(src, offset);
if (pps->pic_scaling_matrix_present_flag) if (pps->pic_scaling_matrix_present_flag)
{ {
//TODO
} }
pps->second_chroma_qp_index_offset = decode_s_golomb(src, offset); pps->second_chroma_qp_index_offset = decode_s_golomb(src, offset);
} }
@ -570,20 +595,164 @@ static bool parse_nal_pps(NAL this, const uint8_t * src, size_t size, size_t * c
static bool parse_nal_ref_pic_list_reordering(NAL this, const uint8_t * src, size_t size, size_t * const offset) static bool parse_nal_ref_pic_list_reordering(NAL this, const uint8_t * src, size_t size, size_t * const offset)
{ {
//TODO NAL_SLICE * slice = &this->slice;
NAL_RPL_REORDER * rpl = &this->slice.ref_pic_list_reordering;
if (slice->slice_type != NAL_SLICE_TYPE_I && slice->slice_type != NAL_SLICE_TYPE_SI)
{
rpl->ref_pic_list_reordering_flag_l0 = get_bit(src, offset);
if(rpl->ref_pic_list_reordering_flag_l0)
{
int index = 0;
NAL_RPL_REORDER_L * l;
do
{
if (index > 2)
{
DEBUG_ERROR("too many reorder records");
return false; return false;
} }
l = &rpl->l0[index++];
l->valid = true;
l->reordering_of_pic_nums_idc = decode_u_golomb(src, offset);
if (l->reordering_of_pic_nums_idc == 0 || l->reordering_of_pic_nums_idc == 1)
l->abs_diff_pic_num_minus1 = decode_u_golomb(src, offset);
else
if (l->reordering_of_pic_nums_idc == 2)
l->long_term_pic_num = decode_u_golomb(src, offset);
}
while(l->reordering_of_pic_nums_idc != 3);
}
}
if (slice->slice_type == NAL_SLICE_TYPE_B)
{
rpl->ref_pic_list_reordering_flag_l1 = get_bit(src, offset);
if (rpl->ref_pic_list_reordering_flag_l1)
{
int index = 0;
NAL_RPL_REORDER_L * l;
do
{
if (index > 2)
{
DEBUG_ERROR("too many reorder records");
return false;
}
l = &rpl->l1[index++];
l->valid = true;
l->reordering_of_pic_nums_idc = decode_u_golomb(src, offset);
if (l->reordering_of_pic_nums_idc == 0 || l->reordering_of_pic_nums_idc == 1)
l->abs_diff_pic_num_minus1 = decode_u_golomb(src, offset);
else
if (l->reordering_of_pic_nums_idc == 2)
l->long_term_pic_num = decode_u_golomb(src, offset);
}
while(l->reordering_of_pic_nums_idc != 3);
}
}
return true;
}
static bool parse_pred_weight_table(NAL this, const uint8_t * src, size_t size, size_t * const offset) static bool parse_pred_weight_table(NAL this, const uint8_t * src, size_t size, size_t * const offset)
{ {
//TODO NAL_SLICE * slice = &this->slice;
return false; NAL_PW_TABLE * tbl = &this->slice.pred_weight_table;
tbl->luma_log2_weight_denom = decode_u_golomb(src, offset);
tbl->chroma_log2_weight_denom = decode_u_golomb(src, offset);
tbl->l0 = this->slice_pred_weight_table_l0;
tbl->l1 = this->slice_pred_weight_table_l1;
for(uint32_t i = 0; i <= this->pps.num_ref_idx_l0_active_minus1; ++i)
{
NAL_PW_TABLE_L * l = &tbl->l0[i];
l->luma_weight_flag = get_bit(src, offset);
if (l->luma_weight_flag)
{
l->luma_weight = decode_s_golomb(src, offset);
l->luma_offset = decode_s_golomb(src, offset);
} }
static bool parse_dec_ref_pic_marking(NAL this, const uint8_t * src, size_t size, size_t * const offset) l->chroma_weight_flag = get_bit(src, offset);
if (l->chroma_weight_flag)
for(int j = 0; j < 2; ++j)
{ {
//TODO l->chroma_weight[j] = decode_s_golomb(src, offset);
return false; l->chroma_offset[j] = decode_s_golomb(src, offset);
}
}
if (slice->slice_type == NAL_SLICE_TYPE_B)
{
for(uint32_t i = 0; i <= this->pps.num_ref_idx_l1_active_minus1; ++i)
{
NAL_PW_TABLE_L * l = &tbl->l1[i];
l->luma_weight_flag = get_bit(src, offset);
if (l->luma_weight_flag)
{
l->luma_weight = decode_s_golomb(src, offset);
l->luma_offset = decode_s_golomb(src, offset);
}
l->chroma_weight_flag = get_bit(src, offset);
if (l->chroma_weight_flag)
for(int j = 0; j < 2; ++j)
{
l->chroma_weight[j] = decode_s_golomb(src, offset);
l->chroma_offset[j] = decode_s_golomb(src, offset);
}
}
}
return true;
}
static bool parse_dec_ref_pic_marking(
NAL this,
const uint8_t ref_unit_type,
const uint8_t * src,
size_t size,
size_t * const offset
)
{
NAL_RP_MARKING * m = &this->slice.dec_ref_pic_marking;
if (ref_unit_type == 5)
{
m->no_output_of_prior_pics_flag = get_bit(src, offset);
m->long_term_reference_flag = get_bit(src, offset);
}
else
{
m->adaptive_ref_pic_marking_mode_flag = get_bit(src, offset);
if (m->adaptive_ref_pic_marking_mode_flag)
{
uint32_t op;
do
{
op = decode_u_golomb(src, offset);
if (op == 1 || op == 3)
m->difference_of_pic_nums_minus1 = decode_u_golomb(src, offset);
if (op == 2)
m->long_term_pic_num = decode_u_golomb(src, offset);
if (op == 3 || op == 6)
m->long_term_frame_idx = decode_u_golomb(src, offset);
if (op == 4)
m->max_long_term_frame_idx_plus1 = decode_u_golomb(src, offset);
} while (op != 0);
}
}
return true;
} }
static bool parse_nal_coded_slice( static bool parse_nal_coded_slice(
@ -660,7 +829,7 @@ static bool parse_nal_coded_slice(
} }
if (ref_idc != 0) if (ref_idc != 0)
if (!parse_dec_ref_pic_marking(this, src, size, offset)) if (!parse_dec_ref_pic_marking(this, ref_unit_type, src, size, offset))
return false; return false;
if (this->pps.entropy_coding_mode_flag && slice->slice_type != NAL_SLICE_TYPE_I && slice->slice_type != NAL_SLICE_TYPE_SI) if (this->pps.entropy_coding_mode_flag && slice->slice_type != NAL_SLICE_TYPE_I && slice->slice_type != NAL_SLICE_TYPE_SI)

View file

@ -210,6 +210,57 @@ typedef struct NAL_PPS
} }
NAL_PPS; NAL_PPS;
typedef struct NAL_RPL_REORDER_L
{
bool valid;
uint32_t reordering_of_pic_nums_idc;
uint32_t abs_diff_pic_num_minus1;
uint32_t long_term_pic_num;
}
NAL_RPL_REORDER_L;
typedef struct NAL_RPL_REORDER
{
uint8_t ref_pic_list_reordering_flag_l0;
NAL_RPL_REORDER_L l0[3];
uint8_t ref_pic_list_reordering_flag_l1;
NAL_RPL_REORDER_L l1[3];
}
NAL_RPL_REORDER;
typedef struct NAL_PW_TABLE_L
{
uint8_t luma_weight_flag;
int32_t luma_weight;
int32_t luma_offset;
uint8_t chroma_weight_flag;
int32_t chroma_weight[2];
int32_t chroma_offset[2];
}
NAL_PW_TABLE_L;
typedef struct NAL_PW_TABLE
{
uint32_t luma_log2_weight_denom;
uint32_t chroma_log2_weight_denom;
NAL_PW_TABLE_L * l0;
NAL_PW_TABLE_L * l1;
}
NAL_PW_TABLE;
typedef struct NAL_RP_MARKING
{
uint8_t no_output_of_prior_pics_flag;
uint8_t long_term_reference_flag;
uint8_t adaptive_ref_pic_marking_mode_flag;
uint32_t memory_management_control_operation;
uint32_t difference_of_pic_nums_minus1;
uint32_t long_term_pic_num;
uint32_t long_term_frame_idx;
uint32_t max_long_term_frame_idx_plus1;
}
NAL_RP_MARKING;
typedef struct NAL_SLICE typedef struct NAL_SLICE
{ {
uint32_t first_mb_in_slice; uint32_t first_mb_in_slice;
@ -227,9 +278,9 @@ typedef struct NAL_SLICE
uint8_t num_ref_idx_active_override_flag; uint8_t num_ref_idx_active_override_flag;
uint32_t num_ref_idx_l0_active_minus1; uint32_t num_ref_idx_l0_active_minus1;
uint32_t num_ref_idx_l1_active_minus1; uint32_t num_ref_idx_l1_active_minus1;
//ref_pic_list_reordering NAL_RPL_REORDER ref_pic_list_reordering;
//pred_weight_table NAL_PW_TABLE pred_weight_table;
//dec_ref_pic_marking NAL_RP_MARKING dec_ref_pic_marking;
uint32_t cabac_init_idc; uint32_t cabac_init_idc;
int32_t slice_qp_delta; int32_t slice_qp_delta;
uint8_t sp_for_switch_flag; uint8_t sp_for_switch_flag;