53 lines
1.5 KiB
Rust
Raw Normal View History

2025-06-21 05:21:57 -05:00
// client/src/output/video.rs
use gstreamer as gst;
use gstreamer_app as gst_app;
use gst::prelude::*;
2025-06-24 23:48:06 -05:00
use gst_app::prelude::*;
2025-06-23 07:18:26 -05:00
use lesavka_common::lesavka::VideoPacket;
2025-06-24 23:48:06 -05:00
use winit::window::{Window, WindowAttributes};
use winit::event_loop::EventLoop;
2025-06-21 05:21:57 -05:00
pub struct MonitorWindow {
id: u32,
_window: Window,
src: gst_app::AppSrc,
}
impl MonitorWindow {
pub fn new(id: u32, el: &EventLoop<()>) -> anyhow::Result<Self> {
gst::init()?;
2025-06-24 23:48:06 -05:00
let window = el.create_window(
WindowAttributes::default()
.with_title(format!("Lesavkamonitor{id}"))
.with_decorations(false)
)?;
2025-06-21 05:21:57 -05:00
// appsrc -> decode -> convert -> waylandsink
2025-06-24 23:48:06 -05:00
let desc = "appsrc name=src is-live=true format=time do-timestamp=true ! \
2025-06-25 12:31:48 -05:00
queue ! h264parse ! decodebin ! videoconvert ! \
waylandsink name=sink sync=false";
2025-06-24 23:48:06 -05:00
let pipeline = gst::parse::launch(desc)?
.downcast::<gst::Pipeline>()
.unwrap();
let src = pipeline
.by_name("src").unwrap()
.downcast::<gst_app::AppSrc>().unwrap();
src.set_latency(gst::ClockTime::NONE, gst::ClockTime::NONE);
2025-06-21 05:21:57 -05:00
pipeline.set_state(gst::State::Playing)?;
2025-06-24 23:48:06 -05:00
2025-06-21 05:21:57 -05:00
Ok(Self { id, _window: window, src })
}
pub fn push_packet(&self, pkt: VideoPacket) {
2025-06-24 23:48:06 -05:00
let mut buf = gst::Buffer::from_slice(pkt.data);
buf.get_mut().unwrap()
.set_pts(Some(gst::ClockTime::from_useconds(pkt.pts)));
let _ = self.src.push_buffer(buf);
2025-06-21 05:21:57 -05:00
}
}