Loading services/audioflinger/Threads.cpp +114 −65 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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 Loading Loading @@ -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 { Loading Loading @@ -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, Loading Loading @@ -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) { Loading @@ -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. Loading Loading @@ -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; Loading Loading @@ -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 // ---------------------------------------------------------------------------- Loading services/audioflinger/Threads.h +35 −25 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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) { } Loading Loading @@ -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(); Loading Loading @@ -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, Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -1564,6 +1587,10 @@ protected: mFastMixer->setMasterBalance(balance); } } void updateHalSupportedLatencyModes_l(); void onHalLatencyModesChanged_l() override; void setHalLatencyMode_l() override; }; class DirectOutputThread : public PlaybackThread { Loading Loading @@ -1767,8 +1794,7 @@ public: } }; class SpatializerThread : public MixerThread, public StreamOutHalInterfaceLatencyModeCallback { class SpatializerThread : public MixerThread { public: SpatializerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, Loading @@ -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; Loading Loading
services/audioflinger/Threads.cpp +114 −65 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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 Loading Loading @@ -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 { Loading Loading @@ -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, Loading Loading @@ -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) { Loading @@ -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. Loading Loading @@ -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; Loading Loading @@ -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 // ---------------------------------------------------------------------------- Loading
services/audioflinger/Threads.h +35 −25 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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) { } Loading Loading @@ -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(); Loading Loading @@ -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, Loading @@ -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, Loading Loading @@ -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 Loading Loading @@ -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); Loading @@ -1564,6 +1587,10 @@ protected: mFastMixer->setMasterBalance(balance); } } void updateHalSupportedLatencyModes_l(); void onHalLatencyModesChanged_l() override; void setHalLatencyMode_l() override; }; class DirectOutputThread : public PlaybackThread { Loading Loading @@ -1767,8 +1794,7 @@ public: } }; class SpatializerThread : public MixerThread, public StreamOutHalInterfaceLatencyModeCallback { class SpatializerThread : public MixerThread { public: SpatializerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, Loading @@ -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; Loading