docs(plan): Phase 18 OQ resolutions + VBR-safe accurate Opus seek model
This commit is contained in:
@@ -13,10 +13,15 @@ endpoint.
|
||||
> (`product-notes/phase-18-opus-low-data-streaming.md`) — is a prerequisite that sequences ahead of
|
||||
> windowing. Phase 21's windowing must work across **both** delivery formats (lossless WAV and Opus).
|
||||
> Its C5 invariant below already anticipated this ("must not foreclose MP3/FLAC"); **Opus is now the
|
||||
> concrete VBR/containerized driver of C5.** Windowing an Opus stream uses the decoder's *approximate*
|
||||
> byte↔time mapping (`OpusFormatDecoder.calculateByteOffset` — Ogg-page interpolation), exactly the C5
|
||||
> case — not the exact CBR-WAV `byteRate` math. Build the window machinery format-agnostically
|
||||
> (§2 C3/C5) so it inherits Opus for free.
|
||||
> concrete VBR/containerized driver of C5.** Windowing an Opus stream uses the decoder's **accurate
|
||||
> index-based** byte↔time mapping (`OpusFormatDecoder.calculateByteOffset` — a binary search in the Phase 18
|
||||
> precomputed seek index), exactly the C5 case — *not* the exact CBR-WAV `byteRate` math, and *not*
|
||||
> approximate Ogg-page interpolation. **Correction (Daniel, 2026-06-23):** an earlier draft described the
|
||||
> Opus mapping as "approximate page interpolation"; the Phase 18 seek-model resolution rejected that — Opus
|
||||
> seeking is **accurate**, backed by a precomputed seek index built at transcode time, so refill resolves to
|
||||
> the *exact* page offset. The windowed refill controller calls the **same** index resolver an explicit seek
|
||||
> does (Phase 18 §3.4a D); a window opening away from byte 0 still decodes via the Phase 18 sidecar setup
|
||||
> header. Build the window machinery format-agnostically (§2 C3/C5) so it inherits Opus for free.
|
||||
|
||||
---
|
||||
|
||||
@@ -66,14 +71,20 @@ docs. This phase **modifies that seam** — so the contract it must preserve is
|
||||
user-visible control, no change to seek/transport semantics beyond what the listener already
|
||||
experiences. Seek must still feel identical.
|
||||
- **C5 — Must window both delivery formats (WAV lossless AND Opus low-data).** Byte↔time mapping for
|
||||
refill is exact and cheap for WAV (CBR: `byteRate` from the header). For VBR/containerized formats it
|
||||
is approximate (the decoders carry TOC/SEEKTABLE/Ogg-page seek math). **Phase 18 (Opus) is sequenced
|
||||
before this phase and is the concrete driver here:** an Ogg Opus 320 stream is VBR and page-paged, so
|
||||
its `calculateByteOffset` is an *approximate* page-interpolation, not exact-offset. The window
|
||||
machinery must express refill purely in terms of the decoder's existing `calculateByteOffset`, so the
|
||||
same code windows WAV exactly and Opus approximately — **no WAV-special-cased offset math in the
|
||||
window layer.** (MP3/FLAC decoders are already wired in the registry too — the registry dispatches on
|
||||
content-type today; an `OpusFormatDecoder` joins them in Phase 18.)
|
||||
refill is exact and cheap for WAV (CBR: `byteRate` from the header). **Phase 18 (Opus) is sequenced
|
||||
before this phase and is the concrete VBR driver here** — and its mapping is **also exact**, but by a
|
||||
different mechanism: an Ogg Opus 320 stream has no linear time↔byte relationship, so
|
||||
`OpusFormatDecoder.calculateByteOffset` resolves via a **precomputed seek index** (granule→byte, built at
|
||||
transcode; Phase 18 §3.4a), a binary search that returns the exact page offset — **not** an approximate
|
||||
page interpolation. (An earlier draft of this invariant said "approximate"; the Phase 18 seek-model
|
||||
resolution, Daniel 2026-06-23, made Opus seeking accurate. Corrected here.) The window machinery must
|
||||
express refill purely in terms of the decoder's existing `calculateByteOffset`, so the same code windows
|
||||
WAV (via `byteRate`) and Opus (via the index) — **no WAV-special-cased offset math in the window layer**,
|
||||
and no approximation for either. A window that opens away from byte 0 must also prepend the decoder's
|
||||
retained/sidecar setup header (Phase 18 §3.4a B) — the format-agnostic refill path already routes
|
||||
continuations through the decoder's header-carry, so this comes for free. (MP3/FLAC decoders are already
|
||||
wired in the registry too — the registry dispatches on content-type today; an `OpusFormatDecoder` joins
|
||||
them in Phase 18.)
|
||||
- **C6 — No regression to the single-instance JS decoder concurrency guarantees.** The current code is
|
||||
careful that only one streaming loop touches the single JS `StreamDecoder` at a time
|
||||
(`DrainActiveStreamingTaskAsync`, the `_streamingCancellation` identity dance). Windowed refill
|
||||
|
||||
Reference in New Issue
Block a user