Merge "Merge dup code at thread entry and param change"

This commit is contained in:
Glenn Kasten
2012-03-12 11:26:39 -07:00
committed by Android (Google) Code Review
2 changed files with 81 additions and 52 deletions

View File

@@ -1464,7 +1464,8 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
mMasterVolume(audioFlinger->masterVolumeSW_l()),
mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
// mMixerStatus
mPrevMixerStatus(MIXER_IDLE)
mPrevMixerStatus(MIXER_IDLE),
standbyDelay(AudioFlinger::mStandbyTimeInNsecs)
{
snprintf(mName, kNameLength, "AudioOut_%X", id);
@@ -1997,14 +1998,8 @@ bool AudioFlinger::PlaybackThread::threadLoop()
Vector< sp<Track> > tracksToRemove;
standbyTime = systemTime();
mixBufferSize = mFrameCount * mFrameSize;
// MIXER
// FIXME: Relaxed timing because of a certain device that can't meet latency
// Should be reduced to 2x after the vendor fixes the driver issue
// increase threshold again due to low power audio mode. The way this warning threshold is
// calculated and its usefulness should be reconsidered anyway.
nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
nsecs_t lastWarning = 0;
if (mType == MIXER) {
longStandbyExit = false;
@@ -2014,8 +2009,7 @@ if (mType == MIXER) {
// FIXME could this be made local to while loop?
writeFrames = 0;
activeSleepTime = activeSleepTimeUs();
idleSleepTime = idleSleepTimeUs();
cacheParameters_l();
sleepTime = idleSleepTime;
if (mType == MIXER) {
@@ -2025,13 +2019,6 @@ if (mType == MIXER) {
// MIXER
CpuStats cpuStats;
// DIRECT
if (mType == DIRECT) {
// use shorter standby delay as on normal output to release
// hardware resources as soon as possible
standbyDelay = microseconds(activeSleepTime*2);
}
acquireWakeLock();
while (!exitPending())
@@ -2050,25 +2037,7 @@ if (mType == MIXER) {
Mutex::Autolock _l(mLock);
if (checkForNewParameters_l()) {
mixBufferSize = mFrameCount * mFrameSize;
if (mType == MIXER) {
// FIXME: Relaxed timing because of a certain device that can't meet latency
// Should be reduced to 2x after the vendor fixes the driver issue
// increase threshold again due to low power audio mode. The way this warning
// threshold is calculated and its usefulness should be reconsidered anyway.
maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
}
updateWaitTime_l();
activeSleepTime = activeSleepTimeUs();
idleSleepTime = idleSleepTimeUs();
if (mType == DIRECT) {
standbyDelay = microseconds(activeSleepTime*2);
}
cacheParameters_l();
}
saveOutputTracks();
@@ -2103,19 +2072,11 @@ if (mType == DIRECT) {
checkSilentMode_l();
if (mType == MIXER || mType == DUPLICATING) {
standbyTime = systemTime() + mStandbyTimeInNsecs;
}
if (mType == DIRECT) {
standbyTime = systemTime() + standbyDelay;
}
sleepTime = idleSleepTime;
if (mType == MIXER) {
sleepTimeShift = 0;
}
if (mType == MIXER) {
sleepTimeShift = 0;
}
continue;
}
@@ -2261,7 +2222,7 @@ void AudioFlinger::MixerThread::threadLoop_mix()
sleepTimeShift--;
}
sleepTime = 0;
standbyTime = systemTime() + mStandbyTimeInNsecs;
standbyTime = systemTime() + standbyDelay;
//TODO: delay standby when effects have a tail
}
@@ -2548,6 +2509,32 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
return mixerStatus;
}
/*
The derived values that are cached:
- mixBufferSize from frame count * frame size
- activeSleepTime from activeSleepTimeUs()
- idleSleepTime from idleSleepTimeUs()
- standbyDelay from mActiveSleepTimeUs (DIRECT only)
- maxPeriod from frame count and sample rate (MIXER only)
The parameters that affect these derived values are:
- frame count
- frame size
- sample rate
- device type: A2DP or not
- device latency
- format: PCM or not
- active sleep time
- idle sleep time
*/
void AudioFlinger::PlaybackThread::cacheParameters_l()
{
mixBufferSize = mFrameCount * mFrameSize;
activeSleepTime = activeSleepTimeUs();
idleSleepTime = idleSleepTimeUs();
}
void AudioFlinger::MixerThread::invalidateTracks(audio_stream_type_t streamType)
{
ALOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
@@ -2718,6 +2705,17 @@ uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs()
return (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000);
}
void AudioFlinger::MixerThread::cacheParameters_l()
{
PlaybackThread::cacheParameters_l();
// FIXME: Relaxed timing because of a certain device that can't meet latency
// Should be reduced to 2x after the vendor fixes the driver issue
// increase threshold again due to low power audio mode. The way this warning
// threshold is calculated and its usefulness should be reconsidered anyway.
maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
}
// ----------------------------------------------------------------------------
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
AudioStreamOut* output, audio_io_handle_t id, uint32_t device)
@@ -3074,6 +3072,14 @@ uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs()
return time;
}
void AudioFlinger::DirectOutputThread::cacheParameters_l()
{
PlaybackThread::cacheParameters_l();
// use shorter standby delay as on normal output to release
// hardware resources as soon as possible
standbyDelay = microseconds(activeSleepTime*2);
}
// ----------------------------------------------------------------------------
@@ -3127,7 +3133,7 @@ void AudioFlinger::DuplicatingThread::threadLoop_sleepTime()
void AudioFlinger::DuplicatingThread::threadLoop_write()
{
standbyTime = systemTime() + mStandbyTimeInNsecs;
standbyTime = systemTime() + standbyDelay;
for (size_t i = 0; i < outputTracks.size(); i++) {
outputTracks[i]->write(mMixBuffer, writeFrames);
}
@@ -3223,6 +3229,14 @@ uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs()
return (mWaitTimeMs * 1000) / 2;
}
void AudioFlinger::DuplicatingThread::cacheParameters_l()
{
// updateWaitTime_l() sets mWaitTimeMs, which affects activeSleepTimeUs(), so call it first
updateWaitTime_l();
MixerThread::cacheParameters_l();
}
// ----------------------------------------------------------------------------
// TrackBase constructor must be called with AudioFlinger::mLock held

View File

@@ -222,6 +222,8 @@ private:
audio_hw_device_t* findSuitableHwDev_l(uint32_t devices);
void purgeStaleEffects_l();
// standby delay for MIXER and DUPLICATING playback threads is read from property
// ro.audio.flinger_standbytime_ms or defaults to kDefaultStandbyTimeInNsecs
static nsecs_t mStandbyTimeInNsecs;
// Internal dump utilites.
@@ -840,9 +842,6 @@ protected:
virtual void threadLoop_write();
virtual void threadLoop_standby();
// Non-trivial for DUPLICATING only
virtual void updateWaitTime_l() { }
// Non-trivial for DIRECT only
virtual void applyVolume() { }
@@ -929,6 +928,9 @@ public:
virtual void saveOutputTracks() { }
virtual void clearOutputTracks() { }
// Cache various calculated values, at threadLoop() entry and after a parameter change
virtual void cacheParameters_l();
private:
friend class AudioFlinger;
@@ -964,8 +966,11 @@ public:
// FIXME rename these former local variables of threadLoop to standard "m" names
nsecs_t standbyTime;
size_t mixBufferSize;
// cached copies of activeSleepTimeUs() and idleSleepTimeUs() made by cacheParameters_l()
uint32_t activeSleepTime;
uint32_t idleSleepTime;
uint32_t sleepTime;
// mixer status returned by prepareTracks_l()
@@ -976,8 +981,13 @@ public:
// MIXER only
bool longStandbyExit;
uint32_t sleepTimeShift;
// DIRECT only
// same as AudioFlinger::mStandbyTimeInNsecs except for DIRECT which uses a shorter value
nsecs_t standbyDelay;
// MIXER only
nsecs_t maxPeriod;
// DUPLICATING only
uint32_t writeFrames;
};
@@ -1003,6 +1013,7 @@ public:
virtual void deleteTrackName_l(int name);
virtual uint32_t idleSleepTimeUs();
virtual uint32_t suspendSleepTimeUs();
virtual void cacheParameters_l();
// threadLoop snippets
virtual void threadLoop_mix();
@@ -1028,6 +1039,7 @@ public:
virtual uint32_t activeSleepTimeUs();
virtual uint32_t idleSleepTimeUs();
virtual uint32_t suspendSleepTimeUs();
virtual void cacheParameters_l();
// threadLoop snippets
virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
@@ -1075,9 +1087,12 @@ private:
virtual void threadLoop_sleepTime();
virtual void threadLoop_write();
virtual void threadLoop_standby();
virtual void cacheParameters_l();
private:
// called from threadLoop, addOutputTrack, removeOutputTrack
virtual void updateWaitTime_l();
protected:
virtual void saveOutputTracks();
virtual void clearOutputTracks();
private: