author | JW Wang <jwwang@mozilla.com> |
Thu, 29 Sep 2016 11:34:54 +0800 | |
changeset 316174 | 613397fea462b15878742bcba882e1af4242a5a3 |
parent 316173 | d5cc0a54f8b8162f0a5ca70faa773f544164b049 |
child 316175 | 31b07a151f535250ed50e5ab91e79cf06aa84c30 |
push id | 30765 |
push user | philringnalda@gmail.com |
push date | Tue, 04 Oct 2016 03:06:46 +0000 |
treeherder | mozilla-central@adb484f84dec [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kikuo |
bugs | 1306186 |
milestone | 52.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -432,34 +432,33 @@ public: if (mMaster->CheckIfDecodeComplete()) { SetState(DECODER_STATE_COMPLETED); return; } mDecodeStartTime = TimeStamp::Now(); - // Reset other state to pristine values before starting decode. - mMaster->mIsAudioPrerolling = !mMaster->DonePrerollingAudio() && - !Reader()->IsWaitingAudioData(); - mMaster->mIsVideoPrerolling = !mMaster->DonePrerollingVideo() && - !Reader()->IsWaitingVideoData(); + mMaster->mIsAudioPrerolling = true; + mMaster->mIsVideoPrerolling = true; // Ensure that we've got tasks enqueued to decode data if we need to. mMaster->DispatchDecodeTasksIfNeeded(); mMaster->ScheduleStateMachine(); } void Exit() override { if (!mDecodeStartTime.IsNull()) { TimeDuration decodeDuration = TimeStamp::Now() - mDecodeStartTime; SLOG("Exiting DECODING, decoded for %.3lfs", decodeDuration.ToSeconds()); } + mMaster->mIsAudioPrerolling = false; + mMaster->mIsVideoPrerolling = false; } void Step() override { if (mMaster->mPlayState != MediaDecoder::PLAY_STATE_PLAYING && mMaster->IsPlaying()) { // We're playing, but the element/decoder is in paused state. Stop // playing! @@ -1044,18 +1043,19 @@ MediaDecoderStateMachine::OnAudioDecoded case DECODER_STATE_DECODING_FIRSTFRAME: { Push(audio, MediaData::AUDIO_DATA); MaybeFinishDecodeFirstFrame(); return; } case DECODER_STATE_DECODING: { Push(audio, MediaData::AUDIO_DATA); - if (mIsAudioPrerolling && DonePrerollingAudio()) { - StopPrerollingAudio(); + if (mIsAudioPrerolling) { + // Schedule next cycle to check if we can stop prerolling. + ScheduleStateMachine(); } return; } default: { // Ignore other cases. return; } @@ -1232,18 +1232,19 @@ MediaDecoderStateMachine::OnVideoDecoded case DECODER_STATE_DECODING_FIRSTFRAME: { Push(video, MediaData::VIDEO_DATA); MaybeFinishDecodeFirstFrame(); return; } case DECODER_STATE_DECODING: { Push(video, MediaData::VIDEO_DATA); - if (mIsVideoPrerolling && DonePrerollingVideo()) { - StopPrerollingVideo(); + if (mIsVideoPrerolling) { + // Schedule next cycle to check if we can stop prerolling. + ScheduleStateMachine(); } // For non async readers, if the requested video sample was slow to // 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()) { @@ -1407,16 +1408,26 @@ void MediaDecoderStateMachine::MaybeStar MOZ_ASSERT(mState == DECODER_STATE_DECODING || mState == DECODER_STATE_COMPLETED); if (IsPlaying()) { // Logging this case is really spammy - don't do it. return; } + if (mIsAudioPrerolling && + (DonePrerollingAudio() || mReader->IsWaitingAudioData())) { + mIsAudioPrerolling = false; + } + + if (mIsVideoPrerolling && + (DonePrerollingVideo() || mReader->IsWaitingVideoData())) { + mIsVideoPrerolling = false; + } + bool playStatePermits = mPlayState == MediaDecoder::PLAY_STATE_PLAYING; if (!playStatePermits || mIsAudioPrerolling || mIsVideoPrerolling || mAudioOffloading) { DECODER_LOG("Not starting playback [playStatePermits: %d, " "mIsAudioPrerolling: %d, mIsVideoPrerolling: %d, " "mAudioOffloading: %d]", (int)playStatePermits, (int)mIsAudioPrerolling, (int)mIsVideoPrerolling, (int)mAudioOffloading); @@ -2759,23 +2770,17 @@ void MediaDecoderStateMachine::SetPlaybackRate(double aPlaybackRate) { MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(aPlaybackRate != 0, "Should be handled by MediaDecoder::Pause()"); mPlaybackRate = aPlaybackRate; mMediaSink->SetPlaybackRate(mPlaybackRate); - if (mIsAudioPrerolling && DonePrerollingAudio()) { - StopPrerollingAudio(); - } - if (mIsVideoPrerolling && DonePrerollingVideo()) { - StopPrerollingVideo(); - } - + // Schedule next cycle to check if we can stop prerolling. ScheduleStateMachine(); } void MediaDecoderStateMachine::PreservesPitchChanged() { MOZ_ASSERT(OnTaskQueue()); mMediaSink->SetPreservesPitch(mPreservesPitch); } @@ -2927,18 +2932,20 @@ MediaDecoderStateMachine::SetAudioCaptur mAudioCaptured = aCaptured; ScheduleStateMachine(); // Don't buffer as much when audio is captured because we don't need to worry // about high latency audio devices. mAmpleAudioThresholdUsecs = mAudioCaptured ? detail::AMPLE_AUDIO_USECS / 2 : detail::AMPLE_AUDIO_USECS; - if (mIsAudioPrerolling && DonePrerollingAudio()) { - StopPrerollingAudio(); + + if (mIsAudioPrerolling) { + // Schedule next cycle to check if we can stop prerolling. + ScheduleStateMachine(); } } uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const { MOZ_ASSERT(OnTaskQueue()); return (mReader->IsAsync() && mReader->VideoIsHardwareAccelerated()) ? std::max<uint32_t>(sVideoQueueHWAccelSize, MIN_VIDEO_QUEUE_SIZE)