Bug 1313449 - Refactor the condition for resolving the waiting promise.
The WaitForDataPromise cannot be resolved even when key has been updated and decode request has be resolved.
2 ScheduleUpdate(NotifyTrackDemuxer, NotifyNewOutput) are merged into 1 so that only mReceivedNewData is set to false again but MFR will
never have a chance to trigger another Update to call CancelWaitingForKey.
By refactoring the condition to resolve the WaitForDataPromise, MDSM is able to request new data and MFR is able to cancel waitingforkey then continue the flow.
MozReview-Commit-ID: 31brwzOoUvF
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -2049,17 +2049,18 @@ MediaFormatReader::UpdateReceivedNewData
ScheduleSeek();
return true;
}
if (decoder.HasInternalSeekPending() || decoder.HasWaitingPromise()) {
if (decoder.HasInternalSeekPending()) {
LOG("Attempting Internal Seek");
InternalSeek(aTrack, decoder.mTimeThreshold.ref());
}
- if (decoder.HasWaitingPromise() && !decoder.IsWaiting()) {
+ if (decoder.HasWaitingPromise() && !decoder.IsWaitingForKey() &&
+ !decoder.IsWaitingForData()) {
MOZ_ASSERT(!decoder.HasPromise());
LOG("We have new data. Resolving WaitingPromise");
decoder.mWaitingPromise.Resolve(decoder.mType, __func__);
}
return true;
}
return false;
}
@@ -2555,19 +2556,19 @@ MediaFormatReader::Update(TrackType aTra
IsDecoderWaitingForCDM(aTrack));
if (IsWaitingOnCDMResource() || !ResolveSetCDMPromiseIfDone(aTrack)) {
// If the content is encrypted, MFR won't start to create decoder until
// CDMProxy is set.
return;
}
- if ((decoder.mWaitingForData &&
+ if ((decoder.IsWaitingForData() &&
(!decoder.mTimeThreshold || decoder.mTimeThreshold.ref().mWaiting)) ||
- (decoder.mWaitingForKey && decoder.mDecodeRequest.Exists())) {
+ (decoder.IsWaitingForKey())) {
// Nothing more we can do at present.
LOGV("Still waiting for data or key. data(%d)/key(%d)",
decoder.mWaitingForData,
decoder.mWaitingForKey);
return;
}
if (decoder.CancelWaitingForKey()) {
@@ -2652,17 +2653,17 @@ MediaFormatReader::SizeOfQueue(TrackType
RefPtr<MediaFormatReader::WaitForDataPromise>
MediaFormatReader::WaitForData(MediaData::Type aType)
{
MOZ_ASSERT(OnTaskQueue());
TrackType trackType = aType == MediaData::VIDEO_DATA ?
TrackType::kVideoTrack : TrackType::kAudioTrack;
auto& decoder = GetDecoderData(trackType);
- if (!decoder.IsWaiting()) {
+ if (!decoder.IsWaitingForData() && !decoder.IsWaitingForKey()) {
// We aren't waiting for anything.
return WaitForDataPromise::CreateAndResolve(decoder.mType, __func__);
}
RefPtr<WaitForDataPromise> p = decoder.mWaitingPromise.Ensure(__func__);
ScheduleUpdate(trackType);
return p;
}
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -416,20 +416,27 @@ private:
// A WaitingPromise is pending if the demuxer is waiting for data or
// if the decoder is waiting for a key.
MozPromiseHolder<WaitForDataPromise> mWaitingPromise;
bool HasWaitingPromise() const
{
MOZ_ASSERT(mOwner->OnTaskQueue());
return !mWaitingPromise.IsEmpty();
}
- bool IsWaiting() const
+
+ bool IsWaitingForData() const
{
MOZ_ASSERT(mOwner->OnTaskQueue());
- return mWaitingForData || mWaitingForKey;
+ return mWaitingForData;
+ }
+
+ bool IsWaitingForKey() const
+ {
+ MOZ_ASSERT(mOwner->OnTaskQueue());
+ return mWaitingForKey && mDecodeRequest.Exists();
}
// MediaDataDecoder handler's variables.
MozPromiseRequestHolder<MediaDataDecoder::DecodePromise> mDecodeRequest;
bool mFlushing; // True if flush is in action.
// Set to true if the last operation run on the decoder was a flush.
bool mFlushed;
RefPtr<SharedShutdownPromiseHolder> mShutdownPromise;
@@ -516,17 +523,17 @@ private:
void Flush();
bool CancelWaitingForKey()
{
if (!mWaitingForKey) {
return false;
}
mWaitingForKey = false;
- if (IsWaiting() || !HasWaitingPromise()) {
+ if (IsWaitingForData() || !HasWaitingPromise()) {
return false;
}
mWaitingPromise.Resolve(mType, __func__);
return true;
}
// Reset the state of the DecoderData, clearing all queued frames
// (pending demuxed and decoded).