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

Commit d02904c6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Use fast mode with patch track and patch record if possible."

parents 965737ed 01c8f568
Loading
Loading
Loading
Loading
+28 −5
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#define ATRACE_TAG ATRACE_TAG_AUDIO

#include "Configuration.h"
#include <audio_utils/format.h>
#include <linux/futex.h>
#include <sys/syscall.h>
#include <media/AudioBufferProvider.h>
@@ -161,7 +162,21 @@ void FastCapture::onWork()
    const FastCaptureState * const current = (const FastCaptureState *) mCurrent;
    FastCaptureDumpState * const dumpState = (FastCaptureDumpState *) mDumpState;
    const FastCaptureState::Command command = mCommand;
    const size_t frameCount = current->mFrameCount;
    size_t frameCount = current->mFrameCount;
    AudioBufferProvider* fastPatchRecordBufferProvider = current->mFastPatchRecordBufferProvider;
    AudioBufferProvider::Buffer patchBuffer;

    if (fastPatchRecordBufferProvider != 0) {
        patchBuffer.frameCount = ~0;
        status_t status = fastPatchRecordBufferProvider->getNextBuffer(&patchBuffer);
        if (status != NO_ERROR) {
            frameCount = 0;
        } else if (patchBuffer.frameCount < frameCount) {
            // TODO: Make sure that it doesn't cause any issues if we just get a small available
            // buffer from the buffer provider.
            frameCount = patchBuffer.frameCount;
        }
    }

    if ((command & FastCaptureState::READ) /*&& isWarm*/) {
        ALOG_ASSERT(mInputSource != NULL);
@@ -176,6 +191,7 @@ void FastCapture::onWork()
            mTotalNativeFramesRead += framesRead;
            dumpState->mFramesRead = mTotalNativeFramesRead;
            mReadBufferState = framesRead;
            patchBuffer.frameCount = framesRead;
        } else {
            dumpState->mReadErrors++;
            mReadBufferState = 0;
@@ -193,11 +209,18 @@ void FastCapture::onWork()
        }
        if (mReadBufferState > 0) {
            ssize_t framesWritten = mPipeSink->write(mReadBuffer, mReadBufferState);
            audio_track_cblk_t* cblk = current->mCblk;
            if (fastPatchRecordBufferProvider != 0) {
                // This indicates the fast track is a patch record, update the cblk by
                // calling releaseBuffer().
                memcpy_by_audio_format(patchBuffer.raw, current->mFastPatchRecordFormat,
                        mReadBuffer, mFormat.mFormat, framesWritten * mFormat.mChannelCount);
                patchBuffer.frameCount = framesWritten;
                fastPatchRecordBufferProvider->releaseBuffer(&patchBuffer);
            } else if (cblk != NULL && framesWritten > 0) {
                // FIXME This supports at most one fast capture client.
                //       To handle multiple clients this could be converted to an array,
                //       or with a lot more work the control block could be shared by all clients.
            audio_track_cblk_t* cblk = current->mCblk;
            if (cblk != NULL && framesWritten > 0) {
                int32_t rear = cblk->u.mStreaming.mRear;
                android_atomic_release_store(framesWritten + rear, &cblk->u.mStreaming.mRear);
                cblk->mServer += framesWritten;
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define ANDROID_AUDIO_FAST_CAPTURE_STATE_H

#include <media/nbaio/NBAIO.h>
#include <media/AudioBufferProvider.h>
#include "FastThreadState.h"
#include <private/media/AudioTrackShared.h>

@@ -37,6 +38,10 @@ struct FastCaptureState : FastThreadState {
    size_t          mFrameCount;        // number of frames per fast capture buffer
    audio_track_cblk_t* mCblk;          // control block for the single fast client, or NULL

    audio_format_t  mFastPatchRecordFormat = AUDIO_FORMAT_INVALID;
    AudioBufferProvider* mFastPatchRecordBufferProvider = nullptr;   // a reference to a patch
                                                                     // record in fast mode

    // Extends FastThreadState::Command
    static const Command
        // The following commands also process configuration changes, and can be "or"ed:
+21 −5
Original line number Diff line number Diff line
@@ -431,14 +431,14 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
    // use a pseudo LCM between input and output framecount
    size_t playbackFrameCount = mPlayback.thread()->frameCount();
    int playbackShift = __builtin_ctz(playbackFrameCount);
    size_t recordFramecount = mRecord.thread()->frameCount();
    int shift = __builtin_ctz(recordFramecount);
    size_t recordFrameCount = mRecord.thread()->frameCount();
    int shift = __builtin_ctz(recordFrameCount);
    if (playbackShift < shift) {
        shift = playbackShift;
    }
    size_t frameCount = (playbackFrameCount * recordFramecount) >> shift;
    ALOGV("%s() playframeCount %zu recordFramecount %zu frameCount %zu",
            __func__, playbackFrameCount, recordFramecount, frameCount);
    size_t frameCount = (playbackFrameCount * recordFrameCount) >> shift;
    ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
            __func__, playbackFrameCount, recordFrameCount, frameCount);

    // create a special record track to capture from record thread
    uint32_t channelCount = mPlayback.thread()->channelCount();
@@ -455,6 +455,17 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
    }
    audio_input_flags_t inputFlags = mAudioPatch.sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
            mAudioPatch.sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
    if (sampleRate == mRecord.thread()->sampleRate() &&
            inChannelMask == mRecord.thread()->channelMask() &&
            mRecord.thread()->fastTrackAvailable() &&
            mRecord.thread()->hasFastCapture()) {
        // Create a fast track if the record thread has fast capture to get better performance.
        // Only enable fast mode when there is no resample needed.
        inputFlags = (audio_input_flags_t) (inputFlags | AUDIO_INPUT_FLAG_FAST);
    } else {
        // Fast mode is not available in this case.
        inputFlags = (audio_input_flags_t) (inputFlags & ~AUDIO_INPUT_FLAG_FAST);
    }
    sp<RecordThread::PatchRecord> tempRecordTrack = new (std::nothrow) RecordThread::PatchRecord(
                                             mRecord.thread().get(),
                                             sampleRate,
@@ -476,6 +487,11 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
        // "reuse one existing output mix" case
        streamType = mAudioPatch.sources[1].ext.mix.usecase.stream;
    }
    if (mPlayback.thread()->hasFastMixer()) {
        // Create a fast track if the playback thread has fast mixer to get better performance.
        outputFlags = (audio_output_flags_t) (outputFlags | AUDIO_OUTPUT_FLAG_FAST);
    }

    // create a special playback track to render to playback thread.
    // this track is given the same buffer as the PatchRecord buffer
    sp<PlaybackThread::PatchTrack> tempPatchTrack = new (std::nothrow) PlaybackThread::PatchTrack(
+8 −0
Original line number Diff line number Diff line
@@ -6700,6 +6700,14 @@ reacquire_wakelock:
                }
                didModify = true;
            }
            AudioBufferProvider* abp = (fastTrack != 0 && fastTrack->isPatchTrack()) ?
                    reinterpret_cast<AudioBufferProvider*>(fastTrack.get()) : nullptr;
            if (state->mFastPatchRecordBufferProvider != abp) {
                state->mFastPatchRecordBufferProvider = abp;
                state->mFastPatchRecordFormat = fastTrack == 0 ?
                        AUDIO_FORMAT_INVALID : fastTrack->format();
                didModify = true;
            }
            sq->end(didModify);
            if (didModify) {
                sq->push(block);
+2 −0
Original line number Diff line number Diff line
@@ -1530,6 +1530,8 @@ public:

            void        updateMetadata_l() override;

            bool        fastTrackAvailable() const { return mFastTrackAvail; }

private:
            // Enter standby if not already in standby, and set mStandby flag
            void    standbyIfNotAlreadyInStandby();