Bug 1159974 - Mirror mVolume. r=jww
authorBobby Holley <bobbyholley@gmail.com>
Wed, 29 Apr 2015 17:27:32 -0700
changeset 242292 41b7be6965cd0fa5222cd39db8f2bf028486230b
parent 242291 3188222d068229029a623956ce16b9eb2fac8643
child 242293 9b076e62f53457c7cf4da503bd5d86e9e540c93a
push id28689
push usercbook@mozilla.com
push dateTue, 05 May 2015 10:05:09 +0000
treeherdermozilla-central@754579ec0e68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjww
bugs1159974
milestone40.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
Bug 1159974 - Mirror mVolume. r=jww
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaDecoderStateMachine.h
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -285,20 +285,17 @@ void MediaDecoder::Pause()
   }
 
   ChangeState(PLAY_STATE_PAUSED);
 }
 
 void MediaDecoder::SetVolume(double aVolume)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  mInitialVolume = aVolume;
-  if (mDecoderStateMachine) {
-    mDecoderStateMachine->SetVolume(aVolume);
-  }
+  mVolume = aVolume;
 }
 
 void MediaDecoder::ConnectDecodedStreamToOutputStream(OutputStreamData* aStream)
 {
   NS_ASSERTION(!aStream->mPort, "Already connected?");
 
   // The output stream must stay in sync with the decoded stream, so if
   // either stream is blocked, we block the other.
@@ -597,17 +594,17 @@ bool MediaDecoder::IsInfinite()
 MediaDecoder::MediaDecoder() :
   mWatchManager(this, AbstractThread::MainThread()),
   mNextFrameStatus(AbstractThread::MainThread(),
                    MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED,
                    "MediaDecoder::mNextFrameStatus (Mirror)"),
   mDecoderPosition(0),
   mPlaybackPosition(0),
   mCurrentTime(0.0),
-  mInitialVolume(0.0),
+  mVolume(AbstractThread::MainThread(), 0.0, "MediaDecoder::mVolume (Canonical)"),
   mInitialPlaybackRate(1.0),
   mInitialPreservesPitch(true),
   mDuration(-1),
   mMediaSeekable(true),
   mSameOriginMedia(false),
   mReentrantMonitor("media.decoder"),
   mPlayState(AbstractThread::MainThread(), PLAY_STATE_LOADING,
              "MediaDecoder::mPlayState (Canonical)"),
@@ -745,17 +742,16 @@ nsresult MediaDecoder::InitializeStateMa
 
   return ScheduleStateMachineThread();
 }
 
 void MediaDecoder::SetStateMachineParameters()
 {
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   mDecoderStateMachine->SetDuration(mDuration);
-  mDecoderStateMachine->SetVolume(mInitialVolume);
   if (GetDecodedStream()) {
     mDecoderStateMachine->SetAudioCaptured();
   }
   SetPlaybackRate(mInitialPlaybackRate);
   mDecoderStateMachine->SetPreservesPitch(mInitialPreservesPitch);
   if (mMinimizePreroll) {
     mDecoderStateMachine->SetMinimizePrerollUntilPlaybackStarts();
   }
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -1074,19 +1074,21 @@ protected:
   int64_t mPlaybackPosition;
 
   // The current playback position of the media resource in units of
   // seconds. This is updated approximately at the framerate of the
   // video (if it is a video) or the callback period of the audio.
   // It is read and written from the main thread only.
   double mCurrentTime;
 
-  // Volume that playback should start at.  0.0 = muted. 1.0 = full
-  // volume.  Readable/Writeable from the main thread.
-  double mInitialVolume;
+  // Volume of playback.  0.0 = muted. 1.0 = full volume.
+  Canonical<double> mVolume;
+public:
+  AbstractCanonical<double>* CanonicalVolume() { return &mVolume; }
+protected:
 
   // PlaybackRate and pitch preservation status we should start at.
   // Readable/Writeable from the main thread.
   double mInitialPlaybackRate;
   bool mInitialPreservesPitch;
 
   // Duration of the media resource. Set to -1 if unknown.
   // Set when the metadata is loaded. Accessed on the main thread
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -221,17 +221,17 @@ MediaDecoderStateMachine::MediaDecoderSt
   mFragmentEndTime(-1),
   mReader(aReader),
   mCurrentFrameTime(0),
   mAudioStartTime(-1),
   mAudioEndTime(-1),
   mDecodedAudioEndTime(-1),
   mVideoFrameEndTime(-1),
   mDecodedVideoEndTime(-1),
-  mVolume(1.0),
+  mVolume(mTaskQueue, 1.0, "MediaDecoderStateMachine::mVolume (Mirror)"),
   mPlaybackRate(1.0),
   mPreservesPitch(true),
   mLowAudioThresholdUsecs(detail::LOW_AUDIO_USECS),
   mAmpleAudioThresholdUsecs(detail::AMPLE_AUDIO_USECS),
   mQuickBufferingLowDataThresholdUsecs(detail::QUICK_BUFFERING_LOW_DATA_USECS),
   mIsAudioPrerolling(false),
   mIsVideoPrerolling(false),
   mAudioCaptured(false),
@@ -302,20 +302,23 @@ MediaDecoderStateMachine::~MediaDecoderS
 void
 MediaDecoderStateMachine::InitializationTask()
 {
   MOZ_ASSERT(OnTaskQueue());
 
   // Connect mirrors.
   mPlayState.Connect(mDecoder->CanonicalPlayState());
   mNextPlayState.Connect(mDecoder->CanonicalNextPlayState());
+  mVolume.Connect(mDecoder->CanonicalVolume());
 
   // Initialize watchers.
   mWatchManager.Watch(mState, &MediaDecoderStateMachine::UpdateNextFrameStatus);
   mWatchManager.Watch(mAudioCompleted, &MediaDecoderStateMachine::UpdateNextFrameStatus);
+  mWatchManager.Watch(mVolume, &MediaDecoderStateMachine::VolumeChanged);
+
 }
 
 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
@@ -1350,21 +1353,20 @@ void MediaDecoderStateMachine::SetState(
               gMachineStateStr[mState], gMachineStateStr[aState]);
 
   mState = aState;
 
   // Clear state-scoped state.
   mSentPlaybackEndedEvent = false;
 }
 
-void MediaDecoderStateMachine::SetVolume(double volume)
+void MediaDecoderStateMachine::VolumeChanged()
 {
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
+  MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  mVolume = volume;
   if (mAudioSink) {
     mAudioSink->SetVolume(mVolume);
   }
 }
 
 void MediaDecoderStateMachine::SetAudioCaptured()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
@@ -2540,16 +2542,17 @@ MediaDecoderStateMachine::FinishShutdown
 
   // Now that those threads are stopped, there's no possibility of
   // mPendingWakeDecoder being needed again. Revoke it.
   mPendingWakeDecoder = nullptr;
 
   // Disconnect canonicals and mirrors before shutting down our task queue.
   mPlayState.DisconnectIfConnected();
   mNextPlayState.DisconnectIfConnected();
+  mVolume.DisconnectIfConnected();
   mNextFrameStatus.DisconnectAll();
 
   // Shut down the watch manager before shutting down our task queue.
   mWatchManager.Shutdown();
 
   MOZ_ASSERT(mState == DECODER_STATE_SHUTDOWN,
              "How did we escape from the shutdown state?");
   // We must daisy-chain these events to destroy the decoder. We must
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -147,19 +147,16 @@ public:
     DECODER_STATE_ERROR
   };
 
   State GetState() {
     AssertCurrentThreadInMonitor();
     return mState;
   }
 
-  // Set the audio volume. The decoder monitor must be obtained before
-  // calling this.
-  void SetVolume(double aVolume);
   void SetAudioCaptured();
 
   // Check if the decoder needs to become dormant state.
   bool IsDormantNeeded();
   // Set/Unset dormant state.
   void SetDormant(bool aDormant);
 
 private:
@@ -442,16 +439,17 @@ protected:
 
   // Pops MediaData* samples from their respective MediaQueues.
   // Note that the audio queue is also drained on the audio thread,
   // which we can't easily react to - This should be fixed when we
   // remove the audio thread in bug 750596.
   already_AddRefed<AudioData> PopAudio();
   already_AddRefed<VideoData> PopVideo();
 
+  void VolumeChanged();
 
   class WakeDecoderRunnable : public nsRunnable {
   public:
     explicit WakeDecoderRunnable(MediaDecoderStateMachine* aSM)
       : mMutex("WakeDecoderRunnable"), mStateMachine(aSM) {}
     NS_IMETHOD Run() override
     {
       nsRefPtr<MediaDecoderStateMachine> stateMachine;
@@ -1004,20 +1002,18 @@ protected:
   // The presentation end time of the last video frame which has been displayed
   // in microseconds. Accessed from the state machine thread.
   int64_t mVideoFrameEndTime;
 
   // The end time of the last decoded video frame. Used to check if we are low
   // on decoded video data.
   int64_t mDecodedVideoEndTime;
 
-  // Volume of playback. 0.0 = muted. 1.0 = full volume. Read/Written
-  // from the state machine and main threads. Synchronised via decoder
-  // monitor.
-  double mVolume;
+  // Volume of playback. 0.0 = muted. 1.0 = full volume.
+  Mirror<double> mVolume;
 
   // Playback rate. 1.0 : normal speed, 0.5 : two times slower. Synchronized via
   // decoder monitor.
   double mPlaybackRate;
 
   // Pitch preservation for the playback rate. Synchronized via decoder monitor.
   bool mPreservesPitch;