Merge dup code at thread entry and param change
This CL is mostly just cleanup, but there are a couple of fixes marked "FIX" below. Merge the duplicate code that was at the beginning of threadLoop() and after a parameter change. cacheParameters_l() is now called at entry to threadLoop() and after any parameter change. It re-calculates all values that are derived from parameters, and caches them in instance variables. updateWaitTime_l(): - FIX activeSleepTime depends on mWaitTimeMs, which was initially set to infinity. updateWaitTime_l() was not called at entry to threadLoop(), so activeSleepTime was not set correctly before the first parameter change. - FIX reversed the order of calls after parameter change for the same reason so that updateWaitTime_l() is called before calculating values that are derived from wait time. - marked it private since now it's only called from DuplicatingThread Change-Id: If2607d2ed66c6893d910433e48208a93c41fb7e9
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user