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

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

Merge "audioflinger: implement Bluetooth latency mode control"

parents 31f20f55 b046394f
Loading
Loading
Loading
Loading
+114 −65
Original line number Diff line number Diff line
@@ -2089,8 +2089,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
        mHwSupportsPause(false), mHwPaused(false), mFlushPending(false),
        mLeftVolFloat(-1.0), mRightVolFloat(-1.0),
        mDownStreamPatch{},
        mIsTimestampAdvancing(kMinimumTimeBetweenTimestampChecksNs),
        mBluetoothLatencyModesEnabled(true)
        mIsTimestampAdvancing(kMinimumTimeBetweenTimestampChecksNs)
{
    snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
    mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
@@ -4693,6 +4692,8 @@ status_t AudioFlinger::MixerThread::createAudioPatch_l(const struct audio_patch
    } else {
        status = PlaybackThread::createAudioPatch_l(patch, handle);
    }

    updateHalSupportedLatencyModes_l();
    return status;
}

@@ -4844,6 +4845,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
    :   PlaybackThread(audioFlinger, output, id, type, systemReady, mixerConfig),
        // mAudioMixer below
        // mFastMixer below
        mBluetoothLatencyModesEnabled(false),
        mFastMixerFutex(0),
        mMasterMono(false)
        // mOutputSink below
@@ -5059,6 +5061,21 @@ AudioFlinger::MixerThread::~MixerThread()
    delete mAudioMixer;
}

void AudioFlinger::MixerThread::onFirstRef() {
    PlaybackThread::onFirstRef();

    Mutex::Autolock _l(mLock);
    if (mOutput != nullptr && mOutput->stream != nullptr) {
        status_t status = mOutput->stream->setLatencyModeCallback(this);
        if (status != INVALID_OPERATION) {
            updateHalSupportedLatencyModes_l();
        }
        // Default to enabled if the HAL supports it. This can be changed by Audioflinger after
        // the thread construction according to AudioFlinger::mBluetoothLatencyModesEnabled
        mBluetoothLatencyModesEnabled.store(
                mOutput->audioHwDev->supportsBluetoothVariableLatency());
    }
}

uint32_t AudioFlinger::MixerThread::correctLatency_l(uint32_t latency) const
{
@@ -6268,6 +6285,100 @@ void AudioFlinger::MixerThread::cacheParameters_l()
    maxPeriod = seconds(mNormalFrameCount) / mSampleRate * 15;
}

void AudioFlinger::MixerThread::onHalLatencyModesChanged_l() {
    mAudioFlinger->onSupportedLatencyModesChanged(mId, mSupportedLatencyModes);
}

void AudioFlinger::MixerThread::setHalLatencyMode_l() {
    // Only handle latency mode if:
    // - mBluetoothLatencyModesEnabled is true
    // - the HAL supports latency modes
    // - the selected device is Bluetooth LE or A2DP
    if (!mBluetoothLatencyModesEnabled.load() || mSupportedLatencyModes.empty()) {
        return;
    }
    if (mOutDeviceTypeAddrs.size() != 1
            || !(audio_is_a2dp_out_device(mOutDeviceTypeAddrs[0].mType)
                 || audio_is_ble_out_device(mOutDeviceTypeAddrs[0].mType))) {
        return;
    }

    audio_latency_mode_t latencyMode = AUDIO_LATENCY_MODE_FREE;
    if (mSupportedLatencyModes.size() == 1) {
        // If the HAL only support one latency mode currently, confirm the choice
        latencyMode = mSupportedLatencyModes[0];
    } else if (mSupportedLatencyModes.size() > 1) {
        // Request low latency if:
        // - At least one active track is either:
        //   - a fast track with gaming usage or
        //   - a track with acessibility usage
        for (const auto& track : mActiveTracks) {
            if ((track->isFastTrack() && track->attributes().usage == AUDIO_USAGE_GAME)
                    || track->attributes().usage == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY) {
                latencyMode = AUDIO_LATENCY_MODE_LOW;
                break;
            }
        }
    }

    if (latencyMode != mSetLatencyMode) {
        status_t status = mOutput->stream->setLatencyMode(latencyMode);
        ALOGD("%s: thread(%d) setLatencyMode(%s) returned %d",
                __func__, mId, toString(latencyMode).c_str(), status);
        if (status == NO_ERROR) {
            mSetLatencyMode = latencyMode;
        }
    }
}

void AudioFlinger::MixerThread::updateHalSupportedLatencyModes_l() {

    if (mOutput == nullptr || mOutput->stream == nullptr) {
        return;
    }
    std::vector<audio_latency_mode_t> latencyModes;
    const status_t status = mOutput->stream->getRecommendedLatencyModes(&latencyModes);
    if (status != NO_ERROR) {
        latencyModes.clear();
    }
    if (latencyModes != mSupportedLatencyModes) {
        ALOGD("%s: thread(%d) status %d supported latency modes: %s",
            __func__, mId, status, toString(latencyModes).c_str());
        mSupportedLatencyModes.swap(latencyModes);
        sendHalLatencyModesChangedEvent_l();
    }
}

status_t AudioFlinger::MixerThread::getSupportedLatencyModes(
        std::vector<audio_latency_mode_t>* modes) {
    if (modes == nullptr) {
        return BAD_VALUE;
    }
    Mutex::Autolock _l(mLock);
    *modes = mSupportedLatencyModes;
    return NO_ERROR;
}

void AudioFlinger::MixerThread::onRecommendedLatencyModeChanged(
        std::vector<audio_latency_mode_t> modes) {
    Mutex::Autolock _l(mLock);
    if (modes != mSupportedLatencyModes) {
        ALOGD("%s: thread(%d) supported latency modes: %s",
            __func__, mId, toString(modes).c_str());
        mSupportedLatencyModes.swap(modes);
        sendHalLatencyModesChangedEvent_l();
    }
}

status_t AudioFlinger::MixerThread::setBluetoothVariableLatencyEnabled(bool enabled) {
    if (mOutput == nullptr || mOutput->audioHwDev == nullptr
            || !mOutput->audioHwDev->supportsBluetoothVariableLatency()) {
        return INVALID_OPERATION;
    }
    mBluetoothLatencyModesEnabled.store(enabled);
    return NO_ERROR;
}

// ----------------------------------------------------------------------------

AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
@@ -7499,13 +7610,7 @@ AudioFlinger::SpatializerThread::SpatializerThread(const sp<AudioFlinger>& audio
}

void AudioFlinger::SpatializerThread::onFirstRef() {
    PlaybackThread::onFirstRef();

    Mutex::Autolock _l(mLock);
    status_t status = mOutput->stream->setLatencyModeCallback(this);
    if (status != INVALID_OPERATION) {
        updateHalSupportedLatencyModes_l();
    }
    MixerThread::onFirstRef();

    const pid_t tid = getTid();
    if (tid == -1) {
@@ -7519,32 +7624,6 @@ void AudioFlinger::SpatializerThread::onFirstRef() {
    }
}

status_t AudioFlinger::SpatializerThread::createAudioPatch_l(const struct audio_patch *patch,
                                                          audio_patch_handle_t *handle)
{
    status_t status = MixerThread::createAudioPatch_l(patch, handle);
    updateHalSupportedLatencyModes_l();
    return status;
}

void AudioFlinger::SpatializerThread::updateHalSupportedLatencyModes_l() {
    std::vector<audio_latency_mode_t> latencyModes;
    const status_t status = mOutput->stream->getRecommendedLatencyModes(&latencyModes);
    if (status != NO_ERROR) {
        latencyModes.clear();
    }
    if (latencyModes != mSupportedLatencyModes) {
        ALOGD("%s: thread(%d) status %d supported latency modes: %s",
            __func__, mId, status, toString(latencyModes).c_str());
        mSupportedLatencyModes.swap(latencyModes);
        sendHalLatencyModesChangedEvent_l();
    }
}

void AudioFlinger::SpatializerThread::onHalLatencyModesChanged_l() {
    mAudioFlinger->onSupportedLatencyModesChanged(mId, mSupportedLatencyModes);
}

void AudioFlinger::SpatializerThread::setHalLatencyMode_l() {
    // if mSupportedLatencyModes is empty, the HAL stream does not support
    // latency mode control and we can exit.
@@ -7592,25 +7671,6 @@ status_t AudioFlinger::SpatializerThread::setRequestedLatencyMode(audio_latency_
    return NO_ERROR;
}

status_t AudioFlinger::SpatializerThread::getSupportedLatencyModes(
        std::vector<audio_latency_mode_t>* modes) {
    if (modes == nullptr) {
        return BAD_VALUE;
    }
    Mutex::Autolock _l(mLock);
    *modes = mSupportedLatencyModes;
    return NO_ERROR;
}

status_t AudioFlinger::PlaybackThread::setBluetoothVariableLatencyEnabled(bool enabled) {
    if (mOutput == nullptr || mOutput->audioHwDev == nullptr
            || !mOutput->audioHwDev->supportsBluetoothVariableLatency()) {
        return INVALID_OPERATION;
    }
    mBluetoothLatencyModesEnabled.store(enabled);
    return NO_ERROR;
}

void AudioFlinger::SpatializerThread::checkOutputStageEffects()
{
    bool hasVirtualizer = false;
@@ -7663,17 +7723,6 @@ void AudioFlinger::SpatializerThread::checkOutputStageEffects()
    }
}

void AudioFlinger::SpatializerThread::onRecommendedLatencyModeChanged(
        std::vector<audio_latency_mode_t> modes) {
    Mutex::Autolock _l(mLock);
    if (modes != mSupportedLatencyModes) {
        ALOGD("%s: thread(%d) supported latency modes: %s",
            __func__, mId, toString(modes).c_str());
        mSupportedLatencyModes.swap(modes);
        sendHalLatencyModesChangedEvent_l();
    }
}

// ----------------------------------------------------------------------------
//      Record
// ----------------------------------------------------------------------------
+35 −25
Original line number Diff line number Diff line
@@ -376,8 +376,6 @@ public:
    virtual     void        toAudioPortConfig(struct audio_port_config *config) = 0;

    virtual     void        resizeInputBuffer_l(int32_t maxSharedAudioHistoryMs);
    virtual     void        onHalLatencyModesChanged_l() {}


                // see note at declaration of mStandby, mOutDevice and mInDevice
                bool        standby() const { return mStandby; }
@@ -625,6 +623,8 @@ protected:

                product_strategy_t getStrategyForStream(audio_stream_type_t stream) const;

    virtual     void        onHalLatencyModesChanged_l() {}

    virtual     void        dumpInternals_l(int fd __unused, const Vector<String16>& args __unused)
                            { }
    virtual     void        dumpTracks_l(int fd __unused, const Vector<String16>& args __unused) { }
@@ -1102,7 +1102,9 @@ public:
                    return INVALID_OPERATION;
                }

    virtual     status_t setBluetoothVariableLatencyEnabled(bool enabled);
    virtual     status_t setBluetoothVariableLatencyEnabled(bool enabled __unused) {
                    return INVALID_OPERATION;
                }

                void startMelComputation(const sp<audio_utils::MelProcessor>& processor);
                void stopMelComputation();
@@ -1462,12 +1464,10 @@ protected:
    virtual     void flushHw_l() {
                    mIsTimestampAdvancing.clear();
                }

        // Bluetooth Variable latency control logic is enabled or disabled for this thread
        std::atomic_bool mBluetoothLatencyModesEnabled;
};

class MixerThread : public PlaybackThread {
class MixerThread : public PlaybackThread,
                    public StreamOutHalInterfaceLatencyModeCallback  {
public:
    MixerThread(const sp<AudioFlinger>& audioFlinger,
                AudioStreamOut* output,
@@ -1477,6 +1477,13 @@ public:
                audio_config_base_t *mixerConfig = nullptr);
    virtual             ~MixerThread();

    // RefBase
    virtual     void        onFirstRef();

                // StreamOutHalInterfaceLatencyModeCallback
                void        onRecommendedLatencyModeChanged(
                                    std::vector<audio_latency_mode_t> modes) override;

    // Thread virtuals

    virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
@@ -1513,6 +1520,17 @@ protected:
    virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);

                AudioMixer* mAudioMixer;    // normal mixer

            // Support low latency mode by default as unless explicitly indicated by the audio HAL
            // we assume the audio path is compatible with the head tracking latency requirements
            std::vector<audio_latency_mode_t> mSupportedLatencyModes = {AUDIO_LATENCY_MODE_LOW};
            // default to invalid value to force first update to the audio HAL
            audio_latency_mode_t mSetLatencyMode =
                    (audio_latency_mode_t)AUDIO_LATENCY_MODE_INVALID;

            // Bluetooth Variable latency control logic is enabled or disabled for this thread
            std::atomic_bool mBluetoothLatencyModesEnabled;

private:
                // one-time initialization, no locks required
                sp<FastMixer>     mFastMixer;     // non-0 if there is also a fast mixer
@@ -1546,6 +1564,11 @@ public:
                                return INVALID_OPERATION;
                            }

                status_t    getSupportedLatencyModes(
                                    std::vector<audio_latency_mode_t>* modes) override;

                status_t    setBluetoothVariableLatencyEnabled(bool enabled) override;

protected:
    virtual     void       setMasterMono_l(bool mono) {
                               mMasterMono.store(mono);
@@ -1564,6 +1587,10 @@ protected:
                                   mFastMixer->setMasterBalance(balance);
                               }
                           }

                void       updateHalSupportedLatencyModes_l();
                void       onHalLatencyModesChanged_l() override;
                void       setHalLatencyMode_l() override;
};

class DirectOutputThread : public PlaybackThread {
@@ -1767,8 +1794,7 @@ public:
    }
};

class SpatializerThread : public MixerThread,
        public StreamOutHalInterfaceLatencyModeCallback {
class SpatializerThread : public MixerThread {
public:
    SpatializerThread(const sp<AudioFlinger>& audioFlinger,
                           AudioStreamOut* output,
@@ -1779,32 +1805,16 @@ public:

            bool hasFastMixer() const override { return false; }

            status_t    createAudioPatch_l(const struct audio_patch *patch,
                                   audio_patch_handle_t *handle) override;

            // RefBase
            virtual void        onFirstRef();

            // StreamOutHalInterfaceLatencyModeCallback
            void onRecommendedLatencyModeChanged(std::vector<audio_latency_mode_t> modes) override;

            status_t setRequestedLatencyMode(audio_latency_mode_t mode) override;
            status_t getSupportedLatencyModes(std::vector<audio_latency_mode_t>* modes) override;

protected:
            void checkOutputStageEffects() override;
            void onHalLatencyModesChanged_l() override;
            void setHalLatencyMode_l() override;

private:
            void updateHalSupportedLatencyModes_l();

            // Support low latency mode by default as unless explicitly indicated by the audio HAL
            // we assume the audio path is compatible with the head tracking latency requirements
            std::vector<audio_latency_mode_t> mSupportedLatencyModes = {AUDIO_LATENCY_MODE_LOW};
            // default to invalid value to force first update to the audio HAL
            audio_latency_mode_t mSetLatencyMode =
                    (audio_latency_mode_t)AUDIO_LATENCY_MODE_INVALID;
            // Do not request a specific mode by default
            audio_latency_mode_t mRequestedLatencyMode = AUDIO_LATENCY_MODE_FREE;