From c809eeb2a84bf38969fdb3e07bc692a92e220668 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Fri, 5 Jan 2018 15:27:36 +1100 Subject: [PATCH] [client] fixed nal parser memory leaks --- client/decoders/h264.c | 1 + client/parsers/nal.c | 88 ++++++++++++++++++++++++++++-------------- client/parsers/nal.h | 39 ++++++++++++++++++- 3 files changed, 97 insertions(+), 31 deletions(-) diff --git a/client/decoders/h264.c b/client/decoders/h264.c index 6edbcdd9..a5435b42 100644 --- a/client/decoders/h264.c +++ b/client/decoders/h264.c @@ -159,6 +159,7 @@ static bool lgd_h264_create(void ** opaque) static void lgd_h264_destroy(void * opaque) { struct Inst * this = (struct Inst *)opaque; + nal_deinitialize(this->nal); lgd_h264_deinitialize(this); free(this); } diff --git a/client/parsers/nal.c b/client/parsers/nal.c index cb968848..644df1a5 100644 --- a/client/parsers/nal.c +++ b/client/parsers/nal.c @@ -37,7 +37,15 @@ struct NAL int32_t * sps_offset_for_ref_frame; uint32_t sps_num_ref_frames_in_pic_order_cnt_cycle; + bool vui_valid; NAL_VUI vui; + NAL_CPB * vui_nal_hrd_parameters_cpb; + uint32_t vui_nal_hrd_parameters_cpb_size; + NAL_CPB * vui_vcl_hrd_parameters_cpb; + uint32_t vui_vcl_hrd_parameters_cpb_size; + + bool pps_valid; + NAL_PPS pps; }; bool nal_initialize(NAL * ptr) @@ -50,38 +58,36 @@ bool nal_initialize(NAL * ptr) void nal_deinitialize(NAL this) { if (this->sps_offset_for_ref_frame) - { free(this->sps_offset_for_ref_frame); - this->sps_offset_for_ref_frame = NULL; - } - if (this->vui.nal_hrd_parameters.cpb) - { - free(this->vui.nal_hrd_parameters.cpb); - this->vui.nal_hrd_parameters.cpb = NULL; - } + if (this->vui_nal_hrd_parameters_cpb) + free(this->vui_nal_hrd_parameters_cpb); - if (this->vui.vcl_hrd_parameters.cpb) - { - free(this->vui.vcl_hrd_parameters.cpb); - this->vui.vcl_hrd_parameters.cpb = NULL; - } + if (this->vui_vcl_hrd_parameters_cpb) + free(this->vui_vcl_hrd_parameters_cpb); free(this); } -static bool parse_nal_hrd(NAL_HRD * const hrd, const uint8_t * src, size_t size, size_t * const offset) +static bool parse_nal_hrd( + NAL_HRD * const hrd, + NAL_CPB ** cpb, + uint32_t * cpb_size, + const uint8_t * src, + size_t size, + size_t * const offset) { hrd->cpb_cnt_minus1 = decode_u_golomb(src, offset); hrd->bit_rate_scale = get_bits(src, offset, 4); hrd->cpb_size_scale = get_bits(src, offset, 4); - if (hrd->cpb_size_count < hrd->cpb_size_scale) + if (*cpb_size < hrd->cpb_size_scale) { - hrd->cpb = realloc(hrd->cpb, hrd->cpb_size_scale * sizeof(NAL_CPB)); - hrd->cpb_size_count = hrd->cpb_size_scale; + *cpb = realloc(*cpb, hrd->cpb_size_scale * sizeof(NAL_CPB)); + *cpb_size = hrd->cpb_size_scale; } + hrd->cpb = *cpb; for(uint32_t i = 0; i < hrd->cpb_size_scale; ++i) { hrd->cpb[i].bit_rate_value_minus1 = decode_u_golomb(src, offset); @@ -97,17 +103,10 @@ static bool parse_nal_hrd(NAL_HRD * const hrd, const uint8_t * src, size_t size, return true; } -static bool parse_nal_vui(NAL_VUI * const vui, const uint8_t * src, size_t size, size_t * const offset) +static bool parse_nal_vui(NAL this, const uint8_t * src, size_t size, size_t * const offset) { - NAL_CPB * nal_hrd_cpb = vui->nal_hrd_parameters.cpb; - uint8_t nal_hrd_count = vui->nal_hrd_parameters.cpb_size_count; - NAL_CPB * vcl_hrd_cpb = vui->vcl_hrd_parameters.cpb; - uint8_t vcl_hrd_count = vui->vcl_hrd_parameters.cpb_size_count; + NAL_VUI * vui = &this->vui; memset(vui, 0, sizeof(NAL_VUI)); - vui->nal_hrd_parameters.cpb = nal_hrd_cpb; - vui->nal_hrd_parameters.cpb_size_count = nal_hrd_count; - vui->vcl_hrd_parameters.cpb = vcl_hrd_cpb; - vui->vcl_hrd_parameters.cpb_size_count = vcl_hrd_count; vui->aspect_ratio_info_present_flag = get_bit(src, offset); if (vui->aspect_ratio_info_present_flag) @@ -155,12 +154,24 @@ static bool parse_nal_vui(NAL_VUI * const vui, const uint8_t * src, size_t size, vui->nal_hrd_parameters_present_flag = get_bit(src, offset); if (vui->nal_hrd_parameters_present_flag) - if (!parse_nal_hrd(&vui->nal_hrd_parameters, src, size, offset)) + if (!parse_nal_hrd( + &vui->nal_hrd_parameters, + &this->vui_nal_hrd_parameters_cpb, + &this->vui_nal_hrd_parameters_cpb_size, + src, + size, + offset)) return false; vui->vcl_hrd_parameters_present_flag = get_bit(src, offset); if (vui->vcl_hrd_parameters_present_flag) - if (!parse_nal_hrd(&vui->vcl_hrd_parameters, src, size, offset)) + if (!parse_nal_hrd( + &vui->vcl_hrd_parameters, + &this->vui_vcl_hrd_parameters_cpb, + &this->vui_vcl_hrd_parameters_cpb_size, + src, + size, + offset)) return false; if (vui->nal_hrd_parameters_present_flag || vui->vcl_hrd_parameters_present_flag) @@ -366,8 +377,11 @@ static bool parse_nal_sps(NAL this, const uint8_t * src, size_t size, size_t * c #endif if (this->sps.vui_parameters_present_flag) - if (!parse_nal_vui(&this->vui, src, size, offset)) + { + if (!parse_nal_vui(this, src, size, offset)) return false; + this->vui_valid = true; + } if (!parse_nal_trailing_bits(this, src, size, offset)) return false; @@ -376,6 +390,11 @@ static bool parse_nal_sps(NAL this, const uint8_t * src, size_t size, size_t * c return true; } +static bool parse_nal_pps(NAL this, const uint8_t * src, size_t size, size_t * const offset) +{ + return false; +} + bool nal_parse(NAL this, const uint8_t * src, size_t size) { static FILE * fd = NULL; @@ -422,6 +441,8 @@ bool nal_parse(NAL this, const uint8_t * src, size_t size) break; case NAL_TYPE_PPS: + if (!parse_nal_pps(this, src, size, &offset)) + return false; break; default: @@ -450,4 +471,13 @@ bool nal_get_primary_picture_type(NAL this, uint8_t * pic_type) return false; *pic_type = this->primary_pic_type; return true; +} + +bool nal_get_pps(NAL this, const NAL_PPS ** pps) +{ + if (!this->pps_valid) + return false; + + *pps = &this->pps; + return true; } \ No newline at end of file diff --git a/client/parsers/nal.h b/client/parsers/nal.h index b50c4316..5c697c49 100644 --- a/client/parsers/nal.h +++ b/client/parsers/nal.h @@ -143,11 +143,46 @@ typedef struct NAL_VUI } NAL_VUI; +typedef struct NAL_SLICE_GROUP +{ + uint32_t run_length_minus1; + uint32_t top_left; + uint32_t bottom_right; +} +NAL_SLICE_GROUP; + +typedef struct NAL_PPS +{ + uint32_t pic_parameter_set_id; + uint32_t seq_parameter_set_id; + uint8_t entropy_coding_mode_flag; + uint8_t pic_order_present_flag; + uint32_t num_slice_groups_minus1; + NAL_SLICE_GROUP * slice_groups; + uint32_t slice_group_map_type; + uint8_t slice_group_change_direction_flag; + uint32_t slice_group_change_rate_minus1; + uint32_t pic_size_in_map_units_minus1; + uint32_t * slice_group_id; + uint32_t num_ref_idx_l0_active_minus1; + uint32_t num_ref_idx_l1_active_minus1; + uint8_t weighted_pred_flag; + uint8_t weighted_bipred_idc; + int32_t pic_init_qp_minus26; + int32_t pic_init_qs_minus26; + int32_t chroma_qp_index_offset; + uint8_t deblocking_filter_control_present_flag; + uint8_t constrained_intra_pred_flag; + uint8_t redundant_pic_cnt_present_flag; +} +NAL_PPS; + typedef struct NAL * NAL; bool nal_initialize (NAL * ptr); void nal_deinitialize(NAL this ); bool nal_parse (NAL this, const uint8_t * src, size_t size); -bool nal_get_sps (NAL this, const NAL_SPS ** sps); -bool nal_get_primary_picture_type(NAL this, uint8_t * pic_type); \ No newline at end of file +bool nal_get_primary_picture_type(NAL this, uint8_t * pic_type); +bool nal_get_sps(NAL this, const NAL_SPS ** sps); +bool nal_get_pps(NAL this, const NAL_PPS ** pps); \ No newline at end of file