diff options
Diffstat (limited to 'services/audioflinger')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 174 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 14 |
2 files changed, 92 insertions, 96 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 4446681..30ed41d 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -432,6 +432,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( audio_format_t format, uint32_t channelMask, int frameCount, + // FIXME dead, remove from IAudioFlinger uint32_t flags, const sp<IMemory>& sharedBuffer, audio_io_handle_t output, @@ -1938,10 +1939,66 @@ AudioFlinger::MixerThread::~MixerThread() delete mAudioMixer; } +class CpuStats { +public: + void sample(); +#ifdef DEBUG_CPU_USAGE +private: + ThreadCpuUsage mCpu; +#endif +}; + +void CpuStats::sample() { +#ifdef DEBUG_CPU_USAGE + const CentralTendencyStatistics& stats = mCpu.statistics(); + mCpu.sampleAndEnable(); + unsigned n = stats.n(); + // mCpu.elapsed() is expensive, so don't call it every loop + if ((n & 127) == 1) { + long long elapsed = mCpu.elapsed(); + if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) { + double perLoop = elapsed / (double) n; + double perLoop100 = perLoop * 0.01; + double mean = stats.mean(); + double stddev = stats.stddev(); + double minimum = stats.minimum(); + double maximum = stats.maximum(); + mCpu.resetStatistics(); + ALOGI("CPU usage over past %.1f secs (%u mixer loops at %.1f mean ms per loop):\n us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f", + elapsed * .000000001, n, perLoop * .000001, + mean * .001, + stddev * .001, + minimum * .001, + maximum * .001, + mean / perLoop100, + stddev / perLoop100, + minimum / perLoop100, + maximum / perLoop100); + } + } +#endif +}; + +void AudioFlinger::PlaybackThread::checkSilentMode_l() +{ + if (!mMasterMute) { + char value[PROPERTY_VALUE_MAX]; + if (property_get("ro.audio.silent", value, "0") > 0) { + char *endptr; + unsigned long ul = strtoul(value, &endptr, 0); + if (*endptr == '\0' && ul != 0) { + ALOGD("Silence is golden"); + // The setprop command will not allow a property to be changed after + // the first time it is set, so we don't have to worry about un-muting. + setMasterMute_l(true); + } + } + } +} + bool AudioFlinger::MixerThread::threadLoop() { Vector< sp<Track> > tracksToRemove; - mixer_state mixerStatus = MIXER_IDLE; nsecs_t standbyTime = systemTime(); size_t mixBufferSize = mFrameCount * mFrameSize; // FIXME: Relaxed timing because of a certain device that can't meet latency @@ -1956,45 +2013,16 @@ bool AudioFlinger::MixerThread::threadLoop() uint32_t sleepTime = idleSleepTime; uint32_t sleepTimeShift = 0; Vector< sp<EffectChain> > effectChains; -#ifdef DEBUG_CPU_USAGE - ThreadCpuUsage cpu; - const CentralTendencyStatistics& stats = cpu.statistics(); -#endif + CpuStats cpuStats; acquireWakeLock(); while (!exitPending()) { -#ifdef DEBUG_CPU_USAGE - cpu.sampleAndEnable(); - unsigned n = stats.n(); - // cpu.elapsed() is expensive, so don't call it every loop - if ((n & 127) == 1) { - long long elapsed = cpu.elapsed(); - if (elapsed >= DEBUG_CPU_USAGE * 1000000000LL) { - double perLoop = elapsed / (double) n; - double perLoop100 = perLoop * 0.01; - double mean = stats.mean(); - double stddev = stats.stddev(); - double minimum = stats.minimum(); - double maximum = stats.maximum(); - cpu.resetStatistics(); - ALOGI("CPU usage over past %.1f secs (%u mixer loops at %.1f mean ms per loop):\n us per mix loop: mean=%.0f stddev=%.0f min=%.0f max=%.0f\n %% of wall: mean=%.1f stddev=%.1f min=%.1f max=%.1f", - elapsed * .000000001, n, perLoop * .000001, - mean * .001, - stddev * .001, - minimum * .001, - maximum * .001, - mean / perLoop100, - stddev / perLoop100, - minimum / perLoop100, - maximum / perLoop100); - } - } -#endif + cpuStats.sample(); processConfigEvents(); - mixerStatus = MIXER_IDLE; + mixer_state mixerStatus = MIXER_IDLE; { // scope for mLock Mutex::Autolock _l(mLock); @@ -2030,20 +2058,13 @@ bool AudioFlinger::MixerThread::threadLoop() releaseWakeLock_l(); // wait until we have something to do... - ALOGV("MixerThread %p TID %d going to sleep", this, gettid()); + ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid()); mWaitWorkCV.wait(mLock); - ALOGV("MixerThread %p TID %d waking up", this, gettid()); + ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid()); acquireWakeLock_l(); mPrevMixerStatus = MIXER_IDLE; - if (!mMasterMute) { - char value[PROPERTY_VALUE_MAX]; - property_get("ro.audio.silent", value, "0"); - if (atoi(value)) { - ALOGD("Silence is golden"); - setMasterMute_l(true); - } - } + checkSilentMode_l(); standbyTime = systemTime() + mStandbyTimeInNsecs; sleepTime = idleSleepTime; @@ -2168,7 +2189,7 @@ bool AudioFlinger::MixerThread::threadLoop() releaseWakeLock(); - ALOGV("MixerThread %p exiting", this); + ALOGV("Thread %p type %d exiting", this, mType); return false; } @@ -2686,7 +2707,6 @@ void AudioFlinger::DirectOutputThread::applyVolume(uint16_t leftVol, uint16_t ri bool AudioFlinger::DirectOutputThread::threadLoop() { - mixer_state mixerStatus = MIXER_IDLE; sp<Track> trackToRemove; sp<Track> activeTrack; nsecs_t standbyTime = systemTime(); @@ -2709,8 +2729,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() processConfigEvents(); - mixerStatus = MIXER_IDLE; - + mixer_state mixerStatus = MIXER_IDLE; { // scope for the mLock Mutex::Autolock _l(mLock); @@ -2727,7 +2746,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() mSuspended)) { // wait until we have something to do... if (!mStandby) { - ALOGV("Audio hardware entering standby, mixer %p", this); + ALOGV("Audio hardware entering standby, mixer %p, mSuspended %d", this, mSuspended); mOutput->stream->common.standby(&mOutput->stream->common); mStandby = true; mBytesWritten = 0; @@ -2740,19 +2759,12 @@ bool AudioFlinger::DirectOutputThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); - ALOGV("DirectOutputThread %p TID %d going to sleep", this, gettid()); + ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid()); mWaitWorkCV.wait(mLock); - ALOGV("DirectOutputThread %p TID %d waking up in active mode", this, gettid()); + ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid()); acquireWakeLock_l(); - if (!mMasterMute) { - char value[PROPERTY_VALUE_MAX]; - property_get("ro.audio.silent", value, "0"); - if (atoi(value)) { - ALOGD("Silence is golden"); - setMasterMute_l(true); - } - } + checkSilentMode_l(); standbyTime = systemTime() + standbyDelay; sleepTime = idleSleepTime; @@ -2966,7 +2978,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() releaseWakeLock(); - ALOGV("DirectOutputThread %p exiting", this); + ALOGV("Thread %p type %d exiting", this, mType); return false; } @@ -3083,7 +3095,6 @@ AudioFlinger::DuplicatingThread::~DuplicatingThread() bool AudioFlinger::DuplicatingThread::threadLoop() { Vector< sp<Track> > tracksToRemove; - mixer_state mixerStatus = MIXER_IDLE; nsecs_t standbyTime = systemTime(); size_t mixBufferSize = mFrameCount*mFrameSize; SortedVector< sp<OutputTrack> > outputTracks; @@ -3099,7 +3110,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop() { processConfigEvents(); - mixerStatus = MIXER_IDLE; + mixer_state mixerStatus = MIXER_IDLE; { // scope for the mLock Mutex::Autolock _l(mLock); @@ -3136,20 +3147,13 @@ bool AudioFlinger::DuplicatingThread::threadLoop() if (exitPending()) break; releaseWakeLock_l(); - ALOGV("DuplicatingThread %p TID %d going to sleep", this, gettid()); + // wait until we have something to do... + ALOGV("Thread %p type %d TID %d going to sleep", this, mType, gettid()); mWaitWorkCV.wait(mLock); - ALOGV("DuplicatingThread %p TID %d waking up", this, gettid()); + ALOGV("Thread %p type %d TID %d waking up", this, mType, gettid()); acquireWakeLock_l(); - mPrevMixerStatus = MIXER_IDLE; - if (!mMasterMute) { - char value[PROPERTY_VALUE_MAX]; - property_get("ro.audio.silent", value, "0"); - if (atoi(value)) { - ALOGD("Silence is golden"); - setMasterMute_l(true); - } - } + checkSilentMode_l(); standbyTime = systemTime() + mStandbyTimeInNsecs; sleepTime = idleSleepTime; @@ -3230,6 +3234,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop() releaseWakeLock(); + ALOGV("Thread %p type %d exiting", this, mType); return false; } @@ -3312,7 +3317,6 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( audio_format_t format, uint32_t channelMask, int frameCount, - uint32_t flags, const sp<IMemory>& sharedBuffer, int sessionId) : RefBase(), @@ -3324,7 +3328,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( mFrameCount(0), mState(IDLE), mFormat(format), - mFlags(flags & ~SYSTEM_FLAGS_MASK), + mStepServerFailed(false), mSessionId(sessionId) // mChannelCount // mChannelMask @@ -3419,7 +3423,7 @@ bool AudioFlinger::ThreadBase::TrackBase::step() { result = cblk->stepServer(mFrameCount); if (!result) { ALOGV("stepServer failed acquiring cblk mutex"); - mFlags |= STEPSERVER_FAILED; + mStepServerFailed = true; } return result; } @@ -3431,7 +3435,7 @@ void AudioFlinger::ThreadBase::TrackBase::reset() { cblk->server = 0; cblk->userBase = 0; cblk->serverBase = 0; - mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK); + mStepServerFailed = false; ALOGV("TrackBase::reset"); } @@ -3471,7 +3475,7 @@ AudioFlinger::PlaybackThread::Track::Track( int frameCount, const sp<IMemory>& sharedBuffer, int sessionId) - : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, 0, sharedBuffer, sessionId), + : TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer, sessionId), mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL), mAuxEffectId(0), mHasVolumeController(false) { @@ -3562,10 +3566,10 @@ status_t AudioFlinger::PlaybackThread::Track::getNextBuffer( uint32_t framesReq = buffer->frameCount; // Check if last stepServer failed, try to step now - if (mFlags & TrackBase::STEPSERVER_FAILED) { + if (mStepServerFailed) { if (!step()) goto getNextBuffer_exit; ALOGV("stepServer recovered"); - mFlags &= ~TrackBase::STEPSERVER_FAILED; + mStepServerFailed = false; } framesReady = cblk->framesReady(); @@ -4161,10 +4165,9 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack( audio_format_t format, uint32_t channelMask, int frameCount, - uint32_t flags, int sessionId) : TrackBase(thread, client, sampleRate, format, - channelMask, frameCount, flags, 0, sessionId), + channelMask, frameCount, 0 /*sharedBuffer*/, sessionId), mOverflow(false) { if (mCblk != NULL) { @@ -4194,10 +4197,10 @@ status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvi uint32_t framesReq = buffer->frameCount; // Check if last stepServer failed, try to step now - if (mFlags & TrackBase::STEPSERVER_FAILED) { + if (mStepServerFailed) { if (!step()) goto getNextBuffer_exit; ALOGV("stepServer recovered"); - mFlags &= ~TrackBase::STEPSERVER_FAILED; + mStepServerFailed = false; } framesAvail = cblk->framesAvailable_l(); @@ -4660,6 +4663,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( audio_format_t format, uint32_t channelMask, int frameCount, + // FIXME dead, remove from IAudioFlinger uint32_t flags, int *sessionId, status_t *status) @@ -4704,7 +4708,6 @@ sp<IAudioRecord> AudioFlinger::openRecord( format, channelMask, frameCount, - flags, lSessionId, &lStatus); } @@ -4998,7 +5001,6 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR audio_format_t format, int channelMask, int frameCount, - uint32_t flags, int sessionId, status_t *status) { @@ -5015,7 +5017,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR Mutex::Autolock _l(mLock); track = new RecordTrack(this, client, sampleRate, - format, channelMask, frameCount, flags, sessionId); + format, channelMask, frameCount, sessionId); if (track->getCblk() == 0) { lStatus = NO_MEMORY; diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 71afc3c..6665bd7 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -312,19 +312,12 @@ private: PAUSED }; - enum track_flags { - STEPSERVER_FAILED = 0x01, // StepServer could not acquire cblk->lock mutex - SYSTEM_FLAGS_MASK = 0x0000ffffUL, - // The upper 16 bits are used for track-specific flags. - }; - TrackBase(ThreadBase *thread, const sp<Client>& client, uint32_t sampleRate, audio_format_t format, uint32_t channelMask, int frameCount, - uint32_t flags, const sp<IMemory>& sharedBuffer, int sessionId); virtual ~TrackBase(); @@ -384,7 +377,7 @@ private: // we don't really need a lock for these track_state mState; const audio_format_t mFormat; - uint32_t mFlags; + bool mStepServerFailed; const int mSessionId; uint8_t mChannelCount; uint32_t mChannelMask; @@ -866,6 +859,9 @@ private: virtual uint32_t idleSleepTimeUs() = 0; virtual uint32_t suspendSleepTimeUs() = 0; + // Code snippets that are temporarily lifted up out of threadLoop() until the merge + void checkSilentMode_l(); + private: friend class AudioFlinger; @@ -1048,7 +1044,6 @@ private: audio_format_t format, uint32_t channelMask, int frameCount, - uint32_t flags, int sessionId); virtual ~RecordTrack(); @@ -1094,7 +1089,6 @@ private: audio_format_t format, int channelMask, int frameCount, - uint32_t flags, int sessionId, status_t *status); |