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

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

Merge "AudioFlinger: flush direct tracks that are paused" into nyc-mr1-dev

parents 7c6bd7b1 4bb650bb
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -522,6 +522,12 @@ public:
        mTimestampMutator.push(timestamp);
    }

    // Flushes the shared ring buffer if the client had requested it using mStreaming.mFlush.
    // If flush occurs then:
    //   cblk->u.mStreaming.mFront, ServerProxy::mFlush and ServerProxy::mFlushed will be modified
    //   client will be notified via Futex
    virtual void    flushBufferIfNeeded();

    // Total count of the number of flushed frames since creation (never reset).
    virtual int64_t     framesFlushed() const { return mFlushed; }

+51 −36
Original line number Diff line number Diff line
@@ -622,24 +622,20 @@ ServerProxy::ServerProxy(audio_track_cblk_t* cblk, void *buffers, size_t frameCo
}

__attribute__((no_sanitize("integer")))
status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
{
    LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0);
    if (mIsShutdown) {
        goto no_init;
    }
void ServerProxy::flushBufferIfNeeded()
{
    audio_track_cblk_t* cblk = mCblk;
    // compute number of frames available to write (AudioTrack) or read (AudioRecord),
    // or use previous cached value from framesReady(), with added barrier if it omits.
    int32_t front;
    int32_t rear;
    // See notes on barriers at ClientProxy::obtainBuffer()
    if (mIsOut) {
        int32_t flush = cblk->u.mStreaming.mFlush;
        rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
        front = cblk->u.mStreaming.mFront;
    // The acquire_load is not really required. But since the write is a release_store in the
    // client, using acquire_load here makes it easier for people to maintain the code,
    // and the logic for communicating ipc variables seems somewhat standard,
    // and there really isn't much penalty for 4 or 8 byte atomics.
    int32_t flush = android_atomic_acquire_load(&cblk->u.mStreaming.mFlush);
    if (flush != mFlush) {
        ALOGV("ServerProxy::flushBufferIfNeeded() mStreaming.mFlush = 0x%x, mFlush = 0x%0x",
                flush, mFlush);
        int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
        int32_t front = cblk->u.mStreaming.mFront;

        // effectively obtain then release whatever is in the buffer
        const size_t overflowBit = mFrameCountP2 << 1;
        const size_t mask = overflowBit - 1;
@@ -672,8 +668,27 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
            }
        }
        mFlushed += (newFront - front) & mask;
            front = newFront;
    }
}

__attribute__((no_sanitize("integer")))
status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
{
    LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0);
    if (mIsShutdown) {
        goto no_init;
    }
    {
    audio_track_cblk_t* cblk = mCblk;
    // compute number of frames available to write (AudioTrack) or read (AudioRecord),
    // or use previous cached value from framesReady(), with added barrier if it omits.
    int32_t front;
    int32_t rear;
    // See notes on barriers at ClientProxy::obtainBuffer()
    if (mIsOut) {
        flushBufferIfNeeded(); // might modify mFront
        rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
        front = cblk->u.mStreaming.mFront;
    } else {
        front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront);
        rear = cblk->u.mStreaming.mRear;
+11 −0
Original line number Diff line number Diff line
@@ -777,6 +777,13 @@ void AudioFlinger::PlaybackThread::Track::flush()
        Mutex::Autolock _l(thread->mLock);
        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();

        // Flush the ring buffer now if the track is not active in the PlaybackThread.
        // Otherwise the flush would not be done until the track is resumed.
        // Requires FastTrack removal be BLOCK_UNTIL_ACKED
        if (playbackThread->mActiveTracks.indexOf(this) < 0) {
            (void)mServerProxy->flushBufferIfNeeded();
        }

        if (isOffloaded()) {
            // If offloaded we allow flush during any state except terminated
            // and keep the track active to avoid problems if user is seeking
@@ -828,6 +835,10 @@ void AudioFlinger::PlaybackThread::Track::flushAck()
    if (!isOffloaded() && !isDirect())
        return;

    // Clear the client ring buffer so that the app can prime the buffer while paused.
    // Otherwise it might not get cleared until playback is resumed and obtainBuffer() is called.
    mServerProxy->flushBufferIfNeeded();

    mFlushHwPending = false;
}