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

Commit 2534b388 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

Abstract access to HAL stream via Source in RecordThread

This allows to replace direct reading from HAL with obtaining
audio data from another source.

It should be possible to encapsulate reading from FastCapture
in the same manner, but it's not required for direct inputs.

Test: make
Change-Id: I3f005583410cc9c5d4b07c127d95e236abb4a85f
parent 8296c252
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -547,6 +547,16 @@ private:
        bool        mute;
    };

    // Abstraction for the Audio Source for the RecordThread (HAL or PassthruPatchRecord).
    struct Source
    {
        virtual ~Source() = default;
        // The following methods have the same signatures as in StreamHalInterface.
        virtual status_t read(void *buffer, size_t bytes, size_t *read) = 0;
        virtual status_t getCapturePosition(int64_t *frames, int64_t *time) = 0;
        virtual status_t standby() = 0;
    };

    // --- PlaybackThread ---
#ifdef FLOAT_EFFECT_CHAIN
#define EFFECT_BUFFER_FORMAT AUDIO_FORMAT_PCM_FLOAT
@@ -749,7 +759,7 @@ using effect_buffer_t = int16_t;
    // For emphasis, we could also make all pointers to them be "const *",
    // but that would clutter the code unnecessarily.

    struct AudioStreamIn {
    struct AudioStreamIn : public Source {
        AudioHwDevice* const audioHwDev;
        sp<StreamInHalInterface> stream;
        audio_input_flags_t flags;
@@ -758,6 +768,13 @@ using effect_buffer_t = int16_t;

        AudioStreamIn(AudioHwDevice *dev, sp<StreamInHalInterface> in, audio_input_flags_t flags) :
            audioHwDev(dev), stream(in), flags(flags) {}
        status_t read(void *buffer, size_t bytes, size_t *read) override {
            return stream->read(buffer, bytes, read);
        }
        status_t getCapturePosition(int64_t *frames, int64_t *time) override {
            return stream->getCapturePosition(frames, time);
        }
        status_t standby() override { return stream->standby(); }
    };

    struct TeePatch {
+2 −0
Original line number Diff line number Diff line
@@ -167,6 +167,8 @@ public:
                const Timeout& timeout = {});
    virtual             ~PatchRecord();

    virtual Source* getSource() { return nullptr; }

    // AudioBufferProvider interface
    virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
    virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+10 −3
Original line number Diff line number Diff line
@@ -6679,6 +6679,7 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
                                         ) :
    ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD, systemReady),
    mInput(input),
    mSource(mInput),
    mActiveTracks(&this->mLocalLog),
    mRsmpInBuffer(NULL),
    // mRsmpInFrames, mRsmpInFramesP2, and mRsmpInFramesOA are set by readInputParameters_l()
@@ -7131,7 +7132,7 @@ reacquire_wakelock:
        } else {
            ATRACE_BEGIN("read");
            size_t bytesRead;
            status_t result = mInput->stream->read(
            status_t result = mSource->read(
                    (uint8_t*)mRsmpInBuffer + rear * mFrameSize, mBufferSize, &bytesRead);
            ATRACE_END();
            if (result < 0) {
@@ -7153,7 +7154,7 @@ reacquire_wakelock:
            int64_t position, time;
            if (mStandby) {
                mTimestampVerifier.discontinuity();
            } else if (mInput->stream->getCapturePosition(&position, &time) == NO_ERROR
            } else if (mSource->getCapturePosition(&position, &time) == NO_ERROR
                    && time > mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]) {

                mTimestampVerifier.add(position, time, mSampleRate);
@@ -7434,7 +7435,7 @@ void AudioFlinger::RecordThread::inputStandBy()
            sq->end(false /*didModify*/);
        }
    }
    status_t result = mInput->stream->standby();
    status_t result = mSource->standby();
    ALOGE_IF(result != OK, "Error when putting input stream into standby: %d", result);

    // If going into standby, flush the pipe source.
@@ -8420,11 +8421,17 @@ void AudioFlinger::RecordThread::addPatchTrack(const sp<PatchRecord>& record)
{
    Mutex::Autolock _l(mLock);
    mTracks.add(record);
    if (record->getSource()) {
        mSource = record->getSource();
    }
}

void AudioFlinger::RecordThread::deletePatchTrack(const sp<PatchRecord>& record)
{
    Mutex::Autolock _l(mLock);
    if (mSource == record->getSource()) {
        mSource = mInput;
    }
    destroyTrack_l(record);
}

+1 −0
Original line number Diff line number Diff line
@@ -1647,6 +1647,7 @@ private:
            void    checkBtNrec_l();

            AudioStreamIn                       *mInput;
            Source                              *mSource;
            SortedVector < sp<RecordTrack> >    mTracks;
            // mActiveTracks has dual roles:  it indicates the current active track(s), and
            // is used together with mStartStopCond to indicate start()/stop() progress