AI: HLS: Fix crash when segment is not open by adding NULL checks. v7.0.113 (#3431)

This commit is contained in:
OSSRS-AI 2025-10-30 12:59:50 -04:00 committed by winlin
parent 91a051b45d
commit 8acceb1b1b
7 changed files with 96 additions and 27 deletions

30
.vscode/launch.json vendored
View File

@ -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",

View File

@ -7,16 +7,17 @@ The changelog for SRS.
<a name="v7-changes"></a>
## 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)

View File

@ -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);
}

View File

@ -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();

View File

@ -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());
}

View File

@ -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;

View File

@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
#define VERSION_REVISION 112
#define VERSION_REVISION 113
#endif