bug 1217625 perform checks for transition to inactive outside of stream processing r=padenot

This will allow streams to be suspended when they are discovered inactive.
Suspending is not possible while iterating over stream lists for processing.

The approach of delaying the transition to inactive state may result in a
couple of extra processing iterations, but can save on the number of messages
that need to be created when compared to the approach of traversing downstream
nodes during stream processing.

--HG--
extra : rebase_source : b6707da5afa9323058b3f70b7743c13380618dad
This commit is contained in:
Karl Tomlinson 2015-10-23 09:37:45 +13:00
parent 008976864a
commit e6e2a0f9e8
7 changed files with 44 additions and 11 deletions

View File

@ -72,7 +72,7 @@ public:
if (mChunksToProcess <= 0) {
if (mChunksToProcess != INT32_MIN) {
mChunksToProcess = INT32_MIN;
aStream->CheckForInactive();
aStream->ScheduleCheckForInactive();
}
return;
}

View File

@ -576,7 +576,9 @@ AudioNodeStream::ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags)
}
if (finished) {
mMarkAsFinishedAfterThisBlock = true;
CheckForInactive();
if (mIsActive) {
ScheduleCheckForInactive();
}
}
if (mDisabledTrackIDs.Contains(static_cast<TrackID>(AUDIO_TRACK))) {
@ -707,6 +709,29 @@ AudioNodeStream::SetActive()
}
}
class AudioNodeStream::CheckForInactiveMessage final : public ControlMessage
{
public:
explicit CheckForInactiveMessage(AudioNodeStream* aStream) :
ControlMessage(aStream) {}
virtual void Run() override
{
auto ns = static_cast<AudioNodeStream*>(mStream);
ns->CheckForInactive();
}
};
void
AudioNodeStream::ScheduleCheckForInactive()
{
if (mActiveInputCount > 0 && !mMarkAsFinishedAfterThisBlock) {
return;
}
nsAutoPtr<CheckForInactiveMessage> message(new CheckForInactiveMessage(this));
GraphImpl()->RunMessageAfterProcessing(Move(message));
}
void
AudioNodeStream::CheckForInactive()
{

View File

@ -164,6 +164,19 @@ public:
* active.
*/
void SetActive();
/*
* ScheduleCheckForInactive() is called during stream processing when the
* engine transitions from active to inactive, or the stream finishes. It
* schedules a call to CheckForInactive() after stream processing.
*/
void ScheduleCheckForInactive();
protected:
class AdvanceAndResumeMessage;
class CheckForInactiveMessage;
virtual void DestroyImpl() override;
/*
* CheckForInactive() is called when the engine transitions from active to
* inactive, or an active input is removed, or the stream finishes. If the
@ -173,11 +186,6 @@ public:
*/
void CheckForInactive();
protected:
class AdvanceAndResumeMessage;
virtual void DestroyImpl() override;
void AdvanceOutputSegment();
void FinishOutput();
void AccumulateInputChunk(uint32_t aInputIndex, const AudioBlock& aChunk,

View File

@ -149,7 +149,7 @@ public:
if (!hasTail) {
if (!mBiquads.IsEmpty()) {
mBiquads.Clear();
aStream->CheckForInactive();
aStream->ScheduleCheckForInactive();
RefPtr<PlayingRefChangeHandler> refchanged =
new PlayingRefChangeHandler(aStream, PlayingRefChangeHandler::RELEASE);

View File

@ -121,7 +121,7 @@ public:
} else {
if (mLeftOverData != INT32_MIN) {
mLeftOverData = INT32_MIN;
aStream->CheckForInactive();
aStream->ScheduleCheckForInactive();
RefPtr<PlayingRefChanged> refchanged =
new PlayingRefChanged(aStream, PlayingRefChanged::RELEASE);
aStream->Graph()->

View File

@ -91,7 +91,7 @@ public:
} else {
if (mLeftOverData != INT32_MIN) {
mLeftOverData = INT32_MIN;
aStream->CheckForInactive();
aStream->ScheduleCheckForInactive();
// Delete our buffered data now we no longer need it
mBuffer.Reset();

View File

@ -150,7 +150,7 @@ public:
} else {
if (mLeftOverData != INT_MIN) {
mLeftOverData = INT_MIN;
aStream->CheckForInactive();
aStream->ScheduleCheckForInactive();
mHRTFPanner->reset();
RefPtr<PlayingRefChangeHandler> refchanged =