ndisrc: Get rid of unnecessary AtomicRefCell dependency

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1727>
This commit is contained in:
Sebastian Dröge 2024-08-19 15:28:56 +03:00 committed by GStreamer Marge Bot
parent 0c4ec370cf
commit ab3db748be
3 changed files with 46 additions and 53 deletions

1
Cargo.lock generated
View file

@ -2672,7 +2672,6 @@ name = "gst-plugin-ndi"
version = "0.14.0-alpha.1" version = "0.14.0-alpha.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"atomic_refcell",
"byte-slice-cast", "byte-slice-cast",
"byteorder", "byteorder",
"data-encoding", "data-encoding",

View file

@ -18,7 +18,6 @@ anyhow = "1.0"
byte-slice-cast = "1" byte-slice-cast = "1"
byteorder = "1.0" byteorder = "1.0"
data-encoding = "2.4.0" data-encoding = "2.4.0"
atomic_refcell = "0.1"
libloading = "0.8" libloading = "0.8"
quick-xml = "0.31" quick-xml = "0.31"
smallvec = { version = "1.11", features = ["const_generics"] } smallvec = { version = "1.11", features = ["const_generics"] }

View file

@ -1,6 +1,5 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use atomic_refcell::AtomicRefCell;
use gst::prelude::*; use gst::prelude::*;
use gst::subclass::prelude::*; use gst::subclass::prelude::*;
use gst_base::prelude::*; use gst_base::prelude::*;
@ -801,22 +800,22 @@ impl NdiSrc {
const WINDOW_LENGTH: u64 = 512; const WINDOW_LENGTH: u64 = 512;
const WINDOW_DURATION: u64 = 2_000_000_000; const WINDOW_DURATION: u64 = 2_000_000_000;
#[derive(Default)] struct Observations {
struct Observations(AtomicRefCell<ObservationsInner>);
struct ObservationsInner {
base_remote_time: Option<u64>,
base_local_time: Option<u64>, base_local_time: Option<u64>,
base_remote_time: Option<u64>,
// Difference between local and remote time
deltas: VecDeque<i64>, deltas: VecDeque<i64>,
// Current minimum difference
min_delta: i64, min_delta: i64,
// Running average of the minimum difference
skew: i64, skew: i64,
filling: bool, filling: bool,
window_size: usize, window_size: usize,
} }
impl Default for ObservationsInner { impl Default for Observations {
fn default() -> ObservationsInner { fn default() -> Observations {
ObservationsInner { Observations {
base_local_time: None, base_local_time: None,
base_remote_time: None, base_remote_time: None,
deltas: VecDeque::new(), deltas: VecDeque::new(),
@ -828,7 +827,7 @@ impl Default for ObservationsInner {
} }
} }
impl ObservationsInner { impl Observations {
fn reset(&mut self) { fn reset(&mut self) {
self.base_local_time = None; self.base_local_time = None;
self.base_remote_time = None; self.base_remote_time = None;
@ -838,14 +837,12 @@ impl ObservationsInner {
self.filling = true; self.filling = true;
self.window_size = 0; self.window_size = 0;
} }
}
impl Observations {
// Based on the algorithm used in GStreamer's rtpjitterbuffer, which comes from // Based on the algorithm used in GStreamer's rtpjitterbuffer, which comes from
// Fober, Orlarey and Letz, 2005, "Real Time Clock Skew Estimation over Network Delays": // Fober, Orlarey and Letz, 2005, "Real Time Clock Skew Estimation over Network Delays":
// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.102.1546 // http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.102.1546
fn process( fn process(
&self, &mut self,
element: &gst::Element, element: &gst::Element,
remote_time: Option<gst::ClockTime>, remote_time: Option<gst::ClockTime>,
local_time: gst::ClockTime, local_time: gst::ClockTime,
@ -854,8 +851,6 @@ impl Observations {
let remote_time = remote_time?.nseconds(); let remote_time = remote_time?.nseconds();
let local_time = local_time.nseconds(); let local_time = local_time.nseconds();
let mut inner = self.0.borrow_mut();
gst::trace!( gst::trace!(
CAT, CAT,
obj = element, obj = element,
@ -865,7 +860,7 @@ impl Observations {
); );
let (base_remote_time, base_local_time) = let (base_remote_time, base_local_time) =
match (inner.base_remote_time, inner.base_local_time) { match (self.base_remote_time, self.base_local_time) {
(Some(remote), Some(local)) => (remote, local), (Some(remote), Some(local)) => (remote, local),
_ => { _ => {
gst::debug!( gst::debug!(
@ -875,8 +870,8 @@ impl Observations {
local_time.nseconds(), local_time.nseconds(),
remote_time.nseconds(), remote_time.nseconds(),
); );
inner.base_remote_time = Some(remote_time); self.base_remote_time = Some(remote_time);
inner.base_local_time = Some(local_time); self.base_local_time = Some(local_time);
return Some((local_time.nseconds(), duration, true)); return Some((local_time.nseconds(), duration, true));
} }
@ -907,7 +902,7 @@ impl Observations {
slope slope
); );
let discont = !inner.deltas.is_empty(); let discont = !self.deltas.is_empty();
gst::debug!( gst::debug!(
CAT, CAT,
@ -917,25 +912,25 @@ impl Observations {
remote_time.nseconds(), remote_time.nseconds(),
); );
inner.reset(); self.reset();
inner.base_remote_time = Some(remote_time); self.base_remote_time = Some(remote_time);
inner.base_local_time = Some(local_time); self.base_local_time = Some(local_time);
return Some((local_time.nseconds(), duration, discont)); return Some((local_time.nseconds(), duration, discont));
} }
if (delta > inner.skew && delta - inner.skew > 1_000_000_000) if (delta > self.skew && delta - self.skew > 1_000_000_000)
|| (delta < inner.skew && inner.skew - delta > 1_000_000_000) || (delta < self.skew && self.skew - delta > 1_000_000_000)
{ {
gst::warning!( gst::warning!(
CAT, CAT,
obj = element, obj = element,
"Delta {} too far from skew {}, resetting", "Delta {} too far from skew {}, resetting",
delta, delta,
inner.skew self.skew
); );
let discont = !inner.deltas.is_empty(); let discont = !self.deltas.is_empty();
gst::debug!( gst::debug!(
CAT, CAT,
@ -945,58 +940,58 @@ impl Observations {
remote_time.nseconds(), remote_time.nseconds(),
); );
inner.reset(); self.reset();
inner.base_remote_time = Some(remote_time); self.base_remote_time = Some(remote_time);
inner.base_local_time = Some(local_time); self.base_local_time = Some(local_time);
return Some((local_time.nseconds(), duration, discont)); return Some((local_time.nseconds(), duration, discont));
} }
if inner.filling { if self.filling {
if inner.deltas.is_empty() || delta < inner.min_delta { if self.deltas.is_empty() || delta < self.min_delta {
inner.min_delta = delta; self.min_delta = delta;
} }
inner.deltas.push_back(delta); self.deltas.push_back(delta);
if remote_diff > WINDOW_DURATION || inner.deltas.len() as u64 == WINDOW_LENGTH { if remote_diff > WINDOW_DURATION || self.deltas.len() as u64 == WINDOW_LENGTH {
inner.window_size = inner.deltas.len(); self.window_size = self.deltas.len();
inner.skew = inner.min_delta; self.skew = self.min_delta;
inner.filling = false; self.filling = false;
} else { } else {
let perc_time = remote_diff.mul_div_floor(100, WINDOW_DURATION).unwrap() as i64; let perc_time = remote_diff.mul_div_floor(100, WINDOW_DURATION).unwrap() as i64;
let perc_window = (inner.deltas.len() as u64) let perc_window = (self.deltas.len() as u64)
.mul_div_floor(100, WINDOW_LENGTH) .mul_div_floor(100, WINDOW_LENGTH)
.unwrap() as i64; .unwrap() as i64;
let perc = cmp::max(perc_time, perc_window); let perc = cmp::max(perc_time, perc_window);
inner.skew = (perc * inner.min_delta + ((10_000 - perc) * inner.skew)) / 10_000; self.skew = (perc * self.min_delta + ((10_000 - perc) * self.skew)) / 10_000;
} }
} else { } else {
let old = inner.deltas.pop_front().unwrap(); let old = self.deltas.pop_front().unwrap();
inner.deltas.push_back(delta); self.deltas.push_back(delta);
if delta <= inner.min_delta { if delta <= self.min_delta {
inner.min_delta = delta; self.min_delta = delta;
} else if old == inner.min_delta { } else if old == self.min_delta {
inner.min_delta = inner.deltas.iter().copied().min().unwrap(); self.min_delta = self.deltas.iter().copied().min().unwrap();
} }
inner.skew = (inner.min_delta + (124 * inner.skew)) / 125; self.skew = (self.min_delta + (124 * self.skew)) / 125;
} }
let out_time = base_local_time + remote_diff; let out_time = base_local_time + remote_diff;
let out_time = if inner.skew < 0 { let out_time = if self.skew < 0 {
out_time.saturating_sub((-inner.skew) as u64) out_time.saturating_sub((-self.skew) as u64)
} else { } else {
out_time + (inner.skew as u64) out_time + (self.skew as u64)
}; };
gst::trace!( gst::trace!(
CAT, CAT,
obj = element, obj = element,
"Skew {}, min delta {}", "Skew {}, min delta {}",
inner.skew, self.skew,
inner.min_delta self.min_delta
); );
gst::trace!(CAT, obj = element, "Outputting {}", out_time.nseconds()); gst::trace!(CAT, obj = element, "Outputting {}", out_time.nseconds());