From 49fdd9c3dec1253a294cceb7fd6348137ff5414d Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Tue, 6 Jan 2026 09:47:41 -0300 Subject: [PATCH] client: allow webcam resolution overrides --- client/src/input/camera.rs | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/client/src/input/camera.rs b/client/src/input/camera.rs index ee949fa..61120cf 100644 --- a/client/src/input/camera.rs +++ b/client/src/input/camera.rs @@ -7,6 +7,13 @@ use gstreamer as gst; use gstreamer_app as gst_app; use lesavka_common::lesavka::VideoPacket; +fn env_u32(name: &str, default: u32) -> u32 { + std::env::var(name) + .ok() + .and_then(|v| v.parse::().ok()) + .unwrap_or(default) +} + pub struct CameraCapture { #[allow(dead_code)] // kept alive to hold PLAYING state pipeline: gst::Pipeline, @@ -28,23 +35,30 @@ impl CameraCapture { // (NVIDIA → VA-API → software x264). let (enc, kf_prop, kf_val) = Self::choose_encoder(); tracing::info!("📸 using encoder element: {enc}"); + let width = env_u32("LESAVKA_CAM_WIDTH", 1280); + let height = env_u32("LESAVKA_CAM_HEIGHT", 720); + let fps = env_u32("LESAVKA_CAM_FPS", 30).max(1); let have_nvvidconv = gst::ElementFactory::find("nvvidconv").is_some(); let (src_caps, preenc) = match enc { // ─────────────────────────────────────────────────────────────────── // Jetson (has nvvidconv) Desktop (falls back to videoconvert) // ─────────────────────────────────────────────────────────────────── "nvh264enc" if have_nvvidconv => - ("video/x-raw(memory:NVMM),format=NV12,width=1280,height=720", - "nvvidconv !"), + (format!( + "video/x-raw(memory:NVMM),format=NV12,width={width},height={height},framerate={fps}/1" + ), "nvvidconv !"), "nvh264enc" /* else */ => - ("video/x-raw,format=NV12,width=1280,height=720", - "videoconvert !"), + (format!( + "video/x-raw,format=NV12,width={width},height={height},framerate={fps}/1" + ), "videoconvert !"), "vaapih264enc" => - ("video/x-raw,format=NV12,width=1280,height=720", - "videoconvert !"), + (format!( + "video/x-raw,format=NV12,width={width},height={height},framerate={fps}/1" + ), "videoconvert !"), _ => - ("video/x-raw,width=1280,height=720", - "videoconvert !"), + (format!( + "video/x-raw,width={width},height={height},framerate={fps}/1" + ), "videoconvert !"), }; // let desc = format!( @@ -65,7 +79,7 @@ impl CameraCapture { queue max-size-buffers=30 leaky=downstream ! \ appsink name=asink emit-signals=true max-buffers=60 drop=true" ); - tracing::info!(%enc, ?desc, "📸 using encoder element"); + tracing::info!(%enc, width, height, fps, ?desc, "📸 using encoder element"); let pipeline: gst::Pipeline = gst::parse::launch(&desc) .context("gst parse_launch(cam)")?