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

Commit 03079276 authored by Atneya Nair's avatar Atneya Nair
Browse files

Consolidate libaudioclient buffers p1

Prepare for libaudioclient buffer refactor by updating
clients of libaudioclient to use new buffer interface.

libaudioclient
- Wrap existing buffers with new interface
- Modify internal calls to be compatible with wrap

AAudio
- Update to use new buffer interface
- Update record to use callback

TrackPlayerBase
- Used for SLES (in different repo). Update to use sp<>

ToneGenerator/MediaPlayerService/AudioPlayer
- Update to use new buffer interface

StageFright
- Update to new callback interface
- Update to use new buffer interface

Bug: 216175830 - shared buffer
Bug: 199156212 - callback interface
Test: atest AudioTrackTest AudioRecordTest
atest AudioTrackOffloadTest
OboeTester non-exclusive, non-MMAP, power-saving for both
AAudio and SLES, input and output
No-Typo-Check: Existing class members

Change-Id: Ib1241f2e530bc509b2d4dde956ec5188f2287994
parent b962f372
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -453,7 +453,7 @@ size_t AudioPlayer::AudioSinkCallback(
}

size_t AudioPlayer::onMoreData(const AudioTrack::Buffer& buffer) {
    return fillBuffer(buffer.raw, buffer.size);
    return fillBuffer(buffer.data(), buffer.size());
}

void AudioPlayer::onStreamEnd() {
+72 −7
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ size_t AudioStreamLegacy::onMoreData(const android::AudioTrack::Buffer& buffer)
    // This takes advantage of them killing the stream when they see a size out of range.
    // That is an undocumented behavior.
    // TODO add to API in AudioRecord and AudioTrack
    // TODO(b/216175830) cleanup size re-computation
    const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;
    aaudio_data_callback_result_t callbackResult;
    (void) checkForDisconnectRequest(true);
@@ -83,7 +84,7 @@ size_t AudioStreamLegacy::onMoreData(const android::AudioTrack::Buffer& buffer)
    // Note that this code assumes an AudioTrack::Buffer is the same as
    // AudioRecord::Buffer
    // TODO define our own AudioBuffer and pass it from the subclasses.
    size_t written = buffer.size;
    size_t written = buffer.size();
    if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
        ALOGW("%s() data, stream disconnected", __func__);
        // This will kill the stream and prevent it from being restarted.
@@ -96,23 +97,23 @@ size_t AudioStreamLegacy::onMoreData(const android::AudioTrack::Buffer& buffer)
        // caused by Legacy callbacks running after the track is "stopped".
        written = 0;
    } else {
        if (buffer.frameCount == 0) {
        if (buffer.getFrameCount() == 0) {
            ALOGW("%s() data, frameCount is zero", __func__);
            return written;
        }

        // If the caller specified an exact size then use a block size adapter.
        if (mBlockAdapter != nullptr) {
            int32_t byteCount = buffer.frameCount * getBytesPerDeviceFrame();
            int32_t byteCount = buffer.getFrameCount() * getBytesPerDeviceFrame();
            callbackResult = mBlockAdapter->processVariableBlock(
                    static_cast<uint8_t*>(buffer.raw), byteCount);
                    buffer.data(), byteCount);
        } else {
            // Call using the AAudio callback interface.
            callbackResult = callDataCallbackFrames(static_cast<uint8_t *>(buffer.raw),
                                                    buffer.frameCount);
            callbackResult = callDataCallbackFrames(buffer.data(),
                                                    buffer.getFrameCount());
        }
        if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
            written = buffer.frameCount * getBytesPerDeviceFrame();
            written = buffer.getFrameCount() * getBytesPerDeviceFrame();
        } else {
            if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
                ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
@@ -134,6 +135,70 @@ size_t AudioStreamLegacy::onMoreData(const android::AudioTrack::Buffer& buffer)
    return written;
}

// TODO (b/216175830) this method is duplicated in order to ease refactoring which will
// reconsolidate.
size_t AudioStreamLegacy::onMoreData(const android::AudioRecord::Buffer& buffer) {
    // This illegal size can be used to tell AudioRecord or AudioTrack to stop calling us.
    // This takes advantage of them killing the stream when they see a size out of range.
    // That is an undocumented behavior.
    // TODO add to API in AudioRecord and AudioTrack
    const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;
    aaudio_data_callback_result_t callbackResult;
    (void) checkForDisconnectRequest(true);

    // Note that this code assumes an AudioTrack::Buffer is the same as
    // AudioRecord::Buffer
    // TODO define our own AudioBuffer and pass it from the subclasses.
    size_t written = buffer.size();
    if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
        ALOGW("%s() data, stream disconnected", __func__);
        // This will kill the stream and prevent it from being restarted.
        // That is OK because the stream is disconnected.
        written = SIZE_STOP_CALLBACKS;
    } else if (!mCallbackEnabled.load()) {
        ALOGW("%s() no data because callback disabled, set size=0", __func__);
        // Do NOT use SIZE_STOP_CALLBACKS here because that will kill the stream and
        // prevent it from being restarted. This can occur because of a race condition
        // caused by Legacy callbacks running after the track is "stopped".
        written = 0;
    } else {
        if (buffer.getFrameCount() == 0) {
            ALOGW("%s() data, frameCount is zero", __func__);
            return written;
        }

        // If the caller specified an exact size then use a block size adapter.
        if (mBlockAdapter != nullptr) {
            int32_t byteCount = buffer.getFrameCount() * getBytesPerDeviceFrame();
            callbackResult = mBlockAdapter->processVariableBlock(
                    buffer.data(), byteCount);
        } else {
            // Call using the AAudio callback interface.
            callbackResult = callDataCallbackFrames(buffer.data(),
                                                    buffer.getFrameCount());
        }
        if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
            written = buffer.getFrameCount() * getBytesPerDeviceFrame();
        } else {
            if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
                ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
            } else {
                ALOGW("%s() callback returned invalid result = %d",
                      __func__, callbackResult);
            }
            written = 0;
            systemStopInternal();
            // Disable the callback just in case the system keeps trying to call us.
            mCallbackEnabled.store(false);
        }

        if (updateStateMachine() != AAUDIO_OK) {
            forceDisconnect();
            mCallbackEnabled.store(false);
        }
    }
    return written;
}

aaudio_result_t AudioStreamLegacy::checkForDisconnectRequest(bool errorCallbackEnabled) {
    if (mRequestDisconnect.isRequested()) {
+8 −2
Original line number Diff line number Diff line
@@ -17,9 +17,10 @@
#ifndef LEGACY_AUDIO_STREAM_LEGACY_H
#define LEGACY_AUDIO_STREAM_LEGACY_H

#include <media/AudioRecord.h>
#include <media/AudioSystem.h>
#include <media/AudioTimestamp.h>
#include <media/AudioTrack.h>
#include <media/AudioSystem.h>

#include <aaudio/AAudio.h>

@@ -57,7 +58,8 @@ typedef int32_t aaudio_callback_operation_t;

class AudioStreamLegacy : public AudioStream,
                          public FixedBlockProcessor,
                          protected android::AudioTrack::IAudioTrackCallback {
                          protected android::AudioTrack::IAudioTrackCallback,
                          protected android::AudioRecord::IAudioRecordCallback {
public:
    AudioStreamLegacy();

@@ -82,7 +84,11 @@ public:

protected:
    size_t onMoreData(const android::AudioTrack::Buffer& buffer) override;
    // TODO (b/216175830) this method is duplicated in order to ease refactoring which will
    // reconsolidate.
    size_t onMoreData(const android::AudioRecord::Buffer& buffer) override;
    void onNewIAudioTrack() override;
    void onNewIAudioRecord() override { onNewIAudioTrack(); }
    aaudio_result_t getBestTimestamp(clockid_t clockId,
                                     int64_t *framePosition,
                                     int64_t *timeNanoseconds,
+2 −27
Original line number Diff line number Diff line
@@ -37,10 +37,6 @@ using android::content::AttributionSourceState;
using namespace android;
using namespace aaudio;

static void sCallbackWrapper(int event, void* userData, void* info) {
    static_cast<AudioStreamRecord*>(userData)->processCallback(event, info);
}

AudioStreamRecord::AudioStreamRecord()
    : AudioStreamLegacy()
    , mFixedBlockWriter(*this)
@@ -128,13 +124,11 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder)
    uint32_t notificationFrames = 0;

    // Setup the callback if there is one.
    AudioRecord::legacy_callback_t callback = nullptr;
    void *callbackData = nullptr;
    sp<AudioRecord::IAudioRecordCallback> callback;
    AudioRecord::transfer_type streamTransferType = AudioRecord::transfer_type::TRANSFER_SYNC;
    if (builder.getDataCallbackProc() != nullptr) {
        streamTransferType = AudioRecord::transfer_type::TRANSFER_CALLBACK;
        callback = sCallbackWrapper;
        callbackData = this;
        callback = sp<AudioRecord::IAudioRecordCallback>::fromExisting(this);
    }
    mCallbackBufferSize = builder.getFramesPerDataCallback();

@@ -181,7 +175,6 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder)
                channelMask,
                frameCount,
                callback,
                callbackData,
                notificationFrames,
                false /*threadCanCallJava*/,
                sessionId,
@@ -354,24 +347,6 @@ const void * AudioStreamRecord::maybeConvertDeviceData(const void *audioData, in
    }
}

void AudioStreamRecord::processCallback(int event, void *info) {
    switch (event) {
        case AudioRecord::EVENT_MORE_DATA:
        {
            AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info);
            audioBuffer->size = onMoreData(*audioBuffer);
            break;
        }
            // Stream got rerouted so we disconnect.
        case AudioRecord::EVENT_NEW_IAUDIORECORD:
            onNewIAudioTrack();
            break;
        default:
            break;
    }
    return;
}

aaudio_result_t AudioStreamRecord::requestStart_l()
{
    if (mAudioRecord.get() == nullptr) {
+8 −8
Original line number Diff line number Diff line
@@ -266,7 +266,7 @@ class LegacyCallbackWrapper : public AudioRecord::IAudioRecordCallback {
    size_t onMoreData(const AudioRecord::Buffer& buffer) override {
        AudioRecord::Buffer copy = buffer;
        mCallback(AudioRecord::EVENT_MORE_DATA, mData, &copy);
        return copy.size;
        return copy.size();
    }

    void onOverrun() override { mCallback(AudioRecord::EVENT_OVERRUN, mData, nullptr); }
@@ -1131,7 +1131,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount, size_
    }
    if (mTransfer != TRANSFER_OBTAIN) {
        audioBuffer->frameCount = 0;
        audioBuffer->size = 0;
        audioBuffer->mSize = 0;
        audioBuffer->raw = NULL;
        if (nonContig != NULL) {
            *nonContig = 0;
@@ -1214,7 +1214,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *r
    } while ((status == DEAD_OBJECT) && (tryCounter-- > 0));

    audioBuffer->frameCount = buffer.mFrameCount;
    audioBuffer->size = buffer.mFrameCount * mServerFrameSize;
    audioBuffer->mSize = buffer.mFrameCount * mServerFrameSize;
    audioBuffer->raw = buffer.mRaw;
    audioBuffer->sequence = oldSequence;
    if (nonContig != NULL) {
@@ -1291,7 +1291,7 @@ ssize_t AudioRecord::read(void* buffer, size_t userSize, bool blocking)

        size_t bytesRead = audioBuffer.frameCount * mFrameSize;
        memcpy_by_audio_format(buffer, mFormat, audioBuffer.raw, mServerConfig.format,
                               audioBuffer.size / mServerSampleSize);
                               audioBuffer.mSize / mServerSampleSize);
        buffer = ((char *) buffer) + bytesRead;
        userSize -= bytesRead;
        read += bytesRead;
@@ -1497,15 +1497,15 @@ nsecs_t AudioRecord::processAudioBuffer()
        if (mServerConfig.format != mFormat) {
            buffer = &mFormatConversionBuffer;
            buffer->frameCount = audioBuffer.frameCount;
            buffer->size = buffer->frameCount * mFrameSize;
            buffer->mSize = buffer->frameCount * mFrameSize;
            buffer->sequence = audioBuffer.sequence;
            memcpy_by_audio_format(buffer->raw, mFormat, audioBuffer.raw,
                                   mServerConfig.format, audioBuffer.size / mServerSampleSize);
                                   mServerConfig.format, audioBuffer.size() / mServerSampleSize);
        }

        const size_t reqSize = buffer->size;
        const size_t reqSize = buffer->size();
        const size_t readSize = callback->onMoreData(*buffer);
        buffer->size = readSize;
        buffer->mSize = readSize;

        // Validate on returned size
        if (ssize_t(readSize) < 0 || readSize > reqSize) {
Loading