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

Commit 2048c229 authored by Haynes Mathew George's avatar Haynes Mathew George Committed by Eric Laurent
Browse files

AudioTrack: When paused, return cached playback position

An offload output can be re-used between two audio tracks having
the same configuration. A timestamp query for a paused track
while the other is running would return an incorrect time.
To fix this, cache the playback position on a pause() and return
this time when requested until the track is resumed.

Bug: 12826612.
Change-Id: Ia42b8b8fd2ba8993dfcc9abca72da48d71d78d74
parent a11111f9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -740,6 +740,7 @@ protected:

    bool                    mInUnderrun;            // whether track is currently in underrun state
    String8                 mName;                  // server's name for this IAudioTrack
    uint32_t                mPausedPosition;

private:
    class DeathNotifier : public IBinder::DeathRecipient {
+22 −3
Original line number Diff line number Diff line
@@ -85,7 +85,8 @@ AudioTrack::AudioTrack()
    : mStatus(NO_INIT),
      mIsTimed(false),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT)
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPausedPosition(0)
{
}

@@ -106,7 +107,8 @@ AudioTrack::AudioTrack(
    : mStatus(NO_INIT),
      mIsTimed(false),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT)
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPausedPosition(0)
{
    mStatus = set(streamType, sampleRate, format, channelMask,
            frameCount, flags, cbf, user, notificationFrames,
@@ -131,7 +133,8 @@ AudioTrack::AudioTrack(
    : mStatus(NO_INIT),
      mIsTimed(false),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT)
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPausedPosition(0)
{
    mStatus = set(streamType, sampleRate, format, channelMask,
            0 /*frameCount*/, flags, cbf, user, notificationFrames,
@@ -529,6 +532,16 @@ void AudioTrack::pause()
    }
    mProxy->interrupt();
    mAudioTrack->pause();

    if (isOffloaded()) {
        if (mOutput != 0) {
            uint32_t halFrames;
            // OffloadThread sends HAL pause in its threadLoop.. time saved
            // here can be slightly off
            AudioSystem::getRenderPosition(mOutput, &halFrames, &mPausedPosition);
            ALOGV("AudioTrack::pause for offload, cache current position %u", mPausedPosition);
        }
    }
}

status_t AudioTrack::setVolume(float left, float right)
@@ -747,6 +760,12 @@ status_t AudioTrack::getPosition(uint32_t *position) const
    if (isOffloaded()) {
        uint32_t dspFrames = 0;

        if ((mState == STATE_PAUSED) || (mState == STATE_PAUSED_STOPPING)) {
            ALOGV("getPosition called in paused state, return cached position %u", mPausedPosition);
            *position = mPausedPosition;
            return NO_ERROR;
        }

        if (mOutput != 0) {
            uint32_t halFrames;
            AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames);