spatializer: disable head tracker sensor when not neeeded
Only enabled the head tracker sensor when the following conditions
are met:
- Spatialization is enabled
- Head tracking desired mode is not static
- A valid head tracking sensor is set
- At least one audio track is active on the spatializer mixer
Bug: 218273231
Test: manual test with uhid-sample sensor simulator
Change-Id: Ie3acd27f4387a9192f907d99a6798a1d8224df12
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 4da4ea0..04d023e 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -485,6 +485,7 @@
status_t status = mAudioPolicyManager->startOutput(portId);
if (status == NO_ERROR) {
client->active = true;
+ onUpdateActiveSpatializerTracks_l();
}
return binderStatusFromStatusT(status);
}
@@ -522,6 +523,7 @@
status_t status = mAudioPolicyManager->stopOutput(portId);
if (status == NO_ERROR) {
client->active = false;
+ onUpdateActiveSpatializerTracks_l();
}
return status;
}
@@ -552,8 +554,10 @@
client->io, client->stream, client->session);
}
Mutex::Autolock _l(mLock);
+ if (client != nullptr && client->active) {
+ onUpdateActiveSpatializerTracks_l();
+ }
mAudioPlaybackClients.removeItem(portId);
-
// called from internal thread: no need to clear caller identity
mAudioPolicyManager->releaseOutput(portId);
}
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 61e2af6..443b9f7 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -397,6 +397,7 @@
if (status == NO_ERROR && currentOutput == newOutput) {
return;
}
+ size_t numActiveTracks = countActiveClientsOnOutput_l(newOutput);
mLock.unlock();
// It is OK to call detachOutput() is none is already attached.
mSpatializer->detachOutput();
@@ -404,7 +405,7 @@
mLock.lock();
return;
}
- status = mSpatializer->attachOutput(newOutput);
+ status = mSpatializer->attachOutput(newOutput, numActiveTracks);
mLock.lock();
if (status != NO_ERROR) {
mAudioPolicyManager->releaseSpatializerOutput(newOutput);
@@ -421,6 +422,34 @@
}
}
+size_t AudioPolicyService::countActiveClientsOnOutput_l(audio_io_handle_t output) REQUIRES(mLock) {
+ size_t count = 0;
+ for (size_t i = 0; i < mAudioPlaybackClients.size(); i++) {
+ auto client = mAudioPlaybackClients.valueAt(i);
+ if (client->io == output && client->active) {
+ count++;
+ }
+ }
+ return count;
+}
+
+void AudioPolicyService::onUpdateActiveSpatializerTracks_l() {
+ if (mSpatializer == nullptr) {
+ return;
+ }
+ mOutputCommandThread->updateActiveSpatializerTracksCommand();
+}
+
+void AudioPolicyService::doOnUpdateActiveSpatializerTracks()
+{
+ Mutex::Autolock _l(mLock);
+ if (mSpatializer == nullptr) {
+ return;
+ }
+ mSpatializer->updateActiveTracks(countActiveClientsOnOutput_l(mSpatializer->getOutput()));
+}
+
+
status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
audio_patch_handle_t *handle,
int delayMs)
@@ -1936,8 +1965,8 @@
mLock.lock();
} break;
- case CHECK_SPATIALIZER: {
- ALOGV("AudioCommandThread() processing updateUID states");
+ case CHECK_SPATIALIZER_OUTPUT: {
+ ALOGV("AudioCommandThread() processing check spatializer");
svc = mService.promote();
if (svc == 0) {
break;
@@ -1947,6 +1976,17 @@
mLock.lock();
} break;
+ case UPDATE_ACTIVE_SPATIALIZER_TRACKS: {
+ ALOGV("AudioCommandThread() processing update spatializer tracks");
+ svc = mService.promote();
+ if (svc == 0) {
+ break;
+ }
+ mLock.unlock();
+ svc->doOnUpdateActiveSpatializerTracks();
+ mLock.lock();
+ } break;
+
default:
ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
}
@@ -2261,11 +2301,19 @@
void AudioPolicyService::AudioCommandThread::checkSpatializerCommand()
{
sp<AudioCommand>command = new AudioCommand();
- command->mCommand = CHECK_SPATIALIZER;
+ command->mCommand = CHECK_SPATIALIZER_OUTPUT;
ALOGV("AudioCommandThread() adding check spatializer");
sendCommand(command);
}
+void AudioPolicyService::AudioCommandThread::updateActiveSpatializerTracksCommand()
+{
+ sp<AudioCommand>command = new AudioCommand();
+ command->mCommand = UPDATE_ACTIVE_SPATIALIZER_TRACKS;
+ ALOGV("AudioCommandThread() adding update active spatializer tracks");
+ sendCommand(command);
+}
+
status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
{
{
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 4944497..d3e0453 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -352,9 +352,13 @@
* by audio policy manager and attach/detach the spatializer effect accordingly.
*/
void onCheckSpatializer() override;
- void onCheckSpatializer_l();
+ void onCheckSpatializer_l() REQUIRES(mLock);
void doOnCheckSpatializer();
+ void onUpdateActiveSpatializerTracks_l() REQUIRES(mLock);
+ void doOnUpdateActiveSpatializerTracks();
+
+
void setEffectSuspended(int effectId,
audio_session_t sessionId,
bool suspended);
@@ -526,7 +530,8 @@
AUDIO_MODULES_UPDATE,
ROUTING_UPDATED,
UPDATE_UID_STATES,
- CHECK_SPATIALIZER
+ CHECK_SPATIALIZER_OUTPUT, // verify if spatializer effect should be created or moved
+ UPDATE_ACTIVE_SPATIALIZER_TRACKS // Update active track counts on spalializer output
};
AudioCommandThread (String8 name, const wp<AudioPolicyService>& service);
@@ -576,6 +581,8 @@
void routingChangedCommand();
void updateUidStatesCommand();
void checkSpatializerCommand();
+ void updateActiveSpatializerTracksCommand();
+
void insertCommand_l(AudioCommand *command, int delayMs = 0);
private:
class AudioCommandData;
@@ -1000,6 +1007,8 @@
void loadAudioPolicyManager();
void unloadAudioPolicyManager();
+ size_t countActiveClientsOnOutput_l(audio_io_handle_t output) REQUIRES(mLock);
+
mutable Mutex mLock; // prevents concurrent access to AudioPolicy manager functions changing
// device connection state or routing
// Note: lock acquisition order is always mLock > mEffectsLock:
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 54d9094..d9e89aa 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -300,6 +300,7 @@
if (levelChanged && mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_LEVEL, std::vector<SpatializationLevel>{level});
}
+ checkHeadSensor_l();
}
if (levelChanged) {
@@ -374,6 +375,7 @@
if (mPoseController != nullptr) {
mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
+ checkHeadSensor_l();
}
return Status::ok();
@@ -448,7 +450,7 @@
std::lock_guard lock(mLock);
mHeadSensor = sensorHandle;
if (mPoseController != nullptr) {
- mPoseController->setHeadSensor(mHeadSensor);
+ checkHeadSensor_l();
}
return Status::ok();
}
@@ -557,7 +559,6 @@
auto vec = headToStage.toVector();
LOG_ALWAYS_FATAL_IF(vec.size() != sHeadPoseKeys.size(),
"%s invalid head to stage vector size %zu", __func__, vec.size());
-
sp<AMessage> msg =
new AMessage(EngineCallbackHandler::kWhatOnHeadToStagePose, mHandler);
for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) {
@@ -571,6 +572,9 @@
sp<media::ISpatializerHeadTrackingCallback> callback;
{
std::lock_guard lock(mLock);
+ if (mActualHeadTrackingMode == SpatializerHeadTrackingMode::DISABLED) {
+ return;
+ }
callback = mHeadTrackingCallback;
if (mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
@@ -621,7 +625,7 @@
}
}
-status_t Spatializer::attachOutput(audio_io_handle_t output) {
+status_t Spatializer::attachOutput(audio_io_handle_t output, size_t numActiveTracks) {
std::shared_ptr<SpatializerPoseController> poseController;
bool outputChanged = false;
sp<media::INativeSpatializerCallback> callback;
@@ -634,6 +638,7 @@
// remove FX instance
mEngine->setEnabled(false);
mEngine.clear();
+ mPoseController.reset();
}
// create FX instance on output
AttributionSourceState attributionSource = AttributionSourceState();
@@ -663,7 +668,8 @@
"%s could not allocate pose controller", __func__);
mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
- mPoseController->setHeadSensor(mHeadSensor);
+ mNumActiveTracks = numActiveTracks;
+ checkHeadSensor_l();
mPoseController->setScreenSensor(mScreenSensor);
mPoseController->setDisplayOrientation(mDisplayOrientation);
poseController = mPoseController;
@@ -697,7 +703,6 @@
output = mOutput;
mOutput = AUDIO_IO_HANDLE_NONE;
mPoseController.reset();
-
callback = mSpatializerCallback;
}
@@ -707,6 +712,24 @@
return output;
}
+void Spatializer::updateActiveTracks(size_t numActiveTracks) {
+ std::lock_guard lock(mLock);
+ mNumActiveTracks = numActiveTracks;
+ checkHeadSensor_l();
+}
+
+void Spatializer::checkHeadSensor_l() {
+ if (mSupportsHeadTracking && mPoseController != nullptr) {
+ if(mNumActiveTracks > 0 && mLevel != SpatializationLevel::NONE
+ && mDesiredHeadTrackingMode != HeadTrackingMode::STATIC
+ && mHeadSensor != SpatializerPoseController::INVALID_SENSOR) {
+ mPoseController->setHeadSensor(mHeadSensor);
+ } else {
+ mPoseController->setHeadSensor(SpatializerPoseController::INVALID_SENSOR);
+ }
+ }
+}
+
void Spatializer::calculateHeadPose() {
ALOGV("%s", __func__);
std::lock_guard lock(mLock);
diff --git a/services/audiopolicy/service/Spatializer.h b/services/audiopolicy/service/Spatializer.h
index 4d77b78..4ce99d8 100644
--- a/services/audiopolicy/service/Spatializer.h
+++ b/services/audiopolicy/service/Spatializer.h
@@ -135,7 +135,7 @@
/** Called by audio policy service when the special output mixer dedicated to spatialization
* is opened and the spatializer engine must be created.
*/
- status_t attachOutput(audio_io_handle_t output);
+ status_t attachOutput(audio_io_handle_t output, size_t numActiveTracks);
/** Called by audio policy service when the special output mixer dedicated to spatialization
* is closed and the spatializer engine must be release.
*/
@@ -143,6 +143,8 @@
/** Returns the output stream the spatializer is attached to. */
audio_io_handle_t getOutput() const { std::lock_guard lock(mLock); return mOutput; }
+ void updateActiveTracks(size_t numActiveTracks);
+
/** Gets the channel mask, sampling rate and format set for the spatializer input. */
audio_config_base_t getAudioInConfig() const;
@@ -274,6 +276,8 @@
void postFramesProcessedMsg(int frames);
+ void checkHeadSensor_l() REQUIRES(mLock);
+
/** Effect engine descriptor */
const effect_descriptor_t mEngineDescriptor;
/** Callback interface to parent audio policy service */
@@ -328,6 +332,8 @@
sp<ALooper> mLooper;
sp<EngineCallbackHandler> mHandler;
+ size_t mNumActiveTracks GUARDED_BY(mLock) = 0;
+
static const std::vector<const char *> sHeadPoseKeys;
};