зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1189506. Simplify blocking calculations based on the observation that once a stream starts blocking in a given processing interval, it must stay blocked. r=karlt
--HG-- extra : commitid : 2gcihxVXqlY extra : rebase_source : dfb0bf716b8608a47fef25838c3fccdf132e0f82
This commit is contained in:
Родитель
2e597371be
Коммит
d18eba5a82
|
@ -399,15 +399,15 @@ MediaStreamGraphImpl::UpdateCurrentTimeForStreams(GraphTime aPrevCurrentTime,
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MediaStreamGraphImpl::WillUnderrun(MediaStream* aStream, GraphTime aTime,
|
||||
GraphTime aEndBlockingDecisions, GraphTime* aEnd)
|
||||
GraphTime
|
||||
MediaStreamGraphImpl::WillUnderrun(MediaStream* aStream,
|
||||
GraphTime aEndBlockingDecisions)
|
||||
{
|
||||
// Finished streams can't underrun. ProcessedMediaStreams also can't cause
|
||||
// underrun currently, since we'll always be able to produce data for them
|
||||
// unless they block on some other stream.
|
||||
if (aStream->mFinished || aStream->AsProcessedStream()) {
|
||||
return false;
|
||||
return aEndBlockingDecisions;
|
||||
}
|
||||
GraphTime bufferEnd =
|
||||
StreamTimeToGraphTime(aStream, aStream->GetBufferEnd(),
|
||||
|
@ -422,27 +422,7 @@ MediaStreamGraphImpl::WillUnderrun(MediaStream* aStream, GraphTime aTime,
|
|||
NS_ASSERTION(bufferEnd >= mProcessedTime, "Buffer underran");
|
||||
}
|
||||
#endif
|
||||
// We should block after bufferEnd.
|
||||
if (bufferEnd <= aTime) {
|
||||
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p will block due to data underrun at %ld, "
|
||||
"bufferEnd %ld",
|
||||
aStream, aTime, bufferEnd));
|
||||
return true;
|
||||
}
|
||||
// We should keep blocking if we're currently blocked and we don't have
|
||||
// data all the way through to aEndBlockingDecisions. If we don't have
|
||||
// data all the way through to aEndBlockingDecisions, we'll block soon,
|
||||
// but we might as well remain unblocked and play the data we've got while
|
||||
// we can.
|
||||
if (bufferEnd < aEndBlockingDecisions && aStream->mBlocked.GetBefore(aTime)) {
|
||||
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p will block due to speculative data underrun, "
|
||||
"bufferEnd %f (end at %ld)",
|
||||
aStream, MediaTimeToSeconds(bufferEnd), bufferEnd));
|
||||
return true;
|
||||
}
|
||||
// Reconsider decisions at bufferEnd
|
||||
*aEnd = std::min(*aEnd, bufferEnd);
|
||||
return false;
|
||||
return std::min(bufferEnd, aEndBlockingDecisions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -715,12 +695,10 @@ MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions)
|
|||
STREAM_LOG(LogLevel::Verbose, ("Media graph %p computing blocking for time %f",
|
||||
this, MediaTimeToSeconds(mStateComputedTime)));
|
||||
for (MediaStream* stream : AllStreams()) {
|
||||
GraphTime end;
|
||||
for (GraphTime t = mStateComputedTime;
|
||||
t < aEndBlockingDecisions; t = end) {
|
||||
end = GRAPH_TIME_MAX;
|
||||
RecomputeBlockingAt(stream, t, aEndBlockingDecisions, &end);
|
||||
}
|
||||
GraphTime blockTime =
|
||||
ComputeStreamBlockTime(stream, mStateComputedTime, aEndBlockingDecisions);
|
||||
stream->mBlocked.SetAtAndAfter(mStateComputedTime, false);
|
||||
stream->mBlocked.SetAtAndAfter(blockTime, true);
|
||||
}
|
||||
STREAM_LOG(LogLevel::Verbose, ("Media graph %p computed blocking for interval %f to %f",
|
||||
this, MediaTimeToSeconds(mStateComputedTime),
|
||||
|
@ -734,50 +712,32 @@ MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions)
|
|||
mStateComputedTime = aEndBlockingDecisions;
|
||||
}
|
||||
|
||||
void
|
||||
MediaStreamGraphImpl::RecomputeBlockingAt(MediaStream* aStream,
|
||||
GraphTime aTime,
|
||||
GraphTime aEndBlockingDecisions,
|
||||
GraphTime* aEnd)
|
||||
GraphTime
|
||||
MediaStreamGraphImpl::ComputeStreamBlockTime(MediaStream* aStream,
|
||||
GraphTime aTime,
|
||||
GraphTime aEndBlockingDecisions)
|
||||
{
|
||||
bool block = false;
|
||||
|
||||
do {
|
||||
if (aStream->mFinished) {
|
||||
GraphTime endTime = StreamTimeToGraphTime(aStream,
|
||||
aStream->GetStreamBuffer().GetAllTracksEnd());
|
||||
if (endTime <= aTime) {
|
||||
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p is blocked due to being finished", aStream));
|
||||
// We'll block indefinitely
|
||||
block = true;
|
||||
*aEnd = std::min(*aEnd, aEndBlockingDecisions);
|
||||
continue;
|
||||
} else {
|
||||
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p is finished, but not blocked yet (end at %f, with blocking at %f)",
|
||||
aStream, MediaTimeToSeconds(aStream->GetBufferEnd()),
|
||||
MediaTimeToSeconds(endTime)));
|
||||
*aEnd = std::min(*aEnd, endTime);
|
||||
}
|
||||
if (aStream->mFinished) {
|
||||
GraphTime endTime = StreamTimeToGraphTime(aStream,
|
||||
aStream->GetStreamBuffer().GetAllTracksEnd());
|
||||
if (endTime <= aTime) {
|
||||
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p is blocked due to being finished", aStream));
|
||||
return aTime;
|
||||
} else {
|
||||
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p is finished, but not blocked yet (end at %f, with blocking at %f)",
|
||||
aStream, MediaTimeToSeconds(aStream->GetBufferEnd()),
|
||||
MediaTimeToSeconds(endTime)));
|
||||
// Data can't be added to a finished stream, so underruns are irrelevant.
|
||||
return std::min(endTime, aEndBlockingDecisions);
|
||||
}
|
||||
}
|
||||
|
||||
if (aStream->IsSuspended()) {
|
||||
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p is blocked due to being suspended", aStream));
|
||||
block = true;
|
||||
continue;
|
||||
}
|
||||
if (aStream->IsSuspended()) {
|
||||
STREAM_LOG(LogLevel::Verbose, ("MediaStream %p is blocked due to being suspended", aStream));
|
||||
return aTime;
|
||||
}
|
||||
|
||||
bool underrun = WillUnderrun(aStream, aTime, aEndBlockingDecisions, aEnd);
|
||||
if (underrun) {
|
||||
// We'll block indefinitely
|
||||
block = true;
|
||||
*aEnd = std::min(*aEnd, aEndBlockingDecisions);
|
||||
continue;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
NS_ASSERTION(*aEnd > aTime, "Failed to advance!");
|
||||
|
||||
aStream->mBlocked.SetAtAndAfter(aTime, block);
|
||||
return WillUnderrun(aStream, aEndBlockingDecisions);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -310,9 +310,9 @@ public:
|
|||
* in the future, *aEnd will be reduced to the first time in the future to
|
||||
* recompute those decisions.
|
||||
*/
|
||||
void RecomputeBlockingAt(MediaStream* aStream,
|
||||
GraphTime aTime, GraphTime aEndBlockingDecisions,
|
||||
GraphTime* aEnd);
|
||||
GraphTime ComputeStreamBlockTime(MediaStream* aStream,
|
||||
GraphTime aTime,
|
||||
GraphTime aEndBlockingDecisions);
|
||||
/**
|
||||
* Returns smallest value of t such that t is a multiple of
|
||||
* WEBAUDIO_BLOCK_SIZE and t > aTime.
|
||||
|
@ -329,13 +329,11 @@ public:
|
|||
GraphTime aFrom,
|
||||
GraphTime aTo);
|
||||
/**
|
||||
* Returns true if aStream will underrun at aTime for its own playback.
|
||||
* aEndBlockingDecisions is when we plan to stop making blocking decisions.
|
||||
* *aEnd will be reduced to the first time in the future to recompute these
|
||||
* decisions.
|
||||
* If aStream will underrun between aTime, and aEndBlockingDecisions, returns
|
||||
* the time at which the underrun will start. Otherwise return
|
||||
* aEndBlockingDecisions.
|
||||
*/
|
||||
bool WillUnderrun(MediaStream* aStream, GraphTime aTime,
|
||||
GraphTime aEndBlockingDecisions, GraphTime* aEnd);
|
||||
GraphTime WillUnderrun(MediaStream* aStream, GraphTime aEndBlockingDecisions);
|
||||
|
||||
/**
|
||||
* Given a graph time aTime, convert it to a stream time taking into
|
||||
|
|
Загрузка…
Ссылка в новой задаче