Bug 1304336. Part 1 - call DispatchSetPlaybackRate() to propagate playback rate changes instead of using a mirror.
MozReview-Commit-ID: 5C48bUItQus
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -739,16 +739,19 @@ MediaDecoder::InitializeStateMachine()
void
MediaDecoder::SetStateMachineParameters()
{
MOZ_ASSERT(NS_IsMainThread());
if (mMinimizePreroll) {
mDecoderStateMachine->DispatchMinimizePrerollUntilPlaybackStarts();
}
+ if (mPlaybackRate != 1 && mPlaybackRate != 0) {
+ mDecoderStateMachine->DispatchSetPlaybackRate(mPlaybackRate);
+ }
mTimedMetadataListener = mDecoderStateMachine->TimedMetadataEvent().Connect(
AbstractThread::MainThread(), this, &MediaDecoder::OnMetadataUpdate);
mMetadataLoadedListener = mDecoderStateMachine->MetadataLoadedEvent().Connect(
AbstractThread::MainThread(), this, &MediaDecoder::MetadataLoaded);
mFirstFrameLoadedListener = mDecoderStateMachine->FirstFrameLoadedEvent().Connect(
AbstractThread::MainThread(), this, &MediaDecoder::FirstFrameLoaded);
mOnPlaybackEvent = mDecoderStateMachine->OnPlaybackEvent().Connect(
@@ -1505,25 +1508,32 @@ MediaDecoder::SetLoadInBackground(bool a
void
MediaDecoder::SetPlaybackRate(double aPlaybackRate)
{
MOZ_ASSERT(NS_IsMainThread());
mPlaybackRate = aPlaybackRate;
if (mPlaybackRate == 0.0) {
mPausedForPlaybackRateNull = true;
Pause();
- } else if (mPausedForPlaybackRateNull) {
+ return;
+ }
+
+ if (mPausedForPlaybackRateNull) {
// Play() uses mPausedForPlaybackRateNull value, so must reset it first
mPausedForPlaybackRateNull = false;
// If the playbackRate is no longer null, restart the playback, iff the
// media was playing.
if (!mOwner->GetPaused()) {
Play();
}
}
+
+ if (mDecoderStateMachine) {
+ mDecoderStateMachine->DispatchSetPlaybackRate(aPlaybackRate);
+ }
}
void
MediaDecoder::SetPreservesPitch(bool aPreservesPitch)
{
MOZ_ASSERT(NS_IsMainThread());
mPreservesPitch = aPreservesPitch;
}
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -819,17 +819,16 @@ MediaDecoderStateMachine::Initialization
// Initialize watchers.
mWatchManager.Watch(mBuffered, &MediaDecoderStateMachine::BufferedRangeUpdated);
mWatchManager.Watch(mIsReaderSuspended, &MediaDecoderStateMachine::ReaderSuspendedChanged);
mWatchManager.Watch(mState, &MediaDecoderStateMachine::UpdateNextFrameStatus);
mWatchManager.Watch(mAudioCompleted, &MediaDecoderStateMachine::UpdateNextFrameStatus);
mWatchManager.Watch(mVideoCompleted, &MediaDecoderStateMachine::UpdateNextFrameStatus);
mWatchManager.Watch(mVolume, &MediaDecoderStateMachine::VolumeChanged);
- mWatchManager.Watch(mLogicalPlaybackRate, &MediaDecoderStateMachine::LogicalPlaybackRateChanged);
mWatchManager.Watch(mPreservesPitch, &MediaDecoderStateMachine::PreservesPitchChanged);
mWatchManager.Watch(mEstimatedDuration, &MediaDecoderStateMachine::RecomputeDuration);
mWatchManager.Watch(mExplicitDuration, &MediaDecoderStateMachine::RecomputeDuration);
mWatchManager.Watch(mObservedDuration, &MediaDecoderStateMachine::RecomputeDuration);
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
if (MediaPrefs::MDSMSuspendBackgroundVideoEnabled()) {
mIsVisible.Connect(aDecoder->CanonicalIsVisible());
@@ -2787,26 +2786,22 @@ bool MediaDecoderStateMachine::OnTaskQue
bool MediaDecoderStateMachine::IsStateMachineScheduled() const
{
MOZ_ASSERT(OnTaskQueue());
return mDispatchedStateMachine || mDelayedScheduler.IsScheduled();
}
void
-MediaDecoderStateMachine::LogicalPlaybackRateChanged()
+MediaDecoderStateMachine::SetPlaybackRate(double aPlaybackRate)
{
MOZ_ASSERT(OnTaskQueue());
-
- if (mLogicalPlaybackRate == 0) {
- // This case is handled in MediaDecoder by pausing playback.
- return;
- }
-
- mPlaybackRate = mLogicalPlaybackRate;
+ MOZ_ASSERT(aPlaybackRate != 0, "Should be handled by MediaDecoder::Pause()");
+
+ mPlaybackRate = aPlaybackRate;
mMediaSink->SetPlaybackRate(mPlaybackRate);
if (mIsAudioPrerolling && DonePrerollingAudio()) {
StopPrerollingAudio();
}
if (mIsVideoPrerolling && DonePrerollingVideo()) {
StopPrerollingVideo();
}
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -169,16 +169,22 @@ public:
void AddOutputStream(ProcessedMediaStream* aStream, bool aFinishWhenEnded);
// Remove an output stream added with AddOutputStream.
void RemoveOutputStream(MediaStream* aStream);
// Seeks to the decoder to aTarget asynchronously.
RefPtr<MediaDecoder::SeekPromise> InvokeSeek(SeekTarget aTarget);
+ void DispatchSetPlaybackRate(double aPlaybackRate)
+ {
+ OwnerThread()->DispatchStateChange(NewRunnableMethod<double>(
+ this, &MediaDecoderStateMachine::SetPlaybackRate, aPlaybackRate));
+ }
+
// Set/Unset dormant state.
void DispatchSetDormant(bool aDormant);
RefPtr<ShutdownPromise> BeginShutdown();
// Notifies the state machine that should minimize the number of samples
// decoded we preroll, until playback starts. The first time playback starts
// the state machine is free to return to prerolling normally. Note
@@ -362,17 +368,17 @@ protected:
void Push(MediaData* aSample, MediaData::Type aSampleType);
void OnAudioPopped(const RefPtr<MediaData>& aSample);
void OnVideoPopped(const RefPtr<MediaData>& aSample);
void AudioAudibleChanged(bool aAudible);
void VolumeChanged();
- void LogicalPlaybackRateChanged();
+ void SetPlaybackRate(double aPlaybackRate);
void PreservesPitchChanged();
MediaQueue<MediaData>& AudioQueue() { return mAudioQueue; }
MediaQueue<MediaData>& VideoQueue() { return mVideoQueue; }
// True if our buffers of decoded audio are not full, and we should
// decode more.
bool NeedToDecodeAudio();