Bug 1440040 - Don't round up to next block unless necessary. r?padenot draft
authorAndreas Pehrson <pehrsons@mozilla.com>
Wed, 28 Feb 2018 22:37:02 +0100
changeset 761297 f7ec887c2ef0bb46c0ca107f3d6ea7705477a953
parent 759927 8934930b9199c69ec3d89ff119efafda87fef38c
child 761298 0567b470825770a812b01c5e396cabf1f2a2dcb5
push id100932
push userbmo:apehrson@mozilla.com
push dateWed, 28 Feb 2018 22:06:38 +0000
reviewerspadenot
bugs1440040
milestone60.0a1
Bug 1440040 - Don't round up to next block unless necessary. r?padenot With block size 128, rounding `128` to end of next block gives `256`, which is not what we want when running MSG iterations. That could mean over-iterating and buffering unnecessary amounts of silence. MozReview-Commit-ID: vW14l2ygRy
dom/media/GraphDriver.cpp
dom/media/MediaStreamGraph.cpp
dom/media/MediaStreamGraphImpl.h
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -290,17 +290,17 @@ ThreadedDriver::RunThread()
     if (mIterationStart >= mIterationEnd) {
       NS_ASSERTION(mIterationStart == mIterationEnd ,
                    "Time can't go backwards!");
       // This could happen due to low clock resolution, maybe?
       LOG(LogLevel::Debug, ("Time did not advance"));
     }
 
     GraphTime nextStateComputedTime =
-      mGraphImpl->RoundUpToNextAudioBlock(
+      mGraphImpl->RoundUpToEndOfAudioBlock(
         mIterationEnd + mGraphImpl->MillisecondsToMediaTime(AUDIO_TARGET_MS));
     if (nextStateComputedTime < stateComputedTime) {
       // A previous driver may have been processing further ahead of
       // iterationEnd.
       LOG(LogLevel::Warning,
           ("Prevent state from going backwards. interval[%ld; %ld] state[%ld; "
            "%ld]",
            (long)mIterationStart,
@@ -926,17 +926,18 @@ AudioCallbackDriver::DataCallback(const 
   // fill part or all with leftover data from last iteration (since we
   // align to Audio blocks)
   mScratchBuffer.Empty(mBuffer);
 
   // State computed time is decided by the audio callback's buffer length. We
   // compute the iteration start and end from there, trying to keep the amount
   // of buffering in the graph constant.
   GraphTime nextStateComputedTime =
-    mGraphImpl->RoundUpToNextAudioBlock(stateComputedTime + mBuffer.Available());
+    mGraphImpl->RoundUpToEndOfAudioBlock(
+      stateComputedTime + mBuffer.Available());
 
   mIterationStart = mIterationEnd;
   // inGraph is the number of audio frames there is between the state time and
   // the current time, i.e. the maximum theoretical length of the interval we
   // could use as [mIterationStart; mIterationEnd].
   GraphTime inGraph = stateComputedTime - mIterationStart;
   // We want the interval [mIterationStart; mIterationEnd] to be before the
   // interval [stateComputedTime; nextStateComputedTime]. We also want
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -1047,23 +1047,31 @@ MediaStreamGraphImpl::PrepareUpdatesToMa
       // Don't send the message to the main thread if it's not going to have
       // any work to do.
       !(mUpdateRunnables.IsEmpty() && mStreamUpdates.IsEmpty())) {
     EnsureStableStateEventPosted();
   }
 }
 
 GraphTime
+MediaStreamGraphImpl::RoundUpToEndOfAudioBlock(GraphTime aTime)
+{
+  if (aTime % WEBAUDIO_BLOCK_SIZE == 0) {
+    return aTime;
+  }
+  return RoundUpToNextAudioBlock(aTime);
+}
+
+GraphTime
 MediaStreamGraphImpl::RoundUpToNextAudioBlock(GraphTime aTime)
 {
-  StreamTime ticks = aTime;
-  uint64_t block = ticks >> WEBAUDIO_BLOCK_SIZE_BITS;
+  uint64_t block = aTime >> WEBAUDIO_BLOCK_SIZE_BITS;
   uint64_t nextBlock = block + 1;
-  StreamTime nextTicks = nextBlock << WEBAUDIO_BLOCK_SIZE_BITS;
-  return nextTicks;
+  GraphTime nextTime = nextBlock << WEBAUDIO_BLOCK_SIZE_BITS;
+  return nextTime;
 }
 
 void
 MediaStreamGraphImpl::ProduceDataForStreamsBlockByBlock(uint32_t aStreamIndex,
                                                         TrackRate aSampleRate)
 {
   MOZ_ASSERT(OnGraphThread());
   MOZ_ASSERT(aStreamIndex <= mFirstCycleBreaker,
@@ -4238,18 +4246,18 @@ MediaStreamGraph::StartNonRealtimeProces
 
   MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(this);
   NS_ASSERTION(!graph->mRealtime, "non-realtime only");
 
   if (graph->mNonRealtimeProcessing)
     return;
 
   graph->mEndTime =
-    graph->RoundUpToNextAudioBlock(graph->mStateComputedTime +
-                                   aTicksToProcess - 1);
+    graph->RoundUpToEndOfAudioBlock(graph->mStateComputedTime +
+                                    aTicksToProcess);
   graph->mNonRealtimeProcessing = true;
   graph->EnsureRunInStableState();
 }
 
 void
 ProcessedMediaStream::AddInput(MediaInputPort* aPort)
 {
   MediaStream* s = aPort->GetSource();
--- a/dom/media/MediaStreamGraphImpl.h
+++ b/dom/media/MediaStreamGraphImpl.h
@@ -330,16 +330,21 @@ public:
    * Sort mStreams so that every stream not in a cycle is after any streams
    * it depends on, and every stream in a cycle is marked as being in a cycle.
    * Also sets mIsConsumed on every stream.
    */
   void UpdateStreamOrder();
 
   /**
    * Returns smallest value of t such that t is a multiple of
+   * WEBAUDIO_BLOCK_SIZE and t >= aTime.
+   */
+  GraphTime RoundUpToEndOfAudioBlock(GraphTime aTime);
+  /**
+   * Returns smallest value of t such that t is a multiple of
    * WEBAUDIO_BLOCK_SIZE and t > aTime.
    */
   GraphTime RoundUpToNextAudioBlock(GraphTime aTime);
   /**
    * Produce data for all streams >= aStreamIndex for the current time interval.
    * Advances block by block, each iteration producing data for all streams
    * for a single block.
    * This is called whenever we have an AudioNodeStream in the graph.