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

Commit 45986c74 authored by Kevin Rocard's avatar Kevin Rocard
Browse files

Audioflinger: add timeout to PatchTrack



Add support for timeout that was only supported by PatchRecord.
This is implemented by moving the timeout and common code in a base
class.

Also remove PatchRecord useless virtual inheritance of RecordTrack.

Test: adb shell audiorecorder --target /data/file.raw
Bug: 111453086
Change-Id: I833148f31a311ca41092be1d7e2d170f086322c5
Signed-off-by: default avatarKevin Rocard <krocard@google.com>
parent ba98acb3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -21,8 +21,10 @@
#include "Configuration.h"
#include <atomic>
#include <mutex>
#include <chrono>
#include <deque>
#include <map>
#include <optional>
#include <set>
#include <string>
#include <vector>
+3 −7
Original line number Diff line number Diff line
@@ -318,7 +318,7 @@ private:
};  // end of OutputTrack

// playback track, used by PatchPanel
class PatchTrack : public Track, public PatchProxyBufferProvider {
class PatchTrack : public Track, public PatchTrackBase {
public:

                        PatchTrack(PlaybackThread *playbackThread,
@@ -329,7 +329,8 @@ public:
                                   size_t frameCount,
                                   void *buffer,
                                   size_t bufferSize,
                                   audio_output_flags_t flags);
                                   audio_output_flags_t flags,
                                   const Timeout& timeout = {});
    virtual             ~PatchTrack();

    virtual status_t    start(AudioSystem::sync_event_t event =
@@ -345,12 +346,7 @@ public:
                                     const struct timespec *timeOut = NULL);
    virtual void        releaseBuffer(Proxy::Buffer* buffer);

            void setPeerProxy(PatchProxyBufferProvider *proxy) { mPeerProxy = proxy; }

private:
            void restartIfDisabled();

    sp<ClientProxy>             mProxy;
    PatchProxyBufferProvider*   mPeerProxy;
    struct timespec             mPeerTimeout;
};  // end of PatchTrack
+3 −9
Original line number Diff line number Diff line
@@ -113,7 +113,7 @@ private:
};

// playback track, used by PatchPanel
class PatchRecord : virtual public RecordTrack, public PatchProxyBufferProvider {
class PatchRecord : public RecordTrack, public PatchTrackBase {
public:

    PatchRecord(RecordThread *recordThread,
@@ -123,7 +123,8 @@ public:
                size_t frameCount,
                void *buffer,
                size_t bufferSize,
                audio_input_flags_t flags);
                audio_input_flags_t flags,
                const Timeout& timeout = {});
    virtual             ~PatchRecord();

    // AudioBufferProvider interface
@@ -134,11 +135,4 @@ public:
    virtual status_t    obtainBuffer(Proxy::Buffer *buffer,
                                     const struct timespec *timeOut = NULL);
    virtual void        releaseBuffer(Proxy::Buffer *buffer);

    void setPeerProxy(PatchProxyBufferProvider *proxy) { mPeerProxy = proxy; }

private:
    sp<ClientProxy>             mProxy;
    PatchProxyBufferProvider*   mPeerProxy;
    struct timespec             mPeerTimeout;
};  // end of PatchRecord
+16 −0
Original line number Diff line number Diff line
@@ -329,3 +329,19 @@ public:
                                     const struct timespec *requested = NULL) = 0;
    virtual void        releaseBuffer(Proxy::Buffer* buffer) = 0;
};

class PatchTrackBase : public PatchProxyBufferProvider
{
public:
    using Timeout = std::optional<std::chrono::nanoseconds>;
                        PatchTrackBase(sp<ClientProxy> proxy, const ThreadBase& thread,
                                       const Timeout& timeout);
            void        setPeerTimeout(std::chrono::nanoseconds timeout);
            void        setPeerProxy(PatchProxyBufferProvider *proxy) { mPeerProxy = proxy; }

protected:
    const sp<ClientProxy>       mProxy;
    PatchProxyBufferProvider*   mPeerProxy = nullptr;
    struct timespec             mPeerTimeout{};

};
+29 −14
Original line number Diff line number Diff line
@@ -277,6 +277,27 @@ status_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>&
    return NO_ERROR;
}

AudioFlinger::ThreadBase::PatchTrackBase::PatchTrackBase(sp<ClientProxy> proxy,
                                                         const ThreadBase& thread,
                                                         const Timeout& timeout)
    : mProxy(proxy)
{
    if (timeout) {
        setPeerTimeout(*timeout);
    } else {
        // Double buffer mixer
        uint64_t mixBufferNs = ((uint64_t)2 * thread.frameCount() * 1000000000) /
                                              thread.sampleRate();
        setPeerTimeout(std::chrono::nanoseconds{mixBufferNs});
    }
}

void AudioFlinger::ThreadBase::PatchTrackBase::setPeerTimeout(std::chrono::nanoseconds timeout) {
    mPeerTimeout.tv_sec = timeout.count() / std::nano::den;
    mPeerTimeout.tv_nsec = timeout.count() % std::nano::den;
}


// ----------------------------------------------------------------------------
//      Playback
// ----------------------------------------------------------------------------
@@ -1615,19 +1636,16 @@ AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThr
                                                     size_t frameCount,
                                                     void *buffer,
                                                     size_t bufferSize,
                                                     audio_output_flags_t flags)
                                                     audio_output_flags_t flags,
                                                     const Timeout& timeout)
    :   Track(playbackThread, NULL, streamType,
              audio_attributes_t{} /* currently unused for patch track */,
              sampleRate, format, channelMask, frameCount,
              buffer, bufferSize, nullptr /* sharedBuffer */,
              AUDIO_SESSION_NONE, AID_AUDIOSERVER, flags, TYPE_PATCH),
              mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
        PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true),
                       *playbackThread, timeout)
{
    uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
                                                                    playbackThread->sampleRate();
    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);

    ALOGV("%s(%d): sampleRate %d mPeerTimeout %d.%03d sec",
                                      __func__, mId, sampleRate,
                                      (int)mPeerTimeout.tv_sec,
@@ -2088,19 +2106,16 @@ AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
                                                     size_t frameCount,
                                                     void *buffer,
                                                     size_t bufferSize,
                                                     audio_input_flags_t flags)
                                                     audio_input_flags_t flags,
                                                     const Timeout& timeout)
    :   RecordTrack(recordThread, NULL,
                audio_attributes_t{} /* currently unused for patch track */,
                sampleRate, format, channelMask, frameCount,
                buffer, bufferSize, AUDIO_SESSION_NONE, AID_AUDIOSERVER,
                flags, TYPE_PATCH),
                mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
        PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true),
                       *recordThread, timeout)
{
    uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /
                                                                recordThread->sampleRate();
    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);

    ALOGV("%s(%d): sampleRate %d mPeerTimeout %d.%03d sec",
                                      __func__, mId, sampleRate,
                                      (int)mPeerTimeout.tv_sec,