author | Bobby Holley <bobbyholley@gmail.com> |
Tue, 05 May 2015 21:32:33 -0700 | |
changeset 242845 | fa9d94918e1211f9350272a995003eb58b23ad29 |
parent 242844 | 6777dea98c1fd7231584b22a17b9758cfefb9691 |
child 242846 | 48a6531ce81b95ec1969764d53204609add5a788 |
push id | 28713 |
push user | kwierso@gmail.com |
push date | Fri, 08 May 2015 17:06:43 +0000 |
treeherder | mozilla-central@fd5e9b7eec13 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jww |
bugs | 1161901 |
milestone | 40.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
|
dom/media/MediaDecoderStateMachine.cpp | file | annotate | diff | comparison | revisions | |
dom/media/MediaDecoderStateMachine.h | file | annotate | diff | comparison | revisions |
--- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -320,39 +320,42 @@ MediaDecoderStateMachine::Initialization mWatchManager.Watch(mAudioCompleted, &MediaDecoderStateMachine::UpdateNextFrameStatus); mWatchManager.Watch(mVolume, &MediaDecoderStateMachine::VolumeChanged); mWatchManager.Watch(mLogicalPlaybackRate, &MediaDecoderStateMachine::LogicalPlaybackRateChanged); mWatchManager.Watch(mPreservesPitch, &MediaDecoderStateMachine::PreservesPitchChanged); mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged); mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged); } -bool MediaDecoderStateMachine::HasFutureAudio() { +bool MediaDecoderStateMachine::HasFutureAudio() +{ MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); NS_ASSERTION(HasAudio(), "Should only call HasFutureAudio() when we have audio"); // We've got audio ready to play if: // 1. We've not completed playback of audio, and // 2. we either have more than the threshold of decoded audio available, or // we've completely decoded all audio (but not finished playing it yet // as per 1). return !mAudioCompleted && (AudioDecodedUsecs() > mLowAudioThresholdUsecs * mPlaybackRate || AudioQueue().IsFinished()); } -bool MediaDecoderStateMachine::HaveNextFrameData() { +bool MediaDecoderStateMachine::HaveNextFrameData() +{ MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); return (!HasAudio() || HasFutureAudio()) && (!HasVideo() || VideoQueue().GetSize() > 0); } -int64_t MediaDecoderStateMachine::GetDecodedAudioDuration() { +int64_t MediaDecoderStateMachine::GetDecodedAudioDuration() +{ MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); int64_t audioDecoded = AudioQueue().Duration(); if (mAudioEndTime != -1) { audioDecoded += mAudioEndTime - GetMediaTime(); } return audioDecoded; } @@ -1390,17 +1393,18 @@ double MediaDecoderStateMachine::GetCurr return static_cast<double>(mCurrentFrameTime) / static_cast<double>(USECS_PER_S); } int64_t MediaDecoderStateMachine::GetCurrentTimeUs() const { return mCurrentFrameTime; } -bool MediaDecoderStateMachine::IsRealTime() const { +bool MediaDecoderStateMachine::IsRealTime() const +{ return mRealTime; } int64_t MediaDecoderStateMachine::GetDuration() { AssertCurrentThreadInMonitor(); if (mEndTime == -1 || mStartTime == -1) @@ -3300,17 +3304,18 @@ void MediaDecoderStateMachine::ScheduleS { MOZ_ASSERT(OnTaskQueue()); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); DispatchAudioDecodeTaskIfNeeded(); DispatchVideoDecodeTaskIfNeeded(); } void -MediaDecoderStateMachine::ScheduleStateMachine() { +MediaDecoderStateMachine::ScheduleStateMachine() +{ MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); if (mDispatchedStateMachine) { return; } mDispatchedStateMachine = true; nsCOMPtr<nsIRunnable> task = @@ -3349,16 +3354,17 @@ bool MediaDecoderStateMachine::OnDecodeT bool MediaDecoderStateMachine::OnTaskQueue() const { return TaskQueue()->IsCurrentThreadIn(); } bool MediaDecoderStateMachine::IsStateMachineScheduled() const { + MOZ_ASSERT(OnTaskQueue()); return mDispatchedStateMachine || mDelayedScheduler.IsScheduled(); } void MediaDecoderStateMachine::LogicalPlaybackRateChanged() { MOZ_ASSERT(OnTaskQueue()); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
--- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -273,25 +273,25 @@ public: return mInfo.HasVideo(); } // Should be called by main thread. bool HaveNextFrameData(); // Must be called with the decode monitor held. bool IsBuffering() const { + MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); - return mState == DECODER_STATE_BUFFERING; } // Must be called with the decode monitor held. bool IsSeeking() const { + MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); - return mState == DECODER_STATE_SEEKING; } nsresult GetBuffered(dom::TimeRanges* aBuffered) { // It's possible for JS to query .buffered before we've determined the start // time from metadata, in which case the reader isn't ready to be asked this // question. ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); @@ -353,16 +353,17 @@ public: void NotReached() { MOZ_DIAGNOSTIC_ASSERT(false); } // Set the media fragment end time. aEndTime is in microseconds. void SetFragmentEndTime(int64_t aEndTime); // Drop reference to decoder. Only called during shutdown dance. void BreakCycles() { + MOZ_ASSERT(NS_IsMainThread()); if (mReader) { mReader->BreakCycles(); } mDecoder = nullptr; } // Copy queued audio/video data in the reader to any output MediaStreams that // need it. @@ -408,20 +409,22 @@ public: TaskQueue()->Dispatch(r.forget()); } void OnAudioDecoded(AudioData* aSample); void OnVideoDecoded(VideoData* aSample); void OnNotDecoded(MediaData::Type aType, MediaDecoderReader::NotDecodedReason aReason); void OnAudioNotDecoded(MediaDecoderReader::NotDecodedReason aReason) { + MOZ_ASSERT(OnTaskQueue()); OnNotDecoded(MediaData::AUDIO_DATA, aReason); } void OnVideoNotDecoded(MediaDecoderReader::NotDecodedReason aReason) { + MOZ_ASSERT(OnTaskQueue()); OnNotDecoded(MediaData::VIDEO_DATA, aReason); } // Resets all state related to decoding and playback, emptying all buffers // and aborting all pending operations on the decode task queue. void Reset(); protected: @@ -502,16 +505,17 @@ protected: // // May not be invoked when mReader->UseBufferingHeuristics() is false. bool HasLowDecodedData(int64_t aAudioUsecs); bool OutOfDecodedAudio(); bool OutOfDecodedVideo() { + MOZ_ASSERT(OnTaskQueue()); // In buffering mode, we keep the last already-played frame in the queue. int emptyVideoSize = mState == DECODER_STATE_BUFFERING ? 1 : 0; return IsVideoDecoding() && !VideoQueue().IsFinished() && VideoQueue().GetSize() <= emptyVideoSize; } // Returns true if we're running low on data which is not yet decoded. // The decoder monitor must be held. @@ -821,16 +825,17 @@ public: mRequest.Begin(mMediaTimer->WaitUntil(mTarget, __func__)->RefableThen( mSelf->TaskQueue(), __func__, mSelf, &MediaDecoderStateMachine::OnDelayedSchedule, &MediaDecoderStateMachine::NotReached)); } void CompleteRequest() { + MOZ_ASSERT(mSelf->OnTaskQueue()); mRequest.Complete(); mTarget = TimeStamp(); } private: MediaDecoderStateMachine* mSelf; nsRefPtr<MediaTimer> mMediaTimer; MediaPromiseConsumerHolder<mozilla::MediaTimerPromise> mRequest; @@ -1065,27 +1070,29 @@ protected: // At the start of decoding we want to "preroll" the decode until we've // got a few frames decoded before we consider whether decode is falling // behind. Otherwise our "we're falling behind" logic will trigger // unneccessarily if we start playing as soon as the first sample is // decoded. These two fields store how many video frames and audio // samples we must consume before are considered to be finished prerolling. uint32_t AudioPrerollUsecs() const { + MOZ_ASSERT(OnTaskQueue()); if (IsRealTime()) { return 0; } uint32_t result = mLowAudioThresholdUsecs * 2; MOZ_ASSERT(result <= mAmpleAudioThresholdUsecs, "Prerolling will never finish"); return result; } uint32_t VideoPrerollFrames() const { + MOZ_ASSERT(OnTaskQueue()); return IsRealTime() ? 0 : GetAmpleVideoFrames() / 2; } bool DonePrerollingAudio() { MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); return !IsAudioDecoding() || GetDecodedAudioDuration() >= AudioPrerollUsecs() * mPlaybackRate; @@ -1096,25 +1103,27 @@ protected: MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); return !IsVideoDecoding() || static_cast<uint32_t>(VideoQueue().GetSize()) >= VideoPrerollFrames() * mPlaybackRate; } void StopPrerollingAudio() { + MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); if (mIsAudioPrerolling) { mIsAudioPrerolling = false; ScheduleStateMachine(); } } void StopPrerollingVideo() { + MOZ_ASSERT(OnTaskQueue()); AssertCurrentThreadInMonitor(); if (mIsVideoPrerolling) { mIsVideoPrerolling = false; ScheduleStateMachine(); } } // This temporarily stores the first frame we decode after we seek. @@ -1136,40 +1145,43 @@ protected: // Only one of a given pair of ({Audio,Video}DataPromise, WaitForDataPromise) // should exist at any given moment. MediaPromiseConsumerHolder<MediaDecoderReader::AudioDataPromise> mAudioDataRequest; MediaPromiseConsumerHolder<MediaDecoderReader::WaitForDataPromise> mAudioWaitRequest; const char* AudioRequestStatus() { + MOZ_ASSERT(OnTaskQueue()); if (mAudioDataRequest.Exists()) { MOZ_DIAGNOSTIC_ASSERT(!mAudioWaitRequest.Exists()); return "pending"; } else if (mAudioWaitRequest.Exists()) { return "waiting"; } return "idle"; } MediaPromiseConsumerHolder<MediaDecoderReader::WaitForDataPromise> mVideoWaitRequest; MediaPromiseConsumerHolder<MediaDecoderReader::VideoDataPromise> mVideoDataRequest; const char* VideoRequestStatus() { + MOZ_ASSERT(OnTaskQueue()); if (mVideoDataRequest.Exists()) { MOZ_DIAGNOSTIC_ASSERT(!mVideoWaitRequest.Exists()); return "pending"; } else if (mVideoWaitRequest.Exists()) { return "waiting"; } return "idle"; } MediaPromiseConsumerHolder<MediaDecoderReader::WaitForDataPromise>& WaitRequestRef(MediaData::Type aType) { + MOZ_ASSERT(OnTaskQueue()); return aType == MediaData::AUDIO_DATA ? mAudioWaitRequest : mVideoWaitRequest; } // True if we shouldn't play our audio (but still write it to any capturing // streams). When this is true, mStopAudioThread is always true and // the audio thread will never start again after it has stopped. bool mAudioCaptured;