From 5201959e08d31d17125b11a1092873183c193193 Mon Sep 17 00:00:00 2001 From: SGavrl <277843151+SGavrl@users.noreply.github.com> Date: Tue, 4 Aug 2026 12:12:47 +0000 Subject: [PATCH] Round screencast frames like Chromium --- crates/obscura-cdp/src/domains/page.rs | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/crates/obscura-cdp/src/domains/page.rs b/crates/obscura-cdp/src/domains/page.rs index f6e5757..806df9b 100644 --- a/crates/obscura-cdp/src/domains/page.rs +++ b/crates/obscura-cdp/src/domains/page.rs @@ -512,8 +512,8 @@ fn encode_screencast_frame( scale = scale.min(f64::from(max_height) / f64::from(source.height())); } let size = ( - (f64::from(source.width()) * scale).floor().max(1.0) as u32, - (f64::from(source.height()) * scale).floor().max(1.0) as u32, + (f64::from(source.width()) * scale).round().max(1.0) as u32, + (f64::from(source.height()) * scale).round().max(1.0) as u32, ); let raster = if size == source.dimensions() { source @@ -1974,6 +1974,27 @@ mod tests { > 0.0 ); assert_eq!(frame.params["sessionId"], 1); + + // Chromium's PageHandler::DetermineSnapshotSize scales the surface + // through gfx::ToRoundedSize. Preserve the fractional 40.8px height + // instead of truncating it to 40px. + ctx.pending_events.clear(); + handle( + "startScreencast", + &json!({"format": "png", "maxWidth": 51}), + &mut ctx, + &session, + ) + .await + .expect("start fractionally scaled screencast"); + let rounded_frame = ctx + .pending_events + .iter() + .find(|event| event.method == "Page.screencastFrame") + .expect("fractionally scaled initial frame"); + let (format, raster) = decode_capture(&rounded_frame.params); + assert_eq!(format, image::ImageFormat::Png); + assert_eq!(raster.dimensions(), (51, 41)); } #[cfg(feature = "render")]