зеркало из https://github.com/mozilla/gecko-dev.git
Bug 848954 - Part 15 - Allow an AudioCallbackDriver to sleep to save power. r=roc
This commit is contained in:
Родитель
a61c50b315
Коммит
4dffa09424
|
@ -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.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче