mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-21 09:36:28 +00:00
Improve usability thanks to opt-ops
The crate option-operations simplifies usage when dealing with `Option`s, which is often the case with `ClockTime`.
This commit is contained in:
parent
bd8a7e8df7
commit
27b9f0d868
29 changed files with 175 additions and 308 deletions
|
@ -235,7 +235,9 @@ impl State {
|
||||||
let distance_ts = distance_samples
|
let distance_ts = distance_samples
|
||||||
.mul_div_floor(*gst::ClockTime::SECOND, self.info.rate() as u64)
|
.mul_div_floor(*gst::ClockTime::SECOND, self.info.rate() as u64)
|
||||||
.map(gst::ClockTime::from_nseconds);
|
.map(gst::ClockTime::from_nseconds);
|
||||||
let pts = pts.zip(distance_ts).map(|(pts, dist)| pts + dist);
|
let pts = pts
|
||||||
|
.opt_checked_add(distance_ts)
|
||||||
|
.map_err(|_| gst::FlowError::Error)?;
|
||||||
|
|
||||||
let inbuf = self
|
let inbuf = self
|
||||||
.adapter
|
.adapter
|
||||||
|
@ -276,7 +278,9 @@ impl State {
|
||||||
let distance_ts = distance_samples
|
let distance_ts = distance_samples
|
||||||
.mul_div_floor(*gst::ClockTime::SECOND, self.info.rate() as u64)
|
.mul_div_floor(*gst::ClockTime::SECOND, self.info.rate() as u64)
|
||||||
.map(gst::ClockTime::from_nseconds);
|
.map(gst::ClockTime::from_nseconds);
|
||||||
let pts = pts.zip(distance_ts).map(|(pts, dist)| pts + dist);
|
let pts = pts
|
||||||
|
.opt_checked_add(distance_ts)
|
||||||
|
.map_err(|_| gst::FlowError::Error)?;
|
||||||
|
|
||||||
let mut _mapped_inbuf = None;
|
let mut _mapped_inbuf = None;
|
||||||
let src = if self.adapter.available() > 0 {
|
let src = if self.adapter.available() > 0 {
|
||||||
|
@ -1702,7 +1706,7 @@ impl AudioLoudNorm {
|
||||||
q.set(
|
q.set(
|
||||||
live,
|
live,
|
||||||
min_latency + 3 * gst::ClockTime::SECOND,
|
min_latency + 3 * gst::ClockTime::SECOND,
|
||||||
max_latency.map(|max| max + 3 * gst::ClockTime::SECOND),
|
max_latency.opt_add(3 * gst::ClockTime::SECOND),
|
||||||
);
|
);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -74,8 +74,9 @@ impl State {
|
||||||
// pts at the beginning of the adapter.
|
// pts at the beginning of the adapter.
|
||||||
let samples = distance / self.in_info.bpf() as u64;
|
let samples = distance / self.in_info.bpf() as u64;
|
||||||
prev_pts
|
prev_pts
|
||||||
.zip(self.samples_to_time(samples))
|
.opt_checked_add(self.samples_to_time(samples))
|
||||||
.map(|(prev_pts, time_offset)| prev_pts + time_offset)
|
.ok()
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn needs_more_data(&self) -> bool {
|
fn needs_more_data(&self) -> bool {
|
||||||
|
@ -367,8 +368,7 @@ impl BaseTransformImpl for AudioRNNoise {
|
||||||
);
|
);
|
||||||
|
|
||||||
min += gst::ClockTime::from_seconds((FRAME_SIZE / 48000) as u64);
|
min += gst::ClockTime::from_seconds((FRAME_SIZE / 48000) as u64);
|
||||||
max = max
|
max = max.opt_add(gst::ClockTime::from_seconds((FRAME_SIZE / 48000) as u64));
|
||||||
.map(|max| max + gst::ClockTime::from_seconds((FRAME_SIZE / 48000) as u64));
|
|
||||||
q.set(live, min, max);
|
q.set(live, min, max);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,12 +481,12 @@ impl BaseTransformImpl for EbuR128Level {
|
||||||
|
|
||||||
// The timestamp we report in messages is always the timestamp until which measurements
|
// The timestamp we report in messages is always the timestamp until which measurements
|
||||||
// are included, not the starting timestamp.
|
// are included, not the starting timestamp.
|
||||||
timestamp = timestamp.map(|ts| {
|
timestamp = timestamp.opt_add(
|
||||||
ts + to_process
|
to_process
|
||||||
.mul_div_floor(*gst::ClockTime::SECOND, state.info.rate() as u64)
|
.mul_div_floor(*gst::ClockTime::SECOND, state.info.rate() as u64)
|
||||||
.map(gst::ClockTime::from_nseconds)
|
.map(gst::ClockTime::from_nseconds)
|
||||||
.unwrap()
|
.unwrap(),
|
||||||
});
|
);
|
||||||
|
|
||||||
// Post a message whenever an interval is full
|
// Post a message whenever an interval is full
|
||||||
if state.interval_frames_remaining.is_zero() {
|
if state.interval_frames_remaining.is_zero() {
|
||||||
|
|
|
@ -120,8 +120,9 @@ impl State {
|
||||||
// pts at the beginning of the adapter.
|
// pts at the beginning of the adapter.
|
||||||
let samples = distance / self.in_info.bpf() as u64;
|
let samples = distance / self.in_info.bpf() as u64;
|
||||||
prev_pts
|
prev_pts
|
||||||
.zip(self.samples_to_time(samples))
|
.opt_checked_add(self.samples_to_time(samples))
|
||||||
.map(|(prev_pts, time_offset)| prev_pts + time_offset)
|
.ok()
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buffer_duration(&self, buffer_size: u64) -> Option<gst::ClockTime> {
|
fn buffer_duration(&self, buffer_size: u64) -> Option<gst::ClockTime> {
|
||||||
|
|
|
@ -181,7 +181,7 @@ fn csound_filter_eos() {
|
||||||
let samples_at_eos = (EOS_NUM_BUFFERS * EOS_NUM_SAMPLES) % ksmps;
|
let samples_at_eos = (EOS_NUM_BUFFERS * EOS_NUM_SAMPLES) % ksmps;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
buffer.as_ref().pts(),
|
buffer.as_ref().pts(),
|
||||||
duration_from_samples(samples_at_eos as _, sr as _).map(|duration| in_pts - duration)
|
in_pts.opt_sub(duration_from_samples(samples_at_eos as _, sr as _))
|
||||||
);
|
);
|
||||||
|
|
||||||
let map = buffer.into_mapped_buffer_readable().unwrap();
|
let map = buffer.into_mapped_buffer_readable().unwrap();
|
||||||
|
|
|
@ -38,8 +38,7 @@ use crate::runtime::prelude::*;
|
||||||
use crate::runtime::{Context, PadSrc, PadSrcRef, PadSrcWeak, Task, TaskState};
|
use crate::runtime::{Context, PadSrc, PadSrcRef, PadSrcWeak, Task, TaskState};
|
||||||
|
|
||||||
const DEFAULT_CONTEXT: &str = "";
|
const DEFAULT_CONTEXT: &str = "";
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
const DEFAULT_CONTEXT_WAIT: Duration = Duration::ZERO;
|
||||||
const DEFAULT_CONTEXT_WAIT: Duration = Duration::from_nanos(0);
|
|
||||||
const DEFAULT_CAPS: Option<gst::Caps> = None;
|
const DEFAULT_CAPS: Option<gst::Caps> = None;
|
||||||
const DEFAULT_MAX_BUFFERS: u32 = 10;
|
const DEFAULT_MAX_BUFFERS: u32 = 10;
|
||||||
const DEFAULT_DO_TIMESTAMP: bool = false;
|
const DEFAULT_DO_TIMESTAMP: bool = false;
|
||||||
|
@ -391,10 +390,7 @@ impl AppSrc {
|
||||||
let now = clock.time();
|
let now = clock.time();
|
||||||
|
|
||||||
let buffer = buffer.make_mut();
|
let buffer = buffer.make_mut();
|
||||||
buffer.set_dts(
|
buffer.set_dts(now.opt_checked_sub(base_time).ok().flatten());
|
||||||
now.zip(base_time)
|
|
||||||
.and_then(|(now, base_time)| now.checked_sub(base_time)),
|
|
||||||
);
|
|
||||||
buffer.set_pts(None);
|
buffer.set_pts(None);
|
||||||
} else {
|
} else {
|
||||||
gst_error!(CAT, obj: element, "Don't have a clock yet");
|
gst_error!(CAT, obj: element, "Don't have a clock yet");
|
||||||
|
|
|
@ -35,8 +35,7 @@ use crate::runtime::prelude::*;
|
||||||
use crate::runtime::{self, PadSink, PadSinkRef, PadSrc, PadSrcRef};
|
use crate::runtime::{self, PadSink, PadSinkRef, PadSrc, PadSrcRef};
|
||||||
|
|
||||||
const DEFAULT_CONTEXT: &str = "";
|
const DEFAULT_CONTEXT: &str = "";
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
const DEFAULT_CONTEXT_WAIT: Duration = Duration::ZERO;
|
||||||
const DEFAULT_CONTEXT_WAIT: Duration = Duration::from_nanos(0);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Settings {
|
struct Settings {
|
||||||
|
@ -82,13 +81,9 @@ impl InputSelectorPadSinkHandler {
|
||||||
) {
|
) {
|
||||||
let now = element.current_running_time();
|
let now = element.current_running_time();
|
||||||
|
|
||||||
match running_time
|
match running_time.into().opt_checked_sub(now) {
|
||||||
.into()
|
Ok(Some(delay)) => runtime::time::delay_for(delay.into()).await,
|
||||||
.zip(now)
|
_ => runtime::executor::yield_now().await,
|
||||||
.and_then(|(running_time, now)| running_time.checked_sub(now))
|
|
||||||
{
|
|
||||||
Some(delay) => runtime::time::delay_for(delay.into()).await,
|
|
||||||
None => runtime::executor::yield_now().await,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,10 +310,7 @@ impl PadSrcHandler for InputSelectorPadSrcHandler {
|
||||||
let (live, min, max) = peer_query.result();
|
let (live, min, max) = peer_query.result();
|
||||||
if live {
|
if live {
|
||||||
min_latency = min.max(min_latency);
|
min_latency = min.max(min_latency);
|
||||||
max_latency = max
|
max_latency = max.opt_min(max_latency).or(max);
|
||||||
.zip(max_latency)
|
|
||||||
.map(|(max, max_latency)| max.min(max_latency))
|
|
||||||
.or(max);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,10 +212,7 @@ impl SinkHandler {
|
||||||
) {
|
) {
|
||||||
if inner.ips_rtptime != Some(rtptime) {
|
if inner.ips_rtptime != Some(rtptime) {
|
||||||
let pts = pts.into();
|
let pts = pts.into();
|
||||||
let new_packet_spacing = inner
|
let new_packet_spacing = pts.opt_checked_sub(inner.ips_pts).ok().flatten();
|
||||||
.ips_pts
|
|
||||||
.zip(pts)
|
|
||||||
.and_then(|(ips_pts, pts)| pts.checked_sub(ips_pts));
|
|
||||||
if let Some(new_packet_spacing) = new_packet_spacing {
|
if let Some(new_packet_spacing) = new_packet_spacing {
|
||||||
let old_packet_spacing = state.packet_spacing;
|
let old_packet_spacing = state.packet_spacing;
|
||||||
|
|
||||||
|
@ -744,7 +741,6 @@ impl SrcHandler {
|
||||||
&[
|
&[
|
||||||
("seqnum", &(lost_seqnum as u32)),
|
("seqnum", &(lost_seqnum as u32)),
|
||||||
("timestamp", ×tamp),
|
("timestamp", ×tamp),
|
||||||
// FIXME would probably make sense being a ClockTime
|
|
||||||
("duration", &duration.nseconds()),
|
("duration", &duration.nseconds()),
|
||||||
("retry", &0),
|
("retry", &0),
|
||||||
],
|
],
|
||||||
|
@ -864,8 +860,7 @@ impl SrcHandler {
|
||||||
|
|
||||||
if state.eos {
|
if state.eos {
|
||||||
gst_debug!(CAT, obj: element, "EOS, not waiting");
|
gst_debug!(CAT, obj: element, "EOS, not waiting");
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
return (now, Some((now, Duration::ZERO)));
|
||||||
return (now, Some((now, Duration::from_nanos(0))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.earliest_pts.is_none() {
|
if state.earliest_pts.is_none() {
|
||||||
|
@ -877,10 +872,8 @@ impl SrcHandler {
|
||||||
.map(|earliest_pts| earliest_pts + latency - state.packet_spacing - context_wait / 2);
|
.map(|earliest_pts| earliest_pts + latency - state.packet_spacing - context_wait / 2);
|
||||||
|
|
||||||
let delay = next_wakeup
|
let delay = next_wakeup
|
||||||
.zip(now)
|
.opt_saturating_sub(now)
|
||||||
.map_or(gst::ClockTime::ZERO, |(next_wakeup, now)| {
|
.unwrap_or(gst::ClockTime::ZERO);
|
||||||
next_wakeup.saturating_sub(now)
|
|
||||||
});
|
|
||||||
|
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
CAT,
|
CAT,
|
||||||
|
@ -1113,8 +1106,7 @@ impl TaskImpl for JitterBufferTask {
|
||||||
);
|
);
|
||||||
|
|
||||||
let (delay_fut, abort_handle) = match next_wakeup {
|
let (delay_fut, abort_handle) = match next_wakeup {
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
Some((_, delay)) if delay.is_zero() => (None, None),
|
||||||
Some((_, delay)) if delay == Duration::from_nanos(0) => (None, None),
|
|
||||||
_ => {
|
_ => {
|
||||||
let (delay_fut, abort_handle) = abortable(async move {
|
let (delay_fut, abort_handle) = abortable(async move {
|
||||||
match next_wakeup {
|
match next_wakeup {
|
||||||
|
@ -1166,10 +1158,7 @@ impl TaskImpl for JitterBufferTask {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some((next_wakeup, _)) = next_wakeup {
|
if let Some((next_wakeup, _)) = next_wakeup {
|
||||||
if next_wakeup
|
if next_wakeup.opt_gt(now).unwrap_or(false) {
|
||||||
.zip(now)
|
|
||||||
.map_or(false, |(next_wakeup, now)| next_wakeup > now)
|
|
||||||
{
|
|
||||||
// Reschedule and wait a bit longer in the next iteration
|
// Reschedule and wait a bit longer in the next iteration
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,7 @@ const DEFAULT_MAX_SIZE_BUFFERS: u32 = 200;
|
||||||
const DEFAULT_MAX_SIZE_BYTES: u32 = 1024 * 1024;
|
const DEFAULT_MAX_SIZE_BYTES: u32 = 1024 * 1024;
|
||||||
const DEFAULT_MAX_SIZE_TIME: gst::ClockTime = gst::ClockTime::SECOND;
|
const DEFAULT_MAX_SIZE_TIME: gst::ClockTime = gst::ClockTime::SECOND;
|
||||||
const DEFAULT_CONTEXT: &str = "";
|
const DEFAULT_CONTEXT: &str = "";
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
const DEFAULT_CONTEXT_WAIT: Duration = Duration::ZERO;
|
||||||
const DEFAULT_CONTEXT_WAIT: Duration = Duration::from_nanos(0);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct SettingsSink {
|
struct SettingsSink {
|
||||||
|
|
|
@ -40,8 +40,7 @@ const DEFAULT_MAX_SIZE_BUFFERS: u32 = 200;
|
||||||
const DEFAULT_MAX_SIZE_BYTES: u32 = 1024 * 1024;
|
const DEFAULT_MAX_SIZE_BYTES: u32 = 1024 * 1024;
|
||||||
const DEFAULT_MAX_SIZE_TIME: gst::ClockTime = gst::ClockTime::SECOND;
|
const DEFAULT_MAX_SIZE_TIME: gst::ClockTime = gst::ClockTime::SECOND;
|
||||||
const DEFAULT_CONTEXT: &str = "";
|
const DEFAULT_CONTEXT: &str = "";
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
const DEFAULT_CONTEXT_WAIT: Duration = Duration::ZERO;
|
||||||
const DEFAULT_CONTEXT_WAIT: Duration = Duration::from_nanos(0);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Settings {
|
struct Settings {
|
||||||
|
|
|
@ -1612,9 +1612,7 @@ mod tests {
|
||||||
task.prepare(TaskPrepareTest { prepare_receiver }, context.clone())
|
task.prepare(TaskPrepareTest { prepare_receiver }, context.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
let start_ctx = Context::acquire("prepare_start_ok_requester", Duration::ZERO).unwrap();
|
||||||
let start_ctx =
|
|
||||||
Context::acquire("prepare_start_ok_requester", Duration::from_nanos(0)).unwrap();
|
|
||||||
let task_clone = task.clone();
|
let task_clone = task.clone();
|
||||||
let (ready_sender, ready_receiver) = oneshot::channel();
|
let (ready_sender, ready_receiver) = oneshot::channel();
|
||||||
let start_handle = start_ctx.spawn(async move {
|
let start_handle = start_ctx.spawn(async move {
|
||||||
|
@ -1737,9 +1735,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
let start_ctx = Context::acquire("prepare_start_error_requester", Duration::ZERO).unwrap();
|
||||||
let start_ctx =
|
|
||||||
Context::acquire("prepare_start_error_requester", Duration::from_nanos(0)).unwrap();
|
|
||||||
let task_clone = task.clone();
|
let task_clone = task.clone();
|
||||||
let (ready_sender, ready_receiver) = oneshot::channel();
|
let (ready_sender, ready_receiver) = oneshot::channel();
|
||||||
let start_handle = start_ctx.spawn(async move {
|
let start_handle = start_ctx.spawn(async move {
|
||||||
|
|
|
@ -143,11 +143,7 @@ impl<T: SocketRead> Socket<T> {
|
||||||
Ok((len, saddr)) => {
|
Ok((len, saddr)) => {
|
||||||
let dts = if T::DO_TIMESTAMP {
|
let dts = if T::DO_TIMESTAMP {
|
||||||
let time = self.clock.as_ref().unwrap().time();
|
let time = self.clock.as_ref().unwrap().time();
|
||||||
let running_time = time
|
let running_time = time.opt_checked_sub(self.base_time).ok().flatten();
|
||||||
.zip(self.base_time)
|
|
||||||
// TODO Do we want None if time < base_time
|
|
||||||
// or do we expect Some?
|
|
||||||
.and_then(|(time, base_time)| time.checked_sub(base_time));
|
|
||||||
// FIXME maybe we should check if running_time.is_none
|
// FIXME maybe we should check if running_time.is_none
|
||||||
// so as to display another message
|
// so as to display another message
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
|
|
|
@ -48,8 +48,7 @@ const DEFAULT_PORT: i32 = 4953;
|
||||||
const DEFAULT_CAPS: Option<gst::Caps> = None;
|
const DEFAULT_CAPS: Option<gst::Caps> = None;
|
||||||
const DEFAULT_BLOCKSIZE: u32 = 4096;
|
const DEFAULT_BLOCKSIZE: u32 = 4096;
|
||||||
const DEFAULT_CONTEXT: &str = "";
|
const DEFAULT_CONTEXT: &str = "";
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
const DEFAULT_CONTEXT_WAIT: Duration = Duration::ZERO;
|
||||||
const DEFAULT_CONTEXT_WAIT: Duration = Duration::from_nanos(0);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Settings {
|
struct Settings {
|
||||||
|
|
|
@ -62,8 +62,7 @@ const DEFAULT_TTL_MC: u32 = 1;
|
||||||
const DEFAULT_QOS_DSCP: i32 = -1;
|
const DEFAULT_QOS_DSCP: i32 = -1;
|
||||||
const DEFAULT_CLIENTS: &str = "";
|
const DEFAULT_CLIENTS: &str = "";
|
||||||
const DEFAULT_CONTEXT: &str = "";
|
const DEFAULT_CONTEXT: &str = "";
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
const DEFAULT_CONTEXT_WAIT: Duration = Duration::ZERO;
|
||||||
const DEFAULT_CONTEXT_WAIT: Duration = Duration::from_nanos(0);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Settings {
|
struct Settings {
|
||||||
|
@ -412,10 +411,7 @@ impl UdpSinkPadHandler {
|
||||||
rtime = segment
|
rtime = segment
|
||||||
.downcast_ref::<gst::format::Time>()
|
.downcast_ref::<gst::format::Time>()
|
||||||
.and_then(|segment| {
|
.and_then(|segment| {
|
||||||
segment
|
segment.to_running_time(buffer.pts()).opt_add(inner.latency)
|
||||||
.to_running_time(buffer.pts())
|
|
||||||
.zip(inner.latency)
|
|
||||||
.map(|(rtime, latency)| rtime + latency)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,13 +525,9 @@ impl UdpSinkPadHandler {
|
||||||
) {
|
) {
|
||||||
let now = element.current_running_time();
|
let now = element.current_running_time();
|
||||||
|
|
||||||
match running_time
|
match running_time.into().opt_checked_sub(now) {
|
||||||
.into()
|
Ok(Some(delay)) => runtime::time::delay_for(delay.into()).await,
|
||||||
.zip(now)
|
_ => runtime::executor::yield_now().await,
|
||||||
.and_then(|(running_time, now)| running_time.checked_sub(now))
|
|
||||||
{
|
|
||||||
Some(delay) => runtime::time::delay_for(delay.into()).await,
|
|
||||||
None => runtime::executor::yield_now().await,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,7 @@ const DEFAULT_MTU: u32 = 1492;
|
||||||
const DEFAULT_SOCKET: Option<GioSocketWrapper> = None;
|
const DEFAULT_SOCKET: Option<GioSocketWrapper> = None;
|
||||||
const DEFAULT_USED_SOCKET: Option<GioSocketWrapper> = None;
|
const DEFAULT_USED_SOCKET: Option<GioSocketWrapper> = None;
|
||||||
const DEFAULT_CONTEXT: &str = "";
|
const DEFAULT_CONTEXT: &str = "";
|
||||||
// FIXME use Duration::ZERO when MSVC >= 1.53.2
|
const DEFAULT_CONTEXT_WAIT: Duration = Duration::ZERO;
|
||||||
const DEFAULT_CONTEXT_WAIT: Duration = Duration::from_nanos(0);
|
|
||||||
const DEFAULT_RETRIEVE_SENDER_ADDRESS: bool = true;
|
const DEFAULT_RETRIEVE_SENDER_ADDRESS: bool = true;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -760,9 +760,7 @@ impl Transcriber {
|
||||||
let running_time = state.in_segment.to_running_time(buffer.pts());
|
let running_time = state.in_segment.to_running_time(buffer.pts());
|
||||||
let now = element.current_running_time();
|
let now = element.current_running_time();
|
||||||
|
|
||||||
delay = running_time
|
delay = running_time.opt_checked_sub(now).ok().flatten();
|
||||||
.zip(now)
|
|
||||||
.and_then(|(running_time, now)| running_time.checked_sub(now));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ impl State {
|
||||||
) {
|
) {
|
||||||
let buffer = buffer.get_mut().unwrap();
|
let buffer = buffer.get_mut().unwrap();
|
||||||
|
|
||||||
self.last_position = pts.zip(duration).map(|(pts, duration)| pts + duration);
|
self.last_position = pts.opt_add(duration);
|
||||||
|
|
||||||
buffer.set_pts(pts);
|
buffer.set_pts(pts);
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ impl JsonGstParse {
|
||||||
let mut buffer = gst::Buffer::from_mut_slice(data.into_bytes());
|
let mut buffer = gst::Buffer::from_mut_slice(data.into_bytes());
|
||||||
|
|
||||||
if let Some(last_position) = state.last_position {
|
if let Some(last_position) = state.last_position {
|
||||||
if let Some(duration) = pts.map(|pts| pts.checked_sub(last_position)) {
|
if let Ok(Some(duration)) = pts.opt_checked_sub(last_position) {
|
||||||
events.push(
|
events.push(
|
||||||
gst::event::Gap::builder(last_position)
|
gst::event::Gap::builder(last_position)
|
||||||
.duration(duration)
|
.duration(duration)
|
||||||
|
@ -274,12 +274,11 @@ impl JsonGstParse {
|
||||||
|
|
||||||
state.add_buffer_metadata(element, &mut buffer, pts, duration);
|
state.add_buffer_metadata(element, &mut buffer, pts, duration);
|
||||||
|
|
||||||
let send_eos = state
|
let send_eos = buffer
|
||||||
.segment
|
.pts()
|
||||||
.stop()
|
.opt_add(buffer.duration())
|
||||||
.zip(buffer.pts())
|
.opt_ge(state.segment.stop())
|
||||||
.zip(buffer.duration())
|
.unwrap_or(false);
|
||||||
.map_or(false, |((stop, pts), duration)| pts + duration >= stop);
|
|
||||||
|
|
||||||
// Drop our state mutex while we push out buffers or events
|
// Drop our state mutex while we push out buffers or events
|
||||||
drop(state);
|
drop(state);
|
||||||
|
@ -346,11 +345,7 @@ impl JsonGstParse {
|
||||||
pts: impl Into<Option<gst::ClockTime>>,
|
pts: impl Into<Option<gst::ClockTime>>,
|
||||||
mut state: MutexGuard<State>,
|
mut state: MutexGuard<State>,
|
||||||
) -> MutexGuard<State> {
|
) -> MutexGuard<State> {
|
||||||
if pts
|
if pts.into().opt_ge(state.segment.start()).unwrap_or(false) {
|
||||||
.into()
|
|
||||||
.zip(state.segment.start())
|
|
||||||
.map_or(false, |(pts, start)| pts >= start)
|
|
||||||
{
|
|
||||||
state.seeking = false;
|
state.seeking = false;
|
||||||
state.discont = true;
|
state.discont = true;
|
||||||
state.replay_last_line = true;
|
state.replay_last_line = true;
|
||||||
|
@ -503,7 +498,7 @@ impl JsonGstParse {
|
||||||
data: _data,
|
data: _data,
|
||||||
}) = serde_json::from_slice(line)
|
}) = serde_json::from_slice(line)
|
||||||
{
|
{
|
||||||
last_pts = pts.zip(duration).map(|(pts, duration)| pts + duration);
|
last_pts = pts.opt_add(duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,17 +752,11 @@ impl JsonGstParse {
|
||||||
let pull = state.pull.as_ref().unwrap();
|
let pull = state.pull.as_ref().unwrap();
|
||||||
|
|
||||||
if start_type == gst::SeekType::Set {
|
if start_type == gst::SeekType::Set {
|
||||||
start = start
|
start = start.opt_min(pull.duration).or(start);
|
||||||
.zip(pull.duration)
|
|
||||||
.map(|(start, duration)| start.min(duration))
|
|
||||||
.or(start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if stop_type == gst::SeekType::Set {
|
if stop_type == gst::SeekType::Set {
|
||||||
stop = stop
|
stop = stop.opt_min(pull.duration).or(stop);
|
||||||
.zip(pull.duration)
|
|
||||||
.map(|(stop, duration)| stop.min(duration))
|
|
||||||
.or(stop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.seeking = true;
|
state.seeking = true;
|
||||||
|
|
|
@ -203,10 +203,9 @@ impl TextWrap {
|
||||||
|
|
||||||
let add_buffer = state
|
let add_buffer = state
|
||||||
.start_ts
|
.start_ts
|
||||||
.zip(Some(accumulate_time))
|
.opt_add(accumulate_time)
|
||||||
.map_or(false, |(start_ts, accumulate_time)| {
|
.opt_lt(pts)
|
||||||
start_ts + accumulate_time < pts
|
.unwrap_or(false);
|
||||||
});
|
|
||||||
|
|
||||||
if add_buffer {
|
if add_buffer {
|
||||||
let mut buf =
|
let mut buf =
|
||||||
|
@ -214,12 +213,8 @@ impl TextWrap {
|
||||||
{
|
{
|
||||||
let buf_mut = buf.get_mut().unwrap();
|
let buf_mut = buf.get_mut().unwrap();
|
||||||
buf_mut.set_pts(state.start_ts);
|
buf_mut.set_pts(state.start_ts);
|
||||||
buf_mut.set_duration(
|
buf_mut
|
||||||
state
|
.set_duration(state.end_ts.opt_checked_sub(state.start_ts).ok().flatten());
|
||||||
.end_ts
|
|
||||||
.zip(state.start_ts)
|
|
||||||
.and_then(|(end_ts, start_ts)| end_ts.checked_sub(start_ts)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
bufferlist.get_mut().unwrap().add(buf);
|
bufferlist.get_mut().unwrap().add(buf);
|
||||||
|
|
||||||
|
@ -262,10 +257,7 @@ impl TextWrap {
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join("\n");
|
.join("\n");
|
||||||
} else {
|
} else {
|
||||||
let duration = state
|
let duration = state.end_ts.opt_checked_sub(state.start_ts).ok().flatten();
|
||||||
.end_ts
|
|
||||||
.zip(state.start_ts)
|
|
||||||
.and_then(|(end_ts, start_ts)| end_ts.checked_sub(start_ts));
|
|
||||||
let contents = chunk
|
let contents = chunk
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| l.to_string())
|
.map(|l| l.to_string())
|
||||||
|
@ -291,7 +283,7 @@ impl TextWrap {
|
||||||
}
|
}
|
||||||
|
|
||||||
current_text = trailing;
|
current_text = trailing;
|
||||||
state.end_ts = state.end_ts.map(|end_ts| end_ts + duration_per_word);
|
state.end_ts = state.end_ts.opt_add(duration_per_word);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.current_text = current_text;
|
state.current_text = current_text;
|
||||||
|
@ -399,10 +391,7 @@ impl TextWrap {
|
||||||
let buf_mut = buf.get_mut().unwrap();
|
let buf_mut = buf.get_mut().unwrap();
|
||||||
buf_mut.set_pts(state.start_ts);
|
buf_mut.set_pts(state.start_ts);
|
||||||
buf_mut.set_duration(
|
buf_mut.set_duration(
|
||||||
state
|
state.end_ts.opt_checked_sub(state.start_ts).ok().flatten(),
|
||||||
.end_ts
|
|
||||||
.zip(state.start_ts)
|
|
||||||
.and_then(|(end_ts, start_ts)| end_ts.checked_sub(start_ts)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -770,19 +770,11 @@ impl PushSrcImpl for SineSrc {
|
||||||
|
|
||||||
let segment = element.segment().downcast::<gst::format::Time>().unwrap();
|
let segment = element.segment().downcast::<gst::format::Time>().unwrap();
|
||||||
let base_time = element.base_time();
|
let base_time = element.base_time();
|
||||||
let running_time = segment.to_running_time(
|
let running_time = segment.to_running_time(buffer.pts().opt_add(buffer.duration()));
|
||||||
buffer
|
|
||||||
.pts()
|
|
||||||
.zip(buffer.duration())
|
|
||||||
.map(|(pts, duration)| pts + duration),
|
|
||||||
);
|
|
||||||
|
|
||||||
// The last sample's clock time is the base time of the element plus the
|
// The last sample's clock time is the base time of the element plus the
|
||||||
// running time of the last sample
|
// running time of the last sample
|
||||||
let wait_until = match running_time
|
let wait_until = match running_time.opt_add(base_time) {
|
||||||
.zip(base_time)
|
|
||||||
.map(|(running_time, base_time)| running_time + base_time)
|
|
||||||
{
|
|
||||||
Some(wait_until) => wait_until,
|
Some(wait_until) => wait_until,
|
||||||
None => return Ok(CreateSuccess::NewBuffer(buffer)),
|
None => return Ok(CreateSuccess::NewBuffer(buffer)),
|
||||||
};
|
};
|
||||||
|
|
|
@ -703,16 +703,12 @@ For working in live mode, we have to add a few different parts in various places
|
||||||
let running_time = segment.to_running_time(
|
let running_time = segment.to_running_time(
|
||||||
buffer
|
buffer
|
||||||
.pts()
|
.pts()
|
||||||
.zip(buffer.duration())
|
.opt_add(buffer.duration()),
|
||||||
.map(|(pts, duration)| pts + duration),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// The last sample's clock time is the base time of the element plus the
|
// The last sample's clock time is the base time of the element plus the
|
||||||
// running time of the last sample
|
// running time of the last sample
|
||||||
let wait_until = match running_time
|
let wait_until = match running_time.opt_add(base_time) {
|
||||||
.zip(base_time)
|
|
||||||
.map(|(running_time, base_time)| running_time + base_time)
|
|
||||||
{
|
|
||||||
Some(wait_until) => wait_until,
|
Some(wait_until) => wait_until,
|
||||||
None => return Ok(buffer),
|
None => return Ok(buffer),
|
||||||
};
|
};
|
||||||
|
|
|
@ -200,8 +200,8 @@ impl FallbackSwitch {
|
||||||
|
|
||||||
if pts.is_none()
|
if pts.is_none()
|
||||||
|| new_running_time
|
|| new_running_time
|
||||||
.zip(target_running_time.into())
|
.opt_le(target_running_time.into())
|
||||||
.map_or(false, |(new, target)| new <= target)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
gst_debug!(CAT, obj: pad, "Dropping trailing buffer {:?}", buffer);
|
gst_debug!(CAT, obj: pad, "Dropping trailing buffer {:?}", buffer);
|
||||||
pad.drop_buffer();
|
pad.drop_buffer();
|
||||||
|
@ -269,16 +269,13 @@ impl FallbackSwitch {
|
||||||
}
|
}
|
||||||
|
|
||||||
let cur_running_time = cur_running_time.into();
|
let cur_running_time = cur_running_time.into();
|
||||||
let (is_late, deadline) = cur_running_time
|
let (is_late, deadline) = match (cur_running_time, agg.latency(), running_time) {
|
||||||
.zip(agg.latency())
|
(Some(cur_running_time), Some(latency), Some(running_time)) => {
|
||||||
.zip(running_time)
|
let deadline = running_time + latency + 40 * gst::ClockTime::MSECOND;
|
||||||
.map_or(
|
(cur_running_time > deadline, Some(deadline))
|
||||||
(false, None),
|
}
|
||||||
|((cur_running_time, latency), running_time)| {
|
_ => (false, None),
|
||||||
let dealine = running_time + latency + 40 * gst::ClockTime::MSECOND;
|
};
|
||||||
(cur_running_time > dealine, Some(dealine))
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if is_late {
|
if is_late {
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
|
@ -289,13 +286,12 @@ impl FallbackSwitch {
|
||||||
deadline.display(),
|
deadline.display(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let is_late = state.last_output_time.zip(running_time).map_or(
|
let is_late = state
|
||||||
false,
|
.last_output_time
|
||||||
|(last_output_time, running_time)| {
|
.opt_add(settings.timeout)
|
||||||
last_output_time + settings.timeout <= running_time
|
.opt_le(running_time);
|
||||||
},
|
|
||||||
);
|
if let Some(true) = is_late {
|
||||||
if is_late {
|
|
||||||
/* This buffer arrived too late - we either already switched
|
/* This buffer arrived too late - we either already switched
|
||||||
* to the other pad or there's no point outputting this anyway */
|
* to the other pad or there's no point outputting this anyway */
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
|
@ -418,12 +414,11 @@ impl FallbackSwitch {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !ignore_timeout {
|
if !ignore_timeout {
|
||||||
let timed_out = !state.last_output_time.zip(running_time).map_or(
|
let timed_out = state
|
||||||
false,
|
.last_output_time
|
||||||
|(last_output_time, running_time)| {
|
.opt_add(settings.timeout)
|
||||||
last_output_time + settings.timeout > running_time
|
.opt_le(running_time)
|
||||||
},
|
.unwrap_or(true);
|
||||||
);
|
|
||||||
|
|
||||||
// Get the next one if this one is before the timeout
|
// Get the next one if this one is before the timeout
|
||||||
if !timed_out {
|
if !timed_out {
|
||||||
|
@ -544,10 +539,7 @@ impl FallbackSwitch {
|
||||||
let base_time = agg.base_time();
|
let base_time = agg.base_time();
|
||||||
|
|
||||||
let cur_running_time = if let Some(clock) = clock {
|
let cur_running_time = if let Some(clock) = clock {
|
||||||
clock
|
clock.time().opt_checked_sub(base_time).ok().flatten()
|
||||||
.time()
|
|
||||||
.zip(base_time)
|
|
||||||
.and_then(|(time, base_time)| time.checked_sub(base_time))
|
|
||||||
} else {
|
} else {
|
||||||
gst::ClockTime::NONE
|
gst::ClockTime::NONE
|
||||||
};
|
};
|
||||||
|
@ -1168,16 +1160,13 @@ impl AggregatorImpl for FallbackSwitch {
|
||||||
audio_info.bpf(),
|
audio_info.bpf(),
|
||||||
)
|
)
|
||||||
} else if pad_state.video_info.is_some() {
|
} else if pad_state.video_info.is_some() {
|
||||||
let stop = pts.zip(duration).map(|(pts, duration)| pts + duration);
|
let stop = pts.opt_add(duration);
|
||||||
segment.clip(pts, stop).map(|(start, stop)| {
|
segment.clip(pts, stop).map(|(start, stop)| {
|
||||||
{
|
{
|
||||||
let buffer = buffer.make_mut();
|
let buffer = buffer.make_mut();
|
||||||
buffer.set_pts(start);
|
buffer.set_pts(start);
|
||||||
if duration.is_some() {
|
if duration.is_some() {
|
||||||
buffer.set_duration(
|
buffer.set_duration(stop.opt_checked_sub(start).ok().flatten());
|
||||||
stop.zip(start)
|
|
||||||
.and_then(|(stop, start)| stop.checked_sub(start)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,7 @@ impl HandleData for (gst::ClockTime, Option<gst::ClockTime>) {
|
||||||
|
|
||||||
segment.clip(self.0, stop).map(|(start, stop)| {
|
segment.clip(self.0, stop).map(|(start, stop)| {
|
||||||
let start = start.expect("provided a defined value");
|
let start = start.expect("provided a defined value");
|
||||||
(start, stop.map(|stop| stop - start))
|
(start, stop.opt_sub(start))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,9 +306,7 @@ impl HandleData for gst::Buffer {
|
||||||
let buffer = self.make_mut();
|
let buffer = self.make_mut();
|
||||||
buffer.set_pts(start);
|
buffer.set_pts(start);
|
||||||
buffer.set_duration(
|
buffer.set_duration(
|
||||||
stop.zip(start)
|
stop.opt_checked_sub(start).ok().flatten(), // FIXME we could expect here
|
||||||
.and_then(|(stop, start)| stop.checked_sub(start)),
|
|
||||||
// FIXME we could expect here
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,7 +368,6 @@ impl ToggleRecord {
|
||||||
};
|
};
|
||||||
|
|
||||||
// This will only do anything for non-raw data
|
// This will only do anything for non-raw data
|
||||||
// FIXME comment why we can unwrap
|
|
||||||
dts_or_pts = state.in_segment.start().unwrap().max(dts_or_pts);
|
dts_or_pts = state.in_segment.start().unwrap().max(dts_or_pts);
|
||||||
dts_or_pts_end = state.in_segment.start().unwrap().max(dts_or_pts_end);
|
dts_or_pts_end = state.in_segment.start().unwrap().max(dts_or_pts_end);
|
||||||
if let Some(stop) = state.in_segment.stop() {
|
if let Some(stop) = state.in_segment.stop() {
|
||||||
|
@ -380,13 +377,12 @@ impl ToggleRecord {
|
||||||
|
|
||||||
let current_running_time = state.in_segment.to_running_time(dts_or_pts);
|
let current_running_time = state.in_segment.to_running_time(dts_or_pts);
|
||||||
let current_running_time_end = state.in_segment.to_running_time(dts_or_pts_end);
|
let current_running_time_end = state.in_segment.to_running_time(dts_or_pts_end);
|
||||||
|
|
||||||
state.current_running_time = current_running_time
|
state.current_running_time = current_running_time
|
||||||
.zip(state.current_running_time)
|
.opt_max(state.current_running_time)
|
||||||
.map(|(cur_rt, state_rt)| cur_rt.max(state_rt))
|
|
||||||
.or(current_running_time);
|
.or(current_running_time);
|
||||||
state.current_running_time_end = current_running_time_end
|
state.current_running_time_end = current_running_time_end
|
||||||
.zip(state.current_running_time_end)
|
.opt_max(state.current_running_time_end)
|
||||||
.map(|(cur_rt_end, state_rt_end)| cur_rt_end.max(state_rt_end))
|
|
||||||
.or(current_running_time_end);
|
.or(current_running_time_end);
|
||||||
|
|
||||||
// FIXME we should probably return if either current_running_time or current_running_time_end
|
// FIXME we should probably return if either current_running_time or current_running_time_end
|
||||||
|
@ -455,8 +451,9 @@ impl ToggleRecord {
|
||||||
rec_state.last_recording_stop = current_running_time;
|
rec_state.last_recording_stop = current_running_time;
|
||||||
let last_recording_duration = rec_state
|
let last_recording_duration = rec_state
|
||||||
.last_recording_stop
|
.last_recording_stop
|
||||||
.zip(rec_state.last_recording_start)
|
.opt_checked_sub(rec_state.last_recording_start)
|
||||||
.and_then(|(stop, start)| stop.checked_sub(start));
|
.ok()
|
||||||
|
.flatten();
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj: pad,
|
||||||
|
@ -477,8 +474,8 @@ impl ToggleRecord {
|
||||||
let s = s.state.lock();
|
let s = s.state.lock();
|
||||||
s.eos
|
s.eos
|
||||||
|| s.current_running_time
|
|| s.current_running_time
|
||||||
.zip(current_running_time)
|
.opt_ge(current_running_time)
|
||||||
.map_or(false, |(s_cur_rt, cur_rt)| s_cur_rt >= cur_rt)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
gst_log!(CAT, obj: pad, "Waiting for other streams to stop");
|
gst_log!(CAT, obj: pad, "Waiting for other streams to stop");
|
||||||
|
@ -570,8 +567,8 @@ impl ToggleRecord {
|
||||||
let s = s.state.lock();
|
let s = s.state.lock();
|
||||||
s.eos
|
s.eos
|
||||||
|| s.current_running_time
|
|| s.current_running_time
|
||||||
.zip(current_running_time)
|
.opt_ge(current_running_time)
|
||||||
.map_or(false, |(s_cur_rt, cur_rt)| s_cur_rt >= cur_rt)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
gst_log!(CAT, obj: pad, "Waiting for other streams to start");
|
gst_log!(CAT, obj: pad, "Waiting for other streams to start");
|
||||||
|
@ -649,7 +646,6 @@ impl ToggleRecord {
|
||||||
};
|
};
|
||||||
|
|
||||||
// This will only do anything for non-raw data
|
// This will only do anything for non-raw data
|
||||||
// FIXME comment why we can unwrap
|
|
||||||
pts = state.in_segment.start().unwrap().max(pts);
|
pts = state.in_segment.start().unwrap().max(pts);
|
||||||
pts_end = state.in_segment.start().unwrap().max(pts_end);
|
pts_end = state.in_segment.start().unwrap().max(pts_end);
|
||||||
if let Some(stop) = state.in_segment.stop() {
|
if let Some(stop) = state.in_segment.stop() {
|
||||||
|
@ -660,12 +656,10 @@ impl ToggleRecord {
|
||||||
let current_running_time = state.in_segment.to_running_time(pts);
|
let current_running_time = state.in_segment.to_running_time(pts);
|
||||||
let current_running_time_end = state.in_segment.to_running_time(pts_end);
|
let current_running_time_end = state.in_segment.to_running_time(pts_end);
|
||||||
state.current_running_time = current_running_time
|
state.current_running_time = current_running_time
|
||||||
.zip(state.current_running_time)
|
.opt_max(state.current_running_time)
|
||||||
.map(|(cur_rt, state_rt)| cur_rt.max(state_rt))
|
|
||||||
.or(current_running_time);
|
.or(current_running_time);
|
||||||
state.current_running_time_end = current_running_time_end
|
state.current_running_time_end = current_running_time_end
|
||||||
.zip(state.current_running_time_end)
|
.opt_max(state.current_running_time_end)
|
||||||
.map(|(cur_rt_end, state_rt_end)| cur_rt_end.max(state_rt_end))
|
|
||||||
.or(current_running_time_end);
|
.or(current_running_time_end);
|
||||||
|
|
||||||
gst_log!(
|
gst_log!(
|
||||||
|
@ -703,18 +697,20 @@ impl ToggleRecord {
|
||||||
&& rec_state.recording_state != RecordingState::Stopping
|
&& rec_state.recording_state != RecordingState::Stopping
|
||||||
&& main_state
|
&& main_state
|
||||||
.current_running_time_end
|
.current_running_time_end
|
||||||
.zip(current_running_time_end)
|
.opt_lt(current_running_time_end)
|
||||||
.map_or(false, |(main_rt_end, cur_rt_end)| main_rt_end < cur_rt_end)
|
.unwrap_or(false)
|
||||||
|| rec_state.recording_state == RecordingState::Starting
|
|| rec_state.recording_state == RecordingState::Starting
|
||||||
&& rec_state
|
&& (rec_state.last_recording_start.is_none()
|
||||||
.last_recording_start
|
|| rec_state
|
||||||
.map_or(true, |last_rec_start| {
|
.last_recording_start
|
||||||
current_running_time.map_or(false, |cur_rt| last_rec_start <= cur_rt)
|
.opt_le(current_running_time)
|
||||||
})
|
.unwrap_or(false))
|
||||||
|| rec_state.recording_state == RecordingState::Stopping
|
|| rec_state.recording_state == RecordingState::Stopping
|
||||||
&& rec_state.last_recording_stop.map_or(true, |last_rec_stop| {
|
&& (rec_state.last_recording_stop.is_none()
|
||||||
current_running_time.map_or(false, |cur_rt| last_rec_stop <= cur_rt)
|
|| rec_state
|
||||||
}))
|
.last_recording_stop
|
||||||
|
.opt_le(current_running_time)
|
||||||
|
.unwrap_or(false)))
|
||||||
&& !main_state.eos
|
&& !main_state.eos
|
||||||
&& !state.flushing
|
&& !state.flushing
|
||||||
{
|
{
|
||||||
|
@ -800,7 +796,10 @@ impl ToggleRecord {
|
||||||
gst_warning!(CAT, obj: pad, "Complete buffer clipped!");
|
gst_warning!(CAT, obj: pad, "Complete buffer clipped!");
|
||||||
return Ok(HandleResult::Drop);
|
return Ok(HandleResult::Drop);
|
||||||
}
|
}
|
||||||
} else if current_running_time.map_or(false, |cur_rt| cur_rt < last_recording_start) {
|
} else if current_running_time
|
||||||
|
.opt_lt(last_recording_start)
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
// Otherwise if the buffer starts before the recording start, drop it. This
|
// Otherwise if the buffer starts before the recording start, drop it. This
|
||||||
// means that we either can't clip, or that the end is also before the
|
// means that we either can't clip, or that the end is also before the
|
||||||
// recording start
|
// recording start
|
||||||
|
@ -814,13 +813,11 @@ impl ToggleRecord {
|
||||||
return Ok(HandleResult::Drop);
|
return Ok(HandleResult::Drop);
|
||||||
} else if data.can_clip(&*state)
|
} else if data.can_clip(&*state)
|
||||||
&& current_running_time
|
&& current_running_time
|
||||||
.zip(rec_state.last_recording_stop)
|
.opt_lt(rec_state.last_recording_stop)
|
||||||
.map_or(false, |(cur_rt, last_rec_stop)| cur_rt < last_rec_stop)
|
.unwrap_or(false)
|
||||||
&& current_running_time_end
|
&& current_running_time_end
|
||||||
.zip(rec_state.last_recording_stop)
|
.opt_gt(rec_state.last_recording_stop)
|
||||||
.map_or(false, |(cur_rt_end, last_rec_stop)| {
|
.unwrap_or(false)
|
||||||
cur_rt_end > last_rec_stop
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
// Similarly if the end is after the recording stop but the start is before and we
|
// Similarly if the end is after the recording stop but the start is before and we
|
||||||
// can clip, clip the buffer and pass it through.
|
// can clip, clip the buffer and pass it through.
|
||||||
|
@ -863,10 +860,8 @@ impl ToggleRecord {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
} else if current_running_time_end
|
} else if current_running_time_end
|
||||||
.zip(rec_state.last_recording_stop)
|
.opt_gt(rec_state.last_recording_stop)
|
||||||
.map_or(false, |(cur_rt_end, last_rec_stop)| {
|
.unwrap_or(false)
|
||||||
cur_rt_end > last_rec_stop
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
// Otherwise if the end of the buffer is after the recording stop, we're EOS
|
// Otherwise if the end of the buffer is after the recording stop, we're EOS
|
||||||
// now. This means that we either couldn't clip or that the start is also after
|
// now. This means that we either couldn't clip or that the start is also after
|
||||||
|
@ -887,11 +882,12 @@ impl ToggleRecord {
|
||||||
} else {
|
} else {
|
||||||
// In all other cases the buffer is fully between recording start and end and
|
// In all other cases the buffer is fully between recording start and end and
|
||||||
// can be passed through as is
|
// can be passed through as is
|
||||||
assert!(current_running_time.map_or(false, |cur_rt| cur_rt >= last_recording_start));
|
assert!(current_running_time
|
||||||
|
.opt_ge(last_recording_start)
|
||||||
|
.unwrap_or(false));
|
||||||
assert!(current_running_time_end
|
assert!(current_running_time_end
|
||||||
.zip(rec_state.last_recording_stop)
|
.opt_le(rec_state.last_recording_stop)
|
||||||
.map_or(false, |(cur_rt_end, last_rec_stop)| cur_rt_end
|
.unwrap_or(false));
|
||||||
<= last_rec_stop));
|
|
||||||
|
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
CAT,
|
CAT,
|
||||||
|
@ -910,15 +906,14 @@ impl ToggleRecord {
|
||||||
// The end of our buffer must be before/at the end of the previous buffer of the main
|
// The end of our buffer must be before/at the end of the previous buffer of the main
|
||||||
// stream
|
// stream
|
||||||
assert!(current_running_time_end
|
assert!(current_running_time_end
|
||||||
.zip(main_state.current_running_time_end)
|
.opt_le(main_state.current_running_time_end)
|
||||||
.map_or(false, |(cur_rt_end, main_cur_rt_end)| cur_rt_end
|
.unwrap_or(false));
|
||||||
<= main_cur_rt_end));
|
|
||||||
|
|
||||||
// We're properly started, must have a start position and
|
// We're properly started, must have a start position and
|
||||||
// be actually after that start position
|
// be actually after that start position
|
||||||
assert!(current_running_time
|
assert!(current_running_time
|
||||||
.zip(rec_state.last_recording_start)
|
.opt_ge(rec_state.last_recording_start)
|
||||||
.map_or(false, |(cur_rt, last_rec_start)| cur_rt >= last_rec_start));
|
.unwrap_or(false));
|
||||||
gst_log!(CAT, obj: pad, "Passing buffer (recording)");
|
gst_log!(CAT, obj: pad, "Passing buffer (recording)");
|
||||||
Ok(HandleResult::Pass(data))
|
Ok(HandleResult::Pass(data))
|
||||||
}
|
}
|
||||||
|
@ -998,9 +993,8 @@ impl ToggleRecord {
|
||||||
// The end of our buffer must be before/at the end of the previous buffer of the main
|
// The end of our buffer must be before/at the end of the previous buffer of the main
|
||||||
// stream
|
// stream
|
||||||
assert!(current_running_time_end
|
assert!(current_running_time_end
|
||||||
.zip(main_state.current_running_time_end)
|
.opt_le(main_state.current_running_time_end)
|
||||||
.map_or(false, |(cur_rt_end, state_rt_end)| cur_rt_end
|
.unwrap_or(false));
|
||||||
<= state_rt_end));
|
|
||||||
|
|
||||||
// We're properly stopped
|
// We're properly stopped
|
||||||
gst_log!(CAT, obj: pad, "Dropping buffer (stopped)");
|
gst_log!(CAT, obj: pad, "Dropping buffer (stopped)");
|
||||||
|
@ -1357,11 +1351,7 @@ impl ToggleRecord {
|
||||||
|
|
||||||
forward = match handle_result {
|
forward = match handle_result {
|
||||||
Ok(HandleResult::Pass((new_pts, new_duration))) => {
|
Ok(HandleResult::Pass((new_pts, new_duration))) => {
|
||||||
if new_pts != pts
|
if new_pts != pts || new_duration.is_some() && new_duration != duration {
|
||||||
|| new_duration
|
|
||||||
.zip(duration)
|
|
||||||
.map_or(false, |(new_duration, duration)| new_duration != duration)
|
|
||||||
{
|
|
||||||
event = gst::event::Gap::builder(new_pts)
|
event = gst::event::Gap::builder(new_pts)
|
||||||
.duration(new_duration)
|
.duration(new_duration)
|
||||||
.build();
|
.build();
|
||||||
|
@ -1587,10 +1577,9 @@ impl ToggleRecord {
|
||||||
{
|
{
|
||||||
if let Some(delta) = state
|
if let Some(delta) = state
|
||||||
.current_running_time_end
|
.current_running_time_end
|
||||||
.zip(rec_state.last_recording_start)
|
.opt_checked_sub(rec_state.last_recording_start)
|
||||||
.and_then(|(cur_rt_end, last_rec_start)| {
|
.ok()
|
||||||
cur_rt_end.checked_sub(last_rec_start)
|
.flatten()
|
||||||
})
|
|
||||||
{
|
{
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
CAT,
|
CAT,
|
||||||
|
@ -1622,10 +1611,9 @@ impl ToggleRecord {
|
||||||
{
|
{
|
||||||
if let Some(delta) = state
|
if let Some(delta) = state
|
||||||
.current_running_time_end
|
.current_running_time_end
|
||||||
.zip(rec_state.last_recording_start)
|
.opt_checked_sub(rec_state.last_recording_start)
|
||||||
.and_then(|(cur_rt_end, last_rec_start)| {
|
.ok()
|
||||||
cur_rt_end.checked_sub(last_rec_start)
|
.flatten()
|
||||||
})
|
|
||||||
{
|
{
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
CAT,
|
CAT,
|
||||||
|
|
|
@ -400,9 +400,7 @@ fn dump(
|
||||||
duration: impl Into<Option<gst::ClockTime>>,
|
duration: impl Into<Option<gst::ClockTime>>,
|
||||||
) {
|
) {
|
||||||
let pts = pts.into();
|
let pts = pts.into();
|
||||||
let end = pts
|
let end = pts.opt_add(duration.into());
|
||||||
.zip(duration.into())
|
|
||||||
.map(|(pts, duration)| pts + duration);
|
|
||||||
|
|
||||||
if cc_data != 0x8080 {
|
if cc_data != 0x8080 {
|
||||||
gst_debug!(
|
gst_debug!(
|
||||||
|
@ -478,10 +476,10 @@ impl State {
|
||||||
Some(Cea608Mode::PopOn) => gst::ClockTime::NONE,
|
Some(Cea608Mode::PopOn) => gst::ClockTime::NONE,
|
||||||
_ => self
|
_ => self
|
||||||
.current_pts
|
.current_pts
|
||||||
.zip(self.current_duration)
|
.opt_add(self.current_duration)
|
||||||
.map(|(cur_pts, cur_duration)| cur_pts + cur_duration)
|
.opt_checked_sub(self.first_pts)
|
||||||
.zip(self.first_pts)
|
.ok()
|
||||||
.and_then(|(cur_end, first_pts)| cur_end.checked_sub(first_pts)),
|
.flatten(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -541,10 +539,10 @@ impl State {
|
||||||
gst_log!(CAT, obj: element, "Draining pending");
|
gst_log!(CAT, obj: element, "Draining pending");
|
||||||
pending.duration = self
|
pending.duration = self
|
||||||
.current_pts
|
.current_pts
|
||||||
.zip(self.current_duration)
|
.opt_add(self.current_duration)
|
||||||
.map(|(cur_pts, cur_dur)| cur_pts + cur_dur)
|
.opt_checked_sub(pending.pts)
|
||||||
.zip(pending.pts)
|
.ok()
|
||||||
.and_then(|(cur_end, pending_pts)| cur_end.checked_sub(pending_pts));
|
.flatten();
|
||||||
Some(pending)
|
Some(pending)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -68,7 +68,7 @@ fn clamp(
|
||||||
mut pts: gst::ClockTime,
|
mut pts: gst::ClockTime,
|
||||||
mut duration: Option<gst::ClockTime>,
|
mut duration: Option<gst::ClockTime>,
|
||||||
) -> Option<(gst::ClockTime, Option<gst::ClockTime>)> {
|
) -> Option<(gst::ClockTime, Option<gst::ClockTime>)> {
|
||||||
let end_pts = duration.map(|duration| pts + duration).unwrap_or(pts);
|
let end_pts = pts.opt_add(duration).unwrap_or(pts);
|
||||||
|
|
||||||
if let Some(segment_start) = segment.start() {
|
if let Some(segment_start) = segment.start() {
|
||||||
if end_pts < segment_start {
|
if end_pts < segment_start {
|
||||||
|
@ -76,9 +76,7 @@ fn clamp(
|
||||||
}
|
}
|
||||||
|
|
||||||
if pts < segment_start {
|
if pts < segment_start {
|
||||||
if let Some(ref mut duration) = duration {
|
duration.opt_sub_assign(segment_start - pts);
|
||||||
*duration = duration.saturating_sub(segment_start - pts);
|
|
||||||
}
|
|
||||||
pts = segment_start;
|
pts = segment_start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,9 +87,7 @@ fn clamp(
|
||||||
}
|
}
|
||||||
|
|
||||||
if end_pts > segment_stop {
|
if end_pts > segment_stop {
|
||||||
if let Some(ref mut duration) = duration {
|
duration.opt_sub_assign(end_pts - segment_stop);
|
||||||
*duration = duration.saturating_sub(end_pts - segment_stop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,10 +318,7 @@ impl State {
|
||||||
|
|
||||||
self.drain(&mut ret, self.segment.to_running_time(pts));
|
self.drain(&mut ret, self.segment.to_running_time(pts));
|
||||||
|
|
||||||
self.last_pts = Some(pts)
|
self.last_pts = Some(pts).opt_add(duration).or(Some(pts));
|
||||||
.zip(duration)
|
|
||||||
.map(|(pts, duration)| pts + duration)
|
|
||||||
.or(Some(pts));
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
|
@ -1015,17 +1015,11 @@ impl MccParse {
|
||||||
let pull = state.pull.as_ref().unwrap();
|
let pull = state.pull.as_ref().unwrap();
|
||||||
|
|
||||||
if start_type == gst::SeekType::Set {
|
if start_type == gst::SeekType::Set {
|
||||||
start = start
|
start = start.opt_min(pull.duration).or(start);
|
||||||
.zip(pull.duration)
|
|
||||||
.map(|(start, duration)| start.min(duration))
|
|
||||||
.or(start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if stop_type == gst::SeekType::Set {
|
if stop_type == gst::SeekType::Set {
|
||||||
stop = stop
|
stop = stop.opt_min(pull.duration).or(stop);
|
||||||
.zip(pull.duration)
|
|
||||||
.map(|(stop, duration)| stop.min(duration))
|
|
||||||
.or(stop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.seeking = true;
|
state.seeking = true;
|
||||||
|
|
|
@ -429,14 +429,8 @@ impl SccParse {
|
||||||
timecode.increment_frame();
|
timecode.increment_frame();
|
||||||
|
|
||||||
if clip_buffers {
|
if clip_buffers {
|
||||||
let end_time = buffer
|
let end_time = buffer.pts().opt_add(buffer.duration());
|
||||||
.pts()
|
if end_time.opt_lt(segment_start).unwrap_or(false) {
|
||||||
.zip(buffer.duration())
|
|
||||||
.map(|(pts, duration)| pts + duration);
|
|
||||||
if end_time
|
|
||||||
.zip(segment_start)
|
|
||||||
.map_or(false, |(end_time, segment_start)| end_time < segment_start)
|
|
||||||
{
|
|
||||||
gst_trace!(
|
gst_trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj: element,
|
||||||
|
@ -448,12 +442,11 @@ impl SccParse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send_eos = state.segment.stop().map_or(false, |stop| {
|
send_eos = buffer
|
||||||
buffer
|
.pts()
|
||||||
.pts()
|
.opt_add(buffer.duration())
|
||||||
.zip(buffer.duration())
|
.opt_ge(state.segment.stop())
|
||||||
.map_or(false, |(pts, duration)| pts + duration >= stop)
|
.unwrap_or(false);
|
||||||
});
|
|
||||||
|
|
||||||
let buffers = buffers.get_mut().unwrap();
|
let buffers = buffers.get_mut().unwrap();
|
||||||
buffers.add(buffer);
|
buffers.add(buffer);
|
||||||
|
@ -899,17 +892,11 @@ impl SccParse {
|
||||||
let pull = state.pull.as_ref().unwrap();
|
let pull = state.pull.as_ref().unwrap();
|
||||||
|
|
||||||
if start_type == gst::SeekType::Set {
|
if start_type == gst::SeekType::Set {
|
||||||
start = start
|
start = start.opt_min(pull.duration).or(start);
|
||||||
.zip(pull.duration)
|
|
||||||
.map(|(start, duration)| start.min(duration))
|
|
||||||
.or(start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if stop_type == gst::SeekType::Set {
|
if stop_type == gst::SeekType::Set {
|
||||||
stop = stop
|
stop = stop.opt_min(pull.duration).or(stop);
|
||||||
.zip(pull.duration)
|
|
||||||
.map(|(stop, duration)| stop.min(duration))
|
|
||||||
.or(stop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state.seeking = true;
|
state.seeking = true;
|
||||||
|
|
|
@ -1198,15 +1198,9 @@ impl StreamingState {
|
||||||
|
|
||||||
fn update_position(&mut self, buffer: &gst::Buffer) {
|
fn update_position(&mut self, buffer: &gst::Buffer) {
|
||||||
if let Some(pts) = buffer.pts() {
|
if let Some(pts) = buffer.pts() {
|
||||||
self.last_position = self
|
self.last_position = self.last_position.opt_max(pts).or(Some(pts));
|
||||||
.last_position
|
|
||||||
.map(|last_pos| last_pos.max(pts))
|
|
||||||
.or(Some(pts));
|
|
||||||
} else if let Some(dts) = buffer.dts() {
|
} else if let Some(dts) = buffer.dts() {
|
||||||
self.last_position = self
|
self.last_position = self.last_position.opt_max(dts).or(Some(dts));
|
||||||
.last_position
|
|
||||||
.map(|last_pos| last_pos.max(dts))
|
|
||||||
.or(Some(dts));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -401,9 +401,9 @@ impl VideoEncoderImpl for GifEnc {
|
||||||
// is probably less visible than the large stuttering when a complete 10ms have to
|
// is probably less visible than the large stuttering when a complete 10ms have to
|
||||||
// "catch up".
|
// "catch up".
|
||||||
gif_frame.delay = (frame_delay.mseconds() as f32 / 10.0).round() as u16;
|
gif_frame.delay = (frame_delay.mseconds() as f32 / 10.0).round() as u16;
|
||||||
state.gif_pts = state.gif_pts.map(|gif_pts| {
|
state.gif_pts = state
|
||||||
gif_pts + gst::ClockTime::from_mseconds(gif_frame.delay as u64 * 10)
|
.gif_pts
|
||||||
});
|
.opt_add(gst::ClockTime::from_mseconds(gif_frame.delay as u64 * 10));
|
||||||
|
|
||||||
// encode new frame
|
// encode new frame
|
||||||
let context = state.context.as_mut().unwrap();
|
let context = state.context.as_mut().unwrap();
|
||||||
|
|
|
@ -48,9 +48,7 @@ fn test_decode() {
|
||||||
assert_eq!(buf.pts(), expected_timestamp);
|
assert_eq!(buf.pts(), expected_timestamp);
|
||||||
assert_eq!(buf.duration(), expected_duration);
|
assert_eq!(buf.duration(), expected_duration);
|
||||||
|
|
||||||
expected_timestamp = expected_timestamp
|
expected_timestamp = expected_timestamp.opt_add(expected_duration);
|
||||||
.zip(expected_duration)
|
|
||||||
.map(|(ts, duration)| ts + duration);
|
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue