From 4a1c4099297651a28a261ea6471fdb3fd80bb2f4 Mon Sep 17 00:00:00 2001 From: Haibo Chen <495810242@qq.com> Date: Tue, 4 Mar 2025 15:59:56 +0800 Subject: [PATCH] prevent memory leaks --- trunk/src/app/srs_app_rtc_source.cpp | 64 ++++++++++++++++++--------- trunk/src/kernel/srs_kernel_codec.hpp | 5 +++ 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index 62dd000d7..8336fbc86 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -1053,6 +1053,13 @@ srs_error_t SrsRtcRtpBuilder::package_opus(SrsAudioFrame* audio, SrsRtpPacket* p return err; } +void cleanup_packets(vector& packets) { + for (size_t i = 0; i < packets.size(); i++) { + srs_freep(packets[i]); + } + packets.clear(); +} + srs_error_t SrsRtcRtpBuilder::on_video(SrsSharedPtrMessage* msg) { srs_error_t err = srs_success; @@ -1111,6 +1118,7 @@ srs_error_t SrsRtcRtpBuilder::on_video(SrsSharedPtrMessage* msg) vector pkts; if (merge_nalus && nn_samples > 1) { if ((err = package_nalus(msg, samples, pkts)) != srs_success) { + cleanup_packets(pkts); return srs_error_wrap(err, "package nalus as one"); } } else { @@ -1120,10 +1128,12 @@ srs_error_t SrsRtcRtpBuilder::on_video(SrsSharedPtrMessage* msg) if (sample->size <= kRtpMaxPayloadSize) { if ((err = package_single_nalu(msg, sample, pkts)) != srs_success) { + cleanup_packets(pkts); return srs_error_wrap(err, "package single nalu"); } } else { if ((err = package_fu_a(msg, sample, kRtpMaxPayloadSize, pkts)) != srs_success) { + cleanup_packets(pkts); return srs_error_wrap(err, "package fu-a"); } } @@ -1255,8 +1265,14 @@ srs_error_t SrsRtcRtpBuilder::package_nalus(SrsSharedPtrMessage* msg, const vect { srs_error_t err = srs_success; + SrsFormat* format = meta->vsh_format(); + if (!format || !format->vcodec) { + return err; + } + bool is_hevc = format->vcodec->id == SrsVideoCodecIdHEVC; + SrsRtpRawNALUs* raw_raw = new SrsRtpRawNALUs(); - SrsAvcNaluType first_nalu_type = SrsAvcNaluTypeReserved; + uint8_t first_nalu_type = 0; for (int i = 0; i < (int)samples.size(); i++) { SrsSample* sample = samples[i]; @@ -1265,8 +1281,8 @@ srs_error_t SrsRtcRtpBuilder::package_nalus(SrsSharedPtrMessage* msg, const vect continue; } - if (first_nalu_type == SrsAvcNaluTypeReserved) { - first_nalu_type = SrsAvcNaluTypeParse(sample->bytes[0]); + if (first_nalu_type == 0) { + first_nalu_type = is_hevc ? SrsHevcNaluTypeParse(sample->bytes[0]) : SrsAvcNaluTypeParse(sample->bytes[0]); } raw_raw->push_back(sample->copy()); @@ -1293,20 +1309,12 @@ srs_error_t SrsRtcRtpBuilder::package_nalus(SrsSharedPtrMessage* msg, const vect pkt->set_payload(raw_raw, SrsRtspPacketPayloadTypeNALU); pkt->wrap(msg); } else { - SrsFormat* format = meta->vsh_format(); - if (!format || !format->vcodec) { - return err; - } - - bool is_hevc = format->vcodec->id == SrsVideoCodecIdHEVC; - // H264 FU-A header size is 1 @see: https://datatracker.ietf.org/doc/html/rfc6184#section-5.8 - // H265 FU-A header size is 2 @see: https://datatracker.ietf.org/doc/html/rfc7798#section-4.4.3 - int header_size = is_hevc ? 2 : 1; - // We must free it, should never use RTP packets to free it, // because more than one RTP packet will refer to it. SrsUniquePtr raw(raw_raw); + int header_size = is_hevc ? SrsHevcNaluHeaderSize : SrsAvcNaluHeaderSize; + // Package NALUs in FU-A RTP packets. int fu_payload_size = kRtpMaxPayloadSize; @@ -1397,9 +1405,9 @@ srs_error_t SrsRtcRtpBuilder::package_fu_a(SrsSharedPtrMessage* msg, SrsSample* } bool is_hevc = format->vcodec->id == SrsVideoCodecIdHEVC; - // H264 FU-A header size is 1 @see: https://datatracker.ietf.org/doc/html/rfc6184#section-5.8 - // H265 FU-A header size is 2 @see: https://datatracker.ietf.org/doc/html/rfc7798#section-4.4.3 - int header_size = is_hevc ? 2 : 1; + int header_size = is_hevc ? SrsHevcNaluHeaderSize : SrsAvcNaluHeaderSize; + srs_assert(sample->size >= header_size); + char* p = sample->bytes + header_size; int nb_left = sample->size - header_size; uint8_t header = sample->bytes[0]; @@ -2128,14 +2136,20 @@ SrsMediaPayloadType SrsVideoPayload::generate_media_payload_type() media_payload_type.rtcp_fb_ = rtcp_fbs_; std::ostringstream format_specific_param; + bool has_param = false; + if (!h264_param_.level_asymmerty_allow.empty()) { format_specific_param << "level-asymmetry-allowed=" << h264_param_.level_asymmerty_allow; + has_param = true; } if (!h264_param_.packetization_mode.empty()) { - format_specific_param << ";packetization-mode=" << h264_param_.packetization_mode; + if (has_param) format_specific_param << ";"; + format_specific_param << "packetization-mode=" << h264_param_.packetization_mode; + has_param = true; } if (!h264_param_.profile_level_id.empty()) { - format_specific_param << ";profile-level-id=" << h264_param_.profile_level_id; + if (has_param) format_specific_param << ";"; + format_specific_param << "profile-level-id=" << h264_param_.profile_level_id; } media_payload_type.format_specific_param_ = format_specific_param.str(); @@ -2152,17 +2166,25 @@ SrsMediaPayloadType SrsVideoPayload::generate_media_payload_type_h265() media_payload_type.rtcp_fb_ = rtcp_fbs_; std::ostringstream format_specific_param; + bool has_param = false; + if (!h265_param_.level_id.empty()) { format_specific_param << "level-id=" << h265_param_.level_id; + has_param = true; } if (!h265_param_.profile_id.empty()) { - format_specific_param << ";profile-id=" << h265_param_.profile_id; + if (has_param) format_specific_param << ";"; + format_specific_param << "profile-id=" << h265_param_.profile_id; + has_param = true; } if (!h265_param_.tier_flag.empty()) { - format_specific_param << ";tier-flag=" << h265_param_.tier_flag; + if (has_param) format_specific_param << ";"; + format_specific_param << "tier-flag=" << h265_param_.tier_flag; + has_param = true; } if (!h265_param_.tx_mode.empty()) { - format_specific_param << ";tx-mode=" << h265_param_.tx_mode; + if (has_param) format_specific_param << ";"; + format_specific_param << "tx-mode=" << h265_param_.tx_mode; } media_payload_type.format_specific_param_ = format_specific_param.str(); diff --git a/trunk/src/kernel/srs_kernel_codec.hpp b/trunk/src/kernel/srs_kernel_codec.hpp index e1e19fa1c..1d498ce71 100644 --- a/trunk/src/kernel/srs_kernel_codec.hpp +++ b/trunk/src/kernel/srs_kernel_codec.hpp @@ -16,6 +16,11 @@ class SrsBuffer; class SrsBitBuffer; class SrsFormat; +// @see: https://datatracker.ietf.org/doc/html/rfc6184#section-1.3 +const int SrsAvcNaluHeaderSize = 1; +// @see: https://datatracker.ietf.org/doc/html/rfc7798#section-1.1.4 +const int SrsHevcNaluHeaderSize = 2; + /** * The video codec id. * @doc video_file_format_spec_v10_1.pdf, page78, E.4.3.1 VIDEODATA