import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1163719 - Store startup cache entries in loading order; r=nfroyd (410ef75ff)
- Bug 1072313: P1. Make MacIOSurface refcount thread-safe. r=mattwoodrow (3be93ce91)
- Bug 1072313: P2 Prevent instanciating MacIOSurfaceLib directly. r=mattwoodrow (8d5d7e2e5)
- Bug 1178513 - Export libxul symbols needed by ACL. r=mattwoodrow (b01035079)
- Bug 1143575. Remove unused CompositableClient::OnTransaction. r=nical (8901f1fe8)
- Bug 1143575. Convert SetCurrentImage(nullptr) callers to call ClearAllImages instead. r=nical (1a89f04f0)
- Bug 1143575. Fix indent. r=cpearce (6b8f4e725)
- Bug 1179111 part 1 - Implement CSSAnimation.animationName; r=smaug, r=jwatt (0d27b5d2e)
- Bug 1179111 part 2 - Implement CSSTransition.transitionProperty; r=smaug, r=jwatt (f395dfc55)
- Bug 1144615 - 2 - Adds a playbackRate selector widget to the animation panel; r=vporof (d538eb734)
- Bug 1144615 - 1 - Minor css fixes in animation panel; r=bgrins (661a6feab)
- Bug 1144615 - 3 - Tests for the playbackRate selection UI in the animation panel; r=vporof (82a4b4f91)
- Bug 1120833 - 3 - Refresh the list of animation widgets when new animations are added; r=miker (f833abeb2)
- Bug 1153903 - Get rid of logspam during devtools talos test runs;r=pbrosset (77f1968d2)
- Bug 1155653 - Preview animation target nodes in animationinspector panel; r=bgrins (61f197d75)
- Bug 1151018 - Refresh the list of Animation widgets when the animation panel loads; r=bgrins (9351a0b64)
- Bug 1155663 - Show animations as synchronized time blocks in animation inspector; r=bgrins (66f544aea)
- Bug 1149999 - 2 - Send animation removed events to the animation-panel for re-starting transitions; r=past (2913b4d4b)
- Bug 1179111 part 3 - Make DevTools read the appropriate name property; r=pbrosset (6dfecd643)
- Bug 1179111 part 4 - Remove KeyframeEffectReadOnly.name; r=smaug (85894f42f)
- Bug 1004383 follow-up: Mark ElementPropertyTransition::AsTransition() as override (f37e36e8a)
- Bug 1179111 part 5 - Remove Name() methods; r=jwatt (8909c4781)
- Bug 1143575. Remove Theora-only duplicate frame optimization. r=cpearce (fe53385ec)
- Bug 1172825 - MDSM playback should depend on IsPlaying() instead of |mPlayState|. r=cpearce. (9a9cf656d)
- Bug 1163223 - Switch test_buffered to use timeupdate rather than loadedmetadata. r=cpearce (b91463faf)
- Bug 1163223 - Move bailout case in GetBuffered into the readers. r=jww (c875c1d71)
- Bug 1161901 - Dispatch MediaDecoderReader::SetIdle directly. r=jww (a9ad2582d)
- Bug 1161901 - Use ProxyMediaCall instead of MDSM::ShutdownReader. r=jww (c866b524c)
- Bug 1161901 - Hoist MDSM shutdown logic into MDSM::Shutdown and remove brittle requirement that RunStateMachine only happen once in SHUTDOWN state. r=jww (0d81368d6)
- Bug 1153149 - Remove IsWaitingMediaResources() from PlatformDecoderModule. r=jya (70bd67ee3)
- Bug 1161984 - Get rid of IsWaitingMediaResources() in MP4Reader. r=jya (94dd1f58c)
- Bug 1163223 - Introduce StartTimeRendezvous and route samples through it. r=jww (b2a80c47a)
- Bug 1163223 - Use AwaitStartTime to handle metadata end time. r=jww (8e22fc3fd)
- Bug 1163223 - Use AwaitStartTime to invoke MediaDecoderReader::SetStartTime. r=jww (6141f5303)
- Bug 1172387 - Clean up code of MediaDecoderStateMachine::StopAudioThread. r=kinetik. (717640128)
- Bug 1163223 - Adjust incoming samples for start time. r=jww (c4029f934)
This commit is contained in:
2021-03-25 09:18:42 +08:00
parent c34e72358b
commit 3fcb35e62d
97 changed files with 2766 additions and 784 deletions
+103 -144
View File
@@ -56,8 +56,6 @@ using namespace mozilla::media;
#undef DECODER_LOG
#undef VERBOSE_LOG
extern PRLogModuleInfo* gMediaDecoderLog;
extern PRLogModuleInfo* gMediaSampleLog;
#define LOG(m, l, x, ...) \
MOZ_LOG(m, l, ("Decoder=%p " x, mDecoder.get(), ##__VA_ARGS__))
#define DECODER_LOG(x, ...) \
@@ -227,9 +225,8 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
mAudioCaptured(false),
mPositionChangeQueued(false),
mAudioCompleted(false, "MediaDecoderStateMachine::mAudioCompleted"),
mGotDurationFromMetaData(false),
mNotifyMetadataBeforeFirstFrame(false),
mDispatchedEventToDecode(false),
mStopAudioThread(true),
mQuickBuffering(false),
mMinimizePreroll(false),
mDecodeThreadWaiting(false),
@@ -776,6 +773,7 @@ MediaDecoderStateMachine::OnAudioDecoded(AudioData* aAudioSample)
nsRefPtr<AudioData> audio(aAudioSample);
MOZ_ASSERT(audio);
mAudioDataRequest.Complete();
aAudioSample->AdjustForStartTime(StartTime());
mDecodedAudioEndTime = audio->GetEndTime();
SAMPLE_LOG("OnAudioDecoded [%lld,%lld] disc=%d",
@@ -1050,7 +1048,9 @@ MediaDecoderStateMachine::OnVideoDecoded(VideoData* aVideoSample)
MOZ_ASSERT(OnTaskQueue());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
nsRefPtr<VideoData> video(aVideoSample);
MOZ_ASSERT(video);
mVideoDataRequest.Complete();
aVideoSample->AdjustForStartTime(StartTime());
mDecodedVideoEndTime = video ? video->GetEndTime() : mDecodedVideoEndTime;
SAMPLE_LOG("OnVideoDecoded [%lld,%lld] disc=%d",
@@ -1435,8 +1435,6 @@ void MediaDecoderStateMachine::RecomputeDuration()
fireDurationChanged = true;
} else if (mInfo.mMetadataDuration.isSome()) {
duration = mInfo.mMetadataDuration.ref();
} else if (mInfo.mMetadataEndTime.isSome() && mStartTime >= 0) {
duration = mInfo.mMetadataEndTime.ref() - TimeUnit::FromMicroseconds(mStartTime);
} else {
return;
}
@@ -1461,11 +1459,10 @@ void MediaDecoderStateMachine::SetDuration(TimeUnit aDuration)
MOZ_ASSERT(OnTaskQueue());
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
MOZ_ASSERT(aDuration.ToMicroseconds() >= 0);
mDurationSet = true;
if (mStartTime == -1) {
SetStartTime(0);
}
mDurationSet = true;
if (aDuration.IsInfinite()) {
mEndTime = -1;
@@ -1565,7 +1562,29 @@ void MediaDecoderStateMachine::Shutdown()
if (mAudioSink) {
mAudioSink->PrepareToShutdown();
}
mDecoder->GetReentrantMonitor().NotifyAll();
mQueuedSeek.RejectIfExists(__func__);
mPendingSeek.RejectIfExists(__func__);
mCurrentSeek.RejectIfExists(__func__);
if (IsPlaying()) {
StopPlayback();
}
Reset();
// Shut down our start time rendezvous.
if (mStartTimeRendezvous) {
mStartTimeRendezvous->Destroy();
}
// Put a task in the decode queue to shutdown the reader.
// the queue to spin down.
ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__, &MediaDecoderReader::Shutdown)
->Then(TaskQueue(), __func__, this,
&MediaDecoderStateMachine::FinishShutdown,
&MediaDecoderStateMachine::FinishShutdown);
DECODER_LOG("Shutdown started");
}
void MediaDecoderStateMachine::StartDecoding()
@@ -1738,17 +1757,6 @@ void MediaDecoderStateMachine::StopAudioThread()
MOZ_ASSERT(OnTaskQueue());
AssertCurrentThreadInMonitor();
if (mStopAudioThread) {
// Audio sink is being stopped in another thread. Wait until finished.
while (mAudioSink) {
mDecoder->GetReentrantMonitor().Wait();
}
return;
}
mStopAudioThread = true;
// Wake up audio sink so that it can reach the finish line.
mDecoder->GetReentrantMonitor().NotifyAll();
if (mAudioSink) {
DECODER_LOG("Shutdown audio thread");
mAudioSink->PrepareToShutdown();
@@ -1758,8 +1766,6 @@ void MediaDecoderStateMachine::StopAudioThread()
}
mAudioSink = nullptr;
}
// Wake up those waiting for audio sink to finish.
mDecoder->GetReentrantMonitor().NotifyAll();
}
nsresult
@@ -1775,14 +1781,6 @@ MediaDecoderStateMachine::EnqueueDecodeFirstFrameTask()
return NS_OK;
}
void
MediaDecoderStateMachine::SetReaderIdle()
{
MOZ_ASSERT(OnDecodeTaskQueue());
DECODER_LOG("Invoking SetReaderIdle()");
mReader->SetIdle();
}
void
MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded()
{
@@ -1840,11 +1838,10 @@ MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded()
}
if (needIdle) {
DECODER_LOG("Dispatching SetReaderIdle() audioQueue=%lld videoQueue=%lld",
DECODER_LOG("Dispatching SetIdle() audioQueue=%lld videoQueue=%lld",
GetDecodedAudioDuration(),
VideoQueue().Duration());
nsCOMPtr<nsIRunnable> task = NS_NewRunnableMethod(
this, &MediaDecoderStateMachine::SetReaderIdle);
nsCOMPtr<nsIRunnable> task = NS_NewRunnableMethod(mReader, &MediaDecoderReader::SetIdle);
DecodeTaskQueue()->Dispatch(task.forget());
}
}
@@ -2039,11 +2036,10 @@ MediaDecoderStateMachine::StartAudioThread()
MOZ_ASSERT(OnTaskQueue());
AssertCurrentThreadInMonitor();
if (mAudioCaptured) {
NS_ASSERTION(mStopAudioThread, "mStopAudioThread must always be true if audio is captured");
MOZ_ASSERT(!mAudioSink);
return NS_OK;
}
mStopAudioThread = false;
if (HasAudio() && !mAudioSink) {
// The audio end time should always be at least the audio start time.
mAudioEndTime = mAudioStartTime;
@@ -2188,9 +2184,36 @@ MediaDecoderStateMachine::OnMetadataRead(MetadataHolder* aMetadata)
mDecoder->SetMediaSeekable(mReader->IsMediaSeekable());
mInfo = aMetadata->mInfo;
mMetadataTags = aMetadata->mTags.forget();
nsRefPtr<MediaDecoderStateMachine> self = this;
if (mInfo.mMetadataDuration.isSome() || mInfo.mMetadataEndTime.isSome()) {
// Set up the start time rendezvous if it doesn't already exist (which is
// generally the case, unless we're coming out of dormant mode).
if (!mStartTimeRendezvous) {
mStartTimeRendezvous = new StartTimeRendezvous(TaskQueue(), HasAudio(), HasVideo(),
mReader->ForceZeroStartTime() || IsRealTime());
mStartTimeRendezvous->AwaitStartTime()->Then(TaskQueue(), __func__,
[self] () -> void {
NS_ENSURE_TRUE_VOID(!self->IsShutdown());
ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor());
self->mReader->SetStartTime(self->StartTime());
},
[] () -> void { NS_WARNING("Setting start time on reader failed"); }
);
}
if (mInfo.mMetadataDuration.isSome()) {
RecomputeDuration();
} else if (mInfo.mUnadjustedMetadataEndTime.isSome()) {
mStartTimeRendezvous->AwaitStartTime()->Then(TaskQueue(), __func__,
[self] () -> void {
NS_ENSURE_TRUE_VOID(!self->IsShutdown());
TimeUnit unadjusted = self->mInfo.mUnadjustedMetadataEndTime.ref();
TimeUnit adjustment = TimeUnit::FromMicroseconds(self->StartTime());
self->mInfo.mMetadataDuration.emplace(unadjusted - adjustment);
self->RecomputeDuration();
}, [] () -> void { NS_WARNING("Adjusting metadata end time failed"); }
);
}
if (HasVideo()) {
@@ -2204,11 +2227,15 @@ MediaDecoderStateMachine::OnMetadataRead(MetadataHolder* aMetadata)
}
mDecoder->StartProgressUpdates();
mGotDurationFromMetaData = (GetDuration() != -1) || mDurationSet;
if (mGotDurationFromMetaData) {
// We have all the information required: duration and size
// Inform the element that we've loaded the metadata.
// In general, we wait until we know the duration before notifying the decoder.
// However, we notify unconditionally in this case without waiting for the start
// time, since the caller might be waiting on metadataloaded to be fired before
// feeding in the CDM, which we need to decode the first frame (and
// thus get the metadata). We could fix this if we could compute the start
// time by demuxing without necessaring decoding.
mNotifyMetadataBeforeFirstFrame = mDurationSet || mReader->IsWaitingOnCDMResource();
if (mNotifyMetadataBeforeFirstFrame) {
EnqueueLoadedMetadataEvent();
}
@@ -2317,17 +2344,27 @@ MediaDecoderStateMachine::DecodeFirstFrame()
NS_ENSURE_SUCCESS(res, res);
} else {
if (HasAudio()) {
mAudioDataRequest.Begin(ProxyMediaCall(DecodeTaskQueue(), mReader.get(),
__func__, &MediaDecoderReader::RequestAudioData)
mAudioDataRequest.Begin(
ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__,
&MediaDecoderReader::RequestAudioData)
->Then(TaskQueue(), __func__, mStartTimeRendezvous.get(),
&StartTimeRendezvous::ProcessFirstSample<AudioDataPromise>,
&StartTimeRendezvous::FirstSampleRejected<AudioData>)
->CompletionPromise()
->Then(TaskQueue(), __func__, this,
&MediaDecoderStateMachine::OnAudioDecoded,
&MediaDecoderStateMachine::OnAudioNotDecoded));
&MediaDecoderStateMachine::OnAudioNotDecoded)
);
}
if (HasVideo()) {
mVideoDecodeStartTime = TimeStamp::Now();
mVideoDataRequest.Begin(ProxyMediaCall(DecodeTaskQueue(), mReader.get(),
__func__, &MediaDecoderReader::RequestVideoData, false,
int64_t(0))
mVideoDataRequest.Begin(
ProxyMediaCall(DecodeTaskQueue(), mReader.get(), __func__,
&MediaDecoderReader::RequestVideoData, false, int64_t(0))
->Then(TaskQueue(), __func__, mStartTimeRendezvous.get(),
&StartTimeRendezvous::ProcessFirstSample<VideoDataPromise>,
&StartTimeRendezvous::FirstSampleRejected<VideoData>)
->CompletionPromise()
->Then(TaskQueue(), __func__, this,
&MediaDecoderStateMachine::OnVideoDecoded,
&MediaDecoderStateMachine::OnVideoNotDecoded));
@@ -2384,15 +2421,11 @@ MediaDecoderStateMachine::FinishDecodeFirstFrame()
nsAutoPtr<MediaInfo> info(new MediaInfo());
*info = mInfo;
if (!mGotDurationFromMetaData) {
// We now have a duration, we can fire the LoadedMetadata and
// FirstFrame event.
if (!mNotifyMetadataBeforeFirstFrame) {
// If we didn't have duration and/or start time before, we should now.
EnqueueLoadedMetadataEvent();
EnqueueFirstFrameLoadedEvent();
} else {
// Inform the element that we've loaded the first frame.
EnqueueFirstFrameLoadedEvent();
}
EnqueueFirstFrameLoadedEvent();
if (mState == DECODER_STATE_DECODING_FIRSTFRAME) {
StartDecoding();
@@ -2508,15 +2541,6 @@ private:
nsRefPtr<MediaDecoderStateMachine> mStateMachine;
};
void
MediaDecoderStateMachine::ShutdownReader()
{
MOZ_ASSERT(OnDecodeTaskQueue());
mReader->Shutdown()->Then(TaskQueue(), __func__, this,
&MediaDecoderStateMachine::FinishShutdown,
&MediaDecoderStateMachine::FinishShutdown);
}
void
MediaDecoderStateMachine::FinishShutdown()
{
@@ -2588,40 +2612,12 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
NS_ENSURE_TRUE(resource, NS_ERROR_NULL_POINTER);
switch (mState) {
case DECODER_STATE_ERROR: {
// Just wait for MediaDecoder::DecodeError to shut us down.
return NS_OK;
}
case DECODER_STATE_SHUTDOWN: {
mQueuedSeek.RejectIfExists(__func__);
mPendingSeek.RejectIfExists(__func__);
mCurrentSeek.RejectIfExists(__func__);
if (IsPlaying()) {
StopPlayback();
}
Reset();
// Put a task in the decode queue to shutdown the reader.
// the queue to spin down.
nsCOMPtr<nsIRunnable> task
= NS_NewRunnableMethod(this, &MediaDecoderStateMachine::ShutdownReader);
DecodeTaskQueue()->Dispatch(task.forget());
DECODER_LOG("Shutdown started");
return NS_OK;
}
case DECODER_STATE_DORMANT: {
return NS_OK;
}
case DECODER_STATE_ERROR:
case DECODER_STATE_SHUTDOWN:
case DECODER_STATE_DORMANT:
case DECODER_STATE_WAIT_FOR_CDM:
case DECODER_STATE_WAIT_FOR_RESOURCES: {
case DECODER_STATE_WAIT_FOR_RESOURCES:
return NS_OK;
}
case DECODER_STATE_DECODING_NONE: {
SetState(DECODER_STATE_DECODING_METADATA);
@@ -2658,7 +2654,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
MaybeStartPlayback();
AdvanceFrame();
NS_ASSERTION(mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
NS_ASSERTION(!IsPlaying() ||
mLogicallySeeking ||
IsStateMachineScheduled() ||
mPlaybackRate == 0.0, "Must have timer scheduled");
@@ -2719,6 +2715,9 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
}
case DECODER_STATE_COMPLETED: {
if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING && IsPlaying()) {
StopPlayback();
}
// Play the remaining media. We want to run AdvanceFrame() at least
// once to ensure the current playback position is advanced to the
// end of the media, and so that we update the readyState.
@@ -2726,8 +2725,10 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
(HasAudio() && !mAudioCompleted) ||
(mAudioCaptured && !GetDecodedStream()->IsFinished()))
{
// Start playback if necessary to play the remaining media.
MaybeStartPlayback();
AdvanceFrame();
NS_ASSERTION(mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
NS_ASSERTION(!IsPlaying() ||
mLogicallySeeking ||
mPlaybackRate == 0 || IsStateMachineScheduled(),
"Must have timer scheduled");
@@ -2819,10 +2820,6 @@ void MediaDecoderStateMachine::RenderVideoFrame(VideoData* aData,
MOZ_ASSERT(OnTaskQueue());
mDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn();
if (aData->mDuplicate) {
return;
}
VERBOSE_LOG("playing video frame %lld (queued=%i, state-machine=%i, decoder-queued=%i)",
aData->mTime, VideoQueue().GetSize() + mReader->SizeOfVideoQueueInFrames(),
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames());
@@ -2929,7 +2926,7 @@ void MediaDecoderStateMachine::AdvanceFrame()
NS_ASSERTION(!HasAudio() || mAudioStartTime != -1,
"Should know audio start time if we have audio.");
if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING || mLogicallySeeking) {
if (!IsPlaying() || mLogicallySeeking) {
return;
}
@@ -3040,13 +3037,7 @@ void MediaDecoderStateMachine::AdvanceFrame()
// duration.
RenderVideoFrame(currentFrame, presTime);
}
// If we're no longer playing after dropping and reacquiring the lock,
// playback must've been stopped on the decode thread (by a seek, for
// example). In that case, the current frame is probably out of date.
if (!IsPlaying()) {
ScheduleStateMachine();
return;
}
MOZ_ASSERT(IsPlaying());
MediaDecoder::FrameStatistics& frameStats = mDecoder->GetFrameStatistics();
frameStats.NotifyPresentedFrame();
remainingTime = currentFrame->GetEndTime() - clock_time;
@@ -3083,27 +3074,11 @@ MediaDecoderStateMachine::DropVideoUpToSeekTarget(VideoData* aSample)
MOZ_ASSERT(OnTaskQueue());
nsRefPtr<VideoData> video(aSample);
MOZ_ASSERT(video);
DECODER_LOG("DropVideoUpToSeekTarget() frame [%lld, %lld] dup=%d",
video->mTime, video->GetEndTime(), video->mDuplicate);
DECODER_LOG("DropVideoUpToSeekTarget() frame [%lld, %lld]",
video->mTime, video->GetEndTime());
MOZ_ASSERT(mCurrentSeek.Exists());
const int64_t target = mCurrentSeek.mTarget.mTime;
// Duplicate handling: if we're dropping frames up the seek target, we must
// be wary of Theora duplicate frames. They don't have an image, so if the
// target frame is in a run of duplicates, we won't have an image to draw
// after the seek. So store the last frame encountered while dropping, and
// copy its Image forward onto duplicate frames, so that every frame has
// an Image.
if (video->mDuplicate &&
mFirstVideoFrameAfterSeek &&
!mFirstVideoFrameAfterSeek->mDuplicate) {
nsRefPtr<VideoData> temp =
VideoData::ShallowCopyUpdateTimestampAndDuration(mFirstVideoFrameAfterSeek,
video->mTime,
video->mDuration);
video = temp;
}
// If the frame end time is less than the seek target, we won't want
// to display this frame after the seek, so discard it.
if (target >= video->GetEndTime()) {
@@ -3211,7 +3186,8 @@ void MediaDecoderStateMachine::SetStartTime(int64_t aStartTimeUsecs)
mStartTime = 0;
if (aStartTimeUsecs != 0) {
mStartTime = aStartTimeUsecs;
if (mGotDurationFromMetaData && GetEndTime() != INT64_MAX) {
// XXXbholley - this whole method goes away in the upcoming patches.
if (mDurationSet && GetEndTime() != INT64_MAX) {
NS_ASSERTION(mEndTime != -1,
"We should have mEndTime as supplied duration here");
// We were specified a duration from a Content-Duration HTTP header.
@@ -3221,17 +3197,11 @@ void MediaDecoderStateMachine::SetStartTime(int64_t aStartTimeUsecs)
}
}
// Pass along this immutable value to the reader so that it can make
// calculations independently of the state machine.
mReader->SetStartTime(mStartTime);
// Set the audio start time to be start of media. If this lies before the
// first actual audio frame we have, we'll inject silence during playback
// to ensure the audio starts at the correct time.
mAudioStartTime = mStartTime;
DECODER_LOG("Set media start time to %lld", mStartTime);
RecomputeDuration();
}
void MediaDecoderStateMachine::UpdateNextFrameStatus()
@@ -3334,11 +3304,6 @@ void MediaDecoderStateMachine::ScheduleStateMachineWithLockAndWakeDecoder()
void
MediaDecoderStateMachine::ScheduleStateMachine() {
AssertCurrentThreadInMonitor();
if (mState == DECODER_STATE_SHUTDOWN) {
NS_WARNING("Refusing to schedule shutdown state machine");
return;
}
if (mDispatchedStateMachine) {
return;
}
@@ -3357,11 +3322,6 @@ MediaDecoderStateMachine::ScheduleStateMachineIn(int64_t aMicroseconds)
// the promise, which must happen on the state
// machine task queue.
MOZ_ASSERT(aMicroseconds > 0);
if (mState == DECODER_STATE_SHUTDOWN) {
NS_WARNING("Refusing to schedule shutdown state machine");
return;
}
if (mDispatchedStateMachine) {
return;
}
@@ -3432,7 +3392,6 @@ void MediaDecoderStateMachine::PreservesPitchChanged()
bool MediaDecoderStateMachine::IsShutdown()
{
AssertCurrentThreadInMonitor();
return mState == DECODER_STATE_ERROR ||
mState == DECODER_STATE_SHUTDOWN;
}