diff --git a/media/filters/mac/audio_toolbox_audio_decoder.cc b/media/filters/mac/audio_toolbox_audio_decoder.cc index dabd6f0d66452..6d828b6a1b278 100644 --- a/media/filters/mac/audio_toolbox_audio_decoder.cc +++ b/media/filters/mac/audio_toolbox_audio_decoder.cc @@ -127,14 +127,28 @@ void AudioToolboxAudioDecoder::Initialize(const AudioDecoderConfig& config, return; } - // This decoder supports re-initialization. + // This decoder supports re-initialization. Clear ALL state from any previous + // configuration: CreateDecoder() has several early-return paths after + // AudioConverterNew() succeeds, and stale `output_bus_` / `output_buffer_list_` + // sized for the old channel count must never be passed to a new-config + // AudioConverterRef in Decode(). decoder_.reset(); + output_bus_.reset(); + output_buffer_list_.reset(); + limiter_queue_.reset(); + discard_helper_.reset(); output_cb_ = output_cb; + const bool ok = CreateDecoder(config); + if (!ok) { + // CreateDecoder() may partial-fail after AudioConverterNew() populated + // `decoder_` via InitializeInto(). Don't leave a live converter around for + // a later Decode() to use with mismatched staging buffers. + decoder_.reset(); + } base::BindPostTaskToCurrentDefault(std::move(init_cb)) - .Run(CreateDecoder(config) - ? DecoderStatus::Codes::kOk - : DecoderStatus::Codes::kFailedToCreateDecoder); + .Run(ok ? DecoderStatus::Codes::kOk + : DecoderStatus::Codes::kFailedToCreateDecoder); } void AudioToolboxAudioDecoder::Decode(scoped_refptr buffer, @@ -142,6 +156,14 @@ void AudioToolboxAudioDecoder::Decode(scoped_refptr buffer, DecodeCB decode_cb_bound = base::BindPostTaskToCurrentDefault(std::move(decode_cb)); + // A compromised renderer can send Decode() over Mojo after Initialize() + // failed (MojoAudioDecoderService does not track init state). Mirror the + // guard in AudioToolboxAudioEncoder::Encode(). + if (!decoder_) { + std::move(decode_cb_bound).Run(DecoderStatus::Codes::kNotInitialized); + return; + } + // Make sure we are notified if https://crbug.com/49709 returns. Issue also // occurs with some damaged files. if (!buffer->end_of_stream() && buffer->timestamp() == kNoTimestamp) { @@ -226,6 +248,10 @@ void AudioToolboxAudioDecoder::Decode(scoped_refptr buffer, } void AudioToolboxAudioDecoder::Reset(base::OnceClosure reset_cb) { + if (!decoder_) { + base::BindPostTaskToCurrentDefault(std::move(reset_cb)).Run(); + return; + } // This could fail, but ResetCB has no error reporting mechanism, so just let // a subsequent decode call fail. const auto result = AudioConverterReset(decoder_.get());