@torrent-tv/proxy 2.89.1 → 2.89.2
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/.claude/commands/opsx/apply.md +155 -155
- package/.claude/commands/opsx/archive.md +160 -160
- package/.claude/commands/opsx/explore.md +174 -174
- package/.claude/commands/opsx/propose.md +109 -109
- package/.claude/commands/opsx/sync.md +143 -143
- package/.claude/skills/openspec-apply-change/SKILL.md +159 -159
- package/.claude/skills/openspec-archive-change/SKILL.md +117 -117
- package/.claude/skills/openspec-explore/SKILL.md +289 -289
- package/.claude/skills/openspec-propose/SKILL.md +113 -113
- package/.claude/skills/openspec-sync-specs/SKILL.md +147 -147
- package/.dockerignore +5 -5
- package/AGENTS.md +6 -1
- package/CHANGELOG.md +2299 -2288
- package/Dockerfile +30 -30
- package/LICENSE +16 -16
- package/README.md +369 -369
- package/assets/calibration/NOTICE.md +100 -100
- package/assets/diagnostics/sctpstate.gdb +31 -31
- package/bin/cli.js +684 -684
- package/bin/thread-pool.js +30 -30
- package/docs/download-architecture.md +261 -261
- package/docs/encode-architecture.md +729 -729
- package/docs/encode-run-state.md +96 -96
- package/docs/logs.md +97 -97
- package/docs/playback-start-forecast.md +42 -8
- package/docs/socks5-egress-research.md +114 -114
- package/docs/storage-architecture.md +267 -267
- package/knip.json +14 -14
- package/openspec/changes/adaptive-bitrate/design.md +92 -92
- package/openspec/changes/adaptive-bitrate/proposal.md +56 -56
- package/openspec/changes/adaptive-bitrate/specs/adaptive-bitrate/spec.md +51 -51
- package/openspec/changes/adaptive-bitrate/tasks.md +40 -40
- package/openspec/changes/binary-distribution/.openspec.yaml +2 -2
- package/openspec/changes/binary-distribution/proposal.md +53 -53
- package/openspec/changes/chunked-request-bodies/design.md +81 -81
- package/openspec/changes/chunked-request-bodies/proposal.md +53 -53
- package/openspec/changes/chunked-request-bodies/specs/chunked-request-bodies/spec.md +30 -30
- package/openspec/changes/chunked-request-bodies/tasks.md +40 -40
- package/openspec/changes/cold-start/design.md +98 -98
- package/openspec/changes/cold-start/proposal.md +62 -62
- package/openspec/changes/cold-start/specs/cold-start/spec.md +47 -47
- package/openspec/changes/cold-start/tasks.md +48 -48
- package/openspec/changes/disk-cap/.openspec.yaml +2 -2
- package/openspec/changes/disk-cap/proposal.md +37 -37
- package/openspec/changes/disk-cap/specs/disk-cap/spec.md +25 -25
- package/openspec/changes/disk-cap/tasks.md +19 -19
- package/openspec/changes/proxy-observability/.openspec.yaml +2 -2
- package/openspec/changes/proxy-observability/design.md +38 -38
- package/openspec/changes/proxy-observability/proposal.md +49 -49
- package/openspec/changes/proxy-observability/specs/observability/spec.md +33 -33
- package/openspec/changes/proxy-observability/tasks.md +21 -21
- package/openspec/changes/seek-debounce/design.md +118 -118
- package/openspec/changes/seek-debounce/proposal.md +59 -59
- package/openspec/changes/seek-debounce/specs/seek-debounce/spec.md +41 -41
- package/openspec/changes/seek-debounce/tasks.md +33 -33
- package/openspec/changes/subtitle-language/.openspec.yaml +2 -2
- package/openspec/changes/subtitle-language/proposal.md +50 -50
- package/openspec/changes/subtitle-language/specs/subtitle-language/spec.md +34 -34
- package/openspec/changes/subtitle-language/tasks.md +26 -26
- package/openspec/changes/track-selection/.openspec.yaml +2 -2
- package/openspec/changes/track-selection/design.md +47 -47
- package/openspec/changes/track-selection/proposal.md +45 -45
- package/openspec/changes/track-selection/specs/track-selection/spec.md +41 -41
- package/openspec/changes/track-selection/tasks.md +20 -20
- package/openspec/changes/transcode-quality/.openspec.yaml +2 -2
- package/openspec/changes/transcode-quality/proposal.md +51 -51
- package/openspec/changes/transcode-quality/specs/transcode-quality/spec.md +139 -139
- package/openspec/changes/transcode-quality/tasks.md +63 -63
- package/openspec/config.yaml +38 -38
- package/package.json +1 -1
- package/public/.well-known/appspecific/com.chrome.devtools.json +1 -1
- package/research/delivery-wedge-stand-ladder-2026-09-13.md +329 -329
- package/research/double-spawn-2026-09-10.md +171 -171
- package/research/handover-2026-09-13.md +209 -209
- package/research/handover-reader-claims-removal-2026-09-12.md +166 -166
- package/research/piece-withdrawn-but-still-claimed-2026-09-12.md +175 -175
- package/research/preset-benchmark-size-scaling-2026-08-22.md +55 -55
- package/research/priority-map-is-the-truth-2026-09-12.md +225 -225
- package/routes/api/client-logs/post.js +86 -86
- package/routes/api/delivery-sink/get.js +72 -72
- package/routes/api/link-probe/get.js +51 -51
- package/routes/api/playback-plan/audio-tracks/post.js +29 -29
- package/routes/api/playback-plan/post.js +53 -53
- package/routes/api/sources/post.js +36 -36
- package/routes/api/sources/stats/get.js +132 -132
- package/routes/api/sources/warm/post.js +217 -217
- package/routes/api/subtitles/get.js +230 -230
- package/routes/api/transcode-sessions/fragment-far/post.js +60 -60
- package/routes/api/transcode-sessions/net-report/post.js +138 -138
- package/routes/api/transcode-sessions/post.js +178 -178
- package/routes/api/transcode-sessions/progress/get.js +27 -27
- package/routes/api/transcode-sessions/release/post.js +41 -41
- package/routes/api/transcode-sessions/seek/post.js +63 -63
- package/routes/health/get.js +13 -13
- package/routes/healthz/get.js +13 -13
- package/routes/stream/get.js +380 -380
- package/routes/transcode/audio-file/get.js +64 -64
- package/routes/transcode/audio-warm/get.js +95 -95
- package/routes/transcode/session-file/get.js +52 -52
- package/routes/transcode/variant-file/get.js +95 -95
- package/routes/transcode/variant-warm/get.js +84 -84
- package/scripts/render-run-graph.js +173 -173
- package/services/encode/CoverageMap.js +428 -428
- package/services/encode/CushionReport.js +345 -345
- package/services/encode/EncodeAdmission.js +376 -376
- package/services/encode/EncodeOrchestrator.js +1217 -1217
- package/services/encode/EncodePlan.js +1366 -1366
- package/services/encode/EncodeRun.js +813 -813
- package/services/encode/Encoder.js +142 -142
- package/services/encode/EncoderSelection.js +38 -38
- package/services/encode/LocalObservations.js +359 -359
- package/services/encode/NvencEncoder.js +50 -50
- package/services/encode/OutputTimes.js +579 -579
- package/services/encode/QsvEncoder.js +58 -58
- package/services/encode/Renditions.js +2282 -2282
- package/services/encode/RunProgress.js +84 -84
- package/services/encode/SegmentDemand.js +95 -95
- package/services/encode/SoftwareEncoder.js +121 -121
- package/services/encode/V4l2m2mEncoder.js +53 -53
- package/services/encode/VaapiEncoder.js +66 -66
- package/services/encode/args.js +418 -418
- package/services/encode/available-share.js +89 -89
- package/services/encode/calibration.js +361 -361
- package/services/encode/contention.js +128 -128
- package/services/encode/decode-cost-fit.js +363 -363
- package/services/encode/encode-exit.js +114 -114
- package/services/encode/encode-run-state.js +551 -551
- package/services/encode/encoder-readings.js +45 -45
- package/services/encode/fingerprint.js +322 -322
- package/services/encode/host-load.js +174 -174
- package/services/encode/index.js +9 -9
- package/services/encode/learned-median.js +90 -90
- package/services/encode/output/EncodedOutput.js +57 -57
- package/services/encode/output/Output.js +131 -131
- package/services/encode/output/OutputCatalog.js +414 -414
- package/services/encode/output/OutputSpec.js +390 -390
- package/services/encode/output/Timeline.js +308 -308
- package/services/encode/output/cut-grid.js +107 -107
- package/services/encode/output/ladder.js +32 -32
- package/services/encode/output/playlists.js +284 -284
- package/services/encode/output/rates.js +125 -125
- package/services/encode/output-key-format.js +21 -21
- package/services/encode/quality/HostLoad.js +525 -525
- package/services/encode/quality/HostTimings.js +249 -249
- package/services/encode/quality/OutputQualityState.js +28 -28
- package/services/encode/quality/QualityController.js +935 -935
- package/services/encode/quality/QualityOffer.js +416 -416
- package/services/encode/quality/drain-threat.js +47 -47
- package/services/encode/quality/link-budget.js +349 -349
- package/services/encode/quality/output-format.js +319 -319
- package/services/encode/quality/serving-output.js +216 -216
- package/services/encode/quality/visible-rung.js +57 -57
- package/services/encode/run-budget.js +97 -97
- package/services/encode/run-costs.js +155 -155
- package/services/encode/run-inputs.js +42 -42
- package/services/encode/segment-formats/fmp4.js +476 -458
- package/services/encode/segment-formats/index.js +103 -85
- package/services/encode/segment-formats/init-compat.js +324 -324
- package/services/encode/segment-formats/mp4-boxes.js +604 -541
- package/services/encode/segment-formats/mpegts.js +134 -134
- package/services/encode/start-stop-cost.js +178 -178
- package/services/encode/throughput.js +97 -97
- package/services/encode/torrent-cost.js +88 -88
- package/services/identity/installation-id.js +38 -38
- package/services/media/SourceFile.js +298 -298
- package/services/media/SubtitleOrchestrator.js +167 -167
- package/services/media/container/KeyframeTable.js +272 -272
- package/services/media/container/ebml-reader.js +159 -159
- package/services/media/ffmpeg-banner.js +260 -260
- package/services/media/keyframe-probe.js +157 -157
- package/services/media/media-info-probe.js +93 -93
- package/services/media/playback-planner.js +931 -931
- package/services/media/tracks/AudioTrack.js +143 -143
- package/services/media/tracks/ImageSubtitleTrack.js +19 -19
- package/services/media/tracks/SubtitleTrack.js +38 -38
- package/services/media/tracks/VideoTrack.js +33 -33
- package/services/media/tracks/audio-bound.js +233 -233
- package/services/media/tracks/index.js +15 -15
- package/services/media/tracks/language-detect.js +174 -174
- package/services/server/OutputLifecycle.js +418 -418
- package/services/server/SegmentServing.js +1150 -1150
- package/services/server/ViewerRequests.js +790 -786
- package/services/server/WaitLedger.js +142 -142
- package/services/server/controllers/PlaybackController.js +40 -40
- package/services/server/controllers/SubtitleController.js +109 -109
- package/services/server/http-responses.js +60 -60
- package/services/server/transcode-session-files.js +325 -325
- package/services/server/wire-outputs.js +1024 -1020
- package/services/storage/Diagnostics.js +202 -202
- package/services/storage/MachineBudget.js +235 -235
- package/services/storage/allowance.js +107 -107
- package/services/storage/core-dumps.js +106 -106
- package/services/storage/files/CompletedFiles.js +391 -391
- package/services/storage/files/piece-from-whole-file.js +118 -118
- package/services/storage/free.js +71 -71
- package/services/storage/keep.js +48 -48
- package/services/storage/machine-memory.js +56 -56
- package/services/storage/memory-report.js +575 -575
- package/services/storage/piece-store/piece-disk-store.js +539 -539
- package/services/storage/piece-store/piece-lru.js +495 -495
- package/services/storage/returns.js +103 -103
- package/services/storage/segment-store/SegmentStore.js +1255 -1255
- package/services/storage/wire.js +175 -175
- package/services/torrent/demand/DemandRegister.js +202 -202
- package/services/torrent/demand/Urgency.js +137 -137
- package/services/torrent/demand/Window.js +118 -118
- package/services/torrent/demand/index.js +8 -8
- package/services/torrent/demand/pieces.js +140 -140
- package/services/torrent/download/SwarmSelection.js +386 -386
- package/services/torrent/download/registry.js +102 -102
- package/services/torrent/download/withdraw-claim.js +80 -80
- package/services/torrent/files.js +455 -455
- package/services/torrent/naming.js +619 -619
- package/services/torrent/piece-store-of.js +29 -29
- package/services/torrent/supply-margin.js +262 -262
- package/services/torrent/worker/background-fill.js +213 -213
- package/services/torrent/worker/channel.js +271 -271
- package/services/torrent/worker/client.js +836 -836
- package/services/torrent/worker/fastest-wires.js +342 -342
- package/services/torrent/worker/handle-state.js +23 -23
- package/services/torrent/worker/install-webrtc-shim.js +32 -32
- package/services/torrent/worker/piece-reader.js +1078 -1078
- package/services/torrent/worker/pool-adapter.js +371 -371
- package/services/torrent/worker/protocol.js +184 -184
- package/services/torrent/worker/resume-warm.js +107 -107
- package/services/torrent/worker/webrtc-shim.js +219 -219
- package/services/transport/delivery-probe.js +842 -842
- package/services/transport/health-collector.js +53 -53
- package/services/transport/nat-classifier.js +231 -231
- package/services/transport/packet-witness.js +808 -808
- package/services/transport/port-mapper.js +235 -235
- package/services/transport/registry-api.js +81 -81
- package/services/transport/tunnel-client.js +447 -447
- package/services/transport/usrsctp-state.js +175 -175
- package/services/transport/webrtc-manager.js +484 -484
- package/services/viewer/Assignments.js +340 -340
- package/services/viewer/PriorityOrchestrator.js +325 -325
- package/services/viewer/Viewer.js +691 -691
- package/services/viewer/Viewers.js +368 -368
- package/services/viewer/active-output.js +37 -37
- package/services/viewer/audio-start.js +46 -46
- package/services/viewer/buffer-trend.js +81 -81
- package/services/viewer/choices.js +647 -647
- package/services/viewer/media-time.js +355 -0
- package/services/{server → viewer}/playback-readiness.js +635 -516
- package/services/viewer/positions.js +126 -126
- package/services/viewer/report-intake.js +46 -46
- package/store/source-registry.js +71 -71
- package/test/asset-paths.test.js +28 -28
- package/test/audio-buffer-continuity.test.js +77 -70
- package/test/audio-inventory.test.js +212 -212
- package/test/audio-track-bitrate.test.js +40 -40
- package/test/auto-quality-step.test.js +707 -707
- package/test/available-share.test.js +76 -76
- package/test/background-fill.test.js +190 -190
- package/test/client-log-file.test.js +110 -110
- package/test/completed-files.test.js +115 -115
- package/test/concurrent-cost.test.js +148 -148
- package/test/container-media-info.test.js +228 -228
- package/test/contention.test.js +76 -76
- package/test/core-dumps.test.js +57 -57
- package/test/coverage-follows-the-disk.test.js +228 -228
- package/test/coverage-map.test.js +195 -195
- package/test/cue-push-carries-what-the-walk-found.test.js +58 -58
- package/test/cut-times-timeline.test.js +65 -65
- package/test/cuts-follow-published-grid.test.js +109 -109
- package/test/data-channel-frame.test.js +63 -63
- package/test/data-channel-viewer-lifecycle.test.js +92 -92
- package/test/dead-torrent-handle.test.js +52 -52
- package/test/declared-rates.test.js +116 -116
- package/test/declared-tracks.test.js +43 -43
- package/test/decode-cost-fit.test.js +202 -202
- package/test/decode-cost.test.js +462 -462
- package/test/delivery-probe.test.js +393 -393
- package/test/demand-register.test.js +206 -206
- package/test/dht-bootstrap.test.js +72 -72
- package/test/drain-threat.test.js +65 -65
- package/test/duplicate-add.test.js +48 -48
- package/test/encode-admission.test.js +146 -146
- package/test/encode-cost.test.js +283 -283
- package/test/encode-exit.test.js +111 -111
- package/test/encode-orchestrator.test.js +419 -419
- package/test/encode-plan-viewers.test.js +718 -718
- package/test/encode-plan.test.js +545 -545
- package/test/encode-run-state.test.js +314 -314
- package/test/encode-run.test.js +162 -162
- package/test/encode-slope.test.js +46 -46
- package/test/encoded-output.test.js +39 -39
- package/test/encoder-kinds.test.js +122 -122
- package/test/encoder-readings.test.js +46 -46
- package/test/every-claimant-is-told-its-share.test.js +152 -152
- package/test/failed-encoder-still-serves-what-exists.test.js +354 -354
- package/test/failed-start-breaker.test.js +202 -202
- package/test/fastest-wires.test.js +143 -143
- package/test/ffmpeg-stream-counts.test.js +78 -78
- package/test/file-edges.test.js +191 -191
- package/test/fmp4-presentation-clock.test.js +146 -162
- package/test/fmp4-self-contained.test.js +80 -80
- package/test/fmp4-timestamps.test.js +140 -140
- package/test/fmp4-track-completeness.test.js +41 -41
- package/test/format-keyed-outputs.test.js +78 -78
- package/test/health-metrics.test.js +38 -38
- package/test/held-request-width.test.js +157 -157
- package/test/helpers/encode-run.js +136 -136
- package/test/helpers/manager.js +57 -57
- package/test/helpers/output-spec.js +63 -63
- package/test/host-load.test.js +68 -68
- package/test/index-accuracy-is-about-the-file.test.js +128 -128
- package/test/init-compat.test.js +219 -219
- package/test/input-lost-quiets-the-plan.test.js +261 -261
- package/test/input-unavailable.test.js +48 -48
- package/test/installation-id.test.js +39 -39
- package/test/keeping-period.test.js +83 -83
- package/test/keyframe-index-accuracy.test.js +188 -188
- package/test/keyframes-belong-to-the-file.test.js +249 -249
- package/test/learned-median.test.js +37 -37
- package/test/letting-go-asks-who-is-watching.test.js +191 -191
- package/test/limit-row-by-area.test.js +60 -60
- package/test/link-budget.test.js +112 -112
- package/test/link-probe.test.js +56 -56
- package/test/local-encoding-data.test.js +273 -273
- package/test/logger-repeats.test.js +134 -134
- package/test/look-ahead-coverage.test.js +56 -56
- package/test/manager-surface.test.js +292 -292
- package/test/matroska-cues-track.test.js +192 -192
- package/test/media-time.test.js +62 -0
- package/test/memory-budget.test.js +390 -390
- package/test/move-cost.test.js +216 -216
- package/test/mp4-subtitles.test.js +173 -173
- package/test/one-authority.test.js +285 -285
- package/test/one-budget.test.js +149 -149
- package/test/one-resource-divided.test.js +185 -185
- package/test/one-serving-output-per-height.test.js +458 -458
- package/test/orchestrator-wired.test.js +206 -206
- package/test/output-catalog.test.js +39 -39
- package/test/output-shape.test.js +21 -21
- package/test/output-spec.test.js +251 -251
- package/test/output-speed.test.js +88 -88
- package/test/outputs-being-prepared.test.js +40 -40
- package/test/packet-witness-ring.test.js +236 -236
- package/test/packet-witness.test.js +148 -148
- package/test/piece-disk-store.test.js +401 -401
- package/test/piece-from-whole-file.test.js +129 -129
- package/test/piece-lru.test.js +319 -319
- package/test/piece-reader.test.js +162 -162
- package/test/piece-selection-offset.test.js +85 -85
- package/test/piece-store-eviction.test.js +595 -595
- package/test/piece-store-never-refuses.test.js +153 -153
- package/test/piece-store-reservations.test.js +403 -403
- package/test/piece-store-slow-disk.test.js +159 -159
- package/test/piece-tail.test.js +97 -97
- package/test/plan-host-timings.test.js +68 -68
- package/test/plan-is-steady.test.js +225 -225
- package/test/playback-readiness.test.js +518 -483
- package/test/playback-start-regressions.test.js +101 -99
- package/test/priority-map-download.test.js +174 -174
- package/test/priority-map-emptied.test.js +204 -204
- package/test/priority-map-per-output.test.js +215 -215
- package/test/priority-map.test.js +163 -163
- package/test/probe-wedge-certainty.test.js +60 -60
- package/test/produced-copy-choice.test.js +213 -213
- package/test/published-timeline.test.js +83 -83
- package/test/quality-offer.test.js +162 -162
- package/test/quality-variants.test.js +1257 -1257
- package/test/rate-control-in-the-output.test.js +180 -180
- package/test/read-survives-withdrawal.test.js +164 -164
- package/test/read-window.test.js +365 -365
- package/test/resume-warm.test.js +39 -39
- package/test/run-graph-drift.test.js +37 -37
- package/test/run-inputs.test.js +80 -80
- package/test/run-intervals.test.js +100 -100
- package/test/run-position-follows-published-grid.test.js +89 -89
- package/test/run-progress.test.js +65 -65
- package/test/same-height-switch.test.js +664 -664
- package/test/seek-frees-the-viewers-requests.test.js +217 -217
- package/test/seek-landing.test.js +109 -109
- package/test/seek-target-not-superseded.test.js +195 -195
- package/test/segment-closed-on-both-branches.test.js +96 -96
- package/test/segment-cut-times.test.js +63 -63
- package/test/segment-demand.test.js +80 -80
- package/test/segment-hold-supersede.test.js +91 -91
- package/test/segment-judged-by-its-own-header.test.js +221 -221
- package/test/segment-store-eviction.test.js +247 -247
- package/test/segment-store.test.js +352 -352
- package/test/segment-true-start.test.js +86 -86
- package/test/segments-are-shared.test.js +176 -176
- package/test/send-chunk-bytes.test.js +86 -86
- package/test/serving-existing-output.test.js +105 -105
- package/test/serving-output.test.js +102 -102
- package/test/shared-piece-store.test.js +310 -310
- package/test/sidecar-naming.test.js +142 -142
- package/test/soundtrack-rate-bound.test.js +289 -289
- package/test/source-file.test.js +133 -133
- package/test/source-registry.test.js +18 -18
- package/test/split-a-stretch.test.js +139 -139
- package/test/stale-request-after-seek.test.js +158 -158
- package/test/startup-readings.test.js +124 -124
- package/test/stream-route.test.js +209 -209
- package/test/subtitle-cue-framing.test.js +200 -200
- package/test/subtitle-cue-source.test.js +102 -102
- package/test/subtitle-cursor.test.js +63 -63
- package/test/subtitle-defaults.test.js +118 -118
- package/test/subtitle-language.test.js +252 -252
- package/test/supply-margin.test.js +177 -177
- package/test/swarm-follows-readers.test.js +174 -174
- package/test/swarm-reach.test.js +130 -130
- package/test/swarm-selection.test.js +220 -220
- package/test/tail-duplication.test.js +167 -167
- package/test/the-channel-has-both-ends.test.js +91 -91
- package/test/the-torrent-thread-serves-bytes.test.js +107 -107
- package/test/thread-pool.test.js +53 -53
- package/test/timeline.test.js +84 -84
- package/test/torrent-contents.test.js +235 -235
- package/test/torrent-cost.test.js +71 -71
- package/test/torrent-files.test.js +221 -221
- package/test/torrent-naming.test.js +255 -255
- package/test/tracks-begin-together.test.js +209 -209
- package/test/tunnel-renewal.test.js +167 -167
- package/test/two-viewers-one-picture.test.js +504 -504
- package/test/upload-hurry.test.js +186 -186
- package/test/usrsctp-state.test.js +131 -131
- package/test/video-facts.test.js +102 -102
- package/test/viewer-assignments.test.js +143 -143
- package/test/viewer-outputs.test.js +285 -285
- package/test/viewer-presence.test.js +116 -116
- package/test/viewer-requests-admission.test.js +89 -89
- package/test/viewer-states.test.js +189 -189
- package/test/viewer-subtitle-subscription.test.js +96 -96
- package/test/viewer.test.js +139 -139
- package/test/viewing-generations.test.js +390 -390
- package/test/visible-rung.test.js +37 -37
- package/test/wait-ledger.test.js +100 -100
- package/test/webrtc-shim.test.js +149 -149
- package/test/wedge-certainty.test.js +131 -131
- package/test/whole-file-held-read.test.js +30 -30
- package/test/withdraw-piece-claim.test.js +212 -212
- package/test/worker-channel.test.js +158 -158
- package/utils/client-log-file.js +151 -151
- package/utils/logger.js +312 -312
- package/utils/parse-range.js +25 -25
- package/utils/perf.js +59 -59
- package/utils/torrent-source-key.js +38 -38
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
# Calibration clips — attribution
|
|
2
|
-
|
|
3
|
-
The clips in this folder are excerpts from **"Meridian"**, part of
|
|
4
|
-
[Netflix Open Content](https://opencontent.netflix.com/), licensed under the
|
|
5
|
-
**Creative Commons Attribution 4.0 International (CC BY 4.0)** licence:
|
|
6
|
-
<https://creativecommons.org/licenses/by/4.0/>.
|
|
7
|
-
|
|
8
|
-
They were cut from `Meridian/Meridian_UHD4k5994_HDR_P3PQ.mp4` and re-encoded to
|
|
9
|
-
H.264 High, 24 fps, 2 s each, no audio:
|
|
10
|
-
|
|
11
|
-
| file | resolution | bitrate |
|
|
12
|
-
|---|---|---|
|
|
13
|
-
| `cal-h264-1080-hi.mp4` | 1920×1080 | 9.36 Mbit/s |
|
|
14
|
-
| `cal-h264-1080-lo.mp4` | 1920×1080 | 1.00 Mbit/s |
|
|
15
|
-
| `cal-h264-720-hi.mp4` | 1280×720 | 9.95 Mbit/s |
|
|
16
|
-
| `cal-h264-720-lo.mp4` | 1280×720 | 1.04 Mbit/s |
|
|
17
|
-
| `cal-h264-480-hi.mp4` | 854×480 | 9.48 Mbit/s |
|
|
18
|
-
| `cal-h264-480-lo.mp4` | 854×480 | 1.25 Mbit/s |
|
|
19
|
-
|
|
20
|
-
## Why six, and why this grid
|
|
21
|
-
|
|
22
|
-
`services/encode/hwaccel.js` decodes them at startup and fits the host's decode cost,
|
|
23
|
-
`a × Mpixel/s + b × Mbit/s + c`, from the measurements
|
|
24
|
-
(`services/encode/decode-cost-fit.js`).
|
|
25
|
-
|
|
26
|
-
The set before this one was three clips for three unknowns — an EXACT system,
|
|
27
|
-
with two of the clips sharing a pixel count. Such a system cannot fail visibly:
|
|
28
|
-
it returns whatever satisfies its three equations, and on 2026-08-17 it returned
|
|
29
|
-
`0.007542 × Mpx/s + 0.000000 × Mbit/s + 0.0000 s/s` — the bitrate term and the
|
|
30
|
-
constant exactly zero, so a film's own bitrate never entered its price, and the
|
|
31
|
-
prediction built on it was 1.8-2.2x optimistic against the same file measured
|
|
32
|
-
while playing.
|
|
33
|
-
|
|
34
|
-
Six clips are three sizes × two bitrates, with the two axes varied
|
|
35
|
-
**independently**. That gives three spare measurements, so the fit has a
|
|
36
|
-
residual — something to notice a degeneracy WITH — and lets a term be refused
|
|
37
|
-
when the data does not determine it, instead of being published as a zero that
|
|
38
|
-
looks measured.
|
|
39
|
-
|
|
40
|
-
A 480p clip at 9.5 Mbit/s is not content anyone ships; that is the point. The
|
|
41
|
-
bitrate has to vary at every size, or it cannot be told apart from the size.
|
|
42
|
-
|
|
43
|
-
## Why real footage
|
|
44
|
-
|
|
45
|
-
Grainy live action rather than a generated pattern: measured 2026-08-14 on the
|
|
46
|
-
addon host, this material decodes 11 % away from the film being served, where a
|
|
47
|
-
generated `testsrc2` clip is 158 % away. It also matches most of what the
|
|
48
|
-
product actually plays — a survey of 133 releases (2026-07-10) found ~67 %
|
|
49
|
-
H.264 live action, the rest HEVC, XviD and animation.
|
|
50
|
-
|
|
51
|
-
## Replacing or extending the set
|
|
52
|
-
|
|
53
|
-
Allowed: the benchmark reads each clip's dimensions, frame rate and bitrate from
|
|
54
|
-
ffmpeg's own output rather than from this table. Two rules hold, though:
|
|
55
|
-
|
|
56
|
-
- **more measurements than terms**, or there is no residual and no way to see a
|
|
57
|
-
degenerate fit;
|
|
58
|
-
- **the axes stay independent** — every size at both bitrates. Dropping one cell
|
|
59
|
-
reintroduces the collinearity that produced the zeros above.
|
|
60
|
-
|
|
61
|
-
## One set per codec family
|
|
62
|
-
|
|
63
|
-
A video that has to be RE-ENCODED is by definition one the browser could not
|
|
64
|
-
play, which is to say HEVC, 10-bit or AV1 — so the model was fitted on the one
|
|
65
|
-
codec it is least often asked about. There is now a set per family, and the
|
|
66
|
-
source's own codec chooses the constants.
|
|
67
|
-
|
|
68
|
-
| file | codec | resolution | bitrate |
|
|
69
|
-
|---|---|---|---|
|
|
70
|
-
| `cal-hevc-1080-hi.mp4` | HEVC Main, 8-bit | 1920×1080 | 5.78 Mbit/s |
|
|
71
|
-
| `cal-hevc-1080-lo.mp4` | HEVC Main, 8-bit | 1920×1080 | 0.52 Mbit/s |
|
|
72
|
-
| `cal-hevc-480-hi.mp4` | HEVC Main, 8-bit | 854×480 | 7.76 Mbit/s |
|
|
73
|
-
| `cal-hevc-480-lo.mp4` | HEVC Main, 8-bit | 854×480 | 0.74 Mbit/s |
|
|
74
|
-
| `cal-hevc10-1080-hi.mp4` | HEVC Main 10 | 1920×1080 | 5.82 Mbit/s |
|
|
75
|
-
| `cal-hevc10-1080-lo.mp4` | HEVC Main 10 | 1920×1080 | 0.52 Mbit/s |
|
|
76
|
-
| `cal-hevc10-480-hi.mp4` | HEVC Main 10 | 854×480 | 6.95 Mbit/s |
|
|
77
|
-
| `cal-hevc10-480-lo.mp4` | HEVC Main 10 | 854×480 | 0.68 Mbit/s |
|
|
78
|
-
|
|
79
|
-
Four per family, not six: two sizes at two bitrates is the smallest grid that
|
|
80
|
-
keeps the axes independent and still leaves one spare measurement, and every
|
|
81
|
-
clip costs the startup about two seconds. They are one second long rather than
|
|
82
|
-
two — the benchmark loops the clip and measures a slope over about a second of
|
|
83
|
-
decoding, so length beyond that buys nothing and only makes the package larger.
|
|
84
|
-
|
|
85
|
-
They were cut from `cal-h264-1080-hi.mp4` rather than from the 4K master, which
|
|
86
|
-
is not in this repository. Re-encoding an already-compressed picture softens its
|
|
87
|
-
grain slightly; what is being measured is the cost of decoding the new
|
|
88
|
-
bitstream, and the grain that survives is the same material in every set, which
|
|
89
|
-
is what makes the families comparable to each other.
|
|
90
|
-
|
|
91
|
-
10-bit is its own family rather than a multiplier on the 8-bit one. Wider
|
|
92
|
-
samples mean wider arithmetic, and how much that costs is a property of the
|
|
93
|
-
machine — which is the thing being measured. Measured on a desktop 2026-08-20,
|
|
94
|
-
1080p at ~5.8 Mbit/s: 7.7x as 8-bit HEVC and 6.3x as 10-bit, so it is a real
|
|
95
|
-
difference and not a rounding.
|
|
96
|
-
|
|
97
|
-
AV1 has no set yet. The release survey of 2026-07-10 found it rare where HEVC
|
|
98
|
-
was 18 %, so it is priced as H.264 until it is worth the startup seconds — and
|
|
99
|
-
the log says which families were measured and which are falling back, rather
|
|
100
|
-
than leaving it to be inferred.
|
|
1
|
+
# Calibration clips — attribution
|
|
2
|
+
|
|
3
|
+
The clips in this folder are excerpts from **"Meridian"**, part of
|
|
4
|
+
[Netflix Open Content](https://opencontent.netflix.com/), licensed under the
|
|
5
|
+
**Creative Commons Attribution 4.0 International (CC BY 4.0)** licence:
|
|
6
|
+
<https://creativecommons.org/licenses/by/4.0/>.
|
|
7
|
+
|
|
8
|
+
They were cut from `Meridian/Meridian_UHD4k5994_HDR_P3PQ.mp4` and re-encoded to
|
|
9
|
+
H.264 High, 24 fps, 2 s each, no audio:
|
|
10
|
+
|
|
11
|
+
| file | resolution | bitrate |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| `cal-h264-1080-hi.mp4` | 1920×1080 | 9.36 Mbit/s |
|
|
14
|
+
| `cal-h264-1080-lo.mp4` | 1920×1080 | 1.00 Mbit/s |
|
|
15
|
+
| `cal-h264-720-hi.mp4` | 1280×720 | 9.95 Mbit/s |
|
|
16
|
+
| `cal-h264-720-lo.mp4` | 1280×720 | 1.04 Mbit/s |
|
|
17
|
+
| `cal-h264-480-hi.mp4` | 854×480 | 9.48 Mbit/s |
|
|
18
|
+
| `cal-h264-480-lo.mp4` | 854×480 | 1.25 Mbit/s |
|
|
19
|
+
|
|
20
|
+
## Why six, and why this grid
|
|
21
|
+
|
|
22
|
+
`services/encode/hwaccel.js` decodes them at startup and fits the host's decode cost,
|
|
23
|
+
`a × Mpixel/s + b × Mbit/s + c`, from the measurements
|
|
24
|
+
(`services/encode/decode-cost-fit.js`).
|
|
25
|
+
|
|
26
|
+
The set before this one was three clips for three unknowns — an EXACT system,
|
|
27
|
+
with two of the clips sharing a pixel count. Such a system cannot fail visibly:
|
|
28
|
+
it returns whatever satisfies its three equations, and on 2026-08-17 it returned
|
|
29
|
+
`0.007542 × Mpx/s + 0.000000 × Mbit/s + 0.0000 s/s` — the bitrate term and the
|
|
30
|
+
constant exactly zero, so a film's own bitrate never entered its price, and the
|
|
31
|
+
prediction built on it was 1.8-2.2x optimistic against the same file measured
|
|
32
|
+
while playing.
|
|
33
|
+
|
|
34
|
+
Six clips are three sizes × two bitrates, with the two axes varied
|
|
35
|
+
**independently**. That gives three spare measurements, so the fit has a
|
|
36
|
+
residual — something to notice a degeneracy WITH — and lets a term be refused
|
|
37
|
+
when the data does not determine it, instead of being published as a zero that
|
|
38
|
+
looks measured.
|
|
39
|
+
|
|
40
|
+
A 480p clip at 9.5 Mbit/s is not content anyone ships; that is the point. The
|
|
41
|
+
bitrate has to vary at every size, or it cannot be told apart from the size.
|
|
42
|
+
|
|
43
|
+
## Why real footage
|
|
44
|
+
|
|
45
|
+
Grainy live action rather than a generated pattern: measured 2026-08-14 on the
|
|
46
|
+
addon host, this material decodes 11 % away from the film being served, where a
|
|
47
|
+
generated `testsrc2` clip is 158 % away. It also matches most of what the
|
|
48
|
+
product actually plays — a survey of 133 releases (2026-07-10) found ~67 %
|
|
49
|
+
H.264 live action, the rest HEVC, XviD and animation.
|
|
50
|
+
|
|
51
|
+
## Replacing or extending the set
|
|
52
|
+
|
|
53
|
+
Allowed: the benchmark reads each clip's dimensions, frame rate and bitrate from
|
|
54
|
+
ffmpeg's own output rather than from this table. Two rules hold, though:
|
|
55
|
+
|
|
56
|
+
- **more measurements than terms**, or there is no residual and no way to see a
|
|
57
|
+
degenerate fit;
|
|
58
|
+
- **the axes stay independent** — every size at both bitrates. Dropping one cell
|
|
59
|
+
reintroduces the collinearity that produced the zeros above.
|
|
60
|
+
|
|
61
|
+
## One set per codec family
|
|
62
|
+
|
|
63
|
+
A video that has to be RE-ENCODED is by definition one the browser could not
|
|
64
|
+
play, which is to say HEVC, 10-bit or AV1 — so the model was fitted on the one
|
|
65
|
+
codec it is least often asked about. There is now a set per family, and the
|
|
66
|
+
source's own codec chooses the constants.
|
|
67
|
+
|
|
68
|
+
| file | codec | resolution | bitrate |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| `cal-hevc-1080-hi.mp4` | HEVC Main, 8-bit | 1920×1080 | 5.78 Mbit/s |
|
|
71
|
+
| `cal-hevc-1080-lo.mp4` | HEVC Main, 8-bit | 1920×1080 | 0.52 Mbit/s |
|
|
72
|
+
| `cal-hevc-480-hi.mp4` | HEVC Main, 8-bit | 854×480 | 7.76 Mbit/s |
|
|
73
|
+
| `cal-hevc-480-lo.mp4` | HEVC Main, 8-bit | 854×480 | 0.74 Mbit/s |
|
|
74
|
+
| `cal-hevc10-1080-hi.mp4` | HEVC Main 10 | 1920×1080 | 5.82 Mbit/s |
|
|
75
|
+
| `cal-hevc10-1080-lo.mp4` | HEVC Main 10 | 1920×1080 | 0.52 Mbit/s |
|
|
76
|
+
| `cal-hevc10-480-hi.mp4` | HEVC Main 10 | 854×480 | 6.95 Mbit/s |
|
|
77
|
+
| `cal-hevc10-480-lo.mp4` | HEVC Main 10 | 854×480 | 0.68 Mbit/s |
|
|
78
|
+
|
|
79
|
+
Four per family, not six: two sizes at two bitrates is the smallest grid that
|
|
80
|
+
keeps the axes independent and still leaves one spare measurement, and every
|
|
81
|
+
clip costs the startup about two seconds. They are one second long rather than
|
|
82
|
+
two — the benchmark loops the clip and measures a slope over about a second of
|
|
83
|
+
decoding, so length beyond that buys nothing and only makes the package larger.
|
|
84
|
+
|
|
85
|
+
They were cut from `cal-h264-1080-hi.mp4` rather than from the 4K master, which
|
|
86
|
+
is not in this repository. Re-encoding an already-compressed picture softens its
|
|
87
|
+
grain slightly; what is being measured is the cost of decoding the new
|
|
88
|
+
bitstream, and the grain that survives is the same material in every set, which
|
|
89
|
+
is what makes the families comparable to each other.
|
|
90
|
+
|
|
91
|
+
10-bit is its own family rather than a multiplier on the 8-bit one. Wider
|
|
92
|
+
samples mean wider arithmetic, and how much that costs is a property of the
|
|
93
|
+
machine — which is the thing being measured. Measured on a desktop 2026-08-20,
|
|
94
|
+
1080p at ~5.8 Mbit/s: 7.7x as 8-bit HEVC and 6.3x as 10-bit, so it is a real
|
|
95
|
+
difference and not a rounding.
|
|
96
|
+
|
|
97
|
+
AV1 has no set yet. The release survey of 2026-07-10 found it rare where HEVC
|
|
98
|
+
was 18 %, so it is priced as H.264 until it is worth the startup seconds — and
|
|
99
|
+
the log says which families were measured and which are falling back, rather
|
|
100
|
+
than leaving it to be inferred.
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
set pagination off
|
|
2
|
-
set confirm off
|
|
3
|
-
set $base = (unsigned long) &system_base_info
|
|
4
|
-
set $hash = *(unsigned long *)($base + 0)
|
|
5
|
-
set $mask = *(unsigned long *)($base + 8)
|
|
6
|
-
printf "asochash=%p mask=%lu\n", $hash, $mask
|
|
7
|
-
set $i = 0
|
|
8
|
-
set $stcb = 0
|
|
9
|
-
if $hash != 0
|
|
10
|
-
while $i <= $mask && $stcb == 0
|
|
11
|
-
set $head = *(unsigned long *)($hash + $i * 8)
|
|
12
|
-
if $head != 0
|
|
13
|
-
set $stcb = $head
|
|
14
|
-
printf "bucket %lu -> stcb=%p\n", $i, $stcb
|
|
15
|
-
end
|
|
16
|
-
set $i = $i + 1
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
if $stcb == 0
|
|
20
|
-
printf "no association found (no viewer connected?)\n"
|
|
21
|
-
else
|
|
22
|
-
set $sock = *(unsigned long *)($stcb + 0)
|
|
23
|
-
printf "socket=%p asoc=%p\n", $sock, $stcb + 88
|
|
24
|
-
set $buf = (unsigned long) malloc(512)
|
|
25
|
-
set $lenp = (unsigned long) malloc(8)
|
|
26
|
-
set *(int *)$lenp = 512
|
|
27
|
-
set $rc = (int) usrsctp_getsockopt($sock, 132, 256, $buf, $lenp)
|
|
28
|
-
printf "getsockopt rc=%d len=%d\n", $rc, *(int *)$lenp
|
|
29
|
-
printf "state=%d rwnd=%u unackdata=%u penddata=%u instrms=%u outstrms=%u fragpoint=%u\n", *(int *)($buf+4), *(unsigned int *)($buf+8), *(unsigned short *)($buf+12), *(unsigned short *)($buf+14), *(unsigned short *)($buf+16), *(unsigned short *)($buf+18), *(unsigned int *)($buf+20)
|
|
30
|
-
printf "primary: state=%d cwnd=%u srtt=%u rto=%u mtu=%u\n", *(int *)($buf+24+4+128), *(unsigned int *)($buf+24+4+128+4), *(unsigned int *)($buf+24+4+128+8), *(unsigned int *)($buf+24+4+128+12), *(unsigned int *)($buf+24+4+128+16)
|
|
31
|
-
end
|
|
1
|
+
set pagination off
|
|
2
|
+
set confirm off
|
|
3
|
+
set $base = (unsigned long) &system_base_info
|
|
4
|
+
set $hash = *(unsigned long *)($base + 0)
|
|
5
|
+
set $mask = *(unsigned long *)($base + 8)
|
|
6
|
+
printf "asochash=%p mask=%lu\n", $hash, $mask
|
|
7
|
+
set $i = 0
|
|
8
|
+
set $stcb = 0
|
|
9
|
+
if $hash != 0
|
|
10
|
+
while $i <= $mask && $stcb == 0
|
|
11
|
+
set $head = *(unsigned long *)($hash + $i * 8)
|
|
12
|
+
if $head != 0
|
|
13
|
+
set $stcb = $head
|
|
14
|
+
printf "bucket %lu -> stcb=%p\n", $i, $stcb
|
|
15
|
+
end
|
|
16
|
+
set $i = $i + 1
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
if $stcb == 0
|
|
20
|
+
printf "no association found (no viewer connected?)\n"
|
|
21
|
+
else
|
|
22
|
+
set $sock = *(unsigned long *)($stcb + 0)
|
|
23
|
+
printf "socket=%p asoc=%p\n", $sock, $stcb + 88
|
|
24
|
+
set $buf = (unsigned long) malloc(512)
|
|
25
|
+
set $lenp = (unsigned long) malloc(8)
|
|
26
|
+
set *(int *)$lenp = 512
|
|
27
|
+
set $rc = (int) usrsctp_getsockopt($sock, 132, 256, $buf, $lenp)
|
|
28
|
+
printf "getsockopt rc=%d len=%d\n", $rc, *(int *)$lenp
|
|
29
|
+
printf "state=%d rwnd=%u unackdata=%u penddata=%u instrms=%u outstrms=%u fragpoint=%u\n", *(int *)($buf+4), *(unsigned int *)($buf+8), *(unsigned short *)($buf+12), *(unsigned short *)($buf+14), *(unsigned short *)($buf+16), *(unsigned short *)($buf+18), *(unsigned int *)($buf+20)
|
|
30
|
+
printf "primary: state=%d cwnd=%u srtt=%u rto=%u mtu=%u\n", *(int *)($buf+24+4+128), *(unsigned int *)($buf+24+4+128+4), *(unsigned int *)($buf+24+4+128+8), *(unsigned int *)($buf+24+4+128+12), *(unsigned int *)($buf+24+4+128+16)
|
|
31
|
+
end
|