Merge "Merge dup code at thread entry and param change"
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f94ab84..2f49808 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1464,7 +1464,8 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
sleepTimeShift--;
}
sleepTime = 0;
- standbyTime = systemTime() + mStandbyTimeInNsecs;
+ standbyTime = systemTime() + standbyDelay;
//TODO: delay standby when effects have a tail
}
@@ -2548,6 +2509,32 @@
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 @@
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 @@
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_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 @@
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
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 38fff8c..194b826 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -222,6 +222,8 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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: