Bug 1299074. Part 4 - replace checks for IsDecodingFirstFrame() with !mSentFirstFrameLoadedEvent.
MozReview-Commit-ID: 4ouQAdn4hbZ
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -483,25 +483,26 @@ bool MediaDecoderStateMachine::HaveEnoug
bool
MediaDecoderStateMachine::NeedToDecodeVideo()
{
MOZ_ASSERT(OnTaskQueue());
SAMPLE_LOG("NeedToDecodeVideo() isDec=%d minPrl=%d enufVid=%d",
IsVideoDecoding(), mMinimizePreroll, HaveEnoughDecodedVideo());
return IsVideoDecoding() &&
mState != DECODER_STATE_SEEKING &&
- ((IsDecodingFirstFrame() && VideoQueue().GetSize() == 0) ||
+ ((!mSentFirstFrameLoadedEvent && VideoQueue().GetSize() == 0) ||
(!mMinimizePreroll && !HaveEnoughDecodedVideo()));
}
bool
MediaDecoderStateMachine::NeedToSkipToNextKeyframe()
{
MOZ_ASSERT(OnTaskQueue());
- if (IsDecodingFirstFrame()) {
+ // Don't skip when we're still decoding first frames.
+ if (!mSentFirstFrameLoadedEvent) {
return false;
}
MOZ_ASSERT(mState == DECODER_STATE_DECODING ||
mState == DECODER_STATE_BUFFERING ||
mState == DECODER_STATE_SEEKING);
// Since GetClock() can only be called after starting MediaSink, we return
// false quickly if it is not started because we won't fall behind playback
@@ -552,17 +553,17 @@ bool
MediaDecoderStateMachine::NeedToDecodeAudio()
{
MOZ_ASSERT(OnTaskQueue());
SAMPLE_LOG("NeedToDecodeAudio() isDec=%d minPrl=%d enufAud=%d",
IsAudioDecoding(), mMinimizePreroll, HaveEnoughDecodedAudio());
return IsAudioDecoding() &&
mState != DECODER_STATE_SEEKING &&
- ((IsDecodingFirstFrame() && AudioQueue().GetSize() == 0) ||
+ ((!mSentFirstFrameLoadedEvent && AudioQueue().GetSize() == 0) ||
(!mMinimizePreroll && !HaveEnoughDecodedAudio()));
}
void
MediaDecoderStateMachine::OnAudioDecoded(MediaData* aAudioSample)
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
@@ -728,17 +729,17 @@ MediaDecoderStateMachine::OnNotDecoded(M
}
}
}
bool
MediaDecoderStateMachine::MaybeFinishDecodeFirstFrame()
{
MOZ_ASSERT(OnTaskQueue());
- if (!IsDecodingFirstFrame() ||
+ if (mSentFirstFrameLoadedEvent ||
(IsAudioDecoding() && AudioQueue().GetSize() == 0) ||
(IsVideoDecoding() && VideoQueue().GetSize() == 0)) {
return false;
}
FinishDecodeFirstFrame();
if (!mQueuedSeek.Exists()) {
return false;
}
@@ -785,17 +786,17 @@ MediaDecoderStateMachine::OnVideoDecoded
// arrive, increase the amount of audio we buffer to ensure that we
// don't run out of audio. This is unnecessary for async readers,
// since they decode audio and video on different threads so they
// are unlikely to run out of decoded audio.
if (mReader->IsAsync()) {
return;
}
TimeDuration decodeTime = TimeStamp::Now() - aDecodeStartTime;
- if (!IsDecodingFirstFrame() &&
+ if (mSentFirstFrameLoadedEvent &&
THRESHOLD_FACTOR * DurationToUsecs(decodeTime) > mLowAudioThresholdUsecs &&
!HasLowUndecodedData())
{
mLowAudioThresholdUsecs =
std::min(THRESHOLD_FACTOR * DurationToUsecs(decodeTime), mAmpleAudioThresholdUsecs);
mAmpleAudioThresholdUsecs = std::max(THRESHOLD_FACTOR * mLowAudioThresholdUsecs,
mAmpleAudioThresholdUsecs);
DECODER_LOG("Slow video decode, set mLowAudioThresholdUsecs=%lld mAmpleAudioThresholdUsecs=%lld",
@@ -1498,18 +1499,22 @@ MediaDecoderStateMachine::Seek(SeekTarge
if (aTarget.IsNextFrame() && !HasVideo()) {
DECODER_WARN("Ignore a NextFrameSeekTask on a media file without video track.");
return MediaDecoder::SeekPromise::CreateAndReject(/* aIgnored = */ true, __func__);
}
MOZ_ASSERT(mState > DECODER_STATE_DECODING_METADATA,
"We should have got duration already");
- if (mState < DECODER_STATE_DECODING ||
- (IsDecodingFirstFrame() && !mReader->ForceZeroStartTime())) {
+ // Can't seek until the start time is known.
+ bool hasStartTime = mSentFirstFrameLoadedEvent || mReader->ForceZeroStartTime();
+ // Can't seek when state is WAIT_FOR_CDM or DORMANT.
+ bool stateAllowed = mState >= DECODER_STATE_DECODING;
+
+ if (!stateAllowed || !hasStartTime) {
DECODER_LOG("Seek() Not Enough Data to continue at this stage, queuing seek");
mQueuedSeek.RejectIfExists(__func__);
mQueuedSeek.mTarget = aTarget;
return mQueuedSeek.mPromise.Ensure(__func__);
}
mQueuedSeek.RejectIfExists(__func__);
DECODER_LOG("Changed state to SEEKING (to %lld)", aTarget.GetTime().ToMicroseconds());
@@ -1893,18 +1898,18 @@ bool MediaDecoderStateMachine::HasLowUnd
{
MOZ_ASSERT(OnTaskQueue());
return HasLowUndecodedData(mLowDataThresholdUsecs);
}
bool MediaDecoderStateMachine::HasLowUndecodedData(int64_t aUsecs)
{
MOZ_ASSERT(OnTaskQueue());
- NS_ASSERTION(mState >= DECODER_STATE_DECODING && !IsDecodingFirstFrame(),
- "Must have loaded first frame for mBuffered to be valid");
+ MOZ_ASSERT(mState >= DECODER_STATE_DECODING && mSentFirstFrameLoadedEvent,
+ "Must have loaded first frame for mBuffered to be valid");
// If we don't have a duration, mBuffered is probably not going to have
// a useful buffered range. Return false here so that we don't get stuck in
// buffering mode for live streams.
if (Duration().IsInfinite()) {
return false;
}
@@ -2262,19 +2267,18 @@ nsresult MediaDecoderStateMachine::RunSt
switch (mState) {
case DECODER_STATE_SHUTDOWN:
case DECODER_STATE_DORMANT:
case DECODER_STATE_WAIT_FOR_CDM:
case DECODER_STATE_DECODING_METADATA:
return NS_OK;
case DECODER_STATE_DECODING: {
- if (IsDecodingFirstFrame()) {
- // We haven't completed decoding our first frames, we can't start
- // playback yet.
+ // Can't start playback until having decoded first frames.
+ if (!mSentFirstFrameLoadedEvent) {
return NS_OK;
}
if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING && IsPlaying())
{
// We're playing, but the element/decoder is in paused state. Stop
// playing!
StopPlayback();
}
@@ -2481,17 +2485,17 @@ MediaDecoderStateMachine::UpdatePlayback
}
void MediaDecoderStateMachine::UpdateNextFrameStatus()
{
MOZ_ASSERT(OnTaskQueue());
MediaDecoderOwner::NextFrameStatus status;
const char* statusString;
- if (mState <= DECODER_STATE_WAIT_FOR_CDM || IsDecodingFirstFrame()) {
+ if (mState < DECODER_STATE_DECODING || !mSentFirstFrameLoadedEvent) {
status = MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
statusString = "NEXT_FRAME_UNAVAILABLE";
} else if (IsBuffering()) {
status = MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_BUFFERING;
statusString = "NEXT_FRAME_UNAVAILABLE_BUFFERING";
} else if (IsSeeking()) {
status = MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING;
statusString = "NEXT_FRAME_UNAVAILABLE_SEEKING";