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

Commit 4d3015f2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes I30701af5,I204198b1 into main am: 7da1f224

parents 4915dfb8 7da1f224
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -654,21 +654,16 @@ status_t StreamOutHalAidl::write(const void *buffer, size_t bytes, size_t *writt
    return transfer(const_cast<void*>(buffer), bytes, written);
}

status_t StreamOutHalAidl::getRenderPosition(uint32_t *dspFrames) {
status_t StreamOutHalAidl::getRenderPosition(uint64_t *dspFrames) {
    if (dspFrames == nullptr) {
        return BAD_VALUE;
    }
    int64_t aidlFrames = 0, aidlTimestamp = 0;
    RETURN_STATUS_IF_ERROR(getObservablePosition(&aidlFrames, &aidlTimestamp));
    *dspFrames = static_cast<uint32_t>(aidlFrames);
    *dspFrames = aidlFrames;
    return OK;
}

status_t StreamOutHalAidl::getNextWriteTimestamp(int64_t *timestamp __unused) {
    // Obsolete, use getPresentationPosition.
    return INVALID_OPERATION;
}

status_t StreamOutHalAidl::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
    ALOGD("%p %s", this, __func__);
    TIME_CHECK();
@@ -729,6 +724,11 @@ status_t StreamOutHalAidl::getPresentationPosition(uint64_t *frames, struct time
    return OK;
}

status_t StreamOutHalAidl::presentationComplete() {
    ALOGD("%p %s::%s", this, getClassName().c_str(), __func__);
    return OK;
}

status_t StreamOutHalAidl::updateSourceMetadata(
        const StreamOutHalInterface::SourceMetadata& sourceMetadata) {
    TIME_CHECK();
+4 −4
Original line number Diff line number Diff line
@@ -308,10 +308,7 @@ class StreamOutHalAidl : public virtual StreamOutHalInterface,

    // Return the number of audio frames written by the audio dsp to DAC since
    // the output has exited standby.
    status_t getRenderPosition(uint32_t *dspFrames) override;

    // Get the local time at which the next write to the audio driver will be presented.
    status_t getNextWriteTimestamp(int64_t *timestamp) override;
    status_t getRenderPosition(uint64_t *dspFrames) override;

    // Set the callback for notifying completion of non-blocking write and drain.
    status_t setCallback(wp<StreamOutHalInterfaceCallback> callback) override;
@@ -337,6 +334,9 @@ class StreamOutHalAidl : public virtual StreamOutHalInterface,
    // Return a recent count of the number of audio frames presented to an external observer.
    status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) override;

    // Notifies the HAL layer that the framework considers the current playback as completed.
    status_t presentationComplete() override;

    // Called when the metadata of the stream's source has been changed.
    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;

+50 −17
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
#define LOG_TAG "StreamHalHidl"
//#define LOG_NDEBUG 0

#include <cinttypes>

#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hwbinder/IPCThreadState.h>
#include <media/AudioParameter.h>
@@ -589,32 +591,39 @@ status_t StreamOutHalHidl::prepareForWriting(size_t bufferSize) {
    return OK;
}

status_t StreamOutHalHidl::getRenderPosition(uint32_t *dspFrames) {
status_t StreamOutHalHidl::getRenderPosition(uint64_t *dspFrames) {
    // TIME_CHECK();  // TODO(b/243839867) reenable only when optimized.
    if (mStream == 0) return NO_INIT;
    Result retval;
    uint32_t halPosition = 0;
    Return<void> ret = mStream->getRenderPosition(
            [&](Result r, uint32_t d) {
                retval = r;
                if (retval == Result::OK) {
                    *dspFrames = d;
                    halPosition = d;
                }
            });
    return processReturn("getRenderPosition", ret, retval);
}

status_t StreamOutHalHidl::getNextWriteTimestamp(int64_t *timestamp) {
    TIME_CHECK();
    if (mStream == 0) return NO_INIT;
    Result retval;
    Return<void> ret = mStream->getNextWriteTimestamp(
            [&](Result r, int64_t t) {
                retval = r;
                if (retval == Result::OK) {
                    *timestamp = t;
    status_t status = processReturn("getRenderPosition", ret, retval);
    if (status != OK) {
        return status;
    }
            });
    return processReturn("getRenderPosition", ret, retval);
    // Maintain a 64-bit render position using the 32-bit result from the HAL.
    // This delta calculation relies on the arithmetic overflow behavior
    // of integers. For example (100 - 0xFFFFFFF0) = 116.
    std::lock_guard l(mPositionMutex);
    const auto truncatedPosition = (uint32_t)mRenderPosition;
    int32_t deltaHalPosition; // initialization not needed, overwitten by __builtin_sub_overflow()
    (void) __builtin_sub_overflow(halPosition, truncatedPosition, &deltaHalPosition);

    if (deltaHalPosition >= 0) {
        mRenderPosition += deltaHalPosition;
    } else if (mExpectRetrograde) {
        mExpectRetrograde = false;
        mRenderPosition -= static_cast<uint64_t>(-deltaHalPosition);
        ALOGW("Retrograde motion of %" PRId32 " frames", -deltaHalPosition);
    }
    *dspFrames = mRenderPosition;
    return OK;
}

status_t StreamOutHalHidl::setCallback(wp<StreamOutHalInterfaceCallback> callback) {
@@ -667,9 +676,23 @@ status_t StreamOutHalHidl::drain(bool earlyNotify) {
status_t StreamOutHalHidl::flush() {
    TIME_CHECK();
    if (mStream == 0) return NO_INIT;
    {
        std::lock_guard l(mPositionMutex);
        mRenderPosition = 0;
        mExpectRetrograde = false;
    }
    return processReturn("pause", mStream->flush());
}

status_t StreamOutHalHidl::standby() {
    {
        std::lock_guard l(mPositionMutex);
        mRenderPosition = 0;
        mExpectRetrograde = false;
    }
    return StreamHalHidl::standby();
}

status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) {
    // TIME_CHECK();  // TODO(b/243839867) reenable only when optimized.
    if (mStream == 0) return NO_INIT;
@@ -696,6 +719,16 @@ status_t StreamOutHalHidl::getPresentationPosition(uint64_t *frames, struct time
    }
}

status_t StreamOutHalHidl::presentationComplete() {
    // Avoid suppressing retrograde motion in mRenderPosition for gapless offload/direct when
    // transitioning between tracks.
    // The HAL resets the frame position without flush/stop being called, but calls back prior to
    // this event. So, on the next occurrence of retrograde motion, we permit backwards movement of
    // mRenderPosition.
    mExpectRetrograde = true;
    return OK;
}

#if MAJOR_VERSION == 2
status_t StreamOutHalHidl::updateSourceMetadata(
        const StreamOutHalInterface::SourceMetadata& /* sourceMetadata */) {
+13 −4
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@
#define ANDROID_HARDWARE_STREAM_HAL_HIDL_H

#include <atomic>
#include <mutex>

#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStream.h)
#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStreamIn.h)
#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h)
#include <android-base/thread_annotations.h>
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
#include <media/audiohal/EffectHalInterface.h>
@@ -119,6 +121,9 @@ class StreamHalHidl : public virtual StreamHalInterface, public CoreConversionHe

class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
  public:
    // Put the audio hardware input/output into standby mode (from StreamHalInterface).
    status_t standby() override;

    // Return the frame size (number of bytes per sample) of a stream.
    virtual status_t getFrameSize(size_t *size);

@@ -136,10 +141,7 @@ class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {

    // Return the number of audio frames written by the audio dsp to DAC since
    // the output has exited standby.
    virtual status_t getRenderPosition(uint32_t *dspFrames);

    // Get the local time at which the next write to the audio driver will be presented.
    virtual status_t getNextWriteTimestamp(int64_t *timestamp);
    virtual status_t getRenderPosition(uint64_t *dspFrames);

    // Set the callback for notifying completion of non-blocking write and drain.
    virtual status_t setCallback(wp<StreamOutHalInterfaceCallback> callback);
@@ -165,6 +167,9 @@ class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
    // Return a recent count of the number of audio frames presented to an external observer.
    virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);

    // Notifies the HAL layer that the framework considers the current playback as completed.
    status_t presentationComplete() override;

    // Called when the metadata of the stream's source has been changed.
    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;

@@ -221,6 +226,10 @@ class StreamOutHalHidl : public StreamOutHalInterface, public StreamHalHidl {
    std::unique_ptr<StatusMQ> mStatusMQ;
    std::atomic<pid_t> mWriterClient;
    EventFlag* mEfGroup;
    std::mutex mPositionMutex;
    // Used to expand correctly the 32-bit position from the HAL.
    uint64_t mRenderPosition GUARDED_BY(mPositionMutex) = 0;
    bool mExpectRetrograde GUARDED_BY(mPositionMutex) = false; // See 'presentationComplete'.

    // Can not be constructed directly by clients.
    StreamOutHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& stream);
+4 −4
Original line number Diff line number Diff line
@@ -151,10 +151,7 @@ class StreamOutHalInterface : public virtual StreamHalInterface {

    // Return the number of audio frames written by the audio dsp to DAC since
    // the output has exited standby.
    virtual status_t getRenderPosition(uint32_t *dspFrames) = 0;

    // Get the local time at which the next write to the audio driver will be presented.
    virtual status_t getNextWriteTimestamp(int64_t *timestamp) = 0;
    virtual status_t getRenderPosition(uint64_t *dspFrames) = 0;

    // Set the callback for notifying completion of non-blocking write and drain.
    // The callback must be owned by someone else. The output stream does not own it
@@ -182,6 +179,9 @@ class StreamOutHalInterface : public virtual StreamHalInterface {
    // Return a recent count of the number of audio frames presented to an external observer.
    virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) = 0;

    // Notifies the HAL layer that the framework considers the current playback as completed.
    virtual status_t presentationComplete() = 0;

    struct SourceMetadata {
        std::vector<playback_track_metadata_v7_t> tracks;
    };
Loading