@camstack/addon-pipeline 1.2.369 → 1.2.370
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 +3 -3
- package/dist/audio-analyzer/index.mjs +3 -3
- package/dist/{custom-model-catalog-C3PYjN8c.js → custom-model-catalog-BFosahFu.js} +2 -2
- package/dist/{custom-model-catalog-uHzR2xWY.mjs → custom-model-catalog-CVbK0xKc.mjs} +2 -2
- package/dist/detection-pipeline/index.js +4 -4
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-DKSwif2M.mjs → dist-CbFPOFAD.mjs} +97 -11
- package/dist/{dist-D3PtiAhd.js → dist-jkwxbcbK.js} +97 -11
- package/dist/{model-catalogs-CVd4TcTQ.mjs → model-catalogs-DJmwfLfC.mjs} +1 -1
- package/dist/{model-catalogs-kGqNkIuV.js → model-catalogs-Ds2hC2Br.js} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-C_Fqti3A.mjs → node-C-2fB9kH.mjs} +1 -1
- package/dist/{node--15m1sN3.js → node-C_1U1uzn.js} +1 -1
- package/dist/pipeline-runner/index.js +3 -3
- package/dist/pipeline-runner/index.mjs +3 -3
- package/dist/{process-memory-Dq_Omilr.mjs → process-memory-B3I-NvnX.mjs} +1 -1
- package/dist/{process-memory-DELcKfDf.js → process-memory-Cfh1BQYg.js} +1 -1
- package/dist/recorder/index.js +2 -2
- package/dist/recorder/index.mjs +2 -2
- package/dist/{segment-demux-js-BTUbXt7b.mjs → segment-demux-js-D3JBJeN6.mjs} +1 -1
- package/dist/{segment-demux-js-DSYbEqvj.js → segment-demux-js-uxBcJy15.js} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CMHYV8dG.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DwwDKaZJ.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Bna0L8uC.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BAvXcDKy.mjs +26 -0
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-Cz1kTtGe.mjs → hostInit-DVwYY7oo.mjs} +2 -2
- package/dist/stream-broker/index.js +302 -90
- package/dist/stream-broker/index.mjs +302 -90
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DBku2n1V.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DNC4tvrD.mjs +0 -26
|
@@ -3,12 +3,12 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
7
|
-
const require_node = require("../node
|
|
6
|
+
const require_dist = require("../dist-jkwxbcbK.js");
|
|
7
|
+
const require_node = require("../node-C_1U1uzn.js");
|
|
8
8
|
const require_restream_intent = require("../restream-intent-7uDNqMKs.js");
|
|
9
9
|
const require_remote_restream = require("../remote-restream-CO36Sr30.js");
|
|
10
10
|
const require_retire_root_keys = require("../retire-root-keys-Csb8z2f3.js");
|
|
11
|
-
const require_segment_demux_js = require("../segment-demux-js-
|
|
11
|
+
const require_segment_demux_js = require("../segment-demux-js-uxBcJy15.js");
|
|
12
12
|
let node_os = require("node:os");
|
|
13
13
|
node_os = require_chunk.__toESM(node_os);
|
|
14
14
|
let node_crypto = require("node:crypto");
|
|
@@ -2367,6 +2367,10 @@ var PacedRtpReplay = class {
|
|
|
2367
2367
|
this.enqueuedLive++;
|
|
2368
2368
|
return true;
|
|
2369
2369
|
}
|
|
2370
|
+
/** Visit every still-queued item (probe time only; no allocation). */
|
|
2371
|
+
forEachQueued(visit) {
|
|
2372
|
+
for (const item of this.queue) visit(item);
|
|
2373
|
+
}
|
|
2370
2374
|
/** Cancel the replay: pending packets are dropped, `onDone` fires with
|
|
2371
2375
|
* `aborted: true`. Safe to call multiple times / before `start`. */
|
|
2372
2376
|
abort() {
|
|
@@ -3086,6 +3090,133 @@ var RtpPacketizer = class {
|
|
|
3086
3090
|
}
|
|
3087
3091
|
};
|
|
3088
3092
|
//#endregion
|
|
3093
|
+
//#region src/stream-broker/stream-broker/owned-buffer.ts
|
|
3094
|
+
/**
|
|
3095
|
+
* Buffers that enter a LONG-LIVED ring own their backing store.
|
|
3096
|
+
*
|
|
3097
|
+
* Node serves `Buffer.from(...)`, `Buffer.allocUnsafe(n)` and `Buffer.concat`
|
|
3098
|
+
* below `Buffer.poolSize >>> 1` (4 KiB) as views of shared 8 KiB pool slabs.
|
|
3099
|
+
* That is the right choice for the ingest path — a start code, a 4-byte
|
|
3100
|
+
* interleave header, a 1.3 KB RTP packet that is fanned out and forgotten
|
|
3101
|
+
* within a tick — and the wrong one for anything RETAINED: a 600-byte NAL kept
|
|
3102
|
+
* for 60 s in a clip ring pins its whole slab, and with it every short-lived
|
|
3103
|
+
* packet that happened to be allocated beside it. On the hub that held
|
|
3104
|
+
* 550–980 MB of ArrayBuffers for ~150–250 MB of payload, and the full GCs the
|
|
3105
|
+
* pinned slabs caused ran every 0.2–0.5 s at 40–65 % of a core.
|
|
3106
|
+
*
|
|
3107
|
+
* The ring byte caps counted payload bytes, so they never saw it. Both rings
|
|
3108
|
+
* now pass every entry through {@link detachFromPool} on the way in and
|
|
3109
|
+
* account it with {@link backingStoreBytes}, so the cap measures what the
|
|
3110
|
+
* entry costs. Short-lived traffic stays pooled.
|
|
3111
|
+
*/
|
|
3112
|
+
/** True when `buf` is the whole of its ArrayBuffer — nothing else shares it. */
|
|
3113
|
+
function ownsBackingStore(buf) {
|
|
3114
|
+
return buf.byteOffset === 0 && buf.buffer.byteLength === buf.length;
|
|
3115
|
+
}
|
|
3116
|
+
/**
|
|
3117
|
+
* What retaining `buf` really costs: its own length when it owns its
|
|
3118
|
+
* ArrayBuffer, the whole shared slab when it is a view of one.
|
|
3119
|
+
*/
|
|
3120
|
+
function backingStoreBytes(buf) {
|
|
3121
|
+
return ownsBackingStore(buf) ? buf.length : buf.buffer.byteLength;
|
|
3122
|
+
}
|
|
3123
|
+
/**
|
|
3124
|
+
* `buf` itself when it already owns its ArrayBuffer (decided by inspecting the
|
|
3125
|
+
* buffer, never by its size: whether a large `allocUnsafe` is pooled is a Node
|
|
3126
|
+
* runtime detail), else a copy that does. One copy, never two: a buffer that is
|
|
3127
|
+
* already unpooled is returned as-is.
|
|
3128
|
+
*/
|
|
3129
|
+
function detachFromPool(buf) {
|
|
3130
|
+
if (ownsBackingStore(buf)) return buf;
|
|
3131
|
+
const owned = Buffer.allocUnsafeSlow(buf.length);
|
|
3132
|
+
buf.copy(owned);
|
|
3133
|
+
return owned;
|
|
3134
|
+
}
|
|
3135
|
+
/**
|
|
3136
|
+
* A copy of `src[start, end)` that OWNS its backing store — the shape a reader
|
|
3137
|
+
* hands out when the packet it cuts from its socket buffer is going to be
|
|
3138
|
+
* retained anyway.
|
|
3139
|
+
*
|
|
3140
|
+
* Every source video packet is: `captureRtpForPreBuffer` keeps it for the life
|
|
3141
|
+
* of a GOP, and the restreamer's keyframe cache keeps the keyframe ones. With
|
|
3142
|
+
* the readers cutting packets as `Buffer.from(subarray)` — a pooled view — the
|
|
3143
|
+
* ring then had to copy each one a second time to own it: two copies of every
|
|
3144
|
+
* packet on the ingest path (measured 15.1 + 14.8 MB/s on the hub's load).
|
|
3145
|
+
* Cutting the packet owned up front makes the ring's and the cache's
|
|
3146
|
+
* `detachFromPool` an identity, so the packet is copied once and shared by the
|
|
3147
|
+
* reader's fan-out, the ring, the cache and every session's write queue.
|
|
3148
|
+
*/
|
|
3149
|
+
function copyOwned(src, start, end) {
|
|
3150
|
+
const owned = Buffer.allocUnsafeSlow(end - start);
|
|
3151
|
+
src.copy(owned, 0, start, end);
|
|
3152
|
+
recordCopyOwned(end - start);
|
|
3153
|
+
return owned;
|
|
3154
|
+
}
|
|
3155
|
+
/** Accumulates entries; each distinct backing ArrayBuffer is summed once. */
|
|
3156
|
+
var BackingTally = class {
|
|
3157
|
+
seen = /* @__PURE__ */ new Set();
|
|
3158
|
+
entries = 0;
|
|
3159
|
+
payload = 0;
|
|
3160
|
+
naive = 0;
|
|
3161
|
+
distinct = 0;
|
|
3162
|
+
capped = false;
|
|
3163
|
+
add(buf) {
|
|
3164
|
+
if (this.entries >= 2e5) {
|
|
3165
|
+
this.capped = true;
|
|
3166
|
+
return;
|
|
3167
|
+
}
|
|
3168
|
+
this.entries += 1;
|
|
3169
|
+
this.payload += buf.length;
|
|
3170
|
+
const backing = backingStoreBytes(buf);
|
|
3171
|
+
this.naive += backing;
|
|
3172
|
+
if (!this.seen.has(buf.buffer)) {
|
|
3173
|
+
this.seen.add(buf.buffer);
|
|
3174
|
+
this.distinct += backing;
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
totals() {
|
|
3178
|
+
return {
|
|
3179
|
+
entries: this.entries,
|
|
3180
|
+
payloadBytes: this.payload,
|
|
3181
|
+
naiveBackingBytes: this.naive,
|
|
3182
|
+
distinctBackingBytes: this.distinct,
|
|
3183
|
+
capped: this.capped
|
|
3184
|
+
};
|
|
3185
|
+
}
|
|
3186
|
+
};
|
|
3187
|
+
/** Add every populated slot of a sender's `rtpCache` (≤ RTP_HISTORY_SIZE). */
|
|
3188
|
+
function tallyRtpCache(tally, cache) {
|
|
3189
|
+
if (cache === void 0) return;
|
|
3190
|
+
for (let i = 0; i < cache.length; i++) {
|
|
3191
|
+
const slot = cache[i];
|
|
3192
|
+
if (slot !== void 0) tally.add(slot.payload);
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
/** Distinct backing bytes a session pins across all four structures. */
|
|
3196
|
+
function sessionBackingBytes(r) {
|
|
3197
|
+
return r.rtpCache.distinctBackingBytes + r.pushQueue.distinctBackingBytes + r.rtpReplay.distinctBackingBytes + r.scrub.distinctBackingBytes;
|
|
3198
|
+
}
|
|
3199
|
+
function mbOf(bytes) {
|
|
3200
|
+
return Number((bytes / (1024 * 1024)).toFixed(1));
|
|
3201
|
+
}
|
|
3202
|
+
/** Flat log meta for the session open / close lines. */
|
|
3203
|
+
function sessionMemMeta(r) {
|
|
3204
|
+
return {
|
|
3205
|
+
rtpCacheEntries: r.rtpCache.entries,
|
|
3206
|
+
rtpCachePayloadMb: mbOf(r.rtpCache.payloadBytes),
|
|
3207
|
+
rtpCacheNaiveMb: mbOf(r.rtpCache.naiveBackingBytes),
|
|
3208
|
+
rtpCacheBackingMb: mbOf(r.rtpCache.distinctBackingBytes),
|
|
3209
|
+
pushQueueFrames: r.pushQueue.entries,
|
|
3210
|
+
pushQueueBackingMb: mbOf(r.pushQueue.distinctBackingBytes),
|
|
3211
|
+
rtpReplayPackets: r.rtpReplay.entries,
|
|
3212
|
+
rtpReplayBackingMb: mbOf(r.rtpReplay.distinctBackingBytes),
|
|
3213
|
+
scrubPayloadMb: mbOf(r.scrub.payloadBytes),
|
|
3214
|
+
scrubBackingMb: mbOf(r.scrub.distinctBackingBytes),
|
|
3215
|
+
sessionBackingMb: mbOf(sessionBackingBytes(r)),
|
|
3216
|
+
memCapped: r.rtpCache.capped || r.pushQueue.capped || r.rtpReplay.capped || r.scrub.capped
|
|
3217
|
+
};
|
|
3218
|
+
}
|
|
3219
|
+
//#endregion
|
|
3089
3220
|
//#region src/stream-broker/stream-broker/broker-mem-probe.ts
|
|
3090
3221
|
/**
|
|
3091
3222
|
* broker-mem-probe — what owns the broker runner's NATIVE memory.
|
|
@@ -3329,8 +3460,58 @@ function formatBrokerMem(input) {
|
|
|
3329
3460
|
const w = input.worker;
|
|
3330
3461
|
if (w !== void 0 && w !== null) parts.push(`workers=${w.workers}`, `workerHeapMb=${mb(w.heapBytes)}`, `workerPhysicalMb=${mb(w.physicalBytes)}`, `workerUsedMb=${mb(w.usedBytes)}`, `workerAgeS=${Math.round(w.maxAgeMs / 1e3)}`, `workerIdleExit=${w.idleTerminates ? "yes" : "never"}`);
|
|
3331
3462
|
parts.push(`brokers=${samples.length}`, `ingesting=${ingesting}`, `annexBPlanes=${planes}`, `rtsp=${rtsp}`, `webrtc=${input.webrtcSessions}`, `encoded=${kindList(consumers)}`, `audioSubs=${audio}`, `pipeClients=${pipe}`, `egress=${input.egressTranscodes}`, `children=${input.childProcesses}`, `opened=${churn.opened}`, `closed=${churn.closed}`, `openedKinds=${kindList(churn.openedByKind)}`, `closedKinds=${kindList(churn.closedByKind)}`, `preBufferMb=${mb(pre)}`, `clipMb=${mb(clip)}`, `rtpRingMb=${mb(rtp)}`, `keyframeMb=${mb(kf)}`, `writeQueueSumMb=${mb(qSum)}`, `writeQueueMaxMb=${mb(qMax)}`, `copiedPackets=${copied.packets}`, `copiedMb=${mb(copied.bytes)}`, `topRingMb=${top === "" ? "none" : top}`);
|
|
3463
|
+
const sessions = input.sessions;
|
|
3464
|
+
if (sessions !== void 0) parts.push(...formatSessionMem(sessions, input));
|
|
3332
3465
|
return parts.join(" ");
|
|
3333
3466
|
}
|
|
3467
|
+
/**
|
|
3468
|
+
* Sums over every WebRTC session, each distinct backing store counted once PER
|
|
3469
|
+
* SESSION, and the three views of the NACK history so pinning shows:
|
|
3470
|
+
* `rtpCachePayloadMb` (what the packets say), `rtpCacheNaiveMb` (each entry's
|
|
3471
|
+
* own backing, a shared slab repeated) and `rtpCacheBackingMb` (each slab once).
|
|
3472
|
+
* `fragMb` is the brk heap NOT explained by v8 external memory.
|
|
3473
|
+
*/
|
|
3474
|
+
function formatSessionMem(sessions, input) {
|
|
3475
|
+
let rtpEntries = 0;
|
|
3476
|
+
let rtpPayload = 0;
|
|
3477
|
+
let rtpNaive = 0;
|
|
3478
|
+
let rtpBacking = 0;
|
|
3479
|
+
let pushFrames = 0;
|
|
3480
|
+
let pushBacking = 0;
|
|
3481
|
+
let replayPackets = 0;
|
|
3482
|
+
let replayBacking = 0;
|
|
3483
|
+
let scrubPayload = 0;
|
|
3484
|
+
let scrubBacking = 0;
|
|
3485
|
+
for (const r of sessions) {
|
|
3486
|
+
rtpEntries += r.rtpCache.entries;
|
|
3487
|
+
rtpPayload += r.rtpCache.payloadBytes;
|
|
3488
|
+
rtpNaive += r.rtpCache.naiveBackingBytes;
|
|
3489
|
+
rtpBacking += r.rtpCache.distinctBackingBytes;
|
|
3490
|
+
pushFrames += r.pushQueue.entries;
|
|
3491
|
+
pushBacking += r.pushQueue.distinctBackingBytes;
|
|
3492
|
+
replayPackets += r.rtpReplay.entries;
|
|
3493
|
+
replayBacking += r.rtpReplay.distinctBackingBytes;
|
|
3494
|
+
scrubPayload += r.scrub.payloadBytes;
|
|
3495
|
+
scrubBacking += r.scrub.distinctBackingBytes;
|
|
3496
|
+
}
|
|
3497
|
+
const top = [...sessions].sort((a, b) => sessionBackingBytes(b) - sessionBackingBytes(a)).slice(0, 3).map((r) => `${r.deviceId ?? "x"}:${mb(sessionBackingBytes(r))}`).join(",");
|
|
3498
|
+
const parts = [
|
|
3499
|
+
`rtpCacheEntries=${rtpEntries}`,
|
|
3500
|
+
`rtpCachePayloadMb=${mb(rtpPayload)}`,
|
|
3501
|
+
`rtpCacheNaiveMb=${mb(rtpNaive)}`,
|
|
3502
|
+
`rtpCacheBackingMb=${mb(rtpBacking)}`,
|
|
3503
|
+
`pushQueueFrames=${pushFrames}`,
|
|
3504
|
+
`pushQueueBackingMb=${mb(pushBacking)}`,
|
|
3505
|
+
`rtpReplayPackets=${replayPackets}`,
|
|
3506
|
+
`rtpReplayBackingMb=${mb(replayBacking)}`,
|
|
3507
|
+
`scrubPayloadMb=${mb(scrubPayload)}`,
|
|
3508
|
+
`scrubBackingMb=${mb(scrubBacking)}`
|
|
3509
|
+
];
|
|
3510
|
+
if (input.arrayBuffersBytes !== void 0) parts.push(`arrayBuffersMb=${mb(input.arrayBuffersBytes)}`);
|
|
3511
|
+
if (input.proc.maps !== null && input.v8 !== void 0 && input.v8 !== null) parts.push(`fragMb=${mb(input.proc.maps.heapBytes - input.v8.externalBytes)}`);
|
|
3512
|
+
parts.push(`topSessionMb=${top === "" ? "none" : top}`);
|
|
3513
|
+
return parts;
|
|
3514
|
+
}
|
|
3334
3515
|
/** Count entries named `name` in `process.getActiveResourcesInfo()`. */
|
|
3335
3516
|
function countActiveResources(resources, name) {
|
|
3336
3517
|
let n = 0;
|
|
@@ -3338,69 +3519,6 @@ function countActiveResources(resources, name) {
|
|
|
3338
3519
|
return n;
|
|
3339
3520
|
}
|
|
3340
3521
|
//#endregion
|
|
3341
|
-
//#region src/stream-broker/stream-broker/owned-buffer.ts
|
|
3342
|
-
/**
|
|
3343
|
-
* Buffers that enter a LONG-LIVED ring own their backing store.
|
|
3344
|
-
*
|
|
3345
|
-
* Node serves `Buffer.from(...)`, `Buffer.allocUnsafe(n)` and `Buffer.concat`
|
|
3346
|
-
* below `Buffer.poolSize >>> 1` (4 KiB) as views of shared 8 KiB pool slabs.
|
|
3347
|
-
* That is the right choice for the ingest path — a start code, a 4-byte
|
|
3348
|
-
* interleave header, a 1.3 KB RTP packet that is fanned out and forgotten
|
|
3349
|
-
* within a tick — and the wrong one for anything RETAINED: a 600-byte NAL kept
|
|
3350
|
-
* for 60 s in a clip ring pins its whole slab, and with it every short-lived
|
|
3351
|
-
* packet that happened to be allocated beside it. On the hub that held
|
|
3352
|
-
* 550–980 MB of ArrayBuffers for ~150–250 MB of payload, and the full GCs the
|
|
3353
|
-
* pinned slabs caused ran every 0.2–0.5 s at 40–65 % of a core.
|
|
3354
|
-
*
|
|
3355
|
-
* The ring byte caps counted payload bytes, so they never saw it. Both rings
|
|
3356
|
-
* now pass every entry through {@link detachFromPool} on the way in and
|
|
3357
|
-
* account it with {@link backingStoreBytes}, so the cap measures what the
|
|
3358
|
-
* entry costs. Short-lived traffic stays pooled.
|
|
3359
|
-
*/
|
|
3360
|
-
/** True when `buf` is the whole of its ArrayBuffer — nothing else shares it. */
|
|
3361
|
-
function ownsBackingStore(buf) {
|
|
3362
|
-
return buf.byteOffset === 0 && buf.buffer.byteLength === buf.length;
|
|
3363
|
-
}
|
|
3364
|
-
/**
|
|
3365
|
-
* What retaining `buf` really costs: its own length when it owns its
|
|
3366
|
-
* ArrayBuffer, the whole shared slab when it is a view of one.
|
|
3367
|
-
*/
|
|
3368
|
-
function backingStoreBytes(buf) {
|
|
3369
|
-
return ownsBackingStore(buf) ? buf.length : buf.buffer.byteLength;
|
|
3370
|
-
}
|
|
3371
|
-
/**
|
|
3372
|
-
* `buf` itself when it already owns its ArrayBuffer (decided by inspecting the
|
|
3373
|
-
* buffer, never by its size: whether a large `allocUnsafe` is pooled is a Node
|
|
3374
|
-
* runtime detail), else a copy that does. One copy, never two: a buffer that is
|
|
3375
|
-
* already unpooled is returned as-is.
|
|
3376
|
-
*/
|
|
3377
|
-
function detachFromPool(buf) {
|
|
3378
|
-
if (ownsBackingStore(buf)) return buf;
|
|
3379
|
-
const owned = Buffer.allocUnsafeSlow(buf.length);
|
|
3380
|
-
buf.copy(owned);
|
|
3381
|
-
return owned;
|
|
3382
|
-
}
|
|
3383
|
-
/**
|
|
3384
|
-
* A copy of `src[start, end)` that OWNS its backing store — the shape a reader
|
|
3385
|
-
* hands out when the packet it cuts from its socket buffer is going to be
|
|
3386
|
-
* retained anyway.
|
|
3387
|
-
*
|
|
3388
|
-
* Every source video packet is: `captureRtpForPreBuffer` keeps it for the life
|
|
3389
|
-
* of a GOP, and the restreamer's keyframe cache keeps the keyframe ones. With
|
|
3390
|
-
* the readers cutting packets as `Buffer.from(subarray)` — a pooled view — the
|
|
3391
|
-
* ring then had to copy each one a second time to own it: two copies of every
|
|
3392
|
-
* packet on the ingest path (measured 15.1 + 14.8 MB/s on the hub's load).
|
|
3393
|
-
* Cutting the packet owned up front makes the ring's and the cache's
|
|
3394
|
-
* `detachFromPool` an identity, so the packet is copied once and shared by the
|
|
3395
|
-
* reader's fan-out, the ring, the cache and every session's write queue.
|
|
3396
|
-
*/
|
|
3397
|
-
function copyOwned(src, start, end) {
|
|
3398
|
-
const owned = Buffer.allocUnsafeSlow(end - start);
|
|
3399
|
-
src.copy(owned, 0, start, end);
|
|
3400
|
-
recordCopyOwned(end - start);
|
|
3401
|
-
return owned;
|
|
3402
|
-
}
|
|
3403
|
-
//#endregion
|
|
3404
3522
|
//#region src/stream-broker/rtsp/sdp-builder.ts
|
|
3405
3523
|
function buildSdp(options) {
|
|
3406
3524
|
const { codec, parameterSets, streamName } = options;
|
|
@@ -24943,6 +25061,23 @@ var AdaptiveSession = class AdaptiveSession {
|
|
|
24943
25061
|
} });
|
|
24944
25062
|
}
|
|
24945
25063
|
/** Whether the session has an active feed (vs idle/pooled). */
|
|
25064
|
+
/**
|
|
25065
|
+
* What this session pins outside the heap, by backing store: werift's NACK
|
|
25066
|
+
* history (video + audio, one tally so a slab shared by both counts once) and
|
|
25067
|
+
* the paced replay queue. Probe / lifecycle-line time only — it walks
|
|
25068
|
+
* ≤ 2 × RTP_HISTORY_SIZE slots and the replay tail, never per packet.
|
|
25069
|
+
*/
|
|
25070
|
+
readMemTotals() {
|
|
25071
|
+
const cache = new BackingTally();
|
|
25072
|
+
tallyRtpCache(cache, this.videoSender?.rtpCache);
|
|
25073
|
+
tallyRtpCache(cache, this.audioSender?.rtpCache);
|
|
25074
|
+
const replay = new BackingTally();
|
|
25075
|
+
this.activeRtpReplay?.forEachQueued((pkt) => replay.add(pkt));
|
|
25076
|
+
return {
|
|
25077
|
+
rtpCache: cache.totals(),
|
|
25078
|
+
rtpReplay: replay.totals()
|
|
25079
|
+
};
|
|
25080
|
+
}
|
|
24946
25081
|
get isFeeding() {
|
|
24947
25082
|
return this.feedAbort !== null && !this.feedAbort.signal.aborted;
|
|
24948
25083
|
}
|
|
@@ -28206,6 +28341,13 @@ var ScrubFragmentCache = class {
|
|
|
28206
28341
|
get size() {
|
|
28207
28342
|
return this.map.size;
|
|
28208
28343
|
}
|
|
28344
|
+
/**
|
|
28345
|
+
* Feed every cached access unit to `tally` — the BACKING-store view of what
|
|
28346
|
+
* `byteSize` counts by `.length`. Probe time only (`session-mem.ts`).
|
|
28347
|
+
*/
|
|
28348
|
+
tallyBacking(tally) {
|
|
28349
|
+
for (const frag of this.map.values()) for (const au of frag.aus) tally.add(au.data);
|
|
28350
|
+
}
|
|
28209
28351
|
};
|
|
28210
28352
|
//#endregion
|
|
28211
28353
|
//#region src/stream-broker/recorded/segment-pts-repair.ts
|
|
@@ -35260,7 +35402,8 @@ var BrokerWebrtcServer = class {
|
|
|
35260
35402
|
iceServers: setup.iceServerCount,
|
|
35261
35403
|
codec: setup.sessionCodec,
|
|
35262
35404
|
useRtpRepacketizer: setup.useRtpRepacketizer,
|
|
35263
|
-
relayOnly: opts.relayOnly === true
|
|
35405
|
+
relayOnly: opts.relayOnly === true,
|
|
35406
|
+
...this.sessionMemMetaFor(setup.sessionId)
|
|
35264
35407
|
} });
|
|
35265
35408
|
return {
|
|
35266
35409
|
sessionId: setup.sessionId,
|
|
@@ -35310,7 +35453,8 @@ var BrokerWebrtcServer = class {
|
|
|
35310
35453
|
setupMs,
|
|
35311
35454
|
negotiateMs,
|
|
35312
35455
|
totalMs: Date.now() - offerStart,
|
|
35313
|
-
...setup.setupTimings
|
|
35456
|
+
...setup.setupTimings,
|
|
35457
|
+
...this.sessionMemMetaFor(setup.sessionId)
|
|
35314
35458
|
} });
|
|
35315
35459
|
return {
|
|
35316
35460
|
sessionId: setup.sessionId,
|
|
@@ -35419,7 +35563,7 @@ var BrokerWebrtcServer = class {
|
|
|
35419
35563
|
let framesDroppedSinceLog = 0;
|
|
35420
35564
|
let purgesSinceLog = 0;
|
|
35421
35565
|
let unalignedPurgesSinceLog = 0;
|
|
35422
|
-
const { source, pushFrame, close: closeSource } = createPushFrameSource((count, keyframeAligned) => {
|
|
35566
|
+
const { source, pushFrame, close: closeSource, forEachQueued: forEachQueuedFrame } = createPushFrameSource((count, keyframeAligned) => {
|
|
35423
35567
|
framesDroppedSinceLog += count;
|
|
35424
35568
|
purgesSinceLog += 1;
|
|
35425
35569
|
if (!keyframeAligned) unalignedPurgesSinceLog += 1;
|
|
@@ -35698,6 +35842,7 @@ var BrokerWebrtcServer = class {
|
|
|
35698
35842
|
unsubSdpParams,
|
|
35699
35843
|
unsubSourceRestart,
|
|
35700
35844
|
closeSource,
|
|
35845
|
+
forEachQueuedFrame,
|
|
35701
35846
|
...talkback !== void 0 ? { closeTalkback: () => void talkback.close() } : {},
|
|
35702
35847
|
rebind: {
|
|
35703
35848
|
deviceId,
|
|
@@ -35990,6 +36135,7 @@ var BrokerWebrtcServer = class {
|
|
|
35990
36135
|
})
|
|
35991
36136
|
});
|
|
35992
36137
|
entry.timeline = timeline;
|
|
36138
|
+
entry.scrubCache = scrubCache;
|
|
35993
36139
|
sessionLogger.info("recorded: TimelineSession wired (control accessors present)", { meta: {
|
|
35994
36140
|
sessionId,
|
|
35995
36141
|
deviceId
|
|
@@ -36121,6 +36267,55 @@ var BrokerWebrtcServer = class {
|
|
|
36121
36267
|
return this.sessions.size;
|
|
36122
36268
|
}
|
|
36123
36269
|
/**
|
|
36270
|
+
* One session's pinned-memory reading, by backing store (`session-mem.ts`).
|
|
36271
|
+
* Walks the session's NACK history, push queue, replay tail and scrub cache:
|
|
36272
|
+
* call at probe / lifecycle-line time only.
|
|
36273
|
+
*/
|
|
36274
|
+
readSessionMem(sessionId, entry) {
|
|
36275
|
+
const own = entry.session.readMemTotals();
|
|
36276
|
+
const push = new BackingTally();
|
|
36277
|
+
entry.forEachQueuedFrame((mf) => push.add(mf.frame.data));
|
|
36278
|
+
const scrub = new BackingTally();
|
|
36279
|
+
entry.scrubCache?.tallyBacking(scrub);
|
|
36280
|
+
return {
|
|
36281
|
+
sessionId,
|
|
36282
|
+
deviceId: deviceIdFromBrokerId(entry.brokerId),
|
|
36283
|
+
rtpCache: own.rtpCache,
|
|
36284
|
+
rtpReplay: own.rtpReplay,
|
|
36285
|
+
pushQueue: push.totals(),
|
|
36286
|
+
scrub: scrub.totals()
|
|
36287
|
+
};
|
|
36288
|
+
}
|
|
36289
|
+
/** Every live session's reading, for the `[broker-mem]` line. */
|
|
36290
|
+
getSessionMemReadings() {
|
|
36291
|
+
const readings = [];
|
|
36292
|
+
for (const [sessionId, entry] of this.sessions) try {
|
|
36293
|
+
readings.push(this.readSessionMem(sessionId, entry));
|
|
36294
|
+
} catch (err) {
|
|
36295
|
+
this.logger.warn("session memory reading failed", {
|
|
36296
|
+
tags: { deviceId: deviceIdFromBrokerId(entry.brokerId) },
|
|
36297
|
+
meta: {
|
|
36298
|
+
sessionId,
|
|
36299
|
+
error: require_dist.errMsg(err)
|
|
36300
|
+
}
|
|
36301
|
+
});
|
|
36302
|
+
}
|
|
36303
|
+
return readings;
|
|
36304
|
+
}
|
|
36305
|
+
/** The counters a lifecycle line carries; empty when the session is gone. */
|
|
36306
|
+
sessionMemMetaFor(sessionId) {
|
|
36307
|
+
const entry = this.sessions.get(sessionId);
|
|
36308
|
+
if (entry === void 0) return {};
|
|
36309
|
+
try {
|
|
36310
|
+
return sessionMemMeta(this.readSessionMem(sessionId, entry));
|
|
36311
|
+
} catch (err) {
|
|
36312
|
+
return {
|
|
36313
|
+
memReadFailed: true,
|
|
36314
|
+
memReadError: require_dist.errMsg(err)
|
|
36315
|
+
};
|
|
36316
|
+
}
|
|
36317
|
+
}
|
|
36318
|
+
/**
|
|
36124
36319
|
* People watching LIVE through this server, per camera (`live-viewers.ts`):
|
|
36125
36320
|
* sessions of a viewer kind whose track is on the live edge. A session on a
|
|
36126
36321
|
* recorded playhead is not watching live; the system's own subscriptions
|
|
@@ -36929,6 +37124,15 @@ var BrokerWebrtcServer = class {
|
|
|
36929
37124
|
cleanupSession(sessionId) {
|
|
36930
37125
|
const entry = this.sessions.get(sessionId);
|
|
36931
37126
|
if (!entry) return;
|
|
37127
|
+
const deviceId = deviceIdFromBrokerId(entry.brokerId);
|
|
37128
|
+
this.logger.info("WebRTC session closing: pinned-memory counters", {
|
|
37129
|
+
tags: { deviceId },
|
|
37130
|
+
meta: {
|
|
37131
|
+
sessionId,
|
|
37132
|
+
deviceId,
|
|
37133
|
+
...this.sessionMemMetaFor(sessionId)
|
|
37134
|
+
}
|
|
37135
|
+
});
|
|
36932
37136
|
this.sessions.delete(sessionId);
|
|
36933
37137
|
reportConsumerEvent(this.logger, "detach", `webrtc:${entry.consumerKind}`, entry.rebind?.deviceId, this.sessions.size);
|
|
36934
37138
|
entry.pendingSwitch?.cancel();
|
|
@@ -37123,28 +37327,33 @@ function createPushFrameSource(onFramesDropped) {
|
|
|
37123
37327
|
});
|
|
37124
37328
|
}
|
|
37125
37329
|
};
|
|
37126
|
-
|
|
37127
|
-
|
|
37128
|
-
|
|
37129
|
-
|
|
37130
|
-
|
|
37131
|
-
|
|
37132
|
-
|
|
37133
|
-
continue;
|
|
37134
|
-
}
|
|
37135
|
-
if (done) return;
|
|
37136
|
-
const result = await new Promise((r) => {
|
|
37137
|
-
resolve = r;
|
|
37138
|
-
});
|
|
37139
|
-
if (result.done) return;
|
|
37140
|
-
yield result.value;
|
|
37330
|
+
const source = (async function* () {
|
|
37331
|
+
try {
|
|
37332
|
+
while (true) {
|
|
37333
|
+
const item = queue.shift();
|
|
37334
|
+
if (item) {
|
|
37335
|
+
yield item;
|
|
37336
|
+
continue;
|
|
37141
37337
|
}
|
|
37142
|
-
|
|
37143
|
-
|
|
37338
|
+
if (done) return;
|
|
37339
|
+
const result = await new Promise((r) => {
|
|
37340
|
+
resolve = r;
|
|
37341
|
+
});
|
|
37342
|
+
if (result.done) return;
|
|
37343
|
+
yield result.value;
|
|
37144
37344
|
}
|
|
37145
|
-
}
|
|
37345
|
+
} finally {
|
|
37346
|
+
done = true;
|
|
37347
|
+
}
|
|
37348
|
+
})();
|
|
37349
|
+
const forEachQueued = (visit) => {
|
|
37350
|
+
for (const frame of queue) visit(frame);
|
|
37351
|
+
};
|
|
37352
|
+
return {
|
|
37353
|
+
source,
|
|
37146
37354
|
pushFrame,
|
|
37147
|
-
close
|
|
37355
|
+
close,
|
|
37356
|
+
forEachQueued
|
|
37148
37357
|
};
|
|
37149
37358
|
}
|
|
37150
37359
|
//#endregion
|
|
@@ -37678,7 +37887,9 @@ async function emitOnce(deps) {
|
|
|
37678
37887
|
churn: consumerChurn.drain(),
|
|
37679
37888
|
copied: readCopyOwnedTotals(),
|
|
37680
37889
|
v8: readV8Heap(),
|
|
37681
|
-
worker
|
|
37890
|
+
worker,
|
|
37891
|
+
sessions: deps.sessionMem(),
|
|
37892
|
+
arrayBuffersBytes: process.memoryUsage().arrayBuffers
|
|
37682
37893
|
});
|
|
37683
37894
|
deps.logger.info(line);
|
|
37684
37895
|
}
|
|
@@ -38229,7 +38440,8 @@ var StreamBrokerAddon = class extends require_dist.BaseAddon {
|
|
|
38229
38440
|
this.stopBrokerMemReport = startBrokerMemReport({
|
|
38230
38441
|
logger: this.ctx.logger,
|
|
38231
38442
|
manager: this.brokerManager,
|
|
38232
|
-
webrtcSessions: () => webrtcServer.getSessionCount()
|
|
38443
|
+
webrtcSessions: () => webrtcServer.getSessionCount(),
|
|
38444
|
+
sessionMem: () => webrtcServer.getSessionMemReadings()
|
|
38233
38445
|
});
|
|
38234
38446
|
const widgetsProvider = { listWidgets: async () => [{
|
|
38235
38447
|
tab: "device-tab",
|