@camstack/addon-pipeline 1.2.219 → 1.2.220
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 +49 -5
- package/dist/audio-analyzer/index.mjs +46 -3
- package/dist/chunk-emK7D4bc.js +35 -0
- package/dist/{default-detection-model-Dsk1a5pY.mjs → default-detection-model-DBNEc3iw.mjs} +1 -1
- package/dist/{default-detection-model-d7-Q_LMo.js → default-detection-model-x6oNMBDH.js} +1 -1
- package/dist/detection-pipeline/index.js +10 -9
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-wtNhtVVo.js → dist-ByPsWlTa.js} +2 -37
- package/dist/{dist-CKK0CBUW.mjs → dist-ClihWGOZ.mjs} +2 -2
- package/dist/{lazy-sharp-zoQ07I43.js → lazy-sharp-BuwKlQLR.js} +2 -2
- package/dist/motion-wasm/index.js +2 -2
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-BduNi21Z.js → node-CNPnaux4.js} +4 -3
- package/dist/{node-CrNBWFbA.mjs → node-DiaTmz84.mjs} +1 -1
- package/dist/pipeline-runner/index.js +222 -157
- package/dist/pipeline-runner/index.mjs +218 -154
- package/dist/{process-memory-Dwl0MFPH.js → process-memory-9KqRtUHt.js} +3 -2
- package/dist/{process-memory-BRQOtDN1.mjs → process-memory-D4t8hpJd.mjs} +1 -1
- package/dist/recorder/index.js +334 -123
- package/dist/recorder/index.mjs +332 -122
- package/dist/{segment-demux-js-D2o9ShNL.mjs → segment-demux-js-CFFXVae4.mjs} +1 -1
- package/dist/{segment-demux-js-CFOU3biG.js → segment-demux-js-CZefXDLx.js} +4 -3
- package/dist/session-decode/decode-worker-child.js +155 -74
- package/dist/session-decode/decode-worker-child.mjs +154 -73
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DN_IoShh.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CtdpN7Sz.mjs} +3 -3
- 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-n7c9pNlt.mjs → hostInit-McoUiljf.mjs} +3 -3
- package/dist/stream-broker/index.js +24 -25
- package/dist/stream-broker/index.mjs +17 -19
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/worker-protocol-B2MfQLlu.js +184 -0
- package/dist/worker-protocol-C_W-P_g-.mjs +161 -0
- package/package.json +1 -1
- package/dist/worker-protocol-Cx3Nqreq.mjs +0 -264
- package/dist/worker-protocol-iWTFnnUM.js +0 -299
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as formatNativeLeaseKnobs, n as isWorkerRequest,
|
|
1
|
+
import { i as formatNativeLeaseKnobs, n as isWorkerRequest, r as logLevelForLine } from "../worker-protocol-C_W-P_g-.mjs";
|
|
2
2
|
import { n as setSharpWarnSink, r as hostExternalEntryUrls, t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
3
3
|
//#region src/session-decode/color-conversion.ts
|
|
4
4
|
/**
|
|
@@ -1601,48 +1601,68 @@ var NATIVE_RING_CAP = (() => {
|
|
|
1601
1601
|
return Math.min(4, Math.max(0, Math.floor(raw)));
|
|
1602
1602
|
})();
|
|
1603
1603
|
/**
|
|
1604
|
-
* The
|
|
1605
|
-
*
|
|
1606
|
-
*
|
|
1607
|
-
*
|
|
1608
|
-
*
|
|
1609
|
-
* `
|
|
1610
|
-
*
|
|
1611
|
-
*
|
|
1612
|
-
*
|
|
1613
|
-
*
|
|
1614
|
-
*
|
|
1615
|
-
*
|
|
1616
|
-
*
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
*
|
|
1621
|
-
*
|
|
1622
|
-
*
|
|
1623
|
-
* `0` DISABLES the hold and falls back to the
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
*
|
|
1628
|
-
*
|
|
1629
|
-
*
|
|
1630
|
-
*
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
*
|
|
1635
|
-
* `
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
*
|
|
1642
|
-
*
|
|
1643
|
-
*
|
|
1644
|
-
|
|
1645
|
-
|
|
1604
|
+
* The native-lease knobs — hold depth, hold RAM ceiling, demand window,
|
|
1605
|
+
* admission mode, subject-tile budget, scene-tile budget — ARRIVE ON `start`
|
|
1606
|
+
* (`WorkerRequest.lease`, D453). They are **operator settings** living on
|
|
1607
|
+
* `pipeline-orchestrator`'s cluster-wide globals; the pipeline-runner reads
|
|
1608
|
+
* them and resolves `setting > env > default` in ITS process
|
|
1609
|
+
* (`native-lease-config.ts`), and this worker builds its stores from the
|
|
1610
|
+
* resolved values in {@link DecodeWorkerChild.handleStart}, before the first
|
|
1611
|
+
* packet. Until then it retains nothing ({@link UNSTARTED_LEASE_KNOBS}).
|
|
1612
|
+
*
|
|
1613
|
+
* Nothing here reads the environment for them any more. The child used to,
|
|
1614
|
+
* from `*_SETTING` vars the parent wrote at fork — which needed the Zod schemas
|
|
1615
|
+
* (the whole `@camstack/types` index) inside this bundle and cost every fork
|
|
1616
|
+
* ~130 ms and ~140 MB, measured; and it bound a worker to the knobs it was
|
|
1617
|
+
* FORKED with, which a pre-forked worker (`decode-worker-pool.ts`) cannot be.
|
|
1618
|
+
* The values AND their sources are logged once per session at `start`.
|
|
1619
|
+
*
|
|
1620
|
+
* What each knob means, in the store it sizes:
|
|
1621
|
+
* - `budgetMb` — hard RAM ceiling (bytes) for the native-frame HOLD store, the
|
|
1622
|
+
* OOM ceiling and since 2026-08-13 nothing else; `holdFrames` is what decides
|
|
1623
|
+
* how much is held. `0` DISABLES the hold and falls back to the
|
|
1624
|
+
* {@link NATIVE_RING_CAP} GPU ring.
|
|
1625
|
+
* - `holdFrames` — how many delivered frames are HELD at once, each waiting for
|
|
1626
|
+
* its own detection result. The ordinary exit is `cutTiles` /
|
|
1627
|
+
* `releaseNativeLease`; this bound only stops a runner that stopped answering
|
|
1628
|
+
* from pinning RAM, and every frame it drops is counted (`holdOverflow`).
|
|
1629
|
+
* - `tileBudgetMb` — the SUBJECT TILE store, what survives a frame. `0` turns
|
|
1630
|
+
* tiles off and restores the pre-2026-08-13 miss profile.
|
|
1631
|
+
* - `sceneBudgetMb` — the SCENE TILE store, one JPEG of the whole native frame
|
|
1632
|
+
* per detection-bearing frame, the only thing that can answer a FULL-FRAME
|
|
1633
|
+
* request after the hold ends. Separate from the subject budget so a key
|
|
1634
|
+
* frame can never evict a face tile. `0` disables the rung.
|
|
1635
|
+
* - `activityMs` — the {@link LeaseActivityGate} demand window: eager per-frame
|
|
1636
|
+
* native downloads run only within it. `0` disables the GATE (always-on eager
|
|
1637
|
+
* capture) — it does not disable retention.
|
|
1638
|
+
*/
|
|
1639
|
+
var MB = 1024 * 1024;
|
|
1640
|
+
/**
|
|
1641
|
+
* What a worker holds BEFORE a session claims it: nothing. Hold off (`budgetMb`
|
|
1642
|
+
* 0 routes to the GPU ring, whose cap is env-only), tiles off, scenes off, the
|
|
1643
|
+
* gate open only because there is nothing behind it to open. Not the shipped
|
|
1644
|
+
* defaults on purpose — those live in `@camstack/types`, which this bundle no
|
|
1645
|
+
* longer carries, and a pre-forked worker that silently held the defaults would
|
|
1646
|
+
* be a worker with a configuration nobody handed it.
|
|
1647
|
+
*/
|
|
1648
|
+
var UNSTARTED_LEASE_KNOBS = {
|
|
1649
|
+
values: {
|
|
1650
|
+
holdFrames: 1,
|
|
1651
|
+
budgetMb: 0,
|
|
1652
|
+
activityMs: 0,
|
|
1653
|
+
admission: "inferred",
|
|
1654
|
+
tileBudgetMb: 0,
|
|
1655
|
+
sceneBudgetMb: 0
|
|
1656
|
+
},
|
|
1657
|
+
sources: {
|
|
1658
|
+
holdFrames: "default",
|
|
1659
|
+
budgetMb: "default",
|
|
1660
|
+
activityMs: "default",
|
|
1661
|
+
admission: "default",
|
|
1662
|
+
tileBudgetMb: "default",
|
|
1663
|
+
sceneBudgetMb: "default"
|
|
1664
|
+
}
|
|
1665
|
+
};
|
|
1646
1666
|
/**
|
|
1647
1667
|
* How long a subject tile is served. A TTL is honest HERE and dishonest on the
|
|
1648
1668
|
* hold: nothing is waiting on a tile, it is speculative retention against a
|
|
@@ -1689,13 +1709,6 @@ var TILE_CUT_WAIT_MS = (() => {
|
|
|
1689
1709
|
const raw = Number(process.env["CAMSTACK_SESSION_TILE_CUT_WAIT_MS"]);
|
|
1690
1710
|
return Number.isFinite(raw) && raw >= 0 ? Math.floor(raw) : 500;
|
|
1691
1711
|
})();
|
|
1692
|
-
/**
|
|
1693
|
-
* Demand window (ms) for the lease-capture {@link LeaseActivityGate}: eager
|
|
1694
|
-
* per-frame native downloads run only within this window of the last
|
|
1695
|
-
* native-crop request (or dial start). `0` disables the GATE (legacy always-on
|
|
1696
|
-
* eager capture) — it does not disable retention. Default 15000.
|
|
1697
|
-
*/
|
|
1698
|
-
var NATIVE_LEASE_ACTIVITY_WINDOW_MS = NATIVE_LEASE_KNOBS.values.activityMs;
|
|
1699
1712
|
/** How many early-withdrawn frame ids the worker remembers for the miss line. */
|
|
1700
1713
|
var UNMARKED_MEMORY = 256;
|
|
1701
1714
|
/**
|
|
@@ -1817,13 +1830,47 @@ async function importNodeAv(bareSpecifier) {
|
|
|
1817
1830
|
throw bareErr;
|
|
1818
1831
|
}
|
|
1819
1832
|
}
|
|
1833
|
+
var _navLoading = null;
|
|
1834
|
+
var _constsLoading = null;
|
|
1820
1835
|
async function getNodeAv() {
|
|
1821
|
-
if (
|
|
1822
|
-
|
|
1836
|
+
if (_nav) return _nav;
|
|
1837
|
+
_navLoading ??= importNodeAv("node-av").then((mod) => {
|
|
1838
|
+
_nav = mod;
|
|
1839
|
+
return mod;
|
|
1840
|
+
});
|
|
1841
|
+
try {
|
|
1842
|
+
return await _navLoading;
|
|
1843
|
+
} catch (err) {
|
|
1844
|
+
_navLoading = null;
|
|
1845
|
+
throw err;
|
|
1846
|
+
}
|
|
1823
1847
|
}
|
|
1824
1848
|
async function getConstants() {
|
|
1825
|
-
if (
|
|
1826
|
-
|
|
1849
|
+
if (_consts) return _consts;
|
|
1850
|
+
_constsLoading ??= importNodeAv("node-av/constants").then((mod) => {
|
|
1851
|
+
_consts = mod;
|
|
1852
|
+
return mod;
|
|
1853
|
+
});
|
|
1854
|
+
try {
|
|
1855
|
+
return await _constsLoading;
|
|
1856
|
+
} catch (err) {
|
|
1857
|
+
_constsLoading = null;
|
|
1858
|
+
throw err;
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
/** The HOLD store, sized from one session's knobs. */
|
|
1862
|
+
function buildLeaseStore(lease) {
|
|
1863
|
+
return new NativeLeaseStore({
|
|
1864
|
+
budgetBytes: lease.values.budgetMb * MB,
|
|
1865
|
+
maxFrames: lease.values.holdFrames
|
|
1866
|
+
});
|
|
1867
|
+
}
|
|
1868
|
+
/** A TILE store (subject or scene) under `budgetMb`, on the shared tile TTL. */
|
|
1869
|
+
function buildTileStore(budgetMb) {
|
|
1870
|
+
return new NativeTileStore({
|
|
1871
|
+
budgetBytes: budgetMb * MB,
|
|
1872
|
+
ttlMs: NATIVE_TILE_TTL_MS
|
|
1873
|
+
});
|
|
1827
1874
|
}
|
|
1828
1875
|
function errMessage(err) {
|
|
1829
1876
|
if (err instanceof Error) return err.message;
|
|
@@ -2010,20 +2057,14 @@ var DecodeWorkerChild = class {
|
|
|
2010
2057
|
* DOWNLOADED (system-memory) frames, retaining a large window has no VAAPI
|
|
2011
2058
|
* surface-pool starvation risk. Cleared on every re-dial + teardown.
|
|
2012
2059
|
*/
|
|
2013
|
-
leaseStore =
|
|
2014
|
-
budgetBytes: NATIVE_LEASE_BUDGET_BYTES,
|
|
2015
|
-
maxFrames: NATIVE_LEASE_HOLD_FRAMES
|
|
2016
|
-
});
|
|
2060
|
+
leaseStore = buildLeaseStore(UNSTARTED_LEASE_KNOBS);
|
|
2017
2061
|
/**
|
|
2018
2062
|
* What SURVIVES a held frame: one compressed native tile per subject, cut at
|
|
2019
2063
|
* the instant the frame's detection result arrived. Every late native crop
|
|
2020
2064
|
* that the hold can no longer serve is served from here — which measurement
|
|
2021
2065
|
* says is the ordinary case, not the exception. See `native-tile-store.ts`.
|
|
2022
2066
|
*/
|
|
2023
|
-
tileStore =
|
|
2024
|
-
budgetBytes: NATIVE_TILE_BUDGET_BYTES,
|
|
2025
|
-
ttlMs: NATIVE_TILE_TTL_MS
|
|
2026
|
-
});
|
|
2067
|
+
tileStore = buildTileStore(UNSTARTED_LEASE_KNOBS.values.tileBudgetMb);
|
|
2027
2068
|
/**
|
|
2028
2069
|
* What survives a held frame for a FULL-FRAME request: one JPEG of the whole
|
|
2029
2070
|
* native raster, cut in the SAME synchronous read phase as the subject tiles.
|
|
@@ -2033,10 +2074,7 @@ var DecodeWorkerChild = class {
|
|
|
2033
2074
|
* key frames evict the face/plate tiles the recognisers live on. Two stores
|
|
2034
2075
|
* make starving that tier impossible rather than unlikely.
|
|
2035
2076
|
*/
|
|
2036
|
-
sceneStore =
|
|
2037
|
-
budgetBytes: NATIVE_SCENE_BUDGET_BYTES,
|
|
2038
|
-
ttlMs: NATIVE_TILE_TTL_MS
|
|
2039
|
-
});
|
|
2077
|
+
sceneStore = buildTileStore(UNSTARTED_LEASE_KNOBS.values.sceneBudgetMb);
|
|
2040
2078
|
/** Tiles cut / served / refused-for-containment, on the throughput line. */
|
|
2041
2079
|
tilesCut = 0;
|
|
2042
2080
|
tileHits = 0;
|
|
@@ -2080,7 +2118,7 @@ var DecodeWorkerChild = class {
|
|
|
2080
2118
|
* per-frame native-res GPU→RAM download (the N100 saturation source) stops
|
|
2081
2119
|
* on cameras nothing is cropping. See `lease-activity-gate.ts`.
|
|
2082
2120
|
*/
|
|
2083
|
-
leaseGate = new LeaseActivityGate(
|
|
2121
|
+
leaseGate = new LeaseActivityGate(UNSTARTED_LEASE_KNOBS.values.activityMs);
|
|
2084
2122
|
/**
|
|
2085
2123
|
* WHICH delivered frames are worth a native lease — the runner marks the ones
|
|
2086
2124
|
* it admitted to inference (`markInferred`), and in `inferred` mode only
|
|
@@ -2089,7 +2127,14 @@ var DecodeWorkerChild = class {
|
|
|
2089
2127
|
* filter rests on is measured on live traffic rather than argued. See
|
|
2090
2128
|
* `lease-admission-ledger.ts`.
|
|
2091
2129
|
*/
|
|
2092
|
-
admission = new LeaseAdmissionLedger({ mode:
|
|
2130
|
+
admission = new LeaseAdmissionLedger({ mode: UNSTARTED_LEASE_KNOBS.values.admission });
|
|
2131
|
+
/**
|
|
2132
|
+
* The knobs this session runs under — `null` until `start` hands them over.
|
|
2133
|
+
* The stores above are REBUILT from them at that moment (they are empty then:
|
|
2134
|
+
* nothing is captured before a dial), and never again: a knob that changes
|
|
2135
|
+
* after the first frame is a knob with two values during a session.
|
|
2136
|
+
*/
|
|
2137
|
+
lease = null;
|
|
2093
2138
|
/**
|
|
2094
2139
|
* DEDICATED full-frame GPU→system download filtergraph
|
|
2095
2140
|
* (`scale_<be>=iw:ih,hwdownload,format=nv12,format=yuv420p`) used ONLY to
|
|
@@ -2250,7 +2295,7 @@ var DecodeWorkerChild = class {
|
|
|
2250
2295
|
}
|
|
2251
2296
|
switch (message.kind) {
|
|
2252
2297
|
case "start":
|
|
2253
|
-
this.handleStart(message.source, message.opts);
|
|
2298
|
+
this.handleStart(message.source, message.opts, message.lease);
|
|
2254
2299
|
return;
|
|
2255
2300
|
case "pull":
|
|
2256
2301
|
this.handlePull();
|
|
@@ -2330,7 +2375,7 @@ var DecodeWorkerChild = class {
|
|
|
2330
2375
|
const skipped = this.framesSkipped + this.frames.droppedCount;
|
|
2331
2376
|
const rssMb = Math.round(process.memoryUsage().rss / 1048576);
|
|
2332
2377
|
const ageS = Math.round((now - this.startedAt) / 1e3);
|
|
2333
|
-
this.emitStderr(`session-decode metrics {framesDecoded:${this.framesDecoded}, framesSkipped:${skipped}, deliveredFps:${deliveredFps}, nativeCropHits:${this.nativeCropHits}, nativeCropMisses:${this.nativeCropMisses}, leaseOffered:${this.admission.offered}, leaseAdmitted:${this.admission.admitted}, leaseMarks:${this.admission.marks}, leaseUnmarkedCrops:${this.admission.unmarkedCrops}, leaseAdmission:${
|
|
2378
|
+
this.emitStderr(`session-decode metrics {framesDecoded:${this.framesDecoded}, framesSkipped:${skipped}, deliveredFps:${deliveredFps}, nativeCropHits:${this.nativeCropHits}, nativeCropMisses:${this.nativeCropMisses}, leaseOffered:${this.admission.offered}, leaseAdmitted:${this.admission.admitted}, leaseMarks:${this.admission.marks}, leaseUnmarkedCrops:${this.admission.unmarkedCrops}, leaseAdmission:${this.lease?.values.admission ?? "unstarted"}, leaseMb:${Math.round(this.leaseStore.totalBytes / 1048576)}, leaseFrames:${this.leaseStore.size}, holdOverflow:${this.leaseStore.overflowCount}, leaseReleased:${this.leaseReleased}, leaseReleaseMisses:${this.leaseReleaseMisses}, leaseReleasedEarly:${this.leaseReleasedEarly}, tilesCut:${this.tilesCut}, tileHits:${this.tileHits}, tileMisses:${this.tileMisses}, tileCutFailures:${this.tileCutFailures}, tileMissesResolvedByWait:${this.tileMissesResolvedByWait}, tileWaitTimeouts:${this.tileWaitTimeouts}, cutLatencyMsP50:${formatLatency(this.pendingCuts.latencyMs(50))}, cutLatencyMsP95:${formatLatency(this.pendingCuts.latencyMs(95))}, cutsInFlight:${this.pendingCuts.inFlight}, tileMb:${Math.round(this.tileStore.totalBytes / 1048576)}, tileFrames:${this.tileStore.frameCount}, scenesCut:${this.scenesCut}, sceneHits:${this.sceneHits}, sceneRefused:${this.sceneRefused}, sceneUnclassified:${this.sceneUnclassified}, sceneEvicted:${this.sceneStore.evictedCount}, sceneMb:${Math.round(this.sceneStore.totalBytes / 1048576)}, sceneFrames:${this.sceneStore.frameCount}, rssMb:${rssMb}, ageS:${ageS}}${final ? " (final)" : ""}\n`);
|
|
2334
2379
|
this.lastMetricsAt = now;
|
|
2335
2380
|
this.lastDeliveredSnapshot = this.framesDelivered;
|
|
2336
2381
|
if (!this.warnedLarge && rssMb >= WORKER_RSS_WARN_MB) {
|
|
@@ -2338,14 +2383,20 @@ var DecodeWorkerChild = class {
|
|
|
2338
2383
|
this.emitStderr(`decode-worker-child: WORKER IS LARGE — rssMb=${rssMb} ageS=${ageS} framesDecoded=${this.framesDecoded}. Siblings normally recycle in ~30s; a worker this size at this age is how the host ran out of memory on 2026-08-05.\n`);
|
|
2339
2384
|
}
|
|
2340
2385
|
}
|
|
2341
|
-
handleStart(source, opts) {
|
|
2386
|
+
handleStart(source, opts, lease) {
|
|
2342
2387
|
if (this.started) {
|
|
2343
2388
|
this.emitStderr("decode-worker-child: duplicate start ignored\n");
|
|
2344
2389
|
return;
|
|
2345
2390
|
}
|
|
2346
2391
|
this.started = true;
|
|
2347
2392
|
this.deviceId = source.deviceId;
|
|
2348
|
-
this.
|
|
2393
|
+
this.lease = lease;
|
|
2394
|
+
this.leaseStore = buildLeaseStore(lease);
|
|
2395
|
+
this.tileStore = buildTileStore(lease.values.tileBudgetMb);
|
|
2396
|
+
this.sceneStore = buildTileStore(lease.values.sceneBudgetMb);
|
|
2397
|
+
this.leaseGate = new LeaseActivityGate(lease.values.activityMs);
|
|
2398
|
+
this.admission = new LeaseAdmissionLedger({ mode: lease.values.admission });
|
|
2399
|
+
this.emitStderr(`decode-worker-child: ${formatNativeLeaseKnobs(lease)}\n`, "info");
|
|
2349
2400
|
this.sessionFormat = opts.format ?? "rgb";
|
|
2350
2401
|
this.minIntervalMs = opts.fps && opts.fps > 0 ? 1e3 / opts.fps : 0;
|
|
2351
2402
|
this.preRollMs = opts.preRollMs && opts.preRollMs > 0 ? opts.preRollMs : 0;
|
|
@@ -2399,7 +2450,7 @@ var DecodeWorkerChild = class {
|
|
|
2399
2450
|
reservedFrameId: this.frames.reservedFrameId,
|
|
2400
2451
|
marked: this.admission.isMarked(frameId),
|
|
2401
2452
|
leaseFrames: this.leaseStore.size,
|
|
2402
|
-
holdFrames:
|
|
2453
|
+
holdFrames: this.lease?.values.holdFrames ?? UNSTARTED_LEASE_KNOBS.values.holdFrames,
|
|
2403
2454
|
holdOverflow: this.leaseStore.overflowCount,
|
|
2404
2455
|
...this.unmarkedBy.has(frameId) ? { unmarkedBy: this.unmarkedBy.get(frameId) } : {}
|
|
2405
2456
|
}), frameId);
|
|
@@ -3561,6 +3612,35 @@ var DecodeWorkerChild = class {
|
|
|
3561
3612
|
this.demuxer?.[Symbol.dispose]?.();
|
|
3562
3613
|
this.demuxer = null;
|
|
3563
3614
|
}
|
|
3615
|
+
/**
|
|
3616
|
+
* Load the native modules BEFORE any session, then say so. This is what a
|
|
3617
|
+
* pre-forked worker in the zygote pool (`decode-worker-pool.ts`) spends its
|
|
3618
|
+
* idle on — node-av's `dlopen` measured ~50 ms on the hub, and after D453
|
|
3619
|
+
* removed the types chunk it is the largest piece of a cold boot that is left.
|
|
3620
|
+
* It touches no stream, no demuxer, no GPU: a warm worker costs RSS and
|
|
3621
|
+
* nothing else, which is the property the pool exists for and the exact
|
|
3622
|
+
* inverse of the keep-warm D282 measured.
|
|
3623
|
+
*
|
|
3624
|
+
* A failure is reported, not fatal: `start` re-runs the same import and
|
|
3625
|
+
* fails the session the way it always has, so a node where node-av cannot
|
|
3626
|
+
* load is no worse off than before — it just is not warm.
|
|
3627
|
+
*/
|
|
3628
|
+
async warm() {
|
|
3629
|
+
try {
|
|
3630
|
+
await getNodeAv();
|
|
3631
|
+
await getConstants();
|
|
3632
|
+
this.send({
|
|
3633
|
+
kind: "ready",
|
|
3634
|
+
warm: true
|
|
3635
|
+
});
|
|
3636
|
+
} catch (err) {
|
|
3637
|
+
this.emitStderr(`decode-worker-child: native module preload failed — ${errMessage(err)}\n`, "warn");
|
|
3638
|
+
this.send({
|
|
3639
|
+
kind: "ready",
|
|
3640
|
+
warm: false
|
|
3641
|
+
});
|
|
3642
|
+
}
|
|
3643
|
+
}
|
|
3564
3644
|
send(reply) {
|
|
3565
3645
|
process.send?.(reply);
|
|
3566
3646
|
}
|
|
@@ -3618,6 +3698,7 @@ setSharpWarnSink((message) => {
|
|
|
3618
3698
|
process.on("message", (message) => {
|
|
3619
3699
|
worker.handleMessage(message);
|
|
3620
3700
|
});
|
|
3701
|
+
worker.warm();
|
|
3621
3702
|
process.on("disconnect", () => {
|
|
3622
3703
|
worker.teardown();
|
|
3623
3704
|
process.exit(0);
|
|
@@ -3,7 +3,7 @@ import "./dist-CYZr2fwk.mjs";
|
|
|
3
3
|
var e = {
|
|
4
4
|
"@camstack/sdk": {
|
|
5
5
|
name: "@camstack/sdk",
|
|
6
|
-
version: "1.2.
|
|
6
|
+
version: "1.2.98",
|
|
7
7
|
scope: ["default"],
|
|
8
8
|
loaded: !1,
|
|
9
9
|
from: "addon_stream_broker_widgets",
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.2.
|
|
21
|
+
version: "1.2.178",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_stream_broker_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.2.
|
|
36
|
+
version: "1.2.146",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_stream_broker_widgets",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_segment_demux_js = require("../segment-demux-js-
|
|
1
|
+
const require_segment_demux_js = require("../segment-demux-js-CZefXDLx.js");
|
|
2
2
|
let node_worker_threads = require("node:worker_threads");
|
|
3
3
|
//#region src/stream-broker/recorded/demux-worker-child.ts
|
|
4
4
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as demuxSegmentFullJs } from "../segment-demux-js-
|
|
1
|
+
import { t as demuxSegmentFullJs } from "../segment-demux-js-CFFXVae4.mjs";
|
|
2
2
|
import { parentPort } from "node:worker_threads";
|
|
3
3
|
//#region src/stream-broker/recorded/demux-worker-child.ts
|
|
4
4
|
/**
|
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.2.
|
|
39
|
+
version: "1.2.178",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -45,7 +45,7 @@ async function r() {
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"@camstack/sdk": {
|
|
48
|
-
version: "1.2.
|
|
48
|
+
version: "1.2.98",
|
|
49
49
|
scope: "default",
|
|
50
50
|
shareConfig: {
|
|
51
51
|
singleton: !0,
|
|
@@ -81,7 +81,7 @@ async function r() {
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"@camstack/ui-library": {
|
|
84
|
-
version: "1.2.
|
|
84
|
+
version: "1.2.146",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|
|
@@ -2,26 +2,27 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
+
const require_dist = require("../dist-ByPsWlTa.js");
|
|
7
|
+
const require_node = require("../node-CNPnaux4.js");
|
|
7
8
|
const require_restream_intent = require("../restream-intent-B1Difcnq.js");
|
|
8
9
|
const require_remote_restream = require("../remote-restream-CO36Sr30.js");
|
|
9
10
|
const require_retire_root_keys = require("../retire-root-keys-Csb8z2f3.js");
|
|
10
|
-
const require_segment_demux_js = require("../segment-demux-js-
|
|
11
|
+
const require_segment_demux_js = require("../segment-demux-js-CZefXDLx.js");
|
|
11
12
|
let node_os = require("node:os");
|
|
12
|
-
node_os =
|
|
13
|
+
node_os = require_chunk.__toESM(node_os);
|
|
13
14
|
let node_crypto = require("node:crypto");
|
|
14
|
-
node_crypto =
|
|
15
|
+
node_crypto = require_chunk.__toESM(node_crypto);
|
|
15
16
|
let node_fs = require("node:fs");
|
|
16
|
-
node_fs =
|
|
17
|
+
node_fs = require_chunk.__toESM(node_fs);
|
|
17
18
|
let node_path = require("node:path");
|
|
18
|
-
node_path =
|
|
19
|
+
node_path = require_chunk.__toESM(node_path);
|
|
19
20
|
let node_child_process = require("node:child_process");
|
|
20
21
|
let node_fs_promises = require("node:fs/promises");
|
|
21
22
|
let node_url = require("node:url");
|
|
22
23
|
let node_module = require("node:module");
|
|
23
24
|
let node_net = require("node:net");
|
|
24
|
-
node_net =
|
|
25
|
+
node_net = require_chunk.__toESM(node_net);
|
|
25
26
|
let node_dgram = require("node:dgram");
|
|
26
27
|
let events = require("events");
|
|
27
28
|
let net = require("net");
|
|
@@ -8380,14 +8381,14 @@ function depacketizeRfc3640(payload, opts = {
|
|
|
8380
8381
|
}
|
|
8381
8382
|
//#endregion
|
|
8382
8383
|
//#region src/stream-broker/rtsp/audio-rtp-decoder.ts
|
|
8383
|
-
/**
|
|
8384
|
-
var
|
|
8385
|
-
var CHUNK_SAMPLES =
|
|
8384
|
+
/** G.711 is 8 kHz by definition (RFC 3551): the plane carries that rate. */
|
|
8385
|
+
var G711_SAMPLE_RATE = 8e3;
|
|
8386
|
+
var CHUNK_SAMPLES = G711_SAMPLE_RATE * 500 / 1e3;
|
|
8386
8387
|
/**
|
|
8387
|
-
* Decodes G.711 audio RTP packets into PCM f32le chunks.
|
|
8388
|
+
* Decodes G.711 audio RTP packets into PCM f32le chunks at 8 kHz.
|
|
8388
8389
|
*
|
|
8389
|
-
* Buffers decoded samples and emits DecodedAudioChunk when
|
|
8390
|
-
*
|
|
8390
|
+
* Buffers decoded samples and emits a DecodedAudioChunk when ~0.5 s has
|
|
8391
|
+
* accumulated (4000 samples, 16 000 bytes).
|
|
8391
8392
|
*/
|
|
8392
8393
|
var AudioRtpDecoder = class {
|
|
8393
8394
|
codec;
|
|
@@ -8401,18 +8402,14 @@ var AudioRtpDecoder = class {
|
|
|
8401
8402
|
}
|
|
8402
8403
|
/**
|
|
8403
8404
|
* Process a raw RTP packet (header + payload).
|
|
8404
|
-
* Strips the 12-byte RTP header
|
|
8405
|
+
* Strips the 12-byte RTP header and decodes the G.711 payload: one byte,
|
|
8406
|
+
* one 8 kHz sample. Nothing is interpolated here.
|
|
8405
8407
|
*/
|
|
8406
8408
|
processPacket(rtpData) {
|
|
8407
8409
|
if (rtpData.length <= 12) return;
|
|
8408
8410
|
const payload = rtpData.subarray(12);
|
|
8409
8411
|
const decode = this.codec === "PCMU" ? decodeUlaw : decodeAlaw;
|
|
8410
|
-
for (let i = 0; i < payload.length; i++)
|
|
8411
|
-
const current = decode(payload[i]);
|
|
8412
|
-
const next = i + 1 < payload.length ? decode(payload[i + 1]) : current;
|
|
8413
|
-
this.pushSample(current);
|
|
8414
|
-
this.pushSample((current + next) * .5);
|
|
8415
|
-
}
|
|
8412
|
+
for (let i = 0; i < payload.length; i++) this.pushSample(decode(payload[i]));
|
|
8416
8413
|
}
|
|
8417
8414
|
/** Flush any remaining buffered samples as a partial chunk. */
|
|
8418
8415
|
flush() {
|
|
@@ -8420,7 +8417,7 @@ var AudioRtpDecoder = class {
|
|
|
8420
8417
|
const data = Buffer.from(this.buffer.buffer, this.buffer.byteOffset, this.bufferOffset * 4);
|
|
8421
8418
|
this.onChunk({
|
|
8422
8419
|
data: Buffer.from(data),
|
|
8423
|
-
sampleRate:
|
|
8420
|
+
sampleRate: G711_SAMPLE_RATE,
|
|
8424
8421
|
channels: 1,
|
|
8425
8422
|
timestamp: Date.now()
|
|
8426
8423
|
});
|
|
@@ -8436,7 +8433,7 @@ var AudioRtpDecoder = class {
|
|
|
8436
8433
|
const data = Buffer.from(this.buffer.buffer, this.buffer.byteOffset, CHUNK_SAMPLES * 4);
|
|
8437
8434
|
this.onChunk({
|
|
8438
8435
|
data: Buffer.from(data),
|
|
8439
|
-
sampleRate:
|
|
8436
|
+
sampleRate: G711_SAMPLE_RATE,
|
|
8440
8437
|
channels: 1,
|
|
8441
8438
|
timestamp: Date.now()
|
|
8442
8439
|
});
|
|
@@ -13694,7 +13691,9 @@ var StreamBroker = class StreamBroker {
|
|
|
13694
13691
|
this.logger?.info("native: audio decoder initialized", { meta: {
|
|
13695
13692
|
codec: codecUpper,
|
|
13696
13693
|
sampleRate: audioTrack.clockRate,
|
|
13697
|
-
channels: audioTrack.channels
|
|
13694
|
+
channels: audioTrack.channels,
|
|
13695
|
+
planeSampleRate: G711_SAMPLE_RATE,
|
|
13696
|
+
planeFormat: "f32le"
|
|
13698
13697
|
} });
|
|
13699
13698
|
} else if (this.audioCodecApi) {
|
|
13700
13699
|
const capCfg = this.buildAudioCodecSessionConfig(audioTrack);
|
|
@@ -27485,7 +27484,7 @@ async function demuxSegmentToPcmu(bytes, ffmpegPath = "ffmpeg") {
|
|
|
27485
27484
|
}
|
|
27486
27485
|
//#endregion
|
|
27487
27486
|
//#region src/stream-broker/recorded/segment-audio-js.ts
|
|
27488
|
-
var import_mp4box_all = /* @__PURE__ */
|
|
27487
|
+
var import_mp4box_all = /* @__PURE__ */ require_chunk.__toESM(require_segment_demux_js.require_mp4box_all());
|
|
27489
27488
|
/** True for an mp4box audio codec string that is Opus (`Opus`/`opus`). */
|
|
27490
27489
|
function isOpusCodec(codec) {
|
|
27491
27490
|
return /^opus$/i.test(codec);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { r as __toESM } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { A as addonWidgetsSourceCapability, Bt as invocationFromEncodeProfile, C as RATE_CONTROL_RELAXED, F as cameraStreamsCapability, Ft as webrtcSessionCapability, Gt as DeviceFeature, H as deriveBatteryPresence, Ht as BOOT_RECOVERY_BACKOFF_MS, I as createHwAccelCache, It as errMsg, K as egressTranscodeSharingKey, Kt as DeviceType, L as createLogChannelsProvider, Lt as AUDIO_PRESETS, Mt as streamBrokerCapability, O as RingBuffer, P as batteryCapability, Qt as nodePin, Tt as resolveEgressDecodeHwAccel, Ut as BaseAddon, Vt as isSoftwareDecode, Wt as CAM_PROFILE_ORDER, Xt as makeProfileBrokerId, Yt as isEvent, Zt as makeSourceBrokerId, an as boolean, at as logChannelsCapability, cn as literal, en as parseProfileBrokerId, fn as record, h as EncodeProfileSchema, hn as EventCategory, i as BatteryStatusSchema, in as array, it as loadContributionCapability, ln as number, mn as union, on as discriminatedUnion, pn as string, q as egressTransportFromRequest, qt as createEvent, rn as _enum, st as maskUrlCredentials, un as object, w as RATE_CONTROL_TIGHT, z as declareLogChannel, zt as buildFfmpegArgs$1 } from "../dist-
|
|
3
|
-
import { i as NO_COST_CLAIM, n as Fmp4FragmentChild, r as Fmp4FragmentPlane, t as ChildCostRegistry } from "../node-
|
|
2
|
+
import { A as addonWidgetsSourceCapability, Bt as invocationFromEncodeProfile, C as RATE_CONTROL_RELAXED, F as cameraStreamsCapability, Ft as webrtcSessionCapability, Gt as DeviceFeature, H as deriveBatteryPresence, Ht as BOOT_RECOVERY_BACKOFF_MS, I as createHwAccelCache, It as errMsg, K as egressTranscodeSharingKey, Kt as DeviceType, L as createLogChannelsProvider, Lt as AUDIO_PRESETS, Mt as streamBrokerCapability, O as RingBuffer, P as batteryCapability, Qt as nodePin, Tt as resolveEgressDecodeHwAccel, Ut as BaseAddon, Vt as isSoftwareDecode, Wt as CAM_PROFILE_ORDER, Xt as makeProfileBrokerId, Yt as isEvent, Zt as makeSourceBrokerId, an as boolean, at as logChannelsCapability, cn as literal, en as parseProfileBrokerId, fn as record, h as EncodeProfileSchema, hn as EventCategory, i as BatteryStatusSchema, in as array, it as loadContributionCapability, ln as number, mn as union, on as discriminatedUnion, pn as string, q as egressTransportFromRequest, qt as createEvent, rn as _enum, st as maskUrlCredentials, un as object, w as RATE_CONTROL_TIGHT, z as declareLogChannel, zt as buildFfmpegArgs$1 } from "../dist-ClihWGOZ.mjs";
|
|
3
|
+
import { i as NO_COST_CLAIM, n as Fmp4FragmentChild, r as Fmp4FragmentPlane, t as ChildCostRegistry } from "../node-DiaTmz84.mjs";
|
|
4
4
|
import { c as PREBUFFER_MAX_MS, d as resolvePrebuffer, i as parseRestreamPath, l as capPreRollRequestMs, n as NO_DECLARATION, u as prebufferRetentionMs } from "../restream-intent-DWe2kInY.mjs";
|
|
5
5
|
import { n as profileForStreamId } from "../remote-restream-BeHi78PZ.mjs";
|
|
6
6
|
import { n as RowMapStore, t as retireRootKeys } from "../retire-root-keys-DZvlso2l.mjs";
|
|
7
|
-
import { i as require_mp4box_all, n as demuxSegmentPreferJs, r as runFfmpegOnce, t as demuxSegmentFullJs } from "../segment-demux-js-
|
|
7
|
+
import { i as require_mp4box_all, n as demuxSegmentPreferJs, r as runFfmpegOnce, t as demuxSegmentFullJs } from "../segment-demux-js-CFFXVae4.mjs";
|
|
8
8
|
import { createRequire } from "node:module";
|
|
9
9
|
import * as os from "node:os";
|
|
10
10
|
import { networkInterfaces, tmpdir } from "node:os";
|
|
@@ -8377,14 +8377,14 @@ function depacketizeRfc3640(payload, opts = {
|
|
|
8377
8377
|
}
|
|
8378
8378
|
//#endregion
|
|
8379
8379
|
//#region src/stream-broker/rtsp/audio-rtp-decoder.ts
|
|
8380
|
-
/**
|
|
8381
|
-
var
|
|
8382
|
-
var CHUNK_SAMPLES =
|
|
8380
|
+
/** G.711 is 8 kHz by definition (RFC 3551): the plane carries that rate. */
|
|
8381
|
+
var G711_SAMPLE_RATE = 8e3;
|
|
8382
|
+
var CHUNK_SAMPLES = G711_SAMPLE_RATE * 500 / 1e3;
|
|
8383
8383
|
/**
|
|
8384
|
-
* Decodes G.711 audio RTP packets into PCM f32le chunks.
|
|
8384
|
+
* Decodes G.711 audio RTP packets into PCM f32le chunks at 8 kHz.
|
|
8385
8385
|
*
|
|
8386
|
-
* Buffers decoded samples and emits DecodedAudioChunk when
|
|
8387
|
-
*
|
|
8386
|
+
* Buffers decoded samples and emits a DecodedAudioChunk when ~0.5 s has
|
|
8387
|
+
* accumulated (4000 samples, 16 000 bytes).
|
|
8388
8388
|
*/
|
|
8389
8389
|
var AudioRtpDecoder = class {
|
|
8390
8390
|
codec;
|
|
@@ -8398,18 +8398,14 @@ var AudioRtpDecoder = class {
|
|
|
8398
8398
|
}
|
|
8399
8399
|
/**
|
|
8400
8400
|
* Process a raw RTP packet (header + payload).
|
|
8401
|
-
* Strips the 12-byte RTP header
|
|
8401
|
+
* Strips the 12-byte RTP header and decodes the G.711 payload: one byte,
|
|
8402
|
+
* one 8 kHz sample. Nothing is interpolated here.
|
|
8402
8403
|
*/
|
|
8403
8404
|
processPacket(rtpData) {
|
|
8404
8405
|
if (rtpData.length <= 12) return;
|
|
8405
8406
|
const payload = rtpData.subarray(12);
|
|
8406
8407
|
const decode = this.codec === "PCMU" ? decodeUlaw : decodeAlaw;
|
|
8407
|
-
for (let i = 0; i < payload.length; i++)
|
|
8408
|
-
const current = decode(payload[i]);
|
|
8409
|
-
const next = i + 1 < payload.length ? decode(payload[i + 1]) : current;
|
|
8410
|
-
this.pushSample(current);
|
|
8411
|
-
this.pushSample((current + next) * .5);
|
|
8412
|
-
}
|
|
8408
|
+
for (let i = 0; i < payload.length; i++) this.pushSample(decode(payload[i]));
|
|
8413
8409
|
}
|
|
8414
8410
|
/** Flush any remaining buffered samples as a partial chunk. */
|
|
8415
8411
|
flush() {
|
|
@@ -8417,7 +8413,7 @@ var AudioRtpDecoder = class {
|
|
|
8417
8413
|
const data = Buffer.from(this.buffer.buffer, this.buffer.byteOffset, this.bufferOffset * 4);
|
|
8418
8414
|
this.onChunk({
|
|
8419
8415
|
data: Buffer.from(data),
|
|
8420
|
-
sampleRate:
|
|
8416
|
+
sampleRate: G711_SAMPLE_RATE,
|
|
8421
8417
|
channels: 1,
|
|
8422
8418
|
timestamp: Date.now()
|
|
8423
8419
|
});
|
|
@@ -8433,7 +8429,7 @@ var AudioRtpDecoder = class {
|
|
|
8433
8429
|
const data = Buffer.from(this.buffer.buffer, this.buffer.byteOffset, CHUNK_SAMPLES * 4);
|
|
8434
8430
|
this.onChunk({
|
|
8435
8431
|
data: Buffer.from(data),
|
|
8436
|
-
sampleRate:
|
|
8432
|
+
sampleRate: G711_SAMPLE_RATE,
|
|
8437
8433
|
channels: 1,
|
|
8438
8434
|
timestamp: Date.now()
|
|
8439
8435
|
});
|
|
@@ -13691,7 +13687,9 @@ var StreamBroker = class StreamBroker {
|
|
|
13691
13687
|
this.logger?.info("native: audio decoder initialized", { meta: {
|
|
13692
13688
|
codec: codecUpper,
|
|
13693
13689
|
sampleRate: audioTrack.clockRate,
|
|
13694
|
-
channels: audioTrack.channels
|
|
13690
|
+
channels: audioTrack.channels,
|
|
13691
|
+
planeSampleRate: G711_SAMPLE_RATE,
|
|
13692
|
+
planeFormat: "f32le"
|
|
13695
13693
|
} });
|
|
13696
13694
|
} else if (this.audioCodecApi) {
|
|
13697
13695
|
const capCfg = this.buildAudioCodecSessionConfig(audioTrack);
|
|
@@ -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-CtdpN7Sz.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|