author | JW Wang <jwwang@mozilla.com> |
Fri, 30 Sep 2016 16:45:48 +0800 | |
changeset 316378 | 8b54936366eadffab32498a6916d29b94076ff4b |
parent 316377 | 2a1edf61eb2b6366e78729edb64289e936b03276 |
child 316379 | 4e654ea0dfa6b0b3396cbeac3dff9fc5700a30a9 |
push id | 30770 |
push user | kwierso@gmail.com |
push date | Wed, 05 Oct 2016 00:00:48 +0000 |
treeherder | mozilla-central@3470e326025c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kaku |
bugs | 1307022 |
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 @@ -207,16 +207,18 @@ public: RefPtr<MediaDecoder::SeekPromise> unused = mMaster->mQueuedSeek.mPromise.Ensure(__func__); SetState(DECODER_STATE_DORMANT); return true; } virtual bool HandleCDMProxyReady() { return false; } + virtual bool HandleAudioDecoded(MediaData* aAudio) { return false; } + 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; } // Note this function will delete the current state object. @@ -410,16 +412,23 @@ public: { mMaster->DecodeFirstFrame(); } State GetState() const override { return DECODER_STATE_DECODING_FIRSTFRAME; } + + bool HandleAudioDecoded(MediaData* aAudio) override + { + mMaster->Push(aAudio, MediaData::AUDIO_DATA); + mMaster->MaybeFinishDecodeFirstFrame(); + return true; + } }; class MediaDecoderStateMachine::DecodingState : public MediaDecoderStateMachine::StateObject { public: explicit DecodingState(Master* aPtr) : StateObject(aPtr) {} @@ -476,16 +485,23 @@ public: mMaster->MaybeStartBuffering(); } State GetState() const override { return DECODER_STATE_DECODING; } + bool HandleAudioDecoded(MediaData* aAudio) override + { + mMaster->Push(aAudio, MediaData::AUDIO_DATA); + mMaster->MaybeStopPrerolling(); + return true; + } + private: // Time at which we started decoding. TimeStamp mDecodeStartTime; }; class MediaDecoderStateMachine::SeekingState : public MediaDecoderStateMachine::StateObject { @@ -511,16 +527,22 @@ public: if (mMaster->mCurrentSeek.mTarget.IsVideoOnly()) { mMaster->mCurrentSeek.mTarget.SetType(SeekTarget::Accurate); mMaster->mCurrentSeek.mTarget.SetVideoOnly(false); } mMaster->mQueuedSeek = Move(mMaster->mCurrentSeek); SetState(DECODER_STATE_DORMANT); return true; } + + bool HandleAudioDecoded(MediaData* aAudio) override + { + MOZ_ASSERT(false); + return true; + } }; class MediaDecoderStateMachine::BufferingState : public MediaDecoderStateMachine::StateObject { public: explicit BufferingState(Master* aPtr) : StateObject(aPtr) {} @@ -583,16 +605,25 @@ public: SetState(DECODER_STATE_DECODING); } State GetState() const override { return DECODER_STATE_BUFFERING; } + bool HandleAudioDecoded(MediaData* aAudio) override + { + // This might be the sample we need to exit buffering. + // Schedule Step() to check it. + mMaster->Push(aAudio, MediaData::AUDIO_DATA); + mMaster->ScheduleStateMachine(); + return true; + } + private: TimeStamp mBufferingStart; }; class MediaDecoderStateMachine::CompletedState : public MediaDecoderStateMachine::StateObject { public: @@ -1013,50 +1044,24 @@ MediaDecoderStateMachine::NeedToDecodeAu ((!mSentFirstFrameLoadedEvent && AudioQueue().GetSize() == 0) || (!mMinimizePreroll && !HaveEnoughDecodedAudio())); } void MediaDecoderStateMachine::OnAudioDecoded(MediaData* aAudio) { MOZ_ASSERT(OnTaskQueue()); - MOZ_ASSERT(mState != DECODER_STATE_SEEKING); MOZ_ASSERT(aAudio); // audio->GetEndTime() is not always mono-increasing in chained ogg. mDecodedAudioEndTime = std::max(aAudio->GetEndTime(), mDecodedAudioEndTime); SAMPLE_LOG("OnAudioDecoded [%lld,%lld]", aAudio->mTime, aAudio->GetEndTime()); - switch (mState) { - case DECODER_STATE_BUFFERING: { - // If we're buffering, this may be the sample we need to stop buffering. - // Save it and schedule the state machine. - Push(aAudio, MediaData::AUDIO_DATA); - ScheduleStateMachine(); - return; - } - - case DECODER_STATE_DECODING_FIRSTFRAME: { - Push(aAudio, MediaData::AUDIO_DATA); - MaybeFinishDecodeFirstFrame(); - return; - } - - case DECODER_STATE_DECODING: { - Push(aAudio, MediaData::AUDIO_DATA); - MaybeStopPrerolling(); - return; - } - - default: { - // Ignore other cases. - return; - } - } + mStateObj->HandleAudioDecoded(aAudio); } void MediaDecoderStateMachine::Push(MediaData* aSample, MediaData::Type aSampleType) { MOZ_ASSERT(OnTaskQueue()); MOZ_ASSERT(aSample);