From 8acceb1b1bffb89b24b4014b29e9ab00c3e19261 Mon Sep 17 00:00:00 2001 From: OSSRS-AI Date: Thu, 30 Oct 2025 12:59:50 -0400 Subject: [PATCH] AI: HLS: Fix crash when segment is not open by adding NULL checks. v7.0.113 (#3431) --- .vscode/launch.json | 30 +++++++++++++++++- trunk/doc/CHANGELOG.md | 19 ++++++------ trunk/src/app/srs_app_hls.cpp | 44 ++++++++++++++++++++++++--- trunk/src/app/srs_app_hls.hpp | 2 ++ trunk/src/app/srs_app_rtc_conn.cpp | 15 +++++---- trunk/src/app/srs_app_rtmp_source.cpp | 11 ++++--- trunk/src/core/srs_core_version7.hpp | 2 +- 7 files changed, 96 insertions(+), 27 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index d462e2057..fd54a400c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,7 +2,7 @@ "version": "0.2.0", "configurations": [ { - "name": "Launch SRS", + "name": "Launch SRS with conf/console.conf", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/trunk/cmake/build/srs", @@ -29,6 +29,34 @@ "engineLogging": true } }, + { + "name": "Launch SRS with conf/rtc.conf", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/trunk/cmake/build/srs", + "args": ["-c", "conf/rtc.conf"], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/trunk", + "environment": [], + "externalConsole": false, + "linux": { + "MIMode": "gdb" + }, + "osx": { + "MIMode": "lldb" + }, + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "build", + "logging": { + "engineLogging": true + } + }, { "name": "Launch srs-proxy", "type": "go", diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 9be489f06..9a1a09f98 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,16 +7,17 @@ The changelog for SRS. ## SRS 7.0 Changelog +* v7.0, 2025-10-30, AI: HLS: Fix crash when segment is not open by adding NULL checks. v7.0.113 (#3431) * v7.0, 2025-10-29, AI: AAC: Fix mono audio reported as stereo in HTTP API. v7.0.112 (#3556) -* v7.0, 2025-10-27, HLS/DASH: Fix dispose to skip unpublish when not enabled, and add forbidden directory protection to SrsPath::unlink. v7.0.111 -* v7.0, 2025-10-27, AI: HTTP-FLV: Enforce minimum 10ms sleep to prevent CPU busy-wait when mw_latency=0. v7.0.110 (#3963) -* v7.0, 2025-10-26, AI: Edge: Fix stream names with dots being incorrectly truncated in source URL generation. v7.0.109 (#4011) -* v7.0, 2025-10-26, AI: HTTPS: Handle SSL_ERROR_ZERO_RETURN as graceful connection closure. v7.0.108 (#4036) -* v7.0, 2025-10-26, AI: API: Add clients field to on_play/on_stop webhooks and total field to HTTP API. v7.0.107 (#4147) -* v7.0, 2025-10-26, AI: WebRTC: Fix camera/microphone not released after closing publisher. v7.0.106 (#4261) -* v7.0, 2025-10-26, AI: Build: Improve dependency checking to report all missing dependencies at once. v7.0.105 (#4293) -* v7.0, 2025-10-26, AI: HLS: Support hls_master_m3u8_path_relative for reverse proxy compatibility. v7.0.104 (#4338) -* v7.0, 2025-10-25, AI: API: Remove minimum limit of 10 for count parameter in /api/v1/streams and /api/v1/clients. v7.0.103 (#4358) +* v7.0, 2025-10-27, HLS/DASH: Skip unpublish if disabled; add protection in SrsPath::unlink. v7.0.111 +* v7.0, 2025-10-27, AI: HTTP-FLV: Add 10 ms sleep to prevent busy-wait when mw_latency=0. v7.0.110 (#3963) +* v7.0, 2025-10-26, AI: Edge: Fix truncation of stream names containing dots. v7.0.109 (#4011) +* v7.0, 2025-10-26, AI: HTTPS: Treat SSL_ERROR_ZERO_RETURN as graceful close. v7.0.108 (#4036) +* v7.0, 2025-10-26, AI: API: Add clients to webhooks and total to stats API. v7.0.107 (#4147) +* v7.0, 2025-10-26, AI: WebRTC: Fix camera/mic not released after closing. v7.0.106 (#4261) +* v7.0, 2025-10-26, AI: Build: Report all missing dependencies at once. v7.0.105 (#4293) +* v7.0, 2025-10-26, AI: HLS: Support hls_master_m3u8_path_relative for reverse proxy. v7.0.104 (#4338) +* v7.0, 2025-10-25, AI: API: Remove minimum count=10 limit in stream/client queries. v7.0.103 (#4358) * v7.0, 2025-10-22, AI: Only support AAC/MP3/Opus audio codec. v7.0.102 (#4516) * v7.0, 2025-10-22, AI: Fix AAC audio sample rate reporting in API. v7.0.101 (#4518) * v7.0, 2025-10-20, Merge [#4537](https://github.com/ossrs/srs/pull/4537): Forward: Reject RTMPS destinations with clear error message. v7.0.100 (#4537) diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp index e52808b52..6fba8cb49 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -847,6 +847,11 @@ std::string SrsHlsFmp4Muxer::generate_m4s_filename() return m4s_file; } +bool SrsHlsFmp4Muxer::is_segment_open() +{ + return current_ != NULL; +} + srs_error_t SrsHlsFmp4Muxer::on_sequence_header() { return srs_success; @@ -854,7 +859,10 @@ srs_error_t SrsHlsFmp4Muxer::on_sequence_header() bool SrsHlsFmp4Muxer::is_segment_overflow() { - srs_assert(current_); + // If segment is not open, it cannot overflow. + if (!is_segment_open()) { + return false; + } // to prevent very small segment. if (current_->duration() < 2 * SRS_HLS_SEGMENT_MIN_DURATION) { @@ -876,7 +884,10 @@ bool SrsHlsFmp4Muxer::wait_keyframe() bool SrsHlsFmp4Muxer::is_segment_absolutely_overflow() { - srs_assert(current_); + // If segment is not open, it cannot overflow. + if (!is_segment_open()) { + return false; + } // to prevent very small segment. if (current_->duration() < 2 * SRS_HLS_SEGMENT_MIN_DURATION) { @@ -890,6 +901,10 @@ bool SrsHlsFmp4Muxer::is_segment_absolutely_overflow() void SrsHlsFmp4Muxer::update_duration(uint64_t dts) { + // If segment is not open, ignore the update event. + if (!is_segment_open()) { + return; + } current_->append(dts / 90); } @@ -1652,7 +1667,11 @@ srs_error_t SrsHlsMuxer::on_sequence_header() { srs_error_t err = srs_success; - srs_assert(current_); + // If segment is not open, ignore the sequence header event. + if (!is_segment_open()) { + srs_warn("sequence header ignored, for segment is not open."); + return err; + } // set the current segment to sequence header, // when close the segement, it will write a discontinuity to m3u8 file. @@ -1661,9 +1680,17 @@ srs_error_t SrsHlsMuxer::on_sequence_header() return err; } +bool SrsHlsMuxer::is_segment_open() +{ + return current_ != NULL; +} + bool SrsHlsMuxer::is_segment_overflow() { - srs_assert(current_); + // If segment is not open, it cannot overflow. + if (!is_segment_open()) { + return false; + } // to prevent very small segment. if (current_->duration() < 2 * SRS_HLS_SEGMENT_MIN_DURATION) { @@ -1685,7 +1712,10 @@ bool SrsHlsMuxer::wait_keyframe() bool SrsHlsMuxer::is_segment_absolutely_overflow() { - srs_assert(current_); + // If segment is not open, it cannot overflow. + if (!is_segment_open()) { + return false; + } // to prevent very small segment. if (current_->duration() < 2 * SRS_HLS_SEGMENT_MIN_DURATION) { @@ -1760,6 +1790,10 @@ srs_error_t SrsHlsMuxer::flush_video(SrsTsMessageCache *cache) void SrsHlsMuxer::update_duration(uint64_t dts) { + // If segment is not open, ignore the update event. + if (!is_segment_open()) { + return; + } current_->append(dts / 90); } diff --git a/trunk/src/app/srs_app_hls.hpp b/trunk/src/app/srs_app_hls.hpp index a34df591e..e5014951b 100644 --- a/trunk/src/app/srs_app_hls.hpp +++ b/trunk/src/app/srs_app_hls.hpp @@ -358,6 +358,7 @@ public: // clang-format off SRS_DECLARE_PRIVATE: // clang-format on virtual std::string generate_ts_filename(); + virtual bool is_segment_open(); public: virtual srs_error_t on_sequence_header(); @@ -541,6 +542,7 @@ public: // clang-format off SRS_DECLARE_PRIVATE: // clang-format on virtual std::string generate_m4s_filename(); + virtual bool is_segment_open(); public: virtual srs_error_t on_sequence_header(); diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index e22123313..5b6f2bad6 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1311,8 +1311,11 @@ srs_error_t SrsRtcPublishStream::initialize(ISrsRequest *r, SrsRtcSourceDescript int twcc_id = -1; uint32_t media_ssrc = 0; - // because audio_track_desc have not twcc id, for example, h5demo - // fetch twcc_id from video track description, + // TWCC is transport-wide, so audio and video share the same extension ID. + // We fetch the TWCC ID from video track, which is sufficient because: + // 1. Standard WebRTC clients use the same TWCC ID for both audio and video. + // 2. The ID is used to parse TWCC extension from all RTP packets (audio+video). + // 3. TWCC feedback will include both audio and video packets. for (int i = 0; i < (int)stream_desc->video_track_descs_.size(); ++i) { SrsRtcTrackDescription *desc = stream_desc->video_track_descs_.at(i); twcc_id = desc->get_rtp_extension_id(kTWCCExt); @@ -2663,6 +2666,10 @@ srs_error_t SrsRtcConnection::send_rtcp(char *data, int nb_data) ++_srs_pps_srtcps->sugar_; + if (_srs_blackhole->blackhole_) { + _srs_blackhole->sendto(data, nb_data); + } + int nb_buf = nb_data; if ((err = networks_->available()->protect_rtcp(data, &nb_buf)) != srs_success) { return srs_error_wrap(err, "protect rtcp"); @@ -2818,10 +2825,6 @@ srs_error_t SrsRtcConnection::send_rtcp_fb_pli(uint32_t ssrc, const SrsContextId nn, pli_epp_->nn_count_, stream.pos()); } - if (_srs_blackhole->blackhole_) { - _srs_blackhole->sendto(stream.data(), stream.pos()); - } - return send_rtcp(stream.data(), stream.pos()); } diff --git a/trunk/src/app/srs_app_rtmp_source.cpp b/trunk/src/app/srs_app_rtmp_source.cpp index 96cd411e5..58f92cbb5 100644 --- a/trunk/src/app/srs_app_rtmp_source.cpp +++ b/trunk/src/app/srs_app_rtmp_source.cpp @@ -1008,11 +1008,12 @@ srs_error_t SrsOriginHub::on_audio(SrsMediaPacket *shared_audio) sample_rate = srs_audio_sample_rate_from_number(srs_aac_srates[c->aac_sample_rate_]); } - // For AAC, use aac_channels_ from AudioSpecificConfig instead of sound_type_ from FLV tag. - // The FLV sound_type field is often incorrect for AAC streams (e.g., FFmpeg sets it to stereo - // even for mono streams). The AAC AudioSpecificConfig channelConfiguration is the authoritative - // source: 1=mono, 2=stereo. Map to SrsAudioChannels: 0=mono, 1=stereo. - // For MP3 and other codecs, use sound_type_ from FLV tag. + // The FLV specification force to be 1(stereo) for AAC codec, see E.4.2 Audio Tags, + // video_file_format_spec_v10_1.pdf, page 77. + // If the SoundFormat indicates AAC, the SoundType should be 1 (stereo) and the + // SoundRate should be 3 (44 kHz). + // FFmpeg also follows this specification, that is why it always send fixed channels + // and sample rate to SRS. SrsAudioChannels channels = c->sound_type_; if (format->acodec_->id_ == SrsAudioCodecIdAAC) { channels = (c->aac_channels_ == 1) ? SrsAudioChannelsMono : SrsAudioChannelsStereo; diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp index f1801d3be..f1ec28521 100644 --- a/trunk/src/core/srs_core_version7.hpp +++ b/trunk/src/core/srs_core_version7.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 7 #define VERSION_MINOR 0 -#define VERSION_REVISION 112 +#define VERSION_REVISION 113 #endif \ No newline at end of file