@camstack/system 1.2.470 → 1.2.472
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon-runner.js +248 -19
- package/dist/addon-runner.mjs +249 -20
- package/dist/addon-utils.mjs +1 -1
- package/dist/{agent-https-DmNQyAl7.mjs → agent-https-JhvY1axF.mjs} +1 -1
- package/dist/{agent-https-D_oo3PNv.js → agent-https-bnyFRK7Y.js} +1 -1
- package/dist/auth/user-manager.d.ts +2 -2
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +4 -4
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +5 -5
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +5 -5
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-history/device-history.addon.js +1 -1
- package/dist/builtins/device-history/device-history.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +1 -1
- package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +3 -3
- package/dist/builtins/keychain/index.mjs +3 -3
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.d.ts +9 -25
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +240 -39
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +237 -38
- package/dist/builtins/liveness-monitor/liveness-reporter.d.ts +28 -0
- package/dist/builtins/liveness-monitor/storage-root-access.d.ts +53 -0
- package/dist/builtins/local-auth/local-auth.addon.js +2 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +5 -5
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +10 -10
- package/dist/builtins/platform-probe/coral-accelerators.d.ts +14 -4
- package/dist/builtins/platform-probe/index.js +9 -6
- package/dist/builtins/platform-probe/index.mjs +15 -12
- package/dist/builtins/record-entries/index.js +1 -1
- package/dist/builtins/record-entries/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +20 -20
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +3 -3
- package/dist/builtins/system-config/system-config.addon.mjs +115 -115
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-B0tqvf0t.mjs → composition-sources-BY6rFuAE.mjs} +1 -1
- package/dist/{composition-sources-CRJffEiB.js → composition-sources-D3h-tNoJ.js} +1 -1
- package/dist/{constants-WF1AqoKF.js → constants-CqbO6e9i.js} +1 -1
- package/dist/{constants--A505iuO.mjs → constants-zBiEodEM.mjs} +1 -1
- package/dist/{coral-accelerators-Cri32b7q.js → coral-accelerators-BSVsBVzt.js} +46 -11
- package/dist/{coral-accelerators-Dl-GnMHn.mjs → coral-accelerators-DBlgWB8k.mjs} +52 -17
- package/dist/{custom-action-registry-BGYDjTqY.mjs → custom-action-registry-DZSCLBuT.mjs} +37 -37
- package/dist/{device-ca-DYmToMp8.mjs → device-ca-BWTWWBcc.mjs} +1 -1
- package/dist/{device-ca-R4MZZtc0.js → device-ca-CfiIg3a9.js} +1 -1
- package/dist/{dist-X1r44BdF.mjs → dist-CdFkkmXW.mjs} +6845 -1651
- package/dist/{dist-DRL3rEfN.js → dist-DX5Fu3mV.js} +6845 -1651
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-DUoTS6jN.js → hub-mdns-ciao-C174UDzO.js} +2 -2
- package/dist/{hub-mdns-ciao-CZV5Hion.mjs → hub-mdns-ciao-CYp1Gipm.mjs} +2 -2
- package/dist/index.js +235 -17
- package/dist/index.mjs +453 -235
- package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +24 -4
- package/dist/kernel/hwaccel/vaapi-init-probe.d.ts +29 -0
- package/dist/kernel/moleculer/runner-process-group.d.ts +4 -0
- package/dist/{restore-archive-Df6PsOHP.js → restore-archive-B2jIFfu_.js} +1 -1
- package/dist/{restore-archive-X0ciGMmO.mjs → restore-archive-BX0gaKtG.mjs} +94 -94
- package/dist/{wal-maintenance-DYvzJiuK.js → wal-maintenance-Dxqd5igw.js} +0 -0
- package/dist/{wal-maintenance-D6J_MmZ8.mjs → wal-maintenance-KHzJXlF2.mjs} +0 -0
- package/package.json +1 -1
package/dist/addon-runner.js
CHANGED
|
@@ -7447,7 +7447,7 @@ function toKebab(name) {
|
|
|
7447
7447
|
return name.replace(/[A-Z]/g, (m, i) => (i > 0 ? "-" : "") + m.toLowerCase());
|
|
7448
7448
|
}
|
|
7449
7449
|
/**
|
|
7450
|
-
* Parse an `op.path` (e.g. `"pipelineExecutor.
|
|
7450
|
+
* Parse an `op.path` (e.g. `"pipelineExecutor.getAvailableEngines"`) into
|
|
7451
7451
|
* the capability name (kebab-case) and the method name.
|
|
7452
7452
|
*/
|
|
7453
7453
|
function parsePath(path) {
|
|
@@ -7893,14 +7893,34 @@ function currentDelegateHost() {
|
|
|
7893
7893
|
override: process.env[_camstack_types_node.EDGETPU_LIB_ENV]
|
|
7894
7894
|
};
|
|
7895
7895
|
}
|
|
7896
|
-
|
|
7897
|
-
|
|
7896
|
+
/** usbfs names a device `/dev/bus/usb/<busnum>/<devnum>`, each zero-padded to three digits. */
|
|
7897
|
+
function usbDeviceNode(device, fsx) {
|
|
7898
|
+
const bus = Number.parseInt(fsx.readUsbAttr(device, "busnum"), 10);
|
|
7899
|
+
const dev = Number.parseInt(fsx.readUsbAttr(device, "devnum"), 10);
|
|
7900
|
+
if (!Number.isInteger(bus) || !Number.isInteger(dev) || bus <= 0 || dev <= 0) return null;
|
|
7901
|
+
return `/dev/bus/usb/${String(bus).padStart(3, "0")}/${String(dev).padStart(3, "0")}`;
|
|
7902
|
+
}
|
|
7903
|
+
/**
|
|
7904
|
+
* USB units: sysfs is the HOST's view — a container whose `/dev/bus/usb`
|
|
7905
|
+
* mapping was removed still lists the stick under `/sys/bus/usb/devices`. A
|
|
7906
|
+
* listed Coral is usable only when its usbfs device node is in this process's
|
|
7907
|
+
* view AND opens read/write; otherwise it is present but not accessible.
|
|
7908
|
+
*/
|
|
7909
|
+
function classifyUsb(devices, fsx) {
|
|
7910
|
+
let usable = 0;
|
|
7911
|
+
const inaccessibleNodes = [];
|
|
7898
7912
|
for (const device of devices) {
|
|
7899
7913
|
const vendor = fsx.readUsbAttr(device, "idVendor").toLowerCase();
|
|
7900
7914
|
const product = fsx.readUsbAttr(device, "idProduct").toLowerCase();
|
|
7901
|
-
if (CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product))
|
|
7915
|
+
if (!CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) continue;
|
|
7916
|
+
const node = usbDeviceNode(device, fsx);
|
|
7917
|
+
if (node !== null && fsx.exists(node) && fsx.canOpen(node)) usable++;
|
|
7918
|
+
else inaccessibleNodes.push(node ?? `/sys/bus/usb/devices/${device}`);
|
|
7902
7919
|
}
|
|
7903
|
-
return
|
|
7920
|
+
return {
|
|
7921
|
+
usable,
|
|
7922
|
+
inaccessibleNodes
|
|
7923
|
+
};
|
|
7904
7924
|
}
|
|
7905
7925
|
function countPciCorals(fsx) {
|
|
7906
7926
|
let count = 0;
|
|
@@ -7943,7 +7963,9 @@ function classifyCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
|
|
|
7943
7963
|
/**
|
|
7944
7964
|
* Detect Coral Edge TPUs on USB and PCIe/M.2, with the evidence that decided.
|
|
7945
7965
|
*
|
|
7946
|
-
* - USB: every matching USB device counts (multiple Corals run concurrently)
|
|
7966
|
+
* - USB: every matching USB device counts (multiple Corals run concurrently),
|
|
7967
|
+
* usable only if its `/dev/bus/usb/<BBB>/<DDD>` node opens read/write — a
|
|
7968
|
+
* listed stick whose node is missing or refused is `device-not-accessible`.
|
|
7947
7969
|
* - PCIe: the apex driver's units, each usable only if its device node opens;
|
|
7948
7970
|
* a Coral PCI function the driver did not bind is `driver-missing`.
|
|
7949
7971
|
* - Fallback: when the USB bus is NOT OBSERVABLE (`/sys/bus/usb/devices`
|
|
@@ -7960,18 +7982,28 @@ function classifyCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
|
|
|
7960
7982
|
function detectCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
|
|
7961
7983
|
const usbDevices = fsx.listUsbDevices();
|
|
7962
7984
|
const usbBus = usbDevices !== null && usbDevices.length > 0 ? "observed" : "unobservable";
|
|
7963
|
-
const usb = usbDevices === null ?
|
|
7985
|
+
const usb = usbDevices === null ? {
|
|
7986
|
+
usable: 0,
|
|
7987
|
+
inaccessibleNodes: []
|
|
7988
|
+
} : classifyUsb(usbDevices, fsx);
|
|
7989
|
+
const usbSeen = usb.usable + usb.inaccessibleNodes.length;
|
|
7990
|
+
const inaccessibleUsbNodes = usb.inaccessibleNodes;
|
|
7964
7991
|
const pci = classifyPci(fsx);
|
|
7965
7992
|
const units = [];
|
|
7966
|
-
if (usb > 0) units.push({
|
|
7993
|
+
if (usb.usable > 0) units.push({
|
|
7967
7994
|
bus: "usb",
|
|
7968
|
-
count: usb
|
|
7995
|
+
count: usb.usable
|
|
7969
7996
|
});
|
|
7970
7997
|
if (pci.usable > 0) units.push({
|
|
7971
7998
|
bus: "pci",
|
|
7972
7999
|
count: pci.usable
|
|
7973
8000
|
});
|
|
7974
8001
|
const unavailable = [];
|
|
8002
|
+
if (usb.inaccessibleNodes.length > 0) unavailable.push({
|
|
8003
|
+
bus: "usb",
|
|
8004
|
+
count: usb.inaccessibleNodes.length,
|
|
8005
|
+
reason: "device-not-accessible"
|
|
8006
|
+
});
|
|
7975
8007
|
if (pci.driverMissing > 0) unavailable.push({
|
|
7976
8008
|
bus: "pci",
|
|
7977
8009
|
count: pci.driverMissing,
|
|
@@ -7992,7 +8024,8 @@ function detectCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
|
|
|
7992
8024
|
units
|
|
7993
8025
|
},
|
|
7994
8026
|
usbBus,
|
|
7995
|
-
decidedBy:
|
|
8027
|
+
decidedBy: usbSeen > 0 ? "usb-ids" : "pci",
|
|
8028
|
+
inaccessibleUsbNodes
|
|
7996
8029
|
};
|
|
7997
8030
|
if (usbBus === "unobservable" && (0, _camstack_types_node.chooseEdgetpuDelegate)({
|
|
7998
8031
|
...delegateHost,
|
|
@@ -8006,12 +8039,14 @@ function detectCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
|
|
|
8006
8039
|
}]
|
|
8007
8040
|
},
|
|
8008
8041
|
usbBus,
|
|
8009
|
-
decidedBy: "delegate-fallback"
|
|
8042
|
+
decidedBy: "delegate-fallback",
|
|
8043
|
+
inaccessibleUsbNodes
|
|
8010
8044
|
};
|
|
8011
8045
|
return {
|
|
8012
8046
|
info: null,
|
|
8013
8047
|
usbBus,
|
|
8014
|
-
decidedBy: "none"
|
|
8048
|
+
decidedBy: "none",
|
|
8049
|
+
inaccessibleUsbNodes
|
|
8015
8050
|
};
|
|
8016
8051
|
}
|
|
8017
8052
|
function safeListOrNull(dir) {
|
|
@@ -8059,6 +8094,148 @@ var nodeCoralFs = {
|
|
|
8059
8094
|
}
|
|
8060
8095
|
};
|
|
8061
8096
|
//#endregion
|
|
8097
|
+
//#region src/kernel/hwaccel/vaapi-init-probe.ts
|
|
8098
|
+
/**
|
|
8099
|
+
* Can libva initialise the VA driver on this node's render node? (D926)
|
|
8100
|
+
*
|
|
8101
|
+
* Measured 2026-10-23 (intel-1.2.509, hub + little-unraid): Intel's iHD 25.2.4
|
|
8102
|
+
* exports only `__vaDriverInit_1_22`, the container's Ubuntu libva 2.20 looks
|
|
8103
|
+
* for `_1_20`, and `vaInitialize` failed — while the resolver kept offering
|
|
8104
|
+
* `qsv, vaapi`. Every session tried, failed and fell back to software: 722
|
|
8105
|
+
* `hwaccel 'vaapi' failed` lines a day and nothing that named the cause.
|
|
8106
|
+
*
|
|
8107
|
+
* One `vainfo --display drm --device <node>` per process answers it. A failure
|
|
8108
|
+
* reads the driver's exported `__vaDriverInit_1_N` so the verdict names the gap
|
|
8109
|
+
* (`driver iHD needs VA-API >= 1.22, libva has 1.20`). No `vainfo` on the host
|
|
8110
|
+
* (a bare install) is `unknown` — the resolver then behaves as it always did.
|
|
8111
|
+
*/
|
|
8112
|
+
var VAINFO_TIMEOUT_MS = 1e4;
|
|
8113
|
+
var INIT_SYMBOL = /__vaDriverInit_(\d+)_(\d+)/g;
|
|
8114
|
+
var VA_API_VERSION = /VA-API version:? (\d+)\.(\d+)/;
|
|
8115
|
+
var DRIVER_OPEN = /Trying to open (\S+_drv_video\.so)/g;
|
|
8116
|
+
function newestInitVersion(symbols) {
|
|
8117
|
+
let best = null;
|
|
8118
|
+
for (const symbol of symbols) for (const m of symbol.matchAll(INIT_SYMBOL)) {
|
|
8119
|
+
const v = {
|
|
8120
|
+
major: Number(m[1]),
|
|
8121
|
+
minor: Number(m[2])
|
|
8122
|
+
};
|
|
8123
|
+
if (!best || v.major > best.major || v.major === best.major && v.minor > best.minor) best = v;
|
|
8124
|
+
}
|
|
8125
|
+
return best;
|
|
8126
|
+
}
|
|
8127
|
+
function lastMatch(text, re) {
|
|
8128
|
+
let last = null;
|
|
8129
|
+
for (const m of text.matchAll(re)) last = m[1] ?? null;
|
|
8130
|
+
return last;
|
|
8131
|
+
}
|
|
8132
|
+
function lastLine(text) {
|
|
8133
|
+
const lines = text.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
8134
|
+
return lines[lines.length - 1] ?? "no output";
|
|
8135
|
+
}
|
|
8136
|
+
function driverName(driverPath) {
|
|
8137
|
+
if (!driverPath) return "unknown";
|
|
8138
|
+
return (0, node_path.basename)(driverPath).replace(/_drv_video\.so$/, "");
|
|
8139
|
+
}
|
|
8140
|
+
/** Classify one vainfo run plus the driver's exported init symbols. Pure. */
|
|
8141
|
+
function classifyVainfo(run, driverSymbols) {
|
|
8142
|
+
const va = VA_API_VERSION.exec(run.output);
|
|
8143
|
+
const vaApiVersion = va ? `${va[1]}.${va[2]}` : null;
|
|
8144
|
+
const driverPath = lastMatch(run.output, DRIVER_OPEN);
|
|
8145
|
+
const needs = newestInitVersion(driverSymbols);
|
|
8146
|
+
const driverNeedsVaApi = needs ? `${needs.major}.${needs.minor}` : null;
|
|
8147
|
+
const base = {
|
|
8148
|
+
vaApiVersion,
|
|
8149
|
+
driverPath,
|
|
8150
|
+
driverNeedsVaApi
|
|
8151
|
+
};
|
|
8152
|
+
if (run.spawnError !== null) return {
|
|
8153
|
+
...base,
|
|
8154
|
+
state: "unknown",
|
|
8155
|
+
summary: `vaapi: unknown (vainfo not run: ${run.spawnError})`
|
|
8156
|
+
};
|
|
8157
|
+
if (run.exitCode === 0) return {
|
|
8158
|
+
...base,
|
|
8159
|
+
state: "ok",
|
|
8160
|
+
summary: `vaapi: ok (VA-API ${vaApiVersion ?? "?"}, driver ${driverName(driverPath)})`
|
|
8161
|
+
};
|
|
8162
|
+
const reason = needs !== null && va !== null && (needs.major > Number(va[1]) || needs.major === Number(va[1]) && needs.minor > Number(va[2])) ? `driver ${driverName(driverPath)} needs VA-API >= ${driverNeedsVaApi}, libva has ${vaApiVersion}` : lastLine(run.output);
|
|
8163
|
+
return {
|
|
8164
|
+
...base,
|
|
8165
|
+
state: "init-failed",
|
|
8166
|
+
summary: `vaapi: init-failed (${reason})`
|
|
8167
|
+
};
|
|
8168
|
+
}
|
|
8169
|
+
/** Run `vainfo` against one render node; never throws. */
|
|
8170
|
+
function runVainfo(renderNode) {
|
|
8171
|
+
return new Promise((resolve) => {
|
|
8172
|
+
(0, node_child_process.execFile)("vainfo", [
|
|
8173
|
+
"--display",
|
|
8174
|
+
"drm",
|
|
8175
|
+
"--device",
|
|
8176
|
+
renderNode
|
|
8177
|
+
], {
|
|
8178
|
+
timeout: VAINFO_TIMEOUT_MS,
|
|
8179
|
+
encoding: "utf8"
|
|
8180
|
+
}, (err, stdout, stderr) => {
|
|
8181
|
+
const output = `${stdout}\n${stderr}`;
|
|
8182
|
+
if (err === null) {
|
|
8183
|
+
resolve({
|
|
8184
|
+
exitCode: 0,
|
|
8185
|
+
output,
|
|
8186
|
+
spawnError: null
|
|
8187
|
+
});
|
|
8188
|
+
return;
|
|
8189
|
+
}
|
|
8190
|
+
const code = err.code;
|
|
8191
|
+
if (typeof code === "number") {
|
|
8192
|
+
resolve({
|
|
8193
|
+
exitCode: code,
|
|
8194
|
+
output,
|
|
8195
|
+
spawnError: null
|
|
8196
|
+
});
|
|
8197
|
+
return;
|
|
8198
|
+
}
|
|
8199
|
+
resolve({
|
|
8200
|
+
exitCode: null,
|
|
8201
|
+
output,
|
|
8202
|
+
spawnError: code ?? (err.killed ? "timeout" : err.message)
|
|
8203
|
+
});
|
|
8204
|
+
});
|
|
8205
|
+
});
|
|
8206
|
+
}
|
|
8207
|
+
/**
|
|
8208
|
+
* The `__vaDriverInit_N_M` names in a driver file, streamed (iHD is ~43 MB),
|
|
8209
|
+
* with an overlap so a name split across two chunks is still found.
|
|
8210
|
+
*/
|
|
8211
|
+
function readDriverInitSymbols(driverPath) {
|
|
8212
|
+
return new Promise((resolve) => {
|
|
8213
|
+
const found = /* @__PURE__ */ new Set();
|
|
8214
|
+
let carry = "";
|
|
8215
|
+
const stream = (0, node_fs.createReadStream)(driverPath, {
|
|
8216
|
+
encoding: "latin1",
|
|
8217
|
+
highWaterMark: 64 * 1024
|
|
8218
|
+
});
|
|
8219
|
+
stream.on("data", (chunk) => {
|
|
8220
|
+
const text = carry + String(chunk);
|
|
8221
|
+
for (const m of text.matchAll(INIT_SYMBOL)) if (m.index + m[0].length < text.length) found.add(m[0]);
|
|
8222
|
+
carry = text.slice(-32);
|
|
8223
|
+
});
|
|
8224
|
+
stream.on("error", () => resolve([]));
|
|
8225
|
+
stream.on("end", () => {
|
|
8226
|
+
for (const m of carry.matchAll(INIT_SYMBOL)) found.add(m[0]);
|
|
8227
|
+
resolve([...found].sort());
|
|
8228
|
+
});
|
|
8229
|
+
});
|
|
8230
|
+
}
|
|
8231
|
+
/** Probe one render node: vainfo, and on failure the driver's init symbols. */
|
|
8232
|
+
async function probeVaapiInit(renderNode) {
|
|
8233
|
+
const run = await runVainfo(renderNode);
|
|
8234
|
+
if (run.spawnError !== null || run.exitCode === 0) return classifyVainfo(run, []);
|
|
8235
|
+
const driverPath = lastMatch(run.output, DRIVER_OPEN);
|
|
8236
|
+
return classifyVainfo(run, driverPath ? await readDriverInitSymbols(driverPath) : []);
|
|
8237
|
+
}
|
|
8238
|
+
//#endregion
|
|
8062
8239
|
//#region src/kernel/hwaccel/hwaccel-resolver.ts
|
|
8063
8240
|
/**
|
|
8064
8241
|
* Platform-probe for hardware video decode acceleration.
|
|
@@ -8128,7 +8305,23 @@ function probePlatform() {
|
|
|
8128
8305
|
coral: classifyCoralAccelerator(nodeCoralFs)
|
|
8129
8306
|
};
|
|
8130
8307
|
}
|
|
8131
|
-
|
|
8308
|
+
/** The backends that open their device through libva on Linux. */
|
|
8309
|
+
var LIBVA_BACKENDS = ["vaapi", "qsv"];
|
|
8310
|
+
/**
|
|
8311
|
+
* The preference list for these signals. A `vaapi` verdict of `init-failed`
|
|
8312
|
+
* (libva cannot initialise the driver — D926) removes every libva-backed
|
|
8313
|
+
* backend and names the cause in the rationale; `ok`, `unknown` or `null`
|
|
8314
|
+
* change nothing.
|
|
8315
|
+
*/
|
|
8316
|
+
function pickBackendsForPlatform(signals, vaapi = null) {
|
|
8317
|
+
const res = pickBackendsFromSignals(signals);
|
|
8318
|
+
if (signals.platform !== "linux" || vaapi?.state !== "init-failed") return res;
|
|
8319
|
+
return {
|
|
8320
|
+
preferred: res.preferred.filter((b) => !LIBVA_BACKENDS.includes(b)),
|
|
8321
|
+
rationale: `${res.rationale} ${vaapi.summary} — vaapi/qsv withheld, decode runs in software.`
|
|
8322
|
+
};
|
|
8323
|
+
}
|
|
8324
|
+
function pickBackendsFromSignals(signals) {
|
|
8132
8325
|
switch (signals.platform) {
|
|
8133
8326
|
case "darwin": return {
|
|
8134
8327
|
preferred: ["videotoolbox"],
|
|
@@ -8189,13 +8382,49 @@ function resolveHwAccel(prefer) {
|
|
|
8189
8382
|
};
|
|
8190
8383
|
return pickBackendsForPlatform(probePlatform());
|
|
8191
8384
|
}
|
|
8385
|
+
var RENDER_NODE = "/dev/dri/renderD128";
|
|
8386
|
+
/** Process-wide: the VA init failure is logged once per process, not per resolver. */
|
|
8387
|
+
var PROCESS_VAAPI_REPORT = { reported: false };
|
|
8388
|
+
/** Process-wide: hub-main builds one resolver per in-process addon; vainfo runs once. */
|
|
8389
|
+
var PROCESS_VAAPI_PROBES = /* @__PURE__ */ new Map();
|
|
8390
|
+
function probeVaapiOncePerProcess(renderNode) {
|
|
8391
|
+
const known = PROCESS_VAAPI_PROBES.get(renderNode);
|
|
8392
|
+
if (known) return known;
|
|
8393
|
+
const probe = probeVaapiInit(renderNode);
|
|
8394
|
+
PROCESS_VAAPI_PROBES.set(renderNode, probe);
|
|
8395
|
+
return probe;
|
|
8396
|
+
}
|
|
8192
8397
|
/**
|
|
8193
8398
|
* Build the `IKernelHwAccel` provider used to populate `ctx.kernel.hwaccel`.
|
|
8194
|
-
*
|
|
8195
|
-
*
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8399
|
+
* An auto resolve on a Linux host with a render node asks libva ONCE per
|
|
8400
|
+
* provider whether it can initialise the driver (D926); an explicit override
|
|
8401
|
+
* is never second-guessed.
|
|
8402
|
+
*/
|
|
8403
|
+
function createKernelHwAccel(options = {}) {
|
|
8404
|
+
const probeSignals = options.probeSignals ?? probePlatform;
|
|
8405
|
+
const probeVaapi = options.probeVaapi ?? probeVaapiOncePerProcess;
|
|
8406
|
+
const reportOnce = options.reportOnce ?? PROCESS_VAAPI_REPORT;
|
|
8407
|
+
let vaapi = null;
|
|
8408
|
+
const vaapiVerdict = async () => {
|
|
8409
|
+
if (vaapi === null) vaapi = probeVaapi(RENDER_NODE);
|
|
8410
|
+
const status = await vaapi;
|
|
8411
|
+
if (status.state === "init-failed" && !reportOnce.reported) {
|
|
8412
|
+
reportOnce.reported = true;
|
|
8413
|
+
options.logger?.error(`hwaccel: ${status.summary} — vaapi/qsv withheld, decode runs in software`, { meta: {
|
|
8414
|
+
renderNode: RENDER_NODE,
|
|
8415
|
+
vaApiVersion: status.vaApiVersion,
|
|
8416
|
+
driverPath: status.driverPath,
|
|
8417
|
+
driverNeedsVaApi: status.driverNeedsVaApi
|
|
8418
|
+
} });
|
|
8419
|
+
}
|
|
8420
|
+
return status;
|
|
8421
|
+
};
|
|
8422
|
+
return { resolve: async (prefer) => {
|
|
8423
|
+
if (prefer === "none" || prefer !== null && prefer !== void 0 && prefer.length > 0) return resolveHwAccel(prefer);
|
|
8424
|
+
const signals = probeSignals();
|
|
8425
|
+
if (signals.platform !== "linux" || !signals.hasRenderNode) return pickBackendsForPlatform(signals);
|
|
8426
|
+
return pickBackendsForPlatform(signals, await vaapiVerdict());
|
|
8427
|
+
} };
|
|
8199
8428
|
}
|
|
8200
8429
|
//#endregion
|
|
8201
8430
|
//#region src/kernel/inference/inference-resolver.ts
|
|
@@ -10540,7 +10769,7 @@ async function buildAddonContext(runtime, declaration, dataDir, options) {
|
|
|
10540
10769
|
value
|
|
10541
10770
|
})
|
|
10542
10771
|
};
|
|
10543
|
-
const hwaccel = createKernelHwAccel();
|
|
10772
|
+
const hwaccel = createKernelHwAccel({ logger: scopedLogger });
|
|
10544
10773
|
const inferenceEngine = createKernelInferenceEngine();
|
|
10545
10774
|
return {
|
|
10546
10775
|
localNodeId: nodeId,
|