bug 962719 move mStateComputedTime to MediaStreamGraphImpl r=padenot

This commit is contained in:
Karl Tomlinson 2015-08-13 16:23:17 +12:00
parent b92d49216f
commit d794b9b48e
4 changed files with 65 additions and 77 deletions

View File

@ -45,7 +45,6 @@ struct AutoProfilerUnregisterThread
GraphDriver::GraphDriver(MediaStreamGraphImpl* aGraphImpl) GraphDriver::GraphDriver(MediaStreamGraphImpl* aGraphImpl)
: mIterationStart(0), : mIterationStart(0),
mIterationEnd(0), mIterationEnd(0),
mStateComputedTime(0),
mGraphImpl(aGraphImpl), mGraphImpl(aGraphImpl),
mWaitState(WAITSTATE_RUNNING), mWaitState(WAITSTATE_RUNNING),
mCurrentTimeStamp(TimeStamp::Now()), mCurrentTimeStamp(TimeStamp::Now()),
@ -55,8 +54,7 @@ GraphDriver::GraphDriver(MediaStreamGraphImpl* aGraphImpl)
void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver, void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver,
GraphTime aLastSwitchNextIterationStart, GraphTime aLastSwitchNextIterationStart,
GraphTime aLastSwitchNextIterationEnd, GraphTime aLastSwitchNextIterationEnd)
GraphTime aLastSwitchStateComputedTime)
{ {
// We set mIterationEnd here, because the first thing a driver do when it // We set mIterationEnd here, because the first thing a driver do when it
// does an iteration is to update graph times, so we are in fact setting // does an iteration is to update graph times, so we are in fact setting
@ -64,7 +62,6 @@ void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver,
// iteration. // iteration.
mIterationStart = aLastSwitchNextIterationStart; mIterationStart = aLastSwitchNextIterationStart;
mIterationEnd = aLastSwitchNextIterationEnd; mIterationEnd = aLastSwitchNextIterationEnd;
mStateComputedTime = aLastSwitchStateComputedTime;
STREAM_LOG(LogLevel::Debug, ("Setting previous driver: %p (%s)", aPreviousDriver, aPreviousDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver" : "SystemClockDriver")); STREAM_LOG(LogLevel::Debug, ("Setting previous driver: %p (%s)", aPreviousDriver, aPreviousDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver" : "SystemClockDriver"));
MOZ_ASSERT(!mPreviousDriver); MOZ_ASSERT(!mPreviousDriver);
@ -99,17 +96,10 @@ void GraphDriver::EnsureImmediateWakeUpLocked()
mGraphImpl->GetMonitor().Notify(); mGraphImpl->GetMonitor().Notify();
} }
void GraphDriver::UpdateStateComputedTime(GraphTime aStateComputedTime) GraphTime
GraphDriver::StateComputedTime() const
{ {
MOZ_ASSERT(aStateComputedTime >= mIterationEnd); return mGraphImpl->mStateComputedTime;
// The next state computed time can be the same as the previous, here: it
// means the driver would be have been blocking indefinitly, but the graph has
// been woken up right after having been to sleep.
if (aStateComputedTime < mStateComputedTime) {
printf("State time can't go backward %ld < %ld.\n", static_cast<long>(aStateComputedTime), static_cast<long>(mStateComputedTime));
}
mStateComputedTime = aStateComputedTime;
} }
void GraphDriver::EnsureNextIteration() void GraphDriver::EnsureNextIteration()
@ -238,8 +228,7 @@ ThreadedDriver::Revive()
// loop again. // loop again.
MonitorAutoLock mon(mGraphImpl->GetMonitor()); MonitorAutoLock mon(mGraphImpl->GetMonitor());
if (mNextDriver) { if (mNextDriver) {
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd, mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mStateComputedTime);
mGraphImpl->SetCurrentDriver(mNextDriver); mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start(); mNextDriver->Start();
} else { } else {
@ -280,9 +269,10 @@ ThreadedDriver::RunThread()
mIterationStart = IterationEnd(); mIterationStart = IterationEnd();
mIterationEnd += GetIntervalForIteration(); mIterationEnd += GetIntervalForIteration();
if (mStateComputedTime < mIterationEnd) { GraphTime stateComputedTime = StateComputedTime();
if (stateComputedTime < mIterationEnd) {
STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected")); STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected"));
mIterationEnd = mStateComputedTime; mIterationEnd = stateComputedTime;
} }
if (mIterationStart >= mIterationEnd) { if (mIterationStart >= mIterationEnd) {
@ -298,19 +288,18 @@ ThreadedDriver::RunThread()
STREAM_LOG(LogLevel::Debug, STREAM_LOG(LogLevel::Debug,
("interval[%ld; %ld] state[%ld; %ld]", ("interval[%ld; %ld] state[%ld; %ld]",
(long)mIterationStart, (long)mIterationEnd, (long)mIterationStart, (long)mIterationEnd,
(long)mStateComputedTime, (long)nextStateComputedTime)); (long)stateComputedTime, (long)nextStateComputedTime));
mGraphImpl->mFlushSourcesNow = mGraphImpl->mFlushSourcesOnNextIteration; mGraphImpl->mFlushSourcesNow = mGraphImpl->mFlushSourcesOnNextIteration;
mGraphImpl->mFlushSourcesOnNextIteration = false; mGraphImpl->mFlushSourcesOnNextIteration = false;
stillProcessing = mGraphImpl->OneIteration(mIterationStart, stillProcessing = mGraphImpl->OneIteration(mIterationStart,
mIterationEnd, mIterationEnd,
StateComputedTime(), stateComputedTime,
nextStateComputedTime); nextStateComputedTime);
if (mNextDriver && stillProcessing) { if (mNextDriver && stillProcessing) {
STREAM_LOG(LogLevel::Debug, ("Switching to AudioCallbackDriver")); STREAM_LOG(LogLevel::Debug, ("Switching to AudioCallbackDriver"));
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd, mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mStateComputedTime);
mGraphImpl->SetCurrentDriver(mNextDriver); mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start(); mNextDriver->Start();
return; return;
@ -327,7 +316,7 @@ SystemClockDriver::GetIntervalForIteration()
mCurrentTimeStamp = now; mCurrentTimeStamp = now;
MOZ_LOG(gMediaStreamGraphLog, LogLevel::Verbose, MOZ_LOG(gMediaStreamGraphLog, LogLevel::Verbose,
("Updating current time to %f (real %f, mStateComputedTime %f)", ("Updating current time to %f (real %f, StateComputedTime() %f)",
mGraphImpl->MediaTimeToSeconds(IterationEnd() + interval), mGraphImpl->MediaTimeToSeconds(IterationEnd() + interval),
(now - mInitialTimeStamp).ToSeconds(), (now - mInitialTimeStamp).ToSeconds(),
mGraphImpl->MediaTimeToSeconds(StateComputedTime()))); mGraphImpl->MediaTimeToSeconds(StateComputedTime())));
@ -573,8 +562,7 @@ AudioCallbackDriver::Init()
NS_WARNING("Could not create a cubeb stream for MediaStreamGraph, falling back to a SystemClockDriver"); NS_WARNING("Could not create a cubeb stream for MediaStreamGraph, falling back to a SystemClockDriver");
// Fall back to a driver using a normal thread. // Fall back to a driver using a normal thread.
mNextDriver = new SystemClockDriver(GraphImpl()); mNextDriver = new SystemClockDriver(GraphImpl());
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd, mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mStateComputedTime);
mGraphImpl->SetCurrentDriver(mNextDriver); mGraphImpl->SetCurrentDriver(mNextDriver);
DebugOnly<bool> found = mGraphImpl->RemoveMixerCallback(this); DebugOnly<bool> found = mGraphImpl->RemoveMixerCallback(this);
NS_WARN_IF_FALSE(!found, "Mixer callback not added when switching?"); NS_WARN_IF_FALSE(!found, "Mixer callback not added when switching?");
@ -667,8 +655,7 @@ AudioCallbackDriver::Revive()
// If we were switching, switch now. Otherwise, start the audio thread again. // If we were switching, switch now. Otherwise, start the audio thread again.
MonitorAutoLock mon(mGraphImpl->GetMonitor()); MonitorAutoLock mon(mGraphImpl->GetMonitor());
if (mNextDriver) { if (mNextDriver) {
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd, mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mStateComputedTime);
mGraphImpl->SetCurrentDriver(mNextDriver); mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start(); mNextDriver->Start();
} else { } else {
@ -786,7 +773,8 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
AutoInCallback aic(this); AutoInCallback aic(this);
#endif #endif
if (mStateComputedTime == 0) { GraphTime stateComputedTime = StateComputedTime();
if (stateComputedTime == 0) {
MonitorAutoLock mon(mGraphImpl->GetMonitor()); MonitorAutoLock mon(mGraphImpl->GetMonitor());
// Because this function is called during cubeb_stream_init (to prefill the // Because this function is called during cubeb_stream_init (to prefill the
// audio buffers), it can be that we don't have a message here (because this // audio buffers), it can be that we don't have a message here (because this
@ -822,15 +810,15 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
// compute the iteration start and end from there, trying to keep the amount // compute the iteration start and end from there, trying to keep the amount
// of buffering in the graph constant. // of buffering in the graph constant.
GraphTime nextStateComputedTime = GraphTime nextStateComputedTime =
mGraphImpl->RoundUpToNextAudioBlock(mStateComputedTime + mBuffer.Available()); mGraphImpl->RoundUpToNextAudioBlock(stateComputedTime + mBuffer.Available());
mIterationStart = mIterationEnd; mIterationStart = mIterationEnd;
// inGraph is the number of audio frames there is between the state time and // 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 // the current time, i.e. the maximum theoretical length of the interval we
// could use as [mIterationStart; mIterationEnd]. // could use as [mIterationStart; mIterationEnd].
GraphTime inGraph = mStateComputedTime - mIterationStart; GraphTime inGraph = stateComputedTime - mIterationStart;
// We want the interval [mIterationStart; mIterationEnd] to be before the // We want the interval [mIterationStart; mIterationEnd] to be before the
// interval [mStateComputedTime; nextStateComputedTime]. We also want // interval [stateComputedTime; nextStateComputedTime]. We also want
// the distance between these intervals to be roughly equivalent each time, to // the distance between these intervals to be roughly equivalent each time, to
// ensure there is no clock drift between current time and state time. Since // ensure there is no clock drift between current time and state time. Since
// we can't act on the state time because we have to fill the audio buffer, we // we can't act on the state time because we have to fill the audio buffer, we
@ -839,20 +827,20 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
STREAM_LOG(LogLevel::Debug, ("interval[%ld; %ld] state[%ld; %ld] (frames: %ld) (durationMS: %u) (duration ticks: %ld)\n", STREAM_LOG(LogLevel::Debug, ("interval[%ld; %ld] state[%ld; %ld] (frames: %ld) (durationMS: %u) (duration ticks: %ld)\n",
(long)mIterationStart, (long)mIterationEnd, (long)mIterationStart, (long)mIterationEnd,
(long)mStateComputedTime, (long)nextStateComputedTime, (long)stateComputedTime, (long)nextStateComputedTime,
(long)aFrames, (uint32_t)durationMS, (long)aFrames, (uint32_t)durationMS,
(long)(nextStateComputedTime - mStateComputedTime))); (long)(nextStateComputedTime - stateComputedTime)));
mCurrentTimeStamp = TimeStamp::Now(); mCurrentTimeStamp = TimeStamp::Now();
if (mStateComputedTime < mIterationEnd) { if (stateComputedTime < mIterationEnd) {
STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected")); STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected"));
mIterationEnd = mStateComputedTime; mIterationEnd = stateComputedTime;
} }
stillProcessing = mGraphImpl->OneIteration(mIterationStart, stillProcessing = mGraphImpl->OneIteration(mIterationStart,
mIterationEnd, mIterationEnd,
mStateComputedTime, stateComputedTime,
nextStateComputedTime); nextStateComputedTime);
} else { } else {
NS_WARNING("DataCallback buffer filled entirely from scratch buffer, skipping iteration."); NS_WARNING("DataCallback buffer filled entirely from scratch buffer, skipping iteration.");
@ -871,8 +859,7 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
} }
} }
STREAM_LOG(LogLevel::Debug, ("Switching to system driver.")); STREAM_LOG(LogLevel::Debug, ("Switching to system driver."));
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd, mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mStateComputedTime);
mGraphImpl->SetCurrentDriver(mNextDriver); mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start(); mNextDriver->Start();
// Returning less than aFrames starts the draining and eventually stops the // Returning less than aFrames starts the draining and eventually stops the
@ -979,8 +966,7 @@ AudioCallbackDriver::DeviceChangedCallback() {
mCallbackReceivedWhileSwitching = 0; mCallbackReceivedWhileSwitching = 0;
mGraphImpl->mFlushSourcesOnNextIteration = true; mGraphImpl->mFlushSourcesOnNextIteration = true;
mNextDriver = new SystemClockDriver(GraphImpl()); mNextDriver = new SystemClockDriver(GraphImpl());
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd, mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mStateComputedTime);
mGraphImpl->SetCurrentDriver(mNextDriver); mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start(); mNextDriver->Start();
#endif #endif

View File

@ -127,10 +127,6 @@ public:
return mIterationEnd; return mIterationEnd;
} }
GraphTime StateComputedTime() {
return mStateComputedTime;
}
virtual void GetAudioBuffer(float** aBuffer, long& aFrames) { virtual void GetAudioBuffer(float** aBuffer, long& aFrames) {
MOZ_CRASH("This is not an Audio GraphDriver!"); MOZ_CRASH("This is not an Audio GraphDriver!");
} }
@ -155,15 +151,7 @@ public:
*/ */
void SetGraphTime(GraphDriver* aPreviousDriver, void SetGraphTime(GraphDriver* aPreviousDriver,
GraphTime aLastSwitchNextIterationStart, GraphTime aLastSwitchNextIterationStart,
GraphTime aLastSwitchNextIterationEnd, GraphTime aLastSwitchNextIterationEnd);
GraphTime aLastSwitchStateComputedTime);
/**
* Whenever the graph has computed the time until it has all state
* (mStateComputedState), it calls this to indicate the new time until which
* we have computed state.
*/
void UpdateStateComputedTime(GraphTime aStateComputedTime);
/** /**
* Call this to indicate that another iteration of the control loop is * Call this to indicate that another iteration of the control loop is
@ -190,12 +178,12 @@ public:
virtual bool OnThread() = 0; virtual bool OnThread() = 0;
protected: protected:
GraphTime StateComputedTime() const;
// Time of the start of this graph iteration. // Time of the start of this graph iteration.
GraphTime mIterationStart; GraphTime mIterationStart;
// Time of the end of this graph iteration. // Time of the end of this graph iteration.
GraphTime mIterationEnd; GraphTime mIterationEnd;
// Time, in the future, for which blocking has been computed.
GraphTime mStateComputedTime;
// The MediaStreamGraphImpl that owns this driver. This has a lifetime longer // The MediaStreamGraphImpl that owns this driver. This has a lifetime longer
// than the driver, and will never be null. // than the driver, and will never be null.
MediaStreamGraphImpl* mGraphImpl; MediaStreamGraphImpl* mGraphImpl;

View File

@ -171,8 +171,8 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
// the stream at all between mBlockingDecisionsMadeUntilTime and // the stream at all between mBlockingDecisionsMadeUntilTime and
// aDesiredUpToTime. // aDesiredUpToTime.
StreamTime t = StreamTime t =
GraphTimeToStreamTime(aStream, CurrentDriver()->StateComputedTime()) + GraphTimeToStreamTime(aStream, mStateComputedTime) +
(aDesiredUpToTime - CurrentDriver()->StateComputedTime()); (aDesiredUpToTime - mStateComputedTime);
STREAM_LOG(LogLevel::Verbose, ("Calling NotifyPull aStream=%p t=%f current end=%f", aStream, STREAM_LOG(LogLevel::Verbose, ("Calling NotifyPull aStream=%p t=%f current end=%f", aStream,
MediaTimeToSeconds(t), MediaTimeToSeconds(t),
MediaTimeToSeconds(aStream->mBuffer.GetEnd()))); MediaTimeToSeconds(aStream->mBuffer.GetEnd())));
@ -254,7 +254,7 @@ StreamTime
MediaStreamGraphImpl::GraphTimeToStreamTime(MediaStream* aStream, MediaStreamGraphImpl::GraphTimeToStreamTime(MediaStream* aStream,
GraphTime aTime) GraphTime aTime)
{ {
MOZ_ASSERT(aTime <= CurrentDriver()->StateComputedTime(), MOZ_ASSERT(aTime <= mStateComputedTime,
"Don't ask about times where we haven't made blocking decisions yet"); "Don't ask about times where we haven't made blocking decisions yet");
if (aTime <= IterationEnd()) { if (aTime <= IterationEnd()) {
return std::max<StreamTime>(0, aTime - aStream->mBufferStartTime); return std::max<StreamTime>(0, aTime - aStream->mBufferStartTime);
@ -275,7 +275,7 @@ StreamTime
MediaStreamGraphImpl::GraphTimeToStreamTimeOptimistic(MediaStream* aStream, MediaStreamGraphImpl::GraphTimeToStreamTimeOptimistic(MediaStream* aStream,
GraphTime aTime) GraphTime aTime)
{ {
GraphTime computedUpToTime = std::min(CurrentDriver()->StateComputedTime(), aTime); GraphTime computedUpToTime = std::min(mStateComputedTime, aTime);
StreamTime s = GraphTimeToStreamTime(aStream, computedUpToTime); StreamTime s = GraphTimeToStreamTime(aStream, computedUpToTime);
return s + (aTime - computedUpToTime); return s + (aTime - computedUpToTime);
} }
@ -303,9 +303,9 @@ MediaStreamGraphImpl::StreamTimeToGraphTime(MediaStream* aStream,
} }
bool blocked; bool blocked;
GraphTime end; GraphTime end;
if (t < CurrentDriver()->StateComputedTime()) { if (t < mStateComputedTime) {
blocked = aStream->mBlocked.GetAt(t, &end); blocked = aStream->mBlocked.GetAt(t, &end);
end = std::min(end, CurrentDriver()->StateComputedTime()); end = std::min(end, mStateComputedTime);
} else { } else {
blocked = false; blocked = false;
end = GRAPH_TIME_MAX; end = GRAPH_TIME_MAX;
@ -752,7 +752,7 @@ MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions)
bool blockingDecisionsWillChange = false; bool blockingDecisionsWillChange = false;
STREAM_LOG(LogLevel::Verbose, ("Media graph %p computing blocking for time %f", STREAM_LOG(LogLevel::Verbose, ("Media graph %p computing blocking for time %f",
this, MediaTimeToSeconds(CurrentDriver()->StateComputedTime()))); this, MediaTimeToSeconds(mStateComputedTime)));
nsTArray<MediaStream*>* runningAndSuspendedPair[2]; nsTArray<MediaStream*>* runningAndSuspendedPair[2];
runningAndSuspendedPair[0] = &mStreams; runningAndSuspendedPair[0] = &mStreams;
runningAndSuspendedPair[1] = &mSuspendedStreams; runningAndSuspendedPair[1] = &mSuspendedStreams;
@ -768,7 +768,7 @@ MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions)
AddBlockingRelatedStreamsToSet(&streamSet, stream); AddBlockingRelatedStreamsToSet(&streamSet, stream);
GraphTime end; GraphTime end;
for (GraphTime t = CurrentDriver()->StateComputedTime(); for (GraphTime t = mStateComputedTime;
t < aEndBlockingDecisions; t = end) { t < aEndBlockingDecisions; t = end) {
end = GRAPH_TIME_MAX; end = GRAPH_TIME_MAX;
RecomputeBlockingAt(streamSet, t, aEndBlockingDecisions, &end); RecomputeBlockingAt(streamSet, t, aEndBlockingDecisions, &end);
@ -786,10 +786,18 @@ MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions)
} }
} }
STREAM_LOG(LogLevel::Verbose, ("Media graph %p computed blocking for interval %f to %f", STREAM_LOG(LogLevel::Verbose, ("Media graph %p computed blocking for interval %f to %f",
this, MediaTimeToSeconds(CurrentDriver()->StateComputedTime()), this, MediaTimeToSeconds(mStateComputedTime),
MediaTimeToSeconds(aEndBlockingDecisions))); MediaTimeToSeconds(aEndBlockingDecisions)));
CurrentDriver()->UpdateStateComputedTime(aEndBlockingDecisions); MOZ_ASSERT(aEndBlockingDecisions >= IterationEnd());
// The next state computed time can be the same as the previous: it
// means the driver would be have been blocking indefinitly, but the graph has
// been woken up right after having been to sleep.
if (aEndBlockingDecisions < mStateComputedTime) {
printf("State time can't go backward %ld < %ld.\n", static_cast<long>(aEndBlockingDecisions), static_cast<long>(mStateComputedTime));
}
mStateComputedTime = aEndBlockingDecisions;
if (blockingDecisionsWillChange) { if (blockingDecisionsWillChange) {
// Make sure we wake up to notify listeners about these changes. // Make sure we wake up to notify listeners about these changes.
@ -1128,13 +1136,13 @@ MediaStreamGraphImpl::PlayVideo(MediaStream* aStream)
// use, we can't really estimate the graph interval duration, we clamp it to // use, we can't really estimate the graph interval duration, we clamp it to
// the current state computed time. // the current state computed time.
GraphTime framePosition = IterationEnd() + MillisecondsToMediaTime(CurrentDriver()->IterationDuration()); GraphTime framePosition = IterationEnd() + MillisecondsToMediaTime(CurrentDriver()->IterationDuration());
if (framePosition > CurrentDriver()->StateComputedTime()) { if (framePosition > mStateComputedTime) {
#ifdef DEBUG #ifdef DEBUG
if (std::abs(framePosition - CurrentDriver()->StateComputedTime()) >= MillisecondsToMediaTime(5)) { if (std::abs(framePosition - mStateComputedTime) >= MillisecondsToMediaTime(5)) {
STREAM_LOG(LogLevel::Debug, ("Graph thread slowdown?")); STREAM_LOG(LogLevel::Debug, ("Graph thread slowdown?"));
} }
#endif #endif
framePosition = CurrentDriver()->StateComputedTime(); framePosition = mStateComputedTime;
} }
MOZ_ASSERT(framePosition >= aStream->mBufferStartTime, "frame position before buffer?"); MOZ_ASSERT(framePosition >= aStream->mBufferStartTime, "frame position before buffer?");
StreamTime frameBufferTime = GraphTimeToStreamTime(aStream, framePosition); StreamTime frameBufferTime = GraphTimeToStreamTime(aStream, framePosition);
@ -1316,13 +1324,13 @@ MediaStreamGraphImpl::UpdateGraph(GraphTime aEndBlockingDecision)
} }
// The loop is woken up so soon that IterationEnd() barely advances and we // The loop is woken up so soon that IterationEnd() barely advances and we
// end up having aEndBlockingDecision == CurrentDriver()->StateComputedTime(). // end up having aEndBlockingDecision == mStateComputedTime.
// Since stream blocking is computed in the interval of // Since stream blocking is computed in the interval of
// [CurrentDriver()->StateComputedTime(), aEndBlockingDecision), it won't be computed at all. // [mStateComputedTime, aEndBlockingDecision), it won't be computed at all.
// We should ensure next iteration so that pending blocking changes will be // We should ensure next iteration so that pending blocking changes will be
// computed in next loop. // computed in next loop.
if (ensureNextIteration || if (ensureNextIteration ||
aEndBlockingDecision == CurrentDriver()->StateComputedTime()) { aEndBlockingDecision == mStateComputedTime) {
EnsureNextIteration(); EnsureNextIteration();
} }
@ -1904,7 +1912,7 @@ MediaStream::Init()
MediaStreamGraphImpl* graph = GraphImpl(); MediaStreamGraphImpl* graph = GraphImpl();
mBlocked.SetAtAndAfter(graph->IterationEnd(), true); mBlocked.SetAtAndAfter(graph->IterationEnd(), true);
mExplicitBlockerCount.SetAtAndAfter(graph->IterationEnd(), true); mExplicitBlockerCount.SetAtAndAfter(graph->IterationEnd(), true);
mExplicitBlockerCount.SetAtAndAfter(graph->CurrentDriver()->StateComputedTime(), false); mExplicitBlockerCount.SetAtAndAfter(graph->mStateComputedTime, false);
} }
MediaStreamGraphImpl* MediaStreamGraphImpl*
@ -2139,7 +2147,7 @@ MediaStream::ChangeExplicitBlockerCount(int32_t aDelta)
virtual void Run() virtual void Run()
{ {
mStream->ChangeExplicitBlockerCountImpl( mStream->ChangeExplicitBlockerCountImpl(
mStream->GraphImpl()->CurrentDriver()->StateComputedTime(), mDelta); mStream->GraphImpl()->mStateComputedTime, mDelta);
} }
int32_t mDelta; int32_t mDelta;
}; };
@ -2162,7 +2170,7 @@ MediaStream::BlockStreamIfNeeded()
virtual void Run() virtual void Run()
{ {
mStream->BlockStreamIfNeededImpl( mStream->BlockStreamIfNeededImpl(
mStream->GraphImpl()->CurrentDriver()->StateComputedTime()); mStream->GraphImpl()->mStateComputedTime);
} }
}; };
@ -2182,7 +2190,7 @@ MediaStream::UnblockStreamIfNeeded()
virtual void Run() virtual void Run()
{ {
mStream->UnblockStreamIfNeededImpl( mStream->UnblockStreamIfNeededImpl(
mStream->GraphImpl()->CurrentDriver()->StateComputedTime()); mStream->GraphImpl()->mStateComputedTime);
} }
}; };
@ -2635,7 +2643,7 @@ SourceMediaStream::GetBufferedTicks(TrackID aID)
MediaSegment* segment = track->GetSegment(); MediaSegment* segment = track->GetSegment();
if (segment) { if (segment) {
return segment->GetDuration() - return segment->GetDuration() -
GraphTimeToStreamTime(GraphImpl()->CurrentDriver()->StateComputedTime()); GraphTimeToStreamTime(GraphImpl()->mStateComputedTime);
} }
} }
return 0; return 0;
@ -3445,7 +3453,7 @@ MediaStreamGraph::StartNonRealtimeProcessing(uint32_t aTicksToProcess)
return; return;
graph->mEndTime = graph->mEndTime =
graph->RoundUpToNextAudioBlock(graph->CurrentDriver()->StateComputedTime() + graph->RoundUpToNextAudioBlock(graph->mStateComputedTime +
aTicksToProcess - 1); aTicksToProcess - 1);
graph->mNonRealtimeProcessing = true; graph->mNonRealtimeProcessing = true;
graph->EnsureRunInStableState(); graph->EnsureRunInStableState();

View File

@ -561,6 +561,12 @@ public:
* cycles. * cycles.
*/ */
uint32_t mFirstCycleBreaker; uint32_t mFirstCycleBreaker;
/**
* Blocking decisions and all stream contents have been computed up to this
* time. The next batch of updates from the main thread will be processed
* at this time.
*/
GraphTime mStateComputedTime = 0;
/** /**
* Date of the last time we updated the main thread with the graph state. * Date of the last time we updated the main thread with the graph state.
*/ */