Skip to content

Fix continue-in-closure compile errors in Windows encoder paths#1578

Merged
richiemcilroy merged 2 commits intomainfrom
copilot/fix-continue-in-closure-error
Feb 4, 2026
Merged

Fix continue-in-closure compile errors in Windows encoder paths#1578
richiemcilroy merged 2 commits intomainfrom
copilot/fix-continue-in-closure-error

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 4, 2026

Rust E0267 errors occurred because continue was used inside closure bodies in the Windows output pipeline. This broke build steps in the recording crate.

  • Encoder frame pacing (hardware): wrapped the closure body in a loop and return early from the closure to keep continue legal while preserving pause/reuse logic.
  • Camera encoder (hardware): applied the same loop/return pattern to handle pauses, timeouts, and timestamp normalization without illegal continue.

Example pattern:

|| {
    loop {
        match video_rx.recv_timeout(frame_interval) {
            Err(RecvTimeoutError::Timeout) if pause_flag.load(Ordering::Acquire) => {
                last_timestamp = None;
                continue;
            }
            Ok(Some((frame, ts))) => {
                last_frame = Some(frame);
                last_timestamp = Some(ts);
            }
            Ok(None) | Err(RecvTimeoutError::Disconnected) => return Ok(None),
            _ => {}
        }

        if let (Some(frame), Some(ts)) = (&last_frame, last_timestamp) {
            let normalized = normalize_camera_timestamp(ts, &mut first_timestamp);
            let texture = upload_mf_buffer_to_texture(&d3d_device, frame, &mut camera_buffers)?;
            return Ok(Some((texture, duration_to_timespan(normalized))));
        }
    }
}

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Greptile Overview

Greptile Summary

fixed continue-in-closure compile errors (E0267) by wrapping closure bodies in an explicit loop and using return statements to exit

  • hardware encoder frame pacing (crates/recording/src/output_pipeline/win.rs:317-370): wrapped in loop, preserved pause/timeout/reuse logic
  • camera encoder (crates/recording/src/output_pipeline/win.rs:842-900): applied same pattern for pause handling and timestamp normalization

the fix maintains identical runtime behavior while satisfying Rust's control flow rules

Confidence Score: 5/5

  • safe to merge - minimal syntax fix that resolves compile errors without changing behavior
  • the changes are a straightforward mechanical fix for Rust E0267 errors (continue in closure), wrapping closure bodies in explicit loops and replacing continue with early returns - the control flow and logic remain identical
  • no files require special attention

Important Files Changed

Filename Overview
crates/recording/src/output_pipeline/win.rs wraps closure bodies in loop to fix continue-in-closure compile errors, preserving pause/timeout logic

Sequence Diagram

sequenceDiagram
    participant Encoder as Hardware Encoder
    participant Closure as Frame Closure
    participant Channel as video_rx Channel
    participant PauseFlag as pause_flag

    Encoder->>Closure: run(closure)
    
    loop Frame Processing Loop
        Closure->>Channel: recv_timeout(frame_interval)
        
        alt Receive Frame
            Channel-->>Closure: Ok(Some((frame, timestamp)))
            Closure->>Closure: Store last_texture/timestamp
        else End of Stream
            Channel-->>Closure: Ok(None)
            Closure-->>Encoder: return Ok(None) [exit]
        else Timeout
            Channel-->>Closure: Err(RecvTimeoutError::Timeout)
            Closure->>PauseFlag: load(Ordering::Acquire)
            alt Paused
                PauseFlag-->>Closure: true
                Closure->>Closure: last_timestamp = None
                Note over Closure: continue loop
            else Not Paused, Has Last Frame
                PauseFlag-->>Closure: false
                Closure->>Closure: Increment timestamp + frames_reused
                Note over Closure: Fall through to return frame
            end
        else Disconnected
            Channel-->>Closure: Err(RecvTimeoutError::Disconnected)
            Closure-->>Encoder: return Ok(None) [exit]
        end
        
        alt Has Both Texture and Timestamp
            Closure->>Closure: normalize_timestamp()
            Closure-->>Encoder: return Ok(Some((texture, time))) [exit]
        else No Frame Yet
            Closure->>Channel: recv() [blocking]
            alt First Frame Received
                Channel-->>Closure: Ok(Some((frame, timestamp)))
                Closure->>Closure: Initialize frame_count = 1
                Closure-->>Encoder: return Ok(Some((texture, time))) [exit]
            else Channel Closed
                Channel-->>Closure: Ok(None) | Err(_)
                Closure-->>Encoder: return Ok(None) [exit]
            end
        end
    end
Loading

Co-authored-by: richiemcilroy <33632126+richiemcilroy@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix continue statement usage inside closure Fix continue-in-closure compile errors in Windows encoder paths Feb 4, 2026
Copilot AI requested a review from richiemcilroy February 4, 2026 13:03
@richiemcilroy richiemcilroy marked this pull request as ready for review February 4, 2026 13:16
@richiemcilroy richiemcilroy merged commit 0539c4d into main Feb 4, 2026
5 checks passed
let frame_time = duration_to_timespan(normalized_ts);
return Ok(Some((texture, frame_time)));
}
Ok(None) | Err(_) => return Ok(None),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This collapses end-of-stream and channel close into the same path and also drops the disconnect signal. Tiny thing, but having separate branches with a trace! makes debugging encoder shutdown/startup a lot easier (same pattern shows up in the camera closure below).

Suggested change
Ok(None) | Err(_) => return Ok(None),
Ok(None) => {
trace!("End of stream signal received");
return Ok(None);
}
Err(e) => {
trace!("Channel disconnected: {e}");
return Ok(None);
}

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.

2 participants