commit 0bf980d7abf0f0fa3cb9c8904556fe7de61ffb10
parent d0a896ca628bff9eb5710a19bf34849e4ddc0fcf
Author: alwu <alwu@mozilla.com>
Date: Wed, 22 Oct 2025 18:53:29 +0000
Bug 1990812 - handle the case where switching the decoder state machine fails due to shutdown. r=media-playback-reviewers,chunmin
We will not create a new state machine if the decoder has already been shut
down. In this case, the old state machine will still report as unsupported,
which currently triggers a MOZ_DIAGNOSTIC_CRASH.
Instead of crashing, we should simply reject the promise.
Differential Revision: https://phabricator.services.mozilla.com/D268464
Diffstat:
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp
@@ -381,7 +381,7 @@ void MediaDecoder::OnPlaybackErrorEvent(const MediaResult& aError) {
#ifdef MOZ_WMF_MEDIA_ENGINE
if (aError == NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR ||
aError == NS_ERROR_DOM_MEDIA_CDM_PROXY_NOT_SUPPORTED_ERR) {
- SwitchStateMachine(aError);
+ Unused << SwitchStateMachine(aError);
return;
}
#endif
@@ -389,12 +389,12 @@ void MediaDecoder::OnPlaybackErrorEvent(const MediaResult& aError) {
}
#ifdef MOZ_WMF_MEDIA_ENGINE
-void MediaDecoder::SwitchStateMachine(const MediaResult& aError) {
+bool MediaDecoder::SwitchStateMachine(const MediaResult& aError) {
MOZ_ASSERT(aError == NS_ERROR_DOM_MEDIA_EXTERNAL_ENGINE_NOT_SUPPORTED_ERR ||
aError == NS_ERROR_DOM_MEDIA_CDM_PROXY_NOT_SUPPORTED_ERR);
// Already in shutting down decoder, no need to create another state machine.
if (mPlayState == PLAY_STATE_SHUTDOWN) {
- return;
+ return false;
}
// External engine can't play the resource or we intentionally disable it, try
@@ -473,6 +473,7 @@ void MediaDecoder::SwitchStateMachine(const MediaResult& aError) {
discardStateMachine->BeginShutdown()->Then(
AbstractThread::MainThread(), __func__, [discardStateMachine] {});
+ return true;
}
#endif
@@ -1513,12 +1514,13 @@ RefPtr<SetCDMPromise> MediaDecoder::SetCDMProxy(CDMProxy* aProxy) {
// given CDM proxy.
LOG("CDM proxy %s not supported! Switch to another state machine.",
NS_ConvertUTF16toUTF8(aProxy->KeySystem()).get());
- SwitchStateMachine(
+ bool switched = SwitchStateMachine(
MediaResult{NS_ERROR_DOM_MEDIA_CDM_PROXY_NOT_SUPPORTED_ERR, aProxy});
rv = GetStateMachine()->IsCDMProxySupported(aProxy);
if (NS_FAILED(rv)) {
- MOZ_DIAGNOSTIC_CRASH("CDM proxy not supported after switch!");
- LOG("CDM proxy not supported after switch!");
+ MOZ_DIAGNOSTIC_ASSERT(
+ !switched, "We should only reach here if we failed to switch");
+ LOG("CDM proxy is still not supported!");
return SetCDMPromise::CreateAndReject(rv, __func__);
}
}
diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h
@@ -565,7 +565,8 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
void ConnectMirrors(MediaDecoderStateMachineBase* aObject);
void DisconnectMirrors();
# ifdef MOZ_WMF_MEDIA_ENGINE
- void SwitchStateMachine(const MediaResult& aError);
+ // Return true if we switched to a new state machine.
+ bool SwitchStateMachine(const MediaResult& aError);
# endif
virtual bool CanPlayThroughImpl() = 0;