@camstack/addon-pipeline 1.2.73 → 1.2.74
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/audio-analyzer/index.js +1 -1
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +2 -2
- package/dist/detection-pipeline/index.mjs +2 -2
- package/dist/{dist-Dpr92hOt.mjs → dist-CKY0efl3.mjs} +1 -1
- package/dist/{dist-BAbvf81B.js → dist-CgJ8MRAy.js} +1 -1
- package/dist/{event-loop-stall-monitor-B7Wd2jo-.mjs → event-loop-stall-monitor-CIapFIez.mjs} +1 -1
- package/dist/{event-loop-stall-monitor-BhKoybot.js → event-loop-stall-monitor-Dx-zXcNg.js} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +106 -17
- package/dist/pipeline-runner/index.mjs +106 -17
- package/dist/recorder/index.js +1 -1
- package/dist/recorder/index.mjs +1 -1
- package/dist/session-decode/decode-worker-child.js +1 -1
- package/dist/session-decode/decode-worker-child.mjs +1 -1
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Cvh5La_s.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DVJ4gKkk.mjs} +1 -1
- package/dist/stream-broker/{hostInit-Ci7epN77.mjs → hostInit-5SFdfUyc.mjs} +1 -1
- package/dist/stream-broker/index.js +1 -1
- package/dist/stream-broker/index.mjs +1 -1
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-C1FtUWvH.mjs → worker-protocol-BzAQPUR-.mjs} +1 -1
- package/dist/{worker-protocol-BFq9AIDa.js → worker-protocol-D44DCkcs.js} +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ 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-
|
|
6
|
+
const require_dist = require("../dist-CgJ8MRAy.js");
|
|
7
7
|
const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
|
|
8
8
|
const require_addon_utils = require("../addon-utils-CQs-AjTJ.js");
|
|
9
9
|
let node_fs = require("node:fs");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as __require } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { B as mapAudioLabelToMacro, E as audioAnalyzerCapability, T as audioAnalysisCapability, ft as hydrateSchema, m as HF_BASE_URL, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG, st as BaseAddon, tt as errMsg } from "../dist-
|
|
2
|
+
import { B as mapAudioLabelToMacro, E as audioAnalyzerCapability, T as audioAnalysisCapability, ft as hydrateSchema, m as HF_BASE_URL, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG, st as BaseAddon, tt as errMsg } from "../dist-CKY0efl3.mjs";
|
|
3
3
|
import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
|
|
4
4
|
import { i as downloadFile } from "../addon-utils-CZ2xo67g.mjs";
|
|
5
5
|
import * as fs from "node:fs";
|
|
@@ -3,8 +3,8 @@ 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_event_loop_stall_monitor = require("../event-loop-stall-monitor-
|
|
6
|
+
const require_dist = require("../dist-CgJ8MRAy.js");
|
|
7
|
+
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-Dx-zXcNg.js");
|
|
8
8
|
const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
|
|
9
9
|
const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
|
|
10
10
|
const require_addon_utils = require("../addon-utils-CQs-AjTJ.js");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as __require } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { $ as supportedRuntimes$1, A as defaultDeviceFor$1, At as string, C as YAMNET_TO_MACRO, G as pipelineExecutorCapability, L as enumerateInferenceDevices, Mt as EventCategory, Ot as object, P as detectionPipelineCapability, R as evaluateZoneRules, St as array, X as runtimeDevices$1, _t as parseJsonUnknown, bt as sleep, dt as createEvent, ft as hydrateSchema, gt as nodePin, jt as union, st as BaseAddon, t as APPLE_SA_TO_MACRO, tt as errMsg, u as DEVICE_BACKEND_TO_FORMAT } from "../dist-
|
|
3
|
-
import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, n as startEventLoopStallMonitor, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep } from "../event-loop-stall-monitor-
|
|
2
|
+
import { $ as supportedRuntimes$1, A as defaultDeviceFor$1, At as string, C as YAMNET_TO_MACRO, G as pipelineExecutorCapability, L as enumerateInferenceDevices, Mt as EventCategory, Ot as object, P as detectionPipelineCapability, R as evaluateZoneRules, St as array, X as runtimeDevices$1, _t as parseJsonUnknown, bt as sleep, dt as createEvent, ft as hydrateSchema, gt as nodePin, jt as union, st as BaseAddon, t as APPLE_SA_TO_MACRO, tt as errMsg, u as DEVICE_BACKEND_TO_FORMAT } from "../dist-CKY0efl3.mjs";
|
|
3
|
+
import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, n as startEventLoopStallMonitor, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep } from "../event-loop-stall-monitor-CIapFIez.mjs";
|
|
4
4
|
import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
|
|
5
5
|
import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
|
|
6
6
|
import { a as ensureModel, o as isModelDownloaded, r as deleteModelFromDisk } from "../addon-utils-CZ2xo67g.mjs";
|
|
@@ -19194,7 +19194,7 @@ var detectionFpsField = {
|
|
|
19194
19194
|
var occupancyRecheckSecField = {
|
|
19195
19195
|
min: 0,
|
|
19196
19196
|
max: 300,
|
|
19197
|
-
default:
|
|
19197
|
+
default: 300,
|
|
19198
19198
|
step: 5
|
|
19199
19199
|
};
|
|
19200
19200
|
var occupancyRecheckFramesField = {
|
|
@@ -19194,7 +19194,7 @@ var detectionFpsField = {
|
|
|
19194
19194
|
var occupancyRecheckSecField = {
|
|
19195
19195
|
min: 0,
|
|
19196
19196
|
max: 300,
|
|
19197
|
-
default:
|
|
19197
|
+
default: 300,
|
|
19198
19198
|
step: 5
|
|
19199
19199
|
};
|
|
19200
19200
|
var occupancyRecheckFramesField = {
|
package/dist/{event-loop-stall-monitor-B7Wd2jo-.mjs → event-loop-stall-monitor-CIapFIez.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS, z as hfModelUrl } from "./dist-
|
|
1
|
+
import { a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS, z as hfModelUrl } from "./dist-CKY0efl3.mjs";
|
|
2
2
|
import { PerformanceObserver } from "node:perf_hooks";
|
|
3
3
|
//#region src/detection-pipeline/registry/model-catalogs.ts
|
|
4
4
|
var HF_REPO = "camstack/camstack-models";
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-CgJ8MRAy.js");
|
|
6
6
|
const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { H as motionDetectionCapability, R as evaluateZoneRules, ft as hydrateSchema, st as BaseAddon, ut as DeviceType } from "../dist-
|
|
1
|
+
import { H as motionDetectionCapability, R as evaluateZoneRules, ft as hydrateSchema, st as BaseAddon, ut as DeviceType } from "../dist-CKY0efl3.mjs";
|
|
2
2
|
import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -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_event_loop_stall_monitor = require("../event-loop-stall-monitor-
|
|
8
|
-
const require_worker_protocol = require("../worker-protocol-
|
|
6
|
+
const require_dist = require("../dist-CgJ8MRAy.js");
|
|
7
|
+
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-Dx-zXcNg.js");
|
|
8
|
+
const require_worker_protocol = require("../worker-protocol-D44DCkcs.js");
|
|
9
9
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
10
10
|
const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
|
|
11
11
|
const require_remote_restream = require("../remote-restream-BYbAsgUf.js");
|
|
@@ -3836,6 +3836,18 @@ function isUsable(bbox) {
|
|
|
3836
3836
|
}
|
|
3837
3837
|
//#endregion
|
|
3838
3838
|
//#region src/pipeline-runner/index.ts
|
|
3839
|
+
/**
|
|
3840
|
+
* Bound on the frames whose cutter is bound but whose result has not come back.
|
|
3841
|
+
* A few per camera in flight; the ceiling only catches results that never
|
|
3842
|
+
* arrive (shed, inference timeout, detach mid-flight).
|
|
3843
|
+
*/
|
|
3844
|
+
var MAX_BOUND_FRAME_CUTTERS = 256;
|
|
3845
|
+
/** How often a camera reports its undispatched cuts. */
|
|
3846
|
+
var TILE_CUT_DROP_LOG_INTERVAL_MS = 6e4;
|
|
3847
|
+
/** The per-frame binding key — the same identity the retention handle carries. */
|
|
3848
|
+
function frameCutterKey(handle) {
|
|
3849
|
+
return `${handle.shmId}#${handle.slot}#${handle.seq}`;
|
|
3850
|
+
}
|
|
3839
3851
|
var DEFAULT_CONFIG = {
|
|
3840
3852
|
maxQueueDepth: 30,
|
|
3841
3853
|
maxConcurrentInferences: 16,
|
|
@@ -4151,6 +4163,20 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
4151
4163
|
*/
|
|
4152
4164
|
nativeCropRegistry = new NativeCropRegistry();
|
|
4153
4165
|
/**
|
|
4166
|
+
* Per-frame cutter bindings — handle key → the requester that can cut this
|
|
4167
|
+
* frame's subject tiles and end its hold.
|
|
4168
|
+
*
|
|
4169
|
+
* Deliberately NOT `nativeCropRegistry`. That one is a node-wide LRU capped
|
|
4170
|
+
* at 256 and shared by every camera to serve LATE cross-process crops; on the
|
|
4171
|
+
* live hub it sits pinned at its cap, so an entry's lifetime depends on how
|
|
4172
|
+
* busy the OTHER cameras are. Ending a frame's hold is a per-frame lifecycle
|
|
4173
|
+
* event and cannot be allowed to depend on that.
|
|
4174
|
+
*/
|
|
4175
|
+
frameCutters = /* @__PURE__ */ new Map();
|
|
4176
|
+
/** Per-camera tally of cuts that could not be dispatched, and why. */
|
|
4177
|
+
tileCutDrops = /* @__PURE__ */ new Map();
|
|
4178
|
+
tileCutDropLoggedAt = /* @__PURE__ */ new Map();
|
|
4179
|
+
/**
|
|
4154
4180
|
* Node-level RAM store of retained rgb detection frames, keyed by the
|
|
4155
4181
|
* `FrameHandle` that rides the inference-result event (shm-ring removal
|
|
4156
4182
|
* 2026-07-16 — replaces the `csr.` shm retention ring). Backs the
|
|
@@ -5158,23 +5184,80 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
5158
5184
|
* by an encode.
|
|
5159
5185
|
*/
|
|
5160
5186
|
cutSubjectTiles(deviceId, result, handle) {
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5187
|
+
const outcome = this.dispatchSubjectTiles(result, handle);
|
|
5188
|
+
if (outcome === "sent") return;
|
|
5189
|
+
const tally = this.tileCutDrops.get(deviceId) ?? {
|
|
5190
|
+
handleless: 0,
|
|
5191
|
+
unbound: 0,
|
|
5192
|
+
threw: 0
|
|
5193
|
+
};
|
|
5194
|
+
tally[outcome] += 1;
|
|
5195
|
+
this.tileCutDrops.set(deviceId, tally);
|
|
5196
|
+
const now = Date.now();
|
|
5197
|
+
if (now - (this.tileCutDropLoggedAt.get(deviceId) ?? 0) < TILE_CUT_DROP_LOG_INTERVAL_MS) return;
|
|
5198
|
+
this.tileCutDropLoggedAt.set(deviceId, now);
|
|
5199
|
+
this.ctx.logger.warn("subject tile cut NOT dispatched — the frame hold will not be released", {
|
|
5200
|
+
tags: { deviceId },
|
|
5201
|
+
meta: {
|
|
5202
|
+
...tally,
|
|
5203
|
+
lastReason: outcome,
|
|
5204
|
+
boundFrames: this.frameCutters.size
|
|
5205
|
+
}
|
|
5206
|
+
});
|
|
5207
|
+
}
|
|
5208
|
+
/**
|
|
5209
|
+
* Send the cut for one finished frame. Returns what happened, so the caller
|
|
5210
|
+
* can account for it.
|
|
5211
|
+
*
|
|
5212
|
+
* The cutter is looked up in {@link frameCutters} — the addon's OWN per-frame
|
|
5213
|
+
* binding — and NOT in `nativeCropRegistry`. That distinction is the bug this
|
|
5214
|
+
* method exists to not have again: the registry is a node-wide LRU capped at
|
|
5215
|
+
* 256 entries, shared by every camera, and it exists to serve LATE
|
|
5216
|
+
* cross-process crops. Measured on the live hub during the incident it sits
|
|
5217
|
+
* PINNED at `registrySize=256 registryCap=256`, so an entry's lifetime is a
|
|
5218
|
+
* function of how many other cameras are busy. Ending a frame's hold is a
|
|
5219
|
+
* per-frame lifecycle event and must never be subject to another camera's
|
|
5220
|
+
* eviction pressure.
|
|
5221
|
+
*/
|
|
5222
|
+
dispatchSubjectTiles(result, handle) {
|
|
5223
|
+
if (!handle) return "handleless";
|
|
5224
|
+
const key = frameCutterKey(handle);
|
|
5225
|
+
const cutter = this.frameCutters.get(key);
|
|
5226
|
+
this.frameCutters.delete(key);
|
|
5227
|
+
if (!cutter) return "unbound";
|
|
5164
5228
|
const boxes = planTileCuts(result.detections ?? [], {
|
|
5165
5229
|
width: result.width,
|
|
5166
5230
|
height: result.height
|
|
5167
5231
|
});
|
|
5168
5232
|
try {
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5233
|
+
cutter.cutTiles(boxes);
|
|
5234
|
+
return "sent";
|
|
5235
|
+
} catch {
|
|
5236
|
+
return "threw";
|
|
5237
|
+
}
|
|
5238
|
+
}
|
|
5239
|
+
/**
|
|
5240
|
+
* Bind a frame's cutter at DELIVERY, so its result can end its hold.
|
|
5241
|
+
*
|
|
5242
|
+
* Bounded by {@link MAX_BOUND_FRAME_CUTTERS}: a frame whose result never
|
|
5243
|
+
* comes back (a shed, a timed-out inference, a camera detaching mid-flight)
|
|
5244
|
+
* would otherwise leave its binding forever. The oldest is dropped and its
|
|
5245
|
+
* hold released directly — the worker's own frame bound would have reclaimed
|
|
5246
|
+
* it anyway, but releasing here is what keeps `holdOverflow` meaning "the
|
|
5247
|
+
* runner stopped answering" rather than "the runner forgot".
|
|
5248
|
+
*/
|
|
5249
|
+
bindFrameCutter(handle, cutter) {
|
|
5250
|
+
const key = frameCutterKey(handle);
|
|
5251
|
+
this.frameCutters.delete(key);
|
|
5252
|
+
this.frameCutters.set(key, cutter);
|
|
5253
|
+
while (this.frameCutters.size > MAX_BOUND_FRAME_CUTTERS) {
|
|
5254
|
+
const oldest = this.frameCutters.keys().next().value;
|
|
5255
|
+
if (oldest === void 0) break;
|
|
5256
|
+
const stale = this.frameCutters.get(oldest);
|
|
5257
|
+
this.frameCutters.delete(oldest);
|
|
5258
|
+
try {
|
|
5259
|
+
stale?.release();
|
|
5260
|
+
} catch {}
|
|
5178
5261
|
}
|
|
5179
5262
|
}
|
|
5180
5263
|
/**
|
|
@@ -5973,7 +6056,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
5973
6056
|
reservation = null;
|
|
5974
6057
|
if (!current) return;
|
|
5975
6058
|
const handle = current.detection ? retainedFrames?.write(config.deviceId, frame) ?? void 0 : void 0;
|
|
5976
|
-
if (handle && nativeCrop)
|
|
6059
|
+
if (handle && nativeCrop) {
|
|
6060
|
+
this.nativeCropRegistry.register(handle, nativeCrop, config.deviceId);
|
|
6061
|
+
this.bindFrameCutter(handle, nativeCrop);
|
|
6062
|
+
}
|
|
5977
6063
|
if (this.enqueueSharedDetectionFrame(config.deviceId, frame, handle, current)) nativeCrop?.markInferred();
|
|
5978
6064
|
}
|
|
5979
6065
|
});
|
|
@@ -6497,7 +6583,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
6497
6583
|
onDecodedFrame: (frame, nativeCrop) => {
|
|
6498
6584
|
if (settled) return;
|
|
6499
6585
|
const handle = retainedFrames?.write(config.deviceId, frame) ?? void 0;
|
|
6500
|
-
if (handle && nativeCrop)
|
|
6586
|
+
if (handle && nativeCrop) {
|
|
6587
|
+
this.nativeCropRegistry.register(handle, nativeCrop, config.deviceId);
|
|
6588
|
+
this.bindFrameCutter(handle, nativeCrop);
|
|
6589
|
+
}
|
|
6501
6590
|
if (runner.enqueueOccupancyFrame(deviceId, frame, handle)) nativeCrop?.markInferred();
|
|
6502
6591
|
count++;
|
|
6503
6592
|
if (count >= frames) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { At as string, Ct as boolean, Dt as number, Et as literal, K as pipelineRunnerCapability, M as deriveDetailCropRect, Mt as EventCategory, Ot as object, St as array, Tt as lazy, U as pickDetailCropConvention, W as pickNativeLeaseOverride, dt as createEvent, gt as nodePin, j as defineCustomActions, k as customAction, s as DEFAULT_DETAIL_CROP_CONVENTION, st as BaseAddon, tt as errMsg, u as DEVICE_BACKEND_TO_FORMAT, xt as _enum } from "../dist-
|
|
2
|
-
import { c as getStepDefinition, t as attributeStall } from "../event-loop-stall-monitor-
|
|
3
|
-
import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-
|
|
1
|
+
import { At as string, Ct as boolean, Dt as number, Et as literal, K as pipelineRunnerCapability, M as deriveDetailCropRect, Mt as EventCategory, Ot as object, St as array, Tt as lazy, U as pickDetailCropConvention, W as pickNativeLeaseOverride, dt as createEvent, gt as nodePin, j as defineCustomActions, k as customAction, s as DEFAULT_DETAIL_CROP_CONVENTION, st as BaseAddon, tt as errMsg, u as DEVICE_BACKEND_TO_FORMAT, xt as _enum } from "../dist-CKY0efl3.mjs";
|
|
2
|
+
import { c as getStepDefinition, t as attributeStall } from "../event-loop-stall-monitor-CIapFIez.mjs";
|
|
3
|
+
import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-BzAQPUR-.mjs";
|
|
4
4
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
5
5
|
import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
|
|
6
6
|
import { i as withDetectionIntent, n as profileForStreamId, t as isRemoteRestream } from "../remote-restream-Ci7RXNGb.mjs";
|
|
@@ -3828,6 +3828,18 @@ function isUsable(bbox) {
|
|
|
3828
3828
|
}
|
|
3829
3829
|
//#endregion
|
|
3830
3830
|
//#region src/pipeline-runner/index.ts
|
|
3831
|
+
/**
|
|
3832
|
+
* Bound on the frames whose cutter is bound but whose result has not come back.
|
|
3833
|
+
* A few per camera in flight; the ceiling only catches results that never
|
|
3834
|
+
* arrive (shed, inference timeout, detach mid-flight).
|
|
3835
|
+
*/
|
|
3836
|
+
var MAX_BOUND_FRAME_CUTTERS = 256;
|
|
3837
|
+
/** How often a camera reports its undispatched cuts. */
|
|
3838
|
+
var TILE_CUT_DROP_LOG_INTERVAL_MS = 6e4;
|
|
3839
|
+
/** The per-frame binding key — the same identity the retention handle carries. */
|
|
3840
|
+
function frameCutterKey(handle) {
|
|
3841
|
+
return `${handle.shmId}#${handle.slot}#${handle.seq}`;
|
|
3842
|
+
}
|
|
3831
3843
|
var DEFAULT_CONFIG = {
|
|
3832
3844
|
maxQueueDepth: 30,
|
|
3833
3845
|
maxConcurrentInferences: 16,
|
|
@@ -4143,6 +4155,20 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
4143
4155
|
*/
|
|
4144
4156
|
nativeCropRegistry = new NativeCropRegistry();
|
|
4145
4157
|
/**
|
|
4158
|
+
* Per-frame cutter bindings — handle key → the requester that can cut this
|
|
4159
|
+
* frame's subject tiles and end its hold.
|
|
4160
|
+
*
|
|
4161
|
+
* Deliberately NOT `nativeCropRegistry`. That one is a node-wide LRU capped
|
|
4162
|
+
* at 256 and shared by every camera to serve LATE cross-process crops; on the
|
|
4163
|
+
* live hub it sits pinned at its cap, so an entry's lifetime depends on how
|
|
4164
|
+
* busy the OTHER cameras are. Ending a frame's hold is a per-frame lifecycle
|
|
4165
|
+
* event and cannot be allowed to depend on that.
|
|
4166
|
+
*/
|
|
4167
|
+
frameCutters = /* @__PURE__ */ new Map();
|
|
4168
|
+
/** Per-camera tally of cuts that could not be dispatched, and why. */
|
|
4169
|
+
tileCutDrops = /* @__PURE__ */ new Map();
|
|
4170
|
+
tileCutDropLoggedAt = /* @__PURE__ */ new Map();
|
|
4171
|
+
/**
|
|
4146
4172
|
* Node-level RAM store of retained rgb detection frames, keyed by the
|
|
4147
4173
|
* `FrameHandle` that rides the inference-result event (shm-ring removal
|
|
4148
4174
|
* 2026-07-16 — replaces the `csr.` shm retention ring). Backs the
|
|
@@ -5150,23 +5176,80 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
5150
5176
|
* by an encode.
|
|
5151
5177
|
*/
|
|
5152
5178
|
cutSubjectTiles(deviceId, result, handle) {
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5179
|
+
const outcome = this.dispatchSubjectTiles(result, handle);
|
|
5180
|
+
if (outcome === "sent") return;
|
|
5181
|
+
const tally = this.tileCutDrops.get(deviceId) ?? {
|
|
5182
|
+
handleless: 0,
|
|
5183
|
+
unbound: 0,
|
|
5184
|
+
threw: 0
|
|
5185
|
+
};
|
|
5186
|
+
tally[outcome] += 1;
|
|
5187
|
+
this.tileCutDrops.set(deviceId, tally);
|
|
5188
|
+
const now = Date.now();
|
|
5189
|
+
if (now - (this.tileCutDropLoggedAt.get(deviceId) ?? 0) < TILE_CUT_DROP_LOG_INTERVAL_MS) return;
|
|
5190
|
+
this.tileCutDropLoggedAt.set(deviceId, now);
|
|
5191
|
+
this.ctx.logger.warn("subject tile cut NOT dispatched — the frame hold will not be released", {
|
|
5192
|
+
tags: { deviceId },
|
|
5193
|
+
meta: {
|
|
5194
|
+
...tally,
|
|
5195
|
+
lastReason: outcome,
|
|
5196
|
+
boundFrames: this.frameCutters.size
|
|
5197
|
+
}
|
|
5198
|
+
});
|
|
5199
|
+
}
|
|
5200
|
+
/**
|
|
5201
|
+
* Send the cut for one finished frame. Returns what happened, so the caller
|
|
5202
|
+
* can account for it.
|
|
5203
|
+
*
|
|
5204
|
+
* The cutter is looked up in {@link frameCutters} — the addon's OWN per-frame
|
|
5205
|
+
* binding — and NOT in `nativeCropRegistry`. That distinction is the bug this
|
|
5206
|
+
* method exists to not have again: the registry is a node-wide LRU capped at
|
|
5207
|
+
* 256 entries, shared by every camera, and it exists to serve LATE
|
|
5208
|
+
* cross-process crops. Measured on the live hub during the incident it sits
|
|
5209
|
+
* PINNED at `registrySize=256 registryCap=256`, so an entry's lifetime is a
|
|
5210
|
+
* function of how many other cameras are busy. Ending a frame's hold is a
|
|
5211
|
+
* per-frame lifecycle event and must never be subject to another camera's
|
|
5212
|
+
* eviction pressure.
|
|
5213
|
+
*/
|
|
5214
|
+
dispatchSubjectTiles(result, handle) {
|
|
5215
|
+
if (!handle) return "handleless";
|
|
5216
|
+
const key = frameCutterKey(handle);
|
|
5217
|
+
const cutter = this.frameCutters.get(key);
|
|
5218
|
+
this.frameCutters.delete(key);
|
|
5219
|
+
if (!cutter) return "unbound";
|
|
5156
5220
|
const boxes = planTileCuts(result.detections ?? [], {
|
|
5157
5221
|
width: result.width,
|
|
5158
5222
|
height: result.height
|
|
5159
5223
|
});
|
|
5160
5224
|
try {
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5225
|
+
cutter.cutTiles(boxes);
|
|
5226
|
+
return "sent";
|
|
5227
|
+
} catch {
|
|
5228
|
+
return "threw";
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
/**
|
|
5232
|
+
* Bind a frame's cutter at DELIVERY, so its result can end its hold.
|
|
5233
|
+
*
|
|
5234
|
+
* Bounded by {@link MAX_BOUND_FRAME_CUTTERS}: a frame whose result never
|
|
5235
|
+
* comes back (a shed, a timed-out inference, a camera detaching mid-flight)
|
|
5236
|
+
* would otherwise leave its binding forever. The oldest is dropped and its
|
|
5237
|
+
* hold released directly — the worker's own frame bound would have reclaimed
|
|
5238
|
+
* it anyway, but releasing here is what keeps `holdOverflow` meaning "the
|
|
5239
|
+
* runner stopped answering" rather than "the runner forgot".
|
|
5240
|
+
*/
|
|
5241
|
+
bindFrameCutter(handle, cutter) {
|
|
5242
|
+
const key = frameCutterKey(handle);
|
|
5243
|
+
this.frameCutters.delete(key);
|
|
5244
|
+
this.frameCutters.set(key, cutter);
|
|
5245
|
+
while (this.frameCutters.size > MAX_BOUND_FRAME_CUTTERS) {
|
|
5246
|
+
const oldest = this.frameCutters.keys().next().value;
|
|
5247
|
+
if (oldest === void 0) break;
|
|
5248
|
+
const stale = this.frameCutters.get(oldest);
|
|
5249
|
+
this.frameCutters.delete(oldest);
|
|
5250
|
+
try {
|
|
5251
|
+
stale?.release();
|
|
5252
|
+
} catch {}
|
|
5170
5253
|
}
|
|
5171
5254
|
}
|
|
5172
5255
|
/**
|
|
@@ -5965,7 +6048,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
5965
6048
|
reservation = null;
|
|
5966
6049
|
if (!current) return;
|
|
5967
6050
|
const handle = current.detection ? retainedFrames?.write(config.deviceId, frame) ?? void 0 : void 0;
|
|
5968
|
-
if (handle && nativeCrop)
|
|
6051
|
+
if (handle && nativeCrop) {
|
|
6052
|
+
this.nativeCropRegistry.register(handle, nativeCrop, config.deviceId);
|
|
6053
|
+
this.bindFrameCutter(handle, nativeCrop);
|
|
6054
|
+
}
|
|
5969
6055
|
if (this.enqueueSharedDetectionFrame(config.deviceId, frame, handle, current)) nativeCrop?.markInferred();
|
|
5970
6056
|
}
|
|
5971
6057
|
});
|
|
@@ -6489,7 +6575,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
6489
6575
|
onDecodedFrame: (frame, nativeCrop) => {
|
|
6490
6576
|
if (settled) return;
|
|
6491
6577
|
const handle = retainedFrames?.write(config.deviceId, frame) ?? void 0;
|
|
6492
|
-
if (handle && nativeCrop)
|
|
6578
|
+
if (handle && nativeCrop) {
|
|
6579
|
+
this.nativeCropRegistry.register(handle, nativeCrop, config.deviceId);
|
|
6580
|
+
this.bindFrameCutter(handle, nativeCrop);
|
|
6581
|
+
}
|
|
6493
6582
|
if (runner.enqueueOccupancyFrame(deviceId, frame, handle)) nativeCrop?.markInferred();
|
|
6494
6583
|
count++;
|
|
6495
6584
|
if (count >= frames) {
|
package/dist/recorder/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
2
|
-
const require_dist = require("../dist-
|
|
2
|
+
const require_dist = require("../dist-CgJ8MRAy.js");
|
|
3
3
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
4
4
|
const require_addon_utils = require("../addon-utils-CQs-AjTJ.js");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
package/dist/recorder/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { At as string, Dt as number, J as recordingExportCapability, Mt as EventCategory, N as deriveRecordingMode, Ot as object, St as array, Z as storageEvictableCapability, _ as OpsLogEntrySchema, b as RECORDING_EXPORT_MAX_READ_BYTES, c as DEFAULT_EVENTS_BAND_BUFFER_SEC, d as EVENT_PAD_MS, ft as hydrateSchema, gt as nodePin, kt as record, p as ExportRecordSchema, q as recordingCapability, st as BaseAddon, tt as errMsg, ut as DeviceType, x as RecordingConfigSchema, yt as selectAssignedProfileSlots } from "../dist-
|
|
1
|
+
import { At as string, Dt as number, J as recordingExportCapability, Mt as EventCategory, N as deriveRecordingMode, Ot as object, St as array, Z as storageEvictableCapability, _ as OpsLogEntrySchema, b as RECORDING_EXPORT_MAX_READ_BYTES, c as DEFAULT_EVENTS_BAND_BUFFER_SEC, d as EVENT_PAD_MS, ft as hydrateSchema, gt as nodePin, kt as record, p as ExportRecordSchema, q as recordingCapability, st as BaseAddon, tt as errMsg, ut as DeviceType, x as RecordingConfigSchema, yt as selectAssignedProfileSlots } from "../dist-CKY0efl3.mjs";
|
|
2
2
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
3
3
|
import { n as createFileDataPlaneHandler, s as parseRangeHeader, t as contentTypeFor } from "../addon-utils-CZ2xo67g.mjs";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
3
|
-
const require_worker_protocol = require("../worker-protocol-
|
|
3
|
+
const require_worker_protocol = require("../worker-protocol-D44DCkcs.js");
|
|
4
4
|
const require_lazy_sharp = require("../lazy-sharp-CcYuXtsa.js");
|
|
5
5
|
let node_url = require("node:url");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as formatNativeLeaseKnobs, n as isWorkerRequest, o as resolveNativeLeaseKnobs, r as logLevelForLine } from "../worker-protocol-
|
|
1
|
+
import { i as formatNativeLeaseKnobs, n as isWorkerRequest, o as resolveNativeLeaseKnobs, r as logLevelForLine } from "../worker-protocol-BzAQPUR-.mjs";
|
|
2
2
|
import { t as getSharp } from "../lazy-sharp-B-mb8uWx.mjs";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
import * as fs from "node:fs";
|
|
@@ -3,7 +3,7 @@ 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-
|
|
6
|
+
const require_dist = require("../dist-CgJ8MRAy.js");
|
|
7
7
|
const require_remote_restream = require("../remote-restream-BYbAsgUf.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
node_crypto = require_chunk.__toESM(node_crypto, 1);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as __toESM, t as __commonJSMin } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { At as string, Ct as boolean, D as cameraStreamsCapability, Dt as number, Et as literal, F as egressTranscodeSharingKey, I as egressTransportFromRequest, Mt as EventCategory, O as createHwAccelCache, Ot as object, Q as streamBrokerCapability, S as RingBuffer, St as array, V as maskUrlCredentials, Y as resolveEgressDecodeHwAccel, at as invocationFromEncodeProfile, ct as CAM_PROFILE_ORDER, dt as createEvent, et as webrtcSessionCapability, f as EncodeProfileSchema, gt as nodePin, ht as makeSourceBrokerId, it as buildFfmpegArgs$1, jt as union, kt as record, lt as DeviceFeature, mt as makeProfileBrokerId, nt as AUDIO_PRESETS, ot as isSoftwareDecode, pt as isEvent, rt as Fmp4BoxSplitter, st as BaseAddon, tt as errMsg, ut as DeviceType, v as RATE_CONTROL_RELAXED, vt as parseProfileBrokerId, w as addonWidgetsSourceCapability, wt as discriminatedUnion, xt as _enum, y as RATE_CONTROL_TIGHT } from "../dist-
|
|
2
|
+
import { At as string, Ct as boolean, D as cameraStreamsCapability, Dt as number, Et as literal, F as egressTranscodeSharingKey, I as egressTransportFromRequest, Mt as EventCategory, O as createHwAccelCache, Ot as object, Q as streamBrokerCapability, S as RingBuffer, St as array, V as maskUrlCredentials, Y as resolveEgressDecodeHwAccel, at as invocationFromEncodeProfile, ct as CAM_PROFILE_ORDER, dt as createEvent, et as webrtcSessionCapability, f as EncodeProfileSchema, gt as nodePin, ht as makeSourceBrokerId, it as buildFfmpegArgs$1, jt as union, kt as record, lt as DeviceFeature, mt as makeProfileBrokerId, nt as AUDIO_PRESETS, ot as isSoftwareDecode, pt as isEvent, rt as Fmp4BoxSplitter, st as BaseAddon, tt as errMsg, ut as DeviceType, v as RATE_CONTROL_RELAXED, vt as parseProfileBrokerId, w as addonWidgetsSourceCapability, wt as discriminatedUnion, xt as _enum, y as RATE_CONTROL_TIGHT } from "../dist-CKY0efl3.mjs";
|
|
3
3
|
import { n as profileForStreamId, r as parseRestreamPath } from "../remote-restream-Ci7RXNGb.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import * as crypto$1 from "node:crypto";
|
|
@@ -30,7 +30,7 @@ async function d(e) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async function f() {
|
|
33
|
-
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-
|
|
33
|
+
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DVJ4gKkk.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as NativeLeaseSettingsSchema, h as NativeLeaseAdmissionSchema, l as DEFAULT_NATIVE_LEASE_SETTINGS } from "./dist-
|
|
1
|
+
import { g as NativeLeaseSettingsSchema, h as NativeLeaseAdmissionSchema, l as DEFAULT_NATIVE_LEASE_SETTINGS } from "./dist-CKY0efl3.mjs";
|
|
2
2
|
//#region src/session-decode/native-lease-config.ts
|
|
3
3
|
/**
|
|
4
4
|
* Resolution of the native-frame hold / tile knobs for one decode worker.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-pipeline",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.74",
|
|
4
4
|
"description": "Pipeline bundle — runner, detection, motion, audio + stream broker. Multi-entry npm package shipping pipeline addons under a single bundle.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|