зеркало из https://github.com/mozilla/gecko-dev.git
Bug 943461. Part 5: Don't allow a stream to finish before it has produced output up to mStateComputedTime. r=padenot
--HG-- extra : rebase_source : 9bf003c246b63b1dd64665024533fda74a8e1fa4
This commit is contained in:
Родитель
01835a84a4
Коммит
0e1cc53aae
|
@ -324,7 +324,8 @@ ConvertSegmentToAudioBlock(AudioSegment* aSegment, AudioChunk* aBlock)
|
|||
}
|
||||
|
||||
void
|
||||
AudioNodeExternalInputStream::ProduceOutput(GraphTime aFrom, GraphTime aTo)
|
||||
AudioNodeExternalInputStream::ProduceOutput(GraphTime aFrom, GraphTime aTo,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
// According to spec, number of outputs is always 1.
|
||||
mLastChunks.SetLength(1);
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
AudioNodeExternalInputStream(AudioNodeEngine* aEngine, TrackRate aSampleRate);
|
||||
~AudioNodeExternalInputStream();
|
||||
|
||||
virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo) MOZ_OVERRIDE;
|
||||
virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// For storing pointers and data about input tracks, like the last TrackTick which
|
||||
|
|
|
@ -399,16 +399,11 @@ AudioNodeStream::UpMixDownMixChunk(const AudioChunk* aChunk,
|
|||
// The MediaStreamGraph guarantees that this is actually one block, for
|
||||
// AudioNodeStreams.
|
||||
void
|
||||
AudioNodeStream::ProduceOutput(GraphTime aFrom, GraphTime aTo)
|
||||
AudioNodeStream::ProduceOutput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags)
|
||||
{
|
||||
if (mMarkAsFinishedAfterThisBlock) {
|
||||
// This stream was finished the last time that we looked at it, and all
|
||||
// of the depending streams have finished their output as well, so now
|
||||
// it's time to mark this stream as finished.
|
||||
FinishOutput();
|
||||
}
|
||||
|
||||
EnsureTrack(AUDIO_TRACK, mSampleRate);
|
||||
// No more tracks will be coming
|
||||
mBuffer.AdvanceKnownTracksTime(STREAM_TIME_MAX);
|
||||
|
||||
uint16_t outputCount = std::max(uint16_t(1), mEngine->OutputCount());
|
||||
mLastChunks.SetLength(outputCount);
|
||||
|
@ -446,7 +441,16 @@ AudioNodeStream::ProduceOutput(GraphTime aFrom, GraphTime aTo)
|
|||
}
|
||||
}
|
||||
|
||||
AdvanceOutputSegment();
|
||||
if (!IsFinishedOnGraphThread()) {
|
||||
// Don't output anything after we've finished!
|
||||
AdvanceOutputSegment();
|
||||
if (mMarkAsFinishedAfterThisBlock && (aFlags & ALLOW_FINISH)) {
|
||||
// This stream was finished the last time that we looked at it, and all
|
||||
// of the depending streams have finished their output as well, so now
|
||||
// it's time to mark this stream as finished.
|
||||
FinishOutput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -84,7 +84,7 @@ public:
|
|||
mAudioParamStream = true;
|
||||
}
|
||||
|
||||
virtual AudioNodeStream* AsAudioNodeStream() { return this; }
|
||||
virtual AudioNodeStream* AsAudioNodeStream() MOZ_OVERRIDE { return this; }
|
||||
|
||||
// Graph thread only
|
||||
void SetStreamTimeParameterImpl(uint32_t aIndex, MediaStream* aRelativeToStream,
|
||||
|
@ -92,7 +92,7 @@ public:
|
|||
void SetChannelMixingParametersImpl(uint32_t aNumberOfChannels,
|
||||
dom::ChannelCountMode aChannelCountMoe,
|
||||
dom::ChannelInterpretation aChannelInterpretation);
|
||||
virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo);
|
||||
virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) MOZ_OVERRIDE;
|
||||
TrackTicks GetCurrentPosition();
|
||||
bool IsAudioParamStream() const
|
||||
{
|
||||
|
|
|
@ -1092,7 +1092,7 @@ MediaStreamGraphImpl::ProduceDataForStreamsBlockByBlock(uint32_t aStreamIndex,
|
|||
for (uint32_t i = aStreamIndex; i < mStreams.Length(); ++i) {
|
||||
ProcessedMediaStream* ps = mStreams[i]->AsProcessedStream();
|
||||
if (ps) {
|
||||
ps->ProduceOutput(t, next);
|
||||
ps->ProduceOutput(t, next, (next == aTo) ? ProcessedMediaStream::ALLOW_FINISH : 0);
|
||||
}
|
||||
}
|
||||
t = next;
|
||||
|
@ -1197,7 +1197,8 @@ MediaStreamGraphImpl::RunThread()
|
|||
ticksProcessed += TimeToTicksRoundDown(n->SampleRate(), mStateComputedTime - prevComputedTime);
|
||||
doneAllProducing = true;
|
||||
} else {
|
||||
ps->ProduceOutput(prevComputedTime, mStateComputedTime);
|
||||
ps->ProduceOutput(prevComputedTime, mStateComputedTime,
|
||||
ProcessedMediaStream::ALLOW_FINISH);
|
||||
NS_ASSERTION(stream->mBuffer.GetEnd() >=
|
||||
GraphTimeToStreamTime(stream, mStateComputedTime),
|
||||
"Stream did not produce enough data");
|
||||
|
|
|
@ -958,10 +958,19 @@ public:
|
|||
* streams (mBlocked is up to date up to mStateComputedTime).
|
||||
* Also, we've produced output for all streams up to this one. If this stream
|
||||
* is not in a cycle, then all its source streams have produced data.
|
||||
* Generate output up to mStateComputedTime.
|
||||
* Generate output from aFrom to aTo.
|
||||
* This is called only on streams that have not finished.
|
||||
* ProduceOutput is allowed to call FinishOnGraphThread only if ALLOW_FINISH
|
||||
* is in aFlags. (This flag will be set when aTo >= mStateComputedTime, i.e.
|
||||
* when we've producing the last block of data we need to produce.) Otherwise
|
||||
* we can get into a situation where we've determined the stream should not
|
||||
* block before mStateComputedTime, but the stream finishes before
|
||||
* mStateComputedTime, violating the invariant that finished streams are blocked.
|
||||
*/
|
||||
virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo) = 0;
|
||||
enum {
|
||||
ALLOW_FINISH = 0x01
|
||||
};
|
||||
virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) = 0;
|
||||
void SetAutofinishImpl(bool aAutofinish) { mAutofinish = aAutofinish; }
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
mFilterCallback(nullptr),
|
||||
mMaxTrackID(0) {}
|
||||
|
||||
virtual void RemoveInput(MediaInputPort* aPort)
|
||||
virtual void RemoveInput(MediaInputPort* aPort) MOZ_OVERRIDE
|
||||
{
|
||||
for (int32_t i = mTrackMap.Length() - 1; i >= 0; --i) {
|
||||
if (mTrackMap[i].mInputPort == aPort) {
|
||||
|
@ -39,7 +39,7 @@ public:
|
|||
}
|
||||
ProcessedMediaStream::RemoveInput(aPort);
|
||||
}
|
||||
virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo)
|
||||
virtual void ProduceOutput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) MOZ_OVERRIDE
|
||||
{
|
||||
nsAutoTArray<bool,8> mappedTracksFinished;
|
||||
nsAutoTArray<bool,8> mappedTracksWithMatchingInputTracks;
|
||||
|
@ -95,7 +95,7 @@ public:
|
|||
mTrackMap.RemoveElementAt(i);
|
||||
}
|
||||
}
|
||||
if (allFinished && mAutofinish) {
|
||||
if (allFinished && mAutofinish && (aFlags & ALLOW_FINISH)) {
|
||||
// All streams have finished and won't add any more tracks, and
|
||||
// all our tracks have actually finished and been removed from our map,
|
||||
// so we're finished now.
|
||||
|
@ -117,7 +117,7 @@ public:
|
|||
|
||||
// Forward SetTrackEnabled(output_track_id, enabled) to the Source MediaStream,
|
||||
// translating the output track ID into the correct ID in the source.
|
||||
virtual void ForwardTrackEnabled(TrackID aOutputID, bool aEnabled) {
|
||||
virtual void ForwardTrackEnabled(TrackID aOutputID, bool aEnabled) MOZ_OVERRIDE {
|
||||
for (int32_t i = mTrackMap.Length() - 1; i >= 0; --i) {
|
||||
if (mTrackMap[i].mOutputTrackID == aOutputID) {
|
||||
mTrackMap[i].mInputPort->GetSource()->
|
||||
|
|
Загрузка…
Ссылка в новой задаче