diff options
author | Glenn Kasten <gkasten@google.com> | 2014-05-09 23:14:12 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-05-09 23:14:12 +0000 |
commit | 16821ec9e1619f4edcc87f21ea1537580109b14d (patch) | |
tree | 37a6c2c5cc999557c0140cc6f5c46fd44e2cc31f /media | |
parent | 01427884471391999393a15abbb95b5f0dce7d3b (diff) | |
parent | d776ac63ce9c013c9626226e43f7db606e035838 (diff) | |
download | frameworks_av-16821ec9e1619f4edcc87f21ea1537580109b14d.zip frameworks_av-16821ec9e1619f4edcc87f21ea1537580109b14d.tar.gz frameworks_av-16821ec9e1619f4edcc87f21ea1537580109b14d.tar.bz2 |
Merge "IAudioFlinger::openRecord returns IMemory(s)"
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 32 | ||||
-rw-r--r-- | media/libmedia/IAudioFlinger.cpp | 34 |
2 files changed, 54 insertions, 12 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 2c8605c..97ab8f8 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -484,6 +484,8 @@ status_t AudioRecord::openRecord_l(size_t epoch) 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; + sp<IMemory> iMem; // for cblk + sp<IMemory> bufferMem; sp<IAudioRecord> record = audioFlinger->openRecord(input, mSampleRate, mFormat, mChannelMask, @@ -491,6 +493,8 @@ status_t AudioRecord::openRecord_l(size_t epoch) &trackFlags, tid, &mSessionId, + iMem, + bufferMem, &status); ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId, "session ID changed from %d to %d", originalSessionId, mSessionId); @@ -504,7 +508,6 @@ status_t AudioRecord::openRecord_l(size_t epoch) // AudioFlinger now owns the reference to the I/O handle, // so we are no longer responsible for releasing it. - sp<IMemory> iMem = record->getCblk(); if (iMem == 0) { ALOGE("Could not get control block"); return NO_INIT; @@ -514,6 +517,22 @@ status_t AudioRecord::openRecord_l(size_t epoch) ALOGE("Could not get control block pointer"); return NO_INIT; } + audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer); + + // Starting address of buffers in shared memory. + // The buffers are either immediately after the control block, + // or in a separate area at discretion of server. + void *buffers; + if (bufferMem == 0) { + buffers = cblk + 1; + } else { + buffers = bufferMem->pointer(); + if (buffers == NULL) { + ALOGE("Could not get buffer pointer"); + return NO_INIT; + } + } + // invariant that mAudioRecord != 0 is true only after set() returns successfully if (mAudioRecord != 0) { mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); @@ -522,7 +541,7 @@ status_t AudioRecord::openRecord_l(size_t epoch) mAudioRecord = record; mCblkMemory = iMem; - audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer); + mBufferMemory = bufferMem; mCblk = cblk; // note that temp is the (possibly revised) value of frameCount if (temp < frameCount || (frameCount == 0 && temp == 0)) { @@ -552,11 +571,6 @@ status_t AudioRecord::openRecord_l(size_t epoch) 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(). @@ -631,6 +645,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *r // keep them from going away if another thread re-creates the track during obtainBuffer() sp<AudioRecordClientProxy> proxy; sp<IMemory> iMem; + sp<IMemory> bufferMem; { // start of lock scope AutoMutex lock(mLock); @@ -654,6 +669,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *r // Keep the extra references proxy = mProxy; iMem = mCblkMemory; + bufferMem = mBufferMemory; // Non-blocking if track is stopped if (!mActive) { @@ -986,7 +1002,7 @@ status_t AudioRecord::restoreRecord_l(const char *from) status_t result; // if the new IAudioRecord is created, openRecord_l() will modify the - // following member variables: mAudioRecord, mCblkMemory and mCblk. + // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory. // It will also delete the strong references on previous IAudioRecord and IMemory size_t position = mProxy->getPosition(); mNewPosition = position + mUpdatePeriod; diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index 1940fe7..0e2463e 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -169,6 +169,8 @@ public: track_flags_t *flags, pid_t tid, int *sessionId, + sp<IMemory>& cblk, + sp<IMemory>& buffers, status_t *status) { Parcel data, reply; @@ -188,6 +190,8 @@ public: lSessionId = *sessionId; } data.writeInt32(lSessionId); + cblk.clear(); + buffers.clear(); status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply); if (lStatus != NO_ERROR) { ALOGE("openRecord error: %s", strerror(-lStatus)); @@ -206,17 +210,34 @@ public: } lStatus = reply.readInt32(); record = interface_cast<IAudioRecord>(reply.readStrongBinder()); + cblk = interface_cast<IMemory>(reply.readStrongBinder()); + if (cblk != 0 && cblk->pointer() == NULL) { + cblk.clear(); + } + buffers = interface_cast<IMemory>(reply.readStrongBinder()); + if (buffers != 0 && buffers->pointer() == NULL) { + buffers.clear(); + } if (lStatus == NO_ERROR) { if (record == 0) { ALOGE("openRecord should have returned an IAudioRecord"); lStatus = UNKNOWN_ERROR; + } else if (cblk == 0) { + ALOGE("openRecord should have returned a cblk"); + lStatus = NO_MEMORY; } + // buffers is permitted to be 0 } else { - if (record != 0) { - ALOGE("openRecord returned an IAudioRecord but with status %d", lStatus); - record.clear(); + if (record != 0 || cblk != 0 || buffers != 0) { + ALOGE("openRecord returned an IAudioRecord, cblk, " + "or buffers but with status %d", lStatus); } } + if (lStatus != NO_ERROR) { + record.clear(); + cblk.clear(); + buffers.clear(); + } } if (status != NULL) { *status = lStatus; @@ -838,15 +859,20 @@ status_t BnAudioFlinger::onTransact( track_flags_t flags = (track_flags_t) data.readInt32(); pid_t tid = (pid_t) data.readInt32(); int sessionId = data.readInt32(); + sp<IMemory> cblk; + sp<IMemory> buffers; status_t status; sp<IAudioRecord> record = openRecord(input, - sampleRate, format, channelMask, &frameCount, &flags, tid, &sessionId, &status); + sampleRate, format, channelMask, &frameCount, &flags, tid, &sessionId, + cblk, buffers, &status); LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR)); reply->writeInt64(frameCount); reply->writeInt32(flags); reply->writeInt32(sessionId); reply->writeInt32(status); reply->writeStrongBinder(record->asBinder()); + reply->writeStrongBinder(cblk->asBinder()); + reply->writeStrongBinder(buffers->asBinder()); return NO_ERROR; } break; case SAMPLE_RATE: { |