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

Commit d42567cf authored by jiabin's avatar jiabin
Browse files

Keep extra reference of shared memory for AudioTrack data callback.

Keep extra reference of shared memory for AudioTrack data callback so
that the shared memory will remain valid when the native track is
restored.

Bug: 274815060
Test: manual
Test: atest AudioTrackTest
Change-Id: I76ce5b7b14732eb6921791c7ab8f283b447710eb
parent 89e07825
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -2185,7 +2185,6 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, const struct timespec *re
        // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to
        // keep them from going away if another thread re-creates the track during obtainBuffer()
        sp<AudioTrackClientProxy> proxy;
        sp<IMemory> iMem;

        {   // start of lock scope
            AutoMutex lock(mLock);
@@ -2211,8 +2210,9 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, const struct timespec *re
            }

            // Keep the extra references
            mProxyObtainBufferRef = mProxy;
            proxy = mProxy;
            iMem = mCblkMemory;
            mCblkMemoryObtainBufferRef = mCblkMemory;

            if (mState == STATE_STOPPING) {
                status = -EINTR;
@@ -2260,6 +2260,8 @@ void AudioTrack::releaseBuffer(const Buffer* audioBuffer)
    buffer.mFrameCount = stepCount;
    buffer.mRaw = audioBuffer->raw;

    sp<IMemory> tempMemory;
    sp<AudioTrackClientProxy> tempProxy;
    AutoMutex lock(mLock);
    if (audioBuffer->sequence != mSequence) {
        // This Buffer came from a different IAudioTrack instance, so ignore the releaseBuffer
@@ -2269,7 +2271,12 @@ void AudioTrack::releaseBuffer(const Buffer* audioBuffer)
    }
    mReleased += stepCount;
    mInUnderrun = false;
    mProxy->releaseBuffer(&buffer);
    mProxyObtainBufferRef->releaseBuffer(&buffer);
    // The extra reference of shared memory and proxy from `obtainBuffer` is not used after
    // calling `releaseBuffer`. Move the extra reference to a temp strong pointer so that it
    // will be cleared outside `releaseBuffer`.
    tempMemory = std::move(mCblkMemoryObtainBufferRef);
    tempProxy = std::move(mProxyObtainBufferRef);

    // restart track if it was disabled by audioflinger due to previous underrun
    restartIfDisabled();
+5 −0
Original line number Diff line number Diff line
@@ -1262,6 +1262,11 @@ public:
    audio_track_cblk_t*     mCblk;                  // re-load after mLock.unlock()
    audio_io_handle_t       mOutput = AUDIO_IO_HANDLE_NONE; // from AudioSystem::getOutputForAttr()

    // A copy of shared memory and proxy between obtainBuffer and releaseBuffer to keep the
    // shared memory valid when processing data.
    sp<IMemory>               mCblkMemoryObtainBufferRef GUARDED_BY(mLock);
    sp<AudioTrackClientProxy> mProxyObtainBufferRef GUARDED_BY(mLock);

    sp<AudioTrackThread>    mAudioTrackThread;
    bool                    mThreadCanCallJava;