diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc index 2a387ac76f4b7..e3a3b5c8210f4 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc @@ -295,15 +295,23 @@ void RTCVideoDecoderAdapter::Impl::Initialize( config, /*low_delay=*/true, /*cdm_context=*/nullptr, base::BindOnce( - [](base::OnceCallback cb, + [](base::WeakPtr weak_impl, base::OnceCallback cb, media::VideoDecoderType* decoder_type, - media::VideoDecoder* video_decoder, media::DecoderStatus status) { - *decoder_type = video_decoder->GetDecoderType(); + media::DecoderStatus status) { + // The decoder may post this callback to the media task runner + // (e.g. MojoVideoDecoder::FailInit), where it can outlive Impl if + // InitializeSync() timed out and Release() destroyed Impl first. + // While Impl is alive the owning adapter is also alive (Release() + // blocks on Impl destruction), so |decoder_type| / |cb| are safe. + if (!weak_impl) { + return; + } + *decoder_type = weak_impl->video_decoder_->GetDecoderType(); std::move(cb).Run(status.is_ok()); }, + weak_decoder_this_, ConvertToBaseOnceCallback(std::move(init_cb)), - CrossThreadUnretained(decoder_type), - CrossThreadUnretained(video_decoder_.get())), + CrossThreadUnretained(decoder_type)), output_cb, base::DoNothing()); }