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

Commit fb12e20e authored by Haynes Mathew George's avatar Haynes Mathew George Committed by Andy Hung
Browse files

audio: Output latency update in Audio Track



AudioTrack needs to query latency from the output descriptor each
time it uses mAfLatency to calculate timestamp or return the track
latency. Until now, the output descriptor latency was queried and
stored when a track is created. On a device switch, IO descriptors
table saved in AudioSystem is updated to reflected the latest
latency values.  Unless a device switch lead to a track teardown,
AudioTrack will be unaware of the latest latency value. Therefore
explicitly check the latest mAfLatency value on each getTimeStamp
call.

Test: Podkicker 2.2x, Photos 240fps and BT
Bug: 35075600
authored-by: default avatarAniket Kumar Lata <alata@codeaurora.org>
Change-Id: I06282182364703574a7d66d2b5cd1301679dfade
parent c77b3bb4
Loading
Loading
Loading
Loading
+29 −6
Original line number Original line Diff line number Diff line
@@ -1245,9 +1245,27 @@ audio_stream_type_t AudioTrack::streamType() const
    return mStreamType;
    return mStreamType;
}
}


uint32_t AudioTrack::latency()
{
    AutoMutex lock(mLock);
    updateLatency_l();
    return mLatency;
}

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


// must be called with mLock held
// must be called with mLock held
void AudioTrack::updateLatency_l()
{
    status_t status = AudioSystem::getLatency(mOutput, &mAfLatency);
    if (status != NO_ERROR) {
        ALOGW("getLatency(%d) failed status %d", mOutput, status);
    } else {
        // FIXME don't believe this lie
        mLatency = mAfLatency + (1000 * mFrameCount) / mSampleRate;
    }
}

status_t AudioTrack::createTrack_l()
status_t AudioTrack::createTrack_l()
{
{
    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
@@ -1542,9 +1560,7 @@ status_t AudioTrack::createTrack_l()
    }
    }


    mAudioTrack->attachAuxEffect(mAuxEffectId);
    mAudioTrack->attachAuxEffect(mAuxEffectId);
    // FIXME doesn't take into account speed or future sample rate changes (until restoreTrack)
    updateLatency_l();  // this refetches mAfLatency and sets mLatency
    // FIXME don't believe this lie
    mLatency = mAfLatency + (1000*frameCount) / mSampleRate;


    mFrameCount = frameCount;
    mFrameCount = frameCount;
    // If IAudioTrack is re-created, don't let the requested frameCount
    // If IAudioTrack is re-created, don't let the requested frameCount
@@ -2316,8 +2332,9 @@ Modulo<uint32_t> AudioTrack::updateAndGetPosition_l()
    return mPosition;
    return mPosition;
}
}


bool AudioTrack::isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) const
bool AudioTrack::isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed)
{
{
    updateLatency_l();
    // applicable for mixing tracks only (not offloaded or direct)
    // applicable for mixing tracks only (not offloaded or direct)
    if (mStaticProxy != 0) {
    if (mStaticProxy != 0) {
        return true; // static tracks do not have issues with buffer sizing.
        return true; // static tracks do not have issues with buffer sizing.
@@ -2325,9 +2342,14 @@ bool AudioTrack::isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) co
    const size_t minFrameCount =
    const size_t minFrameCount =
            calculateMinFrameCount(mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed
            calculateMinFrameCount(mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed
                /*, 0 mNotificationsPerBufferReq*/);
                /*, 0 mNotificationsPerBufferReq*/);
    ALOGV("isSampleRateSpeedAllowed_l mFrameCount %zu  minFrameCount %zu",
    const bool allowed = mFrameCount >= minFrameCount;
    ALOGD_IF(!allowed,
            "isSampleRateSpeedAllowed_l denied "
            "mAfLatency:%u  mAfFrameCount:%zu  mAfSampleRate:%u  sampleRate:%u  speed:%f "
            "mFrameCount:%zu < minFrameCount:%zu",
            mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed,
            mFrameCount, minFrameCount);
            mFrameCount, minFrameCount);
    return mFrameCount >= minFrameCount;
    return allowed;
}
}


status_t AudioTrack::setParameters(const String8& keyValuePairs)
status_t AudioTrack::setParameters(const String8& keyValuePairs)
@@ -2471,6 +2493,7 @@ status_t AudioTrack::getTimestamp_l(AudioTimestamp& timestamp)
            status = ets.getBestTimestamp(&timestamp, &location);
            status = ets.getBestTimestamp(&timestamp, &location);


            if (status == OK) {
            if (status == OK) {
                updateLatency_l();
                // It is possible that the best location has moved from the kernel to the server.
                // It is possible that the best location has moved from the kernel to the server.
                // In this case we adjust the position from the previous computed latency.
                // In this case we adjust the position from the previous computed latency.
                if (location == ExtendedTimestamp::LOCATION_SERVER) {
                if (location == ExtendedTimestamp::LOCATION_SERVER) {
+4 −2
Original line number Original line Diff line number Diff line
@@ -326,7 +326,7 @@ public:
     * This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
     * This includes the latency due to AudioTrack buffer size, AudioMixer (if any)
     * and audio hardware driver.
     * and audio hardware driver.
     */
     */
            uint32_t    latency() const     { return mLatency; }
            uint32_t    latency();


    /* Returns the number of application-level buffer underruns
    /* Returns the number of application-level buffer underruns
     * since the AudioTrack was created.
     * since the AudioTrack was created.
@@ -927,6 +927,8 @@ protected:


            // caller must hold lock on mLock for all _l methods
            // caller must hold lock on mLock for all _l methods


            void updateLatency_l(); // updates mAfLatency and mLatency from AudioSystem cache

            status_t createTrack_l();
            status_t createTrack_l();


            // can only be called when mState != STATE_ACTIVE
            // can only be called when mState != STATE_ACTIVE
@@ -962,7 +964,7 @@ protected:
            Modulo<uint32_t> updateAndGetPosition_l();
            Modulo<uint32_t> updateAndGetPosition_l();


            // check sample rate and speed is compatible with AudioTrack
            // check sample rate and speed is compatible with AudioTrack
            bool     isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed) const;
            bool     isSampleRateSpeedAllowed_l(uint32_t sampleRate, float speed);


            void     restartIfDisabled();
            void     restartIfDisabled();