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

Commit b725c69f authored by Andy Hung's avatar Andy Hung
Browse files

Spatializer: Raise Spatializer-looper priority to RT

Prevents priority inversion when sending HT data to the Spatializer Effect
which was causing a stall of 15ms.

Test: adb shell 'ps -Tl -p $(pgrep audioserver)'
Bug: 261686532
Merged-In: I9746914d7f661ebe9a68ceaa09a37d9763ed43ef
Change-Id: I9746914d7f661ebe9a68ceaa09a37d9763ed43ef
parent 393de3a0
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0

#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <utils/Mutex.h>
#include "ISchedulingPolicyService.h"
#include "mediautils/SchedulingPolicyService.h"
@@ -86,4 +87,25 @@ int requestCpusetBoost(bool enable, const sp<IBinder> &client)
    return ret;
}

int requestSpatializerPriority(pid_t pid, pid_t tid) {
    if (pid == -1 || tid == -1) return BAD_VALUE;

    // update priority to RT if specified.
    constexpr int32_t kRTPriorityMin = 1;
    constexpr int32_t kRTPriorityMax = 3;
    const int32_t priorityBoost =
            property_get_int32("audio.spatializer.priority", kRTPriorityMin);
    if (priorityBoost >= kRTPriorityMin && priorityBoost <= kRTPriorityMax) {
        const status_t status = requestPriority(
                pid, tid, priorityBoost, false /* isForApp */, true /*asynchronous*/);
        if (status != OK) {
            ALOGW("%s: Cannot request spatializer priority boost %d, status:%d",
                    __func__, priorityBoost, status);
            return status < 0 ? status : UNKNOWN_ERROR;
        }
        return priorityBoost;
    }
    return 0;  // no boost requested
}

}   // namespace android
+7 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ namespace android {

class IBinder;
// Request elevated priority for thread tid, whose thread group leader must be pid.
// The priority parameter is currently restricted to either 1 or 2.
// The priority parameter is currently restricted from 1 to 3.
// The asynchronous parameter should be 'true' to return immediately,
// after the request is enqueued but not necessarily executed.
// The default value 'false' means to return after request has been enqueued and executed.
@@ -37,6 +37,12 @@ int requestPriority(pid_t pid, pid_t tid, int32_t prio, bool isForApp, bool asyn
// 'client' is ignored in this case.
int requestCpusetBoost(bool enable, const sp<IBinder> &client);

// Audio: Request Spatializer RT priority for thread tid, whose thread group leader must be pid.
// returns positive value if successful, the RT priority used
//         zero, if no RT priority selected
//         negative status code if RT priority unable to be set.
int requestSpatializerPriority(pid_t pid, pid_t tid);

}   // namespace android

#endif  // _ANDROID_SCHEDULING_POLICY_SERVICE_H
+7 −17
Original line number Diff line number Diff line
@@ -7339,23 +7339,13 @@ void AudioFlinger::SpatializerThread::onFirstRef() {
        updateHalSupportedLatencyModes_l();
    }

    // update priority if specified.
    constexpr int32_t kRTPriorityMin = 1;
    constexpr int32_t kRTPriorityMax = 3;
    const int32_t priorityBoost =
            property_get_int32("audio.spatializer.priority", kRTPriorityMin);
    if (priorityBoost >= kRTPriorityMin && priorityBoost <= kRTPriorityMax) {
        const pid_t pid = getpid();
    const pid_t tid = getTid();

    if (tid == -1) {
        // Unusual: PlaybackThread::onFirstRef() should set the threadLoop running.
            ALOGW("%s: audio.spatializer.priority %d ignored, thread not running",
                    __func__, priorityBoost);
        ALOGW("%s: Cannot update Spatializer mixer thread priority, not running", __func__);
    } else {
            ALOGD("%s: audio.spatializer.priority %d, allowing real time for pid %d  tid %d",
                    __func__, priorityBoost, pid, tid);
            sendPrioConfigEvent_l(pid, tid, priorityBoost, false /*forApp*/);
        const int priorityBoost = requestSpatializerPriority(getpid(), tid);
        if (priorityBoost > 0) {
            stream()->setHalThreadPriority(priorityBoost);
        }
    }
+10 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <media/stagefright/foundation/AMessage.h>
#include <media/MediaMetricsItem.h>
#include <media/ShmemCompat.h>
#include <mediautils/SchedulingPolicyService.h>
#include <mediautils/ServiceUtilities.h>
#include <utils/Thread.h>

@@ -111,6 +112,14 @@ public:
    };

    void onMessageReceived(const sp<AMessage> &msg) override {
        // No ALooper method to get the tid so update
        // Spatializer priority on the first message received.
        std::call_once(mPrioritySetFlag, [](){
            const pid_t pid = getpid();
            const pid_t tid = gettid();
            (void)requestSpatializerPriority(pid, tid);
        });

        sp<Spatializer> spatializer = mSpatializer.promote();
        if (spatializer == nullptr) {
            ALOGW("%s: Cannot promote spatializer", __func__);
@@ -163,6 +172,7 @@ public:
    }
private:
    wp<Spatializer> mSpatializer;
    std::once_flag mPrioritySetFlag;
};

const std::vector<const char *> Spatializer::sHeadPoseKeys = {