Compare commits

..

2 commits

Author SHA1 Message Date
Nickiel12
36e5afeb57 added videorate limit 2024-05-18 15:55:50 -07:00
Nickiel12
ee0b8d571c cargo fmt 2024-05-18 15:55:42 -07:00
7 changed files with 78 additions and 66 deletions

View file

@ -131,7 +131,11 @@ impl<'a> CoordState<'a> {
let conn_string: String = { let conn_string: String = {
let read_settings = self.settings.read().await; let read_settings = self.settings.read().await;
format!("ws://{}:{}", read_settings.camera_ip, read_settings.camera_port.to_string()) format!(
"ws://{}:{}",
read_settings.camera_ip,
read_settings.camera_port.to_string()
)
}; };
match connect_async(conn_string).await { match connect_async(conn_string).await {
@ -165,20 +169,21 @@ impl<'a> CoordState<'a> {
let conn_string: String = { let conn_string: String = {
let read_settings = self.settings.read().await; let read_settings = self.settings.read().await;
format!("ws://{}:{}", read_settings.tracker_ip, read_settings.tracker_port.to_string()) format!(
"ws://{}:{}",
read_settings.tracker_ip,
read_settings.tracker_port.to_string()
)
}; };
self.rt.spawn( self.rt.spawn(remote_video_loop(
remote_video_loop( conn_string,
conn_string, self.pipeline.sink_frame.clone(),
self.pipeline.sink_frame.clone(), self.to_mec.clone(),
self.to_mec.clone(), self.keep_windows_pipe_alive.clone(),
self.keep_windows_pipe_alive.clone(), self.tracker_state.clone(),
self.tracker_state.clone(), self.rt.clone(),
self.rt.clone() ));
),
);
} }
pub async fn check_states(&mut self) { pub async fn check_states(&mut self) {
@ -190,9 +195,7 @@ impl<'a> CoordState<'a> {
)); ));
} }
if !self.keep_windows_pipe_alive.load(Ordering::SeqCst) { if !self.keep_windows_pipe_alive.load(Ordering::SeqCst) {}
}
if !self.sck_alive_server.load(Ordering::SeqCst) { if !self.sck_alive_server.load(Ordering::SeqCst) {
info!("Restarting socket server"); info!("Restarting socket server");

View file

@ -94,7 +94,6 @@ pub async fn remote_video_loop(
// rate limit updates // rate limit updates
sleep_until(Instant::now() + Duration::from_millis(50)).await; sleep_until(Instant::now() + Duration::from_millis(50)).await;
} }
} }
} }

View file

@ -30,6 +30,9 @@ impl WebcamPipeline {
let convert = ElementFactory::make("videoconvert") let convert = ElementFactory::make("videoconvert")
.build() .build()
.expect("Could not build video convert for GStreamer"); .expect("Could not build video convert for GStreamer");
let rate = ElementFactory::make("videorate")
.build()
.expect("Could not build the video rate element");
let tee = ElementFactory::make("tee") let tee = ElementFactory::make("tee")
.build() .build()
@ -51,11 +54,10 @@ impl WebcamPipeline {
.build() .build()
.expect("Could not build videoscale for GStreamer"); .expect("Could not build videoscale for GStreamer");
let caps_string = let caps_string = "video/x-raw,format=RGB,width=640,height=480,max-buffers=1,drop=true";
String::from("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).expect("Couldn't create appsrc caps"); gstreamer::Caps::from_str(caps_string).expect("Couldn't create appsrc caps");
/* /*
// let sink_frame = ElementFactory::make("appsink") // let sink_frame = ElementFactory::make("appsink")
@ -82,6 +84,7 @@ impl WebcamPipeline {
.add_many(&[ .add_many(&[
&source, &source,
&convert, &convert,
&rate,
&tee, &tee,
&queue_app, &queue_app,
&sink_paintable, &sink_paintable,
@ -94,7 +97,14 @@ impl WebcamPipeline {
source source
.link(&convert) .link(&convert)
.expect("Could not link video source to converter"); .expect("Could not link video source to converter");
convert.link(&tee).expect("Could not link converter to tee");
convert.link(&rate)
.expect("Could not link rate to tee");
rate.link_filtered(
&tee,
&gstreamer::caps::Caps::from_str("video/x-raw,framerate=15/1").expect("Could not build framerate caps"),
).expect("Could not link converter to rate");
let tee_src_1 = tee let tee_src_1 = tee
.request_pad_simple("src_%u") .request_pad_simple("src_%u")

View file

@ -1,17 +1,17 @@
use gtk::prelude::{ApplicationExt, ApplicationExtManual};
use gtk::{glib, Application}; use gtk::{glib, Application};
use log::{error, info}; use log::{error, info};
use gtk::prelude::{ApplicationExt, ApplicationExtManual};
use simplelog::SimpleLogger; use simplelog::SimpleLogger;
use std::{env, sync::Arc}; use std::{env, sync::Arc};
use tokio::{runtime, sync::RwLock}; use tokio::{runtime, sync::RwLock};
use crate::config::load_config; use crate::config::load_config;
mod config;
mod coordinator; mod coordinator;
mod gstreamer_pipeline; mod gstreamer_pipeline;
mod joystick_source; mod joystick_source;
mod remote_sources; mod remote_sources;
mod config;
mod ui; mod ui;
const APP_ID: &str = "net.nickiel.joystick-controller-client"; const APP_ID: &str = "net.nickiel.joystick-controller-client";
@ -50,4 +50,3 @@ fn main() -> glib::ExitCode {
exit_code exit_code
} }

View file

@ -14,14 +14,13 @@ use crate::config::AppConfig;
use crate::coordinator::{start_coordinator, ApplicationEvent, MoveEvent}; use crate::coordinator::{start_coordinator, ApplicationEvent, MoveEvent};
use crate::remote_sources::TrackerState; use crate::remote_sources::TrackerState;
mod settings_modal;
mod socket_panel; mod socket_panel;
mod tracker_panel; mod tracker_panel;
mod settings_modal;
use socket_panel::SocketPanel; use socket_panel::SocketPanel;
use tracker_panel::TrackerPanel; use tracker_panel::TrackerPanel;
pub enum GuiUpdate { pub enum GuiUpdate {
SocketState(bool), SocketState(bool),
MoveEvent(MoveEvent), MoveEvent(MoveEvent),
@ -84,7 +83,6 @@ pub fn on_activate(app: &Application) {
app.set_menubar(Some(&menubar)); app.set_menubar(Some(&menubar));
info!("Menu bar set up"); info!("Menu bar set up");
} }
pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Handle) { pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Handle) {
@ -101,7 +99,6 @@ pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Hand
.child(&main_box) .child(&main_box)
.build(); .build();
let rt = runtime.clone(); let rt = runtime.clone();
let config_modal_config = config.clone(); let config_modal_config = config.clone();
let connections_activate = gio::ActionEntry::builder("connections") let connections_activate = gio::ActionEntry::builder("connections")
@ -114,7 +111,6 @@ pub fn build_ui(app: &Application, config: Arc<RwLock<AppConfig>>, runtime: Hand
app.add_action_entries([connections_activate]); app.add_action_entries([connections_activate]);
// Main Event Channel // Main Event Channel
let (to_mec, mec) = async_channel::unbounded::<ApplicationEvent>(); let (to_mec, mec) = async_channel::unbounded::<ApplicationEvent>();
let (to_gui, gui_recv) = async_channel::bounded::<GuiUpdate>(10); let (to_gui, gui_recv) = async_channel::bounded::<GuiUpdate>(10);

View file

@ -1,14 +1,16 @@
use std::sync::Arc; use std::sync::Arc;
use gtk::glib::{self, clone}; use gtk::glib::{self, clone};
use gtk::{prelude::{BoxExt, ButtonExt, EditableExt}, Application, ApplicationWindow, Box, Button, Entry, Label, Window}; use gtk::{
prelude::{BoxExt, ButtonExt, EditableExt},
Application, ApplicationWindow, Box, Button, Entry, Label, Window,
};
use log::{error, info};
use tokio::runtime::Handle; use tokio::runtime::Handle;
use tokio::sync::RwLock; use tokio::sync::RwLock;
use log::{error, info};
use crate::config::{save_config, AppConfig}; use crate::config::{save_config, AppConfig};
pub struct ConnectionsModal { pub struct ConnectionsModal {
pub window: Window, pub window: Window,
@ -16,10 +18,14 @@ pub struct ConnectionsModal {
} }
impl ConnectionsModal { impl ConnectionsModal {
pub fn new(app: &Application, parent: &ApplicationWindow, rt: &Handle, app_config: &Arc<RwLock<AppConfig>>) -> Self { pub fn new(
app: &Application,
parent: &ApplicationWindow,
rt: &Handle,
app_config: &Arc<RwLock<AppConfig>>,
) -> Self {
// Send help :( // Send help :(
let config_read = rt.block_on(async {app_config.read().await}); let config_read = rt.block_on(async { app_config.read().await });
let main_box = gtk::Box::new(gtk::Orientation::Vertical, 0); let main_box = gtk::Box::new(gtk::Orientation::Vertical, 0);
@ -114,39 +120,38 @@ impl ConnectionsModal {
main_box.append(&quit_button); main_box.append(&quit_button);
let new_ref = app_config.clone(); let new_ref = app_config.clone();
quit_button quit_button.connect_activate(clone!(
.connect_activate(clone!( @strong rt,
@strong rt, @weak camera_ip_entry, @weak camera_port_entry,
@weak camera_ip_entry, @weak camera_port_entry, @weak tracker_ip_entry, @weak tracker_port_entry,
@weak tracker_ip_entry, @weak tracker_port_entry, @weak tracker_refresh_millis => move |_| {
@weak tracker_refresh_millis => move |_| {
let new_camera_ip = camera_ip_entry.text().to_string(); let new_camera_ip = camera_ip_entry.text().to_string();
let new_camera_port = camera_port_entry.text().parse::<u32>().unwrap(); let new_camera_port = camera_port_entry.text().parse::<u32>().unwrap();
let new_tracker_ip = tracker_ip_entry.text().to_string(); let new_tracker_ip = tracker_ip_entry.text().to_string();
let new_tracker_port = tracker_port_entry.text().parse::<u32>().unwrap(); let new_tracker_port = tracker_port_entry.text().parse::<u32>().unwrap();
let new_tracker_millis = tracker_refresh_millis.text().parse::<u32>().unwrap(); let new_tracker_millis = tracker_refresh_millis.text().parse::<u32>().unwrap();
{ {
// maybe just send the police. // maybe just send the police.
let mut write_lock = rt.block_on(async {new_ref.write().await}); let mut write_lock = rt.block_on(async {new_ref.write().await});
write_lock.camera_ip = new_camera_ip; write_lock.camera_ip = new_camera_ip;
write_lock.camera_port = new_camera_port; write_lock.camera_port = new_camera_port;
write_lock.tracker_ip = new_tracker_ip; write_lock.tracker_ip = new_tracker_ip;
write_lock.tracker_port = new_tracker_port; write_lock.tracker_port = new_tracker_port;
write_lock.tracker_refresh_rate_millis = new_tracker_millis; write_lock.tracker_refresh_rate_millis = new_tracker_millis;
// why does this feel like the borrow checker gave me a pass? // why does this feel like the borrow checker gave me a pass?
if let Err(e) = save_config(&write_lock.to_owned()) { if let Err(e) = save_config(&write_lock.to_owned()) {
error!("Could not save config! {e}"); error!("Could not save config! {e}");
}
// FBI!!! OPEN UP!!!!
} }
// FBI!!! OPEN UP!!!!
}
info!("Please nicholas, add a non-crashing parse"); info!("Please nicholas, add a non-crashing parse");
})); }));
ConnectionsModal { ConnectionsModal {
window, window,

View file

@ -1,6 +1,8 @@
use async_channel::Sender; use async_channel::Sender;
use gtk::{ use gtk::{
glib, prelude::{BoxExt, ButtonExt}, Box, Button glib,
prelude::{BoxExt, ButtonExt},
Box, Button,
}; };
use log::error; use log::error;
@ -37,13 +39,11 @@ impl SocketPanel {
&self.top_level &self.top_level
} }
pub fn button_label(&self, new_label: &str) { pub fn button_label(&self, new_label: &str) {
self.connect_button.set_label(new_label); self.connect_button.set_label(new_label);
} }
pub fn connect_button_callback(&self, to_mec: Sender<ApplicationEvent>) { pub fn connect_button_callback(&self, to_mec: Sender<ApplicationEvent>) {
self.connect_button.connect_clicked(glib::clone!(@strong to_mec => move |_button| { self.connect_button.connect_clicked(glib::clone!(@strong to_mec => move |_button| {
match to_mec.try_send(ApplicationEvent::StartCameraSocket) { match to_mec.try_send(ApplicationEvent::StartCameraSocket) {
Ok(_) => {}, Ok(_) => {},