mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-02-28 02:26:21 +00:00
Implement cancellation of connection attempts
This commit is contained in:
parent
f27c2507c5
commit
19d25d20a7
3 changed files with 101 additions and 11 deletions
13
src/lib.rs
13
src/lib.rs
|
@ -21,7 +21,7 @@ use ndi::*;
|
||||||
use ndisys::*;
|
use ndisys::*;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering};
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
|
@ -83,6 +83,7 @@ fn connect_ndi(
|
||||||
receiver_ndi_name: &str,
|
receiver_ndi_name: &str,
|
||||||
connect_timeout: u32,
|
connect_timeout: u32,
|
||||||
bandwidth: NDIlib_recv_bandwidth_e,
|
bandwidth: NDIlib_recv_bandwidth_e,
|
||||||
|
cancel: &AtomicBool,
|
||||||
) -> Option<usize> {
|
) -> Option<usize> {
|
||||||
gst_debug!(cat, obj: element, "Starting NDI connection...");
|
gst_debug!(cat, obj: element, "Starting NDI connection...");
|
||||||
|
|
||||||
|
@ -119,8 +120,18 @@ fn connect_ndi(
|
||||||
|
|
||||||
let timeout = time::Instant::now();
|
let timeout = time::Instant::now();
|
||||||
let source = loop {
|
let source = loop {
|
||||||
|
if cancel.load(Ordering::SeqCst) {
|
||||||
|
gst_debug!(cat, obj: element, "Cancelled");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
find.wait_for_sources(50);
|
find.wait_for_sources(50);
|
||||||
|
|
||||||
|
if cancel.load(Ordering::SeqCst) {
|
||||||
|
gst_debug!(cat, obj: element, "Cancelled");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let sources = find.get_current_sources();
|
let sources = find.get_current_sources();
|
||||||
|
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
|
|
|
@ -10,6 +10,7 @@ use gst_base::prelude::*;
|
||||||
use gst_base::subclass::prelude::*;
|
use gst_base::subclass::prelude::*;
|
||||||
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::time;
|
use std::time;
|
||||||
use std::{i32, u32};
|
use std::{i32, u32};
|
||||||
|
|
||||||
|
@ -146,6 +147,7 @@ pub(crate) struct NdiAudioSrc {
|
||||||
cat: gst::DebugCategory,
|
cat: gst::DebugCategory,
|
||||||
settings: Mutex<Settings>,
|
settings: Mutex<Settings>,
|
||||||
state: Mutex<State>,
|
state: Mutex<State>,
|
||||||
|
unlock: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectSubclass for NdiAudioSrc {
|
impl ObjectSubclass for NdiAudioSrc {
|
||||||
|
@ -165,6 +167,7 @@ impl ObjectSubclass for NdiAudioSrc {
|
||||||
),
|
),
|
||||||
settings: Mutex::new(Default::default()),
|
settings: Mutex::new(Default::default()),
|
||||||
state: Mutex::new(Default::default()),
|
state: Mutex::new(Default::default()),
|
||||||
|
unlock: AtomicBool::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,13 +356,38 @@ impl ObjectImpl for NdiAudioSrc {
|
||||||
impl ElementImpl for NdiAudioSrc {}
|
impl ElementImpl for NdiAudioSrc {}
|
||||||
|
|
||||||
impl BaseSrcImpl for NdiAudioSrc {
|
impl BaseSrcImpl for NdiAudioSrc {
|
||||||
|
fn unlock(&self, element: &gst_base::BaseSrc) -> std::result::Result<(), gst::ErrorMessage> {
|
||||||
|
gst_debug!(
|
||||||
|
self.cat,
|
||||||
|
obj: element,
|
||||||
|
"Unlocking",
|
||||||
|
);
|
||||||
|
self.unlock.store(true, Ordering::SeqCst);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unlock_stop(&self, element: &gst_base::BaseSrc) -> std::result::Result<(), gst::ErrorMessage> {
|
||||||
|
gst_debug!(
|
||||||
|
self.cat,
|
||||||
|
obj: element,
|
||||||
|
"Stop unlocking",
|
||||||
|
);
|
||||||
|
self.unlock.store(false, Ordering::SeqCst);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn start(&self, element: &gst_base::BaseSrc) -> Result<(), gst::ErrorMessage> {
|
fn start(&self, element: &gst_base::BaseSrc) -> Result<(), gst::ErrorMessage> {
|
||||||
*self.state.lock().unwrap() = Default::default();
|
*self.state.lock().unwrap() = Default::default();
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
let mut state = self.state.lock().unwrap();
|
|
||||||
|
|
||||||
state.id_receiver = connect_ndi(
|
if settings.ip_address.is_none() && settings.ndi_name.is_none() {
|
||||||
|
return Err(gst_error_msg!(
|
||||||
|
gst::LibraryError::Settings,
|
||||||
|
["No IP address or NDI name given"]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let id_receiver = connect_ndi(
|
||||||
self.cat,
|
self.cat,
|
||||||
element,
|
element,
|
||||||
settings.ip_address.as_ref().map(String::as_str),
|
settings.ip_address.as_ref().map(String::as_str),
|
||||||
|
@ -367,14 +395,22 @@ impl BaseSrcImpl for NdiAudioSrc {
|
||||||
&settings.receiver_ndi_name,
|
&settings.receiver_ndi_name,
|
||||||
settings.connect_timeout,
|
settings.connect_timeout,
|
||||||
settings.bandwidth,
|
settings.bandwidth,
|
||||||
|
&self.unlock,
|
||||||
);
|
);
|
||||||
|
|
||||||
match state.id_receiver {
|
// settings.id_receiver exists
|
||||||
|
match id_receiver {
|
||||||
|
None if self.unlock.load(Ordering::SeqCst) => Ok(()),
|
||||||
None => Err(gst_error_msg!(
|
None => Err(gst_error_msg!(
|
||||||
gst::ResourceError::NotFound,
|
gst::ResourceError::NotFound,
|
||||||
["Could not connect to this source"]
|
["Could not connect to this source"]
|
||||||
)),
|
)),
|
||||||
_ => Ok(()),
|
Some(id_receiver) => {
|
||||||
|
let mut state = self.state.lock().unwrap();
|
||||||
|
state.id_receiver = Some(id_receiver);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ use gst_video;
|
||||||
use gst_video::prelude::*;
|
use gst_video::prelude::*;
|
||||||
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::time;
|
use std::time;
|
||||||
use std::{i32, u32};
|
use std::{i32, u32};
|
||||||
|
|
||||||
|
@ -147,6 +148,7 @@ pub(crate) struct NdiVideoSrc {
|
||||||
cat: gst::DebugCategory,
|
cat: gst::DebugCategory,
|
||||||
settings: Mutex<Settings>,
|
settings: Mutex<Settings>,
|
||||||
state: Mutex<State>,
|
state: Mutex<State>,
|
||||||
|
unlock: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectSubclass for NdiVideoSrc {
|
impl ObjectSubclass for NdiVideoSrc {
|
||||||
|
@ -166,6 +168,7 @@ impl ObjectSubclass for NdiVideoSrc {
|
||||||
),
|
),
|
||||||
settings: Mutex::new(Default::default()),
|
settings: Mutex::new(Default::default()),
|
||||||
state: Mutex::new(Default::default()),
|
state: Mutex::new(Default::default()),
|
||||||
|
unlock: AtomicBool::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,12 +388,43 @@ impl ObjectImpl for NdiVideoSrc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ElementImpl for NdiVideoSrc {}
|
impl ElementImpl for NdiVideoSrc {
|
||||||
|
fn change_state(&self, element: &gst::Element, transition: gst::StateChange) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
|
match transition {
|
||||||
|
gst::StateChange::ReadyToPaused => self.unlock.store(true, Ordering::SeqCst),
|
||||||
|
gst::StateChange::PausedToReady => self.unlock.store(false, Ordering::SeqCst),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.parent_change_state(element, transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl BaseSrcImpl for NdiVideoSrc {
|
impl BaseSrcImpl for NdiVideoSrc {
|
||||||
|
fn unlock(&self, element: &gst_base::BaseSrc) -> std::result::Result<(), gst::ErrorMessage> {
|
||||||
|
gst_debug!(
|
||||||
|
self.cat,
|
||||||
|
obj: element,
|
||||||
|
"Unlocking",
|
||||||
|
);
|
||||||
|
self.unlock.store(true, Ordering::SeqCst);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unlock_stop(&self, element: &gst_base::BaseSrc) -> std::result::Result<(), gst::ErrorMessage> {
|
||||||
|
gst_debug!(
|
||||||
|
self.cat,
|
||||||
|
obj: element,
|
||||||
|
"Stop unlocking",
|
||||||
|
);
|
||||||
|
self.unlock.store(false, Ordering::SeqCst);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn start(&self, element: &gst_base::BaseSrc) -> Result<(), gst::ErrorMessage> {
|
fn start(&self, element: &gst_base::BaseSrc) -> Result<(), gst::ErrorMessage> {
|
||||||
|
self.unlock.store(false, Ordering::SeqCst);
|
||||||
|
|
||||||
*self.state.lock().unwrap() = Default::default();
|
*self.state.lock().unwrap() = Default::default();
|
||||||
let mut state = self.state.lock().unwrap();
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
|
|
||||||
if settings.ip_address.is_none() && settings.ndi_name.is_none() {
|
if settings.ip_address.is_none() && settings.ndi_name.is_none() {
|
||||||
|
@ -400,7 +434,7 @@ impl BaseSrcImpl for NdiVideoSrc {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
state.id_receiver = connect_ndi(
|
let id_receiver = connect_ndi(
|
||||||
self.cat,
|
self.cat,
|
||||||
element,
|
element,
|
||||||
settings.ip_address.as_ref().map(String::as_str),
|
settings.ip_address.as_ref().map(String::as_str),
|
||||||
|
@ -408,19 +442,28 @@ impl BaseSrcImpl for NdiVideoSrc {
|
||||||
&settings.receiver_ndi_name,
|
&settings.receiver_ndi_name,
|
||||||
settings.connect_timeout,
|
settings.connect_timeout,
|
||||||
settings.bandwidth,
|
settings.bandwidth,
|
||||||
|
&self.unlock,
|
||||||
);
|
);
|
||||||
|
|
||||||
// settings.id_receiver exists
|
// settings.id_receiver exists
|
||||||
match state.id_receiver {
|
match id_receiver {
|
||||||
|
None if self.unlock.load(Ordering::SeqCst) => Ok(()),
|
||||||
None => Err(gst_error_msg!(
|
None => Err(gst_error_msg!(
|
||||||
gst::ResourceError::NotFound,
|
gst::ResourceError::NotFound,
|
||||||
["Could not connect to this source"]
|
["Could not connect to this source"]
|
||||||
)),
|
)),
|
||||||
_ => Ok(()),
|
Some(id_receiver) => {
|
||||||
|
let mut state = self.state.lock().unwrap();
|
||||||
|
state.id_receiver = Some(id_receiver);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self, element: &gst_base::BaseSrc) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self, element: &gst_base::BaseSrc) -> Result<(), gst::ErrorMessage> {
|
||||||
|
self.unlock.store(true, Ordering::SeqCst);
|
||||||
|
|
||||||
*self.state.lock().unwrap() = Default::default();
|
*self.state.lock().unwrap() = Default::default();
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue