Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a20b26d authored by Glenn Kasten's avatar Glenn Kasten
Browse files

AudioRecord and AudioTrack client tid

Inform AudioFlinger of the tid of the callback thread.

Change-Id: I670df92dd06749b057238b48ed1094b13aab720b
parent 4212d3fc
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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;

+2 −1
Original line number Diff line number Diff line
@@ -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 
+2 −1
Original line number Diff line number Diff line
@@ -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 
+33 −4
Original line number Diff line number Diff line
@@ -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
+12 −4
Original line number Diff line number Diff line
@@ -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) {
Loading