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

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

Flush FastCapture PipeReader when starting after stop

Discards stale frames.

Bug: 30199985
Change-Id: Ie93a3784bf052aba6989d2ff1be92b1980b0c207
parent 510b5059
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -266,6 +266,17 @@ public:
    //              One or more frames were lost due to overrun, try again to read more recent data.
    virtual ssize_t read(void *buffer, size_t count) = 0;

    // Flush data from buffer.  There is no notion of overrun as all data is dropped.
    // Flushed frames also count towards frames read.
    //
    // Return value:
    //  >= 0    Number of frames successfully flushed
    //  < 0     status_t error occurred
    // Errors:
    //  NEGOTIATE         (Re-)negotiation is needed.
    //  INVALID_OPERATION Not implemented
    virtual ssize_t flush() { return INVALID_OPERATION; }

    // Transfer data from source using a series of callbacks.  More suitable for zero-fill,
    // synthesis, and non-contiguous transfers (e.g. circular buffer or readv).
    // Inputs:
+2 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ public:

    virtual ssize_t read(void *buffer, size_t count);

    virtual ssize_t flush();

    // NBAIO_Source end

#if 0   // until necessary
+17 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ PipeReader::~PipeReader()
    ALOG_ASSERT(readers > 0);
}

__attribute__((no_sanitize("integer")))
ssize_t PipeReader::availableToRead()
{
    if (CC_UNLIKELY(!mNegotiated)) {
@@ -64,6 +65,7 @@ ssize_t PipeReader::availableToRead()
    return avail;
}

__attribute__((no_sanitize("integer")))
ssize_t PipeReader::read(void *buffer, size_t count)
{
    ssize_t avail = availableToRead();
@@ -97,4 +99,19 @@ ssize_t PipeReader::read(void *buffer, size_t count)
    return red;
}

__attribute__((no_sanitize("integer")))
ssize_t PipeReader::flush()
{
    if (CC_UNLIKELY(!mNegotiated)) {
        return NEGOTIATE;
    }
    const int32_t rear = android_atomic_acquire_load(&mPipe.mRear);
    const size_t flushed = rear - mFront;
    // We don't check if flushed > mPipe.mMaxFrames (an overrun occurred) as the
    // distinction is unimportant; all data is dropped.
    mFront = rear;
    mFramesRead += flushed;  // we consider flushed frames as read.
    return flushed;
}

}   // namespace android
+10 −0
Original line number Diff line number Diff line
@@ -6459,6 +6459,16 @@ void AudioFlinger::RecordThread::inputStandBy()
        }
    }
    mInput->stream->common.standby(&mInput->stream->common);

    // If going into standby, flush the pipe source.
    if (mPipeSource.get() != nullptr) {
        const ssize_t flushed = mPipeSource->flush();
        if (flushed > 0) {
            ALOGV("Input standby flushed PipeSource %zd frames", flushed);
            mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] += flushed;
            mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime();
        }
    }
}

// RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held