diff options
Diffstat (limited to 'services/audioflinger')
-rw-r--r-- | services/audioflinger/A2dpAudioInterface.cpp | 89 | ||||
-rw-r--r-- | services/audioflinger/A2dpAudioInterface.h | 1 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 20 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 2 |
4 files changed, 68 insertions, 44 deletions
diff --git a/services/audioflinger/A2dpAudioInterface.cpp b/services/audioflinger/A2dpAudioInterface.cpp index 995e31c..aee01ab 100644 --- a/services/audioflinger/A2dpAudioInterface.cpp +++ b/services/audioflinger/A2dpAudioInterface.cpp @@ -23,10 +23,13 @@ #include "A2dpAudioInterface.h" #include "audio/liba2dp.h" - +#include <hardware_legacy/power.h> namespace android { +static const char *sA2dpWakeLock = "A2dpOutputStream"; +#define MAX_WRITE_RETRIES 5 + // ---------------------------------------------------------------------------- //AudioHardwareInterface* A2dpAudioInterface::createA2dpInterface() @@ -263,44 +266,55 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::set( A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut() { LOGV("A2dpAudioStreamOut destructor"); - standby(); close(); LOGV("A2dpAudioStreamOut destructor returning from close()"); } ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes) { - Mutex::Autolock lock(mLock); - - size_t remaining = bytes; status_t status = -1; + { + Mutex::Autolock lock(mLock); - if (!mBluetoothEnabled || mClosing || mSuspended) { - LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \ - mBluetoothEnabled %d, mClosing %d, mSuspended %d", - mBluetoothEnabled, mClosing, mSuspended); - goto Error; - } - - status = init(); - if (status < 0) - goto Error; + size_t remaining = bytes; - while (remaining > 0) { - status = a2dp_write(mData, buffer, remaining); - if (status <= 0) { - LOGE("a2dp_write failed err: %d\n", status); + if (!mBluetoothEnabled || mClosing || mSuspended) { + LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \ + mBluetoothEnabled %d, mClosing %d, mSuspended %d", + mBluetoothEnabled, mClosing, mSuspended); goto Error; } - remaining -= status; - buffer = ((char *)buffer) + status; - } - mStandby = false; + if (mStandby) { + acquire_wake_lock (PARTIAL_WAKE_LOCK, sA2dpWakeLock); + mStandby = false; + } + + status = init(); + if (status < 0) + goto Error; + + int retries = MAX_WRITE_RETRIES; + while (remaining > 0 && retries) { + status = a2dp_write(mData, buffer, remaining); + if (status < 0) { + LOGE("a2dp_write failed err: %d\n", status); + goto Error; + } + if (status == 0) { + retries--; + } + remaining -= status; + buffer = (char *)buffer + status; + } - return bytes; + return bytes; + } Error: + + standby(); + // Simulate audio output timing in case of error usleep(((bytes * 1000 )/ frameSize() / sampleRate()) * 1000); @@ -324,19 +338,22 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::init() status_t A2dpAudioInterface::A2dpAudioStreamOut::standby() { - int result = 0; - - if (mClosing) { - LOGV("Ignore standby, closing"); - return result; - } - Mutex::Autolock lock(mLock); + return standby_l(); +} + +status_t A2dpAudioInterface::A2dpAudioStreamOut::standby_l() +{ + int result = NO_ERROR; if (!mStandby) { - result = a2dp_stop(mData); - if (result == 0) - mStandby = true; + LOGV_IF(mClosing || !mBluetoothEnabled, "Standby skip stop: closing %d enabled %d", + mClosing, mBluetoothEnabled); + if (!mClosing && mBluetoothEnabled) { + result = a2dp_stop(mData); + } + release_wake_lock(sA2dpWakeLock); + mStandby = true; } return result; @@ -362,6 +379,9 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::setParameters(const String8& ke key = String8("closing"); if (param.get(key, value) == NO_ERROR) { mClosing = (value == "true"); + if (mClosing) { + standby(); + } param.remove(key); } key = AudioParameter::keyRouting; @@ -444,6 +464,7 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::close() status_t A2dpAudioInterface::A2dpAudioStreamOut::close_l() { + standby_l(); if (mData) { LOGV("A2dpAudioStreamOut::close_l() calling a2dp_cleanup(mData)"); a2dp_cleanup(mData); diff --git a/services/audioflinger/A2dpAudioInterface.h b/services/audioflinger/A2dpAudioInterface.h index 48154f9..cef1926 100644 --- a/services/audioflinger/A2dpAudioInterface.h +++ b/services/audioflinger/A2dpAudioInterface.h @@ -103,6 +103,7 @@ private: status_t setAddress(const char* address); status_t setBluetoothEnabled(bool enabled); status_t setSuspended(bool onOff); + status_t standby_l(); private: int mFd; diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 84dd022..51b5947 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -343,7 +343,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( lSessionId = *sessionId; } else { // if no audio session id is provided, create one here - lSessionId = nextUniqueId(); + lSessionId = nextUniqueId_l(); if (sessionId != NULL) { *sessionId = lSessionId; } @@ -3699,7 +3699,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( if (sessionId != NULL && *sessionId != AudioSystem::SESSION_OUTPUT_MIX) { lSessionId = *sessionId; } else { - lSessionId = nextUniqueId(); + lSessionId = nextUniqueId_l(); if (sessionId != NULL) { *sessionId = lSessionId; } @@ -4300,7 +4300,7 @@ int AudioFlinger::openOutput(uint32_t *pDevices, mHardwareStatus = AUDIO_HW_IDLE; if (output != 0) { - int id = nextUniqueId(); + int id = nextUniqueId_l(); if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || (format != AudioSystem::PCM_16_BIT) || (channels != AudioSystem::CHANNEL_OUT_STEREO)) { @@ -4348,7 +4348,7 @@ int AudioFlinger::openDuplicateOutput(int output1, int output2) return 0; } - int id = nextUniqueId(); + int id = nextUniqueId_l(); DuplicatingThread *thread = new DuplicatingThread(this, thread1, id); thread->addOutputTrack(thread2); mPlaybackThreads.add(id, thread); @@ -4473,7 +4473,7 @@ int AudioFlinger::openInput(uint32_t *pDevices, } if (input != 0) { - int id = nextUniqueId(); + int id = nextUniqueId_l(); // Start record thread thread = new RecordThread(this, input, reqSamplingRate, reqChannels, id); mRecordThreads.add(id, thread); @@ -4543,7 +4543,8 @@ status_t AudioFlinger::setStreamOutput(uint32_t stream, int output) int AudioFlinger::newAudioSessionId() { - return nextUniqueId(); + AutoMutex _l(mLock); + return nextUniqueId_l(); } // checkPlaybackThread_l() must be called with AudioFlinger::mLock held @@ -4578,9 +4579,10 @@ AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(int input) const return thread; } -int AudioFlinger::nextUniqueId() +// nextUniqueId_l() must be called with AudioFlinger::mLock held +int AudioFlinger::nextUniqueId_l() { - return android_atomic_inc(&mNextUniqueId); + return mNextUniqueId++; } // ---------------------------------------------------------------------------- @@ -4967,7 +4969,7 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::PlaybackThread::createEffect_l( LOGV("createEffect_l() got effect %p on chain %p", effect == 0 ? 0 : effect.get(), chain.get()); if (effect == 0) { - int id = mAudioFlinger->nextUniqueId(); + int id = mAudioFlinger->nextUniqueId_l(); // Check CPU and memory usage lStatus = AudioSystem::registerEffect(desc, mId, chain->strategy(), sessionId, id); if (lStatus != NO_ERROR) { diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 5917632..f0ef867 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -785,7 +785,7 @@ private: float streamVolumeInternal(int stream) const { return mStreamTypes[stream].volume; } void audioConfigChanged_l(int event, int ioHandle, void *param2); - int nextUniqueId(); + int nextUniqueId_l(); status_t moveEffectChain_l(int session, AudioFlinger::PlaybackThread *srcThread, AudioFlinger::PlaybackThread *dstThread, |