diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 5188773cd086..6687fc70ecce 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -359,61 +359,54 @@ void MediaStreamGraphImpl::UpdateCurrentTimeForStreams(GraphTime aPrevCurrentTime, GraphTime aNextCurrentTime) { - nsTArray* runningAndSuspendedPair[2]; - runningAndSuspendedPair[0] = &mStreams; - runningAndSuspendedPair[1] = &mSuspendedStreams; - - for (uint32_t array = 0; array < 2; array++) { - for (uint32_t i = 0; i < runningAndSuspendedPair[array]->Length(); ++i) { - MediaStream* stream = (*runningAndSuspendedPair[array])[i]; - - // Calculate blocked time and fire Blocked/Unblocked events - GraphTime blockedTime = 0; - GraphTime t = aPrevCurrentTime; - // include |nextCurrentTime| to ensure NotifyBlockingChanged() is called - // before NotifyEvent(this, EVENT_FINISHED) when |nextCurrentTime == - // stream end time| - while (t <= aNextCurrentTime) { - GraphTime end; - bool blocked = stream->mBlocked.GetAt(t, &end); - if (blocked) { - blockedTime += std::min(end, aNextCurrentTime) - t; + for (MediaStream* stream : AllStreams()) { + // Calculate blocked time and fire Blocked/Unblocked events + GraphTime blockedTime = 0; + GraphTime t = aPrevCurrentTime; + // include |nextCurrentTime| to ensure NotifyBlockingChanged() is called + // before NotifyEvent(this, EVENT_FINISHED) when |nextCurrentTime == + // stream end time| + while (t <= aNextCurrentTime) { + GraphTime end; + bool blocked = stream->mBlocked.GetAt(t, &end); + if (blocked) { + blockedTime += std::min(end, aNextCurrentTime) - t; + } + if (blocked != stream->mNotifiedBlocked) { + for (uint32_t j = 0; j < stream->mListeners.Length(); ++j) { + MediaStreamListener* l = stream->mListeners[j]; + l->NotifyBlockingChanged(this, blocked + ? MediaStreamListener::BLOCKED + : MediaStreamListener::UNBLOCKED); } - if (blocked != stream->mNotifiedBlocked) { - for (uint32_t j = 0; j < stream->mListeners.Length(); ++j) { - MediaStreamListener* l = stream->mListeners[j]; - l->NotifyBlockingChanged(this, blocked - ? MediaStreamListener::BLOCKED - : MediaStreamListener::UNBLOCKED); - } - stream->mNotifiedBlocked = blocked; - } - t = end; + stream->mNotifiedBlocked = blocked; + } + t = end; + } + + stream->AdvanceTimeVaryingValuesToCurrentTime(aNextCurrentTime, + blockedTime); + // Advance mBlocked last so that AdvanceTimeVaryingValuesToCurrentTime + // can rely on the value of mBlocked. + stream->mBlocked.AdvanceCurrentTime(aNextCurrentTime); + + STREAM_LOG(LogLevel::Verbose, + ("MediaStream %p bufferStartTime=%f blockedTime=%f", stream, + MediaTimeToSeconds(stream->mBufferStartTime), + MediaTimeToSeconds(blockedTime))); + + if (mSuspendedStreams.IndexOf(stream) == mSuspendedStreams.NoIndex) { + bool streamHasOutput = blockedTime < aNextCurrentTime - aPrevCurrentTime; + NS_ASSERTION(!streamHasOutput || !stream->mNotifiedFinished, + "Shouldn't have already notified of finish *and* have output!"); + + if (streamHasOutput) { + StreamNotifyOutput(stream); } - stream->AdvanceTimeVaryingValuesToCurrentTime(aNextCurrentTime, - blockedTime); - // Advance mBlocked last so that AdvanceTimeVaryingValuesToCurrentTime - // can rely on the value of mBlocked. - stream->mBlocked.AdvanceCurrentTime(aNextCurrentTime); - - if (runningAndSuspendedPair[array] == &mStreams) { - bool streamHasOutput = blockedTime < aNextCurrentTime - aPrevCurrentTime; - NS_ASSERTION(!streamHasOutput || !stream->mNotifiedFinished, - "Shouldn't have already notified of finish *and* have output!"); - - if (streamHasOutput) { - StreamNotifyOutput(stream); - } - - if (stream->mFinished && !stream->mNotifiedFinished) { - StreamReadyToFinish(stream); - } + if (stream->mFinished && !stream->mNotifiedFinished) { + StreamReadyToFinish(stream); } - STREAM_LOG(LogLevel::Verbose, - ("MediaStream %p bufferStartTime=%f blockedTime=%f", stream, - MediaTimeToSeconds(stream->mBufferStartTime), - MediaTimeToSeconds(blockedTime))); } } } @@ -742,26 +735,19 @@ MediaStreamGraphImpl::RecomputeBlocking(GraphTime aEndBlockingDecisions) { STREAM_LOG(LogLevel::Verbose, ("Media graph %p computing blocking for time %f", this, MediaTimeToSeconds(mStateComputedTime))); - nsTArray* runningAndSuspendedPair[2]; - runningAndSuspendedPair[0] = &mStreams; - runningAndSuspendedPair[1] = &mSuspendedStreams; + for (MediaStream* stream : AllStreams()) { + if (!stream->mInBlockingSet) { + // Compute a partition of the streams containing 'stream' such that we + // can + // compute the blocking status of each subset independently. + nsAutoTArray streamSet; + AddBlockingRelatedStreamsToSet(&streamSet, stream); - for (uint32_t array = 0; array < 2; array++) { - for (uint32_t i = 0; i < (*runningAndSuspendedPair[array]).Length(); ++i) { - MediaStream* stream = (*runningAndSuspendedPair[array])[i]; - if (!stream->mInBlockingSet) { - // Compute a partition of the streams containing 'stream' such that we - // can - // compute the blocking status of each subset independently. - nsAutoTArray streamSet; - AddBlockingRelatedStreamsToSet(&streamSet, stream); - - GraphTime end; - for (GraphTime t = mStateComputedTime; - t < aEndBlockingDecisions; t = end) { - end = GRAPH_TIME_MAX; - RecomputeBlockingAt(streamSet, t, aEndBlockingDecisions, &end); - } + GraphTime end; + for (GraphTime t = mStateComputedTime; + t < aEndBlockingDecisions; t = end) { + end = GRAPH_TIME_MAX; + RecomputeBlockingAt(streamSet, t, aEndBlockingDecisions, &end); } } } @@ -3192,19 +3178,12 @@ void MediaStreamGraphImpl::ResetVisitedStreamState() { // Reset the visited/consumed/blocked state of the streams. - nsTArray* runningAndSuspendedPair[2]; - runningAndSuspendedPair[0] = &mStreams; - runningAndSuspendedPair[1] = &mSuspendedStreams; - - for (uint32_t array = 0; array < 2; array++) { - for (uint32_t i = 0; i < runningAndSuspendedPair[array]->Length(); ++i) { - ProcessedMediaStream* ps = - (*runningAndSuspendedPair[array])[i]->AsProcessedStream(); - if (ps) { - ps->mCycleMarker = NOT_VISITED; - ps->mIsConsumed = false; - ps->mInBlockingSet = false; - } + for (MediaStream* stream : AllStreams()) { + ProcessedMediaStream* ps = stream->AsProcessedStream(); + if (ps) { + ps->mCycleMarker = NOT_VISITED; + ps->mIsConsumed = false; + ps->mInBlockingSet = false; } } } diff --git a/dom/media/MediaStreamGraphImpl.h b/dom/media/MediaStreamGraphImpl.h index bba585e2372a..2bc5bebef0fe 100644 --- a/dom/media/MediaStreamGraphImpl.h +++ b/dom/media/MediaStreamGraphImpl.h @@ -528,6 +528,56 @@ public: already_AddRefed ConnectToCaptureStream(uint64_t aWindowId, MediaStream* aMediaStream); + class StreamSet { + public: + class iterator { + public: + explicit iterator(MediaStreamGraphImpl& aGraph) + : mGraph(&aGraph), mArrayNum(-1), mArrayIndex(0) + { + ++(*this); + } + iterator() : mGraph(nullptr), mArrayNum(2), mArrayIndex(0) {} + MediaStream* operator*() + { + return Array()->ElementAt(mArrayIndex); + } + iterator operator++() + { + ++mArrayIndex; + while (mArrayNum < 2 && + (mArrayNum < 0 || mArrayIndex >= Array()->Length())) { + ++mArrayNum; + mArrayIndex = 0; + } + return *this; + } + bool operator==(const iterator& aOther) const + { + return mArrayNum == aOther.mArrayNum && mArrayIndex == aOther.mArrayIndex; + } + bool operator!=(const iterator& aOther) const + { + return !(*this == aOther); + } + private: + nsTArray* Array() + { + return mArrayNum == 0 ? &mGraph->mStreams : &mGraph->mSuspendedStreams; + } + MediaStreamGraphImpl* mGraph; + int mArrayNum; + uint32_t mArrayIndex; + }; + + explicit StreamSet(MediaStreamGraphImpl& aGraph) : mGraph(aGraph) {} + iterator begin() { return iterator(mGraph); } + iterator end() { return iterator(); } + private: + MediaStreamGraphImpl& mGraph; + }; + StreamSet AllStreams() { return StreamSet(*this); } + // Data members // /**