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

Commit b718e342 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4500033 from 8bdef6aa to pi-release

Change-Id: I2366c72106f4aec42bf44f83c3e659dde65e2f57
parents 719745a6 8bdef6aa
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -171,7 +171,7 @@ aaudio_result_t AudioStreamInternal::open(const AudioStreamBuilder &builder) {
    mClockModel.setSampleRate(getSampleRate());
    mClockModel.setSampleRate(getSampleRate());
    mClockModel.setFramesPerBurst(mFramesPerBurst);
    mClockModel.setFramesPerBurst(mFramesPerBurst);


    if (getDataCallbackProc()) {
    if (isDataCallbackSet()) {
        mCallbackFrames = builder.getFramesPerDataCallback();
        mCallbackFrames = builder.getFramesPerDataCallback();
        if (mCallbackFrames > getBufferCapacity() / 2) {
        if (mCallbackFrames > getBufferCapacity() / 2) {
            ALOGE("%s - framesPerCallback too big = %d, capacity = %d",
            ALOGE("%s - framesPerCallback too big = %d, capacity = %d",
@@ -290,7 +290,7 @@ aaudio_result_t AudioStreamInternal::requestStart()
    mNeedCatchUp.request();  // Ask data processing code to catch up when first timestamp received.
    mNeedCatchUp.request();  // Ask data processing code to catch up when first timestamp received.


    // Start data callback thread.
    // Start data callback thread.
    if (result == AAUDIO_OK && getDataCallbackProc() != nullptr) {
    if (result == AAUDIO_OK && isDataCallbackSet()) {
        // Launch the callback loop thread.
        // Launch the callback loop thread.
        int64_t periodNanos = mCallbackFrames
        int64_t periodNanos = mCallbackFrames
                              * AAUDIO_NANOS_PER_SECOND
                              * AAUDIO_NANOS_PER_SECOND
+3 −14
Original line number Original line Diff line number Diff line
@@ -232,8 +232,7 @@ int64_t AudioStreamInternalCapture::getFramesRead() {
void *AudioStreamInternalCapture::callbackLoop() {
void *AudioStreamInternalCapture::callbackLoop() {
    aaudio_result_t result = AAUDIO_OK;
    aaudio_result_t result = AAUDIO_OK;
    aaudio_data_callback_result_t callbackResult = AAUDIO_CALLBACK_RESULT_CONTINUE;
    aaudio_data_callback_result_t callbackResult = AAUDIO_CALLBACK_RESULT_CONTINUE;
    AAudioStream_dataCallback appCallback = getDataCallbackProc();
    if (!isDataCallbackSet()) return NULL;
    if (appCallback == nullptr) return NULL;


    // result might be a frame count
    // result might be a frame count
    while (mCallbackEnabled.load() && isActive() && (result >= 0)) {
    while (mCallbackEnabled.load() && isActive() && (result >= 0)) {
@@ -249,22 +248,12 @@ void *AudioStreamInternalCapture::callbackLoop() {
                // Only read some of the frames requested. Must have timed out.
                // Only read some of the frames requested. Must have timed out.
                result = AAUDIO_ERROR_TIMEOUT;
                result = AAUDIO_ERROR_TIMEOUT;
            }
            }
            AAudioStream_errorCallback errorCallback = getErrorCallbackProc();
            maybeCallErrorCallback(result);
            if (errorCallback != nullptr) {
                (*errorCallback)(
                        (AAudioStream *) this,
                        getErrorCallbackUserData(),
                        result);
            }
            break;
            break;
        }
        }


        // Call application using the AAudio callback interface.
        // Call application using the AAudio callback interface.
        callbackResult = (*appCallback)(
        callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
                (AAudioStream *) this,
                getDataCallbackUserData(),
                mCallbackBuffer,
                mCallbackFrames);


        if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
        if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
            ALOGD("callback returned AAUDIO_CALLBACK_RESULT_STOP");
            ALOGD("callback returned AAUDIO_CALLBACK_RESULT_STOP");
+3 −14
Original line number Original line Diff line number Diff line
@@ -323,18 +323,13 @@ int64_t AudioStreamInternalPlay::getFramesWritten()
void *AudioStreamInternalPlay::callbackLoop() {
void *AudioStreamInternalPlay::callbackLoop() {
    aaudio_result_t result = AAUDIO_OK;
    aaudio_result_t result = AAUDIO_OK;
    aaudio_data_callback_result_t callbackResult = AAUDIO_CALLBACK_RESULT_CONTINUE;
    aaudio_data_callback_result_t callbackResult = AAUDIO_CALLBACK_RESULT_CONTINUE;
    AAudioStream_dataCallback appCallback = getDataCallbackProc();
    if (!isDataCallbackSet()) return NULL;
    if (appCallback == nullptr) return NULL;
    int64_t timeoutNanos = calculateReasonableTimeout(mCallbackFrames);
    int64_t timeoutNanos = calculateReasonableTimeout(mCallbackFrames);


    // result might be a frame count
    // result might be a frame count
    while (mCallbackEnabled.load() && isActive() && (result >= 0)) {
    while (mCallbackEnabled.load() && isActive() && (result >= 0)) {
        // Call application using the AAudio callback interface.
        // Call application using the AAudio callback interface.
        callbackResult = (*appCallback)(
        callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
                (AAudioStream *) this,
                getDataCallbackUserData(),
                mCallbackBuffer,
                mCallbackFrames);


        if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
        if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
            // Write audio data to stream. This is a BLOCKING WRITE!
            // Write audio data to stream. This is a BLOCKING WRITE!
@@ -345,13 +340,7 @@ void *AudioStreamInternalPlay::callbackLoop() {
                    // Only wrote some of the frames requested. Must have timed out.
                    // Only wrote some of the frames requested. Must have timed out.
                    result = AAUDIO_ERROR_TIMEOUT;
                    result = AAUDIO_ERROR_TIMEOUT;
                }
                }
                AAudioStream_errorCallback errorCallback = getErrorCallbackProc();
                maybeCallErrorCallback(result);
                if (errorCallback != nullptr) {
                    (*errorCallback)(
                            (AAudioStream *) this,
                            getErrorCallbackUserData(),
                            result);
                }
                break;
                break;
            }
            }
        } else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
        } else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
+16 −8
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
//#define LOG_NDEBUG 0
#include <utils/Log.h>
#include <utils/Log.h>


#include <mutex>
#include <time.h>
#include <time.h>
#include <pthread.h>
#include <pthread.h>


@@ -238,15 +239,22 @@ AAUDIO_API aaudio_result_t AAudioStreamBuilder_delete(AAudioStreamBuilder* buil


AAUDIO_API aaudio_result_t  AAudioStream_close(AAudioStream* stream)
AAUDIO_API aaudio_result_t  AAudioStream_close(AAudioStream* stream)
{
{
    aaudio_result_t result = AAUDIO_ERROR_NULL;
    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
    ALOGD("AAudioStream_close(%p)", stream);
    ALOGD("AAudioStream_close(%p) called ---------------", stream);
    if (audioStream != nullptr) {
    if (audioStream != nullptr) {
        audioStream->close();
        result = audioStream->safeClose();
        // Close will only fail if called illegally, for example, from a callback.
        // That would result in deleting an active stream, which would cause a crash.
        if (result == AAUDIO_OK) {
            audioStream->unregisterPlayerBase();
            audioStream->unregisterPlayerBase();
            delete audioStream;
            delete audioStream;
        return AAUDIO_OK;
        } else {
            ALOGW("%s attempt to close failed. Close from another thread.", __func__);
        }
        }
    return AAUDIO_ERROR_NULL;
    }
    ALOGD("AAudioStream_close(%p) returned %d ---------", stream, result);
    return result;
}
}


AAUDIO_API aaudio_result_t  AAudioStream_requestStart(AAudioStream* stream)
AAUDIO_API aaudio_result_t  AAudioStream_requestStart(AAudioStream* stream)
@@ -269,7 +277,7 @@ AAUDIO_API aaudio_result_t AAudioStream_requestFlush(AAudioStream* stream)
{
{
    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
    ALOGD("AAudioStream_requestFlush(%p)", stream);
    ALOGD("AAudioStream_requestFlush(%p)", stream);
    return audioStream->requestFlush();
    return audioStream->safeFlush();
}
}


AAUDIO_API aaudio_result_t  AAudioStream_requestStop(AAudioStream* stream)
AAUDIO_API aaudio_result_t  AAudioStream_requestStop(AAudioStream* stream)
@@ -324,7 +332,7 @@ AAUDIO_API aaudio_result_t AAudioStream_write(AAudioStream* stream,
    }
    }


    // Don't allow writes when playing with a callback.
    // Don't allow writes when playing with a callback.
    if (audioStream->getDataCallbackProc() != nullptr && audioStream->isActive()) {
    if (audioStream->isDataCallbackActive()) {
        ALOGE("Cannot write to a callback stream when running.");
        ALOGE("Cannot write to a callback stream when running.");
        return AAUDIO_ERROR_INVALID_STATE;
        return AAUDIO_ERROR_INVALID_STATE;
    }
    }
+98 −2
Original line number Original line Diff line number Diff line
@@ -43,7 +43,7 @@ AudioStream::~AudioStream() {
    LOG_ALWAYS_FATAL_IF(!(getState() == AAUDIO_STREAM_STATE_CLOSED
    LOG_ALWAYS_FATAL_IF(!(getState() == AAUDIO_STREAM_STATE_CLOSED
                          || getState() == AAUDIO_STREAM_STATE_UNINITIALIZED
                          || getState() == AAUDIO_STREAM_STATE_UNINITIALIZED
                          || getState() == AAUDIO_STREAM_STATE_DISCONNECTED),
                          || getState() == AAUDIO_STREAM_STATE_DISCONNECTED),
                        "aaudio stream still in use, state = %s",
                        "~AudioStream() - still in use, state = %s",
                        AAudio_convertStreamStateToText(getState()));
                        AAudio_convertStreamStateToText(getState()));


    mPlayerBase->clearParentReference(); // remove reference to this AudioStream
    mPlayerBase->clearParentReference(); // remove reference to this AudioStream
@@ -97,12 +97,56 @@ aaudio_result_t AudioStream::open(const AudioStreamBuilder& builder)
          (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? "OUTPUT" : "INPUT");
          (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? "OUTPUT" : "INPUT");
    ALOGI("open() device = %d, perfMode = %d, callback: %s with frames = %d",
    ALOGI("open() device = %d, perfMode = %d, callback: %s with frames = %d",
          mDeviceId, mPerformanceMode,
          mDeviceId, mPerformanceMode,
          (mDataCallbackProc == nullptr ? "OFF" : "ON"),
          (isDataCallbackSet() ? "ON" : "OFF"),
          mFramesPerDataCallback);
          mFramesPerDataCallback);


    return AAUDIO_OK;
    return AAUDIO_OK;
}
}


aaudio_result_t AudioStream::safeStart() {
    std::lock_guard<std::mutex> lock(mStreamLock);
    if (collidesWithCallback()) {
        ALOGE("%s cannot be called from a callback!", __func__);
        return AAUDIO_ERROR_INVALID_STATE;
    }
    return requestStart();
}

aaudio_result_t AudioStream::safePause() {
    std::lock_guard<std::mutex> lock(mStreamLock);
    if (collidesWithCallback()) {
        ALOGE("%s cannot be called from a callback!", __func__);
        return AAUDIO_ERROR_INVALID_STATE;
    }
    return requestPause();
}

aaudio_result_t AudioStream::safeFlush() {
    std::lock_guard<std::mutex> lock(mStreamLock);
    if (collidesWithCallback()) {
        ALOGE("%s cannot be called from a callback!", __func__);
        return AAUDIO_ERROR_INVALID_STATE;
    }
    return requestFlush();
}

aaudio_result_t AudioStream::safeStop() {
    std::lock_guard<std::mutex> lock(mStreamLock);
    if (collidesWithCallback()) {
        ALOGE("%s cannot be called from a callback!", __func__);
        return AAUDIO_ERROR_INVALID_STATE;
    }
    return requestStop();
}

aaudio_result_t AudioStream::safeClose() {
    std::lock_guard<std::mutex> lock(mStreamLock);
    if (collidesWithCallback()) {
        ALOGE("%s cannot be called from a callback!", __func__);
        return AAUDIO_ERROR_INVALID_STATE;
    }
    return close();
}


aaudio_result_t AudioStream::waitForStateChange(aaudio_stream_state_t currentState,
aaudio_result_t AudioStream::waitForStateChange(aaudio_stream_state_t currentState,
                                                aaudio_stream_state_t *nextState,
                                                aaudio_stream_state_t *nextState,
@@ -200,6 +244,58 @@ aaudio_result_t AudioStream::joinThread(void** returnArg, int64_t timeoutNanosec
}
}




aaudio_data_callback_result_t AudioStream::maybeCallDataCallback(void *audioData,
                                                                 int32_t numFrames) {
    aaudio_data_callback_result_t result = AAUDIO_CALLBACK_RESULT_STOP;
    AAudioStream_dataCallback dataCallback = getDataCallbackProc();
    if (dataCallback != nullptr) {
        // Store thread ID of caller to detect stop() and close() calls from callback.
        pid_t expected = CALLBACK_THREAD_NONE;
        if (mDataCallbackThread.compare_exchange_strong(expected, gettid())) {
            result = (*dataCallback)(
                    (AAudioStream *) this,
                    getDataCallbackUserData(),
                    audioData,
                    numFrames);
            mDataCallbackThread.store(CALLBACK_THREAD_NONE);
        } else {
            ALOGW("%s() data callback already running!", __func__);
        }
    }
    return result;
}

void AudioStream::maybeCallErrorCallback(aaudio_result_t result) {
    AAudioStream_errorCallback errorCallback = getErrorCallbackProc();
    if (errorCallback != nullptr) {
        // Store thread ID of caller to detect stop() and close() calls from callback.
        pid_t expected = CALLBACK_THREAD_NONE;
        if (mErrorCallbackThread.compare_exchange_strong(expected, gettid())) {
            (*errorCallback)(
                    (AAudioStream *) this,
                    getErrorCallbackUserData(),
                    result);
            mErrorCallbackThread.store(CALLBACK_THREAD_NONE);
        } else {
            ALOGW("%s() error callback already running!", __func__);
        }
    }
}

// Is this running on the same thread as a callback?
// Note: This cannot be implemented using a thread_local because that would
// require using a thread_local variable that is shared between streams.
// So a thread_local variable would prevent stopping or closing stream A from
// a callback on stream B, which is currently legal and not so terrible.
bool AudioStream::collidesWithCallback() const {
    pid_t thisThread = gettid();
    // Compare the current thread ID with the thread ID of the callback
    // threads to see it they match. If so then this code is being
    // called from one of the stream callback functions.
    return ((mErrorCallbackThread.load() == thisThread)
            || (mDataCallbackThread.load() == thisThread));
}

#if AAUDIO_USE_VOLUME_SHAPER
#if AAUDIO_USE_VOLUME_SHAPER
android::media::VolumeShaper::Status AudioStream::applyVolumeShaper(
android::media::VolumeShaper::Status AudioStream::applyVolumeShaper(
        const android::media::VolumeShaper::Configuration& configuration __unused,
        const android::media::VolumeShaper::Configuration& configuration __unused,
Loading