@torrent-tv/proxy 2.100.15 → 2.101.0
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/bin/cli.js +2 -0
- package/package.json +1 -1
- package/server.js +4 -0
- package/services/encode/EncodeInputs.js +16 -2
- package/services/server/wire-outputs.js +7 -0
package/bin/cli.js
CHANGED
|
@@ -90,6 +90,7 @@ program
|
|
|
90
90
|
.option("--no-port-mapping", "Disable automatic UPnP/NAT-PMP port mapping")
|
|
91
91
|
.option("--delivery-sink", "Serve /api/delivery-sink, a torrent-free byte stream for delivery testing")
|
|
92
92
|
.option("--pin-preset <name>", "Encode every software picture at this libx264 preset only, for runs that must be compared at one quality (off by default)")
|
|
93
|
+
.option("--input-stretch-bytes <bytes>", "Size every original-input stretch to this many bytes instead of copy rate times open, for runs that compare input sizes; memory, downloaded bytes and the plan still bound it (off by default)")
|
|
93
94
|
.option("--heap-snapshots", "Write a heap snapshot of a thread whose memory reaches a new high-water; each one stops that thread while it is written (off by default)")
|
|
94
95
|
.option("--profile-start <seconds>", "Profile the CPU of the main thread and the torrent thread for this many seconds from the first source opened, written beside the state (off by default)")
|
|
95
96
|
.option(
|
|
@@ -399,6 +400,7 @@ try {
|
|
|
399
400
|
profileStartSeconds: Number(options.profileStart) || 0,
|
|
400
401
|
heapSnapshots: options.heapSnapshots === true,
|
|
401
402
|
pinnedPreset: typeof options.pinPreset === "string" && options.pinPreset.trim() ? options.pinPreset.trim() : null,
|
|
403
|
+
inputStretchBytes: Number(options.inputStretchBytes) > 0 ? Math.floor(Number(options.inputStretchBytes)) : null,
|
|
402
404
|
// Late-bound the same way `webRtcManager` is below: the torrent pool is
|
|
403
405
|
// built inside `startProxyServer`, before `dataChannelHandler` — the
|
|
404
406
|
// thing that actually owns a channel to push down — exists.
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -134,6 +134,9 @@ export async function startProxyServer({
|
|
|
134
134
|
// The one software preset every picture is encoded at, for runs compared at
|
|
135
135
|
// one quality; null leaves the choice to the machine.
|
|
136
136
|
pinnedPreset = null,
|
|
137
|
+
// The size every original-input stretch is given in place of copy rate
|
|
138
|
+
// times open, for runs that compare input sizes; null keeps the rule.
|
|
139
|
+
inputStretchBytes = null,
|
|
137
140
|
// What viewers' connections carry beyond the film, per byte of film; the
|
|
138
141
|
// transport counts it and is built after this server, so it is late-bound.
|
|
139
142
|
serviceShare = () => null,
|
|
@@ -854,6 +857,7 @@ export async function startProxyServer({
|
|
|
854
857
|
let sourcePreparation;
|
|
855
858
|
const outputParts = wireOutputs({
|
|
856
859
|
pinnedPreset,
|
|
860
|
+
inputStretchBytes,
|
|
857
861
|
indexMemory,
|
|
858
862
|
serviceShare,
|
|
859
863
|
readMetadataActivity: () => containerOrchestrator.activity(),
|
|
@@ -62,10 +62,20 @@ export class EncodeInputs {
|
|
|
62
62
|
* @type {(output: object, from: number, to: number, input: object) => void}
|
|
63
63
|
*/
|
|
64
64
|
#stretchCopied;
|
|
65
|
+
/**
|
|
66
|
+
* A stretch size the operator named for comparison runs
|
|
67
|
+
* (`--input-stretch-bytes`), in place of copy rate times open; null keeps
|
|
68
|
+
* the measured rule. Only the target changes: memory, downloaded bytes and
|
|
69
|
+
* the plan's bound still end a stretch (torrent-tv/meta#182).
|
|
70
|
+
*
|
|
71
|
+
* @type {number | null}
|
|
72
|
+
*/
|
|
73
|
+
#fixedStretchBytes;
|
|
65
74
|
|
|
66
75
|
constructor({ resolve, readRanges, heldRanges = null, reviseBudget, changed, failed, capacity = () => null, urgent = () => true,
|
|
67
|
-
rankAt = () => null, openOf = () => null, log = () => {}, now = Date.now, stretchCopied = () => {} }) {
|
|
76
|
+
rankAt = () => null, openOf = () => null, log = () => {}, now = Date.now, stretchCopied = () => {}, stretchBytes = null }) {
|
|
68
77
|
this.#stretchCopied = stretchCopied;
|
|
78
|
+
this.#fixedStretchBytes = Number.isSafeInteger(stretchBytes) && stretchBytes > 0 ? stretchBytes : null;
|
|
69
79
|
this.#openOf = openOf;
|
|
70
80
|
this.#resolve = resolve;
|
|
71
81
|
this.#read = readRanges;
|
|
@@ -344,6 +354,10 @@ export class EncodeInputs {
|
|
|
344
354
|
#sizingFor(output) {
|
|
345
355
|
const rate = middleOf(this.#copyRates);
|
|
346
356
|
const open = this.#openOf(output);
|
|
357
|
+
if (this.#fixedStretchBytes !== null) {
|
|
358
|
+
return { bytes: this.#fixedStretchBytes, openMeasured: true, openSeconds: open?.seconds ?? null,
|
|
359
|
+
copyBytesPerMs: rate, fixed: true };
|
|
360
|
+
}
|
|
347
361
|
return rate === null || !open ? null : { bytes: Math.floor(rate * open.seconds * 1000),
|
|
348
362
|
openMeasured: open.measured, openSeconds: open.seconds, copyBytesPerMs: rate };
|
|
349
363
|
}
|
|
@@ -607,7 +621,7 @@ export class EncodeInputs {
|
|
|
607
621
|
if (result.kind === "result") {
|
|
608
622
|
this.#log(`encode input selection of ${addressOf(output)}: ${JSON.stringify({
|
|
609
623
|
from, requestedTo: request.to, serves, floor, targetEnd, chosenEnd: end,
|
|
610
|
-
targetBytes: target, minimumBytes: minimum, inputBytes: result.bytes,
|
|
624
|
+
targetBytes: target, targetFixed: sizing?.fixed === true, minimumBytes: minimum, inputBytes: result.bytes,
|
|
611
625
|
copyBytesPerMs: sizing?.copyBytesPerMs ?? null, openSeconds: sizing?.openSeconds ?? null,
|
|
612
626
|
openMeasured: sizing?.openMeasured ?? null, reservations, probes
|
|
613
627
|
})}`);
|
|
@@ -195,6 +195,9 @@ export function wireOutputs({
|
|
|
195
195
|
// A software preset every picture is encoded at, for runs compared at one
|
|
196
196
|
// quality (`--pin-preset`); null leaves the choice to the machine.
|
|
197
197
|
pinnedPreset = null,
|
|
198
|
+
// A size every original-input stretch is given in place of copy rate
|
|
199
|
+
// times open (`--input-stretch-bytes`); null keeps the rule.
|
|
200
|
+
inputStretchBytes = null,
|
|
198
201
|
// What every encoder this host may use was qualified and measured to do at
|
|
199
202
|
// startup, by kind (`encode/calibration.js`). Takes the place of the one
|
|
200
203
|
// array above, which a test may still hand in on its own.
|
|
@@ -1097,6 +1100,7 @@ export function wireOutputs({
|
|
|
1097
1100
|
readRanges: readEncodeRanges,
|
|
1098
1101
|
heldRanges: readEncodeHeldRanges,
|
|
1099
1102
|
stretchCopied,
|
|
1103
|
+
stretchBytes: inputStretchBytes,
|
|
1100
1104
|
reviseBudget: () => parts.machineBudget.revise("memory", "admitted encode inputs"),
|
|
1101
1105
|
capacity: () => parts.machineBudget.capacityOf("memory"),
|
|
1102
1106
|
// How long this output's input takes to open, from the one owner of start
|
|
@@ -1120,6 +1124,9 @@ export function wireOutputs({
|
|
|
1120
1124
|
parts.serving.invalidateWaits(output);
|
|
1121
1125
|
}
|
|
1122
1126
|
}) : null);
|
|
1127
|
+
if (parts.encodeInputs && inputStretchBytes) {
|
|
1128
|
+
logger.info(`encode input: every original-input stretch sized to ${inputStretchBytes} bytes (--input-stretch-bytes)`);
|
|
1129
|
+
}
|
|
1123
1130
|
// One owner of the disk, and the list of what takes it lives with the owner.
|
|
1124
1131
|
parts.machineBudget = wireMachineBudget({
|
|
1125
1132
|
segmentStore: parts.segmentStore,
|