Bug 1312886: P4. Override MediaResource reporting if we have a pending promise. r?jwwang
A future use will see the MediaFormatReader using waiting promise to indicate that the decoders are waiting for an EME key.
We should always enter buffering mode once we're low on data and we're waiting on a key.
MozReview-Commit-ID: DFcT6YEK1Ke
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -225,16 +225,24 @@ public:
protected:
using Master = MediaDecoderStateMachine;
explicit StateObject(Master* aPtr) : mMaster(aPtr) {}
TaskQueue* OwnerThread() const { return mMaster->mTaskQueue; }
MediaResource* Resource() const { return mMaster->mResource; }
MediaDecoderReaderWrapper* Reader() const { return mMaster->mReader; }
const MediaInfo& Info() const { return mMaster->Info(); }
+ bool IsExpectingMoreData() const
+ {
+ // We are expecting more data if either the resource states so, or if we
+ // have a waiting promise pending (such as with non-MSE EME).
+ return Resource()->IsExpectingMoreData() ||
+ (Reader()->IsWaitForDataSupported() &&
+ (Reader()->IsWaitingAudioData() || Reader()->IsWaitingVideoData()));
+ }
// Note this function will delete the current state object.
// Don't access members to avoid UAF after this call.
template <class S, typename... Ts>
auto SetState(Ts... aArgs)
-> decltype(DeclVal<S>().Enter(Move(aArgs)...))
{
// keep mMaster in a local object because mMaster will become invalid after
@@ -1466,17 +1474,17 @@ DecodingState::MaybeStartBuffering()
// Don't enter buffering while prerolling so that the decoder has a chance to
// enqueue some decoded data before we give up and start buffering.
if (!mMaster->IsPlaying()) {
return;
}
bool shouldBuffer;
if (Reader()->UseBufferingHeuristics()) {
- shouldBuffer = Resource()->IsExpectingMoreData() &&
+ shouldBuffer = IsExpectingMoreData() &&
mMaster->HasLowDecodedData() &&
mMaster->HasLowBufferedData();
} else {
MOZ_ASSERT(Reader()->IsWaitForDataSupported());
shouldBuffer =
(mMaster->OutOfDecodedAudio() && Reader()->IsWaitingAudioData()) ||
(mMaster->OutOfDecodedVideo() && Reader()->IsWaitingVideoData());
}
@@ -1606,17 +1614,17 @@ BufferingState::Step()
// we've not decoded enough data to begin playback, or if we've not
// downloaded a reasonable amount of data inside our buffering time.
if (Reader()->UseBufferingHeuristics()) {
TimeDuration elapsed = now - mBufferingStart;
bool isLiveStream = Resource()->IsLiveStream();
if ((isLiveStream || !mMaster->CanPlayThrough()) &&
elapsed < TimeDuration::FromSeconds(mBufferingWait * mMaster->mPlaybackRate) &&
mMaster->HasLowBufferedData(mBufferingWait * USECS_PER_S) &&
- Resource()->IsExpectingMoreData()) {
+ IsExpectingMoreData()) {
SLOG("Buffering: wait %ds, timeout in %.3lfs",
mBufferingWait, mBufferingWait - elapsed.ToSeconds());
mMaster->ScheduleStateMachineIn(USECS_PER_S);
return;
}
} else if (mMaster->OutOfDecodedAudio() || mMaster->OutOfDecodedVideo()) {
MOZ_ASSERT(Reader()->IsWaitForDataSupported(),
"Don't yet have a strategy for non-heuristic + non-WaitForData");