bug 962719 move mStateComputedTime to MediaStreamGraphImpl r=padenot

--HG--
extra : rebase_source : 3c4727a6397cc77800aa2676b17c3d85702cd64f
This commit is contained in:
Karl Tomlinson 2015-08-13 16:23:17 +12:00
Родитель ea84d39947
Коммит 78739ed9f6
4 изменённых файлов: 65 добавлений и 77 удалений

Просмотреть файл

@ -45,7 +45,6 @@ struct AutoProfilerUnregisterThread
GraphDriver::GraphDriver(MediaStreamGraphImpl* aGraphImpl)
: mIterationStart(0),
mIterationEnd(0),
mStateComputedTime(0),
mGraphImpl(aGraphImpl),
mWaitState(WAITSTATE_RUNNING),
mCurrentTimeStamp(TimeStamp::Now()),
@ -55,8 +54,7 @@ GraphDriver::GraphDriver(MediaStreamGraphImpl* aGraphImpl)
void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver,
GraphTime aLastSwitchNextIterationStart,
GraphTime aLastSwitchNextIterationEnd,
GraphTime aLastSwitchStateComputedTime)
GraphTime aLastSwitchNextIterationEnd)
{
// 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
@ -64,7 +62,6 @@ void GraphDriver::SetGraphTime(GraphDriver* aPreviousDriver,
// iteration.
mIterationStart = aLastSwitchNextIterationStart;
mIterationEnd = aLastSwitchNextIterationEnd;
mStateComputedTime = aLastSwitchStateComputedTime;
STREAM_LOG(LogLevel::Debug, ("Setting previous driver: %p (%s)", aPreviousDriver, aPreviousDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver" : "SystemClockDriver"));
MOZ_ASSERT(!mPreviousDriver);
@ -99,17 +96,10 @@ void GraphDriver::EnsureImmediateWakeUpLocked()
mGraphImpl->GetMonitor().Notify();
}
void GraphDriver::UpdateStateComputedTime(GraphTime aStateComputedTime)
GraphTime
GraphDriver::StateComputedTime() const
{
MOZ_ASSERT(aStateComputedTime >= mIterationEnd);
// 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;
return mGraphImpl->mStateComputedTime;
}
void GraphDriver::EnsureNextIteration()
@ -238,8 +228,7 @@ ThreadedDriver::Revive()
// loop again.
MonitorAutoLock mon(mGraphImpl->GetMonitor());
if (mNextDriver) {
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd,
mStateComputedTime);
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start();
} else {
@ -280,9 +269,10 @@ ThreadedDriver::RunThread()
mIterationStart = IterationEnd();
mIterationEnd += GetIntervalForIteration();
if (mStateComputedTime < mIterationEnd) {
GraphTime stateComputedTime = StateComputedTime();
if (stateComputedTime < mIterationEnd) {
STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected"));
mIterationEnd = mStateComputedTime;
mIterationEnd = stateComputedTime;
}
if (mIterationStart >= mIterationEnd) {
@ -298,19 +288,18 @@ ThreadedDriver::RunThread()
STREAM_LOG(LogLevel::Debug,
("interval[%ld; %ld] state[%ld; %ld]",
(long)mIterationStart, (long)mIterationEnd,
(long)mStateComputedTime, (long)nextStateComputedTime));
(long)stateComputedTime, (long)nextStateComputedTime));
mGraphImpl->mFlushSourcesNow = mGraphImpl->mFlushSourcesOnNextIteration;
mGraphImpl->mFlushSourcesOnNextIteration = false;
stillProcessing = mGraphImpl->OneIteration(mIterationStart,
mIterationEnd,
StateComputedTime(),
stateComputedTime,
nextStateComputedTime);
if (mNextDriver && stillProcessing) {
STREAM_LOG(LogLevel::Debug, ("Switching to AudioCallbackDriver"));
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd,
mStateComputedTime);
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start();
return;
@ -327,7 +316,7 @@ SystemClockDriver::GetIntervalForIteration()
mCurrentTimeStamp = now;
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),
(now - mInitialTimeStamp).ToSeconds(),
mGraphImpl->MediaTimeToSeconds(StateComputedTime())));
@ -573,8 +562,7 @@ AudioCallbackDriver::Init()
NS_WARNING("Could not create a cubeb stream for MediaStreamGraph, falling back to a SystemClockDriver");
// Fall back to a driver using a normal thread.
mNextDriver = new SystemClockDriver(GraphImpl());
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd,
mStateComputedTime);
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mGraphImpl->SetCurrentDriver(mNextDriver);
DebugOnly<bool> found = mGraphImpl->RemoveMixerCallback(this);
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.
MonitorAutoLock mon(mGraphImpl->GetMonitor());
if (mNextDriver) {
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd,
mStateComputedTime);
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start();
} else {
@ -786,7 +773,8 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
AutoInCallback aic(this);
#endif
if (mStateComputedTime == 0) {
GraphTime stateComputedTime = StateComputedTime();
if (stateComputedTime == 0) {
MonitorAutoLock mon(mGraphImpl->GetMonitor());
// 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
@ -822,15 +810,15 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
// compute the iteration start and end from there, trying to keep the amount
// of buffering in the graph constant.
GraphTime nextStateComputedTime =
mGraphImpl->RoundUpToNextAudioBlock(mStateComputedTime + mBuffer.Available());
mGraphImpl->RoundUpToNextAudioBlock(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 = mStateComputedTime - mIterationStart;
GraphTime inGraph = stateComputedTime - mIterationStart;
// 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
// 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
@ -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",
(long)mIterationStart, (long)mIterationEnd,
(long)mStateComputedTime, (long)nextStateComputedTime,
(long)stateComputedTime, (long)nextStateComputedTime,
(long)aFrames, (uint32_t)durationMS,
(long)(nextStateComputedTime - mStateComputedTime)));
(long)(nextStateComputedTime - stateComputedTime)));
mCurrentTimeStamp = TimeStamp::Now();
if (mStateComputedTime < mIterationEnd) {
if (stateComputedTime < mIterationEnd) {
STREAM_LOG(LogLevel::Warning, ("Media graph global underrun detected"));
mIterationEnd = mStateComputedTime;
mIterationEnd = stateComputedTime;
}
stillProcessing = mGraphImpl->OneIteration(mIterationStart,
mIterationEnd,
mStateComputedTime,
stateComputedTime,
nextStateComputedTime);
} else {
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."));
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd,
mStateComputedTime);
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start();
// Returning less than aFrames starts the draining and eventually stops the
@ -979,8 +966,7 @@ AudioCallbackDriver::DeviceChangedCallback() {
mCallbackReceivedWhileSwitching = 0;
mGraphImpl->mFlushSourcesOnNextIteration = true;
mNextDriver = new SystemClockDriver(GraphImpl());
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd,
mStateComputedTime);
mNextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
mGraphImpl->SetCurrentDriver(mNextDriver);
mNextDriver->Start();
#endif

Просмотреть файл

@ -127,10 +127,6 @@ public:
return mIterationEnd;
}
GraphTime StateComputedTime() {
return mStateComputedTime;
}
virtual void GetAudioBuffer(float** aBuffer, long& aFrames) {
MOZ_CRASH("This is not an Audio GraphDriver!");
}
@ -155,15 +151,7 @@ public:
*/
void SetGraphTime(GraphDriver* aPreviousDriver,
GraphTime aLastSwitchNextIterationStart,
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);
GraphTime aLastSwitchNextIterationEnd);
/**
* Call this to indicate that another iteration of the control loop is
@ -190,12 +178,12 @@ public:
virtual bool OnThread() = 0;
protected:
GraphTime StateComputedTime() const;
// Time of the start of this graph iteration.
GraphTime mIterationStart;
// Time of the end of this graph iteration.
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
// than the driver, and will never be null.
MediaStreamGraphImpl* mGraphImpl;

Просмотреть файл

@ -171,8 +171,8 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
// the stream at all between mBlockingDecisionsMadeUntilTime and
// aDesiredUpToTime.
StreamTime t =
GraphTimeToStreamTime(aStream, CurrentDriver()->StateComputedTime()) +
(aDesiredUpToTime - CurrentDriver()->StateComputedTime());
GraphTimeToStreamTime(aStream, mStateComputedTime) +
(aDesiredUpToTime - mStateComputedTime);
STREAM_LOG(LogLevel::Verbose, ("Calling NotifyPull aStream=%p t=%f current end=%f", aStream,
MediaTimeToSeconds(t),
MediaTimeToSeconds(aStream->mBuffer.GetEnd())));
@ -254,7 +254,7 @@ StreamTime
MediaStreamGraphImpl::GraphTimeToStreamTime(MediaStream* aStream,
GraphTime aTime)
{
MOZ_ASSERT(aTime <= CurrentDriver()->StateComputedTime(),
MOZ_ASSERT(aTime <= mStateComputedTime,
"Don't ask about times where we haven't made blocking decisions yet");
if (aTime <= IterationEnd()) {
return std::max<StreamTime>(0, aTime - aStream->mBufferStartTime);
@ -275,7 +275,7 @@ StreamTime
MediaStreamGraphImpl::GraphTimeToStreamTimeOptimistic(MediaStream* aStream,
GraphTime aTime)
{
GraphTime computedUpToTime = std::min(CurrentDriver()->StateComputedTime(), aTime);
GraphTime computedUpToTime = std::min(mStateComputedTime, aTime);
StreamTime s = GraphTimeToStreamTime(aStream, computedUpToTime);
return s + (aTime - computedUpToTime);
}
@ -303,9 +303,9 @@ MediaStreamGraphImpl::StreamTimeToGraphTime(MediaStream* aStream,
}
bool blocked;
GraphTime end;
if (t < CurrentDriver()->StateComputedTime()) {
if (t < mStateComputedTime) {
blocked = aStream->mBlocked.GetAt(t, &end);
end = std::min(end, CurrentDriver()->StateComputedTime());
end = std::min(end, mStateComputedTime);
} else {
blocked = false;
end = GRAPH_TIME_MAX;
@ -752,7 +752,7 @@ MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions)
bool blockingDecisionsWillChange = false;
STREAM_LOG(LogLevel::Verbose, ("Media graph %p computing blocking for time %f",
this, MediaTimeToSeconds(CurrentDriver()->StateComputedTime())));
this, MediaTimeToSeconds(mStateComputedTime)));
nsTArray<MediaStream*>* runningAndSuspendedPair[2];
runningAndSuspendedPair[0] = &mStreams;
runningAndSuspendedPair[1] = &mSuspendedStreams;
@ -768,7 +768,7 @@ MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions)
AddBlockingRelatedStreamsToSet(&streamSet, stream);
GraphTime end;
for (GraphTime t = CurrentDriver()->StateComputedTime();
for (GraphTime t = mStateComputedTime;
t < aEndBlockingDecisions; t = end) {
end = GRAPH_TIME_MAX;
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",
this, MediaTimeToSeconds(CurrentDriver()->StateComputedTime()),
this, MediaTimeToSeconds(mStateComputedTime),
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) {
// 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
// the current state computed time.
GraphTime framePosition = IterationEnd() + MillisecondsToMediaTime(CurrentDriver()->IterationDuration());
if (framePosition > CurrentDriver()->StateComputedTime()) {
if (framePosition > mStateComputedTime) {
#ifdef DEBUG
if (std::abs(framePosition - CurrentDriver()->StateComputedTime()) >= MillisecondsToMediaTime(5)) {
if (std::abs(framePosition - mStateComputedTime) >= MillisecondsToMediaTime(5)) {
STREAM_LOG(LogLevel::Debug, ("Graph thread slowdown?"));
}
#endif
framePosition = CurrentDriver()->StateComputedTime();
framePosition = mStateComputedTime;
}
MOZ_ASSERT(framePosition >= aStream->mBufferStartTime, "frame position before buffer?");
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
// end up having aEndBlockingDecision == CurrentDriver()->StateComputedTime().
// end up having aEndBlockingDecision == mStateComputedTime.
// 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
// computed in next loop.
if (ensureNextIteration ||
aEndBlockingDecision == CurrentDriver()->StateComputedTime()) {
aEndBlockingDecision == mStateComputedTime) {
EnsureNextIteration();
}
@ -1904,7 +1912,7 @@ MediaStream::Init()
MediaStreamGraphImpl* graph = GraphImpl();
mBlocked.SetAtAndAfter(graph->IterationEnd(), true);
mExplicitBlockerCount.SetAtAndAfter(graph->IterationEnd(), true);
mExplicitBlockerCount.SetAtAndAfter(graph->CurrentDriver()->StateComputedTime(), false);
mExplicitBlockerCount.SetAtAndAfter(graph->mStateComputedTime, false);
}
MediaStreamGraphImpl*
@ -2139,7 +2147,7 @@ MediaStream::ChangeExplicitBlockerCount(int32_t aDelta)
virtual void Run()
{
mStream->ChangeExplicitBlockerCountImpl(
mStream->GraphImpl()->CurrentDriver()->StateComputedTime(), mDelta);
mStream->GraphImpl()->mStateComputedTime, mDelta);
}
int32_t mDelta;
};
@ -2162,7 +2170,7 @@ MediaStream::BlockStreamIfNeeded()
virtual void Run()
{
mStream->BlockStreamIfNeededImpl(
mStream->GraphImpl()->CurrentDriver()->StateComputedTime());
mStream->GraphImpl()->mStateComputedTime);
}
};
@ -2182,7 +2190,7 @@ MediaStream::UnblockStreamIfNeeded()
virtual void Run()
{
mStream->UnblockStreamIfNeededImpl(
mStream->GraphImpl()->CurrentDriver()->StateComputedTime());
mStream->GraphImpl()->mStateComputedTime);
}
};
@ -2635,7 +2643,7 @@ SourceMediaStream::GetBufferedTicks(TrackID aID)
MediaSegment* segment = track->GetSegment();
if (segment) {
return segment->GetDuration() -
GraphTimeToStreamTime(GraphImpl()->CurrentDriver()->StateComputedTime());
GraphTimeToStreamTime(GraphImpl()->mStateComputedTime);
}
}
return 0;
@ -3445,7 +3453,7 @@ MediaStreamGraph::StartNonRealtimeProcessing(uint32_t aTicksToProcess)
return;
graph->mEndTime =
graph->RoundUpToNextAudioBlock(graph->CurrentDriver()->StateComputedTime() +
graph->RoundUpToNextAudioBlock(graph->mStateComputedTime +
aTicksToProcess - 1);
graph->mNonRealtimeProcessing = true;
graph->EnsureRunInStableState();

Просмотреть файл

@ -561,6 +561,12 @@ public:
* cycles.
*/
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.
*/