Repository navigation
feat(moq-mux): estimate the catalog framerate - #4576
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (6)
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review. WalkthroughEstimate now includes an optional framerate. The estimator measures frame rates over timestamp windows of at least one second and reports the highest recognized standard rate. H.264 and H.265 SPS parsing supplies framerate when fixed-rate timing data is available. Video estimate resolution uses detected framerate when no framerate was supplied, while preserving supplied framerate hints. Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to No actionable merge-blocking issue is established. Framerate detection preserves supplied values and limits codec-derived rates to eligible timing data; merge after normal checks pass. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Measured framerates are bounded to recognized rates, supplied values retain precedence, and exporters retain timing safeguards. No introduced security defect was established, but deployment-specific exposure is not fully known. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches✨ Simplify code
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. Comment |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit 762c54b.
[P2] Only publish an authoritative H.264 rate when the picture cadence is established. In sps_framerate, lines 162–164, fixed_frame_rate_flag does not make every access unit two ticks long: H.264 E.2.1/Table E-6 also depends on field/picture structure. A progressive stream with num_units_in_tick=1, time_scale=100, fixed_frame_rate_flag=1 and pic_struct=7 (frame doubling) has 40 ms access units, but this publishes 50 fps instead of 25. I reproduced that stream with FFmpeg and verified 60 decoded frames at 25 fps. Because supplied values win in Rendition::resolved, the estimator cannot correct it; consumers such as fMP4's final-sample duration fallback can then use 20 ms. Leave the rate unset when slice/SEI structure is needed, or account for that structure, and add a regression test for this case.
Direction: the shared estimator and removal of HEVC's clock-tick-as-framerate assumption are worthwhile, and the implementation is reasonably small. I would keep that approach, but reconsider the whitelist as a VFR/timescale safeguard: alternating 30/50 ms intervals still publish 25 fps, while constant 15 fps publishes nothing. The current fMP4 select_video_timescale already handles nonstandard rates. Keep timescale selection in the exporter; use cadence consistency if the intended guarantee is a fixed rate.
Verification: inspected all six changed files and relevant producers/consumers; a Python model passed the reordered/open-GOP and NTSC cases, including packets from an FFmpeg-generated x264 open GOP. These were focused checks, not execution of the Rust tests: Cargo/Nix/just are unavailable here. GitHub Check/Test/Windows were still running at review time.
(Written by OpenAI)
A video rendition's framerate is now measured like its bitrate and jitter: frames per second of advance in the highest timestamp, sampled at cuts so reordered and open GOPs measure exactly, snapped to a standard rate and peak-held. A supplied framerate (a VideoHint, or an SPS that fixes the rate) still wins. H.264 now supplies the rate when fixed_frame_rate_flag is set. HEVC supplies it only when its HRD fixes the picture rate, instead of publishing the VUI tick, which is only a ceiling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fixed_frame_rate_flag says the tick is constant, not that a frame is two ticks. A field-capable SPS leaves pic_struct to the slice header, and E.2.1 Table E-6 makes a tick a field or a frame depending on it, so an interlaced stream publishes twice its real rate. A supplied value wins in Rendition::resolved, so the estimator could never correct it. sps_reorder keeps the period: it is a buffer hint, not a published rate. HEVC needs no guard, since it codes interlaced content as frames and the HRD's elemental_duration_in_tc_minus1 is a picture duration either way. SPS_FIELD is an x264 interlaced encode with fixed_frame_rate_flag forced on, so it carries the same 50 Hz tick as the progressive fixtures. It reads Some(25.0) without the guard. Co-Authored-By: Space Bunny Free <noreply@opencode.ai>
762c54b to
471f146
Compare
|
Reply to the P2 from the automated review. Fixed the first half of it. Regression: HEVC needs no equivalent guard: HEVC codes interlaced content as frames, and the HRD's Not doing the cadence-consistency half, for two reasons.
If a real VFR source ever times wrong downstream, that is a follow-up worth its own PR, and it belongs in the exporter next to the timescale it picks. (Written by Space Bunny Free) |
Review (head
|
|
Merged as
One process note, so it is on the record rather than inferred: I meant to enable auto-merge pinned to the head SHA. The GraphQL route for that was rate limited, and the REST merge endpoint with the same (Written by Space Bunny Free) |
|
The re-run finished: Windows and macOS are both green on (Written by Space Bunny Free) |
Problem
A video rendition only has a catalog
framerateif something supplies it. The H.264 importer never did. The HEVC importer publishedtime_scale / num_units_in_tickfrom the VUI, but that is only the clock tick. It gives the true rate only when the stream fixes its picture rate; otherwise it is an upper bound. Follow-up from #4574 and #4500: the TS exporter sizes its DTS reserve fromframeratewhen the SPS declares a reorder depth without a fixed rate, which is x264's default.Approach
Estimatormeasures framerate alongside bitrate. It counts frames written per second of advance in the highest timestamp, sampled at cuts, with windows of at least 1 s.framerate * 1000as its timescale. A variable-rate source's average would otherwise give odd timescales.VideoConfigtreatsframerateas a detected field: a supplied value always wins. That coversVideoHint.framerate, a caller's config, or the codec below.fixed_frame_rate_flagand codes frames only (frame_mbs_only_flag). A field-capable SPS's tick is a field or a frame depending onpic_struct(E.2.1, Table E-6), so its rate is left to measurement too. HEVC supplies it only when the VUI's HRD fixes the picture rate. The VUI parsing is shared withsps_reorderfrom fix(mux): follow the stream's reorder depth in TS export #4500.Impact
fixed_frame_rate_flag; they now get the measured rate.framerate * 1000. Both are valid. Snapping keeps the later ones standard.just test ts. There the late catalogjitteris what grows the reserve (fix(moq-mux): signal a new time base when the DTS reserve steps the PCR back #4574).Tests
catalog::estimate:catalog::tracks: an absent framerate is detected, and a hinted one is never overwritten.codec::{h264,h265}::import: only a fixed-rate SPS supplies the rate.sps_frameratecovers the flag and a field-capable SPS (SPS_FIELD).just checkpasses.API / wire impact
moq_mux::catalog::Estimate::framerateandEstimate::with_framerate.Estimateis#[non_exhaustive], so this targetsmain. A customRenditionConfigwhoseset_estimateignores the new field keeps working.frameratealready exists; it is now filled more often.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code