summaryrefslogtreecommitdiffstats
path: root/media/libmedia/AudioRecord.cpp
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2014-07-03 12:28:53 -0700
committerGlenn Kasten <gkasten@google.com>2014-07-17 12:13:18 -0700
commit7410591dad836434c72ddee66680802708b70c10 (patch)
tree697a233ffced732dbe113c927d9de61f14ea3f2c /media/libmedia/AudioRecord.cpp
parentb3b1660ecb67f61f9da54efced8677fa3a6f4863 (diff)
downloadframeworks_av-7410591dad836434c72ddee66680802708b70c10.zip
frameworks_av-7410591dad836434c72ddee66680802708b70c10.tar.gz
frameworks_av-7410591dad836434c72ddee66680802708b70c10.tar.bz2
Move AudioRecord frame count calculations to server
Buffer frame count and notification frame count are now calculated by server instead of by client. The server has more information and can do a better job. Also fix a few bugs: - If a fast track was re-created, even with same pipe depth, it would fail. Now it can correctly re-create a fast track provided the pipe depth is same. - Notification frame count for fast tracks was calculated by client as 1/2 of the total frame count, which is a large value due to the pipe. Now the notification frame count is set by server to the HAL frame count. This should reduce latency for fast tracks. - EVENT_OVERRUN were happening frequently when there was sample rate conversion, because the client didn't know about the sample rate conversion, and under-estimated the necessary buffer size. Now since server calculates the buffer sizes, EVENT_OVERRUN is unlikely. - RecordThread::createRecordTrack_l was checking for mono and stereo for fast tracks. This is not necessary, and now we can handle a multi-channel fast track. Bug: 7498763 Change-Id: I0c581618e8db33084d5ff9ed50a592990c9749e8
Diffstat (limited to 'media/libmedia/AudioRecord.cpp')
-rw-r--r--media/libmedia/AudioRecord.cpp53
1 files changed, 9 insertions, 44 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index c474a25..80c8c5e 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -211,7 +211,7 @@ status_t AudioRecord::set(
mReqFrameCount = frameCount;
mNotificationFramesReq = notificationFrames;
- mNotificationFramesAct = 0;
+ // mNotificationFramesAct is initialized in openRecord_l
if (sessionId == AUDIO_SESSION_ALLOCATE) {
mSessionId = AudioSystem::newAudioSessionId();
@@ -444,42 +444,6 @@ status_t AudioRecord::openRecord_l(size_t epoch)
}
}
- // FIXME Assume double buffering, because we don't know the true HAL sample rate
- const uint32_t nBuffering = 2;
-
- mNotificationFramesAct = mNotificationFramesReq;
- size_t frameCount = mReqFrameCount;
-
- if (!(mFlags & AUDIO_INPUT_FLAG_FAST)) {
- // validate framecount
- // If fast track was not requested, this preserves
- // the old behavior of validating on client side.
- // FIXME Eventually the validation should be done on server side
- // regardless of whether it's a fast or normal track. It's debatable
- // whether to account for the input latency to provision buffers appropriately.
- size_t minFrameCount;
- status = AudioRecord::getMinFrameCount(&minFrameCount,
- mSampleRate, mFormat, mChannelMask);
- if (status != NO_ERROR) {
- ALOGE("getMinFrameCount() failed for sampleRate %u, format %#x, channelMask %#x; "
- "status %d",
- mSampleRate, mFormat, mChannelMask, status);
- return status;
- }
-
- if (frameCount == 0) {
- frameCount = minFrameCount;
- } else if (frameCount < minFrameCount) {
- ALOGE("frameCount %zu < minFrameCount %zu", frameCount, minFrameCount);
- return BAD_VALUE;
- }
-
- // Make sure that application is notified with sufficient margin before overrun
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/2) {
- mNotificationFramesAct = frameCount/2;
- }
- }
-
audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat,
mChannelMask, mSessionId, mFlags);
if (input == AUDIO_IO_HANDLE_NONE) {
@@ -492,12 +456,13 @@ status_t AudioRecord::openRecord_l(size_t epoch)
// Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
// we must release it ourselves if anything goes wrong.
+ size_t frameCount = mReqFrameCount;
size_t temp = frameCount; // temp may be replaced by a revised value of frameCount,
// but we will still need the original value also
int originalSessionId = mSessionId;
// The notification frame count is the period between callbacks, as suggested by the server.
- size_t notificationFrames;
+ size_t notificationFrames = mNotificationFramesReq;
sp<IMemory> iMem; // for cblk
sp<IMemory> bufferMem;
@@ -576,14 +541,14 @@ status_t AudioRecord::openRecord_l(size_t epoch)
// once denied, do not request again if IAudioRecord is re-created
mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
}
- // Theoretically double-buffering is not required for fast tracks,
- // due to tighter scheduling. But in practice, to accomodate kernels with
- // scheduling jitter, and apps with computation jitter, we use double-buffering.
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/nBuffering) {
- mNotificationFramesAct = frameCount/nBuffering;
- }
}
+ // Make sure that application is notified with sufficient margin before overrun
+ if (notificationFrames == 0 || notificationFrames > frameCount) {
+ ALOGW("Received notificationFrames %zu for frameCount %zu", notificationFrames, frameCount);
+ }
+ mNotificationFramesAct = notificationFrames;
+
// We retain a copy of the I/O handle, but don't own the reference
mInput = input;
mRefreshRemaining = true;