Skip to content

Fix fMP4 zero-duration samples#1933

Merged
kixelated merged 4 commits into
mainfrom
codex/fmp4-zero-duration-vod
Jun 29, 2026
Merged

Fix fMP4 zero-duration samples#1933
kixelated merged 4 commits into
mainfrom
codex/fmp4-zero-duration-vod

Conversation

@kixelated

@kixelated kixelated commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Treat explicit zero fMP4 sample durations as unknown during decode and import.
  • Strip explicit zero duration fields when republishing fMP4 passthrough fragments.
  • Fill missing fMP4 export durations from the successor frame when PTS is monotonic, otherwise fall back to the default frame duration.

Tests

  • cargo test -p moq-mux
  • cargo test -p moq-hls
  • cargo test -p moq-mux container::fmp4 -- --nocapture
  • git diff --check

(Written by Codex)

kixelated and others added 2 commits June 27, 2026 18:51
Treat explicit zero MP4 sample durations as unknown during fMP4 decode/import, then infer missing export durations from a successor frame when PTS order is monotonic. Also include formatter output required by just check.

Co-Authored-By: OpenAI Codex <codex@openai.com>
Run just fix after the fMP4 zero-duration fix and keep the markdown formatter output.

Co-Authored-By: OpenAI Codex <codex@openai.com>
@kixelated kixelated marked this pull request as ready for review June 28, 2026 14:28

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The infer_missing_durations/pts_monotonic logic disables PTS-based inference for the whole fragment if any timestamp pair is out of order; consider scoping monotonicity to local neighbors so well-behaved regions still benefit from PTS-derived durations.
  • In the fMP4 import path, treating zero durations as None and erroring on any non-final sample with missing duration (MissingSampleDuration) changes behavior; if certain inputs intentionally use zero-length samples mid-fragment, it may be useful to handle them explicitly or surface a more descriptive error to distinguish malformed from intentional gaps.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `infer_missing_durations`/`pts_monotonic` logic disables PTS-based inference for the whole fragment if any timestamp pair is out of order; consider scoping monotonicity to local neighbors so well-behaved regions still benefit from PTS-derived durations.
- In the fMP4 import path, treating zero durations as `None` and erroring on any non-final sample with missing duration (`MissingSampleDuration`) changes behavior; if certain inputs intentionally use zero-length samples mid-fragment, it may be useful to handle them explicitly or surface a more descriptive error to distinguish malformed from intentional gaps.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The pull request adds missing/zero sample duration inference to the fMP4 pipeline in rs/moq-mux: mod.rs now treats a resolved duration of 0 as None; import.rs validates that only the final sample in a track fragment may have a missing duration and normalizes zero fields before re-encoding; export.rs gains an infer_missing_durations helper that fills missing durations from PTS deltas (using an optional successor frame) and updates emit_fragment accordingly, with new unit tests. Separately, all justfiles are updated from bare set fallback to explicit set fallback := true, with minor whitespace and documentation formatting edits throughout the repository.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and directly matches the main fMP4 zero-duration sample handling change.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description accurately matches the fMP4 zero-duration handling and export duration inference changes in the pull request.
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch codex/fmp4-zero-duration-vod

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@js/watch/README.md`:
- Line 73: The Markdown table row for the `visible` option is being split into
too many columns because the pipe characters inside the value list are
interpreted as delimiters. Update the `visible` row in the README table so the
values are escaped or otherwise rendered as a single cell, keeping the table
consistent with the 4-column layout used by the surrounding rows.

In `@rs/moq-mux/src/container/fmp4/import.rs`:
- Around line 569-579: The duration normalization in the fMP4 import path is
dropping explicit zero values in a way that can fall back to inherited non-zero
defaults. Update the logic in the import routine that mutates
`traf_mut.tfhd.default_sample_duration` and each `trun_mut.entries` duration so
zero is only cleared when no non-zero `trex`/`tfhd` default can apply, or
resolve inherited durations first before removing the override. Keep the fix
localized to the import flow that handles `traf_mut`, `tfhd`, and `trun_mut`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4a54ca79-3fc5-485c-862f-750b7fc2d0d2

📥 Commits

Reviewing files that changed from the base of the PR and between 02273a0 and 6048dc2.

📒 Files selected for processing (27)
  • .github/justfile
  • demo/boy/justfile
  • demo/justfile
  • demo/pub/justfile
  • demo/relay/justfile
  • demo/sub/justfile
  • demo/web/justfile
  • doc/bin/cli.md
  • flake.nix
  • go/justfile
  • infra/apt/justfile
  • infra/justfile
  • infra/rpm/justfile
  • js/CLAUDE.md
  • js/justfile
  • js/watch/README.md
  • justfile
  • kt/justfile
  • nix/modules/moq-relay.nix
  • py/justfile
  • rs/CLAUDE.md
  • rs/justfile
  • rs/moq-mux/src/container/fmp4/export.rs
  • rs/moq-mux/src/container/fmp4/import.rs
  • rs/moq-mux/src/container/fmp4/mod.rs
  • swift/justfile
  • test/justfile

Comment thread js/watch/README.md Outdated
Comment on lines +569 to +579
if traf_mut.tfhd.default_sample_duration == Some(0) {
traf_mut.tfhd.default_sample_duration = None;
}
for trun_mut in &mut traf_mut.trun {
// Reserve the data_offset field; the real value is filled in below.
trun_mut.data_offset = Some(0);
for entry in &mut trun_mut.entries {
if entry.duration == Some(0) {
entry.duration = None;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Avoid letting defaults replace an explicit zero duration.

Clearing tfhd.default_sample_duration == Some(0) or entry.duration == Some(0) can expose a non-zero fallback default from trex/tfhd, so a sample that import treated as “missing duration” may be republished with a real duration. Only strip the zero when no non-zero default can apply, or materialize inherited durations before removing the zero override.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rs/moq-mux/src/container/fmp4/import.rs` around lines 569 - 579, The duration
normalization in the fMP4 import path is dropping explicit zero values in a way
that can fall back to inherited non-zero defaults. Update the logic in the
import routine that mutates `traf_mut.tfhd.default_sample_duration` and each
`trun_mut.entries` duration so zero is only cleared when no non-zero
`trex`/`tfhd` default can apply, or resolve inherited durations first before
removing the override. Keep the fix localized to the import flow that handles
`traf_mut`, `tfhd`, and `trun_mut`.

kixelated and others added 2 commits June 28, 2026 07:44
Run nixfmt from the Nix dev shell so flake.nix and nix/modules/moq-relay.nix match the formatter used by just ci.

Co-Authored-By: OpenAI Codex <codex@openai.com>
Restore the justfile, Nix, and markdown formatter churn so the PR diff only contains the fMP4 zero-duration fix.

Co-Authored-By: OpenAI Codex <codex@openai.com>
@kixelated kixelated merged commit d71655a into main Jun 29, 2026
2 checks passed
@kixelated kixelated deleted the codex/fmp4-zero-duration-vod branch June 29, 2026 00:06
@moq-bot moq-bot Bot mentioned this pull request Jun 28, 2026
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.

1 participant