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

Commit cc21e4f1 authored by Eric Laurent's avatar Eric Laurent
Browse files

AudioTrack: fix head position after restore

The head position transfered to the new track
by restoreTrack_l() must take into account the frames that
are dropped from the old track to avoid a non recoverable
offset in the playback head position returned to applications.

Bug: 11230062.
Change-Id: I51143a08b95e8f264ed709ae2054360315f2b8b1
parent 014e7fa2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -256,6 +256,8 @@ public:
        return mEpoch;
    }

    size_t      getFramesFilled();

private:
    size_t      mEpoch;
};
+3 −1
Original line number Diff line number Diff line
@@ -1662,7 +1662,9 @@ status_t AudioTrack::restoreTrack_l(const char *from)
    // if the new IAudioTrack is created, createTrack_l() will modify the
    // following member variables: mAudioTrack, mCblkMemory and mCblk.
    // It will also delete the strong references on previous IAudioTrack and IMemory
    size_t position = mProxy->getPosition();

    // take the frames that will be lost by track recreation into account in saved position
    size_t position = mProxy->getPosition() + mProxy->getFramesFilled();
    mNewPosition = position + mUpdatePeriod;
    size_t bufferPosition = mStaticProxy != NULL ? mStaticProxy->getBufferPosition() : 0;
    result = createTrack_l(mStreamType,
+21 −0
Original line number Diff line number Diff line
@@ -316,6 +316,27 @@ size_t ClientProxy::getMisalignment()
            (mFrameCountP2 - 1);
}

size_t ClientProxy::getFramesFilled() {
    audio_track_cblk_t* cblk = mCblk;
    int32_t front;
    int32_t rear;

    if (mIsOut) {
        front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront);
        rear = cblk->u.mStreaming.mRear;
    } else {
        rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
        front = cblk->u.mStreaming.mFront;
    }
    ssize_t filled = rear - front;
    // pipe should not be overfull
    if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
        ALOGE("Shared memory control block is corrupt (filled=%d); shutting down", filled);
        return 0;
    }
    return (size_t)filled;
}

// ---------------------------------------------------------------------------

void AudioTrackClientProxy::flush()