@camstack/addon-pipeline 1.2.332 → 1.2.334
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-Biwf5-ML.js → custom-model-catalog-CVeosmYm.js} +236 -165
- package/dist/{default-detection-model-CDffuH2m.mjs → custom-model-catalog-DoOVE7kz.mjs} +225 -166
- package/dist/detection-pipeline/index.js +70 -104
- package/dist/detection-pipeline/index.mjs +18 -52
- package/dist/{dist-DJV7Z6Bb.js → dist-C7v30DMP.js} +69 -22
- package/dist/{dist-BsT15i7i.mjs → dist-Dn3knu_K.mjs} +69 -22
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-CkmucLYG.js → node-DWdekhW3.js} +1 -1
- package/dist/{node-Crsi_8ea.mjs → node-_BruMF4L.mjs} +1 -1
- package/dist/pipeline-runner/index.js +228 -42
- package/dist/pipeline-runner/index.mjs +206 -20
- package/dist/{process-memory-BJb7Ihdp.js → process-memory-CaDpfUdM.js} +1 -1
- package/dist/{process-memory-1mAUV8S1.mjs → process-memory-Dp-4bFOp.mjs} +1 -1
- package/dist/recorder/index.js +2 -2
- package/dist/recorder/index.mjs +2 -2
- package/dist/{segment-demux-js-B_tboBcJ.mjs → segment-demux-js-B_-zBECg.mjs} +1 -1
- package/dist/{segment-demux-js-mK9IBGLf.js → segment-demux-js-BqPTLFZG.js} +1 -1
- package/dist/stream-broker/_stub.js +1 -1
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CC0JSUlW.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BP8FFU2i.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CpjKK9II.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-Bw8lUr35.mjs → hostInit-BEh-hm1x.mjs} +2 -2
- package/dist/stream-broker/index.js +33 -3
- package/dist/stream-broker/index.mjs +33 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +1 -1
- 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/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-C7v30DMP.js");
|
|
7
|
+
const require_node = require("../node-DWdekhW3.js");
|
|
8
|
+
const require_custom_model_catalog = require("../custom-model-catalog-CVeosmYm.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).
|
|
@@ -2004,31 +2156,62 @@ var ROOT_SUPPLY_ROOT_STEP_ID = "object-detection";
|
|
|
2004
2156
|
var PACKAGE_STEP_ID = "package-detection";
|
|
2005
2157
|
var PACKAGE_THRESHOLD_KEY = "minConfidencePackage";
|
|
2006
2158
|
var EMPTY_ROOT_SUPPLY_PLAN = { states: /* @__PURE__ */ new Map() };
|
|
2007
|
-
|
|
2159
|
+
/** The step `addonId` when it is in the tree AND switched on — the per-camera gate's answer. */
|
|
2160
|
+
function findEnabledStep(steps, addonId) {
|
|
2008
2161
|
for (const step of steps) {
|
|
2162
|
+
if (step.enabled === false) continue;
|
|
2009
2163
|
if (step.addonId === addonId) return step;
|
|
2010
|
-
const nested = step.children !== void 0 ?
|
|
2164
|
+
const nested = step.children !== void 0 ? findEnabledStep(step.children, addonId) : void 0;
|
|
2011
2165
|
if (nested !== void 0) return nested;
|
|
2012
2166
|
}
|
|
2013
2167
|
}
|
|
2014
2168
|
/**
|
|
2015
|
-
*
|
|
2016
|
-
*
|
|
2017
|
-
*
|
|
2169
|
+
* The model an UNPINNED root runs on the elected device — the executor's own
|
|
2170
|
+
* rule (`resolveDefaultDetectionModel` on the device's backend, accelerator and
|
|
2171
|
+
* format), so the supplies are read off the model that really runs. Before
|
|
2172
|
+
* this, an unpinned root was judged as the step's flat `defaultModelId`
|
|
2173
|
+
* (`yolo26n`) on every accelerator, while an Intel GPU ran `yolov9m-320-int8`
|
|
2174
|
+
* and a Coral an SSD: `filledBy` named a model that was not running, and a
|
|
2175
|
+
* crop supply's input-size gate (D731) measured the wrong model. No elected
|
|
2176
|
+
* device (the runner's default pool) or an unknown backend ⇒ the flat default.
|
|
2177
|
+
*/
|
|
2178
|
+
function unpinnedRootModelId(deviceKey, flatDefault) {
|
|
2179
|
+
if (deviceKey === void 0) return flatDefault;
|
|
2180
|
+
try {
|
|
2181
|
+
const engine = require_custom_model_catalog.resolveDeviceEngine(deviceKey);
|
|
2182
|
+
return require_custom_model_catalog.resolveDefaultDetectionModel(engine.backend, engine.device ?? null, engine.format);
|
|
2183
|
+
} catch {
|
|
2184
|
+
return flatDefault;
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
/**
|
|
2188
|
+
* Plan a camera's root supplies from its configured tree.
|
|
2189
|
+
*
|
|
2190
|
+
* - The root's model is the one the executor runs: its pin, else the
|
|
2191
|
+
* hardware-aware default of the elected device (`deviceKey`).
|
|
2192
|
+
* - Only a step the camera RUNS is planned. A suppliable step that is absent
|
|
2193
|
+
* from the tree or switched off (the per-camera gate) has no state: the
|
|
2194
|
+
* operator switched that function off, so the root's labels are not made
|
|
2195
|
+
* authoritative for it, its root child boxes are removed, and nothing logs
|
|
2196
|
+
* that the root "supplies" it. Before this, a camera whose classifiers were
|
|
2197
|
+
* gated OFF logged `root model supplies a pipeline step` for both of them
|
|
2198
|
+
* and raised the root's labels to the detection score anyway (D736).
|
|
2018
2199
|
*/
|
|
2019
|
-
function planRootSupplies(steps, resolveModel) {
|
|
2200
|
+
function planRootSupplies(steps, resolveModel, deviceKey) {
|
|
2020
2201
|
if (steps === void 0) return EMPTY_ROOT_SUPPLY_PLAN;
|
|
2021
2202
|
const root = steps.find((s) => s.addonId === "object-detection" && s.enabled !== false);
|
|
2022
2203
|
if (root === void 0) return EMPTY_ROOT_SUPPLY_PLAN;
|
|
2023
|
-
const definition =
|
|
2024
|
-
const rootModelId = root.modelId ?? definition.defaultModelId;
|
|
2204
|
+
const definition = require_custom_model_catalog.getStepDefinition(ROOT_SUPPLY_ROOT_STEP_ID);
|
|
2205
|
+
const rootModelId = root.modelId ?? unpinnedRootModelId(deviceKey, definition.defaultModelId);
|
|
2025
2206
|
const supplies = require_dist.rootSuppliesOf(resolveModel(ROOT_SUPPLY_ROOT_STEP_ID, rootModelId), {
|
|
2026
2207
|
labels: definition.labels ?? [],
|
|
2027
2208
|
...definition.classMap !== void 0 ? { classMap: definition.classMap } : {}
|
|
2028
2209
|
});
|
|
2029
2210
|
const states = /* @__PURE__ */ new Map();
|
|
2030
2211
|
for (const stepId of require_dist.ROOT_SUPPLIABLE_STEP_IDS) {
|
|
2031
|
-
const
|
|
2212
|
+
const step = findEnabledStep(steps, stepId);
|
|
2213
|
+
if (step === void 0) continue;
|
|
2214
|
+
const settings = step.settings;
|
|
2032
2215
|
states.set(stepId, {
|
|
2033
2216
|
...require_dist.resolveRootSupply(stepId, settings, supplies),
|
|
2034
2217
|
...settings !== void 0 ? { settings } : {}
|
|
@@ -2043,7 +2226,7 @@ function planRootSupplies(steps, resolveModel) {
|
|
|
2043
2226
|
function suppliedSteps(plan) {
|
|
2044
2227
|
const out = /* @__PURE__ */ new Map();
|
|
2045
2228
|
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, {
|
|
2229
|
+
for (const [stepId, state] of plan.states) if (state.effective && state.supply !== void 0 && state.supply.kind !== "mask") out.set(stepId, {
|
|
2047
2230
|
modelId: plan.rootModelId,
|
|
2048
2231
|
kind: state.supply.kind
|
|
2049
2232
|
});
|
|
@@ -2121,7 +2304,7 @@ function applyRootSupplyAuthority(result, plan) {
|
|
|
2121
2304
|
}
|
|
2122
2305
|
/** The root step's schema default for its class allow-list. */
|
|
2123
2306
|
function rootDefaultMacroClasses() {
|
|
2124
|
-
const field =
|
|
2307
|
+
const field = require_custom_model_catalog.getStep(ROOT_SUPPLY_ROOT_STEP_ID).getConfigSchema().find((f) => "key" in f && f.key === "enabledMacroClasses");
|
|
2125
2308
|
const value = field !== void 0 && "default" in field ? field.default : void 0;
|
|
2126
2309
|
return Array.isArray(value) ? value : [];
|
|
2127
2310
|
}
|
|
@@ -3363,7 +3546,7 @@ var FaceOutsideParentLog = class {
|
|
|
3363
3546
|
*/
|
|
3364
3547
|
/** The face detector's input side for the step as it will run. */
|
|
3365
3548
|
function detectorInputPx(step) {
|
|
3366
|
-
const def =
|
|
3549
|
+
const def = require_custom_model_catalog.getStepDefinition(step.addonId);
|
|
3367
3550
|
const modelId = step.modelId ?? def.defaultModelId;
|
|
3368
3551
|
return def.models.find((m) => m.id === modelId)?.inputSize.width ?? 160;
|
|
3369
3552
|
}
|
|
@@ -3474,7 +3657,7 @@ async function refineRootFace(deps, input, supplied, step, requested, deviceKey)
|
|
|
3474
3657
|
}
|
|
3475
3658
|
const chain = requested === void 0 ? step : pruneChildStepsToRequested(step, requested);
|
|
3476
3659
|
if (chain.children === void 0 || chain.children.length === 0) return [toDetailResult(face, step.addonId, crop)];
|
|
3477
|
-
const modelId = step.modelId ??
|
|
3660
|
+
const modelId = step.modelId ?? require_custom_model_catalog.getStepDefinition(step.addonId).defaultModelId;
|
|
3478
3661
|
const embedded = await deps.runPipeline([chain], crop.jpeg, input.deviceId, deviceKey, nativeCropRef, refinedAsSupplied(face, step.addonId, modelId));
|
|
3479
3662
|
if (embedded === null) return [toDetailResult(face, step.addonId, crop)];
|
|
3480
3663
|
return embedded.detections.map((d) => toDetailResult(d, step.addonId, crop));
|
|
@@ -7438,7 +7621,7 @@ function writeRetainedDetectionFrame(store, deviceId, frame, retention) {
|
|
|
7438
7621
|
if (retention) return retention.admitFrame(deviceId, frame);
|
|
7439
7622
|
if (!store) return void 0;
|
|
7440
7623
|
if (!isContinuousRetainEnabled()) return store.allocateHandle(deviceId, frame) ?? void 0;
|
|
7441
|
-
return store.write(deviceId, frame, frame.frameRef ? createRetainedContentFallback(
|
|
7624
|
+
return store.write(deviceId, frame, frame.frameRef ? createRetainedContentFallback(require_custom_model_catalog.localFrameRegistry, frame.frameRef) : void 0) ?? void 0;
|
|
7442
7625
|
}
|
|
7443
7626
|
/**
|
|
7444
7627
|
* Occupancy-burst safety timeout (both the dial path and the analyzer-tap
|
|
@@ -7555,7 +7738,7 @@ function collectEnabledStepIds(steps, acc) {
|
|
|
7555
7738
|
*/
|
|
7556
7739
|
function tryGetStepDefinition(stepId) {
|
|
7557
7740
|
try {
|
|
7558
|
-
return
|
|
7741
|
+
return require_custom_model_catalog.getStepDefinition(stepId);
|
|
7559
7742
|
} catch {
|
|
7560
7743
|
return null;
|
|
7561
7744
|
}
|
|
@@ -8121,7 +8304,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
8121
8304
|
});
|
|
8122
8305
|
this.retention = new OnDemandRetentionSession({
|
|
8123
8306
|
store: this.retainedFrames,
|
|
8124
|
-
registry:
|
|
8307
|
+
registry: require_custom_model_catalog.localFrameRegistry,
|
|
8125
8308
|
telemetry: this.frameLazy,
|
|
8126
8309
|
nodeId: this.nodeId,
|
|
8127
8310
|
continuousRetain: isContinuousRetainEnabled()
|
|
@@ -8139,7 +8322,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
8139
8322
|
minThrottledFps: this.config.minThrottledFps,
|
|
8140
8323
|
processFrame: (deviceId, frame, handle) => this.runInference(deviceId, frame, handle),
|
|
8141
8324
|
analyzeMotion: (deviceId, frame, handle) => this.runMotionAnalysis(deviceId, frame, handle),
|
|
8142
|
-
releaseFrameRef: (ref, reason) =>
|
|
8325
|
+
releaseFrameRef: (ref, reason) => require_custom_model_catalog.localFrameRegistry.release(ref, reason),
|
|
8143
8326
|
releaseRetention: (handle, reason) => {
|
|
8144
8327
|
this.retention?.release(handle, reason);
|
|
8145
8328
|
this.frameCutters.drop(handle);
|
|
@@ -9085,7 +9268,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9085
9268
|
detectionMode: config.detectionMode,
|
|
9086
9269
|
...config.detectionSources !== void 0 ? { detectionSources: config.detectionSources } : {},
|
|
9087
9270
|
...config.sessionTrigger !== void 0 ? { sessionTrigger: config.sessionTrigger } : {},
|
|
9088
|
-
...
|
|
9271
|
+
...require_custom_model_catalog.rootObjectGate(config.steps) !== void 0 ? { objectGate: require_custom_model_catalog.rootObjectGate(config.steps) } : {},
|
|
9089
9272
|
fps: config.detectionFps,
|
|
9090
9273
|
motionCooldownMs: config.motionCooldownMs,
|
|
9091
9274
|
occupancyRecheckEnabled: config.occupancyRecheckEnabled,
|
|
@@ -9484,7 +9667,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9484
9667
|
}
|
|
9485
9668
|
/** The evidence crop from the process-local lease, JPEG-encoded by the view. */
|
|
9486
9669
|
async encodeEvidenceFromLease(ref, entry) {
|
|
9487
|
-
const lease =
|
|
9670
|
+
const lease = require_custom_model_catalog.localFrameRegistry.acquire(ref);
|
|
9488
9671
|
if (!lease) return null;
|
|
9489
9672
|
let reason = "error";
|
|
9490
9673
|
try {
|
|
@@ -9574,7 +9757,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9574
9757
|
/** A 16×32 RGB view of `crop`: the lease when there is one, else the inline buffer. */
|
|
9575
9758
|
async readAppearanceView(frame, result, crop) {
|
|
9576
9759
|
if (frame.frameRef !== void 0) {
|
|
9577
|
-
const lease =
|
|
9760
|
+
const lease = require_custom_model_catalog.localFrameRegistry.acquire(frame.frameRef);
|
|
9578
9761
|
if (lease) {
|
|
9579
9762
|
let reason = "error";
|
|
9580
9763
|
try {
|
|
@@ -9920,12 +10103,13 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9920
10103
|
* Refreshed on the async boundaries (`runInference`, `runDetailSubtree`),
|
|
9921
10104
|
* read synchronously by the placement.
|
|
9922
10105
|
*/
|
|
9923
|
-
customModels = new
|
|
10106
|
+
customModels = new require_custom_model_catalog.CustomModelCatalog({ warn: (message, extras) => this.ctxIfReady?.logger.warn(message, extras) });
|
|
9924
10107
|
/**
|
|
9925
10108
|
* Per camera, the root-supply plan (D730) and the announce derived from it,
|
|
9926
10109
|
* keyed on the two inputs it reads: the attach tree and the custom-model
|
|
9927
|
-
* snapshot (a Frigate+ root is a custom model)
|
|
9928
|
-
*
|
|
10110
|
+
* snapshot (a Frigate+ root is a custom model), plus the elected device
|
|
10111
|
+
* whose default an unpinned root runs. Recomputed when any changes — at
|
|
10112
|
+
* most once per catalog refresh.
|
|
9929
10113
|
*/
|
|
9930
10114
|
rootSupplyCache = /* @__PURE__ */ new Map();
|
|
9931
10115
|
/**
|
|
@@ -9934,14 +10118,15 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9934
10118
|
* animal and vehicle classifiers by default, and that must be readable per
|
|
9935
10119
|
* camera rather than inferred from a missing dispatch (D391).
|
|
9936
10120
|
*/
|
|
9937
|
-
rootSupplyPlanFor(deviceId, steps) {
|
|
10121
|
+
rootSupplyPlanFor(deviceId, steps, deviceKey) {
|
|
9938
10122
|
const byStep = this.customModels.current();
|
|
9939
10123
|
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));
|
|
10124
|
+
if (cached !== void 0 && cached.steps === steps && cached.deviceKey === deviceKey && cached.byStep === byStep) return cached.plan;
|
|
10125
|
+
const plan = planRootSupplies(steps, (stepId, modelId) => this.customModels.stepDefinition(stepId)?.models.find((m) => m.id === modelId), deviceKey);
|
|
9942
10126
|
const announces = deriveDetailSteps(steps, plan);
|
|
9943
10127
|
this.rootSupplyCache.set(deviceId, {
|
|
9944
10128
|
steps,
|
|
10129
|
+
deviceKey,
|
|
9945
10130
|
byStep,
|
|
9946
10131
|
plan,
|
|
9947
10132
|
announces
|
|
@@ -10084,7 +10269,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
10084
10269
|
* the elected pool pre-warms, D657) read. Pure: nothing is logged here.
|
|
10085
10270
|
*/
|
|
10086
10271
|
placementOf(config, step, attachedByKey) {
|
|
10087
|
-
return
|
|
10272
|
+
return require_custom_model_catalog.placeDetailStep({
|
|
10088
10273
|
step,
|
|
10089
10274
|
effectiveDeviceKey: config?.deviceKey,
|
|
10090
10275
|
roster: config?.inferenceDevices,
|
|
@@ -10106,7 +10291,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
10106
10291
|
return steps;
|
|
10107
10292
|
}
|
|
10108
10293
|
const attachedByKey = this.perDeviceAttachedCounts();
|
|
10109
|
-
const result =
|
|
10294
|
+
const result = require_custom_model_catalog.stepsForElectedPool(steps, isDetailPlaneStepId, (step) => this.placementOf(config, step, attachedByKey));
|
|
10110
10295
|
this.noteElectedPoolDelegation(deviceId, config.deviceKey, result.delegated);
|
|
10111
10296
|
return result.delegated.length === 0 ? steps : result.steps;
|
|
10112
10297
|
}
|
|
@@ -10797,7 +10982,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
10797
10982
|
return materialize;
|
|
10798
10983
|
},
|
|
10799
10984
|
...useLocalFrameRef ? {
|
|
10800
|
-
frameRegistry:
|
|
10985
|
+
frameRegistry: require_custom_model_catalog.localFrameRegistry,
|
|
10801
10986
|
inlineWhen: () => runner.detectionBackpressure(config.deviceId),
|
|
10802
10987
|
inlineViewSpec: SPLIT_DETECTION_VIEW,
|
|
10803
10988
|
onFrameRef: async (frame, nativeCrop) => {
|
|
@@ -10817,7 +11002,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
10817
11002
|
const admitted = current.detection && (frame.preRoll === true ? runner.enqueuePreRollFrame(config.deviceId, frame, handle) : runner.enqueueReservedDetectionFrame(config.deviceId, frame, handle));
|
|
10818
11003
|
if (admitted) nativeCrop?.markInferred();
|
|
10819
11004
|
if (current.motion) {
|
|
10820
|
-
const motion = await resolveMotionFrameView(
|
|
11005
|
+
const motion = await resolveMotionFrameView(require_custom_model_catalog.localFrameRegistry, frame.frameRef);
|
|
10821
11006
|
if (motion.kind === "view") runner.enqueueMotionFrame(config.deviceId, {
|
|
10822
11007
|
data: Buffer.from(motion.data),
|
|
10823
11008
|
width: motion.width,
|
|
@@ -11072,9 +11257,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11072
11257
|
return null;
|
|
11073
11258
|
}
|
|
11074
11259
|
if (steps.length === 0) return null;
|
|
11075
|
-
const rootSupplyPlan = this.rootSupplyPlanFor(deviceId, steps);
|
|
11260
|
+
const rootSupplyPlan = this.rootSupplyPlanFor(deviceId, steps, camConfig?.deviceKey);
|
|
11076
11261
|
const packageFill = applyPackageFill(steps, rootSupplyPlan);
|
|
11077
|
-
|
|
11262
|
+
const maskFill = applyMaskFill(packageFill.steps, rootSupplyPlan);
|
|
11263
|
+
let dispatchSteps = maskFill.steps;
|
|
11078
11264
|
if (dispatchSteps.some((s) => s.addonId === "package-detection" && s.enabled !== false)) {
|
|
11079
11265
|
this.refreshPackageZoneUnion(deviceId);
|
|
11080
11266
|
const motionInZone = this.lastMotionNearPackageZone.get(deviceId) ?? this.lastAnalyzerDetected.get(deviceId) ?? false;
|
|
@@ -11144,7 +11330,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11144
11330
|
});
|
|
11145
11331
|
} catch (err) {
|
|
11146
11332
|
const msg = require_dist.errMsg(err);
|
|
11147
|
-
if (
|
|
11333
|
+
if (require_custom_model_catalog.isSessionDecodeReadGone(err)) {
|
|
11148
11334
|
log.warn("runInference skipped — session decode frame gone", { meta: {
|
|
11149
11335
|
error: msg,
|
|
11150
11336
|
nodeId: this.nodeId,
|
|
@@ -11162,7 +11348,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11162
11348
|
return null;
|
|
11163
11349
|
}
|
|
11164
11350
|
if (result === null) return null;
|
|
11165
|
-
const looked = withPackageLook(applyRootSupplyAuthority(result, rootSupplyPlan), dispatchSteps, packageFill.filledByRoot);
|
|
11351
|
+
const looked = withPackageLook(applyRootMasks(applyRootSupplyAuthority(result, rootSupplyPlan), maskFill), dispatchSteps, packageFill.filledByRoot);
|
|
11166
11352
|
return this.recoverSmallSubjects(deviceId, frame, looked, dispatchSteps, camConfig?.deviceKey);
|
|
11167
11353
|
}
|
|
11168
11354
|
/**
|
|
@@ -11297,7 +11483,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11297
11483
|
* on a miss — the frame is gone, and the full-frame result stands.
|
|
11298
11484
|
*/
|
|
11299
11485
|
async resolveRecoveryCropView(ref, crop) {
|
|
11300
|
-
const lease =
|
|
11486
|
+
const lease = require_custom_model_catalog.localFrameRegistry.acquire(ref);
|
|
11301
11487
|
if (!lease) return null;
|
|
11302
11488
|
let reason = "error";
|
|
11303
11489
|
try {
|
|
@@ -11822,7 +12008,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
11822
12008
|
},
|
|
11823
12009
|
shouldMaterializeFrame: () => !admissionClosed,
|
|
11824
12010
|
...useLocalFrameRef ? {
|
|
11825
|
-
frameRegistry:
|
|
12011
|
+
frameRegistry: require_custom_model_catalog.localFrameRegistry,
|
|
11826
12012
|
inlineWhen: () => runner.detectionBackpressure(config.deviceId),
|
|
11827
12013
|
inlineViewSpec: SPLIT_DETECTION_VIEW,
|
|
11828
12014
|
onFrameRef: (frame, nativeCrop) => {
|