From 80c9e246046bf45e1caa5a0ea6ad4b365c295098 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Fri, 5 Jan 2018 23:09:43 +1100 Subject: [PATCH] [client] nal: added final SLICE parser features --- client/parsers/nal.c | 185 +++++++++++++++++++++++++++++++++++++++++-- client/parsers/nal.h | 103 ++++++++++++++++++------ 2 files changed, 254 insertions(+), 34 deletions(-) diff --git a/client/parsers/nal.c b/client/parsers/nal.c index 1dae3282..f8b38021 100644 --- a/client/parsers/nal.c +++ b/client/parsers/nal.c @@ -53,6 +53,10 @@ struct NAL bool slice_valid; 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) @@ -64,6 +68,12 @@ bool nal_initialize(NAL * ptr) 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) 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->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; --*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); if (pps->pic_scaling_matrix_present_flag) { + //TODO } 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) { - //TODO - return false; + 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; + } + + 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) { - //TODO - return false; + NAL_SLICE * slice = &this->slice; + 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); + } + + 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); + } + } + + 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 * src, size_t size, size_t * const offset) +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 +) { - //TODO - return false; + 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( @@ -660,7 +829,7 @@ static bool parse_nal_coded_slice( } 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; if (this->pps.entropy_coding_mode_flag && slice->slice_type != NAL_SLICE_TYPE_I && slice->slice_type != NAL_SLICE_TYPE_SI) diff --git a/client/parsers/nal.h b/client/parsers/nal.h index 938f5c0e..65ea0b6c 100644 --- a/client/parsers/nal.h +++ b/client/parsers/nal.h @@ -210,34 +210,85 @@ typedef struct 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 { - uint32_t first_mb_in_slice; - uint32_t slice_type; - uint32_t pic_parameter_set_id; - uint32_t frame_num; - uint8_t field_pic_flag; - uint8_t bottom_field_flag; - uint32_t idr_pic_id; - uint32_t pic_order_cnt_lsb; - int32_t delta_pic_order_cnt_bottom; - int32_t delta_pic_order_cnt[2]; - uint32_t redundant_pic_cnt; - uint8_t direct_spatial_mv_pred_flag; - uint8_t num_ref_idx_active_override_flag; - uint32_t num_ref_idx_l0_active_minus1; - uint32_t num_ref_idx_l1_active_minus1; - //ref_pic_list_reordering - //pred_weight_table - //dec_ref_pic_marking - uint32_t cabac_init_idc; - int32_t slice_qp_delta; - uint8_t sp_for_switch_flag; - int32_t slice_qs_delta; - uint32_t disable_deblocking_filter_idc; - int32_t slice_alpha_c0_offset_div2; - int32_t slice_beta_offset_div2; - uint32_t slice_group_change_cycle; + uint32_t first_mb_in_slice; + uint32_t slice_type; + uint32_t pic_parameter_set_id; + uint32_t frame_num; + uint8_t field_pic_flag; + uint8_t bottom_field_flag; + uint32_t idr_pic_id; + uint32_t pic_order_cnt_lsb; + int32_t delta_pic_order_cnt_bottom; + int32_t delta_pic_order_cnt[2]; + uint32_t redundant_pic_cnt; + uint8_t direct_spatial_mv_pred_flag; + uint8_t num_ref_idx_active_override_flag; + uint32_t num_ref_idx_l0_active_minus1; + uint32_t num_ref_idx_l1_active_minus1; + NAL_RPL_REORDER ref_pic_list_reordering; + NAL_PW_TABLE pred_weight_table; + NAL_RP_MARKING dec_ref_pic_marking; + uint32_t cabac_init_idc; + int32_t slice_qp_delta; + uint8_t sp_for_switch_flag; + int32_t slice_qs_delta; + uint32_t disable_deblocking_filter_idc; + int32_t slice_alpha_c0_offset_div2; + int32_t slice_beta_offset_div2; + uint32_t slice_group_change_cycle; } NAL_SLICE;