summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/Android.mk2
-rw-r--r--media/libmedia/AudioEffect.cpp21
-rw-r--r--media/libmedia/AudioRecord.cpp189
-rw-r--r--media/libmedia/AudioSystem.cpp44
-rw-r--r--media/libmedia/AudioTrack.cpp601
-rw-r--r--media/libmedia/IAudioFlinger.cpp40
-rw-r--r--media/libmedia/IAudioFlingerClient.cpp3
-rw-r--r--media/libmedia/IAudioPolicyService.cpp9
-rw-r--r--media/libmedia/SoundPool.cpp6
-rw-r--r--media/libmedia/ToneGenerator.cpp2
-rw-r--r--media/libmedia/Visualizer.cpp6
11 files changed, 481 insertions, 442 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 54666fb..f2b6441 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -54,7 +54,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libui libcutils libutils libbinder libsonivox libicuuc libexpat \
libcamera_client libstagefright_foundation \
- libgui libdl libaudioutils libmedia_native
+ libgui libdl libaudioutils
LOCAL_WHOLE_STATIC_LIBRARY := libmedia_helper
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index 680604b..3317d57 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -152,7 +152,8 @@ status_t AudioEffect::set(const effect_uuid_t *type,
mCblk->buffer = (uint8_t *)mCblk + bufOffset;
iEffect->asBinder()->linkToDeath(mIEffectClient);
- ALOGV("set() %p OK effect: %s id: %d status %d enabled %d", this, mDescriptor.name, mId, mStatus, mEnabled);
+ ALOGV("set() %p OK effect: %s id: %d status %d enabled %d", this, mDescriptor.name, mId,
+ mStatus, mEnabled);
return mStatus;
}
@@ -266,9 +267,11 @@ status_t AudioEffect::setParameter(effect_param_t *param)
uint32_t size = sizeof(int);
uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
- ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);
+ ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data,
+ (param->psize == 8) ? *((int *)param->data + 1): -1);
- return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size, &param->status);
+ return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size,
+ &param->status);
}
status_t AudioEffect::setParameterDeferred(effect_param_t *param)
@@ -321,11 +324,14 @@ status_t AudioEffect::getParameter(effect_param_t *param)
return BAD_VALUE;
}
- ALOGV("getParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);
+ ALOGV("getParameter: param: %d, param2: %d", *(int *)param->data,
+ (param->psize == 8) ? *((int *)param->data + 1): -1);
- uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
+ uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
+ param->vsize;
- return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param, &psize, param);
+ return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param,
+ &psize, param);
}
@@ -346,7 +352,8 @@ void AudioEffect::binderDied()
void AudioEffect::controlStatusChanged(bool controlGranted)
{
- ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf, mUserData);
+ ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf,
+ mUserData);
if (controlGranted) {
if (mStatus == ALREADY_EXISTS) {
mStatus = NO_ERROR;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 8ea6306..c2ef68c 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -36,7 +36,7 @@ namespace android {
// static
status_t AudioRecord::getMinFrameCount(
- int* frameCount,
+ size_t* frameCount,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask)
@@ -54,7 +54,7 @@ status_t AudioRecord::getMinFrameCount(
}
if (size == 0) {
- ALOGE("Unsupported configuration: sampleRate %d, format %d, channelMask %#x",
+ ALOGE("Unsupported configuration: sampleRate %u, format %d, channelMask %#x",
sampleRate, format, channelMask);
return BAD_VALUE;
}
@@ -63,7 +63,7 @@ status_t AudioRecord::getMinFrameCount(
size <<= 1;
if (audio_is_linear_pcm(format)) {
- int channelCount = popcount(channelMask);
+ uint32_t channelCount = popcount(channelMask);
size /= channelCount * audio_bytes_per_sample(format);
}
@@ -119,15 +119,22 @@ status_t AudioRecord::set(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ int frameCountInt,
callback_t cbf,
void* user,
int notificationFrames,
bool threadCanCallJava,
int sessionId)
{
+ // FIXME "int" here is legacy and will be replaced by size_t later
+ if (frameCountInt < 0) {
+ ALOGE("Invalid frame count %d", frameCountInt);
+ return BAD_VALUE;
+ }
+ size_t frameCount = frameCountInt;
- ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask, frameCount);
+ ALOGV("set(): sampleRate %u, channelMask %#x, frameCount %u", sampleRate, channelMask,
+ frameCount);
AutoMutex lock(mLock);
@@ -155,8 +162,9 @@ status_t AudioRecord::set(
if (!audio_is_input_channel(channelMask)) {
return BAD_VALUE;
}
-
- int channelCount = popcount(channelMask);
+ mChannelMask = channelMask;
+ uint32_t channelCount = popcount(channelMask);
+ mChannelCount = channelCount;
if (sessionId == 0 ) {
mSessionId = AudioSystem::newAudioSessionId();
@@ -176,7 +184,7 @@ status_t AudioRecord::set(
}
// validate framecount
- int minFrameCount = 0;
+ size_t minFrameCount = 0;
status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask);
if (status != NO_ERROR) {
return status;
@@ -194,8 +202,7 @@ status_t AudioRecord::set(
}
// create the IAudioRecord
- status = openRecord_l(sampleRate, format, channelMask,
- frameCount, input);
+ status = openRecord_l(sampleRate, format, frameCount, input);
if (status != NO_ERROR) {
return status;
}
@@ -209,9 +216,14 @@ status_t AudioRecord::set(
mFormat = format;
// Update buffer size in case it has been limited by AudioFlinger during track creation
- mFrameCount = mCblk->frameCount;
- mChannelCount = (uint8_t)channelCount;
- mChannelMask = channelMask;
+ mFrameCount = mCblk->frameCount_;
+
+ if (audio_is_linear_pcm(mFormat)) {
+ mFrameSize = channelCount * audio_bytes_per_sample(format);
+ } else {
+ mFrameSize = sizeof(uint8_t);
+ }
+
mActive = false;
mCbf = cbf;
mNotificationFrames = notificationFrames;
@@ -247,25 +259,16 @@ audio_format_t AudioRecord::format() const
return mFormat;
}
-int AudioRecord::channelCount() const
+uint32_t AudioRecord::channelCount() const
{
return mChannelCount;
}
-uint32_t AudioRecord::frameCount() const
+size_t AudioRecord::frameCount() const
{
return mFrameCount;
}
-size_t AudioRecord::frameSize() const
-{
- if (audio_is_linear_pcm(mFormat)) {
- return channelCount()*audio_bytes_per_sample(mFormat);
- } else {
- return sizeof(uint8_t);
- }
-}
-
audio_source_t AudioRecord::inputSource() const
{
return mInputSource;
@@ -291,17 +294,19 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession)
mActive = true;
cblk->lock.lock();
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
cblk->lock.unlock();
ALOGV("mAudioRecord->start()");
ret = mAudioRecord->start(event, triggerSession);
cblk->lock.lock();
if (ret == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
}
}
- if (cblk->flags & CBLK_INVALID_MSK) {
- ret = restoreRecord_l(cblk);
+ if (cblk->flags & CBLK_INVALID) {
+ audio_track_cblk_t* temp = cblk;
+ ret = restoreRecord_l(temp);
+ cblk = temp;
}
cblk->lock.unlock();
if (ret == NO_ERROR) {
@@ -425,13 +430,13 @@ unsigned int AudioRecord::getInputFramesLost() const
status_t AudioRecord::openRecord_l(
uint32_t sampleRate,
audio_format_t format,
- audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
audio_io_handle_t input)
{
status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
+ ALOGE("Could not get audioflinger");
return NO_INIT;
}
@@ -441,7 +446,7 @@ status_t AudioRecord::openRecord_l(
int originalSessionId = mSessionId;
sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
sampleRate, format,
- channelMask,
+ mChannelMask,
frameCount,
IAudioFlinger::TRACK_DEFAULT,
tid,
@@ -454,20 +459,20 @@ status_t AudioRecord::openRecord_l(
ALOGE("AudioFlinger could not create record track, status: %d", status);
return status;
}
- sp<IMemory> cblk = record->getCblk();
- if (cblk == 0) {
+ sp<IMemory> iMem = record->getCblk();
+ if (iMem == 0) {
ALOGE("Could not get control block");
return NO_INIT;
}
mAudioRecord.clear();
mAudioRecord = record;
mCblkMemory.clear();
- mCblkMemory = cblk;
- mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
- mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
- android_atomic_and(~CBLK_DIRECTION_MSK, &mCblk->flags);
- mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
- mCblk->waitTimeMs = 0;
+ mCblkMemory = iMem;
+ audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
+ mCblk = cblk;
+ mBuffers = (char*)cblk + sizeof(audio_track_cblk_t);
+ cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+ cblk->waitTimeMs = 0;
return NO_ERROR;
}
@@ -483,7 +488,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
audioBuffer->frameCount = 0;
audioBuffer->size = 0;
- uint32_t framesReady = cblk->framesReady();
+ uint32_t framesReady = cblk->framesReadyIn();
if (framesReady == 0) {
cblk->lock.lock();
@@ -498,17 +503,22 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
cblk->lock.unlock();
return WOULD_BLOCK;
}
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
mLock.unlock();
+ // this condition is in shared memory, so if IAudioRecord and control block
+ // are replaced due to mediaserver death or IAudioRecord invalidation then
+ // cv won't be signalled, but fortunately the timeout will limit the wait
result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
cblk->lock.unlock();
mLock.lock();
if (!mActive) {
return status_t(STOPPED);
}
+ // IAudioRecord may have been re-created while mLock was unlocked
+ cblk = mCblk;
cblk->lock.lock();
}
- if (cblk->flags & CBLK_INVALID_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
goto create_new_record;
}
if (CC_UNLIKELY(result != NO_ERROR)) {
@@ -521,9 +531,11 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
cblk->lock.lock();
if (result == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
create_new_record:
- result = AudioRecord::restoreRecord_l(cblk);
+ audio_track_cblk_t* temp = cblk;
+ result = AudioRecord::restoreRecord_l(temp);
+ cblk = temp;
}
if (result != NO_ERROR) {
ALOGW("obtainBuffer create Track error %d", result);
@@ -539,7 +551,7 @@ create_new_record:
}
// read the server count again
start_loop_here:
- framesReady = cblk->framesReady();
+ framesReady = cblk->framesReadyIn();
}
cblk->lock.unlock();
}
@@ -553,18 +565,15 @@ create_new_record:
}
uint32_t u = cblk->user;
- uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+ uint32_t bufferEnd = cblk->userBase + mFrameCount;
if (framesReq > bufferEnd - u) {
framesReq = bufferEnd - u;
}
- audioBuffer->flags = 0;
- audioBuffer->channelCount= mChannelCount;
- audioBuffer->format = mFormat;
audioBuffer->frameCount = framesReq;
- audioBuffer->size = framesReq*cblk->frameSize;
- audioBuffer->raw = (int8_t*)cblk->buffer(u);
+ audioBuffer->size = framesReq * mFrameSize;
+ audioBuffer->raw = cblk->buffer(mBuffers, mFrameSize, u);
active = mActive;
return active ? status_t(NO_ERROR) : status_t(STOPPED);
}
@@ -572,7 +581,7 @@ create_new_record:
void AudioRecord::releaseBuffer(Buffer* audioBuffer)
{
AutoMutex lock(mLock);
- mCblk->stepUser(audioBuffer->frameCount);
+ mCblk->stepUserIn(audioBuffer->frameCount, mFrameCount);
}
audio_io_handle_t AudioRecord::getInput() const
@@ -631,10 +640,12 @@ ssize_t AudioRecord::read(void* buffer, size_t userSize)
status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS));
if (err < 0) {
// out of buffers, return #bytes written
- if (err == status_t(NO_MORE_BUFFERS))
+ if (err == status_t(NO_MORE_BUFFERS)) {
break;
- if (err == status_t(TIMED_OUT))
+ }
+ if (err == status_t(TIMED_OUT)) {
err = 0;
+ }
return ssize_t(err);
}
@@ -701,7 +712,8 @@ bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread)
status_t err = obtainBuffer(&audioBuffer, 1);
if (err < NO_ERROR) {
if (err != TIMED_OUT) {
- ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
+ ALOGE_IF(err != status_t(NO_MORE_BUFFERS),
+ "Error obtaining an audio buffer, giving up.");
return false;
}
break;
@@ -733,11 +745,11 @@ bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread)
// Manage overrun callback
- if (active && (cblk->framesAvailable() == 0)) {
+ if (active && (cblk->framesAvailableIn(mFrameCount) == 0)) {
// The value of active is stale, but we are almost sure to be active here because
// otherwise we would have exited when obtainBuffer returned STOPPED earlier.
ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
- if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
+ if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) {
mCbf(EVENT_OVERRUN, mUserData, NULL);
}
}
@@ -753,57 +765,40 @@ bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread)
// must be called with mLock and cblk.lock held. Callers must also hold strong references on
// the IAudioRecord and IMemory in case they are recreated here.
// If the IAudioRecord is successfully restored, the cblk pointer is updated
-status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk)
+status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& refCblk)
{
status_t result;
- if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
- ALOGW("dead IAudioRecord, creating a new one");
- // signal old cblk condition so that other threads waiting for available buffers stop
- // waiting now
- cblk->cv.broadcast();
- cblk->lock.unlock();
+ audio_track_cblk_t* cblk = refCblk;
+ audio_track_cblk_t* newCblk = cblk;
+ ALOGW("dead IAudioRecord, creating a new one");
- // if the new IAudioRecord is created, openRecord_l() will modify the
- // following member variables: mAudioRecord, mCblkMemory and mCblk.
- // It will also delete the strong references on previous IAudioRecord and IMemory
- result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask,
- mFrameCount, getInput_l());
- if (result == NO_ERROR) {
- // callback thread or sync event hasn't changed
- result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
- }
- if (result != NO_ERROR) {
- mActive = false;
- }
+ // signal old cblk condition so that other threads waiting for available buffers stop
+ // waiting now
+ cblk->cv.broadcast();
+ cblk->lock.unlock();
- // signal old cblk condition for other threads waiting for restore completion
- android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
- cblk->cv.broadcast();
- } else {
- if (!(cblk->flags & CBLK_RESTORED_MSK)) {
- ALOGW("dead IAudioRecord, waiting for a new one to be created");
- mLock.unlock();
- result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
- cblk->lock.unlock();
- mLock.lock();
- } else {
- ALOGW("dead IAudioRecord, already restored");
- result = NO_ERROR;
- cblk->lock.unlock();
- }
- if (result != NO_ERROR || !mActive) {
- result = status_t(STOPPED);
- }
+ // if the new IAudioRecord is created, openRecord_l() will modify the
+ // following member variables: mAudioRecord, mCblkMemory and mCblk.
+ // It will also delete the strong references on previous IAudioRecord and IMemory
+ result = openRecord_l(cblk->sampleRate, mFormat, mFrameCount, getInput_l());
+ if (result == NO_ERROR) {
+ newCblk = mCblk;
+ // callback thread or sync event hasn't changed
+ result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0);
+ }
+ if (result != NO_ERROR) {
+ mActive = false;
}
+
ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
- result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
+ result, mActive, newCblk, cblk, newCblk->flags, cblk->flags);
if (result == NO_ERROR) {
// from now on we switch to the newly created cblk
- cblk = mCblk;
+ refCblk = newCblk;
}
- cblk->lock.lock();
+ newCblk->lock.lock();
ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result);
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 207f96f..028e4a3 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -205,12 +205,7 @@ int AudioSystem::logToLinear(float volume)
return volume ? 100 - int(dBConvertInverse * log(volume) + 0.5) : 0;
}
-// DEPRECATED
-status_t AudioSystem::getOutputSamplingRate(int* samplingRate, int streamType) {
- return getOutputSamplingRate(samplingRate, (audio_stream_type_t)streamType);
-}
-
-status_t AudioSystem::getOutputSamplingRate(int* samplingRate, audio_stream_type_t streamType)
+status_t AudioSystem::getOutputSamplingRate(uint32_t* samplingRate, audio_stream_type_t streamType)
{
audio_io_handle_t output;
@@ -228,7 +223,7 @@ status_t AudioSystem::getOutputSamplingRate(int* samplingRate, audio_stream_type
status_t AudioSystem::getSamplingRate(audio_io_handle_t output,
audio_stream_type_t streamType,
- int* samplingRate)
+ uint32_t* samplingRate)
{
OutputDescriptor *outputDesc;
@@ -246,17 +241,13 @@ status_t AudioSystem::getSamplingRate(audio_io_handle_t output,
gLock.unlock();
}
- ALOGV("getSamplingRate() streamType %d, output %d, sampling rate %d", streamType, output, *samplingRate);
+ ALOGV("getSamplingRate() streamType %d, output %d, sampling rate %u", streamType, output,
+ *samplingRate);
return NO_ERROR;
}
-// DEPRECATED
-status_t AudioSystem::getOutputFrameCount(int* frameCount, int streamType) {
- return getOutputFrameCount(frameCount, (audio_stream_type_t)streamType);
-}
-
-status_t AudioSystem::getOutputFrameCount(int* frameCount, audio_stream_type_t streamType)
+status_t AudioSystem::getOutputFrameCount(size_t* frameCount, audio_stream_type_t streamType)
{
audio_io_handle_t output;
@@ -274,7 +265,7 @@ status_t AudioSystem::getOutputFrameCount(int* frameCount, audio_stream_type_t s
status_t AudioSystem::getFrameCount(audio_io_handle_t output,
audio_stream_type_t streamType,
- int* frameCount)
+ size_t* frameCount)
{
OutputDescriptor *outputDesc;
@@ -290,7 +281,8 @@ status_t AudioSystem::getFrameCount(audio_io_handle_t output,
gLock.unlock();
}
- ALOGV("getFrameCount() streamType %d, output %d, frameCount %d", streamType, output, *frameCount);
+ ALOGV("getFrameCount() streamType %d, output %d, frameCount %d", streamType, output,
+ *frameCount);
return NO_ERROR;
}
@@ -369,7 +361,8 @@ status_t AudioSystem::setVoiceVolume(float value)
return af->setVoiceVolume(value);
}
-status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, audio_stream_type_t stream)
+status_t AudioSystem::getRenderPosition(size_t *halFrames, size_t *dspFrames,
+ audio_stream_type_t stream)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
@@ -381,7 +374,7 @@ status_t AudioSystem::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames
return af->getRenderPosition(halFrames, dspFrames, getOutput(stream));
}
-unsigned int AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
+size_t AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
unsigned int result = 0;
if (af == 0) return result;
@@ -449,8 +442,10 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle
OutputDescriptor *outputDesc = new OutputDescriptor(*desc);
gOutputs.add(ioHandle, outputDesc);
- ALOGV("ioConfigChanged() new output samplingRate %d, format %d channels %#x frameCount %d latency %d",
- outputDesc->samplingRate, outputDesc->format, outputDesc->channels, outputDesc->frameCount, outputDesc->latency);
+ ALOGV("ioConfigChanged() new output samplingRate %u, format %d channels %#x frameCount %u "
+ "latency %d",
+ outputDesc->samplingRate, outputDesc->format, outputDesc->channels,
+ outputDesc->frameCount, outputDesc->latency);
} break;
case OUTPUT_CLOSED: {
if (gOutputs.indexOfKey(ioHandle) < 0) {
@@ -471,7 +466,8 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle
if (param2 == NULL) break;
desc = (const OutputDescriptor *)param2;
- ALOGV("ioConfigChanged() new config for output %d samplingRate %d, format %d channels %#x frameCount %d latency %d",
+ ALOGV("ioConfigChanged() new config for output %d samplingRate %u, format %d channels %#x "
+ "frameCount %d latency %d",
ioHandle, desc->samplingRate, desc->format,
desc->channels, desc->frameCount, desc->latency);
OutputDescriptor *outputDesc = gOutputs.valueAt(index);
@@ -510,7 +506,7 @@ sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient;
-// establish binder interface to AudioFlinger service
+// establish binder interface to AudioPolicy service
const sp<IAudioPolicyService>& AudioSystem::get_audio_policy_service()
{
gLock.lock();
@@ -744,14 +740,14 @@ status_t AudioSystem::isSourceActive(audio_source_t stream, bool* state)
return NO_ERROR;
}
-int32_t AudioSystem::getPrimaryOutputSamplingRate()
+uint32_t AudioSystem::getPrimaryOutputSamplingRate()
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return 0;
return af->getPrimaryOutputSamplingRate();
}
-int32_t AudioSystem::getPrimaryOutputFrameCount()
+size_t AudioSystem::getPrimaryOutputFrameCount()
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return 0;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index aec8c4a..e40895a 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -50,11 +50,13 @@ namespace android {
// static
status_t AudioTrack::getMinFrameCount(
- int* frameCount,
+ size_t* frameCount,
audio_stream_type_t streamType,
uint32_t sampleRate)
{
- if (frameCount == NULL) return BAD_VALUE;
+ if (frameCount == NULL) {
+ return BAD_VALUE;
+ }
// default to 0 in case of error
*frameCount = 0;
@@ -65,11 +67,11 @@ status_t AudioTrack::getMinFrameCount(
// audio_format_t format
// audio_channel_mask_t channelMask
// audio_output_flags_t flags
- int afSampleRate;
+ uint32_t afSampleRate;
if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
return NO_INIT;
}
- int afFrameCount;
+ size_t afFrameCount;
if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
return NO_INIT;
}
@@ -120,28 +122,6 @@ AudioTrack::AudioTrack(
0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId);
}
-// DEPRECATED
-AudioTrack::AudioTrack(
- int streamType,
- uint32_t sampleRate,
- int format,
- int channelMask,
- int frameCount,
- uint32_t flags,
- callback_t cbf,
- void* user,
- int notificationFrames,
- int sessionId)
- : mStatus(NO_INIT),
- mIsTimed(false),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT)
-{
- mStatus = set((audio_stream_type_t)streamType, sampleRate, (audio_format_t)format,
- (audio_channel_mask_t) channelMask,
- frameCount, (audio_output_flags_t)flags, cbf, user, notificationFrames,
- 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId);
-}
-
AudioTrack::AudioTrack(
audio_stream_type_t streamType,
uint32_t sampleRate,
@@ -188,7 +168,7 @@ status_t AudioTrack::set(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ int frameCountInt,
audio_output_flags_t flags,
callback_t cbf,
void* user,
@@ -197,10 +177,17 @@ status_t AudioTrack::set(
bool threadCanCallJava,
int sessionId)
{
+ // FIXME "int" here is legacy and will be replaced by size_t later
+ if (frameCountInt < 0) {
+ ALOGE("Invalid frame count %d", frameCountInt);
+ return BAD_VALUE;
+ }
+ size_t frameCount = frameCountInt;
- ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
+ ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(),
+ sharedBuffer->size());
- ALOGV("set() streamType %d frameCount %d flags %04x", streamType, frameCount, flags);
+ ALOGV("set() streamType %d frameCount %u flags %04x", streamType, frameCount, flags);
AutoMutex lock(mLock);
if (mAudioTrack != 0) {
@@ -214,7 +201,7 @@ status_t AudioTrack::set(
}
if (sampleRate == 0) {
- int afSampleRate;
+ uint32_t afSampleRate;
if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
return NO_INIT;
}
@@ -256,7 +243,9 @@ status_t AudioTrack::set(
ALOGE("Invalid channel mask %#x", channelMask);
return BAD_VALUE;
}
+ mChannelMask = channelMask;
uint32_t channelCount = popcount(channelMask);
+ mChannelCount = channelCount;
audio_io_handle_t output = AudioSystem::getOutput(
streamType,
@@ -272,6 +261,7 @@ status_t AudioTrack::set(
mVolume[RIGHT] = 1.0f;
mSendLevel = 0.0f;
mFrameCount = frameCount;
+ mReqFrameCount = frameCount;
mNotificationFramesReq = notificationFrames;
mSessionId = sessionId;
mAuxEffectId = 0;
@@ -287,7 +277,6 @@ status_t AudioTrack::set(
status_t status = createTrack_l(streamType,
sampleRate,
format,
- channelMask,
frameCount,
flags,
sharedBuffer,
@@ -305,8 +294,15 @@ status_t AudioTrack::set(
mStreamType = streamType;
mFormat = format;
- mChannelMask = channelMask;
- mChannelCount = channelCount;
+
+ if (audio_is_linear_pcm(format)) {
+ mFrameSize = channelCount * audio_bytes_per_sample(format);
+ mFrameSizeAF = channelCount * sizeof(int16_t);
+ } else {
+ mFrameSize = sizeof(uint8_t);
+ mFrameSizeAF = sizeof(uint8_t);
+ }
+
mSharedBuffer = sharedBuffer;
mMuted = false;
mActive = false;
@@ -318,7 +314,6 @@ status_t AudioTrack::set(
mUpdatePeriod = 0;
mFlushed = false;
AudioSystem::acquireAudioSessionId(mSessionId);
- mRestoreStatus = NO_ERROR;
return NO_ERROR;
}
@@ -344,23 +339,14 @@ audio_format_t AudioTrack::format() const
return mFormat;
}
-int AudioTrack::channelCount() const
+uint32_t AudioTrack::channelCount() const
{
return mChannelCount;
}
-uint32_t AudioTrack::frameCount() const
+size_t AudioTrack::frameCount() const
{
- return mCblk->frameCount;
-}
-
-size_t AudioTrack::frameSize() const
-{
- if (audio_is_linear_pcm(mFormat)) {
- return channelCount()*audio_bytes_per_sample(mFormat);
- } else {
- return sizeof(uint8_t);
- }
+ return mFrameCount;
}
sp<IMemory>& AudioTrack::sharedBuffer()
@@ -390,7 +376,7 @@ void AudioTrack::start()
cblk->lock.lock();
cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
cblk->waitTimeMs = 0;
- android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags);
+ android_atomic_and(~CBLK_DISABLED, &cblk->flags);
if (t != 0) {
t->resume();
} else {
@@ -399,19 +385,21 @@ void AudioTrack::start()
androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
}
- ALOGV("start %p before lock cblk %p", this, mCblk);
+ ALOGV("start %p before lock cblk %p", this, cblk);
status_t status = NO_ERROR;
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
cblk->lock.unlock();
ALOGV("mAudioTrack->start()");
status = mAudioTrack->start();
cblk->lock.lock();
if (status == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
}
}
- if (cblk->flags & CBLK_INVALID_MSK) {
- status = restoreTrack_l(cblk, true);
+ if (cblk->flags & CBLK_INVALID) {
+ audio_track_cblk_t* temp = cblk;
+ status = restoreTrack_l(temp, true /*fromStart*/);
+ cblk = temp;
}
cblk->lock.unlock();
if (status != NO_ERROR) {
@@ -528,14 +516,9 @@ status_t AudioTrack::setVolume(float left, float right)
return NO_ERROR;
}
-void AudioTrack::getVolume(float* left, float* right) const
+status_t AudioTrack::setVolume(float volume)
{
- if (left != NULL) {
- *left = mVolume[LEFT];
- }
- if (right != NULL) {
- *right = mVolume[RIGHT];
- }
+ return setVolume(volume, volume);
}
status_t AudioTrack::setAuxEffectSendLevel(float level)
@@ -560,9 +543,9 @@ void AudioTrack::getAuxEffectSendLevel(float* level) const
}
}
-status_t AudioTrack::setSampleRate(int rate)
+status_t AudioTrack::setSampleRate(uint32_t rate)
{
- int afSamplingRate;
+ uint32_t afSamplingRate;
if (mIsTimed) {
return INVALID_OPERATION;
@@ -572,7 +555,9 @@ status_t AudioTrack::setSampleRate(int rate)
return NO_INIT;
}
// Resampler implementation limits input sampling rate to 2 x output sampling rate.
- if (rate <= 0 || rate > afSamplingRate*2 ) return BAD_VALUE;
+ if (rate == 0 || rate > afSamplingRate*2 ) {
+ return BAD_VALUE;
+ }
AutoMutex lock(mLock);
mCblk->sampleRate = rate;
@@ -582,7 +567,7 @@ status_t AudioTrack::setSampleRate(int rate)
uint32_t AudioTrack::getSampleRate() const
{
if (mIsTimed) {
- return INVALID_OPERATION;
+ return 0;
}
AutoMutex lock(mLock);
@@ -615,15 +600,17 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou
}
if (loopStart >= loopEnd ||
- loopEnd - loopStart > cblk->frameCount ||
+ loopEnd - loopStart > mFrameCount ||
cblk->server > loopStart) {
- ALOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user);
+ ALOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, "
+ "user %d", loopStart, loopEnd, loopCount, mFrameCount, cblk->user);
return BAD_VALUE;
}
- if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) {
- ALOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d",
- loopStart, loopEnd, cblk->frameCount);
+ if ((mSharedBuffer != 0) && (loopEnd > mFrameCount)) {
+ ALOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, "
+ "framecount %d",
+ loopStart, loopEnd, mFrameCount);
return BAD_VALUE;
}
@@ -637,7 +624,9 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou
status_t AudioTrack::setMarkerPosition(uint32_t marker)
{
- if (mCbf == NULL) return INVALID_OPERATION;
+ if (mCbf == NULL) {
+ return INVALID_OPERATION;
+ }
mMarkerPosition = marker;
mMarkerReached = false;
@@ -647,7 +636,9 @@ status_t AudioTrack::setMarkerPosition(uint32_t marker)
status_t AudioTrack::getMarkerPosition(uint32_t *marker) const
{
- if (marker == NULL) return BAD_VALUE;
+ if (marker == NULL) {
+ return BAD_VALUE;
+ }
*marker = mMarkerPosition;
@@ -656,7 +647,9 @@ status_t AudioTrack::getMarkerPosition(uint32_t *marker) const
status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod)
{
- if (mCbf == NULL) return INVALID_OPERATION;
+ if (mCbf == NULL) {
+ return INVALID_OPERATION;
+ }
uint32_t curPosition;
getPosition(&curPosition);
@@ -668,7 +661,9 @@ status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod)
status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) const
{
- if (updatePeriod == NULL) return BAD_VALUE;
+ if (updatePeriod == NULL) {
+ return BAD_VALUE;
+ }
*updatePeriod = mUpdatePeriod;
@@ -677,25 +672,34 @@ status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) const
status_t AudioTrack::setPosition(uint32_t position)
{
- if (mIsTimed) return INVALID_OPERATION;
+ if (mIsTimed) {
+ return INVALID_OPERATION;
+ }
AutoMutex lock(mLock);
- if (!stopped_l()) return INVALID_OPERATION;
+ if (!stopped_l()) {
+ return INVALID_OPERATION;
+ }
- Mutex::Autolock _l(mCblk->lock);
+ audio_track_cblk_t* cblk = mCblk;
+ Mutex::Autolock _l(cblk->lock);
- if (position > mCblk->user) return BAD_VALUE;
+ if (position > cblk->user) {
+ return BAD_VALUE;
+ }
- mCblk->server = position;
- android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags);
+ cblk->server = position;
+ android_atomic_or(CBLK_FORCEREADY, &cblk->flags);
return NO_ERROR;
}
status_t AudioTrack::getPosition(uint32_t *position)
{
- if (position == NULL) return BAD_VALUE;
+ if (position == NULL) {
+ return BAD_VALUE;
+ }
AutoMutex lock(mLock);
*position = mFlushed ? 0 : mCblk->server;
@@ -706,11 +710,14 @@ status_t AudioTrack::reload()
{
AutoMutex lock(mLock);
- if (!stopped_l()) return INVALID_OPERATION;
+ if (!stopped_l()) {
+ return INVALID_OPERATION;
+ }
flush_l();
- mCblk->stepUser(mCblk->frameCount);
+ audio_track_cblk_t* cblk = mCblk;
+ cblk->stepUserOut(mFrameCount, mFrameCount);
return NO_ERROR;
}
@@ -750,8 +757,7 @@ status_t AudioTrack::createTrack_l(
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
- audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
audio_output_flags_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output)
@@ -791,7 +797,7 @@ status_t AudioTrack::createTrack_l(
// Same comment as below about ignoring frameCount parameter for set()
frameCount = sharedBuffer->size();
} else if (frameCount == 0) {
- int afFrameCount;
+ size_t afFrameCount;
if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
return NO_INIT;
}
@@ -800,17 +806,16 @@ status_t AudioTrack::createTrack_l(
} else if (sharedBuffer != 0) {
- // Ensure that buffer alignment matches channelCount
- int channelCount = popcount(channelMask);
+ // Ensure that buffer alignment matches channel count
// 8-bit data in shared memory is not currently supported by AudioFlinger
size_t alignment = /* format == AUDIO_FORMAT_PCM_8_BIT ? 1 : */ 2;
- if (channelCount > 1) {
+ if (mChannelCount > 1) {
// More than 2 channels does not require stronger alignment than stereo
alignment <<= 1;
}
- if (((uint32_t)sharedBuffer->pointer() & (alignment - 1)) != 0) {
- ALOGE("Invalid buffer alignment: address %p, channelCount %d",
- sharedBuffer->pointer(), channelCount);
+ if (((size_t)sharedBuffer->pointer() & (alignment - 1)) != 0) {
+ ALOGE("Invalid buffer alignment: address %p, channel count %u",
+ sharedBuffer->pointer(), mChannelCount);
return BAD_VALUE;
}
@@ -818,16 +823,16 @@ status_t AudioTrack::createTrack_l(
// there's no frameCount parameter.
// But when initializing a shared buffer AudioTrack via set(),
// there _is_ a frameCount parameter. We silently ignore it.
- frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t);
+ frameCount = sharedBuffer->size()/mChannelCount/sizeof(int16_t);
} else if (!(flags & AUDIO_OUTPUT_FLAG_FAST)) {
// FIXME move these calculations and associated checks to server
- int afSampleRate;
+ uint32_t afSampleRate;
if (AudioSystem::getSamplingRate(output, streamType, &afSampleRate) != NO_ERROR) {
return NO_INIT;
}
- int afFrameCount;
+ size_t afFrameCount;
if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
return NO_INIT;
}
@@ -836,8 +841,8 @@ status_t AudioTrack::createTrack_l(
uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
if (minBufCount < 2) minBufCount = 2;
- int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
- ALOGV("minFrameCount: %d, afFrameCount=%d, minBufCount=%d, sampleRate=%d, afSampleRate=%d"
+ size_t minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
+ ALOGV("minFrameCount: %u, afFrameCount=%d, minBufCount=%d, sampleRate=%u, afSampleRate=%u"
", afLatency=%d",
minFrameCount, afFrameCount, minBufCount, sampleRate, afSampleRate, afLatency);
@@ -849,7 +854,7 @@ status_t AudioTrack::createTrack_l(
}
// Make sure that application is notified with sufficient margin
// before underrun
- if (mNotificationFramesAct > (uint32_t)frameCount/2) {
+ if (mNotificationFramesAct > frameCount/2) {
mNotificationFramesAct = frameCount/2;
}
if (frameCount < minFrameCount) {
@@ -879,10 +884,12 @@ status_t AudioTrack::createTrack_l(
sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
streamType,
sampleRate,
- format,
- channelMask,
+ // AudioFlinger only sees 16-bit PCM
+ format == AUDIO_FORMAT_PCM_8_BIT ?
+ AUDIO_FORMAT_PCM_16_BIT : format,
+ mChannelMask,
frameCount,
- trackFlags,
+ &trackFlags,
sharedBuffer,
output,
tid,
@@ -893,49 +900,58 @@ status_t AudioTrack::createTrack_l(
ALOGE("AudioFlinger could not create track, status: %d", status);
return status;
}
- sp<IMemory> cblk = track->getCblk();
- if (cblk == 0) {
+ sp<IMemory> iMem = track->getCblk();
+ if (iMem == 0) {
ALOGE("Could not get control block");
return NO_INIT;
}
mAudioTrack = track;
- mCblkMemory = cblk;
- mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
- // old has the previous value of mCblk->flags before the "or" operation
- int32_t old = android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags);
+ mCblkMemory = iMem;
+ audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
+ mCblk = cblk;
+ size_t temp = cblk->frameCount_;
+ if (temp < frameCount || (frameCount == 0 && temp == 0)) {
+ // In current design, AudioTrack client checks and ensures frame count validity before
+ // passing it to AudioFlinger so AudioFlinger should not return a different value except
+ // for fast track as it uses a special method of assigning frame count.
+ ALOGW("Requested frameCount %u but received frameCount %u", frameCount, temp);
+ }
+ frameCount = temp;
if (flags & AUDIO_OUTPUT_FLAG_FAST) {
- if (old & CBLK_FAST) {
- ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", mCblk->frameCount);
+ if (trackFlags & IAudioFlinger::TRACK_FAST) {
+ ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", frameCount);
} else {
- ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", mCblk->frameCount);
+ ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", frameCount);
// once denied, do not request again if IAudioTrack is re-created
flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
mFlags = flags;
}
if (sharedBuffer == 0) {
- mNotificationFramesAct = mCblk->frameCount/2;
+ mNotificationFramesAct = frameCount/2;
}
}
if (sharedBuffer == 0) {
- mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+ mBuffers = (char*)cblk + sizeof(audio_track_cblk_t);
} else {
- mCblk->buffers = sharedBuffer->pointer();
+ mBuffers = sharedBuffer->pointer();
// Force buffer full condition as data is already present in shared memory
- mCblk->stepUser(mCblk->frameCount);
+ cblk->stepUserOut(frameCount, frameCount);
}
- mCblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000));
- mCblk->setSendLevel(mSendLevel);
+ cblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) |
+ uint16_t(mVolume[LEFT] * 0x1000));
+ cblk->setSendLevel(mSendLevel);
mAudioTrack->attachAuxEffect(mAuxEffectId);
- mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
- mCblk->waitTimeMs = 0;
+ cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
+ cblk->waitTimeMs = 0;
mRemainingFrames = mNotificationFramesAct;
// FIXME don't believe this lie
- mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate;
+ mLatency = afLatency + (1000*frameCount) / sampleRate;
+ mFrameCount = frameCount;
// If IAudioTrack is re-created, don't let the requested frameCount
// decrease. This can confuse clients that cache frameCount().
- if (mCblk->frameCount > mFrameCount) {
- mFrameCount = mCblk->frameCount;
+ if (frameCount > mReqFrameCount) {
+ mReqFrameCount = frameCount;
}
return NO_ERROR;
}
@@ -952,10 +968,10 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
audioBuffer->frameCount = 0;
audioBuffer->size = 0;
- uint32_t framesAvail = cblk->framesAvailable();
+ uint32_t framesAvail = cblk->framesAvailableOut(mFrameCount);
cblk->lock.lock();
- if (cblk->flags & CBLK_INVALID_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
goto create_new_track;
}
cblk->lock.unlock();
@@ -974,18 +990,23 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
cblk->lock.unlock();
return WOULD_BLOCK;
}
- if (!(cblk->flags & CBLK_INVALID_MSK)) {
+ if (!(cblk->flags & CBLK_INVALID)) {
mLock.unlock();
+ // this condition is in shared memory, so if IAudioTrack and control block
+ // are replaced due to mediaserver death or IAudioTrack invalidation then
+ // cv won't be signalled, but fortunately the timeout will limit the wait
result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
cblk->lock.unlock();
mLock.lock();
if (!mActive) {
return status_t(STOPPED);
}
+ // IAudioTrack may have been re-created while mLock was unlocked
+ cblk = mCblk;
cblk->lock.lock();
}
- if (cblk->flags & CBLK_INVALID_MSK) {
+ if (cblk->flags & CBLK_INVALID) {
goto create_new_track;
}
if (CC_UNLIKELY(result != NO_ERROR)) {
@@ -994,16 +1015,18 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
// timing out when a loop has been set and we have already written upto loop end
// is a normal condition: no need to wake AudioFlinger up.
if (cblk->user < cblk->loopEnd) {
- ALOGW( "obtainBuffer timed out (is the CPU pegged?) %p name=%#x"
- "user=%08x, server=%08x", this, cblk->mName, cblk->user, cblk->server);
+ ALOGW("obtainBuffer timed out (is the CPU pegged?) %p name=%#x user=%08x, "
+ "server=%08x", this, cblk->mName, cblk->user, cblk->server);
//unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140)
cblk->lock.unlock();
result = mAudioTrack->start();
cblk->lock.lock();
if (result == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &cblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
create_new_track:
- result = restoreTrack_l(cblk, false);
+ audio_track_cblk_t* temp = cblk;
+ result = restoreTrack_l(temp, false /*fromStart*/);
+ cblk = temp;
}
if (result != NO_ERROR) {
ALOGW("obtainBuffer create Track error %d", result);
@@ -1021,7 +1044,7 @@ create_new_track:
}
// read the server count again
start_loop_here:
- framesAvail = cblk->framesAvailable_l();
+ framesAvail = cblk->framesAvailableOut_l(mFrameCount);
}
cblk->lock.unlock();
}
@@ -1033,22 +1056,15 @@ create_new_track:
}
uint32_t u = cblk->user;
- uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+ uint32_t bufferEnd = cblk->userBase + mFrameCount;
if (framesReq > bufferEnd - u) {
framesReq = bufferEnd - u;
}
- audioBuffer->flags = mMuted ? Buffer::MUTE : 0;
- audioBuffer->channelCount = mChannelCount;
audioBuffer->frameCount = framesReq;
- audioBuffer->size = framesReq * cblk->frameSize;
- if (audio_is_linear_pcm(mFormat)) {
- audioBuffer->format = AUDIO_FORMAT_PCM_16_BIT;
- } else {
- audioBuffer->format = mFormat;
- }
- audioBuffer->raw = (int8_t *)cblk->buffer(u);
+ audioBuffer->size = framesReq * mFrameSizeAF;
+ audioBuffer->raw = cblk->buffer(mBuffers, mFrameSizeAF, u);
active = mActive;
return active ? status_t(NO_ERROR) : status_t(STOPPED);
}
@@ -1056,12 +1072,13 @@ create_new_track:
void AudioTrack::releaseBuffer(Buffer* audioBuffer)
{
AutoMutex lock(mLock);
- mCblk->stepUser(audioBuffer->frameCount);
+ audio_track_cblk_t* cblk = mCblk;
+ cblk->stepUserOut(audioBuffer->frameCount, mFrameCount);
if (audioBuffer->frameCount > 0) {
// restart track if it was disabled by audioflinger due to previous underrun
- if (mActive && (mCblk->flags & CBLK_DISABLED_MSK)) {
- android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags);
- ALOGW("releaseBuffer() track %p name=%#x disabled, restarting", this, mCblk->mName);
+ if (mActive && (cblk->flags & CBLK_DISABLED)) {
+ android_atomic_and(~CBLK_DISABLED, &cblk->flags);
+ ALOGW("releaseBuffer() track %p name=%#x disabled, restarting", this, cblk->mName);
mAudioTrack->start();
}
}
@@ -1072,8 +1089,12 @@ void AudioTrack::releaseBuffer(Buffer* audioBuffer)
ssize_t AudioTrack::write(const void* buffer, size_t userSize)
{
- if (mSharedBuffer != 0) return INVALID_OPERATION;
- if (mIsTimed) return INVALID_OPERATION;
+ if (mSharedBuffer != 0) {
+ return INVALID_OPERATION;
+ }
+ if (mIsTimed) {
+ return INVALID_OPERATION;
+ }
if (ssize_t(userSize) < 0) {
// Sanity-check: user is most-likely passing an error code, and it would
@@ -1096,6 +1117,9 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize)
sp<IMemory> iMem = mCblkMemory;
mLock.unlock();
+ // since mLock is unlocked the IAudioTrack and shared memory may be re-created,
+ // so all cblk references might still refer to old shared memory, but that should be benign
+
ssize_t written = 0;
const int8_t *src = (const int8_t *)buffer;
Buffer audioBuffer;
@@ -1107,8 +1131,9 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize)
status_t err = obtainBuffer(&audioBuffer, -1);
if (err < 0) {
// out of buffers, return #bytes written
- if (err == status_t(NO_MORE_BUFFERS))
+ if (err == status_t(NO_MORE_BUFFERS)) {
break;
+ }
return ssize_t(err);
}
@@ -1121,8 +1146,8 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize)
} else {
toWrite = audioBuffer.size;
memcpy(audioBuffer.i8, src, toWrite);
- src += toWrite;
}
+ src += toWrite;
userSize -= toWrite;
written += toWrite;
@@ -1140,27 +1165,37 @@ TimedAudioTrack::TimedAudioTrack() {
status_t TimedAudioTrack::allocateTimedBuffer(size_t size, sp<IMemory>* buffer)
{
+ AutoMutex lock(mLock);
status_t result = UNKNOWN_ERROR;
+ // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed
+ // while we are accessing the cblk
+ sp<IAudioTrack> audioTrack = mAudioTrack;
+ sp<IMemory> iMem = mCblkMemory;
+
// If the track is not invalid already, try to allocate a buffer. alloc
// fails indicating that the server is dead, flag the track as invalid so
// we can attempt to restore in just a bit.
- if (!(mCblk->flags & CBLK_INVALID_MSK)) {
+ audio_track_cblk_t* cblk = mCblk;
+ if (!(cblk->flags & CBLK_INVALID)) {
result = mAudioTrack->allocateTimedBuffer(size, buffer);
if (result == DEAD_OBJECT) {
- android_atomic_or(CBLK_INVALID_ON, &mCblk->flags);
+ android_atomic_or(CBLK_INVALID, &cblk->flags);
}
}
// If the track is invalid at this point, attempt to restore it. and try the
// allocation one more time.
- if (mCblk->flags & CBLK_INVALID_MSK) {
- mCblk->lock.lock();
- result = restoreTrack_l(mCblk, false);
- mCblk->lock.unlock();
+ if (cblk->flags & CBLK_INVALID) {
+ cblk->lock.lock();
+ audio_track_cblk_t* temp = cblk;
+ result = restoreTrack_l(temp, false /*fromStart*/);
+ cblk = temp;
+ cblk->lock.unlock();
- if (result == OK)
+ if (result == OK) {
result = mAudioTrack->allocateTimedBuffer(size, buffer);
+ }
}
return result;
@@ -1172,10 +1207,11 @@ status_t TimedAudioTrack::queueTimedBuffer(const sp<IMemory>& buffer,
status_t status = mAudioTrack->queueTimedBuffer(buffer, pts);
{
AutoMutex lock(mLock);
+ audio_track_cblk_t* cblk = mCblk;
// restart track if it was disabled by audioflinger due to previous underrun
if (buffer->size() != 0 && status == NO_ERROR &&
- mActive && (mCblk->flags & CBLK_DISABLED_MSK)) {
- android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags);
+ mActive && (cblk->flags & CBLK_DISABLED)) {
+ android_atomic_and(~CBLK_DISABLED, &cblk->flags);
ALOGW("queueTimedBuffer() track %p disabled, restarting", this);
mAudioTrack->start();
}
@@ -1206,15 +1242,20 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
bool active = mActive;
mLock.unlock();
+ // since mLock is unlocked the IAudioTrack and shared memory may be re-created,
+ // so all cblk references might still refer to old shared memory, but that should be benign
+
// Manage underrun callback
- if (active && (cblk->framesAvailable() == cblk->frameCount)) {
+ if (active && (cblk->framesAvailableOut(mFrameCount) == mFrameCount)) {
ALOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
- if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) {
+ if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) {
mCbf(EVENT_UNDERRUN, mUserData, 0);
- if (cblk->server == cblk->frameCount) {
+ if (cblk->server == mFrameCount) {
mCbf(EVENT_BUFFER_END, mUserData, 0);
}
- if (mSharedBuffer != 0) return false;
+ if (mSharedBuffer != 0) {
+ return false;
+ }
}
}
@@ -1265,12 +1306,15 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
status_t err = obtainBuffer(&audioBuffer, waitCount);
if (err < NO_ERROR) {
if (err != TIMED_OUT) {
- ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up.");
+ ALOGE_IF(err != status_t(NO_MORE_BUFFERS),
+ "Error obtaining an audio buffer, giving up.");
return false;
}
break;
}
- if (err == status_t(STOPPED)) return false;
+ if (err == status_t(STOPPED)) {
+ return false;
+ }
// Divide buffer size by 2 to take into account the expansion
// due to 8 to 16 bit conversion: the callback must fill only half
@@ -1293,7 +1337,9 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
break;
}
- if (writtenSize > reqSize) writtenSize = reqSize;
+ if (writtenSize > reqSize) {
+ writtenSize = reqSize;
+ }
if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
// 8 to 16 bit conversion, note that source and destination are the same address
@@ -1302,10 +1348,10 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
}
audioBuffer.size = writtenSize;
- // NOTE: mCblk->frameSize is not equal to AudioTrack::frameSize() for
- // 8 bit PCM data: in this case, mCblk->frameSize is based on a sample size of
+ // NOTE: cblk->frameSize is not equal to AudioTrack::frameSize() for
+ // 8 bit PCM data: in this case, cblk->frameSize is based on a sample size of
// 16 bit.
- audioBuffer.frameCount = writtenSize/mCblk->frameSize;
+ audioBuffer.frameCount = writtenSize / mFrameSizeAF;
frames -= audioBuffer.frameCount;
@@ -1321,112 +1367,91 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
return true;
}
-// must be called with mLock and cblk.lock held. Callers must also hold strong references on
+// must be called with mLock and refCblk.lock held. Callers must also hold strong references on
// the IAudioTrack and IMemory in case they are recreated here.
-// If the IAudioTrack is successfully restored, the cblk pointer is updated
-status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart)
+// If the IAudioTrack is successfully restored, the refCblk pointer is updated
+// FIXME Don't depend on caller to hold strong references.
+status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& refCblk, bool fromStart)
{
status_t result;
- if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) {
- ALOGW("dead IAudioTrack, creating a new one from %s TID %d",
- fromStart ? "start()" : "obtainBuffer()", gettid());
+ audio_track_cblk_t* cblk = refCblk;
+ audio_track_cblk_t* newCblk = cblk;
+ ALOGW("dead IAudioTrack, creating a new one from %s",
+ fromStart ? "start()" : "obtainBuffer()");
- // signal old cblk condition so that other threads waiting for available buffers stop
- // waiting now
- cblk->cv.broadcast();
- cblk->lock.unlock();
+ // signal old cblk condition so that other threads waiting for available buffers stop
+ // waiting now
+ cblk->cv.broadcast();
+ cblk->lock.unlock();
- // refresh the audio configuration cache in this process to make sure we get new
- // output parameters in getOutput_l() and createTrack_l()
- AudioSystem::clearAudioConfigCache();
-
- // if the new IAudioTrack is created, createTrack_l() will modify the
- // following member variables: mAudioTrack, mCblkMemory and mCblk.
- // It will also delete the strong references on previous IAudioTrack and IMemory
- result = createTrack_l(mStreamType,
- cblk->sampleRate,
- mFormat,
- mChannelMask,
- mFrameCount,
- mFlags,
- mSharedBuffer,
- getOutput_l());
-
- if (result == NO_ERROR) {
- uint32_t user = cblk->user;
- uint32_t server = cblk->server;
- // restore write index and set other indexes to reflect empty buffer status
- mCblk->user = user;
- mCblk->server = user;
- mCblk->userBase = user;
- mCblk->serverBase = user;
- // restore loop: this is not guaranteed to succeed if new frame count is not
- // compatible with loop length
- setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount);
- if (!fromStart) {
- mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
- // Make sure that a client relying on callback events indicating underrun or
- // the actual amount of audio frames played (e.g SoundPool) receives them.
- if (mSharedBuffer == 0) {
- uint32_t frames = 0;
- if (user > server) {
- frames = ((user - server) > mCblk->frameCount) ?
- mCblk->frameCount : (user - server);
- memset(mCblk->buffers, 0, frames * mCblk->frameSize);
- }
- // restart playback even if buffer is not completely filled.
- android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags);
- // stepUser() clears CBLK_UNDERRUN_ON flag enabling underrun callbacks to
- // the client
- mCblk->stepUser(frames);
+ // refresh the audio configuration cache in this process to make sure we get new
+ // output parameters in getOutput_l() and createTrack_l()
+ AudioSystem::clearAudioConfigCache();
+
+ // if the new IAudioTrack is created, createTrack_l() will modify the
+ // following member variables: mAudioTrack, mCblkMemory and mCblk.
+ // It will also delete the strong references on previous IAudioTrack and IMemory
+ result = createTrack_l(mStreamType,
+ cblk->sampleRate,
+ mFormat,
+ mReqFrameCount, // so that frame count never goes down
+ mFlags,
+ mSharedBuffer,
+ getOutput_l());
+
+ if (result == NO_ERROR) {
+ uint32_t user = cblk->user;
+ uint32_t server = cblk->server;
+ // restore write index and set other indexes to reflect empty buffer status
+ newCblk = mCblk;
+ newCblk->user = user;
+ newCblk->server = user;
+ newCblk->userBase = user;
+ newCblk->serverBase = user;
+ // restore loop: this is not guaranteed to succeed if new frame count is not
+ // compatible with loop length
+ setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount);
+ if (!fromStart) {
+ newCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+ // Make sure that a client relying on callback events indicating underrun or
+ // the actual amount of audio frames played (e.g SoundPool) receives them.
+ if (mSharedBuffer == 0) {
+ uint32_t frames = 0;
+ if (user > server) {
+ frames = ((user - server) > mFrameCount) ?
+ mFrameCount : (user - server);
+ memset(mBuffers, 0, frames * mFrameSizeAF);
}
- }
- if (mSharedBuffer != 0) {
- mCblk->stepUser(mCblk->frameCount);
- }
- if (mActive) {
- result = mAudioTrack->start();
- ALOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result);
- }
- if (fromStart && result == NO_ERROR) {
- mNewPosition = mCblk->server + mUpdatePeriod;
+ // restart playback even if buffer is not completely filled.
+ android_atomic_or(CBLK_FORCEREADY, &newCblk->flags);
+ // stepUser() clears CBLK_UNDERRUN flag enabling underrun callbacks to
+ // the client
+ newCblk->stepUserOut(frames, mFrameCount);
}
}
- if (result != NO_ERROR) {
- android_atomic_and(~CBLK_RESTORING_ON, &cblk->flags);
- ALOGW_IF(result != NO_ERROR, "restoreTrack_l() failed status %d", result);
+ if (mSharedBuffer != 0) {
+ newCblk->stepUserOut(mFrameCount, mFrameCount);
}
- mRestoreStatus = result;
- // signal old cblk condition for other threads waiting for restore completion
- android_atomic_or(CBLK_RESTORED_ON, &cblk->flags);
- cblk->cv.broadcast();
- } else {
- if (!(cblk->flags & CBLK_RESTORED_MSK)) {
- ALOGW("dead IAudioTrack, waiting for a new one TID %d", gettid());
- mLock.unlock();
- result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS));
- if (result == NO_ERROR) {
- result = mRestoreStatus;
- }
- cblk->lock.unlock();
- mLock.lock();
- } else {
- ALOGW("dead IAudioTrack, already restored TID %d", gettid());
- result = mRestoreStatus;
- cblk->lock.unlock();
+ if (mActive) {
+ result = mAudioTrack->start();
+ ALOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result);
+ }
+ if (fromStart && result == NO_ERROR) {
+ mNewPosition = newCblk->server + mUpdatePeriod;
}
}
+ ALOGW_IF(result != NO_ERROR, "restoreTrack_l() failed status %d", result);
ALOGV("restoreTrack_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x",
- result, mActive, mCblk, cblk, mCblk->flags, cblk->flags);
+ result, mActive, newCblk, cblk, newCblk->flags, cblk->flags);
if (result == NO_ERROR) {
// from now on we switch to the newly created cblk
- cblk = mCblk;
+ refCblk = newCblk;
}
- cblk->lock.lock();
+ newCblk->lock.lock();
- ALOGW_IF(result != NO_ERROR, "restoreTrack_l() error %d TID %d", result, gettid());
+ ALOGW_IF(result != NO_ERROR, "restoreTrack_l() error %d", result);
return result;
}
@@ -1438,12 +1463,16 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
char buffer[SIZE];
String8 result;
+ audio_track_cblk_t* cblk = mCblk;
result.append(" AudioTrack::dump\n");
- snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType, mVolume[0], mVolume[1]);
+ snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType,
+ mVolume[0], mVolume[1]);
result.append(buffer);
- snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat, mChannelCount, (mCblk == 0) ? 0 : mCblk->frameCount);
+ snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat,
+ mChannelCount, mFrameCount);
result.append(buffer);
- snprintf(buffer, 255, " sample rate(%d), status(%d), muted(%d)\n", (mCblk == 0) ? 0 : mCblk->sampleRate, mStatus, mMuted);
+ snprintf(buffer, 255, " sample rate(%u), status(%d), muted(%d)\n",
+ (cblk == 0) ? 0 : cblk->sampleRate, mStatus, mMuted);
result.append(buffer);
snprintf(buffer, 255, " active(%d), latency (%d)\n", mActive, mLatency);
result.append(buffer);
@@ -1505,20 +1534,20 @@ void AudioTrack::AudioTrackThread::resume()
audio_track_cblk_t::audio_track_cblk_t()
: lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0),
- userBase(0), serverBase(0), buffers(NULL), frameCount(0),
+ userBase(0), serverBase(0), frameCount_(0),
loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), mVolumeLR(0x10001000),
mSendLevel(0), flags(0)
{
}
-uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount)
+uint32_t audio_track_cblk_t::stepUser(size_t stepCount, size_t frameCount, bool isOut)
{
- ALOGV("stepuser %08x %08x %d", user, server, frameCount);
+ ALOGV("stepuser %08x %08x %d", user, server, stepCount);
uint32_t u = user;
- u += frameCount;
+ u += stepCount;
// Ensure that user is never ahead of server for AudioRecord
- if (flags & CBLK_DIRECTION_MSK) {
+ if (isOut) {
// If stepServer() has been called once, switch to normal obtainBuffer() timeout period
if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) {
bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
@@ -1528,30 +1557,29 @@ uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount)
u = server;
}
- uint32_t fc = this->frameCount;
- if (u >= fc) {
+ if (u >= frameCount) {
// common case, user didn't just wrap
- if (u - fc >= userBase ) {
- userBase += fc;
+ if (u - frameCount >= userBase ) {
+ userBase += frameCount;
}
- } else if (u >= userBase + fc) {
+ } else if (u >= userBase + frameCount) {
// user just wrapped
- userBase += fc;
+ userBase += frameCount;
}
user = u;
// Clear flow control error condition as new data has been written/read to/from buffer.
- if (flags & CBLK_UNDERRUN_MSK) {
- android_atomic_and(~CBLK_UNDERRUN_MSK, &flags);
+ if (flags & CBLK_UNDERRUN) {
+ android_atomic_and(~CBLK_UNDERRUN, &flags);
}
return u;
}
-bool audio_track_cblk_t::stepServer(uint32_t frameCount)
+bool audio_track_cblk_t::stepServer(size_t stepCount, size_t frameCount, bool isOut)
{
- ALOGV("stepserver %08x %08x %d", user, server, frameCount);
+ ALOGV("stepserver %08x %08x %d", user, server, stepCount);
if (!tryLock()) {
ALOGW("stepServer() could not lock cblk");
@@ -1561,8 +1589,8 @@ bool audio_track_cblk_t::stepServer(uint32_t frameCount)
uint32_t s = server;
bool flushed = (s == user);
- s += frameCount;
- if (flags & CBLK_DIRECTION_MSK) {
+ s += stepCount;
+ if (isOut) {
// Mark that we have read the first buffer so that next time stepUser() is called
// we switch to normal obtainBuffer() timeout period
if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) {
@@ -1587,43 +1615,42 @@ bool audio_track_cblk_t::stepServer(uint32_t frameCount)
}
}
- uint32_t fc = this->frameCount;
- if (s >= fc) {
+ if (s >= frameCount) {
// common case, server didn't just wrap
- if (s - fc >= serverBase ) {
- serverBase += fc;
+ if (s - frameCount >= serverBase ) {
+ serverBase += frameCount;
}
- } else if (s >= serverBase + fc) {
+ } else if (s >= serverBase + frameCount) {
// server just wrapped
- serverBase += fc;
+ serverBase += frameCount;
}
server = s;
- if (!(flags & CBLK_INVALID_MSK)) {
+ if (!(flags & CBLK_INVALID)) {
cv.signal();
}
lock.unlock();
return true;
}
-void* audio_track_cblk_t::buffer(uint32_t offset) const
+void* audio_track_cblk_t::buffer(void *buffers, size_t frameSize, uint32_t offset) const
{
return (int8_t *)buffers + (offset - userBase) * frameSize;
}
-uint32_t audio_track_cblk_t::framesAvailable()
+uint32_t audio_track_cblk_t::framesAvailable(size_t frameCount, bool isOut)
{
Mutex::Autolock _l(lock);
- return framesAvailable_l();
+ return framesAvailable_l(frameCount, isOut);
}
-uint32_t audio_track_cblk_t::framesAvailable_l()
+uint32_t audio_track_cblk_t::framesAvailable_l(size_t frameCount, bool isOut)
{
uint32_t u = user;
uint32_t s = server;
- if (flags & CBLK_DIRECTION_MSK) {
+ if (isOut) {
uint32_t limit = (s < loopStart) ? s : loopStart;
return limit + frameCount - u;
} else {
@@ -1631,12 +1658,12 @@ uint32_t audio_track_cblk_t::framesAvailable_l()
}
}
-uint32_t audio_track_cblk_t::framesReady()
+uint32_t audio_track_cblk_t::framesReady(bool isOut)
{
uint32_t u = user;
uint32_t s = server;
- if (flags & CBLK_DIRECTION_MSK) {
+ if (isOut) {
if (u < loopEnd) {
return u - s;
} else {
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index ce8ffc4..a010bb6 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -89,8 +89,8 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
- track_flags_t flags,
+ size_t frameCount,
+ track_flags_t *flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
pid_t tid,
@@ -106,7 +106,8 @@ public:
data.writeInt32(format);
data.writeInt32(channelMask);
data.writeInt32(frameCount);
- data.writeInt32((int32_t) flags);
+ track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
+ data.writeInt32(lFlags);
data.writeStrongBinder(sharedBuffer->asBinder());
data.writeInt32((int32_t) output);
data.writeInt32((int32_t) tid);
@@ -119,6 +120,10 @@ public:
if (lStatus != NO_ERROR) {
ALOGE("createTrack error: %s", strerror(-lStatus));
} else {
+ lFlags = reply.readInt32();
+ if (flags != NULL) {
+ *flags = lFlags;
+ }
lSessionId = reply.readInt32();
if (sessionId != NULL) {
*sessionId = lSessionId;
@@ -138,7 +143,7 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int frameCount,
+ size_t frameCount,
track_flags_t flags,
pid_t tid,
int *sessionId,
@@ -501,7 +506,7 @@ public:
return reply.readInt32();
}
- virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
+ virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
audio_io_handle_t output) const
{
Parcel data, reply;
@@ -522,7 +527,7 @@ public:
return status;
}
- virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const
+ virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -690,7 +695,7 @@ public:
return (audio_module_handle_t) reply.readInt32();
}
- virtual int32_t getPrimaryOutputSamplingRate()
+ virtual uint32_t getPrimaryOutputSamplingRate()
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -698,7 +703,7 @@ public:
return reply.readInt32();
}
- virtual int32_t getPrimaryOutputFrameCount()
+ virtual size_t getPrimaryOutputFrameCount()
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -723,7 +728,7 @@ status_t BnAudioFlinger::onTransact(
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
- size_t bufferCount = data.readInt32();
+ size_t frameCount = data.readInt32();
track_flags_t flags = (track_flags_t) data.readInt32();
sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
@@ -732,7 +737,8 @@ status_t BnAudioFlinger::onTransact(
status_t status;
sp<IAudioTrack> track = createTrack(pid,
(audio_stream_type_t) streamType, sampleRate, format,
- channelMask, bufferCount, flags, buffer, output, tid, &sessionId, &status);
+ channelMask, frameCount, &flags, buffer, output, tid, &sessionId, &status);
+ reply->writeInt32(flags);
reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(track->asBinder());
@@ -745,13 +751,13 @@ status_t BnAudioFlinger::onTransact(
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
- size_t bufferCount = data.readInt32();
+ size_t frameCount = data.readInt32();
track_flags_t flags = (track_flags_t) data.readInt32();
pid_t tid = (pid_t) data.readInt32();
int sessionId = data.readInt32();
status_t status;
sp<IAudioRecord> record = openRecord(pid, input,
- sampleRate, format, channelMask, bufferCount, flags, tid, &sessionId, &status);
+ sampleRate, format, channelMask, frameCount, flags, tid, &sessionId, &status);
reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(record->asBinder());
@@ -865,7 +871,8 @@ status_t BnAudioFlinger::onTransact(
case REGISTER_CLIENT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(data.readStrongBinder());
+ sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(
+ data.readStrongBinder());
registerClient(client);
return NO_ERROR;
} break;
@@ -965,8 +972,8 @@ status_t BnAudioFlinger::onTransact(
case GET_RENDER_POSITION: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
- uint32_t halFrames;
- uint32_t dspFrames;
+ size_t halFrames;
+ size_t dspFrames;
status_t status = getRenderPosition(&halFrames, &dspFrames, output);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1043,7 +1050,8 @@ status_t BnAudioFlinger::onTransact(
int id;
int enabled;
- sp<IEffect> effect = createEffect(pid, &desc, client, priority, output, sessionId, &status, &id, &enabled);
+ sp<IEffect> effect = createEffect(pid, &desc, client, priority, output, sessionId,
+ &status, &id, &enabled);
reply->writeInt32(status);
reply->writeInt32(id);
reply->writeInt32(enabled);
diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp
index 4178b29..2d1e0f8 100644
--- a/media/libmedia/IAudioFlingerClient.cpp
+++ b/media/libmedia/IAudioFlingerClient.cpp
@@ -50,7 +50,8 @@ public:
ALOGV("ioConfigChanged stream %d", stream);
data.writeInt32(stream);
} else if (event != AudioSystem::OUTPUT_CLOSED && event != AudioSystem::INPUT_CLOSED) {
- const AudioSystem::OutputDescriptor *desc = (const AudioSystem::OutputDescriptor *)param2;
+ const AudioSystem::OutputDescriptor *desc =
+ (const AudioSystem::OutputDescriptor *)param2;
data.writeInt32(desc->samplingRate);
data.writeInt32(desc->format);
data.writeInt32(desc->channels);
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 401437c..769deae 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -399,13 +399,15 @@ status_t BnAudioPolicyService::onTransact(
case SET_PHONE_STATE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- reply->writeInt32(static_cast <uint32_t>(setPhoneState((audio_mode_t) data.readInt32())));
+ reply->writeInt32(static_cast <uint32_t>(setPhoneState(
+ (audio_mode_t) data.readInt32())));
return NO_ERROR;
} break;
case SET_FORCE_USE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(data.readInt32());
+ audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(
+ data.readInt32());
audio_policy_forced_cfg_t config =
static_cast <audio_policy_forced_cfg_t>(data.readInt32());
reply->writeInt32(static_cast <uint32_t>(setForceUse(usage, config)));
@@ -414,7 +416,8 @@ status_t BnAudioPolicyService::onTransact(
case GET_FORCE_USE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
- audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(data.readInt32());
+ audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(
+ data.readInt32());
reply->writeInt32(static_cast <uint32_t>(getForceUse(usage)));
return NO_ERROR;
} break;
diff --git a/media/libmedia/SoundPool.cpp b/media/libmedia/SoundPool.cpp
index abc8899..ee70ef7 100644
--- a/media/libmedia/SoundPool.cpp
+++ b/media/libmedia/SoundPool.cpp
@@ -489,7 +489,7 @@ Sample::~Sample()
::close(mFd);
}
mData.clear();
- delete mUrl;
+ free(mUrl);
}
status_t Sample::doLoad()
@@ -568,8 +568,8 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
}
// initialize track
- int afFrameCount;
- int afSampleRate;
+ size_t afFrameCount;
+ uint32_t afSampleRate;
audio_stream_type_t streamType = mSoundPool->streamType();
if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
afFrameCount = kDefaultFrameCount;
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 253602d..42584fe 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -1036,7 +1036,7 @@ bool ToneGenerator::initAudioTrack() {
goto initAudioTrack_exit;
}
- mpAudioTrack->setVolume(mVolume, mVolume);
+ mpAudioTrack->setVolume(mVolume);
mState = TONE_INIT;
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index 8196e10..5b4071b 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -88,7 +88,8 @@ status_t Visualizer::setEnabled(bool enabled)
return status;
}
-status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate)
+status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags,
+ uint32_t rate)
{
if (rate > CAPTURE_RATE_MAX) {
return BAD_VALUE;
@@ -334,7 +335,8 @@ void Visualizer::controlStatusChanged(bool controlGranted) {
//-------------------------------------------------------------------------
-Visualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava)
+Visualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate,
+ bool bCanCallJava)
: Thread(bCanCallJava), mReceiver(receiver)
{
mSleepTimeUs = 1000000000 / captureRate;