From fa5e9016b8fbfa86feb93d780448a3e9fbe19936 Mon Sep 17 00:00:00 2001 From: Richard Thomra Date: Sat, 3 Oct 2026 14:44:59 +0200 Subject: [PATCH 1/2] fix(webrtc-sys): keep NativeAudioSource send streams out of AudioState The m150 port of external_audio_source.patch (#1284) dropped `sending_ = false;` from AudioSendStream::Stop(), so a stopped stream stayed sending. StoreEncoderProperties() then adds it to AudioState whenever a new encoder is set up, and does not check config_.external_source, while Stop() only unregisters non-external streams. A NativeAudioSource stream added that way was never removed, and with PlatformAudio recording, the capture thread called into it from AudioTransportImpl::SendProcessedData after it was destroyed. Keep `sending_ = false;` in Stop() and leave external sources out of AudioState in StoreEncoderProperties(), as Start() already does. Fixes #1490 --- .changeset/external-audio-source-sending.md | 5 +++++ .../patches/external_audio_source.patch | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 .changeset/external-audio-source-sending.md diff --git a/.changeset/external-audio-source-sending.md b/.changeset/external-audio-source-sending.md new file mode 100644 index 000000000..d171214f0 --- /dev/null +++ b/.changeset/external-audio-source-sending.md @@ -0,0 +1,5 @@ +--- +webrtc-sys: patch +--- + +Keep `NativeAudioSource` send streams out of WebRTC's `AudioState`: `AudioSendStream::Stop()` sets `sending_ = false` again, and `StoreEncoderProperties()` no longer adds external sources. A stream added there was never removed, so with `PlatformAudio` recording, the capture thread called into it from `AudioTransportImpl::SendProcessedData` after it was destroyed. diff --git a/webrtc-sys/libwebrtc/patches/external_audio_source.patch b/webrtc-sys/libwebrtc/patches/external_audio_source.patch index c51846c72..c056e2810 100644 --- a/webrtc-sys/libwebrtc/patches/external_audio_source.patch +++ b/webrtc-sys/libwebrtc/patches/external_audio_source.patch @@ -15,7 +15,7 @@ index 643b5f273b..7b5b568692 100644 // Interface of the audio processor used by the audio track to collect diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc -index e9e72b48e7..ca21052ff7 100644 +index e9e72b48e7..76c310ee67 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc @@ -377,8 +377,13 @@ void AudioSendStream::Start() { @@ -34,11 +34,10 @@ index e9e72b48e7..ca21052ff7 100644 } void AudioSendStream::Stop() { -@@ -389,8 +394,10 @@ void AudioSendStream::Stop() { - RTC_LOG(LS_INFO) << "AudioSendStream::Stop: " << config_.rtp.ssrc; +@@ -390,7 +395,10 @@ void AudioSendStream::Stop() { RemoveBitrateObserver(); channel_send_->StopSend(); -- sending_ = false; + sending_ = false; - audio_state()->RemoveSendingStream(this); + // Only unregister if we registered (when not using external source). + if (!config_.external_source) { @@ -47,6 +46,17 @@ index e9e72b48e7..ca21052ff7 100644 } void AudioSendStream::SendAudioData(std::unique_ptr audio_frame) { +@@ -581,7 +589,9 @@ void AudioSendStream::StoreEncoderProperties(int sample_rate_hz, + size_t num_channels) { + encoder_sample_rate_hz_ = sample_rate_hz; + encoder_num_channels_ = num_channels; +- if (sending_) { ++ // External sources never registered with AudioState (see Start()), and ++ // must not be added here either: Stop() would not remove them again. ++ if (sending_ && !config_.external_source) { + // Update AudioState's information about the stream. + audio_state()->AddSendingStream(this, sample_rate_hz, num_channels); + } diff --git a/call/audio_send_stream.h b/call/audio_send_stream.h index 40bfd812a4..a482b16d70 100644 --- a/call/audio_send_stream.h From 8c75b24c77f442f36cd28dec5d06a28cfb1c891c Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Sun, 4 Oct 2026 05:30:13 -0400 Subject: [PATCH 2/2] Drop the changeset until the libwebrtc tag bump This change only edits the patch, so no released crate picks it up until a new WebRTC build is published and WEBRTC_TAG points at it. The changeset moves to that bump PR so the changelog lands with the fix. --- .changeset/external-audio-source-sending.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/external-audio-source-sending.md diff --git a/.changeset/external-audio-source-sending.md b/.changeset/external-audio-source-sending.md deleted file mode 100644 index d171214f0..000000000 --- a/.changeset/external-audio-source-sending.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -webrtc-sys: patch ---- - -Keep `NativeAudioSource` send streams out of WebRTC's `AudioState`: `AudioSendStream::Stop()` sets `sending_ = false` again, and `StoreEncoderProperties()` no longer adds external sources. A stream added there was never removed, so with `PlatformAudio` recording, the capture thread called into it from `AudioTransportImpl::SendProcessedData` after it was destroyed.