Repository navigation
fix(rendering): stale frames in same-clip cross-fades and seeks with the FFmpeg decoder - #2661
Merged
Merged
Conversation
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This comment has been minimized.
This comment has been minimized.
…ux renderer frame
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Exports and editor playback that use the FFmpeg decoder (Linux, and Windows without a D3D11 video device) could show frames up to 89 source frames old. This happened in a cross-fade between two parts of the same clip, after a seek back to the start, and in seek storms.
Causes
editing/export/same-clip-transition/forward/ffmpeg: up to 55 frames stale). Media Foundation holds one position too, and seeks for every interleaved request instead.seek/seek-gop/home-then-play30/ffmpeg).Fix
flowchart LR T[transition frame] -->|incoming side| P[clip decoders] T -->|outgoing side, same clip| S["transition_side(): second readers, opened on first use"] T -->|outgoing side, other clip| O[that clip's decoders]crates/rendering/src/lib.rs).RecordingSegmentDecoders::transition_side()opens a second screen and camera reader on first use and keeps it. The outgoing side of a same-clip transition reads from it: export, editor playback prefetch, the scrub preview and the export preview. The AVAssetReader pool already opens a reader per position, so on macOS it is shared and nothing extra opens. If the second readers fail to open, both sides fall back to the one reader, as before.crates/rendering/src/decoder/ffmpeg.rs).reader_attracks the newest frame the reader has vended since its last reset, including a frame pulled for a request that was then dropped. A cache miss at or behind it resets the reader. Known VFR holds are still answered first, so a reader parked in a long hold does not seek every frame.The same changes apply to the software-fallback loop.
Measured
Engine verify cases on Apple silicon, FFmpeg decoder:
editing/export/same-clip-transition/forwardediting/export/basic/seed-5,-10,-23,-37editing/export/multi-segment/seed-7seek/seek-gop/home-then-play30audio/audio-mix-30s-a2/long-crossfade/mp4-*(Linux, Windows)seek/*/storm*, fast tierseek/*/storm*, full tier (3000 seeks)MAX_FRAME_LOOKBACK_TOLERANCE), now the only mechanism in those entries, which are marked flaky with tight bounds.decoder::model): 27 FFmpeg stale and overread groups pass, 14 entries are removed and 13 narrowed. Eleven seeds move to the existing grid-rounding and future classes. Where main answered them with a stale frame, the decoder now seeks, and the seek path's known rounding (request time to frame, and to the stream tick) can land one frame off.editing/export/basic/seed-23output frame 8 shows incoming camera frame 84 for 76 (main: output frames 7 to 12 up to 70 stale). A traced run (38997099068) shows the decoder answering request 76 with frame 76, the same as on macOS, so the wrong frame comes from the software renderer's shared camera layer, which draws both transition sides. That is a separate follow-up.Performance
scripts/verify/perf-ab.py(#2660) against the merge base on Apple silicon, 3 interleaved pairs, median CPU time: export-basic +0.1%, export-jitter-camera-40s -0.1%, seek storms +0.1% (9.62 s to 9.63 s), playback-basic -0.2%. The second readers open once per clip, and only when a same-clip transition is rendered.

Confidence Score: 5/5
The PR appears safe to merge; no actionable issue was found.Summary
The PR separates the two readers used during same-clip transitions and fixes FFmpeg seeks that previously depended on the last returned frame.
Review used source inspection. No runtime tests were run.
Reviews (1) · Last reviewed commit: "fix(rendering): seek the FFmpeg decoder ..." · Reviewed by Greptile