Bug 1183007. Part 2 - remove dependency on MDSM::OnAudioEndTimeUpdate from AudioSink. r=kinetik.
authorJW Wang <jwwang@mozilla.com>
Thu, 16 Jul 2015 10:13:27 +0800
changeset 253145 6db05cc790a9f54b26cc50a0ed9067b420dd10b9
parent 253144 492e9a6065d2a777890f9c68bf7c149db3a6df6e
child 253146 fafc65c08458810737e0f67ca36f60e976d514fc
push id29061
push userryanvm@gmail.com
push dateThu, 16 Jul 2015 18:53:45 +0000
treeherdermozilla-central@a0f4a688433d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik
bugs1183007
milestone42.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 1183007. Part 2 - remove dependency on MDSM::OnAudioEndTimeUpdate from AudioSink. r=kinetik.
dom/media/AudioSink.cpp
dom/media/AudioSink.h
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/media/AudioSink.cpp
+++ b/dom/media/AudioSink.cpp
@@ -11,49 +11,16 @@
 namespace mozilla {
 
 extern PRLogModuleInfo* gMediaDecoderLog;
 #define SINK_LOG(msg, ...) \
   MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, ("AudioSink=%p " msg, this, ##__VA_ARGS__))
 #define SINK_LOG_V(msg, ...) \
   MOZ_LOG(gMediaDecoderLog, LogLevel::Verbose, ("AudioSink=%p " msg, this, ##__VA_ARGS__))
 
-AudioSink::OnAudioEndTimeUpdateTask::OnAudioEndTimeUpdateTask(
-                                     MediaDecoderStateMachine* aStateMachine)
-  : mMutex("OnAudioEndTimeUpdateTask")
-  , mEndTime(0)
-  , mStateMachine(aStateMachine)
-{
-}
-
-NS_IMETHODIMP
-AudioSink::OnAudioEndTimeUpdateTask::Run() {
-  MutexAutoLock lock(mMutex);
-  if (mStateMachine) {
-    mStateMachine->OnAudioEndTimeUpdate(mEndTime);
-  }
-  return NS_OK;
-}
-
-void
-AudioSink::OnAudioEndTimeUpdateTask::Dispatch(int64_t aEndTime) {
-  MutexAutoLock lock(mMutex);
-  if (mStateMachine) {
-    mEndTime = aEndTime;
-    nsRefPtr<AudioSink::OnAudioEndTimeUpdateTask> runnable(this);
-    mStateMachine->TaskQueue()->Dispatch(runnable.forget());
-  }
-}
-
-void
-AudioSink::OnAudioEndTimeUpdateTask::Cancel() {
-  MutexAutoLock lock(mMutex);
-  mStateMachine = nullptr;
-}
-
 // The amount of audio frames that is used to fuzz rounding errors.
 static const int64_t AUDIO_FUZZ_FRAMES = 1;
 
 AudioSink::AudioSink(MediaDecoderStateMachine* aStateMachine,
                      int64_t aStartTime, AudioInfo aInfo, dom::AudioChannel aChannel)
   : mStateMachine(aStateMachine)
   , mStartTime(aStartTime)
   , mWritten(0)
@@ -63,17 +30,16 @@ AudioSink::AudioSink(MediaDecoderStateMa
   , mVolume(1.0)
   , mPlaybackRate(1.0)
   , mPreservesPitch(false)
   , mStopAudioThread(false)
   , mSetVolume(false)
   , mSetPlaybackRate(false)
   , mSetPreservesPitch(false)
   , mPlaying(true)
-  , mOnAudioEndTimeUpdateTask(new OnAudioEndTimeUpdateTask(aStateMachine))
 {
 }
 
 nsresult
 AudioSink::Init()
 {
   nsresult rv = NS_NewNamedThread("Media Audio",
                                   getter_AddRefs(mThread),
@@ -127,17 +93,16 @@ AudioSink::PrepareToShutdown()
     mAudioStream->Cancel();
   }
   GetReentrantMonitor().NotifyAll();
 }
 
 void
 AudioSink::Shutdown()
 {
-  mOnAudioEndTimeUpdateTask->Cancel();
   mThread->Shutdown();
   mThread = nullptr;
   MOZ_ASSERT(!mAudioStream);
 }
 
 void
 AudioSink::SetVolume(double aVolume)
 {
@@ -213,20 +178,16 @@ AudioSink::AudioLoop()
       // we pushed to the audio hardware. We must push silence into the audio
       // hardware so that the next audio chunk begins playback at the correct
       // time.
       missingFrames = std::min<int64_t>(UINT32_MAX, missingFrames.value());
       mWritten += PlaySilence(static_cast<uint32_t>(missingFrames.value()));
     } else {
       mWritten += PlayFromAudioQueue();
     }
-    int64_t endTime = GetEndTime();
-    if (endTime != -1) {
-      mOnAudioEndTimeUpdateTask->Dispatch(endTime);
-    }
   }
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   MOZ_ASSERT(mStopAudioThread || AudioQueue().AtEndOfStream());
   if (!mStopAudioThread && mPlaying) {
     Drain();
   }
   SINK_LOG("AudioLoop complete");
   Cleanup();
@@ -422,17 +383,17 @@ AudioSink::WriteSilence(uint32_t aFrames
   buf.SetLength(numSamples);
   memset(buf.Elements(), 0, numSamples * sizeof(AudioDataValue));
   mAudioStream->Write(buf.Elements(), aFrames);
 
   StartAudioStreamPlaybackIfNeeded();
 }
 
 int64_t
-AudioSink::GetEndTime()
+AudioSink::GetEndTime() const
 {
   CheckedInt64 playedUsecs = FramesToUsecs(mWritten, mInfo.mRate) + mStartTime;
   if (!playedUsecs.isValid()) {
     NS_WARNING("Int overflow calculating audio end time");
     return -1;
   }
   return playedUsecs.value();
 }
--- a/dom/media/AudioSink.h
+++ b/dom/media/AudioSink.h
@@ -22,16 +22,19 @@ public:
 
   AudioSink(MediaDecoderStateMachine* aStateMachine,
             int64_t aStartTime, AudioInfo aInfo, dom::AudioChannel aChannel);
 
   nsresult Init();
 
   int64_t GetPosition();
 
+  // Thread-safe. Can be called on any thread.
+  int64_t GetEndTime() const;
+
   // Check whether we've pushed more frames to the audio hardware than it has
   // played.
   bool HasUnplayedFrames();
 
   // Tell the AudioSink to stop processing and initiate shutdown.  Must be
   // called with the decoder monitor held.
   void PrepareToShutdown();
 
@@ -85,18 +88,16 @@ private:
 
   void UpdateStreamSettings();
 
   // If we have already written enough frames to the AudioStream, start the
   // playback.
   void StartAudioStreamPlaybackIfNeeded();
   void WriteSilence(uint32_t aFrames);
 
-  int64_t GetEndTime();
-
   MediaQueue<AudioData>& AudioQueue();
 
   ReentrantMonitor& GetReentrantMonitor();
   void AssertCurrentThreadInMonitor();
   void AssertOnAudioThread();
 
   nsRefPtr<MediaDecoderStateMachine> mStateMachine;
 
@@ -119,45 +120,28 @@ private:
   // PCM frames written to the stream so far.
   Atomic<int64_t> mWritten;
 
   // Keep the last good position returned from the audio stream. Used to ensure
   // position returned by GetPosition() is mono-increasing in spite of audio
   // stream error.
   int64_t mLastGoodPosition;
 
-  AudioInfo mInfo;
+  const AudioInfo mInfo;
 
   dom::AudioChannel mChannel;
 
   double mVolume;
   double mPlaybackRate;
   bool mPreservesPitch;
 
   bool mStopAudioThread;
 
   bool mSetVolume;
   bool mSetPlaybackRate;
   bool mSetPreservesPitch;
 
   bool mPlaying;
-
-  class OnAudioEndTimeUpdateTask : public nsRunnable {
-  public:
-    explicit OnAudioEndTimeUpdateTask(MediaDecoderStateMachine* aStateMachine);
-
-    NS_IMETHOD Run() override;
-
-    void Dispatch(int64_t aEndTime);
-    void Cancel();
-
-  private:
-    Mutex mMutex;
-    int64_t mEndTime;
-    nsRefPtr<MediaDecoderStateMachine> mStateMachine;
-  };
-
-  nsRefPtr<OnAudioEndTimeUpdateTask> mOnAudioEndTimeUpdateTask;
 };
 
 } // namespace mozilla
 
 #endif
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -3070,16 +3070,19 @@ void MediaDecoderStateMachine::QueueMeta
   mMetadataManager.QueueMetadata(metadata);
 }
 
 int64_t
 MediaDecoderStateMachine::AudioEndTime() const
 {
   MOZ_ASSERT(OnTaskQueue());
   AssertCurrentThreadInMonitor();
+  if (mAudioSink) {
+    return mAudioSink->GetEndTime();
+  }
   return mAudioEndTime;
 }
 
 void MediaDecoderStateMachine::OnAudioEndTimeUpdate(int64_t aAudioEndTime)
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   MOZ_ASSERT(aAudioEndTime >= AudioEndTime());