diff options
author | Glenn Kasten <gkasten@google.com> | 2012-02-02 10:56:47 -0800 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2012-02-14 07:30:48 -0800 |
commit | 6a20b26d99d40b32a711e6fd5da51da73949aa73 (patch) | |
tree | 4f62a6a7f8a688ba9ccb30c1adca7b375c3045f8 | |
parent | 4212d3fc736712d6e5fb69d5067ce8d9a83806ef (diff) | |
download | frameworks_base-6a20b26d99d40b32a711e6fd5da51da73949aa73.zip frameworks_base-6a20b26d99d40b32a711e6fd5da51da73949aa73.tar.gz frameworks_base-6a20b26d99d40b32a711e6fd5da51da73949aa73.tar.bz2 |
AudioRecord and AudioTrack client tid
Inform AudioFlinger of the tid of the callback thread.
Change-Id: I670df92dd06749b057238b48ed1094b13aab720b
-rw-r--r-- | include/media/AudioRecord.h | 4 | ||||
-rw-r--r-- | include/media/IAudioRecord.h | 3 | ||||
-rw-r--r-- | include/media/IAudioTrack.h | 3 | ||||
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 37 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 16 | ||||
-rw-r--r-- | media/libmedia/IAudioRecord.cpp | 5 | ||||
-rw-r--r-- | media/libmedia/IAudioTrack.cpp | 5 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 28 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 13 |
9 files changed, 79 insertions, 35 deletions
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index ca57f9e..437a89c 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -341,7 +341,7 @@ private: private: friend class AudioRecord; virtual bool threadLoop(); - virtual status_t readyToRun() { return NO_ERROR; } + virtual status_t readyToRun(); virtual void onFirstRef() {} AudioRecord& mReceiver; }; @@ -359,7 +359,9 @@ private: sp<IAudioRecord> mAudioRecord; sp<IMemory> mCblkMemory; sp<ClientRecordThread> mClientRecordThread; + status_t mReadyToRun; Mutex mLock; + Condition mCondition; uint32_t mFrameCount; diff --git a/include/media/IAudioRecord.h b/include/media/IAudioRecord.h index 46735de..7869020 100644 --- a/include/media/IAudioRecord.h +++ b/include/media/IAudioRecord.h @@ -37,8 +37,9 @@ public: /* After it's created the track is not active. Call start() to * make it active. If set, the callback will start being called. + * tid identifies the client callback thread, or 0 if not needed. */ - virtual status_t start() = 0; + virtual status_t start(pid_t tid) = 0; /* Stop a track. If set, the callback will cease being called and * obtainBuffer will return an error. Buffers that are already released diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h index b83e552..b346722 100644 --- a/include/media/IAudioTrack.h +++ b/include/media/IAudioTrack.h @@ -40,8 +40,9 @@ public: /* After it's created the track is not active. Call start() to * make it active. If set, the callback will start being called. + * tid identifies the client callback thread, or 0 if not needed. */ - virtual status_t start() = 0; + virtual status_t start(pid_t tid) = 0; /* Stop a track. If set, the callback will cease being called and * obtainBuffer will return an error. Buffers that are already released diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index b74b3e3..a4068ff 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -304,10 +304,25 @@ status_t AudioRecord::start() if (mActive == 0) { mActive = 1; + pid_t tid; + if (t != 0) { + mReadyToRun = WOULD_BLOCK; + t->run("ClientRecordThread", ANDROID_PRIORITY_AUDIO); + tid = t->getTid(); // pid_t is unknown until run() + ALOGV("getTid=%d", tid); + if (tid == -1) { + tid = 0; + } + // thread blocks in readyToRun() + } else { + tid = 0; // not gettid() + } + cblk->lock.lock(); if (!(cblk->flags & CBLK_INVALID_MSK)) { cblk->lock.unlock(); - ret = mAudioRecord->start(); + ALOGV("mAudioRecord->start(tid=%d)", tid); + ret = mAudioRecord->start(tid); cblk->lock.lock(); if (ret == DEAD_OBJECT) { android_atomic_or(CBLK_INVALID_ON, &cblk->flags); @@ -322,7 +337,9 @@ status_t AudioRecord::start() cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; cblk->waitTimeMs = 0; if (t != 0) { - t->run("ClientRecordThread", ANDROID_PRIORITY_AUDIO); + // thread unblocks in readyToRun() and returns NO_ERROR + mReadyToRun = NO_ERROR; + mCondition.signal(); } else { mPreviousPriority = getpriority(PRIO_PROCESS, 0); mPreviousSchedulingGroup = androidGetThreadSchedulingGroup(0); @@ -330,6 +347,9 @@ status_t AudioRecord::start() } } else { mActive = 0; + // thread unblocks in readyToRun() and returns NO_INIT + mReadyToRun = NO_INIT; + mCondition.signal(); } } @@ -522,7 +542,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) ALOGW( "obtainBuffer timed out (is the CPU pegged?) " "user=%08x, server=%08x", cblk->user, cblk->server); cblk->lock.unlock(); - result = mAudioRecord->start(); + result = mAudioRecord->start(0); // callback thread hasn't changed cblk->lock.lock(); if (result == DEAD_OBJECT) { android_atomic_or(CBLK_INVALID_ON, &cblk->flags); @@ -760,7 +780,7 @@ status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask, mFrameCount, mFlags, getInput_l()); if (result == NO_ERROR) { - result = mAudioRecord->start(); + result = mAudioRecord->start(0); // callback thread hasn't changed } if (result != NO_ERROR) { mActive = false; @@ -811,6 +831,15 @@ bool AudioRecord::ClientRecordThread::threadLoop() return mReceiver.processAudioBuffer(this); } +status_t AudioRecord::ClientRecordThread::readyToRun() +{ + AutoMutex(mReceiver.mLock); + while (mReceiver.mReadyToRun == WOULD_BLOCK) { + mReceiver.mCondition.wait(mReceiver.mLock); + } + return mReceiver.mReadyToRun; +} + // ------------------------------------------------------------------------- }; // namespace android diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 087d7b2..2518921 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -362,18 +362,26 @@ void AudioTrack::start() cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; cblk->waitTimeMs = 0; android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); + pid_t tid; if (t != 0) { t->run("AudioTrackThread", ANDROID_PRIORITY_AUDIO); + tid = t->getTid(); // pid_t is unknown until run() + ALOGV("getTid=%d", tid); + if (tid == -1) { + tid = 0; + } } else { mPreviousPriority = getpriority(PRIO_PROCESS, 0); mPreviousSchedulingGroup = androidGetThreadSchedulingGroup(0); androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); + tid = 0; // not gettid() } ALOGV("start %p before lock cblk %p", this, mCblk); if (!(cblk->flags & CBLK_INVALID_MSK)) { cblk->lock.unlock(); - status = mAudioTrack->start(); + ALOGV("mAudioTrack->start(tid=%d)", tid); + status = mAudioTrack->start(tid); cblk->lock.lock(); if (status == DEAD_OBJECT) { android_atomic_or(CBLK_INVALID_ON, &cblk->flags); @@ -895,7 +903,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) "user=%08x, server=%08x", this, cblk->user, cblk->server); //unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140) cblk->lock.unlock(); - result = mAudioTrack->start(); + result = mAudioTrack->start(0); // callback thread hasn't changed cblk->lock.lock(); if (result == DEAD_OBJECT) { android_atomic_or(CBLK_INVALID_ON, &cblk->flags); @@ -927,7 +935,7 @@ create_new_track: if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) { android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); ALOGW("obtainBuffer() track %p disabled, restarting", this); - mAudioTrack->start(); + mAudioTrack->start(0); // callback thread hasn't changed } cblk->waitTimeMs = 0; @@ -1218,7 +1226,7 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) } } if (mActive) { - result = mAudioTrack->start(); + result = mAudioTrack->start(0); // callback thread hasn't changed ALOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result); } if (fromStart && result == NO_ERROR) { diff --git a/media/libmedia/IAudioRecord.cpp b/media/libmedia/IAudioRecord.cpp index 8c7a960..6b473c9 100644 --- a/media/libmedia/IAudioRecord.cpp +++ b/media/libmedia/IAudioRecord.cpp @@ -42,10 +42,11 @@ public: { } - virtual status_t start() + virtual status_t start(pid_t tid) { Parcel data, reply; data.writeInterfaceToken(IAudioRecord::getInterfaceDescriptor()); + data.writeInt32(tid); status_t status = remote()->transact(START, data, &reply); if (status == NO_ERROR) { status = reply.readInt32(); @@ -90,7 +91,7 @@ status_t BnAudioRecord::onTransact( } break; case START: { CHECK_INTERFACE(IAudioRecord, data, reply); - reply->writeInt32(start()); + reply->writeInt32(start(data.readInt32())); return NO_ERROR; } break; case STOP: { diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp index e618619..3724642 100644 --- a/media/libmedia/IAudioTrack.cpp +++ b/media/libmedia/IAudioTrack.cpp @@ -58,10 +58,11 @@ public: return cblk; } - virtual status_t start() + virtual status_t start(pid_t tid) { Parcel data, reply; data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor()); + data.writeInt32(tid); status_t status = remote()->transact(START, data, &reply); if (status == NO_ERROR) { status = reply.readInt32(); @@ -130,7 +131,7 @@ status_t BnAudioTrack::onTransact( } break; case START: { CHECK_INTERFACE(IAudioTrack, data, reply); - reply->writeInt32(start()); + reply->writeInt32(start(data.readInt32())); return NO_ERROR; } break; case STOP: { diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 5c964b2..fb163d1 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -3494,11 +3494,11 @@ bool AudioFlinger::PlaybackThread::Track::isReady() const { return false; } -status_t AudioFlinger::PlaybackThread::Track::start() +status_t AudioFlinger::PlaybackThread::Track::start(pid_t tid) { status_t status = NO_ERROR; - ALOGV("start(%d), calling pid %d session %d", - mName, IPCThreadState::self()->getCallingPid(), mSessionId); + ALOGV("start(%d), calling pid %d session %d tid %d", + mName, IPCThreadState::self()->getCallingPid(), mSessionId, tid); sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); @@ -3717,12 +3717,12 @@ getNextBuffer_exit: return NOT_ENOUGH_DATA; } -status_t AudioFlinger::RecordThread::RecordTrack::start() +status_t AudioFlinger::RecordThread::RecordTrack::start(pid_t tid) { sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { RecordThread *recordThread = (RecordThread *)thread.get(); - return recordThread->start(this); + return recordThread->start(this, tid); } else { return BAD_VALUE; } @@ -3789,9 +3789,9 @@ AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack() clearBufferQueue(); } -status_t AudioFlinger::PlaybackThread::OutputTrack::start() +status_t AudioFlinger::PlaybackThread::OutputTrack::start(pid_t tid) { - status_t status = Track::start(); + status_t status = Track::start(tid); if (status != NO_ERROR) { return status; } @@ -3821,7 +3821,7 @@ bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t fr uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs(); if (!mActive && frames != 0) { - start(); + start(0); sp<ThreadBase> thread = mThread.promote(); if (thread != 0) { MixerThread *mixerThread = (MixerThread *)thread.get(); @@ -4056,8 +4056,8 @@ sp<IMemory> AudioFlinger::TrackHandle::getCblk() const { return mTrack->getCblk(); } -status_t AudioFlinger::TrackHandle::start() { - return mTrack->start(); +status_t AudioFlinger::TrackHandle::start(pid_t tid) { + return mTrack->start(tid); } void AudioFlinger::TrackHandle::stop() { @@ -4179,9 +4179,9 @@ sp<IMemory> AudioFlinger::RecordHandle::getCblk() const { return mRecordTrack->getCblk(); } -status_t AudioFlinger::RecordHandle::start() { +status_t AudioFlinger::RecordHandle::start(pid_t tid) { ALOGV("RecordHandle::start()"); - return mRecordTrack->start(); + return mRecordTrack->start(tid); } void AudioFlinger::RecordHandle::stop() { @@ -4473,9 +4473,9 @@ Exit: return track; } -status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack) +status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack, pid_t tid) { - ALOGV("RecordThread::start"); + ALOGV("RecordThread::start tid=%d", tid); sp <ThreadBase> strongMe = this; status_t status = NO_ERROR; { diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index fdcd916..aa0ee76 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -314,7 +314,7 @@ private: int sessionId); virtual ~TrackBase(); - virtual status_t start() = 0; + virtual status_t start(pid_t tid) = 0; virtual void stop() = 0; sp<IMemory> getCblk() const { return mCblkMemory; } audio_track_cblk_t* cblk() const { return mCblk; } @@ -586,7 +586,7 @@ private: virtual ~Track(); void dump(char* buffer, size_t size); - virtual status_t start(); + virtual status_t start(pid_t tid); virtual void stop(); void pause(); @@ -668,7 +668,7 @@ private: int frameCount); virtual ~OutputTrack(); - virtual status_t start(); + virtual status_t start(pid_t tid); virtual void stop(); bool write(int16_t* data, uint32_t frames); bool bufferQueueEmpty() const { return (mBufferQueue.size() == 0) ? true : false; } @@ -905,7 +905,7 @@ private: TrackHandle(const sp<PlaybackThread::Track>& track); virtual ~TrackHandle(); virtual sp<IMemory> getCblk() const; - virtual status_t start(); + virtual status_t start(pid_t tid); virtual void stop(); virtual void flush(); virtual void mute(bool); @@ -943,7 +943,7 @@ private: int sessionId); virtual ~RecordTrack(); - virtual status_t start(); + virtual status_t start(pid_t tid); virtual void stop(); bool overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; } @@ -988,6 +988,7 @@ private: status_t *status); status_t start(RecordTrack* recordTrack); + status_t start(RecordTrack* recordTrack, pid_t tid); void stop(RecordTrack* recordTrack); status_t dump(int fd, const Vector<String16>& args); AudioStreamIn* getInput() const; @@ -1028,7 +1029,7 @@ private: RecordHandle(const sp<RecordThread::RecordTrack>& recordTrack); virtual ~RecordHandle(); virtual sp<IMemory> getCblk() const; - virtual status_t start(); + virtual status_t start(pid_t tid); virtual void stop(); virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); |