Skip to content

feat(moq-mux): synthesize fMP4/CMAF init for AV1 video#1804

Merged
kixelated merged 1 commit into
devfrom
claude/cranky-kare-d27df8
Jun 19, 2026
Merged

feat(moq-mux): synthesize fMP4/CMAF init for AV1 video#1804
kixelated merged 1 commit into
devfrom
claude/cranky-kare-d27df8

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Summary

moq-mux's fMP4/CMAF init-segment writer could only synthesize a sample entry for H.264 and H.265; every other codec fell through to UnsupportedSynthesis. Remuxing an AV1 MoQ broadcast to fMP4 therefore failed:

moq-cli subscribe --format fmp4   # (or accept ... --format fmp4) against an AV1 broadcast
Error: cmaf: can't synthesize CMAF init for video codec AV1(AV1 { profile: 0, level: 31, ... })

This adds the AV1 case so synthesize_video_trak builds an av01 sample entry carrying an av1C box.

Changes

  • rs/moq-mux/src/codec/av1/mod.rs: new av1c_from_av1 helper, the inverse of the existing av1_from_av1c (import direction). Maps the catalog AV1 config (profile, level, tier, bit depth, chroma subsampling, monochrome, chroma sample position) into an mp4_atom::Av1c. Adds a bitdepth_flags helper (inverse of bitdepth) for the (twelve_bit, high_bitdepth) flag pair.
  • rs/moq-mux/src/container/fmp4/mod.rs: synthesize_video_trak now handles VideoCodec::AV1, building an av01 sample entry + av1C.
  • config_obus is left empty. moq-video publishes AV1 with the sequence header inline in the bitstream (the .av01 in-band case, analogous to hev1/avc3), so the decoder reads it from the keyframe rather than the out-of-band config record. The catalog's color fields (color primaries / transfer / matrix / full range) have no slot in av1C; they live in the sequence header OBU.
  • doc/lib/rs/crate/moq-mux.md: brought the supported-codec list up to date (it also omitted VP8/VP9, which were already supported).

Public API

No public surface changes. av1c_from_av1 / bitdepth_flags are pub(crate); the new arm is inside a pub(crate) function. No wire or breaking change.

Branch targeting

Targets dev per CLAUDE.md: this is a catalog/container-format area change in moq-mux.

Test plan

  • cargo test -p moq-mux (265 passed) — new av1_source_to_cmaf_export_synthesizes_av01 round-trips a synthesized init back to an av01 sample entry with a well-formed av1C (empty config_obus), plus bitdepth_flags_round_trip and av1c_round_trips_catalog_fields unit tests.
  • cargo clippy -p moq-mux --all-targets -- -D warnings
  • cargo fmt --all --check
  • RUSTDOCFLAGS="-D warnings" cargo doc -p moq-mux --no-deps
  • End-to-end moq-cli accept ... --format fmp4 + ffprobe: not run locally (this Windows box lacks pkg-config/ffmpeg for the full-workspace build); covered by the export round-trip test.

(Written by Claude)

The fMP4/CMAF init-segment writer could only synthesize a sample entry
for H.264 and H.265; everything else fell through to UnsupportedSynthesis.
Remuxing an AV1 MoQ broadcast to fMP4 (moq-cli subscribe/accept
--format fmp4) therefore failed with "can't synthesize CMAF init for
video codec AV1(...)".

Add the AV1 case so synthesize_video_trak builds an av01 sample entry
carrying an av1C box. A new av1c_from_av1 helper is the inverse of the
existing av1_from_av1c (import direction), mapping the catalog AV1 config
(profile, level, tier, bit depth, chroma subsampling, monochrome,
sample position) into the AV1CodecConfigurationRecord. config_obus is
left empty: moq-video publishes AV1 with the sequence header inline in
the bitstream (the .av01 in-band case, like hev1/avc3), so the decoder
reads it from the keyframe rather than the config record.

Adds an AV1 export round-trip test plus unit coverage for the
bit-depth flag inversion, and brings the moq-mux doc's supported-codec
list up to date (it also omitted VP8/VP9).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kixelated kixelated enabled auto-merge (squash) June 19, 2026 19:20
@kixelated kixelated merged commit 927c83f into dev Jun 19, 2026
1 check passed
@kixelated kixelated deleted the claude/cranky-kare-d27df8 branch June 19, 2026 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants