From 14bad67a04001024b2c33c0112faf985ea487c38 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Sun, 29 Jun 2025 12:28:25 -0500 Subject: [PATCH] AV Desc fix --- client/src/output/video.rs | 13 +++++--- server/src/video.rs | 67 +++++++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/client/src/output/video.rs b/client/src/output/video.rs index 4a0591d..8ade65c 100644 --- a/client/src/output/video.rs +++ b/client/src/output/video.rs @@ -35,12 +35,15 @@ impl MonitorWindow { .expect("not a pipeline"); // Optional: turn the sink full‑screen when LESAVKA_FULLSCREEN=1 - if std::env::var("LESAVKA_FULLSCREEN").is_ok() { - if let Some(sink) = pipeline.by_name("sink") { - sink.set_property_from_str("fullscreen", "true"); - sink.set_property("force-aspect-ratio", &true); - // Wayland & GL sinks accept it :contentReference[oaicite:1]{index=1} + let fullscreen = std::env::var("LESAVKA_FULLSCREEN").is_ok(); + if let Some(sink) = pipeline.by_name("sink") { + // glimagesink: title / fullscreen / force‑aspect‑ratio + let title = format!("Lesavka‑eye‑{_id}"); + let _ = sink.set_property("title", &title); // only if supported + if fullscreen { + let _ = sink.set_property("fullscreen", &true); // ditto } + let _ = sink.set_property("force-aspect-ratio", &true); } /* ---------- AppSrc ------------------------------------------------- */ diff --git a/server/src/video.rs b/server/src/video.rs index 5c46558..45499d1 100644 --- a/server/src/video.rs +++ b/server/src/video.rs @@ -8,7 +8,7 @@ use gst::{log, MessageView}; use lesavka_common::lesavka::VideoPacket; use tokio_stream::wrappers::ReceiverStream; use tonic::Status; -use tracing::{debug, enabled, trace, Level}; +use tracing::{debug, warn, error, info, enabled, trace, Level}; use futures_util::Stream; const EYE_ID: [&str; 2] = ["l", "r"]; @@ -76,6 +76,41 @@ pub async fn eye_ball( let (tx, rx) = tokio::sync::mpsc::channel(8192); + /* ----- BUS WATCH: show errors & warnings immediately --------------- */ + let bus = pipeline.bus().expect("bus"); + let eye_clone = eye.to_owned(); + std::thread::spawn(move || { + for msg in bus.iter_timed(gst::ClockTime::NONE) { + use gst::MessageView::*; + match msg.view() { + Error(err) => { + tracing::error!(target:"lesavka_server::video", + eye = %eye_clone, + "💥 pipeline error: {} ({})", + err.error(), err.debug().unwrap_or_default()); + } + Warning(w) => { + tracing::warn!(target:"lesavka_server::video", + eye = %eye_clone, + "⚠️ pipeline warning: {} ({})", + w.error(), w.debug().unwrap_or_default()); + } + Info(i) => { + tracing::info!(target:"lesavka_server::video", + eye = %eye_clone, + "📌 pipeline info: {} ({})", + i.error(), i.debug().unwrap_or_default()); + } + StateChanged(s) if s.current() == gst::State::Playing => { + tracing::info!(target:"lesavka_server::video", + eye = %eye_clone, + "🎬 pipeline PLAYING"); + } + _ => {} + } + } + }); + sink.set_callbacks( gst_app::AppSinkCallbacks::builder() .new_sample(move |sink| { @@ -121,13 +156,29 @@ pub async fn eye_ball( / 1_000; /* -------- ship over gRPC ----- */ - let pkt = VideoPacket { - id, - pts: pts_us, - data: map.as_slice().to_vec(), - }; - tracing::trace!("srv→grpc eye-{eye} {} bytes pts={}", pkt.data.len(), pkt.pts); - let _ = tx.try_send(Ok(pkt)); + let data = map.as_slice().to_vec(); + let size = data.len(); + let pkt = VideoPacket { id, pts: pts_us, data }; + match tx.try_send(Ok(pkt)) { + Ok(_) => { + trace!(target:"lesavka_server::video", + eye = %eye, + size = size, + "📤 sent"); + } + Err(tokio::sync::mpsc::error::TrySendError::Full(_)) => { + static DROP_CNT: std::sync::atomic::AtomicU64 = + std::sync::atomic::AtomicU64::new(0); + let c = DROP_CNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + if c % 120 == 0 { + debug!(target:"lesavka_server::video", + eye = %eye, + dropped = c, + "⏳ channel full – dropping frames"); + } + } + Err(e) => error!("mpsc send err: {e}"), + } Ok(gst::FlowSuccess::Ok) })