mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 11:58:55 +00:00
Bug 1251460 - MDSM now waits on a promise to enqueue first frame loaded. r=jya
MediaDecoderStateMachine's EnqueueFIrstFrameLoadedEvent would previously call into MediaDecoderReader to update MDR's buffered ranges and enqueue the frame loaded event. This commit aims to instead have the buffered update take place, and only afterwards enqueue the event. This should remove the possibility that the event will be fired and handled before the update of the buffered ranges has taken place. MozReview-Commit-ID: GP8w2nF4xmj --HG-- extra : transplant_source : %A0m%13%95%E3Gs%ACMd%1F%F4%25%B9qE%28J%21R
This commit is contained in:
parent
ce47da7e2a
commit
2be9a949c6
@ -88,6 +88,8 @@ public:
|
||||
using WaitForDataPromise =
|
||||
MozPromise<MediaData::Type, WaitForDataRejectValue, IsExclusive>;
|
||||
|
||||
using BufferedUpdatePromise = MozPromise<bool, bool, IsExclusive>;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
|
||||
|
||||
// The caller must ensure that Shutdown() is called before aDecoder is
|
||||
@ -232,6 +234,16 @@ public:
|
||||
UpdateBuffered();
|
||||
}
|
||||
|
||||
// Update the buffered ranges and upon doing so return a promise
|
||||
// to indicate success. Overrides may need to do extra work to ensure
|
||||
// buffered is up to date.
|
||||
virtual RefPtr<BufferedUpdatePromise> UpdateBufferedWithPromise()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
UpdateBuffered();
|
||||
return BufferedUpdatePromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
virtual MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; }
|
||||
virtual MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; }
|
||||
|
||||
|
@ -1325,6 +1325,8 @@ MediaDecoderStateMachine::Shutdown()
|
||||
ScheduleStateMachine();
|
||||
SetState(DECODER_STATE_SHUTDOWN);
|
||||
|
||||
mBufferedUpdateRequest.DisconnectIfExists();
|
||||
|
||||
mQueuedSeek.RejectIfExists(__func__);
|
||||
mPendingSeek.RejectIfExists(__func__);
|
||||
mCurrentSeek.RejectIfExists(__func__);
|
||||
@ -2020,12 +2022,25 @@ void
|
||||
MediaDecoderStateMachine::EnqueueFirstFrameLoadedEvent()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
MediaDecoderEventVisibility visibility =
|
||||
mSentFirstFrameLoadedEvent ? MediaDecoderEventVisibility::Suppressed
|
||||
: MediaDecoderEventVisibility::Observable;
|
||||
mFirstFrameLoadedEvent.Notify(nsAutoPtr<MediaInfo>(new MediaInfo(mInfo)),
|
||||
Move(visibility));
|
||||
// Track value of mSentFirstFrameLoadedEvent from before updating it
|
||||
bool firstFrameBeenLoaded = mSentFirstFrameLoadedEvent;
|
||||
mSentFirstFrameLoadedEvent = true;
|
||||
RefPtr<MediaDecoderStateMachine> self = this;
|
||||
mBufferedUpdateRequest.Begin(InvokeAsync(DecodeTaskQueue(), mReader.get(), __func__,
|
||||
&MediaDecoderReader::UpdateBufferedWithPromise)
|
||||
->Then(OwnerThread(),
|
||||
__func__,
|
||||
// Resolve
|
||||
[self, firstFrameBeenLoaded]() {
|
||||
self->mBufferedUpdateRequest.Complete();
|
||||
MediaDecoderEventVisibility visibility =
|
||||
firstFrameBeenLoaded ? MediaDecoderEventVisibility::Suppressed
|
||||
: MediaDecoderEventVisibility::Observable;
|
||||
self->mFirstFrameLoadedEvent.Notify(nsAutoPtr<MediaInfo>(new MediaInfo(self->mInfo)),
|
||||
Move(visibility));
|
||||
},
|
||||
// Reject
|
||||
[]() { MOZ_CRASH("Should not reach"); }));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1136,6 +1136,9 @@ private:
|
||||
|
||||
mozilla::RollingMean<uint32_t, uint32_t> mCorruptFrames;
|
||||
|
||||
// Track our request to update the buffered ranges
|
||||
MozPromiseRequestHolder<MediaDecoderReader::BufferedUpdatePromise> mBufferedUpdateRequest;
|
||||
|
||||
// True if we need to call FinishDecodeFirstFrame() upon frame decoding
|
||||
// successeeding.
|
||||
bool mDecodingFirstFrame;
|
||||
|
@ -1619,6 +1619,20 @@ MediaFormatReader::GetBuffered()
|
||||
return intervals.Shift(media::TimeUnit::FromMicroseconds(-startTime));
|
||||
}
|
||||
|
||||
// For the MediaFormatReader override we need to force an update to the
|
||||
// buffered ranges, so we call NotifyDataArrive
|
||||
RefPtr<MediaDecoderReader::BufferedUpdatePromise>
|
||||
MediaFormatReader::UpdateBufferedWithPromise() {
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
// Call NotifyDataArrive to force a recalculation of the buffered
|
||||
// ranges. UpdateBuffered alone will not force a recalculation, so we
|
||||
// use NotifyDataArrived which sets flags to force this recalculation.
|
||||
// See MediaFormatReader::UpdateReceivedNewData for an example of where
|
||||
// the new data flag is used.
|
||||
NotifyDataArrived();
|
||||
return BufferedUpdatePromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
|
||||
void MediaFormatReader::ReleaseMediaResources()
|
||||
{
|
||||
// Before freeing a video codec, all video buffers needed to be released
|
||||
|
@ -55,6 +55,8 @@ protected:
|
||||
public:
|
||||
media::TimeIntervals GetBuffered() override;
|
||||
|
||||
RefPtr<BufferedUpdatePromise> UpdateBufferedWithPromise() override;
|
||||
|
||||
bool ForceZeroStartTime() const override;
|
||||
|
||||
// For Media Resource Management
|
||||
|
Loading…
x
Reference in New Issue
Block a user