mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-25 04:51:26 +00:00
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:
parent
0c4ec370cf
commit
ab3db748be
3 changed files with 46 additions and 53 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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"] }
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue