Video Fix
This commit is contained in:
parent
1bda63ee46
commit
43808f95d6
@ -7,6 +7,14 @@ use winit::{
|
|||||||
window::{Window, WindowAttributes},
|
window::{Window, WindowAttributes},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DESC: &str = concat!(
|
||||||
|
"appsrc name=src is-live=true format=time do-timestamp=true block=false ! ",
|
||||||
|
"queue max-size-buffers=0 max-size-bytes=0 max-size-time=0 leaky=downstream ! ",
|
||||||
|
"capsfilter caps=video/x-h264,stream-format=byte-stream,alignment=au ! ",
|
||||||
|
"h264parse disable-passthrough=true ! decodebin ! ",
|
||||||
|
"queue ! videoconvert ! autovideosink sync=false"
|
||||||
|
);
|
||||||
|
|
||||||
pub struct MonitorWindow {
|
pub struct MonitorWindow {
|
||||||
id: u32,
|
id: u32,
|
||||||
_window: Window,
|
_window: Window,
|
||||||
@ -30,25 +38,7 @@ impl MonitorWindow {
|
|||||||
.field("alignment", &"au")
|
.field("alignment", &"au")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Optional HW decode with VA‑API if LESAVKA_HW_DEC is set.
|
let pipeline = gst::parse::launch(DESC)?
|
||||||
let desc = if std::env::var_os("LESAVKA_HW_DEC").is_some() {
|
|
||||||
concat!(
|
|
||||||
"appsrc name=src is-live=true format=time do-timestamp=true block=false ! ",
|
|
||||||
"capsfilter caps=video/x-h264,stream-format=byte-stream,alignment=au ! ",
|
|
||||||
"queue max-size-buffers=0 max-size-bytes=0 max-size-time=0 leaky=downstream ! ",
|
|
||||||
"h264parse ! vaapih264dec low-latency=true ! videoconvert ! ",
|
|
||||||
"direct-render-synchronised-videosink ! autovideosink sync=false",
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
concat!(
|
|
||||||
"appsrc name=src is-live=true format=time do-timestamp=true block=false ! ",
|
|
||||||
"capsfilter caps=video/x-h264,stream-format=byte-stream,alignment=au ! ",
|
|
||||||
"queue max-size-buffers=0 max-size-bytes=0 max-size-time=0 leaky=downstream ! ",
|
|
||||||
"h264parse ! decodebin ! videoconvert ! autovideosink sync=false",
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let pipeline = gst::parse::launch(desc)?
|
|
||||||
.downcast::<gst::Pipeline>()
|
.downcast::<gst::Pipeline>()
|
||||||
.expect("pipeline down‑cast");
|
.expect("pipeline down‑cast");
|
||||||
|
|
||||||
@ -59,7 +49,7 @@ impl MonitorWindow {
|
|||||||
.expect("appsink down‑cast");
|
.expect("appsink down‑cast");
|
||||||
|
|
||||||
src.set_caps(Some(&caps));
|
src.set_caps(Some(&caps));
|
||||||
src.set_format(gst::Format::Undefined); // running‑time PTS
|
src.set_format(gst::Format::Time); // running‑time PTS
|
||||||
src.set_property("blocksize", &0u32); // whole AU per buffer
|
src.set_property("blocksize", &0u32); // whole AU per buffer
|
||||||
src.set_latency(gst::ClockTime::NONE, gst::ClockTime::NONE);
|
src.set_latency(gst::ClockTime::NONE, gst::ClockTime::NONE);
|
||||||
|
|
||||||
@ -71,6 +61,9 @@ impl MonitorWindow {
|
|||||||
/// Push one encoded access‑unit into the local pipeline.
|
/// Push one encoded access‑unit into the local pipeline.
|
||||||
pub fn push_packet(&self, pkt: VideoPacket) {
|
pub fn push_packet(&self, pkt: VideoPacket) {
|
||||||
let buf = gst::Buffer::from_slice(pkt.data); // no PTS manipulation
|
let buf = gst::Buffer::from_slice(pkt.data); // no PTS manipulation
|
||||||
|
if let Some(mut b) = buf.get_mut() {
|
||||||
|
b.set_pts(Some(gst::ClockTime::from_useconds(pkt.pts)));
|
||||||
|
}
|
||||||
let _ = self.src.push_buffer(buf);
|
let _ = self.src.push_buffer(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ edition = "2024"
|
|||||||
tokio = { version = "1.45", features = ["full", "fs"] }
|
tokio = { version = "1.45", features = ["full", "fs"] }
|
||||||
tokio-stream = "0.1"
|
tokio-stream = "0.1"
|
||||||
tonic = { version = "0.13", features = ["transport"] }
|
tonic = { version = "0.13", features = ["transport"] }
|
||||||
|
tonic-reflection = "0.13"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
lesavka_common = { path = "../common" }
|
lesavka_common = { path = "../common" }
|
||||||
tracing = { version = "0.1", features = ["std"] }
|
tracing = { version = "0.1", features = ["std"] }
|
||||||
|
|||||||
@ -14,6 +14,7 @@ use tokio::{
|
|||||||
use tokio_stream::wrappers::ReceiverStream;
|
use tokio_stream::wrappers::ReceiverStream;
|
||||||
use tonic::{Request, Response, Status};
|
use tonic::{Request, Response, Status};
|
||||||
use tonic::transport::Server;
|
use tonic::transport::Server;
|
||||||
|
use tonic_reflection::server::{Builder as ReflBuilder};
|
||||||
use tracing::{info, warn, error, trace};
|
use tracing::{info, warn, error, trace};
|
||||||
use tracing_subscriber::{filter::EnvFilter, fmt, prelude::*};
|
use tracing_subscriber::{filter::EnvFilter, fmt, prelude::*};
|
||||||
use tracing_appender::non_blocking::WorkerGuard;
|
use tracing_appender::non_blocking::WorkerGuard;
|
||||||
@ -198,6 +199,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.tcp_nodelay(true)
|
.tcp_nodelay(true)
|
||||||
.max_frame_size(Some(256*1024))
|
.max_frame_size(Some(256*1024))
|
||||||
.add_service(RelayServer::new(handler))
|
.add_service(RelayServer::new(handler))
|
||||||
|
.add_service(ReflBuilder::configure().build_v1().unwrap())
|
||||||
.serve(([0,0,0,0], 50051).into())
|
.serve(([0,0,0,0], 50051).into())
|
||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user