Repository navigation
fix(mux)!: make fMP4 refusals terminal - #7628
Conversation
Quest-Claim: 1184034e567f919e
Choose terminal refusal over input draining so arbitrary chunking cannot silently resume after dropped bytes. Verify HLS generation recovery and checkpoint the outstanding quiet-host benchmark and full-gate limitation. Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Keep failed importers inert, preserve malformed-track abort codes, and document terminal decoding on the shared container surface. Record the passing clean-shell gate separately from the inherited-environment failure. Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
|
Design change: HLS now retires a refused fMP4 importer immediately instead of spending the transient-fetch retry budget on a terminal decoder. Rewinds still terminate the import, transient fetch failures retain their existing handling, and subsequent decode/control calls on a refused importer keep the original error. This addresses the local review while preserving the quest's authorized terminal-refusal choice. (Written by GPT-6.1 Sol) |
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 34 minutes. View limit details
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. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 7d0717f
No actionable bugs found. Making decode refusals terminal fixes arbitrary-chunk framing at its source and removes recovery/deferred-control complexity. The first error remains sticky across decode and controls, partial media is aborted, and HLS retires refused generations while retaining fatal rewind handling. Migration notes and split-boundary/replacement tests cover the behavior change.
Verification limits: static source review only. I did not run tests, HLS playback, or benchmarks; the reported performance measurements were not independently reproduced.
(Written by OpenAI)
There was a problem hiding this comment.
ℹ️ No critical issues — one test comment claims a retry-budget behavior the code does not have.
Reviewed changes
- Terminal fMP4 refusals —
Import::decodenow delegates to a new privatedrain; on any error it aborts a heldBody::Media, clearsbuffer/moof/deferred, latches the error, and every laterdecode/cut/seek/discontinuityreturns it without reading input or changing tracks.finishstill ends the accepted media. The old refused-box skip and post-refusalsettle()paths are gone, fixing the lost-framing bug where a refused box's unread tail could be silently dropped. - HLS retires refused importers — a decode error other than a timestamp reset now calls
evict()before returning, so the next pass rebuilds the generation from its init segment under fresh track names. The new test covers both passthrough modes and a repaired source. - Docs & tests —
MIGRATE.mdrecords the breaking behavior;import/container.rsdocuments terminal decode errors; the quest and its links are deleted; the fragment/oversized-metadata/text tests are reworked to the terminal contract with a split-sweep test.
The fMP4 terminal-state cleanup is complete: every early return in drain leaves self.body None or a writers-cleared Media, so no open frame leaks, no double-abort occurs, and finish() never synthesizes a spurious UnexpectedEof. HLS eviction is bounded (run retries the non-settled error with backoff rather than looping), and group numbering stays anchored to the HLS sequence so sibling renditions cannot desync.
deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Problem
An fMP4 header refusal dropped the refusing call's unread tail. A later arbitrary chunk could then report success after losing the next box's prefix. This PR implements the framing fix from the quest, re-measures the interleaved import benchmark, and finishes the quest.
Approach
finish()still closes accepted media without clearing the refusal.MAX_RENDITION_FAILUREScount that transient fetch failures still get. The refusal is not settled, sorunstill retries the step within its backoff budget. A timestamp rewind still ends the HLS import (Error::Rewind). Existing init-map replacement, discontinuity, and timestamp-refusal tests pass. CLI chunked input already propagates decode errors and aborts the instance.quest/m1/fmp4-refusal-framing.mdand its links.Impact
container::fmp4::Import::decodefails, decoding and controls keep returning that error; replace the importer to resume, including throughimport::Container. Box-aligned input no longer recovers on the same importer. Migration notes are undermoq-mux/MIGRATE.md's Unreleased section. No signatures or exported items change.Alternatives
Draining the refusing call would preserve recovery but require tracking the first error while processing more input and more failure/control paths. The recorded plan explicitly permits terminal refusal; HLS already owns importer replacement, so the smaller state machine meets its needs.
Performance
cmaf-interleaved-import/4tracks/16runs-4096bytes, the 4,232,444-byte workload the quest names. The historical whole-input ID lacks today's-<chunk>chunksuffix, so the cases are paired explicitly. The bench body is the same at every revision apart from that suffix.Revisions:
base=038ecfa6b3(parent of moq-dev/moq#7232),stream=951cca678c(#7232),main=96244dd854(this branch's merge parent),current=c147c2caf3(this branch at that merge; the later commit only deletes the quest). Each binary was built from agit archiveof its revision with its own target dir. Each pass ran 6 rounds over every order of its sides, each run with Criterion at 1 s warmup, 2 s measurement and 30 samples (the repo's paired-comparison settings), pinned to the P-cores 0-7. Both builds and measurement ran throughquest gate, which admitted them at a 1-minute load of 17-19 on 24 CPUs. Load then rose to 39-45 during the runs from other sessions, so the host was shared, not quiet. Medians of the per-round paired deltas follow; "held" means every round had the same sign.decodecall, from the terminal-error check and wrapper. A variant that moved the failure handling into a#[cold]function and rebuiltOk(())measured −1.1% against this branch with a mixed sign (fixpass: −2.3…+5.4%), so it was dropped as unproven. Choice made without asking: this per-call cost is accepted. One-byte chunks are pathological (HLS feeds whole segments, CLI reads buffered chunks), and the cost is below the noise at any realistic chunk size.951cca678cand96244dd854and is outside this PR (see Follow-ups).Validation
mdatplus four bytes of the nextstypheader, followed by its remaining four bytes, returned success without declaring the segment boundary. The reproduction failed withthe styp prefix was silently dropped. The permanent test sweeps splits through the refused body and next header, including empty input and decoding afterfinish().origin/main(d26e2aac82) on head317662a81b:quest gate nix develop --ignore-environment --keep HOME --keep USER --keep PATH --command just ci origin/main: passed, including 4,416 Rust tests (67 skipped) and every selected check.quest check --base origin/main: 586 documents OK.Review
gpt-6.1-sol, medium effort, round 2 of the Codex session, head317662a81b44e52aad5e4a9b553a0eacd28c492a: 0 findings. Changes since round 1 were a docstring rewording and a merge oforigin/main.run'sSTEP_RETRY_BUDGET, which a refusal still spends. Fixed: the docstring now names theMAX_RENDITION_FAILUREScount the refusal skips, and saysrunstill retries it within its backoff budget.7d0717fc48: 0 findings.3ed95cc36abefore the main merge and quest deletion (Claude Code,claude-opus-5-5, medium): round 1 preservedMalformedTrackabort codes, made HLS retire refused importers immediately, kept failed controls inert, and documented terminal behavior on sharedimport::Container::decode. Broader binding-doc duplication was refuted: the FFI write describes arbitrary chunk splitting and directly propagatesMoqError::Codec(rs/moq-ffi/src/media.rs:1182-1196), and makes no recovery-after-error promise. Round 2 reported 0 findings.Follow-ups
951cca678cand96244dd854made 1-byte-chunk fMP4 import ~19% slower (283 → 341 ms), and whether any realistic chunk size feels it. Candidates touching the path include moq-dev/moq#7491, moq-dev/moq#7398, moq-dev/moq#6985 (feature unification) and moq-dev/moq#7218. Low priority: whole-input and 1 KiB chunks show no change.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code