client: allow webcam resolution overrides

This commit is contained in:
Brad Stein 2026-01-06 09:47:41 -03:00
parent 368319af63
commit 49fdd9c3de

View File

@ -7,6 +7,13 @@ use gstreamer as gst;
use gstreamer_app as gst_app; use gstreamer_app as gst_app;
use lesavka_common::lesavka::VideoPacket; use lesavka_common::lesavka::VideoPacket;
fn env_u32(name: &str, default: u32) -> u32 {
std::env::var(name)
.ok()
.and_then(|v| v.parse::<u32>().ok())
.unwrap_or(default)
}
pub struct CameraCapture { pub struct CameraCapture {
#[allow(dead_code)] // kept alive to hold PLAYING state #[allow(dead_code)] // kept alive to hold PLAYING state
pipeline: gst::Pipeline, pipeline: gst::Pipeline,
@ -28,23 +35,30 @@ impl CameraCapture {
// (NVIDIA → VA-API → software x264). // (NVIDIA → VA-API → software x264).
let (enc, kf_prop, kf_val) = Self::choose_encoder(); let (enc, kf_prop, kf_val) = Self::choose_encoder();
tracing::info!("📸 using encoder element: {enc}"); 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 have_nvvidconv = gst::ElementFactory::find("nvvidconv").is_some();
let (src_caps, preenc) = match enc { let (src_caps, preenc) = match enc {
// ─────────────────────────────────────────────────────────────────── // ───────────────────────────────────────────────────────────────────
// Jetson (has nvvidconv) Desktop (falls back to videoconvert) // Jetson (has nvvidconv) Desktop (falls back to videoconvert)
// ─────────────────────────────────────────────────────────────────── // ───────────────────────────────────────────────────────────────────
"nvh264enc" if have_nvvidconv => "nvh264enc" if have_nvvidconv =>
("video/x-raw(memory:NVMM),format=NV12,width=1280,height=720", (format!(
"nvvidconv !"), "video/x-raw(memory:NVMM),format=NV12,width={width},height={height},framerate={fps}/1"
), "nvvidconv !"),
"nvh264enc" /* else */ => "nvh264enc" /* else */ =>
("video/x-raw,format=NV12,width=1280,height=720", (format!(
"videoconvert !"), "video/x-raw,format=NV12,width={width},height={height},framerate={fps}/1"
), "videoconvert !"),
"vaapih264enc" => "vaapih264enc" =>
("video/x-raw,format=NV12,width=1280,height=720", (format!(
"videoconvert !"), "video/x-raw,format=NV12,width={width},height={height},framerate={fps}/1"
), "videoconvert !"),
_ => _ =>
("video/x-raw,width=1280,height=720", (format!(
"videoconvert !"), "video/x-raw,width={width},height={height},framerate={fps}/1"
), "videoconvert !"),
}; };
// let desc = format!( // let desc = format!(
@ -65,7 +79,7 @@ impl CameraCapture {
queue max-size-buffers=30 leaky=downstream ! \ queue max-size-buffers=30 leaky=downstream ! \
appsink name=asink emit-signals=true max-buffers=60 drop=true" 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) let pipeline: gst::Pipeline = gst::parse::launch(&desc)
.context("gst parse_launch(cam)")? .context("gst parse_launch(cam)")?