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

Commit bbe98f00 authored by Phil Burk's avatar Phil Burk Committed by Android (Google) Code Review
Browse files

Merge "AudioTrack: Add getUnderrunCount()"

parents 27e583ba 2812d9ea
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -305,6 +305,11 @@ public:
     */
            uint32_t    latency() const     { return mLatency; }

    /* Returns the number of application-level buffer underruns
     * since the AudioTrack was created.
     */
            uint32_t    getUnderrunCount() const;

    /* getters, see constructors and set() */

            audio_stream_type_t streamType() const;
@@ -803,6 +808,8 @@ protected:
            // FIXME enum is faster than strcmp() for parameter 'from'
            status_t restoreTrack_l(const char *from);

            uint32_t    getUnderrunCount_l() const;

            bool     isOffloaded() const;
            bool     isDirect() const;
            bool     isOffloadedOrDirect() const;
@@ -934,6 +941,8 @@ protected:
    bool                    mRetrogradeMotionReported; // reduce log spam
    AudioTimestamp          mPreviousTimestamp;     // used to detect retrograde motion

    uint32_t                mUnderrunCountOffset;   // updated when restoring tracks

    audio_output_flags_t    mFlags;
        // const after set(), except for bits AUDIO_OUTPUT_FLAG_FAST and AUDIO_OUTPUT_FLAG_OFFLOAD.
        // mLock must be held to read or write those bits reliably.
+11 −4
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ struct AudioTrackSharedStreaming {
    volatile int32_t mFlush;    // incremented by client to indicate a request to flush;
                                // server notices and discards all data between mFront and mRear
    volatile uint32_t mUnderrunFrames; // server increments for each unavailable but desired frame
    volatile uint32_t mUnderrunCount;  // server increments for each underrun occurrence
};

// Represents a single state of an AudioTrack that was created in static mode (shared memory buffer
@@ -174,8 +175,6 @@ public:

    volatile    int32_t     mFlags;         // combinations of CBLK_*

                // Cache line boundary (32 bytes)

public:
                union {
                    AudioTrackSharedStreaming   mStreaming;
@@ -358,6 +357,9 @@ public:
    virtual uint32_t    getUnderrunFrames() const {
        return mCblk->u.mStreaming.mUnderrunFrames;
    }
    virtual uint32_t    getUnderrunCount() const {
        return mCblk->u.mStreaming.mUnderrunCount;
    }

    bool        clearStreamEndDone();   // and return previous value

@@ -482,7 +484,8 @@ public:
    AudioTrackServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCount,
            size_t frameSize, bool clientInServer = false, uint32_t sampleRate = 0)
        : ServerProxy(cblk, buffers, frameCount, frameSize, true /*isOut*/, clientInServer),
          mPlaybackRateObserver(&cblk->mPlaybackRateQueue) {
          mPlaybackRateObserver(&cblk->mPlaybackRateQueue),
          mUnderrunCount(0), mUnderrunning(false) {
        mCblk->mSampleRate = sampleRate;
        mPlaybackRate = AUDIO_PLAYBACK_RATE_DEFAULT;
    }
@@ -525,6 +528,10 @@ public:
private:
    AudioPlaybackRate             mPlaybackRate;  // last observed playback rate
    PlaybackRateQueue::Observer   mPlaybackRateObserver;

    // The server keeps a copy here where it is safe from the client.
    uint32_t                      mUnderrunCount; // echoed to mCblk
    bool                          mUnderrunning;  // used to detect edge of underrun
};

class StaticAudioTrackServerProxy : public AudioTrackServerProxy {
+15 −0
Original line number Diff line number Diff line
@@ -498,6 +498,7 @@ status_t AudioTrack::set(
    mPreviousTimestampValid = false;
    mTimestampStartupGlitchReported = false;
    mRetrogradeMotionReported = false;
    mUnderrunCountOffset = 0;

    return NO_ERROR;
}
@@ -2150,6 +2151,9 @@ status_t AudioTrack::restoreTrack_l(const char *from)
        return DEAD_OBJECT;
    }

    // Save so we can return count since creation.
    mUnderrunCountOffset = getUnderrunCount_l();

    // save the old static buffer position
    size_t bufferPosition = 0;
    int loopCount = 0;
@@ -2465,6 +2469,17 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args __unused) const
    return NO_ERROR;
}

uint32_t AudioTrack::getUnderrunCount() const
{
    AutoMutex lock(mLock);
    return getUnderrunCount_l();
}

uint32_t AudioTrack::getUnderrunCount_l() const
{
    return mProxy->getUnderrunCount() + mUnderrunCountOffset;
}

uint32_t AudioTrack::getUnderrunFrames() const
{
    AutoMutex lock(mLock);
+22 −5
Original line number Diff line number Diff line
@@ -804,10 +804,25 @@ bool AudioTrackServerProxy::setStreamEndDone() {
void AudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount)
{
    audio_track_cblk_t* cblk = mCblk;
    if (frameCount > 0) {
        cblk->u.mStreaming.mUnderrunFrames += frameCount;

        if (!mUnderrunning) { // start of underrun?
            mUnderrunCount++;
            cblk->u.mStreaming.mUnderrunCount = mUnderrunCount;
            mUnderrunning = true;
            ALOGV("tallyUnderrunFrames(%3u) at uf = %u, bump mUnderrunCount = %u",
                frameCount, cblk->u.mStreaming.mUnderrunFrames, mUnderrunCount);
        }

        // FIXME also wake futex so that underrun is noticed more quickly
        (void) android_atomic_or(CBLK_UNDERRUN, &cblk->mFlags);
    } else {
        ALOGV_IF(mUnderrunning,
            "tallyUnderrunFrames(%3u) at uf = %u, underrun finished",
            frameCount, cblk->u.mStreaming.mUnderrunFrames);
        mUnderrunning = false; // so we can detect the next edge
    }
}

AudioPlaybackRate AudioTrackServerProxy::getPlaybackRate()
@@ -1033,7 +1048,7 @@ void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer)
    buffer->mNonContig = 0;
}

void StaticAudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount __unused)
void StaticAudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount)
{
    // Unlike AudioTrackServerProxy::tallyUnderrunFrames() used for streaming tracks,
    // we don't have a location to count underrun frames.  The underrun frame counter
@@ -1041,8 +1056,10 @@ void StaticAudioTrackServerProxy::tallyUnderrunFrames(uint32_t frameCount __unus
    // possible for static buffer tracks other than at end of buffer, so this is not a loss.

    // FIXME also wake futex so that underrun is noticed more quickly
    if (frameCount > 0) {
        (void) android_atomic_or(CBLK_UNDERRUN, &mCblk->mFlags);
    }
}

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

+5 −0
Original line number Diff line number Diff line
@@ -3788,6 +3788,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
                    recentUnderruns > 0) {
                // FIXME fast mixer will pull & mix partial buffers, but we count as a full underrun
                track->mAudioTrackServerProxy->tallyUnderrunFrames(recentUnderruns * mFrameCount);
            } else {
                track->mAudioTrackServerProxy->tallyUnderrunFrames(0);
            }

            // This is similar to the state machine for normal tracks,
@@ -4157,7 +4159,10 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
                ALOGV("track(%p) underrun,  framesReady(%zu) < framesDesired(%zd)",
                        track, framesReady, desiredFrames);
                track->mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
            } else {
                track->mAudioTrackServerProxy->tallyUnderrunFrames(0);
            }

            // clear effect chain input buffer if an active track underruns to avoid sending
            // previous audio buffer again to effects
            chain = getEffectChain_l(track->sessionId());
Loading