@camstack/addon-pipeline 1.2.333 → 1.2.335
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/THIRD_PARTY_MODELS.md +3 -8
- package/dist/audio-analyzer/index.js +2 -2
- package/dist/audio-analyzer/index.mjs +2 -2
- package/dist/{default-detection-model-CDffuH2m.mjs → custom-model-catalog-Buehc666.mjs} +518 -179
- package/dist/{default-detection-model-Biwf5-ML.js → custom-model-catalog-CL-xJa8w.js} +529 -178
- package/dist/detection-pipeline/index.js +186 -120
- package/dist/detection-pipeline/index.mjs +135 -69
- package/dist/{dist-DJV7Z6Bb.js → dist-C5DlS_lW.js} +214 -22
- package/dist/{dist-BsT15i7i.mjs → dist-CPhDwlSN.mjs} +203 -23
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-CkmucLYG.js → node-BUafKArW.js} +1 -1
- package/dist/{node-Crsi_8ea.mjs → node-DYfEOwjW.mjs} +1 -1
- package/dist/pipeline-runner/index.js +248 -44
- package/dist/pipeline-runner/index.mjs +226 -22
- package/dist/{process-memory-BJb7Ihdp.js → process-memory-DWOQCbg5.js} +1 -1
- package/dist/{process-memory-1mAUV8S1.mjs → process-memory-WPRYnN8c.mjs} +1 -1
- package/dist/recorder/index.js +2 -2
- package/dist/recorder/index.mjs +2 -2
- package/dist/{segment-demux-js-mK9IBGLf.js → segment-demux-js-DWIgUPW1.js} +1 -1
- package/dist/{segment-demux-js-B_tboBcJ.mjs → segment-demux-js-Kz4EnmOr.mjs} +1 -1
- package/dist/stream-broker/_stub.js +1 -1
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-a3HMFtd5.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-RPk9F8CY.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-1Y-WK-Zy.mjs +26 -0
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-DChPnZ5C.mjs → hostInit-DXXdQdLd.mjs} +2 -2
- package/dist/stream-broker/index.js +3 -3
- package/dist/stream-broker/index.mjs +3 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/python/inference_pool.py +52 -2
- package/python/postprocessors/test_yolo_seg_root.py +109 -0
- package/python/postprocessors/yolo.py +52 -13
- package/python/postprocessors/yolo_seg.py +79 -156
- package/python/test_inference_pool_ov_precision.py +98 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DPbj3ML4.mjs +0 -26
|
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
7
|
-
const require_node = require("../node-
|
|
8
|
-
const
|
|
6
|
+
const require_dist = require("../dist-C5DlS_lW.js");
|
|
7
|
+
const require_node = require("../node-BUafKArW.js");
|
|
8
|
+
const require_custom_model_catalog = require("../custom-model-catalog-CL-xJa8w.js");
|
|
9
9
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
10
10
|
const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
|
|
11
11
|
const require_restream_intent = require("../restream-intent-7uDNqMKs.js");
|
|
@@ -1723,7 +1723,7 @@ function cropRgb(frame, bbox, maxWidth) {
|
|
|
1723
1723
|
* pass exists to fix.
|
|
1724
1724
|
*/
|
|
1725
1725
|
async function toDecodedFrame(frame, format, viewSpec) {
|
|
1726
|
-
const geometry = viewSpec ?
|
|
1726
|
+
const geometry = viewSpec ? require_custom_model_catalog.resolveFrameViewGeometry(frame.image.width, frame.image.height, viewSpec) : void 0;
|
|
1727
1727
|
const bytes = await frame.image.toBuffer(geometry ? {
|
|
1728
1728
|
crop: geometry.sourceCrop,
|
|
1729
1729
|
resize: geometry.output,
|
|
@@ -1762,7 +1762,7 @@ function startSessionDecodePump(deps) {
|
|
|
1762
1762
|
workerGone = true;
|
|
1763
1763
|
deps.onWorkerGone?.();
|
|
1764
1764
|
};
|
|
1765
|
-
const iterator =
|
|
1765
|
+
const iterator = require_custom_model_catalog.createSessionDecodeCoordinator({
|
|
1766
1766
|
fork: (source) => {
|
|
1767
1767
|
const child = deps.fork(source);
|
|
1768
1768
|
forked = true;
|
|
@@ -1964,7 +1964,7 @@ function onboardRootDetections(slot, frame, gate) {
|
|
|
1964
1964
|
}
|
|
1965
1965
|
};
|
|
1966
1966
|
});
|
|
1967
|
-
const admitted = detections.filter((d) =>
|
|
1967
|
+
const admitted = detections.filter((d) => require_custom_model_catalog.macroGateVerdict(d.macroClass, d.score, gate) === "pass");
|
|
1968
1968
|
if (admitted.length === 0) return {
|
|
1969
1969
|
kind: "gated",
|
|
1970
1970
|
refused: detections.length
|
|
@@ -1976,6 +1976,158 @@ function onboardRootDetections(slot, frame, gate) {
|
|
|
1976
1976
|
};
|
|
1977
1977
|
}
|
|
1978
1978
|
//#endregion
|
|
1979
|
+
//#region src/pipeline-runner/root-mask-supply.ts
|
|
1980
|
+
/** The frame-plane step a seg root supplies. */
|
|
1981
|
+
var SEGMENTATION_STEP_ID = "segmentation";
|
|
1982
|
+
/** Whether an ENABLED `stepId` is reachable through enabled ancestors. */
|
|
1983
|
+
function dispatchesStep(steps, stepId) {
|
|
1984
|
+
return steps.some((s) => s.enabled !== false && (s.addonId === stepId || s.children !== void 0 && dispatchesStep(s.children, stepId)));
|
|
1985
|
+
}
|
|
1986
|
+
function withoutStep(steps, stepId) {
|
|
1987
|
+
return steps.filter((s) => s.addonId !== stepId).map((s) => s.children !== void 0 ? {
|
|
1988
|
+
...s,
|
|
1989
|
+
children: withoutStep(s.children, stepId)
|
|
1990
|
+
} : s);
|
|
1991
|
+
}
|
|
1992
|
+
/**
|
|
1993
|
+
* When the camera's mask supply is effective and the step would run, drop it
|
|
1994
|
+
* from the dispatch: the root's masks replace one inference per detection.
|
|
1995
|
+
* Otherwise the tree is returned untouched — a root that emits no masks (or a
|
|
1996
|
+
* flag the operator unchecked) leaves the step running its own model.
|
|
1997
|
+
*/
|
|
1998
|
+
function applyMaskFill(steps, plan) {
|
|
1999
|
+
const dispatched = dispatchesStep(steps, SEGMENTATION_STEP_ID);
|
|
2000
|
+
if (!dispatched || plan.states.get("segmentation")?.effective !== true) return {
|
|
2001
|
+
steps,
|
|
2002
|
+
filledByRoot: false,
|
|
2003
|
+
segmentationDispatched: dispatched
|
|
2004
|
+
};
|
|
2005
|
+
return {
|
|
2006
|
+
steps: withoutStep(steps, SEGMENTATION_STEP_ID),
|
|
2007
|
+
filledByRoot: true,
|
|
2008
|
+
segmentationDispatched: false
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* The largest 4-connected non-zero component of a `width × height` byte mask —
|
|
2013
|
+
* the same reduction the `segmentation` step's decode applies to its own mask
|
|
2014
|
+
* (`saliency.py`). `null` when the mask has no foreground (or a size that does
|
|
2015
|
+
* not match its bytes).
|
|
2016
|
+
*/
|
|
2017
|
+
function largestMaskComponent(mask, width, height) {
|
|
2018
|
+
const size = width * height;
|
|
2019
|
+
if (!(size > 0) || mask.length < size) return null;
|
|
2020
|
+
const visited = new Uint8Array(size);
|
|
2021
|
+
const stack = new Int32Array(size);
|
|
2022
|
+
let best = null;
|
|
2023
|
+
for (let start = 0; start < size; start++) {
|
|
2024
|
+
if (mask[start] === 0 || visited[start] === 1) continue;
|
|
2025
|
+
visited[start] = 1;
|
|
2026
|
+
let top = 0;
|
|
2027
|
+
stack[top++] = start;
|
|
2028
|
+
let area = 0;
|
|
2029
|
+
let minX = width;
|
|
2030
|
+
let minY = height;
|
|
2031
|
+
let maxX = -1;
|
|
2032
|
+
let maxY = -1;
|
|
2033
|
+
while (top > 0) {
|
|
2034
|
+
const p = stack[--top];
|
|
2035
|
+
area += 1;
|
|
2036
|
+
const x = p % width;
|
|
2037
|
+
const y = (p - x) / width;
|
|
2038
|
+
if (x < minX) minX = x;
|
|
2039
|
+
if (x > maxX) maxX = x;
|
|
2040
|
+
if (y < minY) minY = y;
|
|
2041
|
+
if (y > maxY) maxY = y;
|
|
2042
|
+
if (x > 0 && visited[p - 1] === 0 && mask[p - 1] !== 0) {
|
|
2043
|
+
visited[p - 1] = 1;
|
|
2044
|
+
stack[top++] = p - 1;
|
|
2045
|
+
}
|
|
2046
|
+
if (x < width - 1 && visited[p + 1] === 0 && mask[p + 1] !== 0) {
|
|
2047
|
+
visited[p + 1] = 1;
|
|
2048
|
+
stack[top++] = p + 1;
|
|
2049
|
+
}
|
|
2050
|
+
if (y > 0 && visited[p - width] === 0 && mask[p - width] !== 0) {
|
|
2051
|
+
visited[p - width] = 1;
|
|
2052
|
+
stack[top++] = p - width;
|
|
2053
|
+
}
|
|
2054
|
+
if (y < height - 1 && visited[p + width] === 0 && mask[p + width] !== 0) {
|
|
2055
|
+
visited[p + width] = 1;
|
|
2056
|
+
stack[top++] = p + width;
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
if (best === null || area > best.area) best = {
|
|
2060
|
+
area,
|
|
2061
|
+
box: [
|
|
2062
|
+
minX,
|
|
2063
|
+
minY,
|
|
2064
|
+
maxX - minX + 1,
|
|
2065
|
+
maxY - minY + 1
|
|
2066
|
+
]
|
|
2067
|
+
};
|
|
2068
|
+
}
|
|
2069
|
+
return best?.box ?? null;
|
|
2070
|
+
}
|
|
2071
|
+
/**
|
|
2072
|
+
* The detection's `refinedBbox` from its own mask — the mapping the result
|
|
2073
|
+
* assembler applies to the `segmentation` step's `maskBbox`: the mask spans
|
|
2074
|
+
* the detection's box, so mask pixels scale linearly onto it.
|
|
2075
|
+
*/
|
|
2076
|
+
function refinedBboxFromMask(detection) {
|
|
2077
|
+
const { mask, maskWidth, maskHeight, bbox } = detection;
|
|
2078
|
+
if (mask === void 0 || maskWidth === void 0 || maskHeight === void 0) return void 0;
|
|
2079
|
+
const component = largestMaskComponent(new Uint8Array(Buffer.from(mask, "base64")), maskWidth, maskHeight);
|
|
2080
|
+
if (component === null) return void 0;
|
|
2081
|
+
const [mx, my, mw, mh] = component;
|
|
2082
|
+
const sx = bbox.width / maskWidth;
|
|
2083
|
+
const sy = bbox.height / maskHeight;
|
|
2084
|
+
return {
|
|
2085
|
+
x: bbox.x + mx * sx,
|
|
2086
|
+
y: bbox.y + my * sy,
|
|
2087
|
+
width: mw * sx,
|
|
2088
|
+
height: mh * sy
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
2091
|
+
function withoutMask(detection) {
|
|
2092
|
+
const { mask: _mask, maskWidth: _w, maskHeight: _h, ...rest } = detection;
|
|
2093
|
+
if (rest.debug === void 0) return rest;
|
|
2094
|
+
const { mask: _dm, maskWidth: _dw, maskHeight: _dh, ...debug } = rest.debug;
|
|
2095
|
+
return {
|
|
2096
|
+
...rest,
|
|
2097
|
+
debug
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Apply the mask decision to a frame. Filled by the root ⇒ each root
|
|
2102
|
+
* detection's mask is completed with its `refinedBbox`, exactly what the
|
|
2103
|
+
* step would have written. The step ran ⇒ untouched (its own masks). Neither
|
|
2104
|
+
* ⇒ a seg root's masks are removed from the first-level detections. Never
|
|
2105
|
+
* mutates; returns the input when nothing changes.
|
|
2106
|
+
*/
|
|
2107
|
+
function applyRootMasks(result, fill) {
|
|
2108
|
+
if (fill.segmentationDispatched) return result;
|
|
2109
|
+
let changed = false;
|
|
2110
|
+
const detections = result.detections.map((d) => {
|
|
2111
|
+
if (d.kind !== "first-level" || d.mask === void 0) return d;
|
|
2112
|
+
if (!fill.filledByRoot) {
|
|
2113
|
+
changed = true;
|
|
2114
|
+
return withoutMask(d);
|
|
2115
|
+
}
|
|
2116
|
+
if (d.refinedBbox !== void 0) return d;
|
|
2117
|
+
const refinedBbox = refinedBboxFromMask(d);
|
|
2118
|
+
if (refinedBbox === void 0) return d;
|
|
2119
|
+
changed = true;
|
|
2120
|
+
return {
|
|
2121
|
+
...d,
|
|
2122
|
+
refinedBbox
|
|
2123
|
+
};
|
|
2124
|
+
});
|
|
2125
|
+
return changed ? {
|
|
2126
|
+
...result,
|
|
2127
|
+
detections
|
|
2128
|
+
} : result;
|
|
2129
|
+
}
|
|
2130
|
+
//#endregion
|
|
1979
2131
|
//#region src/pipeline-runner/root-supply.ts
|
|
1980
2132
|
/**
|
|
1981
2133
|
* The runner's half of root-model supply (D715, D730).
|
|
@@ -2003,35 +2155,80 @@ function onboardRootDetections(slot, frame, gate) {
|
|
|
2003
2155
|
var ROOT_SUPPLY_ROOT_STEP_ID = "object-detection";
|
|
2004
2156
|
var PACKAGE_STEP_ID = "package-detection";
|
|
2005
2157
|
var PACKAGE_THRESHOLD_KEY = "minConfidencePackage";
|
|
2158
|
+
/** The step slider that governs a supplied label — one knob per step (D741). */
|
|
2159
|
+
var SUPPLIED_LABEL_FLOOR_KEY = "minConfidence";
|
|
2160
|
+
/**
|
|
2161
|
+
* The floor a supplied label must clear for one step, under the D738 binding
|
|
2162
|
+
* rule against the ROOT model: an operator value made for the root applies; one
|
|
2163
|
+
* made for the step's own classifier does not (another scale); the root's
|
|
2164
|
+
* measured floor is the default, and no floor at all when it declares none.
|
|
2165
|
+
*/
|
|
2166
|
+
function suppliedLabelFloor(stepId, settings, rootModelId, rootEntry) {
|
|
2167
|
+
const state = require_dist.resolveModelBoundSetting(settings, SUPPLIED_LABEL_FLOOR_KEY, rootModelId, rootEntry?.suppliedLabelFloors?.[stepId] ?? 0, 0);
|
|
2168
|
+
return typeof state.value === "number" ? state.value : 0;
|
|
2169
|
+
}
|
|
2006
2170
|
var EMPTY_ROOT_SUPPLY_PLAN = { states: /* @__PURE__ */ new Map() };
|
|
2007
|
-
|
|
2171
|
+
/** The step `addonId` when it is in the tree AND switched on — the per-camera gate's answer. */
|
|
2172
|
+
function findEnabledStep(steps, addonId) {
|
|
2008
2173
|
for (const step of steps) {
|
|
2174
|
+
if (step.enabled === false) continue;
|
|
2009
2175
|
if (step.addonId === addonId) return step;
|
|
2010
|
-
const nested = step.children !== void 0 ?
|
|
2176
|
+
const nested = step.children !== void 0 ? findEnabledStep(step.children, addonId) : void 0;
|
|
2011
2177
|
if (nested !== void 0) return nested;
|
|
2012
2178
|
}
|
|
2013
2179
|
}
|
|
2014
2180
|
/**
|
|
2015
|
-
*
|
|
2016
|
-
*
|
|
2017
|
-
*
|
|
2181
|
+
* The model an UNPINNED root runs on the elected device — the executor's own
|
|
2182
|
+
* rule (`resolveDefaultDetectionModel` on the device's backend, accelerator and
|
|
2183
|
+
* format), so the supplies are read off the model that really runs. Before
|
|
2184
|
+
* this, an unpinned root was judged as the step's flat `defaultModelId`
|
|
2185
|
+
* (`yolo26n`) on every accelerator, while an Intel GPU ran `yolov9m-320-int8`
|
|
2186
|
+
* and a Coral an SSD: `filledBy` named a model that was not running, and a
|
|
2187
|
+
* crop supply's input-size gate (D731) measured the wrong model. No elected
|
|
2188
|
+
* device (the runner's default pool) or an unknown backend ⇒ the flat default.
|
|
2018
2189
|
*/
|
|
2019
|
-
function
|
|
2190
|
+
function unpinnedRootModelId(deviceKey, flatDefault) {
|
|
2191
|
+
if (deviceKey === void 0) return flatDefault;
|
|
2192
|
+
try {
|
|
2193
|
+
const engine = require_custom_model_catalog.resolveDeviceEngine(deviceKey);
|
|
2194
|
+
return require_custom_model_catalog.resolveDefaultDetectionModel(engine.backend, engine.device ?? null, engine.format);
|
|
2195
|
+
} catch {
|
|
2196
|
+
return flatDefault;
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
/**
|
|
2200
|
+
* Plan a camera's root supplies from its configured tree.
|
|
2201
|
+
*
|
|
2202
|
+
* - The root's model is the one the executor runs: its pin, else the
|
|
2203
|
+
* hardware-aware default of the elected device (`deviceKey`).
|
|
2204
|
+
* - Only a step the camera RUNS is planned. A suppliable step that is absent
|
|
2205
|
+
* from the tree or switched off (the per-camera gate) has no state: the
|
|
2206
|
+
* operator switched that function off, so the root's labels are not made
|
|
2207
|
+
* authoritative for it, its root child boxes are removed, and nothing logs
|
|
2208
|
+
* that the root "supplies" it. Before this, a camera whose classifiers were
|
|
2209
|
+
* gated OFF logged `root model supplies a pipeline step` for both of them
|
|
2210
|
+
* and raised the root's labels to the detection score anyway (D736).
|
|
2211
|
+
*/
|
|
2212
|
+
function planRootSupplies(steps, resolveModel, deviceKey) {
|
|
2020
2213
|
if (steps === void 0) return EMPTY_ROOT_SUPPLY_PLAN;
|
|
2021
2214
|
const root = steps.find((s) => s.addonId === "object-detection" && s.enabled !== false);
|
|
2022
2215
|
if (root === void 0) return EMPTY_ROOT_SUPPLY_PLAN;
|
|
2023
|
-
const definition =
|
|
2024
|
-
const rootModelId = root.modelId ?? definition.defaultModelId;
|
|
2025
|
-
const
|
|
2216
|
+
const definition = require_custom_model_catalog.getStepDefinition(ROOT_SUPPLY_ROOT_STEP_ID);
|
|
2217
|
+
const rootModelId = root.modelId ?? unpinnedRootModelId(deviceKey, definition.defaultModelId);
|
|
2218
|
+
const rootEntry = resolveModel(ROOT_SUPPLY_ROOT_STEP_ID, rootModelId);
|
|
2219
|
+
const supplies = require_dist.rootSuppliesOf(rootEntry, {
|
|
2026
2220
|
labels: definition.labels ?? [],
|
|
2027
2221
|
...definition.classMap !== void 0 ? { classMap: definition.classMap } : {}
|
|
2028
2222
|
});
|
|
2029
2223
|
const states = /* @__PURE__ */ new Map();
|
|
2030
2224
|
for (const stepId of require_dist.ROOT_SUPPLIABLE_STEP_IDS) {
|
|
2031
|
-
const
|
|
2225
|
+
const step = findEnabledStep(steps, stepId);
|
|
2226
|
+
if (step === void 0) continue;
|
|
2227
|
+
const settings = step.settings;
|
|
2032
2228
|
states.set(stepId, {
|
|
2033
2229
|
...require_dist.resolveRootSupply(stepId, settings, supplies),
|
|
2034
|
-
...settings !== void 0 ? { settings } : {}
|
|
2230
|
+
...settings !== void 0 ? { settings } : {},
|
|
2231
|
+
labelFloor: suppliedLabelFloor(stepId, settings, rootModelId, rootEntry)
|
|
2035
2232
|
});
|
|
2036
2233
|
}
|
|
2037
2234
|
return {
|
|
@@ -2043,7 +2240,7 @@ function planRootSupplies(steps, resolveModel) {
|
|
|
2043
2240
|
function suppliedSteps(plan) {
|
|
2044
2241
|
const out = /* @__PURE__ */ new Map();
|
|
2045
2242
|
if (plan.rootModelId === void 0) return out;
|
|
2046
|
-
for (const [stepId, state] of plan.states) if (state.effective && state.supply !== void 0) out.set(stepId, {
|
|
2243
|
+
for (const [stepId, state] of plan.states) if (state.effective && state.supply !== void 0 && state.supply.kind !== "mask") out.set(stepId, {
|
|
2047
2244
|
modelId: plan.rootModelId,
|
|
2048
2245
|
kind: state.supply.kind
|
|
2049
2246
|
});
|
|
@@ -2069,6 +2266,10 @@ function authoritativeLabels(detection, plan) {
|
|
|
2069
2266
|
changed = true;
|
|
2070
2267
|
continue;
|
|
2071
2268
|
}
|
|
2269
|
+
if (state.labelFloor >= 1 || detection.score < state.labelFloor) {
|
|
2270
|
+
changed = true;
|
|
2271
|
+
continue;
|
|
2272
|
+
}
|
|
2072
2273
|
if (label.score === detection.score) {
|
|
2073
2274
|
labels.push(label);
|
|
2074
2275
|
continue;
|
|
@@ -2121,7 +2322,7 @@ function applyRootSupplyAuthority(result, plan) {
|
|
|
2121
2322
|
}
|
|
2122
2323
|
/** The root step's schema default for its class allow-list. */
|
|
2123
2324
|
function rootDefaultMacroClasses() {
|
|
2124
|
-
const field =
|
|
2325
|
+
const field = require_custom_model_catalog.getStep(ROOT_SUPPLY_ROOT_STEP_ID).getConfigSchema().find((f) => "key" in f && f.key === "enabledMacroClasses");
|
|
2125
2326
|
const value = field !== void 0 && "default" in field ? field.default : void 0;
|
|
2126
2327
|
return Array.isArray(value) ? value : [];
|
|
2127
2328
|
}
|
|
@@ -3363,7 +3564,7 @@ var FaceOutsideParentLog = class {
|
|
|
3363
3564
|
*/
|
|
3364
3565
|
/** The face detector's input side for the step as it will run. */
|
|
3365
3566
|
function detectorInputPx(step) {
|
|
3366
|
-
const def =
|
|
3567
|
+
const def = require_custom_model_catalog.getStepDefinition(step.addonId);
|
|
3367
3568
|
const modelId = step.modelId ?? def.defaultModelId;
|
|
3368
3569
|
return def.models.find((m) => m.id === modelId)?.inputSize.width ?? 160;
|
|
3369
3570
|
}
|
|
@@ -3474,7 +3675,7 @@ async function refineRootFace(deps, input, supplied, step, requested, deviceKey)
|
|
|
3474
3675
|
}
|
|
3475
3676
|
const chain = requested === void 0 ? step : pruneChildStepsToRequested(step, requested);
|
|
3476
3677
|
if (chain.children === void 0 || chain.children.length === 0) return [toDetailResult(face, step.addonId, crop)];
|
|
3477
|
-
const modelId = step.modelId ??
|
|
3678
|
+
const modelId = step.modelId ?? require_custom_model_catalog.getStepDefinition(step.addonId).defaultModelId;
|
|
3478
3679
|
const embedded = await deps.runPipeline([chain], crop.jpeg, input.deviceId, deviceKey, nativeCropRef, refinedAsSupplied(face, step.addonId, modelId));
|
|
3479
3680
|
if (embedded === null) return [toDetailResult(face, step.addonId, crop)];
|
|
3480
3681
|
return embedded.detections.map((d) => toDetailResult(d, step.addonId, crop));
|
|
@@ -7438,7 +7639,7 @@ function writeRetainedDetectionFrame(store, deviceId, frame, retention) {
|
|
|
7438
7639
|
if (retention) return retention.admitFrame(deviceId, frame);
|
|
7439
7640
|
if (!store) return void 0;
|
|
7440
7641
|
if (!isContinuousRetainEnabled()) return store.allocateHandle(deviceId, frame) ?? void 0;
|
|
7441
|
-
return store.write(deviceId, frame, frame.frameRef ? createRetainedContentFallback(
|
|
7642
|
+
return store.write(deviceId, frame, frame.frameRef ? createRetainedContentFallback(require_custom_model_catalog.localFrameRegistry, frame.frameRef) : void 0) ?? void 0;
|
|
7442
7643
|
}
|
|
7443
7644
|
/**
|
|
7444
7645
|
* Occupancy-burst safety timeout (both the dial path and the analyzer-tap
|
|
@@ -7555,7 +7756,7 @@ function collectEnabledStepIds(steps, acc) {
|
|
|
7555
7756
|
*/
|
|
7556
7757
|
function tryGetStepDefinition(stepId) {
|
|
7557
7758
|
try {
|
|
7558
|
-
return
|
|
7759
|
+
return require_custom_model_catalog.getStepDefinition(stepId);
|
|
7559
7760
|
} catch {
|
|
7560
7761
|
return null;
|
|
7561
7762
|
}
|
|
@@ -8121,7 +8322,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
8121
8322
|
});
|
|
8122
8323
|
this.retention = new OnDemandRetentionSession({
|
|
8123
8324
|
store: this.retainedFrames,
|
|
8124
|
-
registry:
|
|
8325
|
+
registry: require_custom_model_catalog.localFrameRegistry,
|
|
8125
8326
|
telemetry: this.frameLazy,
|
|
8126
8327
|
nodeId: this.nodeId,
|
|
8127
8328
|
continuousRetain: isContinuousRetainEnabled()
|
|
@@ -8139,7 +8340,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
8139
8340
|
minThrottledFps: this.config.minThrottledFps,
|
|
8140
8341
|
processFrame: (deviceId, frame, handle) => this.runInference(deviceId, frame, handle),
|
|
8141
8342
|
analyzeMotion: (deviceId, frame, handle) => this.runMotionAnalysis(deviceId, frame, handle),
|
|
8142
|
-
releaseFrameRef: (ref, reason) =>
|
|
8343
|
+
releaseFrameRef: (ref, reason) => require_custom_model_catalog.localFrameRegistry.release(ref, reason),
|
|
8143
8344
|
releaseRetention: (handle, reason) => {
|
|
8144
8345
|
this.retention?.release(handle, reason);
|
|
8145
8346
|
this.frameCutters.drop(handle);
|
|
@@ -9085,7 +9286,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9085
9286
|
detectionMode: config.detectionMode,
|
|
9086
9287
|
...config.detectionSources !== void 0 ? { detectionSources: config.detectionSources } : {},
|
|
9087
9288
|
...config.sessionTrigger !== void 0 ? { sessionTrigger: config.sessionTrigger } : {},
|
|
9088
|
-
...
|
|
9289
|
+
...require_custom_model_catalog.rootObjectGate(config.steps) !== void 0 ? { objectGate: require_custom_model_catalog.rootObjectGate(config.steps) } : {},
|
|
9089
9290
|
fps: config.detectionFps,
|
|
9090
9291
|
motionCooldownMs: config.motionCooldownMs,
|
|
9091
9292
|
occupancyRecheckEnabled: config.occupancyRecheckEnabled,
|
|
@@ -9484,7 +9685,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9484
9685
|
}
|
|
9485
9686
|
/** The evidence crop from the process-local lease, JPEG-encoded by the view. */
|
|
9486
9687
|
async encodeEvidenceFromLease(ref, entry) {
|
|
9487
|
-
const lease =
|
|
9688
|
+
const lease = require_custom_model_catalog.localFrameRegistry.acquire(ref);
|
|
9488
9689
|
if (!lease) return null;
|
|
9489
9690
|
let reason = "error";
|
|
9490
9691
|
try {
|
|
@@ -9574,7 +9775,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9574
9775
|
/** A 16×32 RGB view of `crop`: the lease when there is one, else the inline buffer. */
|
|
9575
9776
|
async readAppearanceView(frame, result, crop) {
|
|
9576
9777
|
if (frame.frameRef !== void 0) {
|
|
9577
|
-
const lease =
|
|
9778
|
+
const lease = require_custom_model_catalog.localFrameRegistry.acquire(frame.frameRef);
|
|
9578
9779
|
if (lease) {
|
|
9579
9780
|
let reason = "error";
|
|
9580
9781
|
try {
|
|
@@ -9920,12 +10121,13 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9920
10121
|
* Refreshed on the async boundaries (`runInference`, `runDetailSubtree`),
|
|
9921
10122
|
* read synchronously by the placement.
|
|
9922
10123
|
*/
|
|
9923
|
-
customModels = new
|
|
10124
|
+
customModels = new require_custom_model_catalog.CustomModelCatalog({ warn: (message, extras) => this.ctxIfReady?.logger.warn(message, extras) });
|
|
9924
10125
|
/**
|
|
9925
10126
|
* Per camera, the root-supply plan (D730) and the announce derived from it,
|
|
9926
10127
|
* keyed on the two inputs it reads: the attach tree and the custom-model
|
|
9927
|
-
* snapshot (a Frigate+ root is a custom model)
|
|
9928
|
-
*
|
|
10128
|
+
* snapshot (a Frigate+ root is a custom model), plus the elected device
|
|
10129
|
+
* whose default an unpinned root runs. Recomputed when any changes — at
|
|
10130
|
+
* most once per catalog refresh.
|
|
9929
10131
|
*/
|
|
9930
10132
|
rootSupplyCache = /* @__PURE__ */ new Map();
|
|
9931
10133
|
/**
|
|
@@ -9934,14 +10136,15 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9934
10136
|
* animal and vehicle classifiers by default, and that must be readable per
|
|
9935
10137
|
* camera rather than inferred from a missing dispatch (D391).
|
|
9936
10138
|
*/
|
|
9937
|
-
rootSupplyPlanFor(deviceId, steps) {
|
|
10139
|
+
rootSupplyPlanFor(deviceId, steps, deviceKey) {
|
|
9938
10140
|
const byStep = this.customModels.current();
|
|
9939
10141
|
const cached = this.rootSupplyCache.get(deviceId);
|
|
9940
|
-
if (cached !== void 0 && cached.steps === steps && cached.byStep === byStep) return cached.plan;
|
|
9941
|
-
const plan = planRootSupplies(steps, (stepId, modelId) => this.customModels.stepDefinition(stepId)?.models.find((m) => m.id === modelId));
|
|
10142
|
+
if (cached !== void 0 && cached.steps === steps && cached.deviceKey === deviceKey && cached.byStep === byStep) return cached.plan;
|
|
10143
|
+
const plan = planRootSupplies(steps, (stepId, modelId) => this.customModels.stepDefinition(stepId)?.models.find((m) => m.id === modelId), deviceKey);
|
|
9942
10144
|
const announces = deriveDetailSteps(steps, plan);
|
|
9943
10145
|
this.rootSupplyCache.set(deviceId, {
|
|
9944
10146
|
steps,
|
|
10147
|
+
deviceKey,
|
|
9945
10148
|
byStep,
|
|
9946
10149
|
plan,
|
|
9947
10150
|
announces
|
|
@@ -10084,7 +10287,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
10084
10287
|
* the elected pool pre-warms, D657) read. Pure: nothing is logged here.
|
|
10085
10288
|
*/
|
|
10086
10289
|
placementOf(config, step, attachedByKey) {
|
|
10087
|
-
return
|
|
10290
|
+
return require_custom_model_catalog.placeDetailStep({
|
|
10088
10291
|
step,
|
|
10089
10292
|
effectiveDeviceKey: config?.deviceKey,
|
|
10090
10293
|
roster: config?.inferenceDevices,
|
|
@@ -10106,7 +10309,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
10106
10309
|
return steps;
|
|
10107
10310
|
}
|
|
10108
10311
|
const attachedByKey = this.perDeviceAttachedCounts();
|
|
10109
|
-
const result =
|
|
10312
|
+
const result = require_custom_model_catalog.stepsForElectedPool(steps, isDetailPlaneStepId, (step) => this.placementOf(config, step, attachedByKey));
|
|
10110
10313
|
this.noteElectedPoolDelegation(deviceId, config.deviceKey, result.delegated);
|
|
10111
10314
|
return result.delegated.length === 0 ? steps : result.steps;
|
|
10112
10315
|
}
|
|
@@ -10797,7 +11000,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
10797
11000
|
return materialize;
|
|
10798
11001
|
},
|
|
10799
11002
|
...useLocalFrameRef ? {
|
|
10800
|
-
frameRegistry:
|
|
11003
|
+
frameRegistry: require_custom_model_catalog.localFrameRegistry,
|
|
10801
11004
|
inlineWhen: () => runner.detectionBackpressure(config.deviceId),
|
|
10802
11005
|
inlineViewSpec: SPLIT_DETECTION_VIEW,
|
|
10803
11006
|
onFrameRef: async (frame, nativeCrop) => {
|
|
@@ -10817,7 +11020,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
10817
11020
|
const admitted = current.detection && (frame.preRoll === true ? runner.enqueuePreRollFrame(config.deviceId, frame, handle) : runner.enqueueReservedDetectionFrame(config.deviceId, frame, handle));
|
|
10818
11021
|
if (admitted) nativeCrop?.markInferred();
|
|
10819
11022
|
if (current.motion) {
|
|
10820
|
-
const motion = await resolveMotionFrameView(
|
|
11023
|
+
const motion = await resolveMotionFrameView(require_custom_model_catalog.localFrameRegistry, frame.frameRef);
|
|
10821
11024
|
if (motion.kind === "view") runner.enqueueMotionFrame(config.deviceId, {
|
|
10822
11025
|
data: Buffer.from(motion.data),
|
|
10823
11026
|
width: motion.width,
|
|
@@ -11072,9 +11275,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11072
11275
|
return null;
|
|
11073
11276
|
}
|
|
11074
11277
|
if (steps.length === 0) return null;
|
|
11075
|
-
const rootSupplyPlan = this.rootSupplyPlanFor(deviceId, steps);
|
|
11278
|
+
const rootSupplyPlan = this.rootSupplyPlanFor(deviceId, steps, camConfig?.deviceKey);
|
|
11076
11279
|
const packageFill = applyPackageFill(steps, rootSupplyPlan);
|
|
11077
|
-
|
|
11280
|
+
const maskFill = applyMaskFill(packageFill.steps, rootSupplyPlan);
|
|
11281
|
+
let dispatchSteps = maskFill.steps;
|
|
11078
11282
|
if (dispatchSteps.some((s) => s.addonId === "package-detection" && s.enabled !== false)) {
|
|
11079
11283
|
this.refreshPackageZoneUnion(deviceId);
|
|
11080
11284
|
const motionInZone = this.lastMotionNearPackageZone.get(deviceId) ?? this.lastAnalyzerDetected.get(deviceId) ?? false;
|
|
@@ -11144,7 +11348,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11144
11348
|
});
|
|
11145
11349
|
} catch (err) {
|
|
11146
11350
|
const msg = require_dist.errMsg(err);
|
|
11147
|
-
if (
|
|
11351
|
+
if (require_custom_model_catalog.isSessionDecodeReadGone(err)) {
|
|
11148
11352
|
log.warn("runInference skipped — session decode frame gone", { meta: {
|
|
11149
11353
|
error: msg,
|
|
11150
11354
|
nodeId: this.nodeId,
|
|
@@ -11162,7 +11366,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11162
11366
|
return null;
|
|
11163
11367
|
}
|
|
11164
11368
|
if (result === null) return null;
|
|
11165
|
-
const looked = withPackageLook(applyRootSupplyAuthority(result, rootSupplyPlan), dispatchSteps, packageFill.filledByRoot);
|
|
11369
|
+
const looked = withPackageLook(applyRootMasks(applyRootSupplyAuthority(result, rootSupplyPlan), maskFill), dispatchSteps, packageFill.filledByRoot);
|
|
11166
11370
|
return this.recoverSmallSubjects(deviceId, frame, looked, dispatchSteps, camConfig?.deviceKey);
|
|
11167
11371
|
}
|
|
11168
11372
|
/**
|
|
@@ -11297,7 +11501,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11297
11501
|
* on a miss — the frame is gone, and the full-frame result stands.
|
|
11298
11502
|
*/
|
|
11299
11503
|
async resolveRecoveryCropView(ref, crop) {
|
|
11300
|
-
const lease =
|
|
11504
|
+
const lease = require_custom_model_catalog.localFrameRegistry.acquire(ref);
|
|
11301
11505
|
if (!lease) return null;
|
|
11302
11506
|
let reason = "error";
|
|
11303
11507
|
try {
|
|
@@ -11822,7 +12026,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11822
12026
|
},
|
|
11823
12027
|
shouldMaterializeFrame: () => !admissionClosed,
|
|
11824
12028
|
...useLocalFrameRef ? {
|
|
11825
|
-
frameRegistry:
|
|
12029
|
+
frameRegistry: require_custom_model_catalog.localFrameRegistry,
|
|
11826
12030
|
inlineWhen: () => runner.detectionBackpressure(config.deviceId),
|
|
11827
12031
|
inlineViewSpec: SPLIT_DETECTION_VIEW,
|
|
11828
12032
|
onFrameRef: (frame, nativeCrop) => {
|