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

Commit 704aec43 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audio: Add optional 'DriverInterface::getPosition' method.

This is a method which can be optionally implemented
by a stream in case it can provide more exact position,
for example by taking into account data in intermediate
buffers.

Implemented this method for StreamAlsa and StreamRemoteSubmix.

Bug: 264712385
Test: atest VtsHalAudioCoreTargetTest
Change-Id: I392933f8f6b22d784726925199db00dcb0313648
parent 521fc49f
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -110,11 +110,13 @@ void StreamWorkerCommonLogic::populateReply(StreamDescriptor::Reply* reply,
    if (isConnected) {
        reply->observable.frames = mFrameCount;
        reply->observable.timeNs = ::android::elapsedRealtimeNano();
    } else {
        if (auto status = mDriver->getPosition(&reply->observable); status == ::android::OK) {
            return;
        }
    }
    reply->observable.frames = StreamDescriptor::Position::UNKNOWN;
    reply->observable.timeNs = StreamDescriptor::Position::UNKNOWN;
}
}

void StreamWorkerCommonLogic::populateReplyWrongState(
        StreamDescriptor::Reply* reply, const StreamDescriptor::Command& command) const {
+32 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <android-base/logging.h>

#include <Utils.h>
#include <audio_utils/clock.h>
#include <error/expected_utils.h>

#include "core-impl/StreamAlsa.h"
@@ -96,6 +97,37 @@ StreamAlsa::StreamAlsa(const Metadata& metadata, StreamContext&& context)
    return ::android::OK;
}

::android::status_t StreamAlsa::getPosition(StreamDescriptor::Position* position) {
    if (mAlsaDeviceProxies.empty()) {
        LOG(FATAL) << __func__ << ": no input devices";
        return ::android::NO_INIT;
    }
    if (mIsInput) {
        if (int ret = proxy_get_capture_position(mAlsaDeviceProxies[0].get(), &position->frames,
                                                 &position->timeNs);
            ret != 0) {
            LOG(WARNING) << __func__ << ": failed to retrieve capture position: " << ret;
            return ::android::INVALID_OPERATION;
        }
    } else {
        uint64_t hwFrames;
        struct timespec timestamp;
        if (int ret = proxy_get_presentation_position(mAlsaDeviceProxies[0].get(), &hwFrames,
                                                      &timestamp);
            ret == 0) {
            if (hwFrames > std::numeric_limits<int64_t>::max()) {
                hwFrames -= std::numeric_limits<int64_t>::max();
            }
            position->frames = static_cast<int64_t>(hwFrames);
            position->timeNs = audio_utils_ns_from_timespec(&timestamp);
        } else {
            LOG(WARNING) << __func__ << ": failed to retrieve presentation position: " << ret;
            return ::android::INVALID_OPERATION;
        }
    }
    return ::android::OK;
}

void StreamAlsa::shutdown() {
    mAlsaDeviceProxies.clear();
}
+6 −0
Original line number Diff line number Diff line
@@ -184,6 +184,12 @@ struct DriverInterface {
    virtual ::android::status_t start() = 0;
    virtual ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                         int32_t* latencyMs) = 0;
    // No need to implement 'getPosition' unless the driver can provide more precise
    // data than just total frame count. For example, the driver may correctly account
    // for any intermediate buffers.
    virtual ::android::status_t getPosition(StreamDescriptor::Position* /*position*/) {
        return ::android::OK;
    }
    virtual void shutdown() = 0;  // This function is only called once.
};

+1 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ class StreamAlsa : public StreamCommonImpl {
    ::android::status_t start() override;
    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                 int32_t* latencyMs) override;
    ::android::status_t getPosition(StreamDescriptor::Position* position) override;
    void shutdown() override;

  protected:
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ class StreamRemoteSubmix : public StreamCommonImpl {
    ::android::status_t start() override;
    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                 int32_t* latencyMs) override;
    ::android::status_t getPosition(StreamDescriptor::Position* position) override;
    void shutdown() override;

    // Overridden methods of 'StreamCommonImpl', called on a Binder thread.
Loading