demuxe 0.3.0-beta.3

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.
Files changed (124) hide show
  1. package/LICENSE +352 -0
  2. package/README.md +75 -0
  3. package/bin/demuxe.mjs +30 -0
  4. package/docs/API-MIGRATION.md +54 -0
  5. package/docs/BETA.md +98 -0
  6. package/docs/BRANDING-MIGRATION.md +77 -0
  7. package/docs/COMPATIBILITY-EXPANSION.md +181 -0
  8. package/docs/LICENSING.md +83 -0
  9. package/docs/OPTIMIZATION-COMPLETION.md +511 -0
  10. package/docs/OPTIMIZATION-FLAC.md +178 -0
  11. package/docs/OPTIMIZATION-INTEGRATION.md +221 -0
  12. package/docs/OPTIMIZATION-REVIEW-FIXES.md +78 -0
  13. package/docs/PLAYER-COMPONENT.md +247 -0
  14. package/docs/PUBLIC-API-VALIDATION.md +163 -0
  15. package/docs/PUBLIC-API.md +245 -0
  16. package/docs/RELEASE.md +181 -0
  17. package/docs/RUNTIME-ASSETS.md +127 -0
  18. package/engine-build.json +8781 -0
  19. package/examples/custom-controls.html +14 -0
  20. package/examples/player-element.html +5 -0
  21. package/fixtures/DejaVuSans.ttf +0 -0
  22. package/fixtures/FONT-LICENSE.txt +187 -0
  23. package/index.d.ts +1 -0
  24. package/index.js +1 -0
  25. package/package.json +46 -0
  26. package/player.d.ts +1 -0
  27. package/player.js +1 -0
  28. package/release-manifest.json +541 -0
  29. package/sources.lock.json +96 -0
  30. package/third_party/notices/dav1d/COPYING +23 -0
  31. package/third_party/notices/emscripten/LICENSE +102 -0
  32. package/third_party/notices/emscripten/system/lib/compiler-rt/LICENSE.TXT +311 -0
  33. package/third_party/notices/emscripten/system/lib/libc/musl/COPYRIGHT +193 -0
  34. package/third_party/notices/emscripten/system/lib/libcxx/LICENSE.TXT +311 -0
  35. package/third_party/notices/emscripten/system/lib/libcxxabi/LICENSE.TXT +311 -0
  36. package/third_party/notices/emsdk/LICENSE +27 -0
  37. package/third_party/notices/ffmpeg/COPYING.GPLv2 +339 -0
  38. package/third_party/notices/ffmpeg/COPYING.GPLv3 +674 -0
  39. package/third_party/notices/ffmpeg/COPYING.LGPLv2.1 +502 -0
  40. package/third_party/notices/ffmpeg/LICENSE.md +129 -0
  41. package/third_party/notices/ffmpeg-adaptation/COPYING.LGPLv2.1 +502 -0
  42. package/third_party/notices/ffmpeg-adaptation/LICENSE.md +127 -0
  43. package/third_party/notices/freetype/LICENSE.TXT +46 -0
  44. package/third_party/notices/freetype/docs/FTL.TXT +169 -0
  45. package/third_party/notices/freetype/docs/GPLv2.TXT +340 -0
  46. package/third_party/notices/fribidi/COPYING +504 -0
  47. package/third_party/notices/harfbuzz/COPYING +42 -0
  48. package/third_party/notices/libass/COPYING +15 -0
  49. package/third_party/notices/libplacebo/LICENSE +458 -0
  50. package/third_party/notices/libxml2/Copyright +23 -0
  51. package/third_party/notices/libxml2/dict.c.notice +17 -0
  52. package/third_party/notices/libxml2/list.c.notice +16 -0
  53. package/third_party/notices/mpv/Copyright +78 -0
  54. package/third_party/notices/mpv/LICENSE.GPL +338 -0
  55. package/third_party/notices/mpv/LICENSE.LGPL +501 -0
  56. package/third_party/notices/vulkan-headers/LICENSE.txt +202 -0
  57. package/third_party/notices/zimg/COPYING +14 -0
  58. package/third_party/notices/zlib/LICENSE +22 -0
  59. package/third_party/notices.json +166 -0
  60. package/toolchain.lock.json +204 -0
  61. package/web/audio-worklet.js +45 -0
  62. package/web/cheap-mp4-probe.js +82 -0
  63. package/web/engine-adaptation/manifest.json +75 -0
  64. package/web/engine-adaptation/remux.mjs +2 -0
  65. package/web/engine-adaptation/remux.wasm +0 -0
  66. package/web/engine-ass/manifest.json +55 -0
  67. package/web/engine-ass/subtitles.mjs +2 -0
  68. package/web/engine-ass/subtitles.wasm +0 -0
  69. package/web/engine-hybrid/player.mjs +2 -0
  70. package/web/engine-hybrid/player.wasm +0 -0
  71. package/web/engine-remux/remux.mjs +2 -0
  72. package/web/engine-remux/remux.wasm +0 -0
  73. package/web/engine-software-full/player.mjs +2 -0
  74. package/web/engine-software-full/player.wasm +0 -0
  75. package/web/file-reader.js +34 -0
  76. package/web/filter-retained-engine-worker.js +292 -0
  77. package/web/generated/index.d.ts +6 -0
  78. package/web/generated/index.js +4 -0
  79. package/web/generated/internal/assets.d.ts +2 -0
  80. package/web/generated/internal/assets.js +7 -0
  81. package/web/generated/internal/backend.d.ts +27 -0
  82. package/web/generated/internal/backend.js +1 -0
  83. package/web/generated/internal/errors.d.ts +13 -0
  84. package/web/generated/internal/errors.js +54 -0
  85. package/web/generated/internal/native-ass.d.ts +38 -0
  86. package/web/generated/internal/native-ass.js +206 -0
  87. package/web/generated/internal/native-player.d.ts +95 -0
  88. package/web/generated/internal/native-player.js +502 -0
  89. package/web/generated/internal/playback-plans.d.ts +526 -0
  90. package/web/generated/internal/playback-plans.js +110 -0
  91. package/web/generated/internal/selection.d.ts +45 -0
  92. package/web/generated/internal/selection.js +45 -0
  93. package/web/generated/internal/state.d.ts +8 -0
  94. package/web/generated/internal/state.js +56 -0
  95. package/web/generated/internal/wasm-player.d.ts +127 -0
  96. package/web/generated/internal/wasm-player.js +372 -0
  97. package/web/generated/player/index.d.ts +198 -0
  98. package/web/generated/player/index.js +873 -0
  99. package/web/generated/player/interaction.d.ts +6 -0
  100. package/web/generated/player/interaction.js +14 -0
  101. package/web/generated/player/styles.d.ts +1 -0
  102. package/web/generated/player/styles.js +86 -0
  103. package/web/generated/types.d.ts +227 -0
  104. package/web/generated/types.js +2 -0
  105. package/web/generated/unified-player.d.ts +129 -0
  106. package/web/generated/unified-player.js +1074 -0
  107. package/web/io-worker.js +65 -0
  108. package/web/native-ass-worker.js +26 -0
  109. package/web/native-remux-player.js +301 -0
  110. package/web/native-remux-source-worker.js +25 -0
  111. package/web/native-remux-worker.js +46 -0
  112. package/web/range-reader.js +130 -0
  113. package/web/remux-packaging.js +11 -0
  114. package/web/resource-loader.js +173 -0
  115. package/web/retained-decoder-worker.js +200 -0
  116. package/web/retained-video.js +15 -0
  117. package/web/segmented-subtitles.js +37 -0
  118. package/web/software-full-engine-worker.js +234 -0
  119. package/web/source-probe.js +28 -0
  120. package/web/split-mp4.js +159 -0
  121. package/web/streaming-manifest.js +136 -0
  122. package/web/subtitle-overlay.js +26 -0
  123. package/web/video-codec-config.js +59 -0
  124. package/web/vod-manifest.js +54 -0
@@ -0,0 +1,511 @@
1
+ # Playback optimization completion work
2
+
3
+ Post-review fixes: public range objects are restored for windowed Native, and
4
+ original-track inspection no longer depends on optional preparation assets.
5
+ Package 22 passed the focused Chrome/Firefox routing and Chrome tail regressions;
6
+ see [the fix evidence](../results/optimization-review-fixes-final/README.md).
7
+ The complete package-20 matrix below remains historical exact-artifact evidence.
8
+ Tagged candidate qualification is recorded separately in
9
+ `results/optimization-release-closeout/` and the release verification record.
10
+
11
+ Latest local stage (2026-09-16): automatic lossless admission is implemented for
12
+ the documented local-file subset. The progressive FLAC long-tail path passes
13
+ Chrome output, seek, pause/rate, sample and packet comparisons, including nonzero
14
+ starts and ASS+gain. Firefox's unequal-tail paused-seek failure remains reproduced;
15
+ that Native configuration rejects explicitly and retains the mpv alternatives.
16
+ A distant short-video seek can recover through Software; continuous Firefox Hybrid
17
+ ASS behavior after video EOF is not qualified (see the current evidence).
18
+ Preparation ABI 2 rejects mixed assets. Frame verification uses emitted MP4 sample
19
+ intervals and edit mapping, including rounded B-frame overlaps at fractional seeks.
20
+ Clean optional source builds and the integrated exact-archive release gate are in
21
+ place. Final candidate qualification is recorded in
22
+ [the current closeout evidence](../results/optimization-final/README.md).
23
+
24
+ Earlier package-14 source-build and benchmark results below are historical, as are
25
+ package-12/13 reports. They are not measurements of the final ABI-2 runtime.
26
+
27
+ Prior review fixes: the four Native ASS findings are fixed and covered by Chrome/Firefox regressions. That review used `build/native-ass-04` (interface version 2) and local package candidate `build/optimization-package-13`. See the review-fix section at the end. Earlier package-12 benchmark and checkpoint records remain historical evidence, not measurements of the rebuilt subtitle artifact.
28
+
29
+ The implementation below started at `f97588443ff4d2a043a2fd8500fb73bd45e656e1`.
30
+ Remote main was fetched and verified at that commit, with no later commits and
31
+ no initial working changes. That implementation and its review fixes were committed
32
+ and pushed to main as `cdd1cb5cc2e48f484e58bc0c2f1bc05fb6a7de83`. Subsequent
33
+ closeout work is local in `demuxe-optimization-integration`. The optimization
34
+ laboratory is unchanged.
35
+ Earlier integration, FLAC and review-fix reports are historical evidence; their
36
+ references to an uncommitted checkpoint describe their original preparation date.
37
+
38
+ **Release promotion has not occurred.** The latest scope and remaining browser/
39
+ source limitations are in the current closeout evidence; older sections retain
40
+ their historical qualification boundaries.
41
+
42
+ ## In-place gain
43
+
44
+ All three maintained backends now expose a dedicated scalar attenuation stage.
45
+ Native attaches one MediaElementAudioSourceNode lazily. Hybrid and Software attach
46
+ one GainNode after their existing PCM worklet, preserving the user's mpv filter
47
+ chain, channel count and WebCodecs video path. Unity on a fresh player allocates no
48
+ stage. Once created, the stage remains connected through zero/unity changes;
49
+ ordinary volume and mute remain separate. No new AudioContext is allocated for
50
+ Hybrid or Software. Native resumes its context before redirecting playing media;
51
+ destroy cancels a blocked resume before any late source node can be allocated.
52
+
53
+ `setAudioGain` serializes in-place updates through the existing operation queue.
54
+ The fallback for a backend without a gain method remains transactional. Both
55
+ maintained backends support the in-place method. Diagnostic plans distinguish
56
+ Hybrid gain from mpv scalar filtering and their supported combination.
57
+
58
+ Evidence: `tests/in-place-gain.mjs`, Chrome and Firefox results under
59
+ `results/optimization-completion/gain-*`. Tests measure graph RMS at half, quarter,
60
+ zero, unity and mute; assert backend/worker/remux/context identity; check rapid
61
+ updates, paused position, seek, source replacement and teardown. A suspended-context
62
+ resume barrier proves destroy occurs during an outstanding update. These digital
63
+ measurements do not establish physical speaker output or A/V synchronization.
64
+ The older Native gain test initially assumed synchronous AudioParam observation;
65
+ its failed result remains saved. The corrected test waits for output processing.
66
+
67
+ Baseline and updated root build plus 18 routing/lifecycle contracts pass. The gain
68
+ source assembled with the saved streaming overlay compiles and passes its 59
69
+ contracts (`build/optimization-streaming-16`, logs in the gain evidence directory).
70
+ This is source/contract qualification, not end-to-end HLS/DASH qualification.
71
+
72
+ ## Historical unequal-tail limitation (before the 2026-09-16 stage)
73
+
74
+ Both one-second video with 30-second audio and 1.017-second audio with 30-second
75
+ video reproduce the bounded-work rejection. The new reverse fixture command and
76
+ SHA-256 are retained under `results/optimization-completion/tails/`. Hybrid
77
+ continues beyond the shorter track in both cases. The first reverse-case test
78
+ incorrectly required continuing audio frames after audio ended; that failed result
79
+ is preserved and the test now checks continuing video output instead.
80
+
81
+ The single combined SourceBuffer still cannot provide progressive continuation
82
+ of the longer track under the existing bounds. MSE's open-state track-range
83
+ intersection explains why splitting SourceBuffers alone would not establish
84
+ support ([MSE specification](https://www.w3.org/TR/media-source-2/)). No fake range,
85
+ synthetic sample, timestamp extension or premature end-of-stream workaround has
86
+ been admitted. Existing explicit rejection and Hybrid alternative remain; this
87
+ is containment, **not unequal-tail playback support**.
88
+
89
+ ## Native external ASS/SSA
90
+
91
+ `experimentalNativeASS: true` admits external ASS/SSA through existing
92
+ `addSubtitle`, `addFont`, subtitle selection and visibility APIs. It does not
93
+ extract embedded subtitles. Unsupported external formats retain mpv requirements.
94
+ The optional worker directly links the repository's pinned libass 0.17.3,
95
+ FreeType, FriBidi and HarfBuzz stack. No laboratory renderer or unrelated FFmpeg
96
+ binary is shipped. Assets load only when an external subtitle is attached.
97
+
98
+ The worker owns one renderer and selected track. Limits include 8 MiB per subtitle,
99
+ 16 MiB aggregate attachments, 32 MiB user fonts, 100,000 parsed events, 512 bitmap
100
+ parts and 2 MiB bitmap bytes per render, 1920×1080 presentation, bounded RPC waits,
101
+ and 128 MiB maximum Wasm memory. Existing fonts and subtitle bytes remain owned by
102
+ the Player for transactional replacement. Rendering uses Native source time and
103
+ rejects results from obsolete visibility/seek/resize revisions. Paused resize
104
+ re-renders active cues before replacing the canvas. Paused idle rendering stops.
105
+
106
+ Source-scoped external subtitle identities use attachment order across Native and
107
+ mpv; embedded stream identities remain separate. mpv attachment completion now
108
+ waits for the corresponding track-list update, not just command acceptance.
109
+
110
+ Four complete combinations pass short Chrome and Firefox checks: direct+ASS,
111
+ remux+ASS, FLAC+ASS, FLAC+ASS+gain. Checks cover authored drawing, animated karaoke,
112
+ fonts, active-cue seeks, rate, pause, visibility, resize, gain, mode transitions,
113
+ source replacement and worker cleanup. Screenshots and failures remain under
114
+ `results/optimization-completion/ass-*`.
115
+
116
+ Fullscreen must include the player container. Video-only fullscreen reports a
117
+ limitation; native PiP and remote playback controls are disabled while the overlay
118
+ is attached. An external canvas does not accompany PiP or casting. No Safari,
119
+ mobile, embedded-subtitle, HDR-overlay, long-duration or physical A/V claim.
120
+
121
+ `link-native-ass.py` records pinned inputs and archive/artifact hashes and saves
122
+ wrapper source. Local beta packaging accepts `--ass-build`, includes the optional
123
+ assets and source companion, and refuses release admission. Reused library archive
124
+ hashes are not a clean rebuild/source-correspondence proof; that release gate stays
125
+ open. Ordinary Native playback does not load this worker or Wasm.
126
+
127
+ ## Remaining scope / admission
128
+
129
+ | Item | Current status |
130
+ | --- | --- |
131
+ | Buffered Native seeks | Existing opt-in behavior preserved; previous frame and authority regressions retained |
132
+ | Native / Hybrid / Software gain | In-place implementation and Chrome/Firefox digital-output tests |
133
+ | Hybrid scalar filter | Existing qualified forms preserved; combined gain now has a separate stage |
134
+ | Progressive FLAC, original DTS repair, multi-audio | Opt-in implementation preserved; separate automatic lossless policy admits the narrow documented subset |
135
+ | Long unequal tails | Reproduced both directions; unsupported with bounded rejection |
136
+ | External Native ASS and combinations | Implemented, opt-in; Chrome/Firefox output checks and installed consumer checks |
137
+ | Embedded Native ASS | Not implemented; mpv remains alternative |
138
+ | Opus adaptation | Implemented, explicit Native and lossy permission; H.264 + PCM16/24, 48 kHz mono/stereo; Chrome/Firefox targeted output and lifecycle checks |
139
+ | Executable complete-plan eligibility | Finite registry now filters actual selection and validates the accepted plan; typed admission reasons; adaptation stays explicit |
140
+ | Initial/steady fragment sizes, FLAC settings | 0.125-second initial fragment rejected for PTS regression; 0.5-second default retained. FLAC level 0 sample checks pass; paired cost screen recorded, default 5 retained |
141
+ | Module / worker reuse | No new reuse admitted; credential/source isolation gates remain |
142
+ | Hybrid packet copies / format adapters | Removed redundant owned packet copy with shared-input capability fallback; Chrome/Firefox and configuration-prefix contracts pass |
143
+ | Software YUV/GPU | Existing experimental presenter retained; matching-artifact final qualification pending |
144
+ | Arbitrary GPU, WebCodecs audio, broader separate-track MSE | Not enabled |
145
+ | Rejected transport, routine background handoff, video transcode | Not revived |
146
+
147
+ No dependency upgrades, old/new glue mixing, HLS/DASH manifest ownership changes,
148
+ ABR/live admission or publication are part of the implementation. The source push
149
+ recorded above did not promote an optional runtime to release qualification.
150
+ Final-artifact paired benchmarks and clean-consumer checks are recorded below.
151
+ Clean release source correspondence remains open; no historical percentages are
152
+ used as measurements of the new artifacts.
153
+
154
+ ## Targeted reruns
155
+
156
+ ```sh
157
+ npm run build
158
+ node --test tests/optimization-contracts.mjs tests/remux-buffering.mjs tests/native-selection.mjs
159
+ node tests/in-place-gain.mjs
160
+ BROWSER=firefox node tests/in-place-gain.mjs
161
+ node tests/native-ass.mjs
162
+ BROWSER=firefox node tests/native-ass.mjs
163
+ CASES=audio-tail,video-tail RESULT_ROOT=results/optimization-completion/tails node tests/optimization-review-regressions.mjs
164
+ ```
165
+
166
+ Local ASS link (requires the pinned root libraries built by `scripts/build.sh`):
167
+
168
+ ```sh
169
+ python3 scripts/link-native-ass.py --sdk /path/to/emsdk-4.0.14 \
170
+ --library-root /path/to/matching-root-build --output build/native-ass-FRESH
171
+ ```
172
+
173
+ The served `web/engine-ass` must contain that build's matching `subtitles.mjs` and
174
+ `subtitles.wasm`. Never combine arbitrary glue and Wasm.
175
+
176
+ ## Explicit Opus profile and fidelity
177
+
178
+ The shared maintained preparation controller now supports an Opus encoder profile.
179
+ Only explicit Native mode, `experimentalAudioAdaptation: 'opus'` and
180
+ `allowLossyAudio: true` admit it. The narrow compiled input gate is H.264 video plus
181
+ selected S16/S24 integer PCM, 48 kHz mono/stereo. The native FFmpeg 9.0.1 encoder
182
+ uses 96 kbit/s per channel. No separate library stack, audio resampling, downmix,
183
+ video decoding or video encoding is added. Original-copy audio is attempted first.
184
+ Lossless failure never grants lossy permission. Opus+ASS is unqualified and rejected.
185
+
186
+ Encoding remains continuous until a seek resets its timeline. The existing source,
187
+ range authentication, generation retirement, bounded lookahead and byte budgets
188
+ remain shared. Delayed MP4 initialization and edit-list handling preserve nonzero
189
+ starts and codec pre-skip. Final packet duration carries the partial-frame end;
190
+ raw decoders can expose the declared discard padding. Tests independently reconcile
191
+ input count, encoded count, packet durations, codec delay and raw decoded padding,
192
+ and cross-correlate deterministic audible markers (at most one sample of lag).
193
+ This verifies timeline/sample accounting, not lossless samples or speaker output.
194
+ See [Opus in ISO BMFF](https://www.opus-codec.org/docs/opus_in_isobmff.html).
195
+
196
+ Preserved failures include the original naive raw-count assertion on a partial
197
+ Opus frame. Updated checks explicitly account for padding rather than removing
198
+ samples from the source. Chrome and Firefox pass original-edge, B-frame/nonzero
199
+ mismatch and marker fixtures. FLAC decode-back remains byte-exact on its supported
200
+ integer fixtures, including selected multi-audio. Long unequal tails are still
201
+ unsupported for both profiles. Opus permission, original AAC copy and 44.1 kHz
202
+ rejection have separate browser tests. Paused bounds, cancellation, stale output,
203
+ worker/range failure and source replacement reuse the existing lifecycle harness.
204
+
205
+ ## Selection and error boundaries
206
+
207
+ The finite plan registry now executes admission using requested effects, subtitle
208
+ attachments, source inspection, browser prerequisites, transport requirements and
209
+ fidelity permissions. The actual backend plan is checked before acceptance.
210
+ Automatic copy/direct and packet-copy remux remain ahead of Hybrid and Software;
211
+ audio adaptation never becomes automatic by setting its experimental option.
212
+ Native ASS is limited to file presentations. Explicit mode remains authoritative.
213
+ Selected stream and external attachment identities survive supported mode changes.
214
+
215
+ Admission codes distinguish unsupported features/source, policy prohibition,
216
+ unqualified combinations and deployment requirements. Existing source-integrity,
217
+ authorization and lifecycle handling remains intact. This is not a complete
218
+ migration of all legacy engine message matching into structured errors; compatibility
219
+ handling remains where replacing it lacks matching-engine evidence.
220
+
221
+ ## Smaller optimizations and preserved boundaries
222
+
223
+ EncodedVideoChunk copies its input unless an explicit transfer is requested. The
224
+ Hybrid worker now passes the live Wasm view synchronously into that constructor,
225
+ acknowledges the packet only afterward, and never transfers the shared heap.
226
+ Configuration descriptions and joined prefixes remain owned. A TypeError selects
227
+ one remembered owned-buffer fallback. Chrome and Firefox real playback plus a
228
+ shared-input mutation test pass; short checks eliminate 140–154 kB of redundant
229
+ JavaScript copies. This byte reduction is not a measured universal CPU improvement.
230
+ [WebCodecs specification](https://www.w3.org/TR/webcodecs/).
231
+
232
+ The first-fragment 0.125-second experiment fails video presentation timestamp
233
+ preservation on two retained B-frame/nonzero-start fixtures. Raw captures and
234
+ failures remain under `first-fragment/`; packaging rejects this setting. No speed
235
+ comparison is meaningful after that correctness failure. The default remains 0.5 s
236
+ for initial and steady fragments. FLAC level 0 passes sample/video checks but is
237
+ not promoted merely because its encoder stage can be cheaper.
238
+
239
+ No new worker pool or compiled-module cache is admitted. Cold/warm full startup
240
+ cost is measured, but no isolated pool benefit or credential/decoder-state teardown
241
+ proof exists. Software YUV/GPU remains the existing experimental option with RGB
242
+ fallback. The historical YUV report retains intermittent seek failures and failed
243
+ movie playback gates; no matching new YUV artifact or broader fidelity qualification
244
+ is claimed. Packet/configuration adapters remain in place and their tests pass.
245
+ Arbitrary GPU effects, WebCodecs audio and broader separate-track MSE are deferred;
246
+ rejected transport, routine handoff and general video transcoding remain excluded.
247
+
248
+ ## Final-artifact cost screen
249
+
250
+ The 1280×720/30 fps, 16-second H.264 B-frame + PCM24 fixture is recorded in
251
+ `results/optimization-completion/benchmark-fixture.json`. The retained harness
252
+ measures open, optional subtitle attachment, observed video, ten seconds of
253
+ playback and destroy. Cold means a fresh browser, not a flushed OS cache; warm
254
+ means one preceding open/play/destroy. CDP CPU includes reported browser processes
255
+ and newly observed process lifetime CPU. Summed process RSS can double-count pages;
256
+ external OS media services are excluded. No physical audio-onset or display latency
257
+ claim is made. Two trials per setting/plan are a short screen, not endurance data.
258
+
259
+ FLAC setting screen (`flac-settings/cost-1789520752161/result.json`):
260
+
261
+ | Setting / condition | Browser CPU seconds | Peak summed RSS MiB | Observed video ms | Generated bytes |
262
+ | --- | ---: | ---: | ---: | ---: |
263
+ | Level 5 cold | 3.337 | 946 | 682 | 6,182,478 |
264
+ | Level 0 cold | 3.318 | 1097 | 508 | 6,685,027 |
265
+ | Level 0 warm | 3.146 | 988 | 266 | 6,685,027 |
266
+ | Level 5 warm | 3.223 | 1112 | 283 | 6,182,478 |
267
+
268
+ Level 0 saves less than 3% of observed total CPU in either pairing while producing
269
+ 8.1% more bytes. The observations are too few to attribute a small CPU difference
270
+ to compression; level 5 remains the default. Preparation is included, not moved
271
+ outside the measurement. Engine hashes are recorded for each trial.
272
+
273
+ The first 720p FLAC+ASS+gain seek screen failed both Native trials. It exposed an
274
+ inherited frame-verifier assumption: a playing clock must still be within 1 ms of
275
+ the seek target when the compositor callback runs. The fix briefly holds the
276
+ media clock during buffered seek verification, then restores the captured play
277
+ intent. It preserves workers, MSE, SourceBuffers and forward preparation. The
278
+ exact-target/covering-frame assertion is retained, not widened. Both paused and
279
+ playing intent now have a contract regression; the failed raw run remains under
280
+ `final-cost/cost-1789520825299/`. Hybrid passed that original screen.
281
+
282
+ The corrected complete-plan screen passes all four trials
283
+ (`final-cost/cost-1789520946665/result.json`):
284
+
285
+ | Plan / condition | Browser CPU seconds | Peak summed RSS MiB | Observed video ms | Verified seek / including refill ms |
286
+ | --- | ---: | ---: | ---: | ---: |
287
+ | Native FLAC + ASS + gain cold | 5.295 | 1021 | 909 | 26 / 69 |
288
+ | Hybrid ASS + gain cold | 6.146 | 1156 | 1393 | 464 / 464 |
289
+ | Hybrid ASS + gain warm | 6.058 | 1163 | 613 | 442 / 442 |
290
+ | Native FLAC + ASS + gain warm | 4.974 | 1074 | 303 | 21 / 21 |
291
+
292
+ This screen includes a forward buffered seek near five seconds and Native producer
293
+ refill, plus teardown. Native backend/worker/MediaSource/SourceBuffer identities
294
+ remain unchanged. All workers retire. Hybrid uses the same ASS attachment and gain
295
+ request. CPU differences in this fixture do not establish an automatic ranking or
296
+ universal hardware acceleration. Startup includes subtitle attachment replacement;
297
+ ordinary Native playback avoids the optional assets entirely.
298
+
299
+ ## Final validation, packaging and saved streaming
300
+
301
+ Final root contracts pass 36/36; the assembled saved-streaming source compiles and
302
+ passes 59/59 integration contracts in `build/optimization-streaming-24/streaming`.
303
+ The assembly starts from f2491f62c777fa55225aed9b0b7ecf2e340accf7 and preserves its
304
+ AVIO, worker retirement, decoder generations, manifest/timeline ownership, window
305
+ anchors, source locks and patches. The root mpv/FFmpeg 7.1.1 playback engines and
306
+ optional FFmpeg 9.0.1 preparation engine retain distinct matching JS/Wasm pairs.
307
+ These are assembly/contract checks, not end-to-end streaming or ABR/live admission.
308
+ File adaptation does not qualify HLS/DASH/CMAF adaptation.
309
+
310
+ Final FLAC original-edge and multi-audio decode-back pass; final Opus original-edge
311
+ and marker packet/delay/padding checks pass. Final gain checks pass all three modes
312
+ in Chrome and Firefox, including digital attenuation, identity, restored unity,
313
+ source replacement and destroy during blocked resume. Firefox also passes the
314
+ playing buffered-seek regression with nonzero-start FLAC+ASS+gain. Earlier full
315
+ automatic-selection and public-API suites pass with restored reference fixtures;
316
+ the fixture hashes/provenance and the initial missing-fixture failure are retained.
317
+
318
+ The installed package checks exercise TypeScript exports, manifest hashes, original
319
+ Native without optional engine loading, Hybrid, Software, packet-copy remux,
320
+ external ASS, FLAC, Opus and FLAC+ASS+gain, seeking and cleanup. Eight package-10
321
+ cases pass. Packaging preserves notices and places preferred source companions
322
+ beside the runtime archive. Review found that the combined ASS+adaptation package
323
+ omitted the adaptation source from SHA256SUMS (its per-engine manifest hash was
324
+ already present). The packager now records both companions independently; a
325
+ permanent copy-assets regression verifies both file hashes and checksum entries.
326
+ Package 12 contains this fix; exact results and hashes are in the final logs and
327
+ checkpoint below. This does not close clean-build/source-correspondence release
328
+ qualification. Release-tag attempts for either optional engine and packaging the
329
+ failed first-fragment setting are explicitly rejected without creating an output.
330
+
331
+ Evidence directory: `results/optimization-completion/`. Key logs:
332
+ `final-contracts.log`, `final-streaming-build-24.log`,
333
+ `final-streaming-contracts-24.log`, `final-flac.log`, `final-opus.log`,
334
+ `final-gain.log`, `final-gain-firefox.log`, `final-ass-firefox.log`,
335
+ `final-consumer.log`, `final-consumer-12.log`, `final-copy-assets-12.log`,
336
+ `source-companion-before.log`, `package-gates.json`.
337
+ Historical failures remain alongside passing reruns.
338
+
339
+ Historical package-12 optional artifacts were `build/adaptation-opus-01/engine-1789520173100009000`
340
+ and `build/native-ass-02`. Local package candidate: `build/optimization-package-12`.
341
+ `results/optimization-completion/checkpoint-delivery/` contains the binary integration
342
+ patch and SHA-256 inventory, including untracked new runtime sources and evidence.
343
+ At that historical checkpoint, HEAD was f97588443ff4d2a043a2fd8500fb73bd45e656e1
344
+ and the work was uncommitted. The later source push is recorded at the top.
345
+
346
+ ## Historical package-12 blockers and reruns
347
+
348
+ At that checkpoint, the program remained incomplete: progressive long unequal tails have no qualified
349
+ continuation implementation; clean optional-runtime release correspondence and
350
+ broader source/browser/endurance qualification remain open. Embedded Native ASS,
351
+ Opus+ASS and automatic adaptation are not admitted. Legacy error-message adapters
352
+ have not all been migrated to typed engine errors. No Safari/mobile, casting/PiP
353
+ subtitle destination or physical A/V qualification is implied.
354
+
355
+ ```sh
356
+ npm run build
357
+ node --test tests/plan-admission.mjs tests/optimization-contracts.mjs tests/remux-buffering.mjs tests/native-selection.mjs tests/retained-codec-worker.mjs tests/video-codec-config.mjs
358
+ CASES=original-edge,multi-audio RESULT_ROOT=results/optimization-completion/rerun node tests/audio-adaptation.mjs
359
+ PROFILE=opus CASES=original-edge,opus-markers RESULT_ROOT=results/optimization-completion/rerun node tests/audio-adaptation.mjs
360
+ PROFILE=opus node tests/audio-adaptation-lifecycle.mjs
361
+ BROWSER=firefox PROFILE=opus CASES=bounded-local-gain,authenticated-range,destroy-blocked-read,incorrect-range node tests/audio-adaptation-lifecycle.mjs
362
+ CASES=audio-tail,video-tail RESULT_ROOT=results/optimization-completion/rerun node tests/optimization-review-regressions.mjs
363
+ node tests/in-place-gain.mjs
364
+ BROWSER=firefox node tests/in-place-gain.mjs
365
+ node tests/native-ass.mjs
366
+ BROWSER=firefox node tests/native-ass.mjs
367
+ INTEGRATION_ROOT=build/optimization-streaming-24/streaming RETAINED_WORKER=build/optimization-streaming-24/streaming/web/filter-retained-engine-worker.js node --test experiments/streaming-modernization/integration/*.test.mjs
368
+ BETA_ARCHIVE=build/optimization-package-12/demuxe-0.3.0-beta.3.tgz node --test tests/copy-assets.mjs
369
+ BETA_ARCHIVE=build/optimization-package-12/demuxe-0.3.0-beta.3.tgz ADAPTATION_FIXTURE=build/optimization-fixtures/long-pcm.mkv CASES=automatic-local,hybrid-pin,software-pin,native-remux,native-external-ass,native-adaptation,native-opus,native-adaptation-ass-gain node tests/beta-consumer.mjs
370
+ FIXTURE=build/optimization-fixtures/benchmark-720p.mkv ASS=1 GAIN=.5 QUICK=1 RESULT_ROOT=results/optimization-completion/rerun-cost node tests/audio-adaptation-cost.mjs
371
+ ```
372
+
373
+ Run performance screens alone, not concurrently with qualification or builds.
374
+ The unequal-tail tests passing means predictable rejection plus a working Hybrid
375
+ reference; it does **not** mean Native supports those tails.
376
+
377
+ ## Final package confirmation
378
+
379
+ Package 12 passes all eight installed-consumer playback cases and all six
380
+ asset/source-companion checks. Its SHA-256 is
381
+ `ab336d56a2c8cb3106fe75d300badb16d8fd28c02d88e87d592f3c0e97faf855`. All 61 served runtime files were
382
+ matched to its manifest before the final paired benchmark; the proof is
383
+ `final-benchmark-runtime-hashes.json`. No engine or runtime source changed afterward.
384
+ The source companion hashes are in the package's SHA256SUMS and local checkpoint.
385
+
386
+ Final package cost run: `final-package-cost/cost-1789521577115/result.json`.
387
+ This repeats the same 720p complete-plan screen after the final capability fix.
388
+
389
+ | Plan / condition | Browser CPU seconds | Peak summed RSS MiB | Observed video ms | Verified seek / including refill ms |
390
+ | --- | ---: | ---: | ---: | ---: |
391
+ | native ASS + gain / cold | 5.705 | 1056 | 672 | 14 / 57 |
392
+ | hybrid ASS + gain / cold | 6.724 | 1113 | 983 | 280 / 280 |
393
+ | hybrid ASS + gain / warm | 6.374 | 1144 | 646 | 466 / 466 |
394
+ | native ASS + gain / warm | 5.352 | 1166 | 334 | 25 / 69 |
395
+
396
+ Native in this table includes FLAC preparation; Hybrid includes mpv audio and
397
+ WebCodecs video. The earlier scope and measurement limitations still apply.
398
+ All four final trials pass, with Native presentation resources retained across
399
+ the seek and no workers remaining after destroy. These observations do not change
400
+ automatic ranking.
401
+
402
+ The original multi-audio fixture's second track is 44.1 kHz, so its Opus selection
403
+ correctly rejected. That failed attempted qualification is preserved in
404
+ `final-opus-firefox.log`; no resampling permission was added. A separate two-track
405
+ 48 kHz fixture (`opus/multi-fixture.json`) now passes selected-track Opus accounting
406
+ in Chrome and Firefox (`final-opus-multi*.log`). To repeat:
407
+
408
+ ```sh
409
+ PROFILE=opus CASES=opus-multi-audio node tests/audio-adaptation.mjs
410
+ BROWSER=firefox PROFILE=opus CASES=opus-multi-audio node tests/audio-adaptation.mjs
411
+ ```
412
+
413
+ | Complete plan | Admission | Actual browser evidence |
414
+ | --- | --- | --- |
415
+ | Native direct / packet-copy remux | Existing automatic subset | Chrome/Firefox existing suites; installed Chrome package |
416
+ | Native gain | Requested scalar [0,1] | Chrome/Firefox digital output and in-place identity |
417
+ | Hybrid scalar filter + gain | Explicit filter qualification option | Chrome/Firefox; video remains WebCodecs |
418
+ | Software gain | Requested scalar [0,1] | Chrome/Firefox digital output and in-place identity |
419
+ | Native direct + ASS / remux + ASS | Explicit external ASS option, file presentation | Chrome/Firefox |
420
+ | Native FLAC + ASS / FLAC + ASS + gain | Explicit Native FLAC and ASS options | Chrome/Firefox; final Chrome package and 720p paired cost |
421
+ | Native Opus / Opus + gain | Explicit Native profile and lossy permission | Chrome/Firefox limited source subset and lifecycle; final Chrome package |
422
+ | Opus + ASS, embedded Native ASS, long unequal tails | Rejected / not implemented | No support claim |
423
+ | Native file adaptation for HLS/DASH/CMAF | Gated | No streaming adaptation qualification |
424
+
425
+ This post-build confirmation adds evidence to the repository report; the frozen
426
+ package includes the report as it stood at packaging. Its runtime bytes are those
427
+ verified and benchmarked above. `delivery.json` provides the machine-readable
428
+ closeout. This was a local, uncommitted snapshot before the source push.
429
+
430
+
431
+ The final Opus+gain cost screen also passes four trials
432
+ (`final-opus-cost/cost-1789521758993/result.json`), using the same 720p source and
433
+ package-matched runtime. ASS is disabled because that Opus combination is not
434
+ qualified. Hybrid preserves original decoded audio and the requested gain; Opus
435
+ intentionally adds a lossy generation, so lower cost cannot justify selecting it
436
+ without policy permission.
437
+
438
+ | Plan / condition | Browser CPU seconds | Peak summed RSS MiB | Observed video ms | Verified seek / including refill ms |
439
+ | --- | ---: | ---: | ---: | ---: |
440
+ | native + gain / cold | 4.099 | 953 | 681 | 14 / 79 |
441
+ | hybrid + gain / cold | 5.237 | 1040 | 702 | 440 / 440 |
442
+ | hybrid + gain / warm | 4.892 | 1040 | 298 | 438 / 438 |
443
+ | native + gain / warm | 3.677 | 1101 | 239 | 10 / 118 |
444
+
445
+ Repeat with `PROFILE=opus FIXTURE=build/optimization-fixtures/benchmark-720p.mkv
446
+ GAIN=.5 QUICK=1 node tests/audio-adaptation-cost.mjs` (single shell command).
447
+ The earlier `checkpoint-final` remains an immutable pre-Opus-benchmark snapshot;
448
+ `checkpoint-delivery` is the final patch/evidence inventory. No runtime changed
449
+ between these checkpoints, only the benchmark harness and closeout evidence.
450
+
451
+
452
+ ## Native ASS review fixes
453
+
454
+ The four findings in `results/optimization-review-current/REVIEW.md` are fixed:
455
+
456
+ - **Source versus output dimensions:** the worker passes Native video geometry
457
+ separately from the canvas raster size. libass storage size remains tied to that
458
+ source geometry through resizes. A 10-pixel unscaled border on 640×360 video is
459
+ 5 pixels at 320×180 and returns to 10 when restored. Zero video geometry uses
460
+ libass's script-layout fallback; no new audio-only or anamorphic qualification
461
+ is claimed from the square-pixel video test.
462
+ - **Rejected subtitle selection:** native parsing retains the accepted ASS track
463
+ until the candidate parses and passes its cue budget. The controller retains the
464
+ current bitmap/visibility, blocks intervening render requests during the track
465
+ transaction, and invalidates stale output. A rejected malformed attachment leaves
466
+ the old selection visible and able to render fresh output after seek/toggle.
467
+ - **Construction cleanup:** Worker creation precedes DOM attachment. Subsequent
468
+ synchronous construction failures tear down the worker, observer, listeners and
469
+ canvas and restore altered styles/presentation flags. Three injected Worker
470
+ construction failures now leave zero orphan canvases rather than one per retry.
471
+ - **Visibility versus selection:** Native ASS selected-track metadata no longer
472
+ depends on whether subtitles are visible. Hide/show preserves the selected ID.
473
+
474
+ The changed render ABI is versioned. The worker checks `subtitle_api_version() == 2`
475
+ before initialization, and the packager rejects older ASS manifests. Matching
476
+ `subtitles.mjs` and `subtitles.wasm` were rebuilt from the pinned libraries into
477
+ `build/native-ass-04`; no library source lock or saved streaming contract changed.
478
+ Clean release/source correspondence remains a separate open gate.
479
+
480
+ Permanent regressions:
481
+
482
+ ```sh
483
+ node tests/native-ass-selection-regressions.mjs
484
+ BROWSER=firefox node tests/native-ass-selection-regressions.mjs
485
+ node tests/native-ass-style-regressions.mjs
486
+ BROWSER=firefox node tests/native-ass-style-regressions.mjs
487
+ node tests/native-ass.mjs
488
+ BROWSER=firefox node tests/native-ass.mjs
489
+ ```
490
+
491
+ Both browsers pass all four reviewed regressions, all four existing Native ASS
492
+ combinations, and the blocked-Wasm-load destroy case. The explicit old-interface
493
+ fault injection runs in Chrome. Its initial Firefox attempt is preserved: Firefox
494
+ worker module imports bypassed that Playwright interception, so that additional
495
+ case is marked skipped there; the four actual fix regressions run in both browsers.
496
+ Root contracts remain 36/36, and the rebuilt saved-streaming source assembly
497
+ `build/optimization-streaming-25/streaming` compiles and passes 59/59 contracts.
498
+ No modernized streaming end-to-end qualification is implied.
499
+
500
+ New evidence and package checks are under `results/optimization-ass-fixes/`.
501
+ The original review reproducers/results and package artifacts remain unchanged.
502
+ Package-13 installed-consumer and asset-copy reruns use:
503
+
504
+ ```sh
505
+ BETA_ARCHIVE=build/optimization-package-13/demuxe-0.3.0-beta.3.tgz ADAPTATION_FIXTURE=build/optimization-fixtures/long-pcm.mkv CASES=automatic-local,native-external-ass,native-adaptation-ass-gain node tests/beta-consumer.mjs
506
+ BETA_ARCHIVE=build/optimization-package-13/demuxe-0.3.0-beta.3.tgz node --test tests/copy-assets.mjs
507
+ ```
508
+
509
+ This fix does not resolve long unequal-tail adaptation, embedded Native ASS,
510
+ Opus+ASS, automatic adaptation or release promotion. No new performance improvement
511
+ is claimed; previous benchmark numbers retain their original artifact identities.