diff options
Diffstat (limited to 'media/libmedia')
-rw-r--r-- | media/libmedia/Android.mk | 1 | ||||
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 80 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 19 |
3 files changed, 56 insertions, 44 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index e0acae6..f3770e4 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -72,7 +72,6 @@ LOCAL_WHOLE_STATIC_LIBRARY := libmedia_helper LOCAL_MODULE:= libmedia LOCAL_C_INCLUDES := \ - $(call include-path-for, graphics corecg) \ $(TOP)/frameworks/native/include/media/openmax \ external/icu4c/common \ external/icu4c/i18n \ diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 700718d..4438dfd 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -41,30 +41,22 @@ status_t AudioRecord::getMinFrameCount( return BAD_VALUE; } - // default to 0 in case of error - *frameCount = 0; - - size_t size = 0; + size_t size; status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size); if (status != NO_ERROR) { - ALOGE("AudioSystem could not query the input buffer size; status %d", status); - return NO_INIT; + ALOGE("AudioSystem could not query the input buffer size for sampleRate %u, format %#x, " + "channelMask %#x; status %d", sampleRate, format, channelMask, status); + return status; } - if (size == 0) { + // We double the size of input buffer for ping pong use of record buffer. + // Assumes audio_is_linear_pcm(format) + if ((*frameCount = (size * 2) / (popcount(channelMask) * audio_bytes_per_sample(format))) == 0) { ALOGE("Unsupported configuration: sampleRate %u, format %#x, channelMask %#x", sampleRate, format, channelMask); return BAD_VALUE; } - // We double the size of input buffer for ping pong use of record buffer. - size <<= 1; - - // Assumes audio_is_linear_pcm(format) - uint32_t channelCount = popcount(channelMask); - size /= channelCount * audio_bytes_per_sample(format); - - *frameCount = size; return NO_ERROR; } @@ -110,10 +102,8 @@ AudioRecord::~AudioRecord() mAudioRecordThread->requestExitAndWait(); mAudioRecordThread.clear(); } - if (mAudioRecord != 0) { - mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); - mAudioRecord.clear(); - } + mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); + mAudioRecord.clear(); IPCThreadState::self()->flushCommands(); AudioSystem::releaseAudioSessionId(mSessionId, -1); } @@ -133,6 +123,11 @@ status_t AudioRecord::set( transfer_type transferType, audio_input_flags_t flags) { + ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %d, " + "notificationFrames %d, sessionId %d, transferType %d, flags %#x", + inputSource, sampleRate, format, channelMask, frameCountInt, notificationFrames, + sessionId, transferType, flags); + switch (transferType) { case TRANSFER_DEFAULT: if (cbf == NULL || threadCanCallJava) { @@ -163,16 +158,15 @@ status_t AudioRecord::set( } size_t frameCount = frameCountInt; - ALOGV("set(): sampleRate %u, channelMask %#x, frameCount %u", sampleRate, channelMask, - frameCount); - AutoMutex lock(mLock); + // invariant that mAudioRecord != 0 is true only after set() returns successfully if (mAudioRecord != 0) { ALOGE("Track already in use"); return INVALID_OPERATION; } + // handle default values first. if (inputSource == AUDIO_SOURCE_DEFAULT) { inputSource = AUDIO_SOURCE_MIC; } @@ -209,15 +203,19 @@ status_t AudioRecord::set( uint32_t channelCount = popcount(channelMask); mChannelCount = channelCount; - // Assumes audio_is_linear_pcm(format), else sizeof(uint8_t) - mFrameSize = channelCount * audio_bytes_per_sample(format); + if (audio_is_linear_pcm(format)) { + mFrameSize = channelCount * audio_bytes_per_sample(format); + } else { + mFrameSize = sizeof(uint8_t); + } // validate framecount - size_t minFrameCount = 0; + size_t minFrameCount; status_t status = AudioRecord::getMinFrameCount(&minFrameCount, sampleRate, format, channelMask); if (status != NO_ERROR) { - ALOGE("getMinFrameCount() failed; status %d", status); + ALOGE("getMinFrameCount() failed for sampleRate %u, format %#x, channelMask %#x; status %d", + sampleRate, format, channelMask, status); return status; } ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); @@ -258,7 +256,6 @@ status_t AudioRecord::set( mActive = false; mCbf = cbf; - mRefreshRemaining = true; mUserData = user; // TODO: add audio hardware input latency here mLatency = (1000*mFrameCount) / sampleRate; @@ -485,10 +482,12 @@ status_t AudioRecord::openRecord_l(size_t epoch) ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId, "session ID changed from %d to %d", originalSessionId, mSessionId); - if (record == 0 || status != NO_ERROR) { + if (status != NO_ERROR) { ALOGE("AudioFlinger could not create record track, status: %d", status); goto release; } + ALOG_ASSERT(record != 0); + // AudioFlinger now owns the reference to the I/O handle, // so we are no longer responsible for releasing it. @@ -502,27 +501,21 @@ status_t AudioRecord::openRecord_l(size_t epoch) ALOGE("Could not get control block pointer"); return NO_INIT; } + // invariant that mAudioRecord != 0 is true only after set() returns successfully if (mAudioRecord != 0) { mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); mDeathNotifier.clear(); } - - // We retain a copy of the I/O handle, but don't own the reference - mInput = input; mAudioRecord = record; + mCblkMemory = iMem; audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer); mCblk = cblk; - // note that temp is the (possibly revised) value of mFrameCount + // note that temp is the (possibly revised) value of frameCount if (temp < frameCount || (frameCount == 0 && temp == 0)) { ALOGW("Requested frameCount %u but received frameCount %u", frameCount, temp); } frameCount = temp; - // If IAudioRecord is re-created, don't let the requested frameCount - // decrease. This can confuse clients that cache frameCount(). - if (frameCount > mReqFrameCount) { - mReqFrameCount = frameCount; - } // FIXME missing fast track frameCount logic mAwaitBoost = false; @@ -544,10 +537,21 @@ status_t AudioRecord::openRecord_l(size_t epoch) } } - // starting address of buffers in shared memory + // We retain a copy of the I/O handle, but don't own the reference + mInput = input; + mRefreshRemaining = true; + + // Starting address of buffers in shared memory, immediately after the control block. This + // address is for the mapping within client address space. AudioFlinger::TrackBase::mBuffer + // is for the server address space. void *buffers = (char*)cblk + sizeof(audio_track_cblk_t); mFrameCount = frameCount; + // If IAudioRecord is re-created, don't let the requested frameCount + // decrease. This can confuse clients that cache frameCount(). + if (frameCount > mReqFrameCount) { + mReqFrameCount = frameCount; + } // update proxy mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize); diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 5c62260..adf3847 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -195,6 +195,11 @@ status_t AudioTrack::set( int uid, pid_t pid) { + ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %d, " + "flags #%x, notificationFrames %d, sessionId %d, transferType %d", + streamType, sampleRate, format, channelMask, frameCountInt, flags, notificationFrames, + sessionId, transferType); + switch (transferType) { case TRANSFER_DEFAULT: if (sharedBuffer != 0) { @@ -288,6 +293,9 @@ status_t AudioTrack::set( ALOGE("Invalid channel mask %#x", channelMask); return BAD_VALUE; } + mChannelMask = channelMask; + uint32_t channelCount = popcount(channelMask); + mChannelCount = channelCount; // AudioFlinger does not currently support 8-bit data in shared memory if (format == AUDIO_FORMAT_PCM_8_BIT && sharedBuffer != 0) { @@ -311,10 +319,6 @@ status_t AudioTrack::set( flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER); } - mChannelMask = channelMask; - uint32_t channelCount = popcount(channelMask); - mChannelCount = channelCount; - if (audio_is_linear_pcm(format)) { mFrameSize = channelCount * audio_bytes_per_sample(format); mFrameSizeAF = channelCount * sizeof(int16_t); @@ -1012,10 +1016,12 @@ status_t AudioTrack::createTrack_l(size_t epoch) mClientUid, &status); - if (track == 0) { + if (status != NO_ERROR) { ALOGE("AudioFlinger could not create track, status: %d", status); goto release; } + ALOG_ASSERT(track != 0); + // AudioFlinger now owns the reference to the I/O handle, // so we are no longer responsible for releasing it. @@ -1035,6 +1041,7 @@ status_t AudioTrack::createTrack_l(size_t epoch) mDeathNotifier.clear(); } mAudioTrack = track; + mCblkMemory = iMem; audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer); mCblk = cblk; @@ -1046,6 +1053,7 @@ status_t AudioTrack::createTrack_l(size_t epoch) ALOGW("Requested frameCount %u but received frameCount %u", frameCount, temp); } frameCount = temp; + mAwaitBoost = false; if (mFlags & AUDIO_OUTPUT_FLAG_FAST) { if (trackFlags & IAudioFlinger::TRACK_FAST) { @@ -1099,6 +1107,7 @@ status_t AudioTrack::createTrack_l(size_t epoch) mAudioTrack->attachAuxEffect(mAuxEffectId); // FIXME don't believe this lie mLatency = afLatency + (1000*frameCount) / mSampleRate; + mFrameCount = frameCount; // If IAudioTrack is re-created, don't let the requested frameCount // decrease. This can confuse clients that cache frameCount(). |