Spatializer: control audio HAL latency mode
Add support of HAL stream latency mode control to Spatializer
effect controller.
- Query supported latency modes when attached to a new output stream
and register a callback to be notified of changes
- Only use a head tracker sensor if the HAL stream supports low
latency or does not support latency mode control.
- Set the requested latency mode according to head tracking state.
Bug: 218273231
Test: make
Change-Id: Ia78156d1e190bb49a67988567df066c1ab90f9bd
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index c199a76..e8b599a 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -714,7 +714,9 @@
mEngine->setEnabled(false);
mEngine.clear();
mPoseController.reset();
+ AudioSystem::removeSupportedLatencyModesCallback(this);
}
+
// create FX instance on output
AttributionSourceState attributionSource = AttributionSourceState();
mEngine = new AudioEffect(attributionSource);
@@ -730,6 +732,13 @@
outputChanged = mOutput != output;
mOutput = output;
mNumActiveTracks = numActiveTracks;
+ AudioSystem::addSupportedLatencyModesCallback(this);
+
+ std::vector<audio_latency_mode_t> latencyModes;
+ status = AudioSystem::getSupportedLatencyModes(mOutput, &latencyModes);
+ if (status == OK) {
+ mSupportedLatencyModes = latencyModes;
+ }
checkEngineState_l();
if (mSupportsHeadTracking) {
@@ -759,6 +768,7 @@
// remove FX instance
mEngine->setEnabled(false);
mEngine.clear();
+ AudioSystem::removeSupportedLatencyModesCallback(this);
output = mOutput;
mOutput = AUDIO_IO_HANDLE_NONE;
mPoseController.reset();
@@ -771,6 +781,15 @@
return output;
}
+void Spatializer::onSupportedLatencyModesChanged(
+ audio_io_handle_t output, const std::vector<audio_latency_mode_t>& modes) {
+ std::lock_guard lock(mLock);
+ if (output == mOutput) {
+ mSupportedLatencyModes = modes;
+ checkSensorsState_l();
+ }
+}
+
void Spatializer::updateActiveTracks(size_t numActiveTracks) {
std::lock_guard lock(mLock);
if (mNumActiveTracks != numActiveTracks) {
@@ -781,17 +800,25 @@
}
void Spatializer::checkSensorsState_l() {
- if (mSupportsHeadTracking && mPoseController != nullptr) {
+ audio_latency_mode_t requestedLatencyMode = AUDIO_LATENCY_MODE_FREE;
+ bool lowLatencySupported = mSupportedLatencyModes.empty()
+ || (std::find(mSupportedLatencyModes.begin(), mSupportedLatencyModes.end(),
+ AUDIO_LATENCY_MODE_LOW) != mSupportedLatencyModes.end());
+ if (mSupportsHeadTracking && mPoseController != nullptr && lowLatencySupported) {
if (mNumActiveTracks > 0 && mLevel != SpatializationLevel::NONE
&& mDesiredHeadTrackingMode != HeadTrackingMode::STATIC
&& mHeadSensor != SpatializerPoseController::INVALID_SENSOR) {
mPoseController->setHeadSensor(mHeadSensor);
mPoseController->setScreenSensor(mScreenSensor);
+ requestedLatencyMode = AUDIO_LATENCY_MODE_LOW;
} else {
mPoseController->setHeadSensor(SpatializerPoseController::INVALID_SENSOR);
mPoseController->setScreenSensor(SpatializerPoseController::INVALID_SENSOR);
}
}
+ if (mOutput != AUDIO_IO_HANDLE_NONE) {
+ AudioSystem::setRequestedLatencyMode(mOutput, requestedLatencyMode);
+ }
}
void Spatializer::checkEngineState_l() {