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
Merged-In: Ia78156d1e190bb49a67988567df066c1ab90f9bd
Change-Id: Ia78156d1e190bb49a67988567df066c1ab90f9bd
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 3860bbd..b420199 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -769,7 +769,9 @@
mEngine->setEnabled(false);
mEngine.clear();
mPoseController.reset();
+ AudioSystem::removeSupportedLatencyModesCallback(this);
}
+
// create FX instance on output
AttributionSourceState attributionSource = AttributionSourceState();
mEngine = new AudioEffect(attributionSource);
@@ -785,6 +787,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) {
@@ -815,6 +824,7 @@
// remove FX instance
mEngine->setEnabled(false);
mEngine.clear();
+ AudioSystem::removeSupportedLatencyModesCallback(this);
output = mOutput;
mOutput = AUDIO_IO_HANDLE_NONE;
mPoseController.reset();
@@ -827,6 +837,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) {
@@ -838,17 +857,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() {