From a3fcc2932fdadfe1787bc7bba259bccf600b0e50 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Thu, 26 Feb 2026 00:03:19 +0100 Subject: [PATCH] [WebAudio] Gracefully handle mid-stream audio changes. --- dom/media/webaudio/MediaBufferDecoder.cpp | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/dom/media/webaudio/MediaBufferDecoder.cpp b/dom/media/webaudio/MediaBufferDecoder.cpp index 0d8593e937..a748a2919c 100644 --- a/dom/media/webaudio/MediaBufferDecoder.cpp +++ b/dom/media/webaudio/MediaBufferDecoder.cpp @@ -254,6 +254,9 @@ public: } void operator=(SpeexResamplerState* aResampler) { + if (mResampler) { + speex_resampler_destroy(mResampler); + } mResampler = aResampler; } @@ -392,6 +395,28 @@ MediaDecodeTask::FinishDecode() while ((mediaData = mAudioQueue.PopFront())) { RefPtr audioData = mediaData->As(); audioData->EnsureAudioBuffer(); // could lead to a copy :( + + if (audioData->mChannels != channelCount) { + if (audioData->mChannels > channelCount) { + MOZ_LOG(gMediaDecoderLog, + LogLevel::Error, + ("MediaDecodeTask: Channel count increased from %u to %u mid-stream; " + "this is fatal, stopping decode", channelCount, audioData->mChannels)); + ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent); + return; + } + MOZ_LOG(gMediaDecoderLog, + LogLevel::Verbose, + ("MediaDecodeTask: Channel count changed from %u to %u mid-stream, reinitializing resampler", + channelCount, audioData->mChannels)); + channelCount = audioData->mChannels; + if (sampleRate != destSampleRate) { + resampler = speex_resampler_init(channelCount, sampleRate, destSampleRate, + SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr); + speex_resampler_skip_zeros(resampler); + } + } + AudioDataValue* bufferData = static_cast (audioData->mAudioBuffer->Data());