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
--- 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.