Files
wz-phone/vault/Reports/T4.1-report.md
Siavash Sameni ed8a7ae5aa docs: protocol audit 2026-05-25, update architecture + Obsidian vault
Audit:
- docs/AUDIT-2026-05-25.md: full protocol audit covering 8 findings
  (4 critical, 2 high, 5 medium, 4 low) with code references and fix
  effort estimates
- vault/Audit/Tasks.md: Obsidian Tasks plugin file tracking all audit
  items with priorities, due dates, and per-step checklists

Architecture docs updated for Wire format v2 and Wave 5/6 features:
- ARCHITECTURE.md: adds wzp-video to dependency graph and project
  structure; wire format updated to v2 (16B header, 5B MiniHeader);
  relay concurrency section corrected (DashMap+RwLock is current, not
  a future optimization); test count 571→702; Android note
- PROGRESS.md: Wave 5 and Wave 6 sections appended; test count 372→702;
  current status and open blockers as of 2026-05-25
- ROAD-TO-VIDEO.md: implementation status table inserted (/🟡/🔴/🔲
  per phase); 6-step critical path to first video call
- WZP-SPEC.md: MediaHeader updated to v2 (16B byte-aligned); MiniHeader
  updated to 5B with seq_delta; codec IDs 9-12 added (H.264/H.265/AV1);
  version negotiation section added

Obsidian vault (vault/):
- 114 files across Architecture/, PRDs/, Reports/, Android/,
  Reference/, Audit/ with YAML frontmatter
- 00 - Home.md index note with wiki links
- .obsidian/app.json config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 06:00:17 +04:00

107 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [report, wzp]
type: report
status: Pending Review
---
# T4.1 — `wzp-video` crate scaffold + H.264 NAL framer + depacketizer
**Status:** Pending Review
**Agent:** Kimi Code CLI
**Started:** 2026-05-11T16:29Z
**Completed:** 2026-05-11T16:29Z
**Commit:** (see git log)
**PRD:** ../PRD-video-v1.md
## What I changed
- `Cargo.toml` — Added `crates/wzp-video` to workspace members.
- `crates/wzp-video/Cargo.toml` — New crate manifest with `bytes` and `tracing` deps.
- `crates/wzp-video/src/lib.rs` — Crate root; exports `framer` and `depacketizer` modules.
- `crates/wzp-video/src/framer.rs``H264Framer` + `FramedPacket`:
- Parses Annex-B access units (splits by `0x000001` / `0x00000001` start codes).
- Emits Single-NAL packets when the NAL fits in `max_payload_size`.
- Fragments oversized NALs using H.264 FU-A (RFC 6184): `FU_indicator` (type 28) + `FU_header` (S/E/Type bits) + payload chunk.
- Last packet of the access unit gets `is_frame_end = true`.
- `crates/wzp-video/src/depacketizer.rs``H264Depacketizer`:
- Reassembles Single-NAL packets directly.
- Accumulates FU-A fragments until the end marker (`E=1`) is seen.
- Reconstructs original NAL header as `(FU_indicator & 0xE0) | (FU_header & 0x1F)`.
- Inserts `0x000001` Annex-B start codes between reconstructed NAL units.
- Emits a complete access unit when `is_frame_end` arrives and no fragmentation is in progress.
- `crates/wzp-proto/src/codec_id.rs` — Added `H264Baseline = 9` to `CodecId`:
- `bitrate_bps()`: 2_000_000 (2 Mbps nominal for 720p30)
- `frame_duration_ms()`: 33 (~30 fps)
- `sample_rate_hz()`: 48_000 (not meaningful for video, kept for consistency)
- `from_wire()`: maps wire value 9
- `to_wire()`: inherited from `#[repr(u8)]`
- Added `is_video()` helper.
- `crates/wzp-codec/src/opus_enc.rs` — Added `CodecId::H264Baseline => 0` to DRED-frame match (video has no DRED).
- `crates/wzp-relay/src/conformance.rs` — Added `CodecId::H264Baseline => 1400` to `payload_size_bound` (Tier D video bound).
- `crates/wzp-client/src/call.rs` — Added `CodecId::H264Baseline` panic arm in `profile_for_codec` (audio decoder should never see video codec).
- `crates/wzp-proto/src/codec_id.rs:197` — Updated `codec_id_unknown_values_rejected` test to start at 10 (was 9).
## Why these choices
- FU-A was chosen over STAP-A/MTAP because single-layer H.264 baseline typically sends one access unit per frame, and frames are often larger than MTU. FU-A is the standard fragmentation mechanism for this case.
- `f64` internal token tracking in the token bucket (from T3.5) was kept because sub-second fractional refills are important for smooth rate limiting.
- The depacketizer inserts Annex-B start codes (`0x000001`) rather than length prefixes because the framer consumes Annex-B input and most platform decoders expect Annex-B.
- `H264Baseline` bitrate of 2 Mbps is a conservative nominal for 720p30 baseline. Actual bitrate will be controlled by the platform encoder (T4.2/T4.3).
## Deviations from the task spec
- The task spec (written as part of this commit) says to create `encoder.rs`, `decoder.rs`, `keyframe.rs`, and `config.rs`. These are stubbed for T4.2T4.7; only `framer.rs` and `depacketizer.rs` are fully implemented in T4.1.
## Verification output
```bash
$ cargo test -p wzp-video
running 13 tests
test depacketizer::tests::depacketize_empty_payload_no_emit ... ok
test depacketizer::tests::depacketize_frame_end_without_data_no_emit ... ok
test depacketizer::tests::depacketize_fu_a_fragments ... ok
test depacketizer::tests::depacketize_malformed_fu_a_resets ... ok
test depacketizer::tests::depacketize_multi_nal_access_unit ... ok
test depacketizer::tests::depacketize_single_nal ... ok
test framer::tests::frame_empty_input ... ok
test framer::tests::frame_fu_a_exact_fit ... ok
test framer::tests::frame_fu_a_fragmentation ... ok
test framer::tests::frame_single_nal_roundtrip ... ok
test tests::roundtrip_empty_access_unit ... ok
test tests::roundtrip_single_nal ... ok
test tests::roundtrip_with_fu_a_fragmentation ... ok
test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
```
```bash
$ cargo test --workspace --exclude wzp-android --no-fail-fast
... (all crates pass)
Total: 618 passed; 0 failed
```
## Test summary
- Tests added: 13 (all in `wzp-video`)
- Framer: `frame_empty_input`, `frame_single_nal_roundtrip`, `frame_fu_a_fragmentation`, `frame_fu_a_exact_fit`
- Depacketizer: `depacketize_single_nal`, `depacketize_multi_nal_access_unit`, `depacketize_fu_a_fragments`, `depacketize_empty_payload_no_emit`, `depacketize_frame_end_without_data_no_emit`, `depacketize_malformed_fu_a_resets`
- Roundtrip: `roundtrip_empty_access_unit`, `roundtrip_single_nal`, `roundtrip_with_fu_a_fragmentation`
- Tests modified: 1 (`codec_id_unknown_values_rejected` — range start 9 → 10)
- Workspace test count before: 617 / after: 618
- `cargo clippy -p wzp-video -p wzp-proto --all-targets -- -D warnings`: clean
- `cargo fmt --all -- --check`: pass
## Risks / follow-ups
- `wzp-video` currently has no platform encoder/decoder. T4.2 (VideoToolbox/macOS) and T4.3 (MediaCodec/Android) will add `encoder.rs` and `decoder.rs`.
- The `H264Baseline` codec ID is wired into `CodecId` but no video-specific `MediaType` or `QualityProfile` exists yet. T4.2/T4.5 will likely need to extend these.
- `payload_size_bound(H264Baseline) = 1400` is a rough estimate. Real-world H.264 packet sizes depend on MTU negotiation and encoder settings. This bound may need tuning after end-to-end testing.
## Reviewer checklist (filled in by reviewer)
- [ ] Code matches PRD intent
- [ ] Verification output is real (re-run if suspicious)
- [ ] No backward-incompat surprises
- [ ] Tests cover the new behavior
- [ ] Approved