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

Commit 2c3b2da3 authored by John Grossman's avatar John Grossman
Browse files

AudioFlinger: fix timed audio



(cherry picked from commit e20ac92c564a2f4e8123885807abdf0a78de0dd7)

> AudioFlinger: fix timed audio
>
> Addresses Bug 6900517.
>
> Finish up support for timed audio in the new FastMixer world.  Pay special
> attention to remaining lock-less and voluntary yield free on the FastMixer
> thread.  This fixes audio playback for Q on JB.
>
> Change-Id: Iaf815e58a1b1d0a0190051794bec8dc5c9231785
> Signed-off-by: default avatarJohn Grossman <johngro@google.com>

Change-Id: I9bd687acc345a05867af48e71116690fdb0ce1b5
Signed-off-by: default avatarJohn Grossman <johngro@google.com>
parent ee578c03
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -46,14 +46,16 @@ ssize_t AudioBufferProviderSource::availableToRead()
    return mBuffer.raw != NULL ? mBuffer.frameCount - mConsumed : 0;
}

ssize_t AudioBufferProviderSource::read(void *buffer, size_t count)
ssize_t AudioBufferProviderSource::read(void *buffer,
                                        size_t count,
                                        int64_t readPTS)
{
    if (CC_UNLIKELY(!mNegotiated)) {
        return NEGOTIATE;
    }
    if (CC_UNLIKELY(mBuffer.raw == NULL)) {
        mBuffer.frameCount = count;
        status_t status = mProvider->getNextBuffer(&mBuffer, AudioBufferProvider::kInvalidPTS);
        status_t status = mProvider->getNextBuffer(&mBuffer, readPTS);
        if (status != OK) {
            return status == NOT_ENOUGH_DATA ? (ssize_t) WOULD_BLOCK : (ssize_t) status;
        }
@@ -79,7 +81,8 @@ ssize_t AudioBufferProviderSource::read(void *buffer, size_t count)
    return count;
}

ssize_t AudioBufferProviderSource::readVia(readVia_t via, size_t total, void *user, size_t block)
ssize_t AudioBufferProviderSource::readVia(readVia_t via, size_t total, void *user,
                                           int64_t readPTS, size_t block)
{
    if (CC_UNLIKELY(!mNegotiated)) {
        return NEGOTIATE;
@@ -99,7 +102,7 @@ ssize_t AudioBufferProviderSource::readVia(readVia_t via, size_t total, void *us
        // 1 <= count <= block
        if (CC_UNLIKELY(mBuffer.raw == NULL)) {
            mBuffer.frameCount = count;
            status_t status = mProvider->getNextBuffer(&mBuffer, AudioBufferProvider::kInvalidPTS);
            status_t status = mProvider->getNextBuffer(&mBuffer, readPTS);
            if (CC_LIKELY(status == OK)) {
                ALOG_ASSERT(mBuffer.raw != NULL && mBuffer.frameCount <= count);
                // mConsumed is 0 either from constructor or after releaseBuffer()
@@ -117,7 +120,8 @@ ssize_t AudioBufferProviderSource::readVia(readVia_t via, size_t total, void *us
            count = available;
        }
        if (CC_LIKELY(count > 0)) {
            ssize_t ret = via(user, (char *) mBuffer.raw + (mConsumed << mBitShift), count);
            char* readTgt = (char *) mBuffer.raw + (mConsumed << mBitShift);
            ssize_t ret = via(user, readTgt, count, readPTS);
            if (CC_UNLIKELY(ret <= 0)) {
                if (CC_LIKELY(accumulator > 0)) {
                    return accumulator;
+3 −2
Original line number Diff line number Diff line
@@ -42,8 +42,9 @@ public:
    //virtual size_t framesOverrun();
    //virtual size_t overruns();
    virtual ssize_t availableToRead();
    virtual ssize_t read(void *buffer, size_t count);
    virtual ssize_t readVia(readVia_t via, size_t total, void *user, size_t block);
    virtual ssize_t read(void *buffer, size_t count, int64_t readPTS);
    virtual ssize_t readVia(readVia_t via, size_t total, void *user,
                            int64_t readPTS, size_t block);

private:
    AudioBufferProvider * const mProvider;
+6 −4
Original line number Diff line number Diff line
@@ -2791,9 +2791,10 @@ void AudioFlinger::MixerThread::threadLoop_mix()
    int64_t pts;
    status_t status = INVALID_OPERATION;

    if (NULL != mOutput->stream->get_next_write_timestamp) {
        status = mOutput->stream->get_next_write_timestamp(
                mOutput->stream, &pts);
    if (mNormalSink != 0) {
        status = mNormalSink->getNextWriteTimestamp(&pts);
    } else {
        status = mOutputSink->getNextWriteTimestamp(&pts);
    }

    if (status != NO_ERROR) {
@@ -3579,7 +3580,8 @@ void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& ar
#define TEE_SINK_READ 1024
                short buffer[TEE_SINK_READ * FCC_2];
                size_t count = TEE_SINK_READ;
                ssize_t actual = teeSource->read(buffer, count);
                ssize_t actual = teeSource->read(buffer, count,
                        AudioBufferProvider::kInvalidPTS);
                bool wasFirstRead = firstRead;
                firstRead = false;
                if (actual <= 0) {
+12 −0
Original line number Diff line number Diff line
@@ -67,4 +67,16 @@ ssize_t AudioStreamOutSink::write(const void *buffer, size_t count)
    return ret;
}

status_t AudioStreamOutSink::getNextWriteTimestamp(int64_t *timestamp) {
    ALOG_ASSERT(timestamp != NULL);

    if (NULL == mStream)
        return INVALID_OPERATION;

    if (NULL == mStream->get_next_write_timestamp)
        return INVALID_OPERATION;

    return mStream->get_next_write_timestamp(mStream, timestamp);
}

}   // namespace android
+5 −0
Original line number Diff line number Diff line
@@ -47,6 +47,11 @@ public:

    virtual ssize_t write(const void *buffer, size_t count);

    // AudioStreamOutSink wraps a HAL's output stream.  Its
    // getNextWriteTimestamp method is simply a passthru to the HAL's underlying
    // implementation of GNWT (if any)
    virtual status_t getNextWriteTimestamp(int64_t *timestamp);

    // NBAIO_Sink end

#if 0   // until necessary
Loading