Merge "audioflinger: implement Bluetooth latency mode control"
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 3dcf932..1770b4e 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2089,8 +2089,7 @@
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 @@
} else {
status = PlaybackThread::createAudioPatch_l(patch, handle);
}
+
+ updateHalSupportedLatencyModes_l();
return status;
}
@@ -4844,6 +4845,7 @@
: PlaybackThread(audioFlinger, output, id, type, systemReady, mixerConfig),
// mAudioMixer below
// mFastMixer below
+ mBluetoothLatencyModesEnabled(false),
mFastMixerFutex(0),
mMasterMono(false)
// mOutputSink below
@@ -5059,6 +5061,21 @@
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 @@
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 @@
}
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 @@
}
}
-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 @@
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::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
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 1f0f13a..4ab4557 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -376,8 +376,6 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
mFastMixer->setMasterBalance(balance);
}
}
+
+ void updateHalSupportedLatencyModes_l();
+ void onHalLatencyModesChanged_l() override;
+ void setHalLatencyMode_l() override;
};
class DirectOutputThread : public PlaybackThread {
@@ -1767,8 +1794,7 @@
}
};
-class SpatializerThread : public MixerThread,
- public StreamOutHalInterfaceLatencyModeCallback {
+class SpatializerThread : public MixerThread {
public:
SpatializerThread(const sp<AudioFlinger>& audioFlinger,
AudioStreamOut* output,
@@ -1779,32 +1805,16 @@
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;