diff options
Diffstat (limited to 'services/audioflinger')
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 8 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 2 | ||||
-rw-r--r-- | services/audioflinger/RecordTracks.h | 3 | ||||
-rw-r--r-- | services/audioflinger/Threads.cpp | 3 | ||||
-rw-r--r-- | services/audioflinger/TrackBase.h | 6 | ||||
-rw-r--r-- | services/audioflinger/Tracks.cpp | 37 |
6 files changed, 47 insertions, 12 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index eb00c82..c1c95f8 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1313,6 +1313,8 @@ sp<IAudioRecord> AudioFlinger::openRecord( IAudioFlinger::track_flags_t *flags, pid_t tid, int *sessionId, + sp<IMemory>& cblk, + sp<IMemory>& buffers, status_t *status) { sp<RecordThread::RecordTrack> recordTrack; @@ -1321,6 +1323,9 @@ sp<IAudioRecord> AudioFlinger::openRecord( status_t lStatus; int lSessionId; + cblk.clear(); + buffers.clear(); + // check calling permissions if (!recordingAllowed()) { ALOGE("openRecord() permission denied: recording not allowed"); @@ -1396,6 +1401,9 @@ sp<IAudioRecord> AudioFlinger::openRecord( goto Exit; } + cblk = recordTrack->getCblk(); + buffers = recordTrack->getBuffers(); + // return handle to client recordHandle = new RecordHandle(recordTrack); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index ec32edd..462f9e2 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -120,6 +120,8 @@ public: IAudioFlinger::track_flags_t *flags, pid_t tid, int *sessionId, + sp<IMemory>& cblk, + sp<IMemory>& buffers, status_t *status /*non-NULL*/); virtual uint32_t sampleRate(audio_io_handle_t output) const; diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h index 6fc06d8..4ca2ad4 100644 --- a/services/audioflinger/RecordTracks.h +++ b/services/audioflinger/RecordTracks.h @@ -29,7 +29,8 @@ public: audio_channel_mask_t channelMask, size_t frameCount, int sessionId, - int uid); + int uid, + bool isFast); virtual ~RecordTrack(); virtual status_t start(AudioSystem::sync_event_t event, int triggerSession); diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index 2c5a0eb..be7d725 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -5163,7 +5163,8 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe Mutex::Autolock _l(mLock); track = new RecordTrack(this, client, sampleRate, - format, channelMask, frameCount, sessionId, uid); + format, channelMask, frameCount, sessionId, uid, + (*flags & IAudioFlinger::TRACK_FAST) != 0); lStatus = track->initCheck(); if (lStatus != NO_ERROR) { diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h index 58705c4..06023fd 100644 --- a/services/audioflinger/TrackBase.h +++ b/services/audioflinger/TrackBase.h @@ -48,7 +48,8 @@ public: const sp<IMemory>& sharedBuffer, int sessionId, int uid, - bool isOut); + bool isOut, + bool useReadOnlyHeap = false); virtual ~TrackBase(); virtual status_t initCheck() const { return getCblk() != 0 ? NO_ERROR : NO_MEMORY; } @@ -61,6 +62,8 @@ public: int uid() const { return mUid; } virtual status_t setSyncEvent(const sp<SyncEvent>& event); + sp<IMemory> getBuffers() const { return mBufferMemory; } + protected: TrackBase(const TrackBase&); TrackBase& operator = (const TrackBase&); @@ -112,6 +115,7 @@ protected: /*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const sp<IMemory> mCblkMemory; audio_track_cblk_t* mCblk; + sp<IMemory> mBufferMemory; // currently non-0 for fast RecordTrack only void* mBuffer; // start of track buffer, typically in shared memory // except for OutputTrack when it is in local memory // we don't really need a lock for these diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index 1064fd1..5889567 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -69,7 +69,8 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( const sp<IMemory>& sharedBuffer, int sessionId, int clientUid, - bool isOut) + bool isOut, + bool useReadOnlyHeap) : RefBase(), mThread(thread), mClient(client), @@ -110,7 +111,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize); size_t size = sizeof(audio_track_cblk_t); size_t bufferSize = (sharedBuffer == 0 ? roundup(frameCount) : frameCount) * mFrameSize; - if (sharedBuffer == 0) { + if (sharedBuffer == 0 && !useReadOnlyHeap) { size += bufferSize; } @@ -132,15 +133,31 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( // construct the shared structure in-place. if (mCblk != NULL) { new(mCblk) audio_track_cblk_t(); - // clear all buffers - if (sharedBuffer == 0) { - mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t); + if (useReadOnlyHeap) { + const sp<MemoryDealer> roHeap(thread->readOnlyHeap()); + if (roHeap == 0 || + (mBufferMemory = roHeap->allocate(bufferSize)) == 0 || + (mBuffer = mBufferMemory->pointer()) == NULL) { + ALOGE("not enough memory for read-only buffer size=%zu", bufferSize); + if (roHeap != 0) { + roHeap->dump("buffer"); + } + mCblkMemory.clear(); + mBufferMemory.clear(); + return; + } memset(mBuffer, 0, bufferSize); } else { - mBuffer = sharedBuffer->pointer(); + // clear all buffers + if (sharedBuffer == 0) { + mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t); + memset(mBuffer, 0, bufferSize); + } else { + mBuffer = sharedBuffer->pointer(); #if 0 - mCblk->mFlags = CBLK_FORCEREADY; // FIXME hack, need to fix the track ready logic + mCblk->mFlags = CBLK_FORCEREADY; // FIXME hack, need to fix the track ready logic #endif + } } #ifdef TEE_SINK @@ -1819,9 +1836,11 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack( audio_channel_mask_t channelMask, size_t frameCount, int sessionId, - int uid) + int uid, + bool isFast) : TrackBase(thread, client, sampleRate, format, - channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, uid, false /*isOut*/), + channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, uid, false /*isOut*/, + isFast /*useReadOnlyHeap*/), mOverflow(false), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpOutFrameCount(0), // See real initialization of mRsmpInFront at RecordThread::start() mRsmpInUnrel(0), mRsmpInFront(0), mFramesToDrop(0), mResamplerBufferProvider(NULL) |