Loading services/audioflinger/AudioFlinger.cpp +62 −48 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading @@ -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) { Loading @@ -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()) Loading @@ -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(); Loading Loading @@ -2103,16 +2072,8 @@ 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; } Loading Loading @@ -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 } Loading Loading @@ -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", Loading Loading @@ -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) Loading Loading @@ -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); } // ---------------------------------------------------------------------------- Loading Loading @@ -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); } Loading Loading @@ -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 Loading services/audioflinger/AudioFlinger.h +19 −4 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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() { } Loading Loading @@ -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; Loading Loading @@ -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() Loading @@ -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; }; Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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: Loading Loading
services/audioflinger/AudioFlinger.cpp +62 −48 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading @@ -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) { Loading @@ -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()) Loading @@ -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(); Loading Loading @@ -2103,16 +2072,8 @@ 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; } Loading Loading @@ -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 } Loading Loading @@ -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", Loading Loading @@ -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) Loading Loading @@ -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); } // ---------------------------------------------------------------------------- Loading Loading @@ -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); } Loading Loading @@ -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 Loading
services/audioflinger/AudioFlinger.h +19 −4 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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() { } Loading Loading @@ -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; Loading Loading @@ -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() Loading @@ -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; }; Loading @@ -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(); Loading @@ -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); Loading Loading @@ -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: Loading