Skip to content

fix(compositor): no Full Camera trail on a clip's first frame when its start is inexact in f32 - #1294

Merged
EtienneLescot merged 1 commit into
mainfrom
fix/fullcam-cut-ghost-f32
Oct 16, 2026
Merged

EtienneLescot merged 1 commit into
mainfrom
fix/fullcam-cut-ghost-f32

Conversation

@EtienneLescot

@EtienneLescot EtienneLescot commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Summary

The macOS e2e pass of v2.1.0-rc.3 found a ghost frame at a trim cut inside a Full Camera region. It shows in the export and in getFrames, but not in the preview. The fix for #1266 (297dfea) didn't catch it. On the first frame of the clip after the cut, the full-frame camera is smeared into several copies that slide toward its PiP corner.

Cause: 297dfea clamps the previous frame's time to the clip's start, but the test that guards that clamp compares the frame time, an f32, with the clip's start widened to f64.

  • The first frame of a clip lands exactly on its start: SpeedSegment::source_time clamps it there, and set_timeline_time passes it on as f32.
  • For a start that f32 rounds down, such as 11.388 (which reads back as 11.38799953 in f64), the clamp was skipped.
  • The previous frame then fell in the trim's hole, where the camera sits in its PiP corner.
  • Meanwhile the Full Camera phase, compared in f32, already had the camera full frame, which gives the trail.

A start that rounds up, such as 15.788090425531916, was unaffected, which is why the same check looked clean on another cut.

The fix compares in f32, as the region bounds already are. A new test reproduces the rc.3 case: a clip starting at 11.388, with its first frame exactly on that start.

Related issue

Refs #1266

Type of change

  • Bug fix
  • Feature
  • Enhancement
  • Documentation
  • Refactor / maintenance
  • Performance
  • Security

Release impact

  • Patch
  • Minor
  • Major / breaking change
  • No release note needed

Desktop impact

  • Windows
  • macOS
  • Linux
  • Installer / packaging
  • Not platform-specific

Screenshots / video

Evidence from the rc.3 export (Full Camera 8.006–14.061 s, trim 10.001–11.388 s, 60 fps):

  • Frame 600 shows the trail toward the corner. It is the first frame of the clip after the cut: the clip before it ends at frame 599.
  • Frames 597–599 and 601–603 are clean.
  • getFrames at 10.000, 10.001, 10.017 and 10.033 s returned the same ghosted frame.

Testing

  • New test the_first_frame_of_a_clip_starting_inside_full_camera_has_no_trail in crates/compositor/src/frame_geometry.rs. It fails without the change, with w_dst_prev at the PiP rect.
  • Not compiled or run locally. The Mac this was written on has no Rust toolchain. This relies on CI's cargo test -p openscreen-compositor --lib --tests (macOS arm64 and x64, Windows, Linux).
  • To verify once merged: export the rc.3 repro project and check frame 600.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed webcam motion blur at clip boundaries so the first frame no longer includes a trail from before the clip starts.

…s start is inexact in f32

The previous frame's time is held at the clip's start (297dfea), but the
test compared the frame time, an f32, with the clip's start widened to f64.
The first frame of the clip after a cut lands exactly on that start
(SpeedSegment::source_time clamps it there, and set_timeline_time hands it
over as f32), and a start f32 rounds down, 11.388 among them, read back as
11.38799953 < 11.388: the hold was skipped, the previous frame fell in the
trim's hole with the camera in its PiP corner, while the Full Camera phase,
compared in f32, already had it full frame. One ghosted frame at the cut in
the export, and in getFrames (macOS pass of v2.1.0-rc.3, frame 600). A start
that rounds up, like 15.788090425531916, was unaffected, which is why the
same check looked clean on another cut.

Compare in f32, as the region bounds are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c0d1761b-d964-423a-bc2d-fdd0f7b293f6
📥 Commits

Reviewing files that changed from the base of the PR and between bb4660b and ea938d6.

📒 Files selected for processing: 1
  • crates/compositor/src/frame_geometry.rs

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

📝 Walkthrough

The active-clip start guard now compares source_t with the clip start converted to f32. A regression test checks the webcam’s first frame when the clip start is not exactly representable as f32.

Changes: Clip-start timestamp precision

Layer / File(s) Summary
Clip-start guard and regression test
crates/compositor/src/frame_geometry.rs
The guard compares source_t with clip.source_start_sec as f32. The regression test checks that the webcam remains full-frame and has no pre-clip motion-blur trail on the first frame.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Merge Risk: ⚪ Minimal · up to ea938

No actionable issue is established; merge after the planned CI tests pass.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly identifies the compositor bug and the specific fix for an inexact f32 clip start causing a Full Camera trail on the first frame.
Description check Passed The description follows the repository template. It explains the bug, cause, fix, related issue, change type, release impact, platform impact, evidence, and testing status. It clearly states that loca…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files.
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.
Full details: Description check

Explanation

The description follows the repository template. It explains the bug, cause, fix, related issue, change type, release impact, platform impact, evidence, and testing status. It clearly states that local tests were not run and identifies the CI validation required.

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 Clippy (1.98.1)

Clippy execution failed

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.

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