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

Commit 6953e3a7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add AudioTrackTest#OffloadCompletion to audiotrack_tests" into main

parents b8a693f9 d20bfb5f
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -136,7 +136,10 @@ cc_defaults {
    cflags: [
        "-Wthread-safety",
    ],
    data: ["bbb*.raw"],
    data: [
        "bbb*.raw",
        "sine960hz_48000_3s.ape",
    ],
    srcs: [
        "audio_test_utils.cpp",
        "test_execution_tracer.cpp",
+1 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
        <!-- Files used for audio testing -->
        <option name="push-file" key="bbb_1ch_8kHz_s16le.raw" value="/data/local/tmp/bbb_1ch_8kHz_s16le.raw" />
        <option name="push-file" key="bbb_2ch_24kHz_s16le.raw" value="/data/local/tmp/bbb_2ch_24kHz_s16le.raw" />
        <option name="push-file" key="sine960hz_48000_3s.ape" value="/data/local/tmp/sine960hz_48000_3s.ape" />
    </target_preparer>

    <test class="com.android.tradefed.testtype.GTest" >
+51 −22
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
 * limitations under the License.
 */

#include <thread>

//#define LOG_NDEBUG 0
#define LOG_TAG "AudioTestUtils"

@@ -22,12 +24,16 @@
#include <binder/IServiceManager.h>
#include <system/audio_config.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>

#include "audio_test_utils.h"

#define WAIT_PERIOD_MS 10  // from AudioTrack.cpp
#define MAX_WAIT_TIME_MS 5000

static constexpr auto kShortCallbackTimeout = std::chrono::milliseconds(500);
static constexpr auto kLongCallbackTimeout = std::chrono::seconds(10);

void OnAudioDeviceUpdateNotifier::onAudioDeviceUpdate(audio_io_handle_t audioIo,
                                                      audio_port_handle_t deviceId) {
    ALOGI("%s: audioIo=%d deviceId=%d", __func__, audioIo, deviceId);
@@ -41,7 +47,7 @@ void OnAudioDeviceUpdateNotifier::onAudioDeviceUpdate(audio_io_handle_t audioIo,

status_t OnAudioDeviceUpdateNotifier::waitForAudioDeviceCb(audio_port_handle_t expDeviceId) {
    std::unique_lock lock(mMutex);
    android::base::ScopedLockAssertion lock_assertion(mMutex);
    base::ScopedLockAssertion lock_assertion(mMutex);
    if (mAudioIo == AUDIO_IO_HANDLE_NONE ||
        (expDeviceId != AUDIO_PORT_HANDLE_NONE && expDeviceId != mDeviceId)) {
        mCondition.wait_for(lock, std::chrono::milliseconds(500));
@@ -70,14 +76,7 @@ AudioPlayback::AudioPlayback(uint32_t sampleRate, audio_format_t format,
      mSessionId(sessionId),
      mTransferType(transferType),
      mAttributes(attributes),
      mOffloadInfo(info) {
    mStopPlaying = false;
    mBytesUsedSoFar = 0;
    mState = PLAY_NO_INIT;
    mMemCapacity = 0;
    mMemoryDealer = nullptr;
    mMemory = nullptr;
}
      mOffloadInfo(info) {}

AudioPlayback::~AudioPlayback() {
    stop();
@@ -92,15 +91,16 @@ status_t AudioPlayback::create() {
    attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
    attributionSource.token = sp<BBinder>::make();
    if (mTransferType == AudioTrack::TRANSFER_OBTAIN) {
        mTrack = new AudioTrack(attributionSource);
        mTrack = sp<TestAudioTrack>::make(attributionSource);
        mTrack->set(AUDIO_STREAM_MUSIC, mSampleRate, mFormat, mChannelMask, 0 /* frameCount */,
                    mFlags, nullptr /* callback */, 0 /* notificationFrames */,
                    nullptr /* sharedBuffer */, false /*canCallJava */, mSessionId, mTransferType,
                    mOffloadInfo, attributionSource, mAttributes);
                    mFlags, wp<AudioTrack::IAudioTrackCallback>::fromExisting(this),
                    0 /* notificationFrames */, nullptr /* sharedBuffer */, false /*canCallJava */,
                    mSessionId, mTransferType, mOffloadInfo, attributionSource, mAttributes);
    } else if (mTransferType == AudioTrack::TRANSFER_SHARED) {
        mTrack = new AudioTrack(AUDIO_STREAM_MUSIC, mSampleRate, mFormat, mChannelMask, mMemory,
                                mFlags, wp<AudioTrack::IAudioTrackCallback>::fromExisting(this), 0,
                                mSessionId, mTransferType, nullptr, attributionSource, mAttributes);
        mTrack = sp<TestAudioTrack>::make(
                AUDIO_STREAM_MUSIC, mSampleRate, mFormat, mChannelMask, mMemory, mFlags,
                wp<AudioTrack::IAudioTrackCallback>::fromExisting(this), 0, mSessionId,
                mTransferType, nullptr, attributionSource, mAttributes);
    } else {
        ALOGE("Test application is not handling transfer type %s",
              AudioTrack::convertTransferToText(mTransferType));
@@ -153,6 +153,8 @@ status_t AudioPlayback::start() {
        if (OK == status) {
            mState = PLAY_STARTED;
            LOG_FATAL_IF(false != mTrack->stopped());
            std::lock_guard l(mMutex);
            mStreamEndReceived = false;
        }
    }
    return status;
@@ -163,6 +165,15 @@ void AudioPlayback::onBufferEnd() {
    mStopPlaying = true;
}

void AudioPlayback::onStreamEnd() {
    ALOGD("%s", __func__);
    {
        std::lock_guard lock(mMutex);
        mStreamEndReceived = true;
    }
    mCondition.notify_all();
}

status_t AudioPlayback::fillBuffer() {
    if (PLAY_STARTED != mState) return INVALID_OPERATION;
    const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
@@ -189,6 +200,7 @@ status_t AudioPlayback::fillBuffer() {
            counter++;
        }
    }
    mBytesUsedSoFar = 0;
    return OK;
}

@@ -254,7 +266,7 @@ void AudioPlayback::stop() {
    if (mState != PLAY_STOPPED && mState != PLAY_NO_INIT) {
        int32_t msec = 0;
        (void)mTrack->pendingDuration(&msec);
        mTrack->stopAndJoinCallbacks();
        mTrack->stop();  // Do not join the callback thread, drain may be ongoing.
        LOG_FATAL_IF(true != mTrack->stopped());
        mState = PLAY_STOPPED;
        if (msec > 0) {
@@ -264,6 +276,23 @@ void AudioPlayback::stop() {
    }
}

bool AudioPlayback::waitForStreamEnd() {
    ALOGD("%s", __func__);
    const int64_t endMs = uptimeMillis() + std::chrono::milliseconds(kLongCallbackTimeout).count();
    while (uptimeMillis() < endMs) {
        // Wake up the AudioPlaybackThread to get notifications.
        mTrack->wakeCallbackThread();
        std::unique_lock lock(mMutex);
        base::ScopedLockAssertion lock_assertion(mMutex);
        mCondition.wait_for(lock, kShortCallbackTimeout, [this]() {
            base::ScopedLockAssertion lock_assertion(mMutex);
            return mStreamEndReceived;
        });
        if (mStreamEndReceived) return true;
    }
    return false;
}

// hold pcm data sent by AudioRecord
RawBuffer::RawBuffer(int64_t ptsPipeline, int64_t ptsManual, int32_t capacity)
    : mData(capacity > 0 ? new uint8_t[capacity] : nullptr),
@@ -565,7 +594,7 @@ status_t AudioCapture::obtainBufferCb(RawBuffer& buffer) {
    const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
    int counter = 0;
    std::unique_lock lock(mMutex);
    android::base::ScopedLockAssertion lock_assertion(mMutex);
    base::ScopedLockAssertion lock_assertion(mMutex);
    while (mBuffersReceived.empty() && !mStopRecording && counter < maxTries) {
        mCondition.wait_for(lock, std::chrono::milliseconds(WAIT_PERIOD_MS));
        counter++;
@@ -625,9 +654,9 @@ void AudioCapture::setMarkerPosition(uint32_t markerPosition) {

uint32_t AudioCapture::waitAndGetReceivedCbMarkerAtPosition() const {
    std::unique_lock lock(mMutex);
    android::base::ScopedLockAssertion lock_assertion(mMutex);
    base::ScopedLockAssertion lock_assertion(mMutex);
    mMarkerCondition.wait_for(lock, std::chrono::seconds(3), [this]() {
        android::base::ScopedLockAssertion lock_assertion(mMutex);
        base::ScopedLockAssertion lock_assertion(mMutex);
        return mReceivedCbMarkerAtPosition.has_value();
    });
    return mReceivedCbMarkerAtPosition.value_or(~0);
@@ -635,9 +664,9 @@ uint32_t AudioCapture::waitAndGetReceivedCbMarkerAtPosition() const {

uint32_t AudioCapture::waitAndGetReceivedCbMarkerCount() const {
    std::unique_lock lock(mMutex);
    android::base::ScopedLockAssertion lock_assertion(mMutex);
    base::ScopedLockAssertion lock_assertion(mMutex);
    mMarkerCondition.wait_for(lock, std::chrono::seconds(3), [this]() {
        android::base::ScopedLockAssertion lock_assertion(mMutex);
        base::ScopedLockAssertion lock_assertion(mMutex);
        return mReceivedCbMarkerCount.has_value();
    });
    return mReceivedCbMarkerCount.value_or(0);
+46 −9
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
#include <deque>
#include <memory>
#include <mutex>
#include <thread>
#include <utility>

#include <android-base/thread_annotations.h>
@@ -75,6 +74,39 @@ class OnAudioDeviceUpdateNotifier : public AudioSystem::AudioDeviceCallback {
    std::condition_variable mCondition;
};

namespace {

class TestAudioTrack : public AudioTrack {
  public:
    explicit TestAudioTrack(const AttributionSourceState& attributionSourceState = {})
        : AudioTrack(attributionSourceState) {}
    TestAudioTrack(audio_stream_type_t streamType, uint32_t sampleRate, audio_format_t format,
                   audio_channel_mask_t channelMask, const sp<IMemory>& sharedBuffer,
                   audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                   const wp<IAudioTrackCallback>& callback = nullptr,
                   int32_t notificationFrames = 0,
                   audio_session_t sessionId = AUDIO_SESSION_ALLOCATE,
                   transfer_type transferType = TRANSFER_DEFAULT,
                   const audio_offload_info_t* offloadInfo = nullptr,
                   const AttributionSourceState& attributionSource = AttributionSourceState(),
                   const audio_attributes_t* pAttributes = nullptr, bool doNotReconnect = false,
                   float maxRequiredSpeed = 1.0f)
        : AudioTrack(streamType, sampleRate, format, channelMask, sharedBuffer, flags, callback,
                     notificationFrames, sessionId, transferType, offloadInfo, attributionSource,
                     pAttributes, doNotReconnect, maxRequiredSpeed) {}
    // The callback thread is normally used for TRANSFER_SYNC_NOTIF_CALLBACK
    // in order to deliver "more data" callback. However, for offload we are
    // interested in the "stream end" event which is also served via the same
    // callback interface.
    void wakeCallbackThread() {
        if (sp<AudioTrackThread> t = mAudioTrackThread; t != nullptr) {
            t->wake();
        }
    }
};

}  // namespace

// Simple AudioPlayback class.
class AudioPlayback : public AudioTrack::IAudioTrackCallback {
    friend sp<AudioPlayback>;
@@ -92,11 +124,14 @@ class AudioPlayback : public AudioTrack::IAudioTrackCallback {
    status_t waitForConsumption(bool testSeek = false) EXCLUDES(mMutex);
    status_t fillBuffer();
    status_t onProcess(bool testSeek = false);
    void onBufferEnd() override EXCLUDES(mMutex);
    void stop() EXCLUDES(mMutex);
    bool waitForStreamEnd();

    bool mStopPlaying GUARDED_BY(mMutex);
    mutable std::mutex mMutex;
    // IAudioTrackCallback
    void onBufferEnd() override EXCLUDES(mMutex);
    void onStreamEnd() override EXCLUDES(mMutex);

    bool mStopPlaying GUARDED_BY(mMutex) = false;

    enum State {
        PLAY_NO_INIT,
@@ -116,13 +151,15 @@ class AudioPlayback : public AudioTrack::IAudioTrackCallback {
    const audio_attributes_t* mAttributes;
    const audio_offload_info_t* mOffloadInfo;

    size_t mBytesUsedSoFar;
    State mState;
    size_t mMemCapacity;
    size_t mBytesUsedSoFar = 0;
    State mState = PLAY_NO_INIT;
    size_t mMemCapacity = 0;
    sp<MemoryDealer> mMemoryDealer;
    sp<IMemory> mMemory;

    sp<AudioTrack> mTrack;
    sp<TestAudioTrack> mTrack;
    mutable std::mutex mMutex;
    bool mStreamEndReceived GUARDED_BY(mMutex) = false;
    std::condition_variable mCondition;
};

// hold pcm data sent by AudioRecord
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <fstream>
#include <iostream>
#include <string>
#include <thread>
#include <tuple>
#include <vector>

Loading