Bug 884632 - Optimize MediaStreamGraphImpl::PrepareUpdatesToMainThreadState in order to only include AudioNodeStreams that the main thread is interested in; r=roc
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 18 Jun 2013 23:09:44 -0400
changeset 135623 566ca9eb534e4aec2b0f131ef20b01f536494d19
parent 135622 42ec2b2ca9877b7010654e77cc11ee269cdd0c77
child 135624 deed7fb2834e4a1d490c06c18c1ae77fdc7a1eea
push id24847
push userkwierso@gmail.com
push dateWed, 19 Jun 2013 23:38:15 +0000
treeherdermozilla-central@8ea92aeab783 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs884632
milestone24.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 884632 - Optimize MediaStreamGraphImpl::PrepareUpdatesToMainThreadState in order to only include AudioNodeStreams that the main thread is interested in; r=roc
content/media/AudioNodeStream.h
content/media/MediaStreamGraph.cpp
content/media/MediaStreamGraph.h
content/media/webaudio/AudioBufferSourceNode.cpp
--- a/content/media/AudioNodeStream.h
+++ b/content/media/AudioNodeStream.h
@@ -103,16 +103,22 @@ public:
   bool IsAudioParamStream() const
   {
     return mAudioParamStream;
   }
   const OutputChunks& LastChunks() const
   {
     return mLastChunks;
   }
+  virtual bool MainThreadNeedsUpdates() const MOZ_OVERRIDE
+  {
+    // Only source and external streams need updates on the main thread.
+    return (mKind == MediaStreamGraph::SOURCE_STREAM && mFinished) ||
+           mKind == MediaStreamGraph::EXTERNAL_STREAM;
+  }
 
   // Any thread
   AudioNodeEngine* Engine() { return mEngine; }
   TrackRate SampleRate() const { return mSampleRate; }
 
 protected:
   void FinishOutput();
 
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -890,16 +890,19 @@ MediaStreamGraphImpl::PlayVideo(MediaStr
 
 void
 MediaStreamGraphImpl::PrepareUpdatesToMainThreadState(bool aFinalUpdate)
 {
   mMonitor.AssertCurrentThreadOwns();
 
   for (uint32_t i = 0; i < mStreams.Length(); ++i) {
     MediaStream* stream = mStreams[i];
+    if (!stream->MainThreadNeedsUpdates()) {
+      continue;
+    }
     StreamUpdate* update = mStreamUpdates.AppendElement();
     update->mGraphUpdateIndex = stream->mGraphUpdateIndices.GetAt(mCurrentTime);
     update->mStream = stream;
     update->mNextMainThreadCurrentTime =
       GraphTimeToStreamTime(stream, mCurrentTime);
     update->mNextMainThreadFinished =
       stream->mFinished &&
       StreamTimeToGraphTime(stream, stream->GetBufferEnd()) <= mCurrentTime;
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -438,16 +438,22 @@ public:
   void ApplyTrackDisabling(TrackID aTrackID, MediaSegment* aSegment);
 
   DOMMediaStream* GetWrapper()
   {
     NS_ASSERTION(NS_IsMainThread(), "Only use DOMMediaStream on main thread");
     return mWrapper;
   }
 
+  // Return true if the main thread needs to observe updates from this stream.
+  virtual bool MainThreadNeedsUpdates() const
+  {
+    return true;
+  }
+
 protected:
   virtual void AdvanceTimeVaryingValuesToCurrentTime(GraphTime aCurrentTime, GraphTime aBlockedTime)
   {
     mBufferStartTime += aBlockedTime;
     mGraphUpdateIndices.InsertTimeAtStart(aBlockedTime);
     mGraphUpdateIndices.AdvanceCurrentTime(aCurrentTime);
     mExplicitBlockerCount.AdvanceCurrentTime(aCurrentTime);
 
@@ -932,17 +938,17 @@ public:
    * tracks, whichever is greater.
    * TODO at some point we will probably need to add API to select
    * particular tracks of each input stream.
    */
   ProcessedMediaStream* CreateTrackUnionStream(DOMMediaStream* aWrapper);
   // Internal AudioNodeStreams can only pass their output to another
   // AudioNode, whereas external AudioNodeStreams can pass their output
   // to an nsAudioStream for playback.
-  enum AudioNodeStreamKind { INTERNAL_STREAM, EXTERNAL_STREAM };
+  enum AudioNodeStreamKind { SOURCE_STREAM, INTERNAL_STREAM, EXTERNAL_STREAM };
   /**
    * Create a stream that will process audio for an AudioNode.
    * Takes ownership of aEngine.  aSampleRate is the sampling rate used
    * for the stream.  If 0 is passed, the sampling rate of the engine's
    * node will get used.
    */
   AudioNodeStream* CreateAudioNodeStream(AudioNodeEngine* aEngine,
                                          AudioNodeStreamKind aKind,
--- a/content/media/webaudio/AudioBufferSourceNode.cpp
+++ b/content/media/webaudio/AudioBufferSourceNode.cpp
@@ -433,17 +433,17 @@ AudioBufferSourceNode::AudioBufferSource
   , mDuration(std::numeric_limits<double>::min())
   , mPlaybackRate(new AudioParam(this, SendPlaybackRateToStream, 1.0f))
   , mLoop(false)
   , mStartCalled(false)
   , mStopped(false)
 {
   mStream = aContext->Graph()->CreateAudioNodeStream(
       new AudioBufferSourceNodeEngine(this, aContext->Destination()),
-      MediaStreamGraph::INTERNAL_STREAM);
+      MediaStreamGraph::SOURCE_STREAM);
   mStream->AddMainThreadListener(this);
 }
 
 AudioBufferSourceNode::~AudioBufferSourceNode()
 {
   if (Context()) {
     Context()->UnregisterAudioBufferSourceNode(this);
   }