Skip to content

refactor(moq-mux)!: split the fMP4 init segment out of Fragment - #2692

Merged
kixelated merged 5 commits into
moq-dev:devfrom
zshenker:refactor/fmp4-chunk
Aug 6, 2026
Merged

refactor(moq-mux)!: split the fMP4 init segment out of Fragment#2692
kixelated merged 5 commits into
moq-dev:devfrom
zshenker:refactor/fmp4-chunk

Conversation

@zshenker

@zshenker zshenker commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

fmp4::Fragment described two different emits with one struct. The init segment carried init: true, independent: false, and duration: 0.0; every media fragment carried init: false and meant the other two. Three of its four fields were sentinels on one of the two shapes it covered, and a consumer had to read a bool to know which fields were real.

Export::next_chunk now returns a Chunk: Init holds the bytes and nothing else, while Fragment holds a Fragment with no dead field. Export::next is unchanged for consumers that only want bytes.

Review feedback also moved Fragment::duration from untyped f64 seconds to std::time::Duration, and added consuming Chunk::init and Chunk::fragment accessors. rs/CLAUDE.md now records the repository convention to use typed time values and convert numeric serialized forms at the boundary, using serde_with where possible.

Chunk is deliberately not #[non_exhaustive]. The set is closed by the container format, which emits an init segment and media segments and nothing else, so a wildcard arm would be permanent noise on every match.

Public API changes

item change
fmp4::Chunk new enum: Init(Bytes), Fragment(Fragment)
Chunk::data, Chunk::into_data new byte accessors
Chunk::init, Chunk::fragment new consuming variant accessors
Fragment::init removed
Fragment::duration changed from f64 seconds to std::time::Duration
Export::next_fragment renamed to next_chunk, now returns Option<Chunk>
Export::poll_next_fragment renamed to poll_next_chunk, now returns Option<Chunk>
Export::next / poll_next unchanged

This targets dev because it breaks published moq-mux APIs.

Test plan

Run on the final head after merging the latest origin/dev:

  • nix develop --command just fix
  • nix develop --command just check
  • nix develop --command just rs test -p moq-mux: 482 passed, 0 failed

just test smoke-full was not run because this changes no wire format, moq-ffi API, or gateway behavior.

Cross-Package Sync

No table rows apply. moq-mux has no cross-package row, no wire format or CLI surface changed, and doc/lib/rs/crate/moq-mux.md describes the crate's scope rather than this API.

(Written by GPT-5)

`Fragment` described two different emits with one struct. The init segment
carried `init: true`, `independent: false` and `duration: 0.0`, while every
media fragment carried `init: false` and meant the other two. Three of its four
fields were sentinels on one of the two shapes it had to cover.

`Export::next_chunk` now returns a `Chunk`, whose `Init` variant holds the bytes
and nothing else, and whose `Fragment` variant holds a `Fragment` with no dead
field. A consumer that only wants bytes stays on `next`, which is unchanged.

`Chunk` is left exhaustive rather than `#[non_exhaustive]`: the set is closed by
the container format, which emits an init segment and media segments and nothing
else, so a wildcard arm would be permanent noise on every match.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@kixelated

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 4046b6d3be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-mux/src/container/fmp4/export.rs Outdated
Comment thread rs/moq-mux/src/container/fmp4/export_test.rs Outdated
…it/fragment accessors

Fragment::duration was f64 seconds; the computation already ran in
std::time::Duration and flattened at the end, so carry the Duration
through and let a playlist writer call as_secs_f64 itself.

Chunk::init and Chunk::fragment replace the panicking test helpers, so a
consumer expecting one variant writes chunk.fragment().expect(..).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@kixelated
kixelated enabled auto-merge (squash) August 6, 2026 20:45

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the final head after syncing with dev and adding the typed-time guidance. The chunk API cleanly separates init data from media fragment metadata, the Duration change preserves exact internal values, and the two prior review requests are implemented. just check and all 482 moq-mux nextest tests passed. No blocking findings.

(Written by GPT-5)

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the final head after merging the latest dev. The upstream commit is unrelated to the fMP4 API change and merged without conflicts. The full Rust CI test stage passed all 2,955 tests locally, the scoped repository checks passed on the prior equivalent head, and the final diff passes git diff --check. No blocking findings.\n\n(Written by GPT-5)

@kixelated
kixelated merged commit b7cdec6 into moq-dev:dev Aug 6, 2026
1 check passed
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