Skip to content

fix(moq-mux): keep fMP4 decode times increasing in sub-GOP fragments - #7491

Merged
kixelated merged 7 commits into
mainfrom
quest/m1/fmp4-bframe-decode-time
Nov 2, 2026
Merged

kixelated merged 7 commits into
mainfrom
quest/m1/fmp4-bframe-decode-time

Conversation

@kixelated

@kixelated kixelated commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Completes quest/m1/fmp4-bframe-decode-time.md (deleted here, with its link in quest/m1/README.md).

Problem

With B-frame video and --fragment-duration shorter than a GOP, fmp4::Export wrote tfdts that stepped backwards. Found on moq-dev/moq#7357. Reproduced with bbb5s_cbr.ts (HEVC with B-pyramids, imported as Legacy, so frames carry no durations):

  • --fragment-duration 0s: video tfdts went 35600, 39600, 37600, 36600, ... and ffprobe warned DTS 37600 < 39600 out of order.
  • --fragment-duration 100ms: 23 backwards steps in 5 s.

There were two causes, both in the exporter code that export fmp4, HLS packaging of its output, and the unfinished export mp4 file all share:

  1. Decode times. Every fragment anchored its tfdt at its first frame's presentation time. Mid-GOP, that frame is often a reference frame that presents after the B-frames decoded next.
  2. Durations. A sub-GOP run can't see the reordering around it. So a duration-less I-frame followed by its P-frame took the I-to-P gap (4 frames) as its duration, and the decode timeline overran the next GOP.

Approach

  • rs/moq-mux/src/container/fmp4/export.rs:
    • Each track remembers where its last fragment's decode timeline ended (decode_end). A fragment that doesn't open a GOP continues from there. A fragment that opens a GOP still anchors at the keyframe's presentation time, as before. Audio is unchanged.
    • infer_missing_durations takes a Run. For a Run::PartialGop (video cut inside a GOP whose rendition may reorder), no inferred duration exceeds the catalog cadence. Durations the frame states itself, or that a publisher's cut gives it, are never touched.
    • A rendition may reorder when its catalog reorder is above 0, or when reorder is undeclared and the codec allows reordering (codec::video::max_reorder > 0). The JS publisher declares reorder: 0, and VP8, VP9 and AV1 never reorder. Those keep using the real successor gaps, so their sub-GOP timing doesn't change.
  • rs/moq-mux/src/container/fmp4/mod.rs: encode_at also returns the decode time its fragment ends at. fragmenter.rs now uses that value instead of recomputing it.
  • with_fragment_duration docs describe the new behaviour.

With the fix, sub-GOP fragments of the clip carry the same per-sample decode timeline as the whole-GOP export (one frame period per sample, the same composition offsets), and ffprobe reads them cleanly.

Impact

  • Public API: no signature changes. Export::with_fragment_duration now preserves the video decode timeline across sub-GOP fragments; explicit sample durations and audio timing stay unchanged.
  • Wire: no MoQ protocol or hang container changes. Exported fMP4 tfdt, inferred sample durations, and composition offsets reflect the continued decode timeline.

Tests

  • reordered_video_cut_inside_a_gop_keeps_decode_times_increasing: imports bbb5s_cbr.ts and exports it with fragment durations 0s and 100ms. It checks that:
    • every track's tfdt starts at or after its previous fragment's end;
    • every sample of both tracks presents exactly as it does in the whole-GOP export (same presentation order and A/V timing);
    • ffprobe -v warning over the whole file prints nothing.
  • zero_fragment_duration_trusts_a_long_gap_only_without_reordering: H.264 with undeclared reorder takes the cadence for a 50 ms gap. The same stream declaring reorder: 0 keeps the 50 ms.
  • a_partial_gop_caps_inferred_durations_at_the_cadence: a unit test of the cap. A shorter gap and a stated duration are kept.
  • Local on head fd138e82ffdc9d5b6655d8d5377c406f924c92e9: quest gate nix develop --ignore-environment --keep HOME --keep USER --keep PATH --command just ci origin/main passed, exit 0. All selected checks passed: 4,403 Rust tests, 67 skipped, clippy, fmt, docs, dependency hygiene, quest, markdown, shell, GitHub tooling, large files, TOML, Nix, justfile, and drill sensitivity. Both sub-GOP integration tests and the cadence-cap unit test passed.
  • quest check --base origin/main --branch quest/m1/fmp4-bframe-decode-time: passed, 602 documents. git diff --check origin/main...HEAD: passed.
  • The current main merge includes the relay import fix from moq-dev/moq#7559; no local source patch was needed. ALSA is available in the Nix shell (pkg-config: 1.2.16.1).
  • The first inherited-environment gate failed to launch Cargo through mbx (Argument list too long). Existing moq-dev/moq#7594 owns that environment defect. The successful clean-environment run kept mbx and every selected check.

Choices made without asking

  • Duration rule for sub-GOP runs: the Plan settles that the fix goes in the exporter's shared inference. I picked "no inferred duration above the catalog cadence, only when the rendition may reorder". This is exact for constant-rate B-frame video. When frames arrive faster than the cadence, it still keeps the shorter real gap.
    • The trade-off: H.264 or H.265 that doesn't declare reorder: 0 and stalls longer than the cadence now gets the cadence in a sub-GOP fragment. Before, it got the real gap.
    • Under-timing only makes decode times lag. The next GOP then re-anchors forward, which is valid. Presentation is unchanged, because the composition offsets carry it.
    • Alternative: author decode times with the DeclaredClock that the TS, FLV and MKV exporters already use. That would be exact for variable-rate reordered video, but it needs a declared depth and holds that many frames. I suggested it as a follow-up below.
  • GOP re-anchoring is unchanged: a keyframe-started fragment still anchors at the keyframe's presentation time, like Fragmenter::push_group. When the inferred durations of the previous GOP overshoot (only possible when the catalog frame rate is slower than the real one), that boundary can still step back. Clamping it would let composition offsets grow without bound, which the Fragmenter docs warn against.

Alternatives

A declared-depth clock gives exact variable-rate reordered timing, but adds buffering and needs the signed initial-DTS representation settled. The maintainer assigned that work to m2 on 2026-11-01, retaining this cadence-based fix first.

Follow-ups

Review

Head fd138e82ffdc9d5b6655d8d5377c406f924c92e9: conflict-free merge of origin/main (4a82a6a5f7). Git merged every file itself, including both fMP4 files; the quest merge driver resolved the link list. No implementation changes beyond the base merge. The existing clean review and mechanical-fix record below carry forward under the guide's conflict-free base-merge exemption; no new round or review session was started.

conflict-free merge of origin/main (fd0b0cb9e4) by Claude Code: git merged every file itself; the quest merge driver resolved the quest/m1/README.md link list, and the PR's net diff against main is unchanged. No new review needed per the guide. (head 2d998e4)

mechanical fix by codex / Codex: Merged base and followed its moq_clock to kio::clock rename in the new fMP4 test; passed cargo test --locked -p moq-mux --tests individually and in the combined batch, cargo fmt --check -p moq-mux, and cargo clippy --locked -p moq-mux --tests -- -D warnings. (head 1a728e2)

Round 1: Codex (codex exec review), gpt-6.1-sol, medium effort, on head aaa22ccaf9c6bd5fea168ce76480821b280f7821 against origin/main. No findings.

🤖 Generated with Claude Code

(Written by Claude Opus 5.5)

(Written by GPT-6.1 Sol)

kixelated and others added 3 commits October 31, 2026 22:49
With B-frame video and a fragment duration shorter than a GOP, the fMP4
exporter anchored each fragment's tfdt at its first frame's presentation
time and timed a reference frame by the gap to its successor, so tfdt
stepped backwards and the decode timeline overran the next GOP.

A fragment cut inside a GOP now continues the decode timeline where the
track's previous fragment ended, and in video that may reorder (catalog
reorder > 0, or undeclared on a codec that can) no inferred duration in
such a fragment exceeds the catalog cadence. Whole-GOP fragments and
video declared reorder 0 keep their existing timing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title fMP4 fragments shorter than a GOP keep decode times increasing fix(moq-mux): keep fMP4 decode times increasing in sub-GOP fragments Nov 1, 2026
@kixelated
kixelated marked this pull request as ready for review November 1, 2026 06:34

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: aaa22cc

No actionable bugs found in the changed code and relevant surrounding paths. Continuing sub-GOP decode time from the encoder's actual end tick is the right shared-layer fix, and returning that end from encode_at avoids duplicating duration arithmetic. The partial-GOP cadence cap preserves explicit durations and keeps the non-reordering path separate; the added tests cover B-frame fragmentation, presentation timing, and the reorder: 0 distinction.

The documented variable-rate/inaccurate-cadence limitation remains: this is not general DTS reconstruction or a guarantee against backwards GOP-boundary re-anchoring. A declared-depth clock is a reasonable separate follow-up rather than extra buffering in this targeted fix.

Verification: static GitHub review only; I did not run builds, tests, or ffprobe.

@pullfrog pullfrog 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.

✅ No new issues found. The two root causes are addressed at their shared source, and the tests reproduce the reported clip.

Reviewed changes

  • Decode-timeline continuity. Fmp4Track gains decode_end, the tick the track's last fragment ended at. encode_fragment now takes opens_gop; a video run cut inside a GOP bases tfdt on decode_end instead of its first frame's PTS, while a GOP opener still re-anchors at the keyframe's presentation time. Audio always re-anchors, so it is unchanged.
  • Cadence cap for partial runs. infer_missing_durations takes a Run. A run starting or ending inside a GOP on a rendition that may reorder (Rendition::may_reorder) is PartialGop, and its inferred (never stated) durations are capped at the catalog cadence. Run::Whole call sites keep the old gap-based timing.
  • encode_at returns the decode end. encode_fragment/Fragmenter::emit consume it instead of recomputing ticks; Muxer::resolve_durations passes Run::Whole.
  • Tests. reordered_video_cut_inside_a_gop_keeps_decode_times_increasing imports bbb5s_cbr.ts and exports at caps 0s/100ms, asserting tfdt continuity, presentation parity with the whole-GOP export, and a clean ffprobe -v warning read; plus unit tests for the cap and the reorder: 0 distinction.
  • Quest cleanup. The quest file is deleted and its quest/m1/README.md row removed.

Verification: the JS publisher declares reorder: 0 (js/publish/src/video/encoder.ts:619) and max_reorder is 0 for VP8/VP9/AV1, so the reorder detection matches the claim. The only production with_fragment_duration consumer is moq-cli subscribe; the HLS and Muxer::fragment paths accumulate whole groups per fragment and anchor on a keyframe, where Run::Whole is correct.

The two acknowledged trade-offs (a GOP re-anchor can still step tfdt back after an overshooting previous GOP; undeclared-reorder H.264/H.265 that stalls past the cadence now takes the cadence) are pre-existing or explicitly reasoned, not introduced regressions.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@coderabbitai

coderabbitai Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b9ea95d2-8b06-492a-822e-9299fcd230ff
Commits

Reviewing files that changed from the base of the PR and between aaa22cc and 1a728e2.

Files selected for processing: 4
  • quest/m1/README.md
  • rs/moq-mux/src/container/fmp4/export.rs
  • rs/moq-mux/src/container/fmp4/export_test.rs
  • rs/moq-mux/src/container/fmp4/mod.rs
Files with no reviewable changes: 1
  • quest/m1/README.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

Walkthrough

The fMP4 exporter retains each fragment’s decode endpoint and uses it to continue fragments that do not open a GOP. It classifies runs as whole or partial GOPs and caps inferred durations longer than the fallback cadence for partial-GOP runs that may reorder. The encoding API returns fragment bytes with the ending decode time. Added tests check duration inference and capped exports. The related quest entry and planning document were removed.

Merge Risk: Minimal · up to 1a728

No merge-blocking issue was identified; normal checks should pass before merge.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly and concisely identifies the main change: preventing decreasing fMP4 decode times in sub-GOP fragments.
Docstring Coverage Passed Docstring coverage is 93.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentati…
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 pull request description directly explains the fMP4 decode-timestamp problem, the exporter changes, affected behavior, limitations, and tests. It is clearly related to the changeset.
Full details: Docstring Coverage

Explanation

Docstring coverage is 93.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 15 functions across 5 files.

Finishing Touches
Simplify code
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@moq-bot
moq-bot Bot disabled auto-merge November 1, 2026 21:56
@moq-bot
moq-bot Bot enabled auto-merge (squash) November 1, 2026 21:56
@moq-bot
moq-bot Bot disabled auto-merge November 1, 2026 23:15
@moq-bot moq-bot Bot removed the quest:merge label Nov 1, 2026
@moq-bot

moq-bot Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

codex / Codex land fixer: This maintainer pick already used its mechanical fi·x attempt. Run /quest-iterate to diagnose the repeated failure, then pick it again. Recommendation: run /quest-iterate before picking it again.

        relay_command,
    ]
    if number == 7512:
        commands.extend([
            'cargo bench --locked --manifest-path rs/moq-auth/Cargo.toml --bench verify --profile dev -- --test',
            'python3 sh/gh/nightly.test.py',
        ])
    reason = (
        f'Healthy unchanged; apparent flaky test {test} (failure log lines 10642-10645); '
        'no supplied PR can be identified as the cause from its changes. '
        'Passed on this pinned branch: ' + '; '.join(commands) + '. '
        f'Also passed 20/20 strict repetitions on base and 20/20 on batch: {stress_command}.'
    )
    entries.append({'number': number, 'action': 'requeue', 'reason': reason})
Path('quest-land-result.json').write_text(json.dumps(entries, indent=2) + '\\n')
assert len(json.loads(Path('quest-land-result.json').read_text())) == 5
print('Wrote five requeue entries; all pinned branch heads verified unchanged.')
PY
git status --short" in /work
 succeeded in 31ms:
Switched to branch 'base'
Wrote five requeue entries; all pinned branch heads verified unchanged.
?? quest-land-result.json

diff --git a//tmp/quest-validate.sh b//tmp/quest-validate.sh
new file mode 100644
index 0000000000000000000000000000000000000000..47c533ed93127a5ca5153eb61f1dc7aed4873b28
--- /dev/null
+++ b//tmp/quest-validate.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+set -u
+cd /work
+ulimit -Sl "$(ulimit -Hl)"
+for spec in 7464:moq-nvenc 7465:moq-rtmp 7491:moq-mux 7502:moq-uring 7512:moq-auth; do
+    number=${spec%%:*}
+    package=${spec#*:}
+    git switch "pr-$number" || exit 1
+    if [[ $number == 7512 ]]; then
+        selector=(--manifest-path rs/moq-auth/Cargo.toml)
+    else
+        selector=(-p "$package")
+    fi
+    cargo build --locked "${selector[@]}" > "/tmp/quest-$number-build.log" 2>&1
+    echo "$number build $?"
+    CI_STRICT=1 timeout 300 cargo test --locked "${selector[@]}" --tests -- --test-threads=4 > "/tmp/quest-$number-tests.log" 2>&1
+    echo "$number tests $?"
+    CI_STRICT=1 cargo test --locked -p moq-relay --features io-uring --test integration runtime_uring::uring_auth_reports_distinct_quic_and_webtransport -- --exact --nocapture > "/tmp/quest-$number-relay.log" 2>&1
+    echo "$number relay $?"
+    if [[ $number == 7512 ]]; then
+        cargo bench --locked --manifest-path rs/moq-auth/Cargo.toml --bench verify --profile dev -- --test > /tmp/quest-7512-bench.log 2>&1
+        echo "$number bench $?"
+        python3 sh/gh/nightly.test.py > /tmp/quest-7512-nightly.log 2>&1
+        echo "$number nightly $?"
+    fi
+done

codex
Recorded all five PRs as **requeue unchanged** in [quest-land-result.json](/work/quest-land-result.json).

Builds and tests passed. The failing transport test passed 20 strict runs each on base and batch; it is named as apparently flaky. No blame assigned, no branches changed, and the result file remains uncommitted.
diff --git a//tmp/quest-validate.sh b//tmp/quest-validate.sh
new file mode 100644
index 0000000000000000000000000000000000000000..47c533ed93127a5ca5153eb61f1dc7aed4873b28
--- /dev/null
+++ b//tmp/quest-validate.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+set -u
+cd /work
+ulimit -Sl "$(ulimit -Hl)"
+for spec in 7464:moq-nvenc 7465:moq-rtmp 7491:moq-mux 7502:moq-uring 7512:moq-auth; do
+    number=${spec%%:*}
+    package=${spec#*:}
+    git switch "pr-$number" || exit 1
+    if [[ $number == 7512 ]]; then
+        selector=(--manifest-path rs/moq-auth/Cargo.toml)
+    else
+        selector=(-p "$package")
+    fi
+    cargo build --locked "${selector[@]}" > "/tmp/quest-$number-build.log" 2>&1
+    echo "$number build $?"
+    CI_STRICT=1 timeout 300 cargo test --locked "${selector[@]}" --tests -- --test-threads=4 > "/tmp/quest-$number-tests.log" 2>&1
+    echo "$number tests $?"
+    CI_STRICT=1 cargo test --locked -p moq-relay --features io-uring --test integration runtime_uring::uring_auth_reports_distinct_quic_and_webtransport -- --exact --nocapture > "/tmp/quest-$number-relay.log" 2>&1
+    echo "$number relay $?"
+    if [[ $number == 7512 ]]; then
+        cargo bench --locked --manifest-path rs/moq-auth/Cargo.toml --bench verify --profile dev -- --test > /tmp/quest-7512-bench.log 2>&1
+        echo "$number bench $?"
+        python3 sh/gh/nightly.test.py > /tmp/quest-7512-nightly.log 2>&1
+        echo "$number nightly $?"
+    fi
+done

tokens used
117,023
Recorded all five PRs as **requeue unchanged** in [quest-land-result.json](/work/quest-land-result.json).

Builds and tests passed. The failing transport test passed 20 strict runs each on base and batch; it is named as apparently flaky. No blame assigned, no branches changed, and the result file remains uncommitted.
fixer result written

(written by codex / Codex)

@kixelated

Copy link
Copy Markdown
Collaborator Author

Diagnosis of the failed_checks handback (2026-11-01T23:15Z): the failure isn't caused by this PR, and the head stays at 1a728e23287c9bdc78307dfa5cf39f8688d8a599.

  • The two land failures were different. The first was this PR's new fMP4 test still using moq_clock after main renamed it to kio::clock; the land fixer's mechanical fix resolved it. The second, which used up the pick, was moq-relay's runtime_uring::uring_auth_reports_distinct_quic_and_webtransport.
  • This PR only changes moq-mux fMP4 export, and moq-relay doesn't depend on moq-mux (cargo tree -p moq-relay -e normal,dev has no moq-mux). The failing test doesn't build any of this PR's code.
  • The fixer's validation passed that test 20/20 strict on both base and batch. The other four PRs in that batch were requeued unchanged and have since landed, including moq-dev/moq#7502 (moq-uring) and moq-dev/moq#7512 (moq-auth), so later batches passed the same test.
  • The existing work on io_uring test flakiness is moq-dev/moq#7593 (draft): it puts every uring test in the nextest group and surfaces worker startup errors instead of timeouts.
  • Locally, merging current origin/main into this branch is conflict-free, and just rs check-test-changed (moq-mux and its dependents: clippy, tests, fmt, docs) passes: 4118 + 582 + 277 tests.
  • That local run needed a one-line fix outside this PR: since moq-dev/moq#7494, the listener::Io re-export at rs/moq-relay/src/listener.rs:20 is unused without the websocket feature. Builds that select only moq-cli or moq-studio (which use default-features = false) then fail under -D warnings. Workspace feature unification hides it in full builds. It isn't committed here; it's a separate follow-up.

The existing review record still covers this head (round 1 plus the land fixer's recorded mechanical fix), so it's ready to pick again.

(Written by Claude Opus 5.5)

@kixelated
kixelated enabled auto-merge (squash) November 2, 2026 06:15
@moq-bot

moq-bot Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

codex / Codex land fixer note:

No blame assigned: the failing listener.rs file is byte-for-byte identical on base, the pinned PR head, and batch; this PR changes moq-mux and does not tighten checks.

Original failure log, lines 845–865:

warning: unused import: Io
--> rs/moq-relay/src/listener.rs:20:34
pub(crate) use idle::{Admission, Io};
error: moq-relay (lib) generated 1 warning
error: warnings are denied by build.warnings configuration

At the pinned PR head, CARGO_BUILD_WARNINGS=deny RUSTC_WORKSPACE_WRAPPER=$(command -v clippy-driver) cargo nextest run --locked --tests -p moq-mux built successfully: 1,961 tests passed, 3 skipped, including both added regression tests.

Retried the batch's package selection and feature set, but its build exited 101: "The system library alsa required by crate alsa-sys was not found." Required batch validation therefore remains incomplete. No tracked files or PR branches were changed.

(written by codex / Codex)

@moq-bot
moq-bot Bot disabled auto-merge November 2, 2026 07:02
@moq-bot moq-bot Bot removed the quest:merge label Nov 2, 2026
@moq-bot

moq-bot Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

codex / Codex land fixer: Batch log reports base's unchanged moq-relay unused Io import with warnings denied; local batch validation &#96;CARGO_BUILD_WARNINGS=deny RUSTC_WORKSPACE_WRAPPER=$(command -v clippy-driver) cargo nextest . Recommendation: Fi·x the unused Io re-export on base separately, restore ALSA pkg-config configuration, and rerun the required batch validation; retain PR &#35;7491 unchanged.

warning: unused import: `Io`
  --> rs/moq-relay/src/listener.rs:20:34
   |
20 | pub(crate) use idle::{Admission, Io};
   |                                  ^^
   |
   = note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default

   Compiling moq-audio v0.1.10 (/work/rs/moq-audio)
   Compiling moq-hls v0.5.11 (/work/rs/moq-hls)
   Compiling moq-rtc v0.3.12 (/work/rs/moq-rtc)
   Compiling moq-rtmp v0.3.11 (/work/rs/moq-rtmp)
   Compiling moq-rtsp v0.1.0 (/work/rs/moq-rtsp)
   Compiling moq-srt v0.3.11 (/work/rs/moq-srt)
   Compiling moq-scene v0.1.0 (/work/rs/moq-scene)
   Compiling moq-carla-bridge v0.1.0 (/work/demo/carla/bridge)
   Compiling moq-transcode v0.1.10 (/work/rs/moq-transcode)
error: `moq-relay` (lib) generated 1 warning (run `cargo clippy --fix --lib -p moq-relay` to apply 1 suggestion)
error: warnings are denied by `build.warnings` configuration
warning: build failed, waiting for other jobs to finish...
error: command `/nix/store/85lxjwg78jw6rf7pqkf3vcq6291nrlfh-cargo-1.98.1-x86_64-unknown-linux-gnu/bin/cargo '--color=auto' test --no-run --message-format json-render-diagnostics --package 'path+file:///work/demo/carla/bridge#moq-carla-bridge@0.1.0' --package 'path+file:///work/rs/hang#0.21.11' --package 'path+file:///work/rs/moq-audio#0.1.10' --package 'path+file:///work/rs/moq-boy#0.5.12' --package 'path+file:///work/rs/moq-c#0.7.0' --package 'path+file:///work/rs/moq-cli#0.14.2' --package 'path+file:///work/rs/moq-ffi#0.4.12' --package 'path+file:///work/rs/moq-gst#0.4.12' --package 'path+file:///work/rs/moq-hls#0.5.11' --package 'path+file:///work/rs/moq-mux#0.10.11' --package 'path+file:///work/rs/moq-rtc#0.3.12' --package 'path+file:///work/rs/moq-rtmp#0.3.11' --package 'path+file:///work/rs/moq-rtsp#0.1.0' --package 'path+file:///work/rs/moq-scene#0.1.0' --package 'path+file:///work/rs/moq-srt#0.3.11' --package 'path+file:///work/rs/moq-studio#0.1.0' --package 'path+file:///work/rs/moq-transcode#0.1.10' --package 'path+file:///work/rs/moq-video#0.1.10' --package moq-video --package moq-audio --tests --features 'moq-video/capture moq-audio/capture moq-audio/playback moq-cli/play moq-cli/openh264' --locked` exited with code 101

(written by codex / Codex)

@kixelated
kixelated added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit f882be3 Nov 2, 2026
10 checks passed
@kixelated
kixelated deleted the quest/m1/fmp4-bframe-decode-time branch November 2, 2026 16:04
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