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

Commit f20a4e9f authored by Andy Hung's avatar Andy Hung
Browse files

AudioTrack: Fix timestamp restore

Test: Photos with BT on and off.
Bug: 29946998
Change-Id: I729590451126e180ee85e1ab3dee2a0b24f0572d
parent 8922c251
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1056,6 +1056,10 @@ protected:
                                                    // after flush.
    int64_t                 mFramesWrittenServerOffset; // An offset to server frames due to
                                                    // restoring AudioTrack, or stop/start.
                                                    // This offset is also used for static tracks.
    int64_t                 mFramesWrittenAtRestore; // Frames written at restore point (or frames
                                                    // delivered for static tracks).
                                                    // -1 indicates no previous restore point.

    audio_output_flags_t    mFlags;                 // same as mOrigFlags, except for bits that may
                                                    // be denied by client or server, such as
+18 −2
Original line number Diff line number Diff line
@@ -539,6 +539,7 @@ status_t AudioTrack::set(
    mUnderrunCountOffset = 0;
    mFramesWritten = 0;
    mFramesWrittenServerOffset = 0;
    mFramesWrittenAtRestore = -1; // -1 is a unique initializer.

    return NO_ERROR;
}
@@ -2181,10 +2182,12 @@ status_t AudioTrack::restoreTrack_l(const char *from)
    mUnderrunCountOffset = getUnderrunCount_l();

    // save the old static buffer position
    uint32_t staticPosition = 0;
    size_t bufferPosition = 0;
    int loopCount = 0;
    if (mStaticProxy != 0) {
        mStaticProxy->getBufferPositionAndLoopCount(&bufferPosition, &loopCount);
        staticPosition = mStaticProxy->getPosition().unsignedValue();
    }

    mFlags = mOrigFlags;
@@ -2216,8 +2219,11 @@ status_t AudioTrack::restoreTrack_l(const char *from)
        }
        if (mState == STATE_ACTIVE) {
            result = mAudioTrack->start();
            mFramesWrittenServerOffset = mFramesWritten; // server resets to zero so we offset
        }
        // server resets to zero so we offset
        mFramesWrittenServerOffset =
                mStaticProxy.get() != nullptr ? staticPosition : mFramesWritten;
        mFramesWrittenAtRestore = mFramesWrittenServerOffset;
    }
    if (result != NO_ERROR) {
        ALOGW("restoreTrack_l() failed status %d", result);
@@ -2400,9 +2406,19 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp)
            }
        }
        if (status == INVALID_OPERATION) {
            // INVALID_OPERATION occurs when no timestamp has been issued by the server;
            // other failures are signaled by a negative time.
            // If we come out of FLUSHED or STOPPED where the position is known
            // to be zero we convert this to WOULD_BLOCK (with the implicit meaning of
            // "zero" for NuPlayer).  We don't convert for track restoration as position
            // does not reset.
            ALOGV("timestamp server offset:%lld restore frames:%lld",
                    (long long)mFramesWrittenServerOffset, (long long)mFramesWrittenAtRestore);
            if (mFramesWrittenServerOffset != mFramesWrittenAtRestore) {
                status = WOULD_BLOCK;
            }
        }
    }
    if (status != NO_ERROR) {
        ALOGV_IF(status != WOULD_BLOCK, "getTimestamp error:%#x", status);
        return status;