diff options
Diffstat (limited to 'services/audioflinger/AudioFlinger.cpp')
| -rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 203 |
1 files changed, 106 insertions, 97 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 2d856ad..7e2f6be 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -160,7 +160,10 @@ static const char * const audio_interfaces[] = { AudioFlinger::AudioFlinger() : BnAudioFlinger(), - mPrimaryHardwareDev(NULL), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1), + mPrimaryHardwareDev(NULL), + mHardwareStatus(AUDIO_HW_IDLE), // see also onFirstRef() + mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1), + mMode(AUDIO_MODE_INVALID), mBtNrecIsOff(false) { } @@ -172,7 +175,6 @@ void AudioFlinger::onFirstRef() Mutex::Autolock _l(mLock); /* TODO: move all this work into an Init() function */ - mHardwareStatus = AUDIO_HW_IDLE; for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) { const hw_module_t *mod; @@ -265,13 +267,10 @@ status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args) result.append("Clients:\n"); for (size_t i = 0; i < mClients.size(); ++i) { - wp<Client> wClient = mClients.valueAt(i); - if (wClient != 0) { - sp<Client> client = wClient.promote(); - if (client != 0) { - snprintf(buffer, SIZE, " pid: %d\n", client->pid()); - result.append(buffer); - } + sp<Client> client = mClients.valueAt(i).promote(); + if (client != 0) { + snprintf(buffer, SIZE, " pid: %d\n", client->pid()); + result.append(buffer); } } @@ -971,7 +970,8 @@ void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2) { size_t size = mNotificationClients.size(); for (size_t i = 0; i < size; i++) { - mNotificationClients.valueAt(i)->client()->ioConfigChanged(event, ioHandle, param2); + mNotificationClients.valueAt(i)->audioFlingerClient()->ioConfigChanged(event, ioHandle, + param2); } } @@ -985,13 +985,19 @@ void AudioFlinger::removeClient_l(pid_t pid) // ---------------------------------------------------------------------------- -AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device) +AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device, + type_t type) : Thread(false), - mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0), - mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID), mStandby(false), mId(id), mExiting(false), - mDevice(device) + mType(type), + mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), + // mChannelMask + mChannelCount(0), + mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID), + mParamStatus(NO_ERROR), + mStandby(false), mId(id), mExiting(false), + mDevice(device), + mDeathRecipient(new PMDeathRecipient(this)) { - mDeathRecipient = new PMDeathRecipient(this); } AudioFlinger::ThreadBase::~ThreadBase() @@ -1372,20 +1378,24 @@ void AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled_l(const sp<EffectModu AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, - uint32_t device) - : ThreadBase(audioFlinger, id, device), - mMixBuffer(NULL), mSuspended(0), mBytesWritten(0), mOutput(output), + uint32_t device, + type_t type) + : ThreadBase(audioFlinger, id, device, type), + mMixBuffer(NULL), mSuspended(0), mBytesWritten(0), + // Assumes constructor is called by AudioFlinger with it's mLock held, + // but it would be safer to explicitly pass initial masterMute as parameter + mMasterMute(audioFlinger->masterMute_l()), + // mStreamTypes[] initialized in constructor body + mOutput(output), + // Assumes constructor is called by AudioFlinger with it's mLock held, + // but it would be safer to explicitly pass initial masterVolume as parameter + mMasterVolume(audioFlinger->masterVolume_l()), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false) { snprintf(mName, kNameLength, "AudioOut_%d", id); readOutputParameters(); - // Assumes constructor is called by AudioFlinger with it's mLock held, - // but it would be safer to explicitly pass these as parameters - mMasterVolume = mAudioFlinger->masterVolume_l(); - mMasterMute = mAudioFlinger->masterMute_l(); - // mStreamTypes[AUDIO_STREAM_CNT] is initialized by stream_type_t default constructor // There is no AUDIO_STREAM_MIN, and ++ operator does not compile for (audio_stream_type_t stream = (audio_stream_type_t) 0; stream < AUDIO_STREAM_CNT; @@ -1431,13 +1441,10 @@ status_t AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16> result.append(buffer); result.append(" Name Clien Typ Fmt Chn mask Session Buf S M F SRate LeftV RighV Serv User Main buf Aux Buf\n"); for (size_t i = 0; i < mActiveTracks.size(); ++i) { - wp<Track> wTrack = mActiveTracks[i]; - if (wTrack != 0) { - sp<Track> track = wTrack.promote(); - if (track != 0) { - track->dump(buffer, SIZE); - result.append(buffer); - } + sp<Track> track = mActiveTracks[i].promote(); + if (track != 0) { + track->dump(buffer, SIZE); + result.append(buffer); } } write(fd, result.string(), result.size()); @@ -1705,7 +1712,7 @@ String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys) // audioConfigChanged_l() must be called with AudioFlinger::mLock held void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) { AudioSystem::OutputDescriptor desc; - void *param2 = 0; + void *param2 = NULL; ALOGV("PlaybackThread::audioConfigChanged_l, thread %p, event %d, param %d", this, event, param); @@ -1740,7 +1747,7 @@ void AudioFlinger::PlaybackThread::readOutputParameters() // FIXME - Current mixer implementation only supports stereo output: Always // Allocate a stereo buffer even if HW output is mono. - if (mMixBuffer != NULL) delete[] mMixBuffer; + delete[] mMixBuffer; mMixBuffer = new int16_t[mFrameCount * 2]; memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t)); @@ -1758,7 +1765,7 @@ void AudioFlinger::PlaybackThread::readOutputParameters() status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames) { - if (halFrames == 0 || dspFrames == 0) { + if (halFrames == NULL || dspFrames == NULL) { return BAD_VALUE; } Mutex::Autolock _l(mLock); @@ -1845,13 +1852,12 @@ uint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs() // ---------------------------------------------------------------------------- -AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device) - : PlaybackThread(audioFlinger, output, id, device), - mAudioMixer(NULL), mPrevMixerStatus(MIXER_IDLE) +AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, + int id, uint32_t device, type_t type) + : PlaybackThread(audioFlinger, output, id, device, type), + mAudioMixer(new AudioMixer(mFrameCount, mSampleRate)), + mPrevMixerStatus(MIXER_IDLE) { - mType = ThreadBase::MIXER; - mAudioMixer = new AudioMixer(mFrameCount, mSampleRate); - // FIXME - Current mixer implementation only supports stereo output if (mChannelCount == 1) { ALOGE("Invalid audio hardware channel count"); @@ -2193,7 +2199,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac // read original volumes with volume control float typeVolume = mStreamTypes[track->type()].volume; float v = masterVolume * typeVolume; - uint32_t vlr = cblk->volumeLR; + uint32_t vlr = cblk->getVolumeLR(); vl = vlr & 0xFFFF; vr = vlr >> 16; // track volumes come from shared memory, so can't be trusted and must be clamped @@ -2461,6 +2467,8 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l() } if (status == NO_ERROR && reconfig) { delete mAudioMixer; + // for safety in case readOutputParameters() accesses mAudioMixer (it doesn't) + mAudioMixer = NULL; readOutputParameters(); mAudioMixer = new AudioMixer(mFrameCount, mSampleRate); for (size_t i = 0; i < mTracks.size() ; i++) { @@ -2513,9 +2521,10 @@ uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs() // ---------------------------------------------------------------------------- AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device) - : PlaybackThread(audioFlinger, output, id, device) + : PlaybackThread(audioFlinger, output, id, device, DIRECT) + // mLeftVolFloat, mRightVolFloat + // mLeftVolShort, mRightVolShort { - mType = ThreadBase::DIRECT; } AudioFlinger::DirectOutputThread::~DirectOutputThread() @@ -2729,7 +2738,7 @@ bool AudioFlinger::DirectOutputThread::threadLoop() } else { float typeVolume = mStreamTypes[track->type()].volume; float v = mMasterVolume * typeVolume; - uint32_t vlr = cblk->volumeLR; + uint32_t vlr = cblk->getVolumeLR(); float v_clamped = v * (vlr & 0xFFFF); if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN; left = v_clamped/MAX_GAIN; @@ -2992,10 +3001,11 @@ uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs() // ---------------------------------------------------------------------------- -AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread, int id) - : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->device()), mWaitTimeMs(UINT_MAX) +AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, + AudioFlinger::MixerThread* mainThread, int id) + : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->device(), DUPLICATING), + mWaitTimeMs(UINT_MAX) { - mType = ThreadBase::DUPLICATING; addOutputTrack(mainThread); } @@ -3244,13 +3254,17 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( : RefBase(), mThread(thread), mClient(client), - mCblk(0), + mCblk(NULL), + // mBuffer + // mBufferEnd mFrameCount(0), mState(IDLE), mClientTid(-1), mFormat(format), mFlags(flags & ~SYSTEM_FLAGS_MASK), mSessionId(sessionId) + // mChannelCount + // mChannelMask { ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size()); @@ -3266,7 +3280,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( mCblkMemory = client->heap()->allocate(size); if (mCblkMemory != 0) { mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer()); - if (mCblk) { // construct the shared structure in-place. + if (mCblk != NULL) { // construct the shared structure in-place. new(mCblk) audio_track_cblk_t(); // clear all buffers mCblk->frameCount = frameCount; @@ -3309,7 +3323,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( AudioFlinger::ThreadBase::TrackBase::~TrackBase() { - if (mCblk) { + if (mCblk != NULL) { mCblk->~audio_track_cblk_t(); // destroy our shared-structure. if (mClient == NULL) { delete mCblk; @@ -3317,6 +3331,7 @@ AudioFlinger::ThreadBase::TrackBase::~TrackBase() } mCblkMemory.clear(); // and free the shared memory if (mClient != NULL) { + // Client destructor must run with AudioFlinger mutex locked Mutex::Autolock _l(mClient->audioFlinger()->mLock); mClient.clear(); } @@ -3383,7 +3398,7 @@ void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t f server %d, serverBase %d, user %d, userBase %d", bufferStart, bufferEnd, mBuffer, mBufferEnd, cblk->server, cblk->serverBase, cblk->user, cblk->userBase); - return 0; + return NULL; } return bufferStart; @@ -3468,7 +3483,7 @@ void AudioFlinger::PlaybackThread::Track::destroy() void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) { - uint32_t vlr = mCblk->volumeLR; + uint32_t vlr = mCblk->getVolumeLR(); snprintf(buffer, size, " %05d %05d %03u %03u 0x%08x %05u %04u %1d %1d %1d %05u %05u %05u 0x%08x 0x%08x 0x%08x 0x%08x\n", mName - AudioMixer::TRACK0, (mClient == NULL) ? getpid() : mClient->pid(), @@ -3827,7 +3842,6 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack( if (mCblk != NULL) { mCblk->flags |= CBLK_DIRECTION_OUT; mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); - mCblk->volumeLR = (MAX_GAIN_INT << 16) | MAX_GAIN_INT; mOutBuffer.frameCount = 0; playbackThread->mTracks.add(this); ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, " \ @@ -4065,7 +4079,7 @@ AudioFlinger::Client::~Client() mAudioFlinger->removeClient_l(mPid); } -const sp<MemoryDealer>& AudioFlinger::Client::heap() const +sp<MemoryDealer> AudioFlinger::Client::heap() const { return mMemoryDealer; } @@ -4075,13 +4089,12 @@ const sp<MemoryDealer>& AudioFlinger::Client::heap() const AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger, const sp<IAudioFlingerClient>& client, pid_t pid) - : mAudioFlinger(audioFlinger), mPid(pid), mClient(client) + : mAudioFlinger(audioFlinger), mPid(pid), mAudioFlingerClient(client) { } AudioFlinger::NotificationClient::~NotificationClient() { - mClient.clear(); } void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who) @@ -4266,15 +4279,16 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, uint32_t channels, int id, uint32_t device) : - ThreadBase(audioFlinger, id, device), - mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL) + ThreadBase(audioFlinger, id, device, RECORD), + mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL), + // mRsmpInIndex and mInputBytes set by readInputParameters() + mReqChannelCount(popcount(channels)), + mReqSampleRate(sampleRate) + // mBytesRead is only meaningful while active, and so is cleared in start() + // (but might be better to also clear here for dump?) { - mType = ThreadBase::RECORD; - snprintf(mName, kNameLength, "AudioIn_%d", id); - mReqChannelCount = popcount(channels); - mReqSampleRate = sampleRate; readInputParameters(); } @@ -4282,10 +4296,8 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::RecordThread::~RecordThread() { delete[] mRsmpInBuffer; - if (mResampler != NULL) { - delete mResampler; - delete[] mRsmpOutBuffer; - } + delete mResampler; + delete[] mRsmpOutBuffer; } void AudioFlinger::RecordThread::onFirstRef() @@ -4807,7 +4819,7 @@ String8 AudioFlinger::RecordThread::getParameters(const String8& keys) void AudioFlinger::RecordThread::audioConfigChanged_l(int event, int param) { AudioSystem::OutputDescriptor desc; - void *param2 = 0; + void *param2 = NULL; switch (event) { case AudioSystem::INPUT_OPENED: @@ -4829,9 +4841,11 @@ void AudioFlinger::RecordThread::audioConfigChanged_l(int event, int param) { void AudioFlinger::RecordThread::readInputParameters() { - if (mRsmpInBuffer) delete mRsmpInBuffer; - if (mRsmpOutBuffer) delete mRsmpOutBuffer; - if (mResampler) delete mResampler; + delete mRsmpInBuffer; + // mRsmpInBuffer is always assigned a new[] below + delete mRsmpOutBuffer; + mRsmpOutBuffer = NULL; + delete mResampler; mResampler = NULL; mSampleRate = mInput->stream->common.get_sample_rate(&mInput->stream->common); @@ -4983,10 +4997,10 @@ int AudioFlinger::openOutput(uint32_t *pDevices, } mPlaybackThreads.add(id, thread); - if (pSamplingRate) *pSamplingRate = samplingRate; - if (pFormat) *pFormat = format; - if (pChannels) *pChannels = channels; - if (pLatencyMs) *pLatencyMs = thread->latency(); + if (pSamplingRate != NULL) *pSamplingRate = samplingRate; + if (pFormat != NULL) *pFormat = format; + if (pChannels != NULL) *pChannels = channels; + if (pLatencyMs != NULL) *pLatencyMs = thread->latency(); // notify client processes of the new output creation thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED); @@ -5038,7 +5052,7 @@ status_t AudioFlinger::closeOutput(int output) } } } - void *param2 = 0; + void *param2 = NULL; audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, param2); mPlaybackThreads.removeItem(output); } @@ -5154,9 +5168,9 @@ int AudioFlinger::openInput(uint32_t *pDevices, device); mRecordThreads.add(id, thread); ALOGV("openInput() created record thread: ID %d thread %p", id, thread); - if (pSamplingRate) *pSamplingRate = reqSamplingRate; - if (pFormat) *pFormat = format; - if (pChannels) *pChannels = reqChannels; + if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate; + if (pFormat != NULL) *pFormat = format; + if (pChannels != NULL) *pChannels = reqChannels; input->stream->common.standby(&input->stream->common); @@ -5181,7 +5195,7 @@ status_t AudioFlinger::closeInput(int input) } ALOGV("closeInput() %d", input); - void *param2 = 0; + void *param2 = NULL; audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, param2); mRecordThreads.removeItem(input); } @@ -5243,12 +5257,8 @@ void AudioFlinger::acquireAudioSessionId(int audioSession) return; } } - AudioSessionRef *ref = new AudioSessionRef(); - ref->sessionid = audioSession; - ref->pid = caller; - ref->cnt = 1; - mAudioSessionRefs.push(ref); - ALOGV(" added new entry for %d", ref->sessionid); + mAudioSessionRefs.push(new AudioSessionRef(audioSession, caller)); + ALOGV(" added new entry for %d", audioSession); } void AudioFlinger::releaseAudioSessionId(int audioSession) @@ -5792,7 +5802,7 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l( // create effect handle and connect it to effect module handle = new EffectHandle(effect, client, effectClient, priority); lStatus = effect->addHandle(handle); - if (enabled) { + if (enabled != NULL) { *enabled = (int)effect->isEnabled(); } } @@ -6179,7 +6189,7 @@ AudioFlinger::EffectModule::~EffectModule() } } -status_t AudioFlinger::EffectModule::addHandle(sp<EffectHandle>& handle) +status_t AudioFlinger::EffectModule::addHandle(const sp<EffectHandle>& handle) { status_t status; @@ -6226,7 +6236,7 @@ size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle) bool enabled = false; EffectHandle *hdl = handle.unsafe_get(); - if (hdl) { + if (hdl != NULL) { ALOGV("removeHandle() unsafe_get OK"); enabled = hdl->enabled(); } @@ -6862,7 +6872,7 @@ AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect, if (mCblkMemory != 0) { mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer()); - if (mCblk) { + if (mCblk != NULL) { new(mCblk) effect_param_cblk_t(); mBuffer = (uint8_t *)mCblk + bufOffset; } @@ -6959,7 +6969,7 @@ void AudioFlinger::EffectHandle::disconnect(bool unpiniflast) // release sp on module => module destructor can be called now mEffect.clear(); if (mClient != 0) { - if (mCblk) { + if (mCblk != NULL) { mCblk->~effect_param_cblk_t(); // destroy our shared-structure. } mCblkMemory.clear(); // and free the shared memory @@ -7089,7 +7099,7 @@ status_t AudioFlinger::EffectHandle::onTransact( void AudioFlinger::EffectHandle::dump(char* buffer, size_t size) { - bool locked = mCblk ? tryLock(mCblk->lock) : false; + bool locked = mCblk != NULL && tryLock(mCblk->lock); snprintf(buffer, size, "\t\t\t%05d %05d %01u %01u %05u %05u\n", (mClient == NULL) ? getpid() : mClient->pid(), @@ -7551,7 +7561,8 @@ void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend) ALOGV("setEffectSuspendedAll_l() add entry for 0"); } if (desc->mRefCount++ == 0) { - Vector< sp<EffectModule> > effects = getSuspendEligibleEffects(); + Vector< sp<EffectModule> > effects; + getSuspendEligibleEffects(effects); for (size_t i = 0; i < effects.size(); i++) { setEffectSuspended_l(&effects[i]->desc().type, true); } @@ -7602,16 +7613,14 @@ bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descript return true; } -Vector< sp<AudioFlinger::EffectModule> > AudioFlinger::EffectChain::getSuspendEligibleEffects() +void AudioFlinger::EffectChain::getSuspendEligibleEffects(Vector< sp<AudioFlinger::EffectModule> > &effects) { - Vector< sp<EffectModule> > effects; + effects.clear(); for (size_t i = 0; i < mEffects.size(); i++) { - if (!isEffectEligibleForSuspend(mEffects[i]->desc())) { - continue; + if (isEffectEligibleForSuspend(mEffects[i]->desc())) { + effects.add(mEffects[i]); } - effects.add(mEffects[i]); } - return effects; } sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled( |
