@camstack/addon-pipeline 1.2.75 → 1.2.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{addon-utils-a_36HH_N.js → addon-utils-CTpQfjSR.js} +1 -1
- package/dist/audio-analyzer/index.js +2 -2
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +4 -4
- package/dist/detection-pipeline/index.mjs +2 -2
- package/dist/{dist-6ZJCV0jY.js → dist-CZLjObZZ.js} +97 -3
- package/dist/{dist-T_8jMw7d.mjs → dist-zksfWnEA.mjs} +97 -3
- package/dist/{event-loop-stall-monitor-XeGmL4xr.mjs → event-loop-stall-monitor-BuZA3loB.mjs} +1 -1
- package/dist/{event-loop-stall-monitor-Cjof8vA1.js → event-loop-stall-monitor-CcBQAI28.js} +1 -1
- package/dist/{lazy-sharp-DvwPafeP.js → lazy-sharp-SWR_D1Um.js} +1 -1
- package/dist/motion-wasm/index.js +2 -2
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +278 -15
- package/dist/pipeline-runner/index.mjs +277 -14
- package/dist/recorder/index.js +2 -2
- package/dist/recorder/index.mjs +1 -1
- package/dist/session-decode/decode-worker-child.js +2 -2
- package/dist/session-decode/decode-worker-child.mjs +1 -1
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-H2OTmgR6.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Dd6XOtVn.mjs} +1 -1
- package/dist/stream-broker/{hostInit-4XDN_Nt0.mjs → hostInit-COc_Q_xX.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-B0cbTXyw.js → worker-protocol-DAQ1iZFK.js} +1 -1
- package/dist/{worker-protocol-SqED7Y9i.mjs → worker-protocol-DyX_HbaJ.mjs} +1 -1
- package/package.json +1 -1
|
@@ -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-zksfWnEA.mjs";
|
|
2
|
+
import { c as getStepDefinition, t as attributeStall } from "../event-loop-stall-monitor-BuZA3loB.mjs";
|
|
3
|
+
import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-DyX_HbaJ.mjs";
|
|
4
4
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
5
5
|
import { t as getSharp } from "../lazy-sharp-6oymT_yf.mjs";
|
|
6
6
|
import { i as withDetectionIntent, n as profileForStreamId, t as isRemoteRestream } from "../remote-restream-Ci7RXNGb.mjs";
|
|
@@ -2359,13 +2359,36 @@ function summarizeRunnerHardware(hardware, cpuCores = os.cpus().length) {
|
|
|
2359
2359
|
* just picked one up — which coincide with motion in the package zone
|
|
2360
2360
|
* SETTLING (transitioning from moving to still). This governor fires:
|
|
2361
2361
|
*
|
|
2362
|
-
* - on a **settle edge**: motion was observed, then has
|
|
2363
|
-
* `settleMs` (kills flicker between motion frames and the
|
|
2364
|
-
* set down then snatched back" case)
|
|
2362
|
+
* - on a **settle edge**: motion NEAR THE PACKAGE ZONE was observed, then has
|
|
2363
|
+
* been absent for `settleMs` (kills flicker between motion frames and the
|
|
2364
|
+
* "bag briefly set down then snatched back" case). The settle edge opens a
|
|
2365
|
+
* **BURST**, and
|
|
2365
2366
|
* - on a **low-cadence safety poll** (`pollIntervalMs`, ~30–60s): a
|
|
2366
2367
|
* backstop so a delivery whose motion was never observed (a session-gap
|
|
2367
2368
|
* camera that only decodes intermittently) is still eventually caught.
|
|
2368
2369
|
*
|
|
2370
|
+
* ## The burst, and why the poll alone was not enough
|
|
2371
|
+
*
|
|
2372
|
+
* A parcel appears at the END of a motion episode — the courier walks up, puts
|
|
2373
|
+
* it down, walks away. That is a settle edge, and it is the moment we know
|
|
2374
|
+
* something MIGHT have been left behind. So the settle edge does not fire one
|
|
2375
|
+
* inference, it opens a burst: `burstCount` runs `burstIntervalMs` apart.
|
|
2376
|
+
*
|
|
2377
|
+
* The poll alone made the downstream promotion criterion unreachable in
|
|
2378
|
+
* PRACTICE and the notification useless in LATENCY. One observation per 45s
|
|
2379
|
+
* (and on a session-dispatch camera the measured gap was ~2 minutes) meant a
|
|
2380
|
+
* parcel needed minutes to accumulate enough evidence to be called parked, if
|
|
2381
|
+
* it ever did. The burst supplies the whole evidence chain inside ~20s, so a
|
|
2382
|
+
* delivery is reported while the courier is still in the street.
|
|
2383
|
+
*
|
|
2384
|
+
* The poll stays, unchanged in role: it is the SAFETY NET for the parcel whose
|
|
2385
|
+
* motion was never observed at all — a camera that just came up, an occlusion,
|
|
2386
|
+
* a missed analyzer frame. It is not the primary path any more.
|
|
2387
|
+
*
|
|
2388
|
+
* The two feed the SAME downstream round counter (`PackageStillnessTracker`),
|
|
2389
|
+
* which is what lets one promotion criterion serve both cadences. That is the
|
|
2390
|
+
* relation `scripts/check-package-promotion-satisfiable.ts` enforces.
|
|
2391
|
+
*
|
|
2369
2392
|
* Pure logic with an injected clock (every method takes `now`), mirroring
|
|
2370
2393
|
* `FrameGovernor` / `recomputeGovernor(now)` — no timers, no `Date.now()`
|
|
2371
2394
|
* inside, fully unit-testable. Per-device state lives in a Map; the caller
|
|
@@ -2384,14 +2407,37 @@ function summarizeRunnerHardware(hardware, cpuCores = os.cpus().length) {
|
|
|
2384
2407
|
*/
|
|
2385
2408
|
/** The step id (`PipelineStepInput.addonId`) the governor gates. */
|
|
2386
2409
|
var PACKAGE_DETECTION_STEP_ID = "package-detection";
|
|
2410
|
+
/**
|
|
2411
|
+
* Burst: 5 runs, 5s apart — 0s, 5s, 10s, 15s, 20s after the settle edge.
|
|
2412
|
+
*
|
|
2413
|
+
* Sized against the two downstream numbers it has to satisfy, both pinned by
|
|
2414
|
+
* `scripts/check-package-promotion-satisfiable.ts`:
|
|
2415
|
+
*
|
|
2416
|
+
* - `PACKAGE_STILLNESS_ROUND_GAP_MS` (5 000) — the spacing must be ≥ this or
|
|
2417
|
+
* the runs collapse into one round;
|
|
2418
|
+
* - `packageDropDwellSec` (15s default) — the burst SPAN
|
|
2419
|
+
* (`(burstCount - 1) × burstIntervalMs` = 20s) must clear the dwell, or the
|
|
2420
|
+
* burst ends before the parcel has been still long enough to count and the
|
|
2421
|
+
* delivery falls back to the poll. 20s over 15s is one whole run of margin,
|
|
2422
|
+
* which is what absorbs a dropped analyzer frame.
|
|
2423
|
+
*
|
|
2424
|
+
* Cost: 5 extra inferences per motion episode, on cameras with an active
|
|
2425
|
+
* package zone only (the caller consults this governor only while the
|
|
2426
|
+
* `package-detection` step is in the camera's tree, and the resolver appends
|
|
2427
|
+
* that step only for an enabled `package`-stage zone rule).
|
|
2428
|
+
*/
|
|
2387
2429
|
var DEFAULT_MOTION_SETTLE_CONFIG = {
|
|
2388
2430
|
settleMs: 3e3,
|
|
2389
|
-
pollIntervalMs: 45e3
|
|
2431
|
+
pollIntervalMs: 45e3,
|
|
2432
|
+
burstCount: 5,
|
|
2433
|
+
burstIntervalMs: 5e3
|
|
2390
2434
|
};
|
|
2391
2435
|
var INITIAL_STATE = {
|
|
2392
2436
|
lastMotionAt: null,
|
|
2393
2437
|
armed: false,
|
|
2394
|
-
lastRunAt: Number.NEGATIVE_INFINITY
|
|
2438
|
+
lastRunAt: Number.NEGATIVE_INFINITY,
|
|
2439
|
+
burstRemaining: 0,
|
|
2440
|
+
burstNextAt: 0
|
|
2395
2441
|
};
|
|
2396
2442
|
var NO_RUN = {
|
|
2397
2443
|
run: false,
|
|
@@ -2417,18 +2463,35 @@ var MotionSettleGovernor = class {
|
|
|
2417
2463
|
this.state.set(sample.deviceId, {
|
|
2418
2464
|
lastMotionAt,
|
|
2419
2465
|
armed: false,
|
|
2420
|
-
lastRunAt: sample.now
|
|
2466
|
+
lastRunAt: sample.now,
|
|
2467
|
+
burstRemaining: Math.max(0, this.config.burstCount - 1),
|
|
2468
|
+
burstNextAt: sample.now + this.config.burstIntervalMs
|
|
2421
2469
|
});
|
|
2422
2470
|
return {
|
|
2423
2471
|
run: true,
|
|
2424
2472
|
reason: "settle"
|
|
2425
2473
|
};
|
|
2426
2474
|
}
|
|
2475
|
+
if (prev.burstRemaining > 0 && sample.now >= prev.burstNextAt) {
|
|
2476
|
+
this.state.set(sample.deviceId, {
|
|
2477
|
+
lastMotionAt,
|
|
2478
|
+
armed,
|
|
2479
|
+
lastRunAt: sample.now,
|
|
2480
|
+
burstRemaining: prev.burstRemaining - 1,
|
|
2481
|
+
burstNextAt: sample.now + this.config.burstIntervalMs
|
|
2482
|
+
});
|
|
2483
|
+
return {
|
|
2484
|
+
run: true,
|
|
2485
|
+
reason: "burst"
|
|
2486
|
+
};
|
|
2487
|
+
}
|
|
2427
2488
|
if (pollReady) {
|
|
2428
2489
|
this.state.set(sample.deviceId, {
|
|
2429
2490
|
lastMotionAt,
|
|
2430
2491
|
armed,
|
|
2431
|
-
lastRunAt: sample.now
|
|
2492
|
+
lastRunAt: sample.now,
|
|
2493
|
+
burstRemaining: prev.burstRemaining,
|
|
2494
|
+
burstNextAt: prev.burstNextAt
|
|
2432
2495
|
});
|
|
2433
2496
|
return {
|
|
2434
2497
|
run: true,
|
|
@@ -2438,7 +2501,9 @@ var MotionSettleGovernor = class {
|
|
|
2438
2501
|
this.state.set(sample.deviceId, {
|
|
2439
2502
|
lastMotionAt,
|
|
2440
2503
|
armed,
|
|
2441
|
-
lastRunAt: prev.lastRunAt
|
|
2504
|
+
lastRunAt: prev.lastRunAt,
|
|
2505
|
+
burstRemaining: prev.burstRemaining,
|
|
2506
|
+
burstNextAt: prev.burstNextAt
|
|
2442
2507
|
});
|
|
2443
2508
|
return NO_RUN;
|
|
2444
2509
|
}
|
|
@@ -2452,6 +2517,90 @@ var MotionSettleGovernor = class {
|
|
|
2452
2517
|
}
|
|
2453
2518
|
};
|
|
2454
2519
|
//#endregion
|
|
2520
|
+
//#region src/pipeline-runner/package-zone-proximity.ts
|
|
2521
|
+
/**
|
|
2522
|
+
* How much the zone-union box grows on EVERY side, as a fraction of its own
|
|
2523
|
+
* width / height.
|
|
2524
|
+
*
|
|
2525
|
+
* 0.5 means a doormat 271px wide on a 640px frame is approached through a
|
|
2526
|
+
* ~135px apron on each side — about one adult's width at that distance, which
|
|
2527
|
+
* is the thing being detected: a person standing next to the mat, not on it.
|
|
2528
|
+
* Larger and a passer-by on the pavement opens a burst; smaller and the
|
|
2529
|
+
* courier who never steps on the mat does not.
|
|
2530
|
+
*/
|
|
2531
|
+
var PACKAGE_ZONE_DILATION = .5;
|
|
2532
|
+
/** Grow a box by {@link PACKAGE_ZONE_DILATION}, clamped to the frame. */
|
|
2533
|
+
function dilateZoneBox(box, dilation = PACKAGE_ZONE_DILATION) {
|
|
2534
|
+
const dx = box.w * dilation;
|
|
2535
|
+
const dy = box.h * dilation;
|
|
2536
|
+
const x = Math.max(0, box.x - dx);
|
|
2537
|
+
const y = Math.max(0, box.y - dy);
|
|
2538
|
+
return {
|
|
2539
|
+
x,
|
|
2540
|
+
y,
|
|
2541
|
+
w: Math.min(1, box.x + box.w + dx) - x,
|
|
2542
|
+
h: Math.min(1, box.y + box.h + dy) - y
|
|
2543
|
+
};
|
|
2544
|
+
}
|
|
2545
|
+
function intersects(a, b) {
|
|
2546
|
+
return a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;
|
|
2547
|
+
}
|
|
2548
|
+
/**
|
|
2549
|
+
* Does any motion region reach the dilated package zone?
|
|
2550
|
+
*
|
|
2551
|
+
* **Fail-open on unknown geometry.** `zoneUnion === undefined` means the caller
|
|
2552
|
+
* has not (or could not) resolve the zones — a cold cache, a failed cap read.
|
|
2553
|
+
* It answers "yes, if there is any motion at all", which degrades to exactly
|
|
2554
|
+
* the whole-frame behaviour this replaced. The alternative — answering "no" —
|
|
2555
|
+
* would let one failed read silence package detection on a camera for as long
|
|
2556
|
+
* as the read kept failing, and be indistinguishable from a quiet doorstep.
|
|
2557
|
+
* That is the shape of D49, and it has cost this repo real deliveries.
|
|
2558
|
+
*/
|
|
2559
|
+
function motionNearPackageZone(input) {
|
|
2560
|
+
if (input.regions.length === 0) return false;
|
|
2561
|
+
if (input.zoneUnion === void 0) return true;
|
|
2562
|
+
if (input.frameWidth <= 0 || input.frameHeight <= 0) return true;
|
|
2563
|
+
const target = dilateZoneBox(input.zoneUnion);
|
|
2564
|
+
for (const region of input.regions) if (intersects({
|
|
2565
|
+
x: region.bbox.x / input.frameWidth,
|
|
2566
|
+
y: region.bbox.y / input.frameHeight,
|
|
2567
|
+
w: region.bbox.w / input.frameWidth,
|
|
2568
|
+
h: region.bbox.h / input.frameHeight
|
|
2569
|
+
}, target)) return true;
|
|
2570
|
+
return false;
|
|
2571
|
+
}
|
|
2572
|
+
/**
|
|
2573
|
+
* The bounding box of a set of normalised polygons — the package zone union.
|
|
2574
|
+
* Returns `undefined` when there is no usable geometry, which the caller must
|
|
2575
|
+
* pass through as "unknown" rather than as an empty zone.
|
|
2576
|
+
*/
|
|
2577
|
+
function packageZoneUnion(polygons) {
|
|
2578
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
2579
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
2580
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
2581
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
2582
|
+
let sawPoint = false;
|
|
2583
|
+
for (const polygon of polygons) for (const point of polygon) {
|
|
2584
|
+
sawPoint = true;
|
|
2585
|
+
if (point.x < minX) minX = point.x;
|
|
2586
|
+
if (point.y < minY) minY = point.y;
|
|
2587
|
+
if (point.x > maxX) maxX = point.x;
|
|
2588
|
+
if (point.y > maxY) maxY = point.y;
|
|
2589
|
+
}
|
|
2590
|
+
if (!sawPoint) return void 0;
|
|
2591
|
+
const x = Math.max(0, Math.min(1, minX));
|
|
2592
|
+
const y = Math.max(0, Math.min(1, minY));
|
|
2593
|
+
const w = Math.max(0, Math.min(1, maxX)) - x;
|
|
2594
|
+
const h = Math.max(0, Math.min(1, maxY)) - y;
|
|
2595
|
+
if (w <= 0 || h <= 0) return void 0;
|
|
2596
|
+
return {
|
|
2597
|
+
x,
|
|
2598
|
+
y,
|
|
2599
|
+
w,
|
|
2600
|
+
h
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2603
|
+
//#endregion
|
|
2455
2604
|
//#region src/pipeline-runner/native-crop-tier.ts
|
|
2456
2605
|
/**
|
|
2457
2606
|
* Pure tier decision for `getNativeCrop`. A native HIT always resolves to the
|
|
@@ -3829,6 +3978,13 @@ function isUsable(bbox) {
|
|
|
3829
3978
|
//#endregion
|
|
3830
3979
|
//#region src/pipeline-runner/index.ts
|
|
3831
3980
|
/**
|
|
3981
|
+
* How often a device's package zone-union geometry is re-read. An operator
|
|
3982
|
+
* redrawing a package zone takes effect within one interval; the read is a
|
|
3983
|
+
* cross-addon cap call reached from the per-frame package gate, so it must be
|
|
3984
|
+
* throttled to something far slower than the frame rate.
|
|
3985
|
+
*/
|
|
3986
|
+
var PACKAGE_ZONE_UNION_TTL_MS = 6e4;
|
|
3987
|
+
/**
|
|
3832
3988
|
* Bound on the frames whose cutter is bound but whose result has not come back.
|
|
3833
3989
|
* A few per camera in flight; the ceiling only catches results that never
|
|
3834
3990
|
* arrive (shed, inference timeout, detach mid-flight).
|
|
@@ -4199,6 +4355,36 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
4199
4355
|
*/
|
|
4200
4356
|
packageGovernor = new MotionSettleGovernor();
|
|
4201
4357
|
/**
|
|
4358
|
+
* Frames on which the governor DROPPED `package-detection` since that
|
|
4359
|
+
* device last ran it. The drop is the single most consequential silent
|
|
4360
|
+
* branch in the package chain — it decides the cadence that the whole
|
|
4361
|
+
* downstream promotion criterion has to be satisfiable at — and it logged
|
|
4362
|
+
* nothing at all, so "the parcel was never detected" and "the step never
|
|
4363
|
+
* ran" were indistinguishable in the logs. Counted here and reported on the
|
|
4364
|
+
* transition (first skip) and on every run, never per frame.
|
|
4365
|
+
*/
|
|
4366
|
+
packageGateSkips = /* @__PURE__ */ new Map();
|
|
4367
|
+
/**
|
|
4368
|
+
* Per-device package zone-union box (normalised), the target the motion
|
|
4369
|
+
* proximity test measures against.
|
|
4370
|
+
*
|
|
4371
|
+
* A device MISSING from this map is "unknown", not "no zones" — and unknown
|
|
4372
|
+
* FAILS OPEN in `motionNearPackageZone`, degrading to the whole-frame motion
|
|
4373
|
+
* signal. Resolved off the frame path (on attach, and refreshed on the
|
|
4374
|
+
* package-step gate's own cadence), never inside `runMotionAnalysis`.
|
|
4375
|
+
*/
|
|
4376
|
+
packageZoneUnionByDevice = /* @__PURE__ */ new Map();
|
|
4377
|
+
/** In-flight/last zone-union resolution time per device, so the refresh does
|
|
4378
|
+
* not stampede the zone caps from the motion path. */
|
|
4379
|
+
packageZoneUnionAt = /* @__PURE__ */ new Map();
|
|
4380
|
+
/**
|
|
4381
|
+
* Whether the last analyzer frame saw motion NEAR the device's package
|
|
4382
|
+
* zones — the boolean the settle-burst governor consumes. Distinct from
|
|
4383
|
+
* `lastAnalyzerDetected` (whole-frame), which is what the phase machine
|
|
4384
|
+
* uses and which must not change meaning.
|
|
4385
|
+
*/
|
|
4386
|
+
lastMotionNearPackageZone = /* @__PURE__ */ new Map();
|
|
4387
|
+
/**
|
|
4202
4388
|
* Last positive motion timestamp per device — preserved across the
|
|
4203
4389
|
* OFF transition so the motion runtime-state slice keeps a stable
|
|
4204
4390
|
* `lastDetectedAt` after the cooldown closes the phase. Cleared on
|
|
@@ -4399,6 +4585,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
4399
4585
|
}
|
|
4400
4586
|
this.lastAnalyzerDetected.clear();
|
|
4401
4587
|
this.packageGovernor.reset();
|
|
4588
|
+
this.packageGateSkips.clear();
|
|
4589
|
+
this.packageZoneUnionByDevice.clear();
|
|
4590
|
+
this.packageZoneUnionAt.clear();
|
|
4591
|
+
this.lastMotionNearPackageZone.clear();
|
|
4402
4592
|
for (const deviceId of [...this.onboardAnalyzerTeardownTimers.keys(), ...this.onboardAnalyzerSubs.keys()]) this.clearOnboardAnalyzer(deviceId);
|
|
4403
4593
|
if (this.runner) {
|
|
4404
4594
|
this.runner.stop();
|
|
@@ -5661,6 +5851,10 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
5661
5851
|
this.lastMotionFrameAt.delete(deviceId);
|
|
5662
5852
|
this.lastDecodeUnexpectedEndAt.delete(deviceId);
|
|
5663
5853
|
this.packageGovernor.forget(deviceId);
|
|
5854
|
+
this.packageGateSkips.delete(deviceId);
|
|
5855
|
+
this.packageZoneUnionByDevice.delete(deviceId);
|
|
5856
|
+
this.packageZoneUnionAt.delete(deviceId);
|
|
5857
|
+
this.lastMotionNearPackageZone.delete(deviceId);
|
|
5664
5858
|
const warnPrefix = `${deviceId}:`;
|
|
5665
5859
|
for (const key of this.warnedNoJumpDevice) if (key.startsWith(warnPrefix)) this.warnedNoJumpDevice.delete(key);
|
|
5666
5860
|
this.attached.delete(deviceId);
|
|
@@ -6237,13 +6431,31 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
6237
6431
|
if (steps.length === 0) return null;
|
|
6238
6432
|
let dispatchSteps = steps;
|
|
6239
6433
|
if (steps.some((s) => s.addonId === "package-detection" && s.enabled !== false)) {
|
|
6240
|
-
|
|
6434
|
+
this.refreshPackageZoneUnion(deviceId);
|
|
6435
|
+
const motionInZone = this.lastMotionNearPackageZone.get(deviceId) ?? this.lastAnalyzerDetected.get(deviceId) ?? false;
|
|
6436
|
+
const decision = this.packageGovernor.evaluate({
|
|
6241
6437
|
deviceId,
|
|
6242
|
-
motionInZone
|
|
6438
|
+
motionInZone,
|
|
6243
6439
|
now: Date.now()
|
|
6244
|
-
})
|
|
6440
|
+
});
|
|
6441
|
+
const skipped = this.packageGateSkips.get(deviceId) ?? 0;
|
|
6442
|
+
if (!decision.run) {
|
|
6245
6443
|
dispatchSteps = steps.filter((s) => s.addonId !== PACKAGE_DETECTION_STEP_ID);
|
|
6444
|
+
if (skipped === 0) log.info("package-detection gated off by the motion-settle governor", {
|
|
6445
|
+
tags: { deviceId },
|
|
6446
|
+
meta: { motionInZone: this.lastAnalyzerDetected.get(deviceId) ?? false }
|
|
6447
|
+
});
|
|
6448
|
+
this.packageGateSkips.set(deviceId, skipped + 1);
|
|
6246
6449
|
if (dispatchSteps.length === 0) return null;
|
|
6450
|
+
} else {
|
|
6451
|
+
this.packageGateSkips.set(deviceId, 0);
|
|
6452
|
+
log.info("package-detection dispatched by the motion-settle governor", {
|
|
6453
|
+
tags: { deviceId },
|
|
6454
|
+
meta: {
|
|
6455
|
+
reason: decision.reason,
|
|
6456
|
+
framesSkippedSinceLastRun: skipped
|
|
6457
|
+
}
|
|
6458
|
+
});
|
|
6247
6459
|
}
|
|
6248
6460
|
}
|
|
6249
6461
|
let image;
|
|
@@ -6292,6 +6504,51 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
6292
6504
|
}
|
|
6293
6505
|
return false;
|
|
6294
6506
|
}
|
|
6507
|
+
/**
|
|
6508
|
+
* Refresh a device's package zone-union box, off the caller's path.
|
|
6509
|
+
*
|
|
6510
|
+
* Cross-addon reads go through `ctx.api` (the only cross-addon layer), and
|
|
6511
|
+
* they are RATE-LIMITED per device: this is reached from the per-frame
|
|
6512
|
+
* package gate, and two cap calls per frame would be a self-inflicted load
|
|
6513
|
+
* problem on the exact cameras the feature exists for.
|
|
6514
|
+
*
|
|
6515
|
+
* A FAILED read leaves the mirror untouched (D49): the last-known-good
|
|
6516
|
+
* geometry keeps being used, and a device that has never been read stays
|
|
6517
|
+
* absent from the map, which `motionNearPackageZone` treats as unknown and
|
|
6518
|
+
* fails OPEN on. Nothing here can make package detection quieter.
|
|
6519
|
+
*/
|
|
6520
|
+
refreshPackageZoneUnion(deviceId) {
|
|
6521
|
+
const now = Date.now();
|
|
6522
|
+
if (now - (this.packageZoneUnionAt.get(deviceId) ?? 0) < PACKAGE_ZONE_UNION_TTL_MS) return;
|
|
6523
|
+
this.packageZoneUnionAt.set(deviceId, now);
|
|
6524
|
+
const api = this.ctx.api;
|
|
6525
|
+
if (!api) return;
|
|
6526
|
+
(async () => {
|
|
6527
|
+
try {
|
|
6528
|
+
const [zones, rules] = await Promise.all([api.zones.listZones.query({ deviceId }), api.zoneRules.listRules.query({
|
|
6529
|
+
deviceId,
|
|
6530
|
+
stage: "package"
|
|
6531
|
+
})]);
|
|
6532
|
+
const zoneIds = new Set(rules.filter((r) => r.enabled !== false).flatMap((r) => r.zoneIds));
|
|
6533
|
+
const polygons = zones.filter((z) => zoneIds.has(z.id)).map((z) => z.polygon);
|
|
6534
|
+
const union = packageZoneUnion(polygons);
|
|
6535
|
+
const previous = this.packageZoneUnionByDevice.get(deviceId);
|
|
6536
|
+
this.packageZoneUnionByDevice.set(deviceId, union);
|
|
6537
|
+
if (previous === void 0 && union !== void 0) this.ctx.logger.info("package zone geometry resolved — motion proximity armed", {
|
|
6538
|
+
tags: { deviceId },
|
|
6539
|
+
meta: {
|
|
6540
|
+
zoneUnion: union,
|
|
6541
|
+
zones: polygons.length
|
|
6542
|
+
}
|
|
6543
|
+
});
|
|
6544
|
+
} catch (err) {
|
|
6545
|
+
this.ctx.logger.warn("package zone geometry read failed — motion proximity fails open", {
|
|
6546
|
+
tags: { deviceId },
|
|
6547
|
+
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
6548
|
+
});
|
|
6549
|
+
}
|
|
6550
|
+
})();
|
|
6551
|
+
}
|
|
6295
6552
|
async runMotionAnalysis(deviceId, frame, handle) {
|
|
6296
6553
|
const ctx = this.ctx;
|
|
6297
6554
|
const runner = this.runner;
|
|
@@ -6312,6 +6569,12 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
6312
6569
|
});
|
|
6313
6570
|
if (!result) return;
|
|
6314
6571
|
const detected = result.regions.length > 0;
|
|
6572
|
+
this.lastMotionNearPackageZone.set(deviceId, motionNearPackageZone({
|
|
6573
|
+
regions: result.regions,
|
|
6574
|
+
frameWidth: result.frameWidth,
|
|
6575
|
+
frameHeight: result.frameHeight,
|
|
6576
|
+
zoneUnion: this.packageZoneUnionByDevice.get(deviceId)
|
|
6577
|
+
}));
|
|
6315
6578
|
if (detected !== (this.lastAnalyzerDetected.get(deviceId) ?? false)) {
|
|
6316
6579
|
this.lastAnalyzerDetected.set(deviceId, detected);
|
|
6317
6580
|
if (this.ctx.eventBus) this.ctx.eventBus.emit(createEvent(EventCategory.MotionOnMotionChanged, {
|
package/dist/recorder/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const require_dist = require("../dist-
|
|
1
|
+
const require_dist = require("../dist-CZLjObZZ.js");
|
|
2
2
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
3
|
-
const require_addon_utils = require("../addon-utils-
|
|
3
|
+
const require_addon_utils = require("../addon-utils-CTpQfjSR.js");
|
|
4
4
|
let node_crypto = require("node:crypto");
|
|
5
5
|
let node_child_process = require("node:child_process");
|
|
6
6
|
let node_path = require("node:path");
|
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-zksfWnEA.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-A2S9D7pu.mjs";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_worker_protocol = require("../worker-protocol-
|
|
3
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
2
|
+
const require_worker_protocol = require("../worker-protocol-DAQ1iZFK.js");
|
|
3
|
+
const require_lazy_sharp = require("../lazy-sharp-SWR_D1Um.js");
|
|
4
4
|
//#region src/session-decode/color-conversion.ts
|
|
5
5
|
/**
|
|
6
6
|
* Explicit YUV→RGB colorspace/range resolution for the session-decode worker.
|
|
@@ -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-DyX_HbaJ.mjs";
|
|
2
2
|
import { n as setSharpWarnSink, r as hostExternalEntryUrls, t as getSharp } from "../lazy-sharp-6oymT_yf.mjs";
|
|
3
3
|
//#region src/session-decode/color-conversion.ts
|
|
4
4
|
/**
|
|
@@ -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-CZLjObZZ.js");
|
|
6
6
|
const require_remote_restream = require("../remote-restream-BYbAsgUf.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
node_crypto = require_dist.__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-zksfWnEA.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-Dd6XOtVn.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-zksfWnEA.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.76",
|
|
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",
|