Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1590359d authored by Eric Laurent's avatar Eric Laurent
Browse files

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
parent 07b6cbda
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -485,6 +485,7 @@ Status AudioPolicyService::startOutput(int32_t portIdAidl)
    status_t status = mAudioPolicyManager->startOutput(portId);
    status_t status = mAudioPolicyManager->startOutput(portId);
    if (status == NO_ERROR) {
    if (status == NO_ERROR) {
        client->active = true;
        client->active = true;
        onUpdateActiveSpatializerTracks_l();
    }
    }
    return binderStatusFromStatusT(status);
    return binderStatusFromStatusT(status);
}
}
@@ -522,6 +523,7 @@ status_t AudioPolicyService::doStopOutput(audio_port_handle_t portId)
    status_t status = mAudioPolicyManager->stopOutput(portId);
    status_t status = mAudioPolicyManager->stopOutput(portId);
    if (status == NO_ERROR) {
    if (status == NO_ERROR) {
        client->active = false;
        client->active = false;
        onUpdateActiveSpatializerTracks_l();
    }
    }
    return status;
    return status;
}
}
@@ -552,8 +554,10 @@ void AudioPolicyService::doReleaseOutput(audio_port_handle_t portId)
            client->io, client->stream, client->session);
            client->io, client->stream, client->session);
    }
    }
    Mutex::Autolock _l(mLock);
    Mutex::Autolock _l(mLock);
    if (client != nullptr && client->active) {
        onUpdateActiveSpatializerTracks_l();
    }
    mAudioPlaybackClients.removeItem(portId);
    mAudioPlaybackClients.removeItem(portId);

    // called from internal thread: no need to clear caller identity
    // called from internal thread: no need to clear caller identity
    mAudioPolicyManager->releaseOutput(portId);
    mAudioPolicyManager->releaseOutput(portId);
}
}
+52 −4
Original line number Original line Diff line number Diff line
@@ -397,6 +397,7 @@ void AudioPolicyService::doOnCheckSpatializer()
            if (status == NO_ERROR && currentOutput == newOutput) {
            if (status == NO_ERROR && currentOutput == newOutput) {
                return;
                return;
            }
            }
            size_t numActiveTracks = countActiveClientsOnOutput_l(newOutput);
            mLock.unlock();
            mLock.unlock();
            // It is OK to call detachOutput() is none is already attached.
            // It is OK to call detachOutput() is none is already attached.
            mSpatializer->detachOutput();
            mSpatializer->detachOutput();
@@ -404,7 +405,7 @@ void AudioPolicyService::doOnCheckSpatializer()
                mLock.lock();
                mLock.lock();
                return;
                return;
            }
            }
            status = mSpatializer->attachOutput(newOutput);
            status = mSpatializer->attachOutput(newOutput, numActiveTracks);
            mLock.lock();
            mLock.lock();
            if (status != NO_ERROR) {
            if (status != NO_ERROR) {
                mAudioPolicyManager->releaseSpatializerOutput(newOutput);
                mAudioPolicyManager->releaseSpatializerOutput(newOutput);
@@ -421,6 +422,34 @@ void AudioPolicyService::doOnCheckSpatializer()
    }
    }
}
}


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,
status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
                                                audio_patch_handle_t *handle,
                                                audio_patch_handle_t *handle,
                                                int delayMs)
                                                int delayMs)
@@ -1936,8 +1965,8 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
                    mLock.lock();
                    mLock.lock();
                    } break;
                    } break;


                case CHECK_SPATIALIZER: {
                case CHECK_SPATIALIZER_OUTPUT: {
                    ALOGV("AudioCommandThread() processing updateUID states");
                    ALOGV("AudioCommandThread() processing check spatializer");
                    svc = mService.promote();
                    svc = mService.promote();
                    if (svc == 0) {
                    if (svc == 0) {
                        break;
                        break;
@@ -1947,6 +1976,17 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
                    mLock.lock();
                    mLock.lock();
                    } break;
                    } 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:
                default:
                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
                }
                }
@@ -2261,11 +2301,19 @@ void AudioPolicyService::AudioCommandThread::routingChangedCommand()
void AudioPolicyService::AudioCommandThread::checkSpatializerCommand()
void AudioPolicyService::AudioCommandThread::checkSpatializerCommand()
{
{
    sp<AudioCommand>command = new AudioCommand();
    sp<AudioCommand>command = new AudioCommand();
    command->mCommand = CHECK_SPATIALIZER;
    command->mCommand = CHECK_SPATIALIZER_OUTPUT;
    ALOGV("AudioCommandThread() adding check spatializer");
    ALOGV("AudioCommandThread() adding check spatializer");
    sendCommand(command);
    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)
status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
{
{
    {
    {
+11 −2
Original line number Original line Diff line number Diff line
@@ -352,9 +352,13 @@ public:
     * by audio policy manager and attach/detach the spatializer effect accordingly.
     * by audio policy manager and attach/detach the spatializer effect accordingly.
     */
     */
    void onCheckSpatializer() override;
    void onCheckSpatializer() override;
    void onCheckSpatializer_l();
    void onCheckSpatializer_l() REQUIRES(mLock);
    void doOnCheckSpatializer();
    void doOnCheckSpatializer();


    void onUpdateActiveSpatializerTracks_l() REQUIRES(mLock);
    void doOnUpdateActiveSpatializerTracks();


    void setEffectSuspended(int effectId,
    void setEffectSuspended(int effectId,
                            audio_session_t sessionId,
                            audio_session_t sessionId,
                            bool suspended);
                            bool suspended);
@@ -526,7 +530,8 @@ private:
            AUDIO_MODULES_UPDATE,
            AUDIO_MODULES_UPDATE,
            ROUTING_UPDATED,
            ROUTING_UPDATED,
            UPDATE_UID_STATES,
            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);
        AudioCommandThread (String8 name, const wp<AudioPolicyService>& service);
@@ -576,6 +581,8 @@ private:
                    void        routingChangedCommand();
                    void        routingChangedCommand();
                    void        updateUidStatesCommand();
                    void        updateUidStatesCommand();
                    void        checkSpatializerCommand();
                    void        checkSpatializerCommand();
                    void        updateActiveSpatializerTracksCommand();

                    void        insertCommand_l(AudioCommand *command, int delayMs = 0);
                    void        insertCommand_l(AudioCommand *command, int delayMs = 0);
    private:
    private:
        class AudioCommandData;
        class AudioCommandData;
@@ -1000,6 +1007,8 @@ private:
    void loadAudioPolicyManager();
    void loadAudioPolicyManager();
    void unloadAudioPolicyManager();
    void unloadAudioPolicyManager();


    size_t countActiveClientsOnOutput_l(audio_io_handle_t output) REQUIRES(mLock);

    mutable Mutex mLock;    // prevents concurrent access to AudioPolicy manager functions changing
    mutable Mutex mLock;    // prevents concurrent access to AudioPolicy manager functions changing
                            // device connection state  or routing
                            // device connection state  or routing
    // Note: lock acquisition order is always mLock > mEffectsLock:
    // Note: lock acquisition order is always mLock > mEffectsLock:
+28 −5
Original line number Original line Diff line number Diff line
@@ -300,6 +300,7 @@ Status Spatializer::setLevel(SpatializationLevel level) {
        if (levelChanged && mEngine != nullptr) {
        if (levelChanged && mEngine != nullptr) {
            setEffectParameter_l(SPATIALIZER_PARAM_LEVEL, std::vector<SpatializationLevel>{level});
            setEffectParameter_l(SPATIALIZER_PARAM_LEVEL, std::vector<SpatializationLevel>{level});
        }
        }
        checkHeadSensor_l();
    }
    }


    if (levelChanged) {
    if (levelChanged) {
@@ -374,6 +375,7 @@ Status Spatializer::setDesiredHeadTrackingMode(SpatializerHeadTrackingMode mode)


    if (mPoseController != nullptr) {
    if (mPoseController != nullptr) {
        mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
        mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
        checkHeadSensor_l();
    }
    }


    return Status::ok();
    return Status::ok();
@@ -448,7 +450,7 @@ Status Spatializer::setHeadSensor(int sensorHandle) {
    std::lock_guard lock(mLock);
    std::lock_guard lock(mLock);
    mHeadSensor = sensorHandle;
    mHeadSensor = sensorHandle;
    if (mPoseController != nullptr) {
    if (mPoseController != nullptr) {
        mPoseController->setHeadSensor(mHeadSensor);
        checkHeadSensor_l();
    }
    }
    return Status::ok();
    return Status::ok();
}
}
@@ -557,7 +559,6 @@ void Spatializer::onHeadToStagePose(const Pose3f& headToStage) {
    auto vec = headToStage.toVector();
    auto vec = headToStage.toVector();
    LOG_ALWAYS_FATAL_IF(vec.size() != sHeadPoseKeys.size(),
    LOG_ALWAYS_FATAL_IF(vec.size() != sHeadPoseKeys.size(),
            "%s invalid head to stage vector size %zu", __func__, vec.size());
            "%s invalid head to stage vector size %zu", __func__, vec.size());

    sp<AMessage> msg =
    sp<AMessage> msg =
            new AMessage(EngineCallbackHandler::kWhatOnHeadToStagePose, mHandler);
            new AMessage(EngineCallbackHandler::kWhatOnHeadToStagePose, mHandler);
    for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) {
    for (size_t i = 0 ; i < sHeadPoseKeys.size(); i++) {
@@ -571,6 +572,9 @@ void Spatializer::onHeadToStagePoseMsg(const std::vector<float>& headToStage) {
    sp<media::ISpatializerHeadTrackingCallback> callback;
    sp<media::ISpatializerHeadTrackingCallback> callback;
    {
    {
        std::lock_guard lock(mLock);
        std::lock_guard lock(mLock);
        if (mActualHeadTrackingMode == SpatializerHeadTrackingMode::DISABLED) {
            return;
        }
        callback = mHeadTrackingCallback;
        callback = mHeadTrackingCallback;
        if (mEngine != nullptr) {
        if (mEngine != nullptr) {
            setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
            setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
@@ -621,7 +625,7 @@ void Spatializer::onActualModeChangeMsg(HeadTrackingMode mode) {
    }
    }
}
}


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;
    std::shared_ptr<SpatializerPoseController> poseController;
    bool outputChanged = false;
    bool outputChanged = false;
    sp<media::INativeSpatializerCallback> callback;
    sp<media::INativeSpatializerCallback> callback;
@@ -634,6 +638,7 @@ status_t Spatializer::attachOutput(audio_io_handle_t output) {
            // remove FX instance
            // remove FX instance
            mEngine->setEnabled(false);
            mEngine->setEnabled(false);
            mEngine.clear();
            mEngine.clear();
            mPoseController.reset();
        }
        }
        // create FX instance on output
        // create FX instance on output
        AttributionSourceState attributionSource = AttributionSourceState();
        AttributionSourceState attributionSource = AttributionSourceState();
@@ -663,7 +668,8 @@ status_t Spatializer::attachOutput(audio_io_handle_t output) {
                                "%s could not allocate pose controller", __func__);
                                "%s could not allocate pose controller", __func__);


            mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
            mPoseController->setDesiredMode(mDesiredHeadTrackingMode);
            mPoseController->setHeadSensor(mHeadSensor);
            mNumActiveTracks = numActiveTracks;
            checkHeadSensor_l();
            mPoseController->setScreenSensor(mScreenSensor);
            mPoseController->setScreenSensor(mScreenSensor);
            mPoseController->setDisplayOrientation(mDisplayOrientation);
            mPoseController->setDisplayOrientation(mDisplayOrientation);
            poseController = mPoseController;
            poseController = mPoseController;
@@ -697,7 +703,6 @@ audio_io_handle_t Spatializer::detachOutput() {
        output = mOutput;
        output = mOutput;
        mOutput = AUDIO_IO_HANDLE_NONE;
        mOutput = AUDIO_IO_HANDLE_NONE;
        mPoseController.reset();
        mPoseController.reset();

        callback = mSpatializerCallback;
        callback = mSpatializerCallback;
    }
    }


@@ -707,6 +712,24 @@ audio_io_handle_t Spatializer::detachOutput() {
    return output;
    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() {
void Spatializer::calculateHeadPose() {
    ALOGV("%s", __func__);
    ALOGV("%s", __func__);
    std::lock_guard lock(mLock);
    std::lock_guard lock(mLock);
+7 −1
Original line number Original line Diff line number Diff line
@@ -135,7 +135,7 @@ class Spatializer : public media::BnSpatializer,
    /** Called by audio policy service when the special output mixer dedicated to spatialization
    /** Called by audio policy service when the special output mixer dedicated to spatialization
     * is opened and the spatializer engine must be created.
     * 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
    /** Called by audio policy service when the special output mixer dedicated to spatialization
     * is closed and the spatializer engine must be release.
     * is closed and the spatializer engine must be release.
     */
     */
@@ -143,6 +143,8 @@ class Spatializer : public media::BnSpatializer,
    /** Returns the output stream the spatializer is attached to. */
    /** Returns the output stream the spatializer is attached to. */
    audio_io_handle_t getOutput() const { std::lock_guard lock(mLock); return mOutput; }
    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. */
    /** Gets the channel mask, sampling rate and format set for the spatializer input. */
    audio_config_base_t getAudioInConfig() const;
    audio_config_base_t getAudioInConfig() const;


@@ -274,6 +276,8 @@ private:


    void postFramesProcessedMsg(int frames);
    void postFramesProcessedMsg(int frames);


    void checkHeadSensor_l() REQUIRES(mLock);

    /** Effect engine descriptor */
    /** Effect engine descriptor */
    const effect_descriptor_t mEngineDescriptor;
    const effect_descriptor_t mEngineDescriptor;
    /** Callback interface to parent audio policy service */
    /** Callback interface to parent audio policy service */
@@ -328,6 +332,8 @@ private:
    sp<ALooper> mLooper;
    sp<ALooper> mLooper;
    sp<EngineCallbackHandler> mHandler;
    sp<EngineCallbackHandler> mHandler;


    size_t mNumActiveTracks GUARDED_BY(mLock) = 0;

    static const std::vector<const char *> sHeadPoseKeys;
    static const std::vector<const char *> sHeadPoseKeys;
};
};