summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2012-04-24 14:35:14 -0700
committerGlenn Kasten <gkasten@google.com>2012-04-25 18:41:32 -0700
commite0fa467e1150c65a7b1b1ed904c579b40f97c9df (patch)
tree44ae1e182fd15695fccf5d1f396f99edc7942ee5 /media/libmedia
parente370bb62b89d2f2980f519392010ea08a24c558e (diff)
downloadframeworks_av-e0fa467e1150c65a7b1b1ed904c579b40f97c9df.zip
frameworks_av-e0fa467e1150c65a7b1b1ed904c579b40f97c9df.tar.gz
frameworks_av-e0fa467e1150c65a7b1b1ed904c579b40f97c9df.tar.bz2
Move frame count calculations for fast tracks
For fast tracks: move the default and minimum frame count calculations from client to server. If accepted, the default and minimum frame count is the fast mixer (HAL) frame count. If denied, the default and minimum frame count is the same as it currently is for normal tracks. For normal tracks: there is no change yet, preserve legacy behavior for now but add a FIXME to change this later. Bug fix: the test for buffer alignment matches channelCount was wrong. Bug fix: check for 8-bit data in shared memory, which isn't supported. Optimizations: - in set(), only call AudioSystem::getOutputSamplingRate() when needed - in createTrack_l(), only call AudioSystem::getSamplingRate() and AudioSystem::getFrameCount() when needed Change-Id: I79d2fe507db1a8f7bb094c71da8a129951dbb82f
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/AudioTrack.cpp128
1 files changed, 84 insertions, 44 deletions
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index b1be8b1..cd419bd 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -54,6 +54,12 @@ status_t AudioTrack::getMinFrameCount(
audio_stream_type_t streamType,
uint32_t sampleRate)
{
+ // FIXME merge with similar code in createTrack_l(), except we're missing
+ // some information here that is available in createTrack_l():
+ // audio_io_handle_t output
+ // audio_format_t format
+ // audio_channel_mask_t channelMask
+ // audio_output_flags_t flags
int afSampleRate;
if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
return NO_INIT;
@@ -201,11 +207,11 @@ status_t AudioTrack::set(
streamType = AUDIO_STREAM_MUSIC;
}
- int afSampleRate;
- if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
- return NO_INIT;
- }
if (sampleRate == 0) {
+ int afSampleRate;
+ if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
+ return NO_INIT;
+ }
sampleRate = afSampleRate;
}
@@ -223,6 +229,12 @@ status_t AudioTrack::set(
return BAD_VALUE;
}
+ // AudioFlinger does not currently support 8-bit data in shared memory
+ if (format == AUDIO_FORMAT_PCM_8_BIT && sharedBuffer != 0) {
+ ALOGE("8-bit data in shared memory is not supported");
+ return BAD_VALUE;
+ }
+
// force direct flag if format is not linear PCM
if (!audio_is_linear_pcm(format)) {
flags = (audio_output_flags_t)
@@ -744,14 +756,6 @@ status_t AudioTrack::createTrack_l(
return NO_INIT;
}
- int afSampleRate;
- if (AudioSystem::getSamplingRate(output, streamType, &afSampleRate) != NO_ERROR) {
- return NO_INIT;
- }
- int afFrameCount;
- if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
- return NO_INIT;
- }
uint32_t afLatency;
if (AudioSystem::getLatency(output, streamType, &afLatency) != NO_ERROR) {
return NO_INIT;
@@ -768,14 +772,57 @@ status_t AudioTrack::createTrack_l(
ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client");
flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
}
- ALOGV("createTrack_l() output %d afFrameCount %d afLatency %d", output, afFrameCount, afLatency);
+ ALOGV("createTrack_l() output %d afLatency %d", output, afLatency);
mNotificationFramesAct = mNotificationFramesReq;
+
if (!audio_is_linear_pcm(format)) {
+
if (sharedBuffer != 0) {
+ // Same comment as below about ignoring frameCount parameter for set()
frameCount = sharedBuffer->size();
+ } else if (frameCount == 0) {
+ int afFrameCount;
+ if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
+ return NO_INIT;
+ }
+ frameCount = afFrameCount;
}
- } else {
+
+ } else if (sharedBuffer != 0) {
+
+ // Ensure that buffer alignment matches channelCount
+ int channelCount = popcount(channelMask);
+ // 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) {
+ // 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);
+ return BAD_VALUE;
+ }
+
+ // When initializing a shared buffer AudioTrack via constructors,
+ // 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);
+
+ } else if (!(flags & AUDIO_OUTPUT_FLAG_FAST)) {
+
+ // FIXME move these calculations and associated checks to server
+ int afSampleRate;
+ if (AudioSystem::getSamplingRate(output, streamType, &afSampleRate) != NO_ERROR) {
+ return NO_INIT;
+ }
+ int afFrameCount;
+ if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
+ return NO_INIT;
+ }
+
// Ensure that buffer depth covers at least audio hardware latency
uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
if (minBufCount < 2) minBufCount = 2;
@@ -784,38 +831,27 @@ status_t AudioTrack::createTrack_l(
ALOGV("minFrameCount: %d, afFrameCount=%d, minBufCount=%d, sampleRate=%d, afSampleRate=%d"
", afLatency=%d",
minFrameCount, afFrameCount, minBufCount, sampleRate, afSampleRate, afLatency);
-#define MIN_FRAME_COUNT_FAST 128 // FIXME hard-coded
- if ((flags & AUDIO_OUTPUT_FLAG_FAST) && (minFrameCount > MIN_FRAME_COUNT_FAST)) {
- minFrameCount = MIN_FRAME_COUNT_FAST;
- }
- if (sharedBuffer == 0) {
- if (frameCount == 0) {
- frameCount = minFrameCount;
- }
- if (mNotificationFramesAct == 0) {
- mNotificationFramesAct = frameCount/2;
- }
- // Make sure that application is notified with sufficient margin
- // before underrun
- if (mNotificationFramesAct > (uint32_t)frameCount/2) {
- mNotificationFramesAct = frameCount/2;
- }
- if (frameCount < minFrameCount) {
- // not ALOGW because it happens all the time when playing key clicks over A2DP
- ALOGV("Minimum buffer size corrected from %d to %d",
- frameCount, minFrameCount);
- frameCount = minFrameCount;
- }
- } else {
- // Ensure that buffer alignment matches channelCount
- int channelCount = popcount(channelMask);
- if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) {
- ALOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount);
- return BAD_VALUE;
- }
- frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t);
+ if (frameCount == 0) {
+ frameCount = minFrameCount;
+ }
+ if (mNotificationFramesAct == 0) {
+ mNotificationFramesAct = frameCount/2;
+ }
+ // Make sure that application is notified with sufficient margin
+ // before underrun
+ if (mNotificationFramesAct > (uint32_t)frameCount/2) {
+ mNotificationFramesAct = frameCount/2;
}
+ if (frameCount < minFrameCount) {
+ // not ALOGW because it happens all the time when playing key clicks over A2DP
+ ALOGV("Minimum buffer size corrected from %d to %d",
+ frameCount, minFrameCount);
+ frameCount = minFrameCount;
+ }
+
+ } else {
+ // For fast tracks, the frame count calculations and checks are done by server
}
IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT;
@@ -864,6 +900,9 @@ status_t AudioTrack::createTrack_l(
} else {
ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %u", mCblk->frameCount);
}
+ if (sharedBuffer == 0) {
+ mNotificationFramesAct = mCblk->frameCount/2;
+ }
}
if (sharedBuffer == 0) {
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
@@ -879,6 +918,7 @@ status_t AudioTrack::createTrack_l(
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
mRemainingFrames = mNotificationFramesAct;
+ // FIXME don't believe this lie
mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate;
return NO_ERROR;
}