ebml-webm 0.2.1

Sans-IO EBML/WebM mux + demux (Segment/Tracks/Cluster/SimpleBlock subset)
Documentation
# ebml-webm — roadmap

Sans-IO EBML/WebM demux (unprefixed). Workspace index: [`docs/roadmap.md`](../../../docs/roadmap.md).

## Stages

### 1 — EBML VINT + WebM demux subset (this session)

- [x] Crate + naming (ADR-0012) + [`adr/0001`]../adr/0001-ebml-vint-webm-schema-v1.md
- [x] EBML VINT decode (element ID + element size, incl. unknown-size marker)
- [x] Element tree walk: `EBML` header (skipped), `Segment`, `Segment\Info`
      (`TimecodeScale`), `Tracks`/`TrackEntry` (`TrackNumber`, `TrackType`,
      `CodecID`, `Video\PixelWidth`/`PixelHeight`), `Cluster` (`Timecode`)
- [x] `SimpleBlock` → frame (track number, absolute timecode, keyframe flag)
- [x] Used by `mediaway-container::webm` (`Demux` only; codecs without a
      `CodecKind` mapping — VP8, Vorbis — are recognized structurally but
      omitted from the Mediaway-typed surface)

### 2 — Full Matroska profile elements (this session)

- [x] Crate-local [`adr/0002`]../adr/0002-full-matroska-profile.md
- [x] Lacing: Xiph, fixed-size, and EBML (all three, not just one)
- [x] `BlockGroup` / `Block` / `BlockDuration` / `ReferenceBlock` (keyframe =
      absence of `ReferenceBlock`; `Frame::duration_ticks`)
- [x] `Audio\SamplingFrequency` (EBML Float) / `Channels``TrackInfo`
- [x] `Cues` / `SeekHead` — parsed and exposed informationally
      (`Demuxer::cues()`/`seek_head()`); this crate does no seeking itself

### Deferred (tracked, not silently dropped)

- [ ] Sibling-ID lookahead to close indefinite-size `Cluster` elements early —
      still keeps such a `Cluster` open until its parent `Segment` closes or
      EOF; correct for typical file/VOD WebM (definite-size clusters), a known
      gap for long-running indefinite-size live streams (unbounded
      open-element stack growth)
- [ ] `SimpleBlock` lacing on the **mux** side (never lacs; demux already
      reads all three lacing kinds for other encoders' output)

### 3 — Mux (2026-07-29)

- [x] Crate-local [`adr/0003`]../adr/0003-webm-mux.md
- [x] `mux::Muxer<Open | Live>``EBML` header, `Segment` (always
      unknown-size), `Segment\Info\TimecodeScale`, `Tracks\TrackEntry`
      (`Video`/`Audio` sub-fields), `Cluster\Timecode` + `SimpleBlock`
      (known-size `Cluster` batches, no lacing/`BlockGroup` on write)
- [x] `vint::encode_id`/`encode_size`/`encode_unknown_size` — new public,
      low-level, total (never panic) encode counterparts to `decode_id`/`decode_size`
- [x] Verified by round-tripping through this crate's own `Demuxer`
      (`mux_tests.rs`) — no external WebM mux oracle available this session
- [x] Used by `mediaway-container::webm` (`Mux` impl, see that crate's roadmap)