Bug 848954 - Part 15 - Allow an AudioCallbackDriver to sleep to save power. r=roc

This commit is contained in:
Paul Adenot 2014-08-26 17:02:08 +02:00
Родитель a61c50b315
Коммит 4dffa09424
4 изменённых файлов: 24 добавлений и 55 удалений

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

@ -331,7 +331,6 @@ SystemClockDriver::WaitForNextIteration()
mWaitState = WAITSTATE_WAITING_FOR_NEXT_ITERATION; mWaitState = WAITSTATE_WAITING_FOR_NEXT_ITERATION;
} else { } else {
mWaitState = WAITSTATE_WAITING_INDEFINITELY; mWaitState = WAITSTATE_WAITING_INDEFINITELY;
mGraphImpl->PausedIndefinitly();
} }
if (timeout > 0) { if (timeout > 0) {
mGraphImpl->GetMonitor().Wait(timeout); mGraphImpl->GetMonitor().Wait(timeout);
@ -340,7 +339,6 @@ SystemClockDriver::WaitForNextIteration()
(TimeStamp::Now() - now).ToSeconds())); (TimeStamp::Now() - now).ToSeconds()));
} }
mGraphImpl->ResumedFromPaused();
mWaitState = WAITSTATE_RUNNING; mWaitState = WAITSTATE_RUNNING;
mNeedAnotherIteration = false; mNeedAnotherIteration = false;
} }
@ -445,6 +443,13 @@ AsyncCubebTask::Run()
mDriver->Stop(); mDriver->Stop();
mDriver = nullptr; mDriver = nullptr;
break; break;
case AsyncCubebOperation::SLEEP: {
MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
mDriver->Stop();
mDriver->mGraphImpl->GetMonitor().Wait(PR_INTERVAL_NO_TIMEOUT);
STREAM_LOG(PR_LOG_DEBUG, ("Restarting audio stream from sleep."));
mDriver->Start();
}
default: default:
MOZ_CRASH("Operation not implemented."); MOZ_CRASH("Operation not implemented.");
} }
@ -602,6 +607,19 @@ AudioCallbackDriver::GetCurrentTime()
return mSampleRate * position; return mSampleRate * position;
} }
void AudioCallbackDriver::WaitForNextIteration()
{
// We can't block on the monitor in the audio callback, so we kick off a new
// thread that will pause the audio stream, and restart it when unblocked.
if (!mNeedAnotherIteration) {
mWaitState = WAITSTATE_WAITING_INDEFINITELY;
STREAM_LOG(PR_LOG_DEBUG+1, ("AudioCallbackDriver going to sleep"));
nsRefPtr<AsyncCubebTask> sleepEvent =
new AsyncCubebTask(this, AsyncCubebTask::SLEEP);
sleepEvent->Dispatch();
}
}
void void
AudioCallbackDriver::WakeUp() AudioCallbackDriver::WakeUp()
{ {
@ -720,6 +738,7 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames)
mBuffer.BufferFilled(); mBuffer.BufferFilled();
} }
WaitForNextIteration();
if (mNextDriver && stillProcessing) { if (mNextDriver && stillProcessing) {
{ {

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

@ -340,7 +340,8 @@ class AsyncCubebTask : public nsRunnable
public: public:
enum AsyncCubebOperation { enum AsyncCubebOperation {
INIT, INIT,
SHUTDOWN SHUTDOWN,
SLEEP
}; };
@ -406,7 +407,7 @@ public:
virtual void GetIntervalForIteration(GraphTime& aFrom, virtual void GetIntervalForIteration(GraphTime& aFrom,
GraphTime& aTo) MOZ_OVERRIDE; GraphTime& aTo) MOZ_OVERRIDE;
virtual GraphTime GetCurrentTime() MOZ_OVERRIDE; virtual GraphTime GetCurrentTime() MOZ_OVERRIDE;
virtual void WaitForNextIteration() MOZ_OVERRIDE { } virtual void WaitForNextIteration() MOZ_OVERRIDE;
virtual void WakeUp() MOZ_OVERRIDE; virtual void WakeUp() MOZ_OVERRIDE;
/* Static wrapper function cubeb calls back. */ /* Static wrapper function cubeb calls back. */

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

@ -1227,42 +1227,6 @@ MediaStreamGraphImpl::AllFinishedStreamsNotified()
return true; return true;
} }
void MediaStreamGraphImpl::PausedIndefinitly()
{
PauseAllAudioOutputs();
}
void MediaStreamGraphImpl::ResumedFromPaused()
{
ResumeAllAudioOutputs();
}
void
MediaStreamGraphImpl::PauseAllAudioOutputs()
{
if (mAudioOutputsPaused) {
return;
}
if (mMixedAudioStream) {
mMixedAudioStream->Pause();
}
mAudioOutputsPaused = true;
}
void
MediaStreamGraphImpl::ResumeAllAudioOutputs()
{
if (!mAudioOutputsPaused) {
return;
}
if (mMixedAudioStream) {
mMixedAudioStream->Resume();
}
mAudioOutputsPaused = false;
}
void void
MediaStreamGraphImpl::UpdateGraph(GraphTime aEndBlockingDecision) MediaStreamGraphImpl::UpdateGraph(GraphTime aEndBlockingDecision)
{ {
@ -2698,7 +2662,6 @@ MediaStreamGraphImpl::MediaStreamGraphImpl(bool aRealtime,
, mSelfRef(MOZ_THIS_IN_INITIALIZER_LIST()) , mSelfRef(MOZ_THIS_IN_INITIALIZER_LIST())
, mAudioStreamSizes() , mAudioStreamSizes()
, mNeedsMemoryReport(false) , mNeedsMemoryReport(false)
, mAudioOutputsPaused(false)
#ifdef DEBUG #ifdef DEBUG
, mCanRunMessagesSynchronously(false) , mCanRunMessagesSynchronously(false)
#endif #endif

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

@ -371,14 +371,6 @@ public:
{ {
mStreamOrderDirty = true; mStreamOrderDirty = true;
} }
/**
* Pause all AudioStreams being written to by MediaStreams
*/
void PauseAllAudioOutputs();
/**
* Resume all AudioStreams being written to by MediaStreams
*/
void ResumeAllAudioOutputs();
TrackRate AudioSampleRate() const { return mSampleRate; } TrackRate AudioSampleRate() const { return mSampleRate; }
TrackRate GraphRate() const { return mSampleRate; } TrackRate GraphRate() const { return mSampleRate; }
@ -634,12 +626,6 @@ private:
*/ */
bool mNeedsMemoryReport; bool mNeedsMemoryReport;
/**
* True if the audio outputs are paused because they would output silence
* anyway.
*/
bool mAudioOutputsPaused;
#ifdef DEBUG #ifdef DEBUG
/** /**
* Used to assert when AppendMessage() runs ControlMessages synchronously. * Used to assert when AppendMessage() runs ControlMessages synchronously.