Compare commits
2 commits
4b56e1bc5d
...
dce14132ce
Author | SHA1 | Date | |
---|---|---|---|
|
dce14132ce | ||
|
4edda4e05a |
7 changed files with 287 additions and 74 deletions
144
Cargo.lock
generated
144
Cargo.lock
generated
|
@ -294,6 +294,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.5.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.19"
|
version = "0.8.19"
|
||||||
|
@ -1189,9 +1198,13 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"serde",
|
"serde",
|
||||||
"simplelog",
|
"simplelog",
|
||||||
|
"snafu",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
"toml",
|
"toml",
|
||||||
|
"tracing",
|
||||||
|
"tracing-appender",
|
||||||
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1326,6 +1339,16 @@ dependencies = [
|
||||||
"minimal-lexical",
|
"minimal-lexical",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-ansi-term"
|
||||||
|
version = "0.46.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||||
|
dependencies = [
|
||||||
|
"overload",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-conv"
|
name = "num-conv"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1414,6 +1437,12 @@ dependencies = [
|
||||||
"hashbrown 0.13.2",
|
"hashbrown 0.13.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "overload"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pango"
|
name = "pango"
|
||||||
version = "0.19.2"
|
version = "0.19.2"
|
||||||
|
@ -1741,6 +1770,15 @@ dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simplelog"
|
name = "simplelog"
|
||||||
version = "0.12.2"
|
version = "0.12.2"
|
||||||
|
@ -1767,6 +1805,27 @@ version = "1.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "snafu"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75976f4748ab44f6e5332102be424e7c2dc18daeaf7e725f2040c3ebb133512e"
|
||||||
|
dependencies = [
|
||||||
|
"snafu-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "snafu-derive"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4b19911debfb8c2fb1107bc6cb2d61868aaf53a988449213959bb1b5b1ed95f"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.53",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.5.6"
|
version = "0.5.6"
|
||||||
|
@ -1859,6 +1918,16 @@ dependencies = [
|
||||||
"syn 2.0.53",
|
"syn 2.0.53",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.34"
|
version = "0.3.34"
|
||||||
|
@ -2000,6 +2069,75 @@ dependencies = [
|
||||||
"winnow 0.6.5",
|
"winnow 0.6.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-appender"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
|
"thiserror",
|
||||||
|
"time",
|
||||||
|
"tracing-subscriber",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.53",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-core"
|
||||||
|
version = "0.1.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"valuable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-log"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.3.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||||
|
dependencies = [
|
||||||
|
"nu-ansi-term",
|
||||||
|
"sharded-slab",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tungstenite"
|
name = "tungstenite"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
|
@ -2087,6 +2225,12 @@ version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
|
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "valuable"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec_map"
|
name = "vec_map"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
|
|
@ -27,3 +27,7 @@ tokio = { version = "1.37.0", features = ["rt-multi-thread", "time"] }
|
||||||
tokio-tungstenite = "0.21.0"
|
tokio-tungstenite = "0.21.0"
|
||||||
toml = "0.8.12"
|
toml = "0.8.12"
|
||||||
interprocess = { version = "2.0.0", features = ["tokio"] }
|
interprocess = { version = "2.0.0", features = ["tokio"] }
|
||||||
|
tracing = "0.1.40"
|
||||||
|
tracing-subscriber = { version = "0.3.18", features = ["tracing-log"] }
|
||||||
|
tracing-appender = "0.2.3"
|
||||||
|
snafu = "0.8.2"
|
||||||
|
|
|
@ -104,7 +104,7 @@ impl<'a> CoordState<'a> {
|
||||||
to_gui,
|
to_gui,
|
||||||
rt,
|
rt,
|
||||||
|
|
||||||
pipeline: gstreamer_pipeline::WebcamPipeline::new(),
|
pipeline: gstreamer_pipeline::WebcamPipeline::new().unwrap(),
|
||||||
tracker_keep_alive: Arc::new(AtomicBool::new(false)),
|
tracker_keep_alive: Arc::new(AtomicBool::new(false)),
|
||||||
tracker_is_alive: Arc::new(AtomicBool::new(false)),
|
tracker_is_alive: Arc::new(AtomicBool::new(false)),
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,10 @@ pub async fn remote_video_loop(
|
||||||
tracker_state: Arc<Mutex<TrackerState>>,
|
tracker_state: Arc<Mutex<TrackerState>>,
|
||||||
runtime: Handle,
|
runtime: Handle,
|
||||||
) {
|
) {
|
||||||
info!("Starting remote tracker processing connection to: {}", conn_string);
|
info!(
|
||||||
|
"Starting remote tracker processing connection to: {}",
|
||||||
|
conn_string
|
||||||
|
);
|
||||||
let video_info =
|
let video_info =
|
||||||
gstreamer_video::VideoInfo::builder(gstreamer_video::VideoFormat::Rgb, 640, 480)
|
gstreamer_video::VideoInfo::builder(gstreamer_video::VideoFormat::Rgb, 640, 480)
|
||||||
.build()
|
.build()
|
||||||
|
@ -95,7 +98,6 @@ pub async fn remote_video_loop(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if !keep_alive.load(Ordering::SeqCst) {
|
if !keep_alive.load(Ordering::SeqCst) {
|
||||||
info!("Shutting down remote video loop");
|
info!("Shutting down remote video loop");
|
||||||
break;
|
break;
|
||||||
|
@ -152,7 +154,10 @@ async fn listen_to_messages(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info!("Stopping tracker connection listen with keep alive: {}", keep_alive.load(Ordering::SeqCst));
|
info!(
|
||||||
|
"Stopping tracker connection listen with keep alive: {}",
|
||||||
|
keep_alive.load(Ordering::SeqCst)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_video_frame(
|
fn get_video_frame(
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use gstreamer::prelude::*;
|
use gstreamer::{prelude::*, PadLinkError};
|
||||||
use gstreamer::{Element, ElementFactory, Pipeline};
|
use gstreamer::{Element, ElementFactory, Pipeline};
|
||||||
use gstreamer_app::AppSink;
|
use gstreamer_app::AppSink;
|
||||||
|
use gtk::glib::BoolError;
|
||||||
|
use snafu::prelude::*;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
@ -19,56 +21,56 @@ pub struct WebcamPipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebcamPipeline {
|
impl WebcamPipeline {
|
||||||
pub fn new() -> WebcamPipeline {
|
pub fn new() -> Result<WebcamPipeline, PipelineError> {
|
||||||
let pipeline = Pipeline::with_name("webcam_pipeline");
|
let pipeline = Pipeline::with_name("webcam_pipeline");
|
||||||
|
|
||||||
// All of the following errors are unrecoverable
|
// All of the following errors are unrecoverable
|
||||||
|
|
||||||
let source = ElementFactory::make("mfvideosrc")
|
let source = ElementFactory::make("mfvideosrc")
|
||||||
.build()
|
.build()
|
||||||
.expect("Could not build video source for GStreamer");
|
.context(BuildSnafu {
|
||||||
|
element: "mfvideosrc",
|
||||||
|
})?;
|
||||||
let convert = ElementFactory::make("videoconvert")
|
let convert = ElementFactory::make("videoconvert")
|
||||||
.build()
|
.build()
|
||||||
.expect("Could not build video convert for GStreamer");
|
.context(BuildSnafu {
|
||||||
|
element: "videoconvert",
|
||||||
|
})?;
|
||||||
let rate = ElementFactory::make("videorate")
|
let rate = ElementFactory::make("videorate")
|
||||||
.build()
|
.build()
|
||||||
.expect("Could not build the video rate element");
|
.context(BuildSnafu {
|
||||||
|
element: "videorate",
|
||||||
|
})?;
|
||||||
|
|
||||||
let tee = ElementFactory::make("tee")
|
let tee = ElementFactory::make("tee")
|
||||||
.build()
|
.build()
|
||||||
.expect("Could not create tee element");
|
.context(BuildSnafu { element: "tee" })?;
|
||||||
|
|
||||||
let queue_app = ElementFactory::make("queue")
|
let queue_app = ElementFactory::make("queue").build().context(BuildSnafu {
|
||||||
.build()
|
element: "paintable queue",
|
||||||
.expect("Could not create the queue buffer");
|
})?;
|
||||||
let sink_paintable = ElementFactory::make("gtk4paintablesink")
|
let sink_paintable = ElementFactory::make("gtk4paintablesink")
|
||||||
.name("gtk4_output")
|
.name("gtk4_output")
|
||||||
.build()
|
.build()
|
||||||
.expect("Could not build gtk sink for GStreamer");
|
.context(BuildSnafu {
|
||||||
|
element: "gtkpaintablesink",
|
||||||
|
})?;
|
||||||
|
|
||||||
let queue = ElementFactory::make("queue")
|
let queue = ElementFactory::make("queue").build().context(BuildSnafu {
|
||||||
.build()
|
element: "appsink queue",
|
||||||
.expect("Could not create the queue buffer");
|
})?;
|
||||||
|
|
||||||
let resize = ElementFactory::make("videoscale")
|
let resize = ElementFactory::make("videoscale")
|
||||||
.build()
|
.build()
|
||||||
.expect("Could not build videoscale for GStreamer");
|
.context(BuildSnafu {
|
||||||
|
element: "videoscale",
|
||||||
|
})?;
|
||||||
|
|
||||||
let caps_string = "video/x-raw,format=RGB,width=640,height=480,max-buffers=1,drop=true";
|
let caps_string = "video/x-raw,format=RGB,width=640,height=480,max-buffers=1,drop=true";
|
||||||
// let caps_string = String::from("video/x-raw,format=RGB,max-buffers=1,drop=true");
|
// let caps_string = String::from("video/x-raw,format=RGB,max-buffers=1,drop=true");
|
||||||
let appsrc_caps =
|
let appsrc_caps = gstreamer::Caps::from_str(caps_string).context(BuildSnafu {
|
||||||
gstreamer::Caps::from_str(caps_string).expect("Couldn't create appsrc caps");
|
element: "appsink caps",
|
||||||
|
})?;
|
||||||
/*
|
|
||||||
// let sink_frame = ElementFactory::make("appsink")
|
|
||||||
// .name("frame_output")
|
|
||||||
// .property("sync", &false)
|
|
||||||
// .build()
|
|
||||||
// .expect("Could not build appsrc for GStreamer");
|
|
||||||
let video_info = gstreamer_video::VideoInfo::builder(gstreamer_video::VideoFormat::Rgb, 650, 480)
|
|
||||||
.build()
|
|
||||||
.expect("Couldn't build video info!");
|
|
||||||
*/
|
|
||||||
|
|
||||||
let sink_frame = AppSink::builder()
|
let sink_frame = AppSink::builder()
|
||||||
.name("frame_output")
|
.name("frame_output")
|
||||||
|
@ -92,49 +94,81 @@ impl WebcamPipeline {
|
||||||
&queue,
|
&queue,
|
||||||
&sink_frame.upcast_ref(),
|
&sink_frame.upcast_ref(),
|
||||||
])
|
])
|
||||||
.expect("Could not link the elements to the pipeline");
|
.context(LinkSnafu {
|
||||||
|
from: "all",
|
||||||
|
to: "pipeline",
|
||||||
|
})?;
|
||||||
|
|
||||||
source
|
source.link(&convert).context(LinkSnafu {
|
||||||
.link(&convert)
|
from: "mfvideosrc",
|
||||||
.expect("Could not link video source to converter");
|
to: "videoconvert",
|
||||||
|
})?;
|
||||||
|
|
||||||
convert.link(&rate)
|
convert.link(&rate).context(LinkSnafu {
|
||||||
.expect("Could not link rate to tee");
|
from: "videoconvert",
|
||||||
|
to: "videorate",
|
||||||
|
})?;
|
||||||
|
|
||||||
rate.link_filtered(
|
let tee_caps =
|
||||||
&tee,
|
gstreamer::caps::Caps::from_str("video/x-raw,framerate=15/1").context(BuildSnafu {
|
||||||
&gstreamer::caps::Caps::from_str("video/x-raw,framerate=15/1").expect("Could not build framerate caps"),
|
element: "tee caps",
|
||||||
).expect("Could not link converter to rate");
|
})?;
|
||||||
|
|
||||||
|
rate.link_filtered(&tee, &tee_caps).context(LinkSnafu {
|
||||||
|
from: "videorate",
|
||||||
|
to: "tee",
|
||||||
|
})?;
|
||||||
|
|
||||||
let tee_src_1 = tee
|
let tee_src_1 = tee
|
||||||
.request_pad_simple("src_%u")
|
.request_pad_simple("src_%u")
|
||||||
.expect("Could not create src pad 1");
|
.ok_or(PipelineError::PadRequestError {
|
||||||
let sink_paintable_sinkpad = queue_app
|
element: "tee pad 1".to_string(),
|
||||||
.static_pad("sink")
|
})?;
|
||||||
.expect("Could not get sink pad for paintablesink queue");
|
let paintable_queue_sinkpad =
|
||||||
tee_src_1
|
|
||||||
.link(&sink_paintable_sinkpad)
|
|
||||||
.expect("Could not link tee srcpad 1 to paintablesink pad");
|
|
||||||
queue_app
|
queue_app
|
||||||
.link(&sink_paintable)
|
.static_pad("sink")
|
||||||
.expect("Could not link app queue to paintable sink");
|
.ok_or(PipelineError::PadRequestError {
|
||||||
|
element: "gtk4 sink".to_string(),
|
||||||
|
})?;
|
||||||
|
tee_src_1
|
||||||
|
.link(&paintable_queue_sinkpad)
|
||||||
|
.context(PadLinkSnafu {
|
||||||
|
from: "tee src pad",
|
||||||
|
to: "gtk4 paintable queue",
|
||||||
|
})?;
|
||||||
|
queue_app.link(&sink_paintable).context(LinkSnafu {
|
||||||
|
from: "gtk4 paintable queue",
|
||||||
|
to: "gtk4 paintable",
|
||||||
|
})?;
|
||||||
|
|
||||||
let tee_src_2 = tee
|
let tee_src_2 = tee
|
||||||
.request_pad_simple("src_%u")
|
.request_pad_simple("src_%u")
|
||||||
.expect("Could not create src pad 2");
|
.ok_or(PipelineError::PadRequestError {
|
||||||
let sink_frameoutput_sinkpad = queue
|
element: "tee pad 2".to_string(),
|
||||||
|
})?;
|
||||||
|
let appsink_queue_sinkpad =
|
||||||
|
queue
|
||||||
.static_pad("sink")
|
.static_pad("sink")
|
||||||
.expect("Could not get sink pad for frameoutput sink");
|
.ok_or(PipelineError::PadRequestError {
|
||||||
|
element: "appsink queue".to_string(),
|
||||||
|
})?;
|
||||||
tee_src_2
|
tee_src_2
|
||||||
.link(&sink_frameoutput_sinkpad)
|
.link(&appsink_queue_sinkpad)
|
||||||
.expect("Could not link tee srcpad 2 to frame output sink pad");
|
.context(PadLinkSnafu {
|
||||||
|
from: "tee src pad 2",
|
||||||
|
to: "appsink queue sinkpad",
|
||||||
|
})?;
|
||||||
|
|
||||||
queue.link(&resize).expect("Could not link queue to resize");
|
queue.link(&resize).context(LinkSnafu {
|
||||||
resize
|
from: "appsink queue",
|
||||||
.link(&sink_frame)
|
to: "videoscale",
|
||||||
.expect("Could not bind resize to appsrc");
|
})?;
|
||||||
|
resize.link(&sink_frame).context(LinkSnafu {
|
||||||
|
from: "videoscale",
|
||||||
|
to: "appsink",
|
||||||
|
})?;
|
||||||
|
|
||||||
WebcamPipeline {
|
Ok(WebcamPipeline {
|
||||||
pipeline,
|
pipeline,
|
||||||
src: source,
|
src: source,
|
||||||
converter: convert,
|
converter: convert,
|
||||||
|
@ -144,6 +178,26 @@ impl WebcamPipeline {
|
||||||
resize,
|
resize,
|
||||||
queue,
|
queue,
|
||||||
sink_frame: Arc::new(Mutex::new(sink_frame)),
|
sink_frame: Arc::new(Mutex::new(sink_frame)),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Snafu)]
|
||||||
|
pub enum PipelineError {
|
||||||
|
#[snafu(display("Error during element linking"))]
|
||||||
|
LinkError {
|
||||||
|
source: BoolError,
|
||||||
|
from: String,
|
||||||
|
to: String,
|
||||||
|
},
|
||||||
|
#[snafu(display("Error linking pads"))]
|
||||||
|
PadLinkError {
|
||||||
|
source: PadLinkError,
|
||||||
|
from: String,
|
||||||
|
to: String,
|
||||||
|
},
|
||||||
|
#[snafu(display("Error creating element"))]
|
||||||
|
BuildError { source: BoolError, element: String },
|
||||||
|
#[snafu(display("Error getting pad from element"))]
|
||||||
|
PadRequestError { element: String },
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@ use crate::coordinator::{ApplicationEvent, MoveEvent};
|
||||||
|
|
||||||
use async_channel::Sender;
|
use async_channel::Sender;
|
||||||
use gilrs::{ev::filter::FilterFn, Axis, Button, Event, EventType, Filter, Gilrs, GilrsBuilder};
|
use gilrs::{ev::filter::FilterFn, Axis, Button, Event, EventType, Filter, Gilrs, GilrsBuilder};
|
||||||
use log::{info, warn};
|
|
||||||
use std::{
|
use std::{
|
||||||
panic::{self, AssertUnwindSafe},
|
panic::{self, AssertUnwindSafe},
|
||||||
sync::{atomic::AtomicBool, Arc},
|
sync::{atomic::AtomicBool, Arc},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
use tracing::{info, warn};
|
||||||
|
|
||||||
static MAX_SENT_ZEROS: u32 = 10;
|
static MAX_SENT_ZEROS: u32 = 10;
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ impl FilterFn for UnknownSlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument]
|
||||||
pub async fn joystick_loop(tx: Sender<ApplicationEvent>, is_alive: Arc<AtomicBool>) {
|
pub async fn joystick_loop(tx: Sender<ApplicationEvent>, is_alive: Arc<AtomicBool>) {
|
||||||
let mut gilrs = GilrsBuilder::new().set_update_state(false).build().unwrap();
|
let mut gilrs = GilrsBuilder::new().set_update_state(false).build().unwrap();
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ pub async fn joystick_loop(tx: Sender<ApplicationEvent>, is_alive: Arc<AtomicBoo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Err(async_channel::TrySendError::Full(_)) => {
|
Err(async_channel::TrySendError::Full(_)) => {
|
||||||
warn!("[joystick loop] The MEC is full!")
|
warn!("The MEC is full!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -1,9 +1,10 @@
|
||||||
use gtk::prelude::{ApplicationExt, ApplicationExtManual};
|
use gtk::prelude::{ApplicationExt, ApplicationExtManual};
|
||||||
use gtk::{glib, Application};
|
use gtk::{glib, Application};
|
||||||
use log::{error, info};
|
|
||||||
use simplelog::SimpleLogger;
|
|
||||||
use std::{env, sync::Arc};
|
use std::{env, sync::Arc};
|
||||||
use tokio::{runtime, sync::RwLock};
|
use tokio::{runtime, sync::RwLock};
|
||||||
|
use tracing::{self, info, Level};
|
||||||
|
use tracing_appender;
|
||||||
|
use tracing_subscriber;
|
||||||
|
|
||||||
use crate::config::load_config;
|
use crate::config::load_config;
|
||||||
|
|
||||||
|
@ -19,10 +20,14 @@ fn main() -> glib::ExitCode {
|
||||||
// set the environment var to make gtk use window's default action bar
|
// set the environment var to make gtk use window's default action bar
|
||||||
env::set_var("gtk_csd", "0");
|
env::set_var("gtk_csd", "0");
|
||||||
|
|
||||||
if let Err(e) = SimpleLogger::init(simplelog::LevelFilter::Debug, simplelog::Config::default())
|
let file_appender = tracing_appender::rolling::daily(".", "joystick-log.log");
|
||||||
{
|
let (non_blocking, _gaurd) = tracing_appender::non_blocking(file_appender);
|
||||||
error!("Failed to init the simplelogger!: {e}");
|
tracing_subscriber::fmt().with_writer(non_blocking).init();
|
||||||
}
|
|
||||||
|
let span = tracing::span!(Level::TRACE, "main");
|
||||||
|
let _enter = span.enter();
|
||||||
|
|
||||||
|
info!("tracing intialized");
|
||||||
|
|
||||||
let config = Arc::new(RwLock::new(load_config()));
|
let config = Arc::new(RwLock::new(load_config()));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue