summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2012-02-02 10:56:47 -0800
committerGlenn Kasten <gkasten@google.com>2012-02-14 07:30:48 -0800
commit6dbc1359f778575d09d6da722b060a6d72c2e7c5 (patch)
tree721c46e8b89595b51a80ee71c71542895edc1308
parent7a8b0ed6419e57dd8b41d3806893d63d3df91aab (diff)
downloadframeworks_av-6dbc1359f778575d09d6da722b060a6d72c2e7c5.zip
frameworks_av-6dbc1359f778575d09d6da722b060a6d72c2e7c5.tar.gz
frameworks_av-6dbc1359f778575d09d6da722b060a6d72c2e7c5.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.h4
-rw-r--r--include/media/IAudioRecord.h3
-rw-r--r--include/media/IAudioTrack.h3
-rw-r--r--media/libmedia/AudioRecord.cpp37
-rw-r--r--media/libmedia/AudioTrack.cpp16
-rw-r--r--media/libmedia/IAudioRecord.cpp5
-rw-r--r--media/libmedia/IAudioTrack.cpp5
-rw-r--r--services/audioflinger/AudioFlinger.cpp28
-rw-r--r--services/audioflinger/AudioFlinger.h13
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);