mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-25 04:51:26 +00:00
Update for new debug log macro syntax
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1658>
This commit is contained in:
parent
f88f5b03c4
commit
98b28d69ce
156 changed files with 4513 additions and 3278 deletions
|
@ -263,7 +263,7 @@ impl State {
|
||||||
|
|
||||||
// Drains everything
|
// Drains everything
|
||||||
fn drain(&mut self, imp: &AudioLoudNorm) -> Result<gst::Buffer, gst::FlowError> {
|
fn drain(&mut self, imp: &AudioLoudNorm) -> Result<gst::Buffer, gst::FlowError> {
|
||||||
gst::debug!(CAT, imp: imp, "Draining");
|
gst::debug!(CAT, imp = imp, "Draining");
|
||||||
|
|
||||||
let (pts, distance) = self.adapter.prev_pts();
|
let (pts, distance) = self.adapter.prev_pts();
|
||||||
let distance_samples = distance / self.info.bpf() as u64;
|
let distance_samples = distance / self.info.bpf() as u64;
|
||||||
|
@ -298,7 +298,7 @@ impl State {
|
||||||
self.frame_type = FrameType::Final;
|
self.frame_type = FrameType::Final;
|
||||||
} else if src.is_empty() {
|
} else if src.is_empty() {
|
||||||
// Nothing to drain at all
|
// Nothing to drain at all
|
||||||
gst::debug!(CAT, imp: imp, "No data to drain");
|
gst::debug!(CAT, imp = imp, "No data to drain");
|
||||||
return Err(gst::FlowError::Eos);
|
return Err(gst::FlowError::Eos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Calculated global loudness for first frame {} with peak {}",
|
"Calculated global loudness for first frame {} with peak {}",
|
||||||
global,
|
global,
|
||||||
true_peak
|
true_peak
|
||||||
|
@ -395,7 +395,7 @@ impl State {
|
||||||
self.prev_delta = self.delta[self.index];
|
self.prev_delta = self.delta[self.index];
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Initializing for first frame with gain adjustment of {}",
|
"Initializing for first frame with gain adjustment of {}",
|
||||||
self.prev_delta
|
self.prev_delta
|
||||||
);
|
);
|
||||||
|
@ -457,7 +457,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Applying gain adjustment {}-{}",
|
"Applying gain adjustment {}-{}",
|
||||||
gain,
|
gain,
|
||||||
gain_next
|
gain_next
|
||||||
|
@ -531,7 +531,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Calculated global loudness {}, short term loudness {} and relative threshold {}",
|
"Calculated global loudness {}, short term loudness {} and relative threshold {}",
|
||||||
global,
|
global,
|
||||||
shortterm,
|
shortterm,
|
||||||
|
@ -554,7 +554,7 @@ impl State {
|
||||||
self.above_threshold = true;
|
self.above_threshold = true;
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Above threshold now ({} >= {}, {} > -70)",
|
"Above threshold now ({} >= {}, {} > -70)",
|
||||||
shortterm_out,
|
shortterm_out,
|
||||||
self.target_i,
|
self.target_i,
|
||||||
|
@ -582,7 +582,7 @@ impl State {
|
||||||
self.prev_delta = self.delta[self.index];
|
self.prev_delta = self.delta[self.index];
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Calculated new gain adjustment {}",
|
"Calculated new gain adjustment {}",
|
||||||
self.prev_delta
|
self.prev_delta
|
||||||
);
|
);
|
||||||
|
@ -776,7 +776,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Applying linear gain adjustment of {}",
|
"Applying linear gain adjustment of {}",
|
||||||
self.offset
|
self.offset
|
||||||
);
|
);
|
||||||
|
@ -855,7 +855,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Found peak {} at sample {}, going to attack state at sample {} (gain reduction {}-{})",
|
"Found peak {} at sample {}, going to attack state at sample {} (gain reduction {}-{})",
|
||||||
peak_value,
|
peak_value,
|
||||||
smp_cnt + LIMITER_ATTACK_WINDOW,
|
smp_cnt + LIMITER_ATTACK_WINDOW,
|
||||||
|
@ -992,7 +992,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Found new peak {} at sample {}, restarting attack state at sample {} (gain reduction {}-{})",
|
"Found new peak {} at sample {}, restarting attack state at sample {} (gain reduction {}-{})",
|
||||||
peak_value,
|
peak_value,
|
||||||
smp_cnt + LIMITER_ATTACK_WINDOW,
|
smp_cnt + LIMITER_ATTACK_WINDOW,
|
||||||
|
@ -1041,7 +1041,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Found new peak {} at sample {}, adjusting attack state at sample {} (gain reduction {}-{})",
|
"Found new peak {} at sample {}, adjusting attack state at sample {} (gain reduction {}-{})",
|
||||||
peak_value,
|
peak_value,
|
||||||
smp_cnt + LIMITER_ATTACK_WINDOW,
|
smp_cnt + LIMITER_ATTACK_WINDOW,
|
||||||
|
@ -1056,7 +1056,7 @@ impl State {
|
||||||
// to ensure that we at least sustain it for that long afterwards.
|
// to ensure that we at least sustain it for that long afterwards.
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Found new low peak {} at sample {} in attack state at sample {}",
|
"Found new low peak {} at sample {} in attack state at sample {}",
|
||||||
peak_value,
|
peak_value,
|
||||||
smp_cnt + LIMITER_ATTACK_WINDOW,
|
smp_cnt + LIMITER_ATTACK_WINDOW,
|
||||||
|
@ -1072,7 +1072,7 @@ impl State {
|
||||||
// If we reached the target gain reduction, go into sustain state.
|
// If we reached the target gain reduction, go into sustain state.
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Going to sustain state at sample {} (gain reduction {})",
|
"Going to sustain state at sample {} (gain reduction {})",
|
||||||
smp_cnt,
|
smp_cnt,
|
||||||
self.gain_reduction[1]
|
self.gain_reduction[1]
|
||||||
|
@ -1151,7 +1151,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Found new peak {} at sample {}, going back to attack state at sample {} (gain reduction {}-{})",
|
"Found new peak {} at sample {}, going back to attack state at sample {} (gain reduction {}-{})",
|
||||||
peak_value,
|
peak_value,
|
||||||
smp_cnt + LIMITER_ATTACK_WINDOW,
|
smp_cnt + LIMITER_ATTACK_WINDOW,
|
||||||
|
@ -1162,7 +1162,7 @@ impl State {
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Found new peak {} at sample {}, going sustain further at sample {} (gain reduction {})",
|
"Found new peak {} at sample {}, going sustain further at sample {} (gain reduction {})",
|
||||||
peak_value,
|
peak_value,
|
||||||
smp_cnt + LIMITER_ATTACK_WINDOW,
|
smp_cnt + LIMITER_ATTACK_WINDOW,
|
||||||
|
@ -1189,7 +1189,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Going to release state for sample {} at sample {} (gain reduction {}-1.0)",
|
"Going to release state for sample {} at sample {} (gain reduction {}-1.0)",
|
||||||
smp_cnt + LIMITER_RELEASE_WINDOW,
|
smp_cnt + LIMITER_RELEASE_WINDOW,
|
||||||
smp_cnt,
|
smp_cnt,
|
||||||
|
@ -1259,7 +1259,7 @@ impl State {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Found new peak {} at sample {}, going back to attack state at sample {} (gain reduction {}-{})",
|
"Found new peak {} at sample {}, going back to attack state at sample {} (gain reduction {}-{})",
|
||||||
peak_value,
|
peak_value,
|
||||||
smp_cnt + LIMITER_ATTACK_WINDOW,
|
smp_cnt + LIMITER_ATTACK_WINDOW,
|
||||||
|
@ -1271,7 +1271,7 @@ impl State {
|
||||||
self.gain_reduction[1] = current_gain_reduction;
|
self.gain_reduction[1] = current_gain_reduction;
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Going from release to sustain state at sample {} because of low peak {} at sample {} (gain reduction {})",
|
"Going from release to sustain state at sample {} because of low peak {} at sample {} (gain reduction {})",
|
||||||
smp_cnt,
|
smp_cnt,
|
||||||
peak_value,
|
peak_value,
|
||||||
|
@ -1312,7 +1312,7 @@ impl State {
|
||||||
self.limiter_state = LimiterState::Out;
|
self.limiter_state = LimiterState::Out;
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Leaving release state and going to out state at sample {}",
|
"Leaving release state and going to out state at sample {}",
|
||||||
smp_cnt,
|
smp_cnt,
|
||||||
);
|
);
|
||||||
|
@ -1350,7 +1350,7 @@ impl State {
|
||||||
self.gain_reduction[1] = self.target_tp / max;
|
self.gain_reduction[1] = self.target_tp / max;
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Reducing gain for start of first frame by {} ({} > {}) and going to sustain state",
|
"Reducing gain for start of first frame by {} ({} > {}) and going to sustain state",
|
||||||
self.gain_reduction[1],
|
self.gain_reduction[1],
|
||||||
max,
|
max,
|
||||||
|
@ -1366,7 +1366,7 @@ impl State {
|
||||||
let channels = self.info.channels() as usize;
|
let channels = self.info.channels() as usize;
|
||||||
let nb_samples = dst.len() / channels;
|
let nb_samples = dst.len() / channels;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: imp, "Running limiter for {} samples", nb_samples);
|
gst::debug!(CAT, imp = imp, "Running limiter for {} samples", nb_samples);
|
||||||
|
|
||||||
// For the first frame we can't adjust the gain before it smoothly anymore so instead
|
// For the first frame we can't adjust the gain before it smoothly anymore so instead
|
||||||
// apply the gain reduction immediately if we get above the threshold and move to sustain
|
// apply the gain reduction immediately if we get above the threshold and move to sustain
|
||||||
|
@ -1535,12 +1535,12 @@ impl AudioLoudNorm {
|
||||||
_pad: &gst::Pad,
|
_pad: &gst::Pad,
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(CAT, imp: self, "Handling buffer {:?}", buffer);
|
gst::log!(CAT, imp = self, "Handling buffer {:?}", buffer);
|
||||||
|
|
||||||
let mut state_guard = self.state.borrow_mut();
|
let mut state_guard = self.state.borrow_mut();
|
||||||
let state = match *state_guard {
|
let state = match *state_guard {
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, imp: self, "Not negotiated yet");
|
gst::error!(CAT, imp = self, "Not negotiated yet");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
Some(ref mut state) => state,
|
Some(ref mut state) => state,
|
||||||
|
@ -1548,7 +1548,7 @@ impl AudioLoudNorm {
|
||||||
|
|
||||||
let mut outbufs = vec![];
|
let mut outbufs = vec![];
|
||||||
if buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
if buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
||||||
gst::debug!(CAT, imp: self, "Draining on discontinuity");
|
gst::debug!(CAT, imp = self, "Draining on discontinuity");
|
||||||
match state.drain(self) {
|
match state.drain(self) {
|
||||||
Ok(outbuf) => {
|
Ok(outbuf) => {
|
||||||
outbufs.push(outbuf);
|
outbufs.push(outbuf);
|
||||||
|
@ -1566,7 +1566,7 @@ impl AudioLoudNorm {
|
||||||
drop(state_guard);
|
drop(state_guard);
|
||||||
|
|
||||||
for buffer in outbufs {
|
for buffer in outbufs {
|
||||||
gst::log!(CAT, imp: self, "Outputting buffer {:?}", buffer);
|
gst::log!(CAT, imp = self, "Outputting buffer {:?}", buffer);
|
||||||
self.srcpad.push(buffer)?;
|
self.srcpad.push(buffer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1576,17 +1576,17 @@ impl AudioLoudNorm {
|
||||||
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling event {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling event {:?}", event);
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Caps(c) => {
|
EventView::Caps(c) => {
|
||||||
let caps = c.caps();
|
let caps = c.caps();
|
||||||
gst::info!(CAT, obj: pad, "Got caps {:?}", caps);
|
gst::info!(CAT, obj = pad, "Got caps {:?}", caps);
|
||||||
|
|
||||||
let info = match gst_audio::AudioInfo::from_caps(caps) {
|
let info = match gst_audio::AudioInfo::from_caps(caps) {
|
||||||
Ok(info) => info,
|
Ok(info) => info,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::error!(CAT, obj: pad, "Failed to parse caps");
|
gst::error!(CAT, obj = pad, "Failed to parse caps");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1604,9 +1604,9 @@ impl AudioLoudNorm {
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
if let Some(outbuf) = outbuf {
|
if let Some(outbuf) = outbuf {
|
||||||
gst::log!(CAT, imp: self, "Outputting buffer {:?}", outbuf);
|
gst::log!(CAT, imp = self, "Outputting buffer {:?}", outbuf);
|
||||||
if let Err(err) = self.srcpad.push(outbuf) {
|
if let Err(err) = self.srcpad.push(outbuf) {
|
||||||
gst::error!(CAT, imp: self, "Failed to push drained data: {}", err);
|
gst::error!(CAT, imp = self, "Failed to push drained data: {}", err);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1626,11 +1626,11 @@ impl AudioLoudNorm {
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
if let Some(outbuf) = outbuf {
|
if let Some(outbuf) = outbuf {
|
||||||
gst::log!(CAT, imp: self, "Outputting buffer {:?}", outbuf);
|
gst::log!(CAT, imp = self, "Outputting buffer {:?}", outbuf);
|
||||||
if let Err(err) = self.srcpad.push(outbuf) {
|
if let Err(err) = self.srcpad.push(outbuf) {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to push drained data on EOS: {}",
|
"Failed to push drained data on EOS: {}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
|
@ -1660,7 +1660,7 @@ impl AudioLoudNorm {
|
||||||
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling query {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling query {:?}", query);
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
QueryViewMut::Latency(q) => {
|
QueryViewMut::Latency(q) => {
|
||||||
let mut peer_query = gst::query::Latency::new();
|
let mut peer_query = gst::query::Latency::new();
|
||||||
|
|
|
@ -113,7 +113,7 @@ impl AudioRNNoise {
|
||||||
|
|
||||||
let settings = *self.settings.lock().unwrap();
|
let settings = *self.settings.lock().unwrap();
|
||||||
let mut buffer = gst::Buffer::with_size(available).map_err(|e| {
|
let mut buffer = gst::Buffer::with_size(available).map_err(|e| {
|
||||||
gst::error!(CAT, imp: self, "Failed to allocate buffer at EOS {:?}", e);
|
gst::error!(CAT, imp = self, "Failed to allocate buffer at EOS {:?}", e);
|
||||||
gst::FlowError::Flushing
|
gst::FlowError::Flushing
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ impl AudioRNNoise {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Voice activity: {}", vad);
|
gst::trace!(CAT, imp = self, "Voice activity: {}", vad);
|
||||||
if vad < settings.vad_threshold {
|
if vad < settings.vad_threshold {
|
||||||
out_frame.fill(0.0);
|
out_frame.fill(0.0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -237,8 +237,9 @@ impl AudioRNNoise {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"rms: {}, level: {}, has_voice : {} ", rms,
|
"rms: {}, level: {}, has_voice : {} ",
|
||||||
|
rms,
|
||||||
level,
|
level,
|
||||||
has_voice
|
has_voice
|
||||||
);
|
);
|
||||||
|
@ -345,7 +346,7 @@ impl BaseTransformImpl for AudioRNNoise {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
if let EventView::Eos(_) = event.view() {
|
if let EventView::Eos(_) = event.view() {
|
||||||
gst::debug!(CAT, imp: self, "Handling EOS");
|
gst::debug!(CAT, imp = self, "Handling EOS");
|
||||||
if self.drain().is_err() {
|
if self.drain().is_err() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -361,7 +362,7 @@ impl BaseTransformImpl for AudioRNNoise {
|
||||||
let (live, mut min, mut max) = upstream_query.result();
|
let (live, mut min, mut max) = upstream_query.result();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Peer latency: live {} min {} max {}",
|
"Peer latency: live {} min {} max {}",
|
||||||
live,
|
live,
|
||||||
min,
|
min,
|
||||||
|
@ -406,7 +407,7 @@ impl AudioFilterImpl for AudioRNNoise {
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Set caps to {:?}", info);
|
gst::debug!(CAT, imp = self, "Set caps to {:?}", info);
|
||||||
|
|
||||||
let mut denoisers = vec![];
|
let mut denoisers = vec![];
|
||||||
for _i in 0..info.channels() {
|
for _i in 0..info.channels() {
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl ObjectImpl for EbuR128Level {
|
||||||
let this = args[0].get::<super::EbuR128Level>().unwrap();
|
let this = args[0].get::<super::EbuR128Level>().unwrap();
|
||||||
let imp = this.imp();
|
let imp = this.imp();
|
||||||
|
|
||||||
gst::info!(CAT, obj: this, "Resetting measurements",);
|
gst::info!(CAT, obj = this, "Resetting measurements",);
|
||||||
imp.reset.store(true, atomic::Ordering::SeqCst);
|
imp.reset.store(true, atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -175,7 +175,7 @@ impl ObjectImpl for EbuR128Level {
|
||||||
let mode = value.get().expect("type checked upstream");
|
let mode = value.get().expect("type checked upstream");
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing mode from {:?} to {:?}",
|
"Changing mode from {:?} to {:?}",
|
||||||
settings.mode,
|
settings.mode,
|
||||||
mode
|
mode
|
||||||
|
@ -186,7 +186,7 @@ impl ObjectImpl for EbuR128Level {
|
||||||
let post_messages = value.get().expect("type checked upstream");
|
let post_messages = value.get().expect("type checked upstream");
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing post-messages from {} to {}",
|
"Changing post-messages from {} to {}",
|
||||||
settings.post_messages,
|
settings.post_messages,
|
||||||
post_messages
|
post_messages
|
||||||
|
@ -197,7 +197,7 @@ impl ObjectImpl for EbuR128Level {
|
||||||
let interval = value.get::<u64>().unwrap().nseconds();
|
let interval = value.get::<u64>().unwrap().nseconds();
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing interval from {} to {}",
|
"Changing interval from {} to {}",
|
||||||
settings.interval,
|
settings.interval,
|
||||||
interval,
|
interval,
|
||||||
|
@ -286,7 +286,7 @@ impl BaseTransformImpl for EbuR128Level {
|
||||||
// Drop state
|
// Drop state
|
||||||
let _ = self.state.borrow_mut().take();
|
let _ = self.state.borrow_mut().take();
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Stopped");
|
gst::info!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -377,7 +377,7 @@ impl BaseTransformImpl for EbuR128Level {
|
||||||
Ok(loudness) => s.set("momentary-loudness", loudness),
|
Ok(loudness) => s.set("momentary-loudness", loudness),
|
||||||
Err(err) => gst::error!(
|
Err(err) => gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to get momentary loudness: {}",
|
"Failed to get momentary loudness: {}",
|
||||||
err
|
err
|
||||||
),
|
),
|
||||||
|
@ -389,7 +389,7 @@ impl BaseTransformImpl for EbuR128Level {
|
||||||
Ok(loudness) => s.set("shortterm-loudness", loudness),
|
Ok(loudness) => s.set("shortterm-loudness", loudness),
|
||||||
Err(err) => gst::error!(
|
Err(err) => gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to get shortterm loudness: {}",
|
"Failed to get shortterm loudness: {}",
|
||||||
err
|
err
|
||||||
),
|
),
|
||||||
|
@ -401,7 +401,7 @@ impl BaseTransformImpl for EbuR128Level {
|
||||||
Ok(loudness) => s.set("global-loudness", loudness),
|
Ok(loudness) => s.set("global-loudness", loudness),
|
||||||
Err(err) => gst::error!(
|
Err(err) => gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to get global loudness: {}",
|
"Failed to get global loudness: {}",
|
||||||
err
|
err
|
||||||
),
|
),
|
||||||
|
@ -411,7 +411,7 @@ impl BaseTransformImpl for EbuR128Level {
|
||||||
Ok(threshold) => s.set("relative-threshold", threshold),
|
Ok(threshold) => s.set("relative-threshold", threshold),
|
||||||
Err(err) => gst::error!(
|
Err(err) => gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to get relative threshold: {}",
|
"Failed to get relative threshold: {}",
|
||||||
err
|
err
|
||||||
),
|
),
|
||||||
|
@ -422,7 +422,12 @@ impl BaseTransformImpl for EbuR128Level {
|
||||||
match state.ebur128.loudness_range() {
|
match state.ebur128.loudness_range() {
|
||||||
Ok(range) => s.set("loudness-range", range),
|
Ok(range) => s.set("loudness-range", range),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to get loudness range: {}", err)
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to get loudness range: {}",
|
||||||
|
err
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,7 +440,7 @@ impl BaseTransformImpl for EbuR128Level {
|
||||||
match peaks {
|
match peaks {
|
||||||
Ok(peaks) => s.set("sample-peak", peaks),
|
Ok(peaks) => s.set("sample-peak", peaks),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to get sample peaks: {}", err)
|
gst::error!(CAT, imp = self, "Failed to get sample peaks: {}", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,12 +453,12 @@ impl BaseTransformImpl for EbuR128Level {
|
||||||
match peaks {
|
match peaks {
|
||||||
Ok(peaks) => s.set("true-peak", peaks),
|
Ok(peaks) => s.set("true-peak", peaks),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to get true peaks: {}", err)
|
gst::error!(CAT, imp = self, "Failed to get true peaks: {}", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Posting message {}", s);
|
gst::debug!(CAT, imp = self, "Posting message {}", s);
|
||||||
|
|
||||||
let msg = gst::message::Element::builder(s).src(&*self.obj()).build();
|
let msg = gst::message::Element::builder(s).src(&*self.obj()).build();
|
||||||
|
|
||||||
|
@ -504,7 +509,7 @@ impl AudioFilterImpl for EbuR128Level {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> {
|
fn setup(&self, info: &gst_audio::AudioInfo) -> Result<(), gst::LoggableError> {
|
||||||
gst::debug!(CAT, imp: self, "Configured for caps {:?}", info);
|
gst::debug!(CAT, imp = self, "Configured for caps {:?}", info);
|
||||||
|
|
||||||
let settings = *self.settings.lock().unwrap();
|
let settings = *self.settings.lock().unwrap();
|
||||||
|
|
||||||
|
@ -567,7 +572,7 @@ impl AudioFilterImpl for EbuR128Level {
|
||||||
val => {
|
val => {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Unknown channel position {:?}, ignoring channel",
|
"Unknown channel position {:?}, ignoring channel",
|
||||||
val
|
val
|
||||||
);
|
);
|
||||||
|
@ -745,12 +750,12 @@ fn interleaved_channel_data_into_slice<'a, T: FromByteSlice>(
|
||||||
) -> Result<&'a [T], gst::FlowError> {
|
) -> Result<&'a [T], gst::FlowError> {
|
||||||
buf.plane_data(0)
|
buf.plane_data(0)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: imp, "Failed to get audio data: {}", err);
|
gst::error!(CAT, imp = imp, "Failed to get audio data: {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?
|
})?
|
||||||
.as_slice_of::<T>()
|
.as_slice_of::<T>()
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: imp, "Failed to handle audio data: {}", err);
|
gst::error!(CAT, imp = imp, "Failed to handle audio data: {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -764,12 +769,12 @@ fn non_interleaved_channel_data_into_slices<'a, T: FromByteSlice>(
|
||||||
.map(|c| {
|
.map(|c| {
|
||||||
buf.plane_data(c)
|
buf.plane_data(c)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: imp, "Failed to get audio data: {}", err);
|
gst::error!(CAT, imp = imp, "Failed to get audio data: {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?
|
})?
|
||||||
.as_slice_of::<T>()
|
.as_slice_of::<T>()
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: imp, "Failed to handle audio data: {}", err);
|
gst::error!(CAT, imp = imp, "Failed to handle audio data: {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -224,7 +224,7 @@ impl HrtfRender {
|
||||||
let mut outbuf =
|
let mut outbuf =
|
||||||
gst_audio::AudioBufferRef::from_buffer_ref_writable(outbuf, &state.outinfo).map_err(
|
gst_audio::AudioBufferRef::from_buffer_ref_writable(outbuf, &state.outinfo).map_err(
|
||||||
|err| {
|
|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map buffer : {}", err);
|
gst::error!(CAT, imp = self, "Failed to map buffer : {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
@ -248,13 +248,13 @@ impl HrtfRender {
|
||||||
|
|
||||||
while state.adapter.available() >= inblksz {
|
while state.adapter.available() >= inblksz {
|
||||||
let inbuf = state.adapter.take_buffer(inblksz).map_err(|_| {
|
let inbuf = state.adapter.take_buffer(inblksz).map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map buffer");
|
gst::error!(CAT, imp = self, "Failed to map buffer");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let inbuf = gst_audio::AudioBuffer::from_buffer_readable(inbuf, &state.ininfo)
|
let inbuf = gst_audio::AudioBuffer::from_buffer_readable(inbuf, &state.ininfo)
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map buffer");
|
gst::error!(CAT, imp = self, "Failed to map buffer");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -624,7 +624,7 @@ impl BaseTransformImpl for HrtfRender {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Adapter size: {}, input size {}, transformed size {}",
|
"Adapter size: {}, input size {}, transformed size {}",
|
||||||
state.adapter.available(),
|
state.adapter.available(),
|
||||||
size,
|
size,
|
||||||
|
@ -670,7 +670,7 @@ impl BaseTransformImpl for HrtfRender {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Transformed caps from {} to {} in direction {:?}",
|
"Transformed caps from {} to {} in direction {:?}",
|
||||||
caps,
|
caps,
|
||||||
other_caps,
|
other_caps,
|
||||||
|
@ -741,7 +741,7 @@ impl BaseTransformImpl for HrtfRender {
|
||||||
adapter: gst_base::UniqueAdapter::new(),
|
adapter: gst_base::UniqueAdapter::new(),
|
||||||
});
|
});
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Configured for caps {}", incaps);
|
gst::debug!(CAT, imp = self, "Configured for caps {}", incaps);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -749,7 +749,7 @@ impl BaseTransformImpl for HrtfRender {
|
||||||
fn sink_event(&self, event: gst::Event) -> bool {
|
fn sink_event(&self, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Handling event {:?}", event);
|
gst::debug!(CAT, imp = self, "Handling event {:?}", event);
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::FlushStop(_) => {
|
EventView::FlushStop(_) => {
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl AudioDecoderImpl for ClaxonDec {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_format(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
|
fn set_format(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
|
||||||
gst::debug!(CAT, imp: self, "Setting format {:?}", caps);
|
gst::debug!(CAT, imp = self, "Setting format {:?}", caps);
|
||||||
|
|
||||||
let mut audio_info: Option<gst_audio::AudioInfo> = None;
|
let mut audio_info: Option<gst_audio::AudioInfo> = None;
|
||||||
|
|
||||||
|
@ -124,15 +124,15 @@ impl AudioDecoderImpl for ClaxonDec {
|
||||||
let streamheaders = streamheaders.as_slice();
|
let streamheaders = streamheaders.as_slice();
|
||||||
|
|
||||||
if streamheaders.len() < 2 {
|
if streamheaders.len() < 2 {
|
||||||
gst::debug!(CAT, imp: self, "Not enough streamheaders, trying in-band");
|
gst::debug!(CAT, imp = self, "Not enough streamheaders, trying in-band");
|
||||||
} else {
|
} else {
|
||||||
let ident_buf = streamheaders[0].get::<Option<gst::Buffer>>();
|
let ident_buf = streamheaders[0].get::<Option<gst::Buffer>>();
|
||||||
if let Ok(Some(ident_buf)) = ident_buf {
|
if let Ok(Some(ident_buf)) = ident_buf {
|
||||||
gst::debug!(CAT, imp: self, "Got streamheader buffers");
|
gst::debug!(CAT, imp = self, "Got streamheader buffers");
|
||||||
let inmap = ident_buf.map_readable().unwrap();
|
let inmap = ident_buf.map_readable().unwrap();
|
||||||
|
|
||||||
if inmap[0..7] != [0x7f, b'F', b'L', b'A', b'C', 0x01, 0x00] {
|
if inmap[0..7] != [0x7f, b'F', b'L', b'A', b'C', 0x01, 0x00] {
|
||||||
gst::debug!(CAT, imp: self, "Unknown streamheader format");
|
gst::debug!(CAT, imp = self, "Unknown streamheader format");
|
||||||
} else if let Ok(tstreaminfo) = claxon_streaminfo(&inmap[13..]) {
|
} else if let Ok(tstreaminfo) = claxon_streaminfo(&inmap[13..]) {
|
||||||
if let Ok(taudio_info) = gstaudioinfo(&tstreaminfo) {
|
if let Ok(taudio_info) = gstaudioinfo(&tstreaminfo) {
|
||||||
// To speed up negotiation
|
// To speed up negotiation
|
||||||
|
@ -142,7 +142,7 @@ impl AudioDecoderImpl for ClaxonDec {
|
||||||
{
|
{
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Error to negotiate output from based on in-caps streaminfo"
|
"Error to negotiate output from based on in-caps streaminfo"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ impl AudioDecoderImpl for ClaxonDec {
|
||||||
&self,
|
&self,
|
||||||
inbuf: Option<&gst::Buffer>,
|
inbuf: Option<&gst::Buffer>,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::debug!(CAT, imp: self, "Handling buffer {:?}", inbuf);
|
gst::debug!(CAT, imp = self, "Handling buffer {:?}", inbuf);
|
||||||
|
|
||||||
let inbuf = match inbuf {
|
let inbuf = match inbuf {
|
||||||
None => return Ok(gst::FlowSuccess::Ok),
|
None => return Ok(gst::FlowSuccess::Ok),
|
||||||
|
@ -173,7 +173,7 @@ impl AudioDecoderImpl for ClaxonDec {
|
||||||
};
|
};
|
||||||
|
|
||||||
let inmap = inbuf.map_readable().map_err(|_| {
|
let inmap = inbuf.map_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Failed to buffer readable");
|
gst::error!(CAT, imp = self, "Failed to buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -181,18 +181,18 @@ impl AudioDecoderImpl for ClaxonDec {
|
||||||
let state = state_guard.as_mut().ok_or(gst::FlowError::NotNegotiated)?;
|
let state = state_guard.as_mut().ok_or(gst::FlowError::NotNegotiated)?;
|
||||||
|
|
||||||
if inmap.as_slice() == b"fLaC" {
|
if inmap.as_slice() == b"fLaC" {
|
||||||
gst::debug!(CAT, imp: self, "fLaC buffer received");
|
gst::debug!(CAT, imp = self, "fLaC buffer received");
|
||||||
} else if inmap[0] & 0x7F == 0x00 {
|
} else if inmap[0] & 0x7F == 0x00 {
|
||||||
gst::debug!(CAT, imp: self, "Streaminfo header buffer received");
|
gst::debug!(CAT, imp = self, "Streaminfo header buffer received");
|
||||||
return self.handle_streaminfo_header(state, inmap.as_ref());
|
return self.handle_streaminfo_header(state, inmap.as_ref());
|
||||||
} else if inmap[0] == 0b1111_1111 && inmap[1] & 0b1111_1100 == 0b1111_1000 {
|
} else if inmap[0] == 0b1111_1111 && inmap[1] & 0b1111_1100 == 0b1111_1000 {
|
||||||
gst::debug!(CAT, imp: self, "Data buffer received");
|
gst::debug!(CAT, imp = self, "Data buffer received");
|
||||||
return self.handle_data(state, inmap.as_ref());
|
return self.handle_data(state, inmap.as_ref());
|
||||||
} else {
|
} else {
|
||||||
// info about other headers in flacparse and https://xiph.org/flac/format.html
|
// info about other headers in flacparse and https://xiph.org/flac/format.html
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Other header buffer received {:?}",
|
"Other header buffer received {:?}",
|
||||||
inmap[0] & 0x7F
|
inmap[0] & 0x7F
|
||||||
);
|
);
|
||||||
|
@ -220,7 +220,7 @@ impl ClaxonDec {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Successfully parsed headers: {:?}",
|
"Successfully parsed headers: {:?}",
|
||||||
audio_info
|
audio_info
|
||||||
);
|
);
|
||||||
|
|
|
@ -191,7 +191,7 @@ impl CsoundFilter {
|
||||||
(avail / state.in_info.channels() as usize) * state.out_info.channels() as usize;
|
(avail / state.in_info.channels() as usize) * state.out_info.channels() as usize;
|
||||||
|
|
||||||
let mut buffer = gst::Buffer::with_size(out_bytes).map_err(|e| {
|
let mut buffer = gst::Buffer::with_size(out_bytes).map_err(|e| {
|
||||||
gst::error!(CAT, imp: self, "Failed to allocate buffer at EOS {:?}", e);
|
gst::error!(CAT, imp = self, "Failed to allocate buffer at EOS {:?}", e);
|
||||||
gst::FlowError::Flushing
|
gst::FlowError::Flushing
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ impl CsoundFilter {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Generating output at: {} - duration: {}",
|
"Generating output at: {} - duration: {}",
|
||||||
pts.display(),
|
pts.display(),
|
||||||
duration.display(),
|
duration.display(),
|
||||||
|
@ -481,7 +481,7 @@ impl BaseTransformImpl for CsoundFilter {
|
||||||
csound.reset();
|
csound.reset();
|
||||||
let _ = self.state.lock().unwrap().take();
|
let _ = self.state.lock().unwrap().take();
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Stopped");
|
gst::info!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -490,7 +490,7 @@ impl BaseTransformImpl for CsoundFilter {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
if let EventView::Eos(_) = event.view() {
|
if let EventView::Eos(_) = event.view() {
|
||||||
gst::log!(CAT, imp: self, "Handling Eos");
|
gst::log!(CAT, imp = self, "Handling Eos");
|
||||||
if self.drain().is_err() {
|
if self.drain().is_err() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -535,7 +535,7 @@ impl BaseTransformImpl for CsoundFilter {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Transformed caps from {} to {} in direction {:?}",
|
"Transformed caps from {} to {} in direction {:?}",
|
||||||
caps,
|
caps,
|
||||||
other_caps,
|
other_caps,
|
||||||
|
|
|
@ -120,7 +120,7 @@ impl AudioDecoderImpl for LewtonDec {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_format(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
|
fn set_format(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
|
||||||
gst::debug!(CAT, imp: self, "Setting format {:?}", caps);
|
gst::debug!(CAT, imp = self, "Setting format {:?}", caps);
|
||||||
|
|
||||||
// When the caps are changing we require new headers
|
// When the caps are changing we require new headers
|
||||||
let mut state_guard = self.state.borrow_mut();
|
let mut state_guard = self.state.borrow_mut();
|
||||||
|
@ -138,7 +138,7 @@ impl AudioDecoderImpl for LewtonDec {
|
||||||
if let Ok(Some(streamheaders)) = s.get_optional::<gst::ArrayRef>("streamheader") {
|
if let Ok(Some(streamheaders)) = s.get_optional::<gst::ArrayRef>("streamheader") {
|
||||||
let streamheaders = streamheaders.as_slice();
|
let streamheaders = streamheaders.as_slice();
|
||||||
if streamheaders.len() < 3 {
|
if streamheaders.len() < 3 {
|
||||||
gst::debug!(CAT, imp: self, "Not enough streamheaders, trying in-band");
|
gst::debug!(CAT, imp = self, "Not enough streamheaders, trying in-band");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ impl AudioDecoderImpl for LewtonDec {
|
||||||
if let (Ok(Some(ident_buf)), Ok(Some(comment_buf)), Ok(Some(setup_buf))) =
|
if let (Ok(Some(ident_buf)), Ok(Some(comment_buf)), Ok(Some(setup_buf))) =
|
||||||
(ident_buf, comment_buf, setup_buf)
|
(ident_buf, comment_buf, setup_buf)
|
||||||
{
|
{
|
||||||
gst::debug!(CAT, imp: self, "Got streamheader buffers");
|
gst::debug!(CAT, imp = self, "Got streamheader buffers");
|
||||||
state.header_bufs = (Some(ident_buf), Some(comment_buf), Some(setup_buf));
|
state.header_bufs = (Some(ident_buf), Some(comment_buf), Some(setup_buf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ impl AudioDecoderImpl for LewtonDec {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self, _hard: bool) {
|
fn flush(&self, _hard: bool) {
|
||||||
gst::debug!(CAT, imp: self, "Flushing");
|
gst::debug!(CAT, imp = self, "Flushing");
|
||||||
|
|
||||||
let mut state_guard = self.state.borrow_mut();
|
let mut state_guard = self.state.borrow_mut();
|
||||||
if let Some(ref mut state) = *state_guard {
|
if let Some(ref mut state) = *state_guard {
|
||||||
|
@ -169,7 +169,7 @@ impl AudioDecoderImpl for LewtonDec {
|
||||||
&self,
|
&self,
|
||||||
inbuf: Option<&gst::Buffer>,
|
inbuf: Option<&gst::Buffer>,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::debug!(CAT, imp: self, "Handling buffer {:?}", inbuf);
|
gst::debug!(CAT, imp = self, "Handling buffer {:?}", inbuf);
|
||||||
|
|
||||||
let inbuf = match inbuf {
|
let inbuf = match inbuf {
|
||||||
None => return Ok(gst::FlowSuccess::Ok),
|
None => return Ok(gst::FlowSuccess::Ok),
|
||||||
|
@ -177,7 +177,7 @@ impl AudioDecoderImpl for LewtonDec {
|
||||||
};
|
};
|
||||||
|
|
||||||
let inmap = inbuf.map_readable().map_err(|_| {
|
let inmap = inbuf.map_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Failed to buffer readable");
|
gst::error!(CAT, imp = self, "Failed to buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ impl AudioDecoderImpl for LewtonDec {
|
||||||
if state.headerset.is_some() {
|
if state.headerset.is_some() {
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Got empty packet before all headers");
|
gst::error!(CAT, imp = self, "Got empty packet before all headers");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,14 +219,14 @@ impl LewtonDec {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
// ident header
|
// ident header
|
||||||
if indata[0] == 0x01 {
|
if indata[0] == 0x01 {
|
||||||
gst::debug!(CAT, imp: self, "Got ident header buffer");
|
gst::debug!(CAT, imp = self, "Got ident header buffer");
|
||||||
state.header_bufs = (Some(inbuf.clone()), None, None);
|
state.header_bufs = (Some(inbuf.clone()), None, None);
|
||||||
} else if indata[0] == 0x03 {
|
} else if indata[0] == 0x03 {
|
||||||
// comment header
|
// comment header
|
||||||
if state.header_bufs.0.is_none() {
|
if state.header_bufs.0.is_none() {
|
||||||
gst::warning!(CAT, imp: self, "Got comment header before ident header");
|
gst::warning!(CAT, imp = self, "Got comment header before ident header");
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Got comment header buffer");
|
gst::debug!(CAT, imp = self, "Got comment header buffer");
|
||||||
state.header_bufs.1 = Some(inbuf.clone());
|
state.header_bufs.1 = Some(inbuf.clone());
|
||||||
}
|
}
|
||||||
} else if indata[0] == 0x05 {
|
} else if indata[0] == 0x05 {
|
||||||
|
@ -234,11 +234,11 @@ impl LewtonDec {
|
||||||
if state.header_bufs.0.is_none() || state.header_bufs.1.is_none() {
|
if state.header_bufs.0.is_none() || state.header_bufs.1.is_none() {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Got setup header before ident/comment header"
|
"Got setup header before ident/comment header"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Got setup header buffer");
|
gst::debug!(CAT, imp = self, "Got setup header buffer");
|
||||||
state.header_bufs.2 = Some(inbuf.clone());
|
state.header_bufs.2 = Some(inbuf.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ impl LewtonDec {
|
||||||
|
|
||||||
// First try to parse the headers
|
// First try to parse the headers
|
||||||
let ident_map = ident_buf.map_readable().map_err(|_| {
|
let ident_map = ident_buf.map_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map ident buffer readable");
|
gst::error!(CAT, imp = self, "Failed to map ident buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let ident = lewton::header::read_header_ident(ident_map.as_ref()).map_err(|err| {
|
let ident = lewton::header::read_header_ident(ident_map.as_ref()).map_err(|err| {
|
||||||
|
@ -276,7 +276,7 @@ impl LewtonDec {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let comment_map = comment_buf.map_readable().map_err(|_| {
|
let comment_map = comment_buf.map_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map comment buffer readable");
|
gst::error!(CAT, imp = self, "Failed to map comment buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let comment = lewton::header::read_header_comment(comment_map.as_ref()).map_err(|err| {
|
let comment = lewton::header::read_header_comment(comment_map.as_ref()).map_err(|err| {
|
||||||
|
@ -289,7 +289,7 @@ impl LewtonDec {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let setup_map = setup_buf.map_readable().map_err(|_| {
|
let setup_map = setup_buf.map_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map setup buffer readable");
|
gst::error!(CAT, imp = self, "Failed to map setup buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let setup = lewton::header::read_header_setup(
|
let setup = lewton::header::read_header_setup(
|
||||||
|
@ -327,7 +327,7 @@ impl LewtonDec {
|
||||||
if gst_audio::channel_reorder_map(from, to, &mut map[..channels]).is_err() {
|
if gst_audio::channel_reorder_map(from, to, &mut map[..channels]).is_err() {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to generate channel reorder map from {:?} to {:?}",
|
"Failed to generate channel reorder map from {:?} to {:?}",
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
|
@ -343,7 +343,7 @@ impl LewtonDec {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Successfully parsed headers: {:?}",
|
"Successfully parsed headers: {:?}",
|
||||||
audio_info
|
audio_info
|
||||||
);
|
);
|
||||||
|
@ -396,7 +396,7 @@ impl LewtonDec {
|
||||||
}
|
}
|
||||||
|
|
||||||
let sample_count = decoded.samples.len() / audio_info.channels() as usize;
|
let sample_count = decoded.samples.len() / audio_info.channels() as usize;
|
||||||
gst::debug!(CAT, imp: self, "Got {} decoded samples", sample_count);
|
gst::debug!(CAT, imp = self, "Got {} decoded samples", sample_count);
|
||||||
|
|
||||||
if sample_count == 0 {
|
if sample_count == 0 {
|
||||||
return self.obj().finish_frame(None, 1);
|
return self.obj().finish_frame(None, 1);
|
||||||
|
|
|
@ -135,7 +135,7 @@ impl Settings {
|
||||||
if !self.username.is_empty() && self.username != cached_cred.username {
|
if !self.username.is_empty() && self.username != cached_cred.username {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
cat,
|
cat,
|
||||||
obj: &src,
|
obj = &src,
|
||||||
"ignore cached credentials for user {} which mismatch user {}",
|
"ignore cached credentials for user {} which mismatch user {}",
|
||||||
cached_cred.username,
|
cached_cred.username,
|
||||||
self.username
|
self.username
|
||||||
|
@ -143,7 +143,7 @@ impl Settings {
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
cat,
|
cat,
|
||||||
obj: &src,
|
obj = &src,
|
||||||
"reuse cached credentials for user {}",
|
"reuse cached credentials for user {}",
|
||||||
cached_cred.username
|
cached_cred.username
|
||||||
);
|
);
|
||||||
|
@ -162,7 +162,7 @@ impl Settings {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
cat,
|
cat,
|
||||||
obj: &src,
|
obj = &src,
|
||||||
"credentials not in cache or cached credentials invalid",
|
"credentials not in cache or cached credentials invalid",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ impl BaseSrcImpl for SpotifyAudioSrc {
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
if let Some(state) = self.state.lock().unwrap().take() {
|
if let Some(state) = self.state.lock().unwrap().take() {
|
||||||
gst::debug!(CAT, imp: self, "stopping");
|
gst::debug!(CAT, imp = self, "stopping");
|
||||||
state.player.stop();
|
state.player.stop();
|
||||||
state.player_channel_handle.abort();
|
state.player_channel_handle.abort();
|
||||||
// FIXME: not sure why this is needed to unblock BufferSink::write(), dropping State should drop the receiver
|
// FIXME: not sure why this is needed to unblock BufferSink::write(), dropping State should drop the receiver
|
||||||
|
@ -270,13 +270,13 @@ impl PushSrcImpl for SpotifyAudioSrc {
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Err(_aborted) => {
|
Err(_aborted) => {
|
||||||
gst::debug!(CAT, imp: self, "setup has been cancelled");
|
gst::debug!(CAT, imp = self, "setup has been cancelled");
|
||||||
setup_thread = self.setup_thread.lock().unwrap();
|
setup_thread = self.setup_thread.lock().unwrap();
|
||||||
*setup_thread = SetupThread::Cancelled;
|
*setup_thread = SetupThread::Cancelled;
|
||||||
return Err(gst::FlowError::Flushing);
|
return Err(gst::FlowError::Flushing);
|
||||||
}
|
}
|
||||||
Ok(Err(err)) => {
|
Ok(Err(err)) => {
|
||||||
gst::error!(CAT, imp: self, "failed to start: {err:?}");
|
gst::error!(CAT, imp = self, "failed to start: {err:?}");
|
||||||
gst::element_imp_error!(self, gst::ResourceError::Settings, ["{err:?}"]);
|
gst::element_imp_error!(self, gst::ResourceError::Settings, ["{err:?}"]);
|
||||||
setup_thread = self.setup_thread.lock().unwrap();
|
setup_thread = self.setup_thread.lock().unwrap();
|
||||||
*setup_thread = SetupThread::None;
|
*setup_thread = SetupThread::None;
|
||||||
|
@ -295,15 +295,15 @@ impl PushSrcImpl for SpotifyAudioSrc {
|
||||||
|
|
||||||
match state.receiver.recv().unwrap() {
|
match state.receiver.recv().unwrap() {
|
||||||
Message::Buffer(buffer) => {
|
Message::Buffer(buffer) => {
|
||||||
gst::log!(CAT, imp: self, "got buffer of size {}", buffer.size());
|
gst::log!(CAT, imp = self, "got buffer of size {}", buffer.size());
|
||||||
Ok(CreateSuccess::NewBuffer(buffer))
|
Ok(CreateSuccess::NewBuffer(buffer))
|
||||||
}
|
}
|
||||||
Message::Eos => {
|
Message::Eos => {
|
||||||
gst::debug!(CAT, imp: self, "eos");
|
gst::debug!(CAT, imp = self, "eos");
|
||||||
Err(gst::FlowError::Eos)
|
Err(gst::FlowError::Eos)
|
||||||
}
|
}
|
||||||
Message::Unavailable => {
|
Message::Unavailable => {
|
||||||
gst::error!(CAT, imp: self, "track is not available");
|
gst::error!(CAT, imp = self, "track is not available");
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::ResourceError::NotFound,
|
gst::ResourceError::NotFound,
|
||||||
|
@ -352,7 +352,7 @@ impl URIHandlerImpl for SpotifyAudioSrc {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_uri(&self, uri: &str) -> Result<(), glib::Error> {
|
fn set_uri(&self, uri: &str) -> Result<(), glib::Error> {
|
||||||
gst::debug!(CAT, imp: self, "set URI: {}", uri);
|
gst::debug!(CAT, imp = self, "set URI: {}", uri);
|
||||||
|
|
||||||
let url = url::Url::parse(uri)
|
let url = url::Url::parse(uri)
|
||||||
.map_err(|e| glib::Error::new(gst::URIError::BadUri, &format!("{e:?}")))?;
|
.map_err(|e| glib::Error::new(gst::URIError::BadUri, &format!("{e:?}")))?;
|
||||||
|
@ -364,7 +364,7 @@ impl URIHandlerImpl for SpotifyAudioSrc {
|
||||||
self.obj().set_property(&key, value.as_ref());
|
self.obj().set_property(&key, value.as_ref());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::warning!(CAT, imp: self, "unsupported query: {}={}", key, value);
|
gst::warning!(CAT, imp = self, "unsupported query: {}={}", key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ impl SpotifyAudioSrc {
|
||||||
|
|
||||||
let session = common.connect_session(src.clone(), &CAT).await?;
|
let session = common.connect_session(src.clone(), &CAT).await?;
|
||||||
let track = common.track_id()?;
|
let track = common.track_id()?;
|
||||||
gst::debug!(CAT, imp: self, "Requesting bitrate {:?}", bitrate);
|
gst::debug!(CAT, imp = self, "Requesting bitrate {:?}", bitrate);
|
||||||
|
|
||||||
(session, track, bitrate)
|
(session, track, bitrate)
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,20 +81,20 @@ impl FileSink {
|
||||||
Some(ref location_cur) => {
|
Some(ref location_cur) => {
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing `location` from {:?} to {}",
|
"Changing `location` from {:?} to {}",
|
||||||
location_cur,
|
location_cur,
|
||||||
location,
|
location,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
gst::info!(CAT, imp: self, "Setting `location` to {}", location,);
|
gst::info!(CAT, imp = self, "Setting `location` to {}", location,);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(location)
|
Some(location)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
gst::info!(CAT, imp: self, "Resetting `location` to None",);
|
gst::info!(CAT, imp = self, "Resetting `location` to None",);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -140,7 +140,12 @@ impl ObjectImpl for FileSink {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::error!(CAT, imp: self, "Failed to set property `location`: {}", err);
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to set property `location`: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
|
@ -222,10 +227,10 @@ impl BaseSinkImpl for FileSink {
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
gst::debug!(CAT, imp: self, "Opened file {:?}", file);
|
gst::debug!(CAT, imp = self, "Opened file {:?}", file);
|
||||||
|
|
||||||
*state = State::Started { file, position: 0 };
|
*state = State::Started { file, position: 0 };
|
||||||
gst::info!(CAT, imp: self, "Started");
|
gst::info!(CAT, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -240,7 +245,7 @@ impl BaseSinkImpl for FileSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
*state = State::Stopped;
|
*state = State::Stopped;
|
||||||
gst::info!(CAT, imp: self, "Stopped");
|
gst::info!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -260,7 +265,7 @@ impl BaseSinkImpl for FileSink {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Rendering {:?}", buffer);
|
gst::trace!(CAT, imp = self, "Rendering {:?}", buffer);
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::element_imp_error!(self, gst::CoreError::Failed, ["Failed to map buffer"]);
|
gst::element_imp_error!(self, gst::CoreError::Failed, ["Failed to map buffer"]);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
|
|
|
@ -94,20 +94,20 @@ impl FileSrc {
|
||||||
Some(ref location_cur) => {
|
Some(ref location_cur) => {
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing `location` from {:?} to {}",
|
"Changing `location` from {:?} to {}",
|
||||||
location_cur,
|
location_cur,
|
||||||
location,
|
location,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
gst::info!(CAT, imp: self, "Setting `location to {}", location,);
|
gst::info!(CAT, imp = self, "Setting `location to {}", location,);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(location)
|
Some(location)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
gst::info!(CAT, imp: self, "Resetting `location` to None",);
|
gst::info!(CAT, imp = self, "Resetting `location` to None",);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -148,7 +148,12 @@ impl ObjectImpl for FileSrc {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::error!(CAT, imp: self, "Failed to set property `location`: {}", err);
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to set property `location`: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
|
@ -250,11 +255,11 @@ impl BaseSrcImpl for FileSrc {
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Opened file {:?}", file);
|
gst::debug!(CAT, imp = self, "Opened file {:?}", file);
|
||||||
|
|
||||||
*state = State::Started { file, position: 0 };
|
*state = State::Started { file, position: 0 };
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Started");
|
gst::info!(CAT, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -270,7 +275,7 @@ impl BaseSrcImpl for FileSrc {
|
||||||
|
|
||||||
*state = State::Stopped;
|
*state = State::Stopped;
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Stopped");
|
gst::info!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,12 +164,16 @@ impl Stream {
|
||||||
let pts = segment
|
let pts = segment
|
||||||
.to_running_time_full(pts_position)
|
.to_running_time_full(pts_position)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::error!(CAT, obj: self.sinkpad, "Couldn't convert PTS to running time");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
obj = self.sinkpad,
|
||||||
|
"Couldn't convert PTS to running time"
|
||||||
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?
|
})?
|
||||||
.positive()
|
.positive()
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
gst::warning!(CAT, obj: self.sinkpad, "Negative PTSs are not supported");
|
gst::warning!(CAT, obj = self.sinkpad, "Negative PTSs are not supported");
|
||||||
gst::ClockTime::ZERO
|
gst::ClockTime::ZERO
|
||||||
});
|
});
|
||||||
let end_pts = segment
|
let end_pts = segment
|
||||||
|
@ -177,14 +181,14 @@ impl Stream {
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.sinkpad,
|
obj = self.sinkpad,
|
||||||
"Couldn't convert end PTS to running time"
|
"Couldn't convert end PTS to running time"
|
||||||
);
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?
|
})?
|
||||||
.positive()
|
.positive()
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
gst::warning!(CAT, obj: self.sinkpad, "Negative PTSs are not supported");
|
gst::warning!(CAT, obj = self.sinkpad, "Negative PTSs are not supported");
|
||||||
gst::ClockTime::ZERO
|
gst::ClockTime::ZERO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -198,7 +202,11 @@ impl Stream {
|
||||||
.unwrap_or(dts_position);
|
.unwrap_or(dts_position);
|
||||||
|
|
||||||
let dts = segment.to_running_time_full(dts_position).ok_or_else(|| {
|
let dts = segment.to_running_time_full(dts_position).ok_or_else(|| {
|
||||||
gst::error!(CAT, obj: self.sinkpad, "Couldn't convert DTS to running time");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
obj = self.sinkpad,
|
||||||
|
"Couldn't convert DTS to running time"
|
||||||
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -207,7 +215,7 @@ impl Stream {
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.sinkpad,
|
obj = self.sinkpad,
|
||||||
"Couldn't convert end DTS to running time"
|
"Couldn't convert end DTS to running time"
|
||||||
);
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
|
@ -239,7 +247,7 @@ impl Stream {
|
||||||
if let Some(prev_gop) = self.queued_gops.get_mut(1) {
|
if let Some(prev_gop) = self.queued_gops.get_mut(1) {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.sinkpad,
|
obj = self.sinkpad,
|
||||||
"Updating previous GOP starting at PTS {} to end PTS {}",
|
"Updating previous GOP starting at PTS {} to end PTS {}",
|
||||||
prev_gop.earliest_pts,
|
prev_gop.earliest_pts,
|
||||||
pts,
|
pts,
|
||||||
|
@ -258,7 +266,7 @@ impl Stream {
|
||||||
if self.delta_frames.requires_dts() {
|
if self.delta_frames.requires_dts() {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.sinkpad,
|
obj = self.sinkpad,
|
||||||
"Previous GOP has final earliest PTS at {}",
|
"Previous GOP has final earliest PTS at {}",
|
||||||
prev_gop.earliest_pts
|
prev_gop.earliest_pts
|
||||||
);
|
);
|
||||||
|
@ -281,7 +289,7 @@ impl Stream {
|
||||||
if gop.earliest_pts > pts && !gop.final_earliest_pts {
|
if gop.earliest_pts > pts && !gop.final_earliest_pts {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.sinkpad,
|
obj = self.sinkpad,
|
||||||
"Updating current GOP earliest PTS from {} to {}",
|
"Updating current GOP earliest PTS from {} to {}",
|
||||||
gop.earliest_pts,
|
gop.earliest_pts,
|
||||||
pts
|
pts
|
||||||
|
@ -292,7 +300,7 @@ impl Stream {
|
||||||
if prev_gop.end_pts < pts {
|
if prev_gop.end_pts < pts {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.sinkpad,
|
obj = self.sinkpad,
|
||||||
"Updating previous GOP starting PTS {} end time from {} to {}",
|
"Updating previous GOP starting PTS {} end time from {} to {}",
|
||||||
pts,
|
pts,
|
||||||
prev_gop.end_pts,
|
prev_gop.end_pts,
|
||||||
|
@ -311,7 +319,7 @@ impl Stream {
|
||||||
if gop.start_pts <= dts && !gop.final_earliest_pts {
|
if gop.start_pts <= dts && !gop.final_earliest_pts {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.sinkpad,
|
obj = self.sinkpad,
|
||||||
"GOP has final earliest PTS at {}",
|
"GOP has final earliest PTS at {}",
|
||||||
gop.earliest_pts
|
gop.earliest_pts
|
||||||
);
|
);
|
||||||
|
@ -337,7 +345,7 @@ impl Stream {
|
||||||
) {
|
) {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.sinkpad,
|
obj = self.sinkpad,
|
||||||
"Queued full GOPs duration updated to {}",
|
"Queued full GOPs duration updated to {}",
|
||||||
prev_gop.end_pts.saturating_sub(first_gop.earliest_pts),
|
prev_gop.end_pts.saturating_sub(first_gop.earliest_pts),
|
||||||
);
|
);
|
||||||
|
@ -345,7 +353,7 @@ impl Stream {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.sinkpad,
|
obj = self.sinkpad,
|
||||||
"Queued duration updated to {}",
|
"Queued duration updated to {}",
|
||||||
Option::zip(self.queued_gops.front(), self.queued_gops.back())
|
Option::zip(self.queued_gops.front(), self.queued_gops.back())
|
||||||
.map(|(end, start)| end.end_pts.saturating_sub(start.start_pts))
|
.map(|(end, start)| end.end_pts.saturating_sub(start.start_pts))
|
||||||
|
@ -412,7 +420,7 @@ impl GopBuffer {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
if buffer.pts().is_none() {
|
if buffer.pts().is_none() {
|
||||||
gst::error!(CAT, obj: obj, "Require timestamped buffers!");
|
gst::error!(CAT, obj = obj, "Require timestamped buffers!");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,12 +437,12 @@ impl GopBuffer {
|
||||||
|
|
||||||
if stream.delta_frames.intra_only() && buffer.flags().contains(gst::BufferFlags::DELTA_UNIT)
|
if stream.delta_frames.intra_only() && buffer.flags().contains(gst::BufferFlags::DELTA_UNIT)
|
||||||
{
|
{
|
||||||
gst::error!(CAT, obj: pad, "Intra-only stream with delta units");
|
gst::error!(CAT, obj = pad, "Intra-only stream with delta units");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if stream.delta_frames.requires_dts() && buffer.dts().is_none() {
|
if stream.delta_frames.requires_dts() && buffer.dts().is_none() {
|
||||||
gst::error!(CAT, obj: pad, "Require DTS for video streams");
|
gst::error!(CAT, obj = pad, "Require DTS for video streams");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +476,7 @@ impl GopBuffer {
|
||||||
let stored_duration_without_oldest = newest_ts.saturating_sub(oldest_ts);
|
let stored_duration_without_oldest = newest_ts.saturating_sub(oldest_ts);
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: obj,
|
obj = obj,
|
||||||
"newest_pts {}, second oldest_pts {}, stored_duration_without_oldest_gop {}, min-time {}",
|
"newest_pts {}, second oldest_pts {}, stored_duration_without_oldest_gop {}, min-time {}",
|
||||||
newest_ts.display(),
|
newest_ts.display(),
|
||||||
oldest_ts.display(),
|
oldest_ts.display(),
|
||||||
|
@ -497,7 +505,7 @@ impl GopBuffer {
|
||||||
.opt_saturating_sub(oldest_ts)
|
.opt_saturating_sub(oldest_ts)
|
||||||
.is_some_and(|diff| diff > gst::Signed::Positive(max_time))
|
.is_some_and(|diff| diff > gst::Signed::Positive(max_time))
|
||||||
{
|
{
|
||||||
gst::warning!(CAT, obj: obj, "Stored data has overflowed the maximum allowed stored time {}, pushing oldest GOP", max_time.display());
|
gst::warning!(CAT, obj = obj, "Stored data has overflowed the maximum allowed stored time {}, pushing oldest GOP", max_time.display());
|
||||||
gops_to_push.push(stream.oldest_gop().unwrap());
|
gops_to_push.push(stream.oldest_gop().unwrap());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -527,11 +535,11 @@ impl GopBuffer {
|
||||||
stream.delta_frames = delta_frames;
|
stream.delta_frames = delta_frames;
|
||||||
}
|
}
|
||||||
gst::EventView::FlushStop(_flush) => {
|
gst::EventView::FlushStop(_flush) => {
|
||||||
gst::debug!(CAT, obj: obj, "flushing stored data");
|
gst::debug!(CAT, obj = obj, "flushing stored data");
|
||||||
stream.flush();
|
stream.flush();
|
||||||
}
|
}
|
||||||
gst::EventView::Eos(_eos) => {
|
gst::EventView::Eos(_eos) => {
|
||||||
gst::debug!(CAT, obj: obj, "draining data at EOS");
|
gst::debug!(CAT, obj = obj, "draining data at EOS");
|
||||||
let gops = stream.drain_all().collect::<Vec<_>>();
|
let gops = stream.drain_all().collect::<Vec<_>>();
|
||||||
let srcpad = stream.srcpad.clone();
|
let srcpad = stream.srcpad.clone();
|
||||||
drop(state);
|
drop(state);
|
||||||
|
@ -555,7 +563,12 @@ impl GopBuffer {
|
||||||
if event.is_serialized() {
|
if event.is_serialized() {
|
||||||
if stream.peek_oldest_gop().is_none() {
|
if stream.peek_oldest_gop().is_none() {
|
||||||
// if there is nothing queued, the event can go straight through
|
// if there is nothing queued, the event can go straight through
|
||||||
gst::trace!(CAT, obj: obj, "nothing queued, event {:?} passthrough", event.structure().map(|s| s.name().as_str()));
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
obj = obj,
|
||||||
|
"nothing queued, event {:?} passthrough",
|
||||||
|
event.structure().map(|s| s.name().as_str())
|
||||||
|
);
|
||||||
drop(state);
|
drop(state);
|
||||||
return gst::Pad::event_default(pad, Some(&*obj), event);
|
return gst::Pad::event_default(pad, Some(&*obj), event);
|
||||||
}
|
}
|
||||||
|
@ -573,7 +586,11 @@ impl GopBuffer {
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
if query.is_serialized() {
|
if query.is_serialized() {
|
||||||
// TODO: serialized queries somehow?
|
// TODO: serialized queries somehow?
|
||||||
gst::warning!(CAT, obj: pad, "Serialized queries are currently not supported");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
obj = pad,
|
||||||
|
"Serialized queries are currently not supported"
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
gst::Pad::query_default(pad, Some(&*obj), query)
|
gst::Pad::query_default(pad, Some(&*obj), query)
|
||||||
|
@ -604,7 +621,7 @@ impl GopBuffer {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Latency query response: live {} min {} max {}",
|
"Latency query response: live {} min {} max {}",
|
||||||
live,
|
live,
|
||||||
min,
|
min,
|
||||||
|
|
|
@ -108,7 +108,7 @@ impl ObjectImpl for InterSink {
|
||||||
InterStreamProducer::acquire(&settings.producer_name, &appsink)
|
InterStreamProducer::acquire(&settings.producer_name, &appsink)
|
||||||
{
|
{
|
||||||
drop(settings);
|
drop(settings);
|
||||||
gst::error!(CAT, imp: self, "{err}");
|
gst::error!(CAT, imp = self, "{err}");
|
||||||
self.post_error_message(gst::error_msg!(
|
self.post_error_message(gst::error_msg!(
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
["{err}"]
|
["{err}"]
|
||||||
|
@ -191,7 +191,7 @@ impl ElementImpl for InterSink {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
if transition == gst::StateChange::ReadyToPaused {
|
if transition == gst::StateChange::ReadyToPaused {
|
||||||
if let Err(err) = self.prepare() {
|
if let Err(err) = self.prepare() {
|
||||||
|
|
|
@ -177,7 +177,7 @@ impl ElementImpl for InterSrc {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
if transition == gst::StateChange::ReadyToPaused {
|
if transition == gst::StateChange::ReadyToPaused {
|
||||||
if let Err(err) = self.prepare() {
|
if let Err(err) = self.prepare() {
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl State {
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::debug!(CAT, obj: pad, "Returned pull size: {}", map.len());
|
gst::debug!(CAT, obj = pad, "Returned pull size: {}", map.len());
|
||||||
|
|
||||||
let mut nonce = add_nonce(self.initial_nonce.unwrap(), chunk_index);
|
let mut nonce = add_nonce(self.initial_nonce.unwrap(), chunk_index);
|
||||||
let block_size = self.block_size.expect("Block size wasn't set") as usize + box_::MACBYTES;
|
let block_size = self.block_size.expect("Block size wasn't set") as usize + box_::MACBYTES;
|
||||||
|
@ -144,8 +144,8 @@ impl State {
|
||||||
adapter_offset: usize,
|
adapter_offset: usize,
|
||||||
) -> Result<gst::PadGetRangeSuccess, gst::FlowError> {
|
) -> Result<gst::PadGetRangeSuccess, gst::FlowError> {
|
||||||
let avail = self.adapter.available();
|
let avail = self.adapter.available();
|
||||||
gst::debug!(CAT, obj: pad, "Avail: {}", avail);
|
gst::debug!(CAT, obj = pad, "Avail: {}", avail);
|
||||||
gst::debug!(CAT, obj: pad, "Adapter offset: {}", adapter_offset);
|
gst::debug!(CAT, obj = pad, "Adapter offset: {}", adapter_offset);
|
||||||
|
|
||||||
// if this underflows, the available buffer in the adapter is smaller than the
|
// if this underflows, the available buffer in the adapter is smaller than the
|
||||||
// requested offset, which means we have reached EOS
|
// requested offset, which means we have reached EOS
|
||||||
|
@ -189,7 +189,7 @@ impl State {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Failed to map provided buffer writable: {}",
|
"Failed to map provided buffer writable: {}",
|
||||||
e
|
e
|
||||||
);
|
);
|
||||||
|
@ -197,7 +197,7 @@ impl State {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Err(e) = self.adapter.copy(0, &mut map[..available_size]) {
|
if let Err(e) = self.adapter.copy(0, &mut map[..available_size]) {
|
||||||
gst::error!(CAT, obj: pad, "Failed to copy into provided buffer: {}", e);
|
gst::error!(CAT, obj = pad, "Failed to copy into provided buffer: {}", e);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
if map.len() != available_size {
|
if map.len() != available_size {
|
||||||
|
@ -278,7 +278,7 @@ impl Decrypter {
|
||||||
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling query {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling query {:?}", query);
|
||||||
|
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
QueryViewMut::Scheduling(q) => {
|
QueryViewMut::Scheduling(q) => {
|
||||||
|
@ -288,12 +288,12 @@ impl Decrypter {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Upstream returned {:?}", peer_query);
|
gst::log!(CAT, obj = pad, "Upstream returned {:?}", peer_query);
|
||||||
|
|
||||||
let (flags, min, max, align) = peer_query.result();
|
let (flags, min, max, align) = peer_query.result();
|
||||||
q.set(flags, min, max, align);
|
q.set(flags, min, max, align);
|
||||||
q.add_scheduling_modes(&[gst::PadMode::Pull]);
|
q.add_scheduling_modes(&[gst::PadMode::Pull]);
|
||||||
gst::log!(CAT, obj: pad, "Returning {:?}", q.query_mut());
|
gst::log!(CAT, obj = pad, "Returning {:?}", q.query_mut());
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
QueryViewMut::Duration(q) => {
|
QueryViewMut::Duration(q) => {
|
||||||
|
@ -334,7 +334,7 @@ impl Decrypter {
|
||||||
// subtrack the MAC of each block
|
// subtrack the MAC of each block
|
||||||
let size = size - total_chunks * box_::MACBYTES as u64;
|
let size = size - total_chunks * box_::MACBYTES as u64;
|
||||||
|
|
||||||
gst::debug!(CAT, obj: pad, "Setting duration bytes: {}", size);
|
gst::debug!(CAT, obj = pad, "Setting duration bytes: {}", size);
|
||||||
q.set(size.bytes());
|
q.set(size.bytes());
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@ -402,9 +402,9 @@ impl Decrypter {
|
||||||
let state = state.as_mut().unwrap();
|
let state = state.as_mut().unwrap();
|
||||||
|
|
||||||
state.initial_nonce = Some(nonce);
|
state.initial_nonce = Some(nonce);
|
||||||
gst::debug!(CAT, imp: self, "Setting nonce to: {:?}", nonce.0);
|
gst::debug!(CAT, imp = self, "Setting nonce to: {:?}", nonce.0);
|
||||||
state.block_size = Some(block_size);
|
state.block_size = Some(block_size);
|
||||||
gst::debug!(CAT, imp: self, "Setting block size to: {}", block_size);
|
gst::debug!(CAT, imp = self, "Setting block size to: {}", block_size);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -420,8 +420,8 @@ impl Decrypter {
|
||||||
+ (chunk_index * block_size as u64)
|
+ (chunk_index * block_size as u64)
|
||||||
+ (chunk_index * box_::MACBYTES as u64);
|
+ (chunk_index * box_::MACBYTES as u64);
|
||||||
|
|
||||||
gst::debug!(CAT, obj: pad, "Pull offset: {}", pull_offset);
|
gst::debug!(CAT, obj = pad, "Pull offset: {}", pull_offset);
|
||||||
gst::debug!(CAT, obj: pad, "block size: {}", block_size);
|
gst::debug!(CAT, obj = pad, "block size: {}", block_size);
|
||||||
|
|
||||||
// calculate how many chunks are needed, if we need something like 3.2
|
// calculate how many chunks are needed, if we need something like 3.2
|
||||||
// round the number to 4 and cut the buffer afterwards.
|
// round the number to 4 and cut the buffer afterwards.
|
||||||
|
@ -440,7 +440,7 @@ impl Decrypter {
|
||||||
|
|
||||||
// Read at least one chunk in case 0 bytes were requested
|
// Read at least one chunk in case 0 bytes were requested
|
||||||
let total_chunks = u32::max((checked - 1) / block_size, 1);
|
let total_chunks = u32::max((checked - 1) / block_size, 1);
|
||||||
gst::debug!(CAT, obj: pad, "Blocks to be pulled: {}", total_chunks);
|
gst::debug!(CAT, obj = pad, "Blocks to be pulled: {}", total_chunks);
|
||||||
|
|
||||||
// Pull a buffer of all the chunks we will need
|
// Pull a buffer of all the chunks we will need
|
||||||
let checked_size = total_chunks.checked_mul(block_size).ok_or_else(|| {
|
let checked_size = total_chunks.checked_mul(block_size).ok_or_else(|| {
|
||||||
|
@ -457,18 +457,29 @@ impl Decrypter {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let total_size = checked_size + (total_chunks * box_::MACBYTES as u32);
|
let total_size = checked_size + (total_chunks * box_::MACBYTES as u32);
|
||||||
gst::debug!(CAT, obj: pad, "Requested pull size: {}", total_size);
|
gst::debug!(CAT, obj = pad, "Requested pull size: {}", total_size);
|
||||||
|
|
||||||
self.sinkpad.pull_range(pull_offset, total_size).map_err(|err| {
|
self.sinkpad
|
||||||
|
.pull_range(pull_offset, total_size)
|
||||||
|
.map_err(|err| {
|
||||||
match err {
|
match err {
|
||||||
gst::FlowError::Flushing => {
|
gst::FlowError::Flushing => {
|
||||||
gst::debug!(CAT, obj: self.sinkpad, "Pausing after pulling buffer, reason: flushing");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
obj = self.sinkpad,
|
||||||
|
"Pausing after pulling buffer, reason: flushing"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
gst::FlowError::Eos => {
|
gst::FlowError::Eos => {
|
||||||
gst::debug!(CAT, obj: self.sinkpad, "Eos");
|
gst::debug!(CAT, obj = self.sinkpad, "Eos");
|
||||||
}
|
}
|
||||||
flow => {
|
flow => {
|
||||||
gst::error!(CAT, obj: self.sinkpad, "Failed to pull, reason: {:?}", flow);
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
obj = self.sinkpad,
|
||||||
|
"Failed to pull, reason: {:?}",
|
||||||
|
flow
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -493,11 +504,11 @@ impl Decrypter {
|
||||||
state.block_size.expect("Block size wasn't set")
|
state.block_size.expect("Block size wasn't set")
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::debug!(CAT, obj: pad, "Requested offset: {}", offset);
|
gst::debug!(CAT, obj = pad, "Requested offset: {}", offset);
|
||||||
gst::debug!(CAT, obj: pad, "Requested size: {}", requested_size);
|
gst::debug!(CAT, obj = pad, "Requested size: {}", requested_size);
|
||||||
|
|
||||||
let chunk_index = offset / block_size as u64;
|
let chunk_index = offset / block_size as u64;
|
||||||
gst::debug!(CAT, obj: pad, "Stream Block index: {}", chunk_index);
|
gst::debug!(CAT, obj = pad, "Stream Block index: {}", chunk_index);
|
||||||
|
|
||||||
let pull_offset = offset - (chunk_index * block_size as u64);
|
let pull_offset = offset - (chunk_index * block_size as u64);
|
||||||
assert!(pull_offset <= u32::MAX as u64);
|
assert!(pull_offset <= u32::MAX as u64);
|
||||||
|
@ -670,7 +681,7 @@ impl ElementImpl for Decrypter {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::debug!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::debug!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -166,7 +166,7 @@ impl Encrypter {
|
||||||
pad: &gst::Pad,
|
pad: &gst::Pad,
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(CAT, obj: pad, "Handling buffer {:?}", buffer);
|
gst::log!(CAT, obj = pad, "Handling buffer {:?}", buffer);
|
||||||
|
|
||||||
let mut buffers = BufferVec::new();
|
let mut buffers = BufferVec::new();
|
||||||
let mut state_guard = self.state.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
|
@ -193,7 +193,7 @@ impl Encrypter {
|
||||||
|
|
||||||
for buffer in buffers {
|
for buffer in buffers {
|
||||||
self.srcpad.push(buffer).map_err(|err| {
|
self.srcpad.push(buffer).map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to push buffer {:?}", err);
|
gst::error!(CAT, imp = self, "Failed to push buffer {:?}", err);
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ impl Encrypter {
|
||||||
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling event {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling event {:?}", event);
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Caps(_) => {
|
EventView::Caps(_) => {
|
||||||
|
@ -236,7 +236,7 @@ impl Encrypter {
|
||||||
|
|
||||||
for buffer in buffers {
|
for buffer in buffers {
|
||||||
if let Err(err) = self.srcpad.push(buffer) {
|
if let Err(err) = self.srcpad.push(buffer) {
|
||||||
gst::error!(CAT, imp: self, "Failed to push buffer at EOS {:?}", err);
|
gst::error!(CAT, imp = self, "Failed to push buffer at EOS {:?}", err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ impl Encrypter {
|
||||||
fn src_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn src_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling event {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling event {:?}", event);
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Seek(_) => false,
|
EventView::Seek(_) => false,
|
||||||
|
@ -261,7 +261,7 @@ impl Encrypter {
|
||||||
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling query {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling query {:?}", query);
|
||||||
|
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
QueryViewMut::Seeking(q) => {
|
QueryViewMut::Seeking(q) => {
|
||||||
|
@ -271,7 +271,7 @@ impl Encrypter {
|
||||||
gst::GenericFormattedValue::none_for_format(format),
|
gst::GenericFormattedValue::none_for_format(format),
|
||||||
gst::GenericFormattedValue::none_for_format(format),
|
gst::GenericFormattedValue::none_for_format(format),
|
||||||
);
|
);
|
||||||
gst::log!(CAT, obj: pad, "Returning {:?}", q.query_mut());
|
gst::log!(CAT, obj = pad, "Returning {:?}", q.query_mut());
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
QueryViewMut::Duration(q) => {
|
QueryViewMut::Duration(q) => {
|
||||||
|
@ -311,7 +311,7 @@ impl Encrypter {
|
||||||
// add static offsets
|
// add static offsets
|
||||||
let size = size + crate::HEADERS_SIZE as u64;
|
let size = size + crate::HEADERS_SIZE as u64;
|
||||||
|
|
||||||
gst::debug!(CAT, obj: pad, "Setting duration bytes: {}", size);
|
gst::debug!(CAT, obj = pad, "Setting duration bytes: {}", size);
|
||||||
q.set(size.bytes());
|
q.set(size.bytes());
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@ -492,7 +492,7 @@ impl ElementImpl for Encrypter {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::debug!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::debug!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
macro_rules! debug_or_trace {
|
macro_rules! debug_or_trace {
|
||||||
($cat:expr, $raise_log_level:expr, $qual:ident: $obj:expr, $rest:tt $(,)?) => {
|
($cat:expr, $raise_log_level:expr, $qual:ident = $obj:expr, $rest:tt $(,)?) => {
|
||||||
if $raise_log_level {
|
if $raise_log_level {
|
||||||
gst::debug!($cat, $qual: $obj, $rest);
|
gst::debug!($cat, $qual = $obj, $rest);
|
||||||
} else {
|
} else {
|
||||||
gst::trace!($cat, $qual: $obj, $rest);
|
gst::trace!($cat, $qual = $obj, $rest);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! log_or_trace {
|
macro_rules! log_or_trace {
|
||||||
($cat:expr, $raise_log_level:expr, $qual:ident: $obj:expr, $rest:tt $(,)?) => {
|
($cat:expr, $raise_log_level:expr, $qual:ident = $obj:expr, $rest:tt $(,)?) => {
|
||||||
if $raise_log_level {
|
if $raise_log_level {
|
||||||
gst::log!($cat, $qual: $obj, $rest);
|
gst::log!($cat, $qual = $obj, $rest);
|
||||||
} else {
|
} else {
|
||||||
gst::trace!($cat, $qual: $obj, $rest);
|
gst::trace!($cat, $qual = $obj, $rest);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,14 +43,14 @@ impl PadSinkHandlerInner {
|
||||||
log_or_trace!(
|
log_or_trace!(
|
||||||
CAT,
|
CAT,
|
||||||
self.is_main_elem,
|
self.is_main_elem,
|
||||||
obj: elem,
|
obj = elem,
|
||||||
"Discarding {buffer:?} (flushing)"
|
"Discarding {buffer:?} (flushing)"
|
||||||
);
|
);
|
||||||
|
|
||||||
return Err(gst::FlowError::Flushing);
|
return Err(gst::FlowError::Flushing);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_or_trace!(CAT, self.is_main_elem, obj: elem, "Received {buffer:?}");
|
debug_or_trace!(CAT, self.is_main_elem, obj = elem, "Received {buffer:?}");
|
||||||
|
|
||||||
let dts = buffer
|
let dts = buffer
|
||||||
.dts()
|
.dts()
|
||||||
|
@ -67,18 +67,23 @@ impl PadSinkHandlerInner {
|
||||||
stats.add_buffer(latency, interval);
|
stats.add_buffer(latency, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_or_trace!(CAT, self.is_main_elem, obj: elem, "o latency {latency:.2?}");
|
|
||||||
debug_or_trace!(
|
debug_or_trace!(
|
||||||
CAT,
|
CAT,
|
||||||
self.is_main_elem,
|
self.is_main_elem,
|
||||||
obj: elem,
|
obj = elem,
|
||||||
|
"o latency {latency:.2?}"
|
||||||
|
);
|
||||||
|
debug_or_trace!(
|
||||||
|
CAT,
|
||||||
|
self.is_main_elem,
|
||||||
|
obj = elem,
|
||||||
"o interval {interval:.2?}",
|
"o interval {interval:.2?}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_dts = Some(dts);
|
self.last_dts = Some(dts);
|
||||||
|
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: elem, "Buffer processed");
|
log_or_trace!(CAT, self.is_main_elem, obj = elem, "Buffer processed");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -117,7 +122,7 @@ impl PadSinkHandler for AsyncPadSinkHandler {
|
||||||
EventView::Eos(_) => {
|
EventView::Eos(_) => {
|
||||||
{
|
{
|
||||||
let mut inner = self.0.lock().await;
|
let mut inner = self.0.lock().await;
|
||||||
debug_or_trace!(CAT, inner.is_main_elem, obj: elem, "EOS");
|
debug_or_trace!(CAT, inner.is_main_elem, obj = elem, "EOS");
|
||||||
inner.is_flushing = true;
|
inner.is_flushing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +201,7 @@ pub struct AsyncMutexSink {
|
||||||
impl AsyncMutexSink {
|
impl AsyncMutexSink {
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
debug_or_trace!(CAT, settings.is_main_elem, imp: self, "Preparing");
|
debug_or_trace!(CAT, settings.is_main_elem, imp = self, "Preparing");
|
||||||
let stats = if settings.logs_stats {
|
let stats = if settings.logs_stats {
|
||||||
Some(Stats::new(
|
Some(Stats::new(
|
||||||
settings.max_buffers,
|
settings.max_buffers,
|
||||||
|
@ -207,25 +212,25 @@ impl AsyncMutexSink {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.sink_pad_handler.prepare(settings.is_main_elem, stats);
|
self.sink_pad_handler.prepare(settings.is_main_elem, stats);
|
||||||
debug_or_trace!(CAT, settings.is_main_elem, imp: self, "Prepared");
|
debug_or_trace!(CAT, settings.is_main_elem, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Stopping");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Stopping");
|
||||||
self.sink_pad_handler.stop();
|
self.sink_pad_handler.stop();
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Stopped");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Starting");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Starting");
|
||||||
self.sink_pad_handler.start();
|
self.sink_pad_handler.start();
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Started");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -311,7 +316,7 @@ impl ElementImpl for AsyncMutexSink {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {transition:?}");
|
gst::trace!(CAT, imp = self, "Changing state {transition:?}");
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -42,14 +42,14 @@ impl PadSinkHandlerInner {
|
||||||
log_or_trace!(
|
log_or_trace!(
|
||||||
CAT,
|
CAT,
|
||||||
self.is_main_elem,
|
self.is_main_elem,
|
||||||
obj: elem,
|
obj = elem,
|
||||||
"Discarding {buffer:?} (flushing)"
|
"Discarding {buffer:?} (flushing)"
|
||||||
);
|
);
|
||||||
|
|
||||||
return Err(gst::FlowError::Flushing);
|
return Err(gst::FlowError::Flushing);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_or_trace!(CAT, self.is_main_elem, obj: elem, "Received {buffer:?}");
|
debug_or_trace!(CAT, self.is_main_elem, obj = elem, "Received {buffer:?}");
|
||||||
|
|
||||||
let dts = buffer
|
let dts = buffer
|
||||||
.dts()
|
.dts()
|
||||||
|
@ -66,18 +66,23 @@ impl PadSinkHandlerInner {
|
||||||
stats.add_buffer(latency, interval);
|
stats.add_buffer(latency, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_or_trace!(CAT, self.is_main_elem, obj: elem, "o latency {latency:.2?}");
|
|
||||||
debug_or_trace!(
|
debug_or_trace!(
|
||||||
CAT,
|
CAT,
|
||||||
self.is_main_elem,
|
self.is_main_elem,
|
||||||
obj: elem,
|
obj = elem,
|
||||||
|
"o latency {latency:.2?}"
|
||||||
|
);
|
||||||
|
debug_or_trace!(
|
||||||
|
CAT,
|
||||||
|
self.is_main_elem,
|
||||||
|
obj = elem,
|
||||||
"o interval {interval:.2?}",
|
"o interval {interval:.2?}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_dts = Some(dts);
|
self.last_dts = Some(dts);
|
||||||
|
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: elem, "Buffer processed");
|
log_or_trace!(CAT, self.is_main_elem, obj = elem, "Buffer processed");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -116,7 +121,7 @@ impl PadSinkHandler for SyncPadSinkHandler {
|
||||||
EventView::Eos(_) => {
|
EventView::Eos(_) => {
|
||||||
{
|
{
|
||||||
let mut inner = self.0.lock().unwrap();
|
let mut inner = self.0.lock().unwrap();
|
||||||
debug_or_trace!(CAT, inner.is_main_elem, obj: elem, "EOS");
|
debug_or_trace!(CAT, inner.is_main_elem, obj = elem, "EOS");
|
||||||
inner.is_flushing = true;
|
inner.is_flushing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +194,7 @@ pub struct DirectSink {
|
||||||
impl DirectSink {
|
impl DirectSink {
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
debug_or_trace!(CAT, settings.is_main_elem, imp: self, "Preparing");
|
debug_or_trace!(CAT, settings.is_main_elem, imp = self, "Preparing");
|
||||||
let stats = if settings.logs_stats {
|
let stats = if settings.logs_stats {
|
||||||
Some(Stats::new(
|
Some(Stats::new(
|
||||||
settings.max_buffers,
|
settings.max_buffers,
|
||||||
|
@ -200,25 +205,25 @@ impl DirectSink {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.sink_pad_handler.prepare(settings.is_main_elem, stats);
|
self.sink_pad_handler.prepare(settings.is_main_elem, stats);
|
||||||
debug_or_trace!(CAT, settings.is_main_elem, imp: self, "Prepared");
|
debug_or_trace!(CAT, settings.is_main_elem, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Stopping");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Stopping");
|
||||||
self.sink_pad_handler.stop();
|
self.sink_pad_handler.stop();
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Stopped");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Starting");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Starting");
|
||||||
self.sink_pad_handler.start();
|
self.sink_pad_handler.start();
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Started");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -304,7 +309,7 @@ impl ElementImpl for DirectSink {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {transition:?}");
|
gst::trace!(CAT, imp = self, "Changing state {transition:?}");
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -68,7 +68,7 @@ impl PadSinkHandler for TaskPadSinkHandler {
|
||||||
}
|
}
|
||||||
EventView::Eos(_) => {
|
EventView::Eos(_) => {
|
||||||
let is_main_elem = elem.imp().settings.lock().unwrap().is_main_elem;
|
let is_main_elem = elem.imp().settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, obj: elem, "EOS");
|
debug_or_trace!(CAT, is_main_elem, obj = elem, "EOS");
|
||||||
|
|
||||||
// When each element sends its own EOS message,
|
// When each element sends its own EOS message,
|
||||||
// it takes ages for the pipeline to process all of them.
|
// it takes ages for the pipeline to process all of them.
|
||||||
|
@ -137,13 +137,13 @@ impl TaskImpl for TaskSinkTask {
|
||||||
type Item = StreamItem;
|
type Item = StreamItem;
|
||||||
|
|
||||||
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Preparing Task");
|
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Preparing Task");
|
||||||
future::ok(()).boxed()
|
future::ok(()).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async {
|
async {
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Starting Task");
|
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Starting Task");
|
||||||
self.last_dts = None;
|
self.last_dts = None;
|
||||||
if let Some(stats) = self.stats.as_mut() {
|
if let Some(stats) = self.stats.as_mut() {
|
||||||
stats.start();
|
stats.start();
|
||||||
|
@ -156,7 +156,7 @@ impl TaskImpl for TaskSinkTask {
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async {
|
async {
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Stopping Task");
|
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Stopping Task");
|
||||||
self.flush();
|
self.flush();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ impl TaskImpl for TaskSinkTask {
|
||||||
|
|
||||||
fn handle_item(&mut self, item: StreamItem) -> BoxFuture<'_, Result<(), gst::FlowError>> {
|
fn handle_item(&mut self, item: StreamItem) -> BoxFuture<'_, Result<(), gst::FlowError>> {
|
||||||
async move {
|
async move {
|
||||||
debug_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Received {item:?}");
|
debug_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Received {item:?}");
|
||||||
|
|
||||||
match item {
|
match item {
|
||||||
StreamItem::Buffer(buffer) => {
|
StreamItem::Buffer(buffer) => {
|
||||||
|
@ -194,20 +194,20 @@ impl TaskImpl for TaskSinkTask {
|
||||||
debug_or_trace!(
|
debug_or_trace!(
|
||||||
CAT,
|
CAT,
|
||||||
self.is_main_elem,
|
self.is_main_elem,
|
||||||
obj: self.elem,
|
obj = self.elem,
|
||||||
"o latency {latency:.2?}",
|
"o latency {latency:.2?}",
|
||||||
);
|
);
|
||||||
debug_or_trace!(
|
debug_or_trace!(
|
||||||
CAT,
|
CAT,
|
||||||
self.is_main_elem,
|
self.is_main_elem,
|
||||||
obj: self.elem,
|
obj = self.elem,
|
||||||
"o interval {interval:.2?}",
|
"o interval {interval:.2?}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_dts = Some(dts);
|
self.last_dts = Some(dts);
|
||||||
|
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Buffer processed");
|
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Buffer processed");
|
||||||
}
|
}
|
||||||
StreamItem::Event(evt) => {
|
StreamItem::Event(evt) => {
|
||||||
if let EventView::Segment(evt) = evt.view() {
|
if let EventView::Segment(evt) = evt.view() {
|
||||||
|
@ -249,7 +249,7 @@ impl TaskSink {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
debug_or_trace!(CAT, settings.is_main_elem, imp: self, "Preparing");
|
debug_or_trace!(CAT, settings.is_main_elem, imp = self, "Preparing");
|
||||||
|
|
||||||
let ts_ctx = Context::acquire(&settings.context, settings.context_wait).map_err(|err| {
|
let ts_ctx = Context::acquire(&settings.context, settings.context_wait).map_err(|err| {
|
||||||
error_msg!(
|
error_msg!(
|
||||||
|
@ -265,32 +265,32 @@ impl TaskSink {
|
||||||
|
|
||||||
*self.item_sender.lock().unwrap() = Some(item_sender);
|
*self.item_sender.lock().unwrap() = Some(item_sender);
|
||||||
|
|
||||||
debug_or_trace!(CAT, settings.is_main_elem, imp: self, "Prepared");
|
debug_or_trace!(CAT, settings.is_main_elem, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Unpreparing");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Unpreparing");
|
||||||
self.task.unprepare().block_on().unwrap();
|
self.task.unprepare().block_on().unwrap();
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Unprepared");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Stopping");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Stopping");
|
||||||
self.task.stop().block_on()?;
|
self.task.stop().block_on()?;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Stopped");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Starting");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Starting");
|
||||||
self.task.start().block_on()?;
|
self.task.start().block_on()?;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Started");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -376,7 +376,7 @@ impl ElementImpl for TaskSink {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {transition:?}");
|
gst::trace!(CAT, imp = self, "Changing state {transition:?}");
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl TaskImpl for SrcTask {
|
||||||
let settings = imp.settings.lock().unwrap();
|
let settings = imp.settings.lock().unwrap();
|
||||||
self.is_main_elem = settings.is_main_elem;
|
self.is_main_elem = settings.is_main_elem;
|
||||||
|
|
||||||
log_or_trace!(CAT, self.is_main_elem, imp: imp, "Preparing Task");
|
log_or_trace!(CAT, self.is_main_elem, imp = imp, "Preparing Task");
|
||||||
|
|
||||||
self.push_period = settings.push_period;
|
self.push_period = settings.push_period;
|
||||||
self.num_buffers = settings.num_buffers;
|
self.num_buffers = settings.num_buffers;
|
||||||
|
@ -113,12 +113,17 @@ impl TaskImpl for SrcTask {
|
||||||
|
|
||||||
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Starting Task");
|
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Starting Task");
|
||||||
|
|
||||||
if self.need_initial_events {
|
if self.need_initial_events {
|
||||||
let imp = self.elem.imp();
|
let imp = self.elem.imp();
|
||||||
|
|
||||||
debug_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Pushing initial events");
|
debug_or_trace!(
|
||||||
|
CAT,
|
||||||
|
self.is_main_elem,
|
||||||
|
obj = self.elem,
|
||||||
|
"Pushing initial events"
|
||||||
|
);
|
||||||
|
|
||||||
let stream_id =
|
let stream_id =
|
||||||
format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
||||||
|
@ -157,7 +162,7 @@ impl TaskImpl for SrcTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Stopping Task");
|
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Stopping Task");
|
||||||
self.buffer_pool.set_active(false).unwrap();
|
self.buffer_pool.set_active(false).unwrap();
|
||||||
self.timer = None;
|
self.timer = None;
|
||||||
self.need_initial_events = true;
|
self.need_initial_events = true;
|
||||||
|
@ -167,9 +172,9 @@ impl TaskImpl for SrcTask {
|
||||||
|
|
||||||
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
|
fn try_next(&mut self) -> BoxFuture<'_, Result<(), gst::FlowError>> {
|
||||||
async move {
|
async move {
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Awaiting timer");
|
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Awaiting timer");
|
||||||
self.timer.as_mut().unwrap().next().await;
|
self.timer.as_mut().unwrap().next().await;
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Timer ticked");
|
log_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Timer ticked");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -190,13 +195,18 @@ impl TaskImpl for SrcTask {
|
||||||
buffer
|
buffer
|
||||||
})
|
})
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, obj: self.elem, "Failed to acquire buffer {err}");
|
gst::error!(CAT, obj = self.elem, "Failed to acquire buffer {err}");
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
debug_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Forwarding buffer");
|
debug_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Forwarding buffer");
|
||||||
self.elem.imp().src_pad.push(buffer).await?;
|
self.elem.imp().src_pad.push(buffer).await?;
|
||||||
log_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Successfully pushed buffer");
|
log_or_trace!(
|
||||||
|
CAT,
|
||||||
|
self.is_main_elem,
|
||||||
|
obj = self.elem,
|
||||||
|
"Successfully pushed buffer"
|
||||||
|
);
|
||||||
|
|
||||||
self.buffer_count += 1;
|
self.buffer_count += 1;
|
||||||
|
|
||||||
|
@ -213,22 +223,22 @@ impl TaskImpl for SrcTask {
|
||||||
async move {
|
async move {
|
||||||
match err {
|
match err {
|
||||||
gst::FlowError::Eos => {
|
gst::FlowError::Eos => {
|
||||||
debug_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Pushing EOS");
|
debug_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Pushing EOS");
|
||||||
|
|
||||||
let imp = self.elem.imp();
|
let imp = self.elem.imp();
|
||||||
if !imp.src_pad.push_event(gst::event::Eos::new()).await {
|
if !imp.src_pad.push_event(gst::event::Eos::new()).await {
|
||||||
gst::error!(CAT, imp: imp, "Error pushing EOS");
|
gst::error!(CAT, imp = imp, "Error pushing EOS");
|
||||||
}
|
}
|
||||||
|
|
||||||
task::Trigger::Stop
|
task::Trigger::Stop
|
||||||
}
|
}
|
||||||
gst::FlowError::Flushing => {
|
gst::FlowError::Flushing => {
|
||||||
debug_or_trace!(CAT, self.is_main_elem, obj: self.elem, "Flushing");
|
debug_or_trace!(CAT, self.is_main_elem, obj = self.elem, "Flushing");
|
||||||
|
|
||||||
task::Trigger::FlushStart
|
task::Trigger::FlushStart
|
||||||
}
|
}
|
||||||
err => {
|
err => {
|
||||||
gst::error!(CAT, obj: self.elem, "Got error {err}");
|
gst::error!(CAT, obj = self.elem, "Got error {err}");
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
&self.elem,
|
&self.elem,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -254,7 +264,7 @@ pub struct TestSrc {
|
||||||
impl TestSrc {
|
impl TestSrc {
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Preparing");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Preparing");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
let ts_ctx = Context::acquire(&settings.context, settings.context_wait).map_err(|err| {
|
let ts_ctx = Context::acquire(&settings.context, settings.context_wait).map_err(|err| {
|
||||||
|
@ -269,41 +279,41 @@ impl TestSrc {
|
||||||
.prepare(SrcTask::new(self.obj().clone()), ts_ctx)
|
.prepare(SrcTask::new(self.obj().clone()), ts_ctx)
|
||||||
.block_on()?;
|
.block_on()?;
|
||||||
|
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Prepared");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Unpreparing");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Unpreparing");
|
||||||
self.task.unprepare().block_on().unwrap();
|
self.task.unprepare().block_on().unwrap();
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Unprepared");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Stopping");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Stopping");
|
||||||
self.task.stop().block_on()?;
|
self.task.stop().block_on()?;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Stopped");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Starting");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Starting");
|
||||||
self.task.start().block_on()?;
|
self.task.start().block_on()?;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Started");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
let is_main_elem = self.settings.lock().unwrap().is_main_elem;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Pausing");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Pausing");
|
||||||
self.task.pause().block_on()?;
|
self.task.pause().block_on()?;
|
||||||
debug_or_trace!(CAT, is_main_elem, imp: self, "Paused");
|
debug_or_trace!(CAT, is_main_elem, imp = self, "Paused");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -453,7 +463,7 @@ impl ElementImpl for TestSrc {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {transition:?}");
|
gst::trace!(CAT, imp = self, "Changing state {transition:?}");
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl PadSrcHandler for AppSrcPadHandler {
|
||||||
type ElementImpl = AppSrc;
|
type ElementImpl = AppSrc;
|
||||||
|
|
||||||
fn src_event(self, pad: &gst::Pad, imp: &AppSrc, event: gst::Event) -> bool {
|
fn src_event(self, pad: &gst::Pad, imp: &AppSrc, event: gst::Event) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
let ret = match event.view() {
|
let ret = match event.view() {
|
||||||
|
@ -94,16 +94,16 @@ impl PadSrcHandler for AppSrcPadHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret {
|
if ret {
|
||||||
gst::log!(CAT, obj: pad, "Handled {:?}", event);
|
gst::log!(CAT, obj = pad, "Handled {:?}", event);
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, obj: pad, "Didn't handle {:?}", event);
|
gst::log!(CAT, obj = pad, "Didn't handle {:?}", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(self, pad: &gst::Pad, imp: &AppSrc, query: &mut gst::QueryRef) -> bool {
|
fn src_query(self, pad: &gst::Pad, imp: &AppSrc, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling {:?}", query);
|
||||||
|
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
let ret = match query.view_mut() {
|
let ret = match query.view_mut() {
|
||||||
|
@ -135,9 +135,9 @@ impl PadSrcHandler for AppSrcPadHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret {
|
if ret {
|
||||||
gst::log!(CAT, obj: pad, "Handled {:?}", query);
|
gst::log!(CAT, obj = pad, "Handled {:?}", query);
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, obj: pad, "Didn't handle {:?}", query);
|
gst::log!(CAT, obj = pad, "Didn't handle {:?}", query);
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
@ -169,11 +169,11 @@ impl AppSrcTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn push_item(&mut self, item: StreamItem) -> Result<gst::FlowSuccess, gst::FlowError> {
|
async fn push_item(&mut self, item: StreamItem) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(CAT, obj: self.element, "Handling {:?}", item);
|
gst::log!(CAT, obj = self.element, "Handling {:?}", item);
|
||||||
let appsrc = self.element.imp();
|
let appsrc = self.element.imp();
|
||||||
|
|
||||||
if self.need_initial_events {
|
if self.need_initial_events {
|
||||||
gst::debug!(CAT, obj: self.element, "Pushing initial events");
|
gst::debug!(CAT, obj = self.element, "Pushing initial events");
|
||||||
|
|
||||||
let stream_id = format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
let stream_id = format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
||||||
let stream_start_evt = gst::event::StreamStart::builder(&stream_id)
|
let stream_start_evt = gst::event::StreamStart::builder(&stream_id)
|
||||||
|
@ -203,7 +203,7 @@ impl AppSrcTask {
|
||||||
|
|
||||||
match item {
|
match item {
|
||||||
StreamItem::Buffer(buffer) => {
|
StreamItem::Buffer(buffer) => {
|
||||||
gst::log!(CAT, obj: self.element, "Forwarding {:?}", buffer);
|
gst::log!(CAT, obj = self.element, "Forwarding {:?}", buffer);
|
||||||
appsrc.src_pad.push(buffer).await
|
appsrc.src_pad.push(buffer).await
|
||||||
}
|
}
|
||||||
StreamItem::Event(event) => {
|
StreamItem::Event(event) => {
|
||||||
|
@ -213,7 +213,7 @@ impl AppSrcTask {
|
||||||
Err(gst::FlowError::Eos)
|
Err(gst::FlowError::Eos)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::log!(CAT, obj: self.element, "Forwarding {:?}", event);
|
gst::log!(CAT, obj = self.element, "Forwarding {:?}", event);
|
||||||
appsrc.src_pad.push_event(event).await;
|
appsrc.src_pad.push_event(event).await;
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
}
|
}
|
||||||
|
@ -241,18 +241,18 @@ impl TaskImpl for AppSrcTask {
|
||||||
let res = self.push_item(item).await;
|
let res = self.push_item(item).await;
|
||||||
match res {
|
match res {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
gst::log!(CAT, obj: self.element, "Successfully pushed item");
|
gst::log!(CAT, obj = self.element, "Successfully pushed item");
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Eos) => {
|
Err(gst::FlowError::Eos) => {
|
||||||
gst::debug!(CAT, obj: self.element, "EOS");
|
gst::debug!(CAT, obj = self.element, "EOS");
|
||||||
let appsrc = self.element.imp();
|
let appsrc = self.element.imp();
|
||||||
appsrc.src_pad.push_event(gst::event::Eos::new()).await;
|
appsrc.src_pad.push_event(gst::event::Eos::new()).await;
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Flushing) => {
|
Err(gst::FlowError::Flushing) => {
|
||||||
gst::debug!(CAT, obj: self.element, "Flushing");
|
gst::debug!(CAT, obj = self.element, "Flushing");
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, obj: self.element, "Got error {}", err);
|
gst::error!(CAT, obj = self.element, "Got error {}", err);
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
&self.element,
|
&self.element,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -269,13 +269,13 @@ impl TaskImpl for AppSrcTask {
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Stopping task");
|
gst::log!(CAT, obj = self.element, "Stopping task");
|
||||||
|
|
||||||
self.flush();
|
self.flush();
|
||||||
self.need_initial_events = true;
|
self.need_initial_events = true;
|
||||||
self.need_segment = true;
|
self.need_segment = true;
|
||||||
|
|
||||||
gst::log!(CAT, obj: self.element, "Task stopped");
|
gst::log!(CAT, obj = self.element, "Task stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -283,12 +283,12 @@ impl TaskImpl for AppSrcTask {
|
||||||
|
|
||||||
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Starting task flush");
|
gst::log!(CAT, obj = self.element, "Starting task flush");
|
||||||
|
|
||||||
self.flush();
|
self.flush();
|
||||||
self.need_segment = true;
|
self.need_segment = true;
|
||||||
|
|
||||||
gst::log!(CAT, obj: self.element, "Task flush started");
|
gst::log!(CAT, obj = self.element, "Task flush started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -308,7 +308,7 @@ impl AppSrc {
|
||||||
fn push_buffer(&self, mut buffer: gst::Buffer) -> bool {
|
fn push_buffer(&self, mut buffer: gst::Buffer) -> bool {
|
||||||
let state = self.task.lock_state();
|
let state = self.task.lock_state();
|
||||||
if *state != TaskState::Started && *state != TaskState::Paused {
|
if *state != TaskState::Started && *state != TaskState::Paused {
|
||||||
gst::debug!(CAT, imp: self, "Rejecting buffer due to element state");
|
gst::debug!(CAT, imp = self, "Rejecting buffer due to element state");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ impl AppSrc {
|
||||||
buffer.set_dts(now.opt_checked_sub(base_time).ok().flatten());
|
buffer.set_dts(now.opt_checked_sub(base_time).ok().flatten());
|
||||||
buffer.set_pts(None);
|
buffer.set_pts(None);
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Don't have a clock yet");
|
gst::error!(CAT, imp = self, "Don't have a clock yet");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,7 +336,7 @@ impl AppSrc {
|
||||||
{
|
{
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to queue buffer: {}", err);
|
gst::error!(CAT, imp = self, "Failed to queue buffer: {}", err);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,14 +352,14 @@ impl AppSrc {
|
||||||
match sender.try_send(StreamItem::Event(gst::event::Eos::new())) {
|
match sender.try_send(StreamItem::Event(gst::event::Eos::new())) {
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to queue EOS: {}", err);
|
gst::error!(CAT, imp = self, "Failed to queue EOS: {}", err);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Preparing");
|
gst::debug!(CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
let context =
|
let context =
|
||||||
|
@ -386,38 +386,38 @@ impl AppSrc {
|
||||||
.prepare(AppSrcTask::new(self.obj().clone(), receiver), context)
|
.prepare(AppSrcTask::new(self.obj().clone(), receiver), context)
|
||||||
.block_on()?;
|
.block_on()?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Prepared");
|
gst::debug!(CAT, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Unpreparing");
|
gst::debug!(CAT, imp = self, "Unpreparing");
|
||||||
|
|
||||||
*self.sender.lock().unwrap() = None;
|
*self.sender.lock().unwrap() = None;
|
||||||
self.task.unprepare().block_on().unwrap();
|
self.task.unprepare().block_on().unwrap();
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Unprepared");
|
gst::debug!(CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Stopping");
|
gst::debug!(CAT, imp = self, "Stopping");
|
||||||
self.task.stop().block_on()?;
|
self.task.stop().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Stopped");
|
gst::debug!(CAT, imp = self, "Stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Starting");
|
gst::debug!(CAT, imp = self, "Starting");
|
||||||
self.task.start().block_on()?;
|
self.task.start().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Started");
|
gst::debug!(CAT, imp = self, "Started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Pausing");
|
gst::debug!(CAT, imp = self, "Pausing");
|
||||||
self.task.pause().block_on()?;
|
self.task.pause().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Paused");
|
gst::debug!(CAT, imp = self, "Paused");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -598,7 +598,7 @@ impl ElementImpl for AppSrc {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -90,7 +90,7 @@ impl PadSrcHandler for AudioTestSrcPadHandler {
|
||||||
type ElementImpl = AudioTestSrc;
|
type ElementImpl = AudioTestSrc;
|
||||||
|
|
||||||
fn src_query(self, pad: &gst::Pad, imp: &Self::ElementImpl, query: &mut gst::QueryRef) -> bool {
|
fn src_query(self, pad: &gst::Pad, imp: &Self::ElementImpl, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::debug!(CAT, obj: pad, "Received {query:?}");
|
gst::debug!(CAT, obj = pad, "Received {query:?}");
|
||||||
|
|
||||||
if let gst::QueryViewMut::Latency(q) = query.view_mut() {
|
if let gst::QueryViewMut::Latency(q) = query.view_mut() {
|
||||||
let settings = imp.settings.lock().unwrap();
|
let settings = imp.settings.lock().unwrap();
|
||||||
|
@ -187,17 +187,17 @@ impl AudioTestSrcTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut caps = pad.peer_query_caps(Some(&DEFAULT_CAPS));
|
let mut caps = pad.peer_query_caps(Some(&DEFAULT_CAPS));
|
||||||
gst::debug!(CAT, imp: imp, "Peer returned {caps:?}");
|
gst::debug!(CAT, imp = imp, "Peer returned {caps:?}");
|
||||||
|
|
||||||
if caps.is_empty() {
|
if caps.is_empty() {
|
||||||
pad.mark_reconfigure();
|
pad.mark_reconfigure();
|
||||||
let err = gst::error_msg!(gst::CoreError::Pad, ["No common Caps"]);
|
let err = gst::error_msg!(gst::CoreError::Pad, ["No common Caps"]);
|
||||||
gst::error!(CAT, imp: imp, "{err}");
|
gst::error!(CAT, imp = imp, "{err}");
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if caps.is_any() {
|
if caps.is_any() {
|
||||||
gst::debug!(CAT, imp: imp, "Using our own Caps");
|
gst::debug!(CAT, imp = imp, "Using our own Caps");
|
||||||
caps = DEFAULT_CAPS.clone();
|
caps = DEFAULT_CAPS.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ impl AudioTestSrcTask {
|
||||||
let caps = caps.make_mut();
|
let caps = caps.make_mut();
|
||||||
let s = caps.structure_mut(0).ok_or_else(|| {
|
let s = caps.structure_mut(0).ok_or_else(|| {
|
||||||
let err = gst::error_msg!(gst::CoreError::Pad, ["Invalid peer Caps structure"]);
|
let err = gst::error_msg!(gst::CoreError::Pad, ["Invalid peer Caps structure"]);
|
||||||
gst::error!(CAT, imp: imp, "{err}");
|
gst::error!(CAT, imp = imp, "{err}");
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ impl AudioTestSrcTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
caps.fixate();
|
caps.fixate();
|
||||||
gst::debug!(CAT, imp: imp, "fixated to {caps:?}");
|
gst::debug!(CAT, imp = imp, "fixated to {caps:?}");
|
||||||
|
|
||||||
imp.src_pad.push_event(gst::event::Caps::new(&caps)).await;
|
imp.src_pad.push_event(gst::event::Caps::new(&caps)).await;
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ impl TaskImpl for AudioTestSrcTask {
|
||||||
type Item = gst::Buffer;
|
type Item = gst::Buffer;
|
||||||
|
|
||||||
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
gst::log!(CAT, obj: self.elem, "Preparing Task");
|
gst::log!(CAT, obj = self.elem, "Preparing Task");
|
||||||
|
|
||||||
let imp = self.elem.imp();
|
let imp = self.elem.imp();
|
||||||
let settings = imp.settings.lock().unwrap();
|
let settings = imp.settings.lock().unwrap();
|
||||||
|
@ -260,10 +260,10 @@ impl TaskImpl for AudioTestSrcTask {
|
||||||
|
|
||||||
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.elem, "Starting Task");
|
gst::log!(CAT, obj = self.elem, "Starting Task");
|
||||||
|
|
||||||
if self.need_initial_events {
|
if self.need_initial_events {
|
||||||
gst::debug!(CAT, obj: self.elem, "Pushing initial events");
|
gst::debug!(CAT, obj = self.elem, "Pushing initial events");
|
||||||
|
|
||||||
let stream_id =
|
let stream_id =
|
||||||
format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
||||||
|
@ -311,14 +311,14 @@ impl TaskImpl for AudioTestSrcTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn pause(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
gst::log!(CAT, obj: self.elem, "Pausing Task");
|
gst::log!(CAT, obj = self.elem, "Pausing Task");
|
||||||
self.buffer_pool.set_active(false).unwrap();
|
self.buffer_pool.set_active(false).unwrap();
|
||||||
|
|
||||||
future::ok(()).boxed()
|
future::ok(()).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
gst::log!(CAT, obj: self.elem, "Stopping Task");
|
gst::log!(CAT, obj = self.elem, "Stopping Task");
|
||||||
|
|
||||||
self.need_initial_events = true;
|
self.need_initial_events = true;
|
||||||
self.accumulator = 0.0;
|
self.accumulator = 0.0;
|
||||||
|
@ -331,7 +331,7 @@ impl TaskImpl for AudioTestSrcTask {
|
||||||
let mut buffer = match self.buffer_pool.acquire_buffer(None) {
|
let mut buffer = match self.buffer_pool.acquire_buffer(None) {
|
||||||
Ok(buffer) => buffer,
|
Ok(buffer) => buffer,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, obj: self.elem, "Failed to acquire buffer {}", err);
|
gst::error!(CAT, obj = self.elem, "Failed to acquire buffer {}", err);
|
||||||
return future::err(err).boxed();
|
return future::err(err).boxed();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -399,9 +399,9 @@ impl TaskImpl for AudioTestSrcTask {
|
||||||
async move {
|
async move {
|
||||||
let imp = self.elem.imp();
|
let imp = self.elem.imp();
|
||||||
|
|
||||||
gst::debug!(CAT, imp: imp, "Pushing {buffer:?}");
|
gst::debug!(CAT, imp = imp, "Pushing {buffer:?}");
|
||||||
imp.src_pad.push(buffer).await?;
|
imp.src_pad.push(buffer).await?;
|
||||||
gst::log!(CAT, imp: imp, "Successfully pushed buffer");
|
gst::log!(CAT, imp = imp, "Successfully pushed buffer");
|
||||||
|
|
||||||
self.buffer_count += 1;
|
self.buffer_count += 1;
|
||||||
|
|
||||||
|
@ -442,12 +442,12 @@ impl TaskImpl for AudioTestSrcTask {
|
||||||
async move {
|
async move {
|
||||||
match err {
|
match err {
|
||||||
gst::FlowError::Flushing => {
|
gst::FlowError::Flushing => {
|
||||||
gst::debug!(CAT, obj: self.elem, "Flushing");
|
gst::debug!(CAT, obj = self.elem, "Flushing");
|
||||||
|
|
||||||
task::Trigger::FlushStart
|
task::Trigger::FlushStart
|
||||||
}
|
}
|
||||||
gst::FlowError::Eos => {
|
gst::FlowError::Eos => {
|
||||||
gst::debug!(CAT, obj: self.elem, "EOS");
|
gst::debug!(CAT, obj = self.elem, "EOS");
|
||||||
self.elem
|
self.elem
|
||||||
.imp()
|
.imp()
|
||||||
.src_pad
|
.src_pad
|
||||||
|
@ -457,7 +457,7 @@ impl TaskImpl for AudioTestSrcTask {
|
||||||
task::Trigger::Stop
|
task::Trigger::Stop
|
||||||
}
|
}
|
||||||
err => {
|
err => {
|
||||||
gst::error!(CAT, obj: self.elem, "Got error {err}");
|
gst::error!(CAT, obj = self.elem, "Got error {err}");
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
&self.elem,
|
&self.elem,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -482,7 +482,7 @@ pub struct AudioTestSrc {
|
||||||
|
|
||||||
impl AudioTestSrc {
|
impl AudioTestSrc {
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Preparing");
|
gst::debug!(CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
let context =
|
let context =
|
||||||
|
@ -498,37 +498,37 @@ impl AudioTestSrc {
|
||||||
.prepare(AudioTestSrcTask::new(self.obj().clone()), context)
|
.prepare(AudioTestSrcTask::new(self.obj().clone()), context)
|
||||||
.block_on()?;
|
.block_on()?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Prepared");
|
gst::debug!(CAT, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Unpreparing");
|
gst::debug!(CAT, imp = self, "Unpreparing");
|
||||||
self.task.unprepare().block_on().unwrap();
|
self.task.unprepare().block_on().unwrap();
|
||||||
gst::debug!(CAT, imp: self, "Unprepared");
|
gst::debug!(CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Stopping");
|
gst::debug!(CAT, imp = self, "Stopping");
|
||||||
self.task.stop().block_on()?;
|
self.task.stop().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Stopped");
|
gst::debug!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Starting");
|
gst::debug!(CAT, imp = self, "Starting");
|
||||||
self.task.start().block_on()?;
|
self.task.start().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Started");
|
gst::debug!(CAT, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Pausing");
|
gst::debug!(CAT, imp = self, "Pausing");
|
||||||
self.task.pause().block_on()?;
|
self.task.pause().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Paused");
|
gst::debug!(CAT, imp = self, "Paused");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -695,7 +695,7 @@ impl ElementImpl for AudioTestSrc {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {transition:?}");
|
gst::trace!(CAT, imp = self, "Changing state {transition:?}");
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -126,10 +126,14 @@ impl DataQueue {
|
||||||
pub fn start(&self) {
|
pub fn start(&self) {
|
||||||
let mut inner = self.0.lock().unwrap();
|
let mut inner = self.0.lock().unwrap();
|
||||||
if inner.state == DataQueueState::Started {
|
if inner.state == DataQueueState::Started {
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Data queue already Started");
|
gst::debug!(
|
||||||
|
DATA_QUEUE_CAT,
|
||||||
|
obj = inner.element,
|
||||||
|
"Data queue already Started"
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Starting data queue");
|
gst::debug!(DATA_QUEUE_CAT, obj = inner.element, "Starting data queue");
|
||||||
inner.state = DataQueueState::Started;
|
inner.state = DataQueueState::Started;
|
||||||
inner.wake();
|
inner.wake();
|
||||||
}
|
}
|
||||||
|
@ -137,10 +141,14 @@ impl DataQueue {
|
||||||
pub fn stop(&self) {
|
pub fn stop(&self) {
|
||||||
let mut inner = self.0.lock().unwrap();
|
let mut inner = self.0.lock().unwrap();
|
||||||
if inner.state == DataQueueState::Stopped {
|
if inner.state == DataQueueState::Stopped {
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Data queue already Stopped");
|
gst::debug!(
|
||||||
|
DATA_QUEUE_CAT,
|
||||||
|
obj = inner.element,
|
||||||
|
"Data queue already Stopped"
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Stopping data queue");
|
gst::debug!(DATA_QUEUE_CAT, obj = inner.element, "Stopping data queue");
|
||||||
inner.state = DataQueueState::Stopped;
|
inner.state = DataQueueState::Stopped;
|
||||||
inner.wake();
|
inner.wake();
|
||||||
}
|
}
|
||||||
|
@ -148,7 +156,7 @@ impl DataQueue {
|
||||||
pub fn clear(&self) {
|
pub fn clear(&self) {
|
||||||
let mut inner = self.0.lock().unwrap();
|
let mut inner = self.0.lock().unwrap();
|
||||||
|
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Clearing data queue");
|
gst::debug!(DATA_QUEUE_CAT, obj = inner.element, "Clearing data queue");
|
||||||
|
|
||||||
let src_pad = inner.src_pad.clone();
|
let src_pad = inner.src_pad.clone();
|
||||||
for item in inner.queue.drain(..) {
|
for item in inner.queue.drain(..) {
|
||||||
|
@ -162,7 +170,7 @@ impl DataQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Data queue cleared");
|
gst::debug!(DATA_QUEUE_CAT, obj = inner.element, "Data queue cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&self, item: DataQueueItem) -> Result<(), DataQueueItem> {
|
pub fn push(&self, item: DataQueueItem) -> Result<(), DataQueueItem> {
|
||||||
|
@ -171,7 +179,7 @@ impl DataQueue {
|
||||||
if inner.state == DataQueueState::Stopped {
|
if inner.state == DataQueueState::Stopped {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
DATA_QUEUE_CAT,
|
DATA_QUEUE_CAT,
|
||||||
obj: inner.element,
|
obj = inner.element,
|
||||||
"Rejecting item {:?} in state {:?}",
|
"Rejecting item {:?} in state {:?}",
|
||||||
item,
|
item,
|
||||||
inner.state
|
inner.state
|
||||||
|
@ -179,7 +187,12 @@ impl DataQueue {
|
||||||
return Err(item);
|
return Err(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Pushing item {:?}", item);
|
gst::debug!(
|
||||||
|
DATA_QUEUE_CAT,
|
||||||
|
obj = inner.element,
|
||||||
|
"Pushing item {:?}",
|
||||||
|
item
|
||||||
|
);
|
||||||
|
|
||||||
let (count, bytes) = item.size();
|
let (count, bytes) = item.size();
|
||||||
let queue_ts = inner.queue.iter().filter_map(|i| i.timestamp()).next();
|
let queue_ts = inner.queue.iter().filter_map(|i| i.timestamp()).next();
|
||||||
|
@ -187,14 +200,26 @@ impl DataQueue {
|
||||||
|
|
||||||
if let Some(max) = inner.max_size_buffers {
|
if let Some(max) = inner.max_size_buffers {
|
||||||
if max <= inner.cur_size_buffers {
|
if max <= inner.cur_size_buffers {
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Queue is full (buffers): {} <= {}", max, inner.cur_size_buffers);
|
gst::debug!(
|
||||||
|
DATA_QUEUE_CAT,
|
||||||
|
obj = inner.element,
|
||||||
|
"Queue is full (buffers): {} <= {}",
|
||||||
|
max,
|
||||||
|
inner.cur_size_buffers
|
||||||
|
);
|
||||||
return Err(item);
|
return Err(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(max) = inner.max_size_bytes {
|
if let Some(max) = inner.max_size_bytes {
|
||||||
if max <= inner.cur_size_bytes {
|
if max <= inner.cur_size_bytes {
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Queue is full (bytes): {} <= {}", max, inner.cur_size_bytes);
|
gst::debug!(
|
||||||
|
DATA_QUEUE_CAT,
|
||||||
|
obj = inner.element,
|
||||||
|
"Queue is full (bytes): {} <= {}",
|
||||||
|
max,
|
||||||
|
inner.cur_size_bytes
|
||||||
|
);
|
||||||
return Err(item);
|
return Err(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +233,13 @@ impl DataQueue {
|
||||||
};
|
};
|
||||||
|
|
||||||
if max <= level {
|
if max <= level {
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Queue is full (time): {} <= {}", max, level);
|
gst::debug!(
|
||||||
|
DATA_QUEUE_CAT,
|
||||||
|
obj = inner.element,
|
||||||
|
"Queue is full (time): {} <= {}",
|
||||||
|
max,
|
||||||
|
level
|
||||||
|
);
|
||||||
return Err(item);
|
return Err(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,10 +262,15 @@ impl DataQueue {
|
||||||
match inner.state {
|
match inner.state {
|
||||||
DataQueueState::Started => match inner.queue.pop_front() {
|
DataQueueState::Started => match inner.queue.pop_front() {
|
||||||
None => {
|
None => {
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Data queue is empty");
|
gst::debug!(DATA_QUEUE_CAT, obj = inner.element, "Data queue is empty");
|
||||||
}
|
}
|
||||||
Some(item) => {
|
Some(item) => {
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Popped item {:?}", item);
|
gst::debug!(
|
||||||
|
DATA_QUEUE_CAT,
|
||||||
|
obj = inner.element,
|
||||||
|
"Popped item {:?}",
|
||||||
|
item
|
||||||
|
);
|
||||||
|
|
||||||
let (count, bytes) = item.size();
|
let (count, bytes) = item.size();
|
||||||
inner.cur_size_buffers -= count;
|
inner.cur_size_buffers -= count;
|
||||||
|
@ -244,7 +280,7 @@ impl DataQueue {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DataQueueState::Stopped => {
|
DataQueueState::Stopped => {
|
||||||
gst::debug!(DATA_QUEUE_CAT, obj: inner.element, "Data queue Stopped");
|
gst::debug!(DATA_QUEUE_CAT, obj = inner.element, "Data queue Stopped");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ impl InputSelectorPadSinkHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_active {
|
if is_active {
|
||||||
gst::log!(CAT, obj: pad, "Forwarding {:?}", buffer);
|
gst::log!(CAT, obj = pad, "Forwarding {:?}", buffer);
|
||||||
|
|
||||||
if switched_pad && !buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
if switched_pad && !buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
||||||
let buffer = buffer.make_mut();
|
let buffer = buffer.make_mut();
|
||||||
|
@ -172,7 +172,7 @@ impl PadSinkHandler for InputSelectorPadSinkHandler {
|
||||||
list: gst::BufferList,
|
list: gst::BufferList,
|
||||||
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: pad, "Handling buffer list {:?}", list);
|
gst::log!(CAT, obj = pad, "Handling buffer list {:?}", list);
|
||||||
// TODO: Ideally we would keep the list intact and forward it in one go
|
// TODO: Ideally we would keep the list intact and forward it in one go
|
||||||
for buffer in list.iter_owned() {
|
for buffer in list.iter_owned() {
|
||||||
self.handle_item(&pad, &elem, buffer).await?;
|
self.handle_item(&pad, &elem, buffer).await?;
|
||||||
|
@ -229,14 +229,14 @@ impl PadSinkHandler for InputSelectorPadSinkHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_query(self, pad: &gst::Pad, imp: &InputSelector, query: &mut gst::QueryRef) -> bool {
|
fn sink_query(self, pad: &gst::Pad, imp: &InputSelector, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling query {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling query {:?}", query);
|
||||||
|
|
||||||
if query.is_serialized() {
|
if query.is_serialized() {
|
||||||
// FIXME: How can we do this (drops ALLOCATION and DRAIN)?
|
// FIXME: How can we do this (drops ALLOCATION and DRAIN)?
|
||||||
gst::log!(CAT, obj: pad, "Dropping serialized query {:?}", query);
|
gst::log!(CAT, obj = pad, "Dropping serialized query {:?}", query);
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, obj: pad, "Forwarding query {:?}", query);
|
gst::log!(CAT, obj = pad, "Forwarding query {:?}", query);
|
||||||
imp.src_pad.gst_pad().peer_query(query)
|
imp.src_pad.gst_pad().peer_query(query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ impl PadSrcHandler for InputSelectorPadSrcHandler {
|
||||||
type ElementImpl = InputSelector;
|
type ElementImpl = InputSelector;
|
||||||
|
|
||||||
fn src_query(self, pad: &gst::Pad, imp: &InputSelector, query: &mut gst::QueryRef) -> bool {
|
fn src_query(self, pad: &gst::Pad, imp: &InputSelector, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling {:?}", query);
|
||||||
|
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
|
@ -339,9 +339,9 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
impl InputSelector {
|
impl InputSelector {
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
gst::debug!(CAT, imp: self, "Unpreparing");
|
gst::debug!(CAT, imp = self, "Unpreparing");
|
||||||
*state = State::default();
|
*state = State::default();
|
||||||
gst::debug!(CAT, imp: self, "Unprepared");
|
gst::debug!(CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +515,7 @@ impl ElementImpl for InputSelector {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
if let gst::StateChange::ReadyToNull = transition {
|
if let gst::StateChange::ReadyToNull = transition {
|
||||||
self.unprepare();
|
self.unprepare();
|
||||||
|
|
|
@ -144,7 +144,7 @@ impl SinkHandler {
|
||||||
|
|
||||||
// For resetting if seqnum discontinuities
|
// For resetting if seqnum discontinuities
|
||||||
fn reset(&self, inner: &mut SinkHandlerInner, jb: &JitterBuffer) -> BTreeSet<GapPacket> {
|
fn reset(&self, inner: &mut SinkHandlerInner, jb: &JitterBuffer) -> BTreeSet<GapPacket> {
|
||||||
gst::info!(CAT, imp: jb, "Resetting");
|
gst::info!(CAT, imp = jb, "Resetting");
|
||||||
|
|
||||||
let mut state = jb.state.lock().unwrap();
|
let mut state = jb.state.lock().unwrap();
|
||||||
state.jbuf.flush();
|
state.jbuf.flush();
|
||||||
|
@ -176,17 +176,17 @@ impl SinkHandler {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let s = caps.structure(0).ok_or(gst::FlowError::Error)?;
|
let s = caps.structure(0).ok_or(gst::FlowError::Error)?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: jb, "Parsing {:?}", caps);
|
gst::debug!(CAT, imp = jb, "Parsing {:?}", caps);
|
||||||
|
|
||||||
let payload = s.get::<i32>("payload").map_err(|err| {
|
let payload = s.get::<i32>("payload").map_err(|err| {
|
||||||
gst::debug!(CAT, imp: jb, "Caps 'payload': {}", err);
|
gst::debug!(CAT, imp = jb, "Caps 'payload': {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if pt != 0 && payload as u8 != pt {
|
if pt != 0 && payload as u8 != pt {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: jb,
|
imp = jb,
|
||||||
"Caps 'payload' ({}) doesn't match payload type ({})",
|
"Caps 'payload' ({}) doesn't match payload type ({})",
|
||||||
payload,
|
payload,
|
||||||
pt
|
pt
|
||||||
|
@ -196,12 +196,12 @@ impl SinkHandler {
|
||||||
|
|
||||||
inner.last_pt = Some(pt);
|
inner.last_pt = Some(pt);
|
||||||
let clock_rate = s.get::<i32>("clock-rate").map_err(|err| {
|
let clock_rate = s.get::<i32>("clock-rate").map_err(|err| {
|
||||||
gst::debug!(CAT, imp: jb, "Caps 'clock-rate': {}", err);
|
gst::debug!(CAT, imp = jb, "Caps 'clock-rate': {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if clock_rate <= 0 {
|
if clock_rate <= 0 {
|
||||||
gst::debug!(CAT, imp: jb, "Caps 'clock-rate' <= 0");
|
gst::debug!(CAT, imp = jb, "Caps 'clock-rate' <= 0");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
state.clock_rate = Some(clock_rate as u32);
|
state.clock_rate = Some(clock_rate as u32);
|
||||||
|
@ -258,7 +258,7 @@ impl SinkHandler {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: jb,
|
imp = jb,
|
||||||
"Handling big gap, gap packets length: {}",
|
"Handling big gap, gap packets length: {}",
|
||||||
gap_packets_length
|
gap_packets_length
|
||||||
);
|
);
|
||||||
|
@ -272,7 +272,7 @@ impl SinkHandler {
|
||||||
for gap_packet in inner.gap_packets.iter() {
|
for gap_packet in inner.gap_packets.iter() {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: jb,
|
imp = jb,
|
||||||
"Looking at gap packet with seq {}",
|
"Looking at gap packet with seq {}",
|
||||||
gap_packet.seq,
|
gap_packet.seq,
|
||||||
);
|
);
|
||||||
|
@ -292,7 +292,7 @@ impl SinkHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: jb, "all consecutive: {}", all_consecutive);
|
gst::debug!(CAT, imp = jb, "all consecutive: {}", all_consecutive);
|
||||||
|
|
||||||
if all_consecutive && gap_packets_length > 3 {
|
if all_consecutive && gap_packets_length > 3 {
|
||||||
reset = true;
|
reset = true;
|
||||||
|
@ -334,7 +334,7 @@ impl SinkHandler {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: jb,
|
imp = jb,
|
||||||
"Storing buffer, seq: {}, rtptime: {}, pt: {}",
|
"Storing buffer, seq: {}, rtptime: {}, pt: {}",
|
||||||
seq,
|
seq,
|
||||||
rtptime,
|
rtptime,
|
||||||
|
@ -367,7 +367,7 @@ impl SinkHandler {
|
||||||
inner.last_pt = Some(pt);
|
inner.last_pt = Some(pt);
|
||||||
state.clock_rate = None;
|
state.clock_rate = None;
|
||||||
|
|
||||||
gst::debug!(CAT, obj: pad, "New payload type: {}", pt);
|
gst::debug!(CAT, obj = pad, "New payload type: {}", pt);
|
||||||
|
|
||||||
if let Some(caps) = pad.current_caps() {
|
if let Some(caps) = pad.current_caps() {
|
||||||
/* Ignore errors at this point, as we want to emit request-pt-map */
|
/* Ignore errors at this point, as we want to emit request-pt-map */
|
||||||
|
@ -381,7 +381,7 @@ impl SinkHandler {
|
||||||
let caps = element
|
let caps = element
|
||||||
.emit_by_name::<Option<gst::Caps>>("request-pt-map", &[&(pt as u32)])
|
.emit_by_name::<Option<gst::Caps>>("request-pt-map", &[&(pt as u32)])
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::error!(CAT, obj: pad, "Signal 'request-pt-map' returned None");
|
gst::error!(CAT, obj = pad, "Signal 'request-pt-map' returned None");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let mut state = jb.state.lock().unwrap();
|
let mut state = jb.state.lock().unwrap();
|
||||||
|
@ -404,7 +404,7 @@ impl SinkHandler {
|
||||||
if pts.is_none() {
|
if pts.is_none() {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: jb,
|
imp = jb,
|
||||||
"cannot calculate a valid pts for #{}, discard",
|
"cannot calculate a valid pts for #{}, discard",
|
||||||
seq
|
seq
|
||||||
);
|
);
|
||||||
|
@ -437,7 +437,7 @@ impl SinkHandler {
|
||||||
|
|
||||||
if gap <= 0 {
|
if gap <= 0 {
|
||||||
state.stats.num_late += 1;
|
state.stats.num_late += 1;
|
||||||
gst::debug!(CAT, imp: jb, "Dropping late {}", seq);
|
gst::debug!(CAT, imp = jb, "Dropping late {}", seq);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,7 +481,7 @@ impl SinkHandler {
|
||||||
state.earliest_seqnum = Some(seq);
|
state.earliest_seqnum = Some(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Stored buffer");
|
gst::log!(CAT, obj = pad, "Stored buffer");
|
||||||
|
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
}
|
}
|
||||||
|
@ -531,7 +531,7 @@ impl SinkHandler {
|
||||||
{
|
{
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Rescheduling for new item {} < {}",
|
"Rescheduling for new item {} < {}",
|
||||||
next_wakeup.display(),
|
next_wakeup.display(),
|
||||||
previous_next_wakeup.display(),
|
previous_next_wakeup.display(),
|
||||||
|
@ -555,7 +555,7 @@ impl PadSinkHandler for SinkHandler {
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
||||||
async move {
|
async move {
|
||||||
gst::debug!(CAT, obj: pad, "Handling {:?}", buffer);
|
gst::debug!(CAT, obj = pad, "Handling {:?}", buffer);
|
||||||
self.enqueue_item(pad, elem.imp(), Some(buffer))
|
self.enqueue_item(pad, elem.imp(), Some(buffer))
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -564,11 +564,11 @@ impl PadSinkHandler for SinkHandler {
|
||||||
fn sink_event(self, pad: &gst::Pad, jb: &JitterBuffer, event: gst::Event) -> bool {
|
fn sink_event(self, pad: &gst::Pad, jb: &JitterBuffer, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
if let EventView::FlushStart(..) = event.view() {
|
if let EventView::FlushStart(..) = event.view() {
|
||||||
if let Err(err) = jb.task.flush_start().await_maybe_on_context() {
|
if let Err(err) = jb.task.flush_start().await_maybe_on_context() {
|
||||||
gst::error!(CAT, obj: pad, "FlushStart failed {:?}", err);
|
gst::error!(CAT, obj = pad, "FlushStart failed {:?}", err);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
jb,
|
jb,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -579,7 +579,7 @@ impl PadSinkHandler for SinkHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Forwarding {:?}", event);
|
gst::log!(CAT, obj = pad, "Forwarding {:?}", event);
|
||||||
jb.src_pad.gst_pad().push_event(event)
|
jb.src_pad.gst_pad().push_event(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +590,7 @@ impl PadSinkHandler for SinkHandler {
|
||||||
event: gst::Event,
|
event: gst::Event,
|
||||||
) -> BoxFuture<'static, bool> {
|
) -> BoxFuture<'static, bool> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
let jb = elem.imp();
|
let jb = elem.imp();
|
||||||
|
|
||||||
|
@ -603,7 +603,7 @@ impl PadSinkHandler for SinkHandler {
|
||||||
}
|
}
|
||||||
EventView::FlushStop(..) => {
|
EventView::FlushStop(..) => {
|
||||||
if let Err(err) = jb.task.flush_stop().await_maybe_on_context() {
|
if let Err(err) = jb.task.flush_stop().await_maybe_on_context() {
|
||||||
gst::error!(CAT, obj: pad, "FlushStop failed {:?}", err);
|
gst::error!(CAT, obj = pad, "FlushStop failed {:?}", err);
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
elem,
|
elem,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -626,7 +626,7 @@ impl PadSinkHandler for SinkHandler {
|
||||||
|
|
||||||
if forward {
|
if forward {
|
||||||
// FIXME: These events should really be queued up and stay in order
|
// FIXME: These events should really be queued up and stay in order
|
||||||
gst::log!(CAT, obj: pad, "Forwarding serialized {:?}", event);
|
gst::log!(CAT, obj = pad, "Forwarding serialized {:?}", event);
|
||||||
jb.src_pad.push_event(event).await
|
jb.src_pad.push_event(event).await
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
@ -665,7 +665,7 @@ impl SrcHandler {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Generating lost events seq: {}, last popped seq: {:?}",
|
"Generating lost events seq: {}, last popped seq: {:?}",
|
||||||
seqnum,
|
seqnum,
|
||||||
last_popped_seqnum,
|
last_popped_seqnum,
|
||||||
|
@ -801,11 +801,22 @@ impl SrcHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
for event in lost_events {
|
for event in lost_events {
|
||||||
gst::debug!(CAT, obj: jb.src_pad.gst_pad(), "Pushing lost event {:?}", event);
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
obj = jb.src_pad.gst_pad(),
|
||||||
|
"Pushing lost event {:?}",
|
||||||
|
event
|
||||||
|
);
|
||||||
let _ = jb.src_pad.push_event(event).await;
|
let _ = jb.src_pad.push_event(event).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, obj: jb.src_pad.gst_pad(), "Pushing {:?} with seq {:?}", buffer, seq);
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
obj = jb.src_pad.gst_pad(),
|
||||||
|
"Pushing {:?} with seq {:?}",
|
||||||
|
buffer,
|
||||||
|
seq
|
||||||
|
);
|
||||||
|
|
||||||
jb.src_pad.push(buffer).await
|
jb.src_pad.push(buffer).await
|
||||||
}
|
}
|
||||||
|
@ -824,7 +835,7 @@ impl SrcHandler {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Now is {}, EOS {}, earliest pts is {}, packet_spacing {} and latency {}",
|
"Now is {}, EOS {}, earliest pts is {}, packet_spacing {} and latency {}",
|
||||||
now.display(),
|
now.display(),
|
||||||
state.eos,
|
state.eos,
|
||||||
|
@ -834,7 +845,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");
|
||||||
return (now, Some((now, Duration::ZERO)));
|
return (now, Some((now, Duration::ZERO)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,7 +865,7 @@ impl SrcHandler {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Next wakeup at {} with delay {}",
|
"Next wakeup at {} with delay {}",
|
||||||
next_wakeup.display(),
|
next_wakeup.display(),
|
||||||
delay
|
delay
|
||||||
|
@ -870,12 +881,12 @@ impl PadSrcHandler for SrcHandler {
|
||||||
fn src_event(self, pad: &gst::Pad, jb: &JitterBuffer, event: gst::Event) -> bool {
|
fn src_event(self, pad: &gst::Pad, jb: &JitterBuffer, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::FlushStart(..) => {
|
EventView::FlushStart(..) => {
|
||||||
if let Err(err) = jb.task.flush_start().await_maybe_on_context() {
|
if let Err(err) = jb.task.flush_start().await_maybe_on_context() {
|
||||||
gst::error!(CAT, obj: pad, "FlushStart failed {:?}", err);
|
gst::error!(CAT, obj = pad, "FlushStart failed {:?}", err);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
jb,
|
jb,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -887,7 +898,7 @@ impl PadSrcHandler for SrcHandler {
|
||||||
}
|
}
|
||||||
EventView::FlushStop(..) => {
|
EventView::FlushStop(..) => {
|
||||||
if let Err(err) = jb.task.flush_stop().await_maybe_on_context() {
|
if let Err(err) = jb.task.flush_stop().await_maybe_on_context() {
|
||||||
gst::error!(CAT, obj: pad, "FlushStop failed {:?}", err);
|
gst::error!(CAT, obj = pad, "FlushStop failed {:?}", err);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
jb,
|
jb,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -900,14 +911,14 @@ impl PadSrcHandler for SrcHandler {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Forwarding {:?}", event);
|
gst::log!(CAT, obj = pad, "Forwarding {:?}", event);
|
||||||
jb.sink_pad.gst_pad().push_event(event)
|
jb.sink_pad.gst_pad().push_event(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(self, pad: &gst::Pad, jb: &JitterBuffer, query: &mut gst::QueryRef) -> bool {
|
fn src_query(self, pad: &gst::Pad, jb: &JitterBuffer, query: &mut gst::QueryRef) -> bool {
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Forwarding {:?}", query);
|
gst::log!(CAT, obj = pad, "Forwarding {:?}", query);
|
||||||
|
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
QueryViewMut::Latency(q) => {
|
QueryViewMut::Latency(q) => {
|
||||||
|
@ -1030,7 +1041,7 @@ impl TaskImpl for JitterBufferTask {
|
||||||
|
|
||||||
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Starting task");
|
gst::log!(CAT, obj = self.element, "Starting task");
|
||||||
|
|
||||||
self.src_pad_handler.clear();
|
self.src_pad_handler.clear();
|
||||||
self.sink_pad_handler.clear();
|
self.sink_pad_handler.clear();
|
||||||
|
@ -1043,7 +1054,7 @@ impl TaskImpl for JitterBufferTask {
|
||||||
state.jbuf.set_delay(latency);
|
state.jbuf.set_delay(latency);
|
||||||
*jb.state.lock().unwrap() = state;
|
*jb.state.lock().unwrap() = state;
|
||||||
|
|
||||||
gst::log!(CAT, obj: self.element, "Task started");
|
gst::log!(CAT, obj = self.element, "Task started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -1103,9 +1114,9 @@ impl TaskImpl for JitterBufferTask {
|
||||||
|
|
||||||
// Got aborted, reschedule if needed
|
// Got aborted, reschedule if needed
|
||||||
if let Some(delay_fut) = delay_fut {
|
if let Some(delay_fut) = delay_fut {
|
||||||
gst::debug!(CAT, obj: self.element, "Waiting");
|
gst::debug!(CAT, obj = self.element, "Waiting");
|
||||||
if let Err(Aborted) = delay_fut.await {
|
if let Err(Aborted) = delay_fut.await {
|
||||||
gst::debug!(CAT, obj: self.element, "Waiting aborted");
|
gst::debug!(CAT, obj = self.element, "Waiting aborted");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1123,7 +1134,7 @@ impl TaskImpl for JitterBufferTask {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.element,
|
obj = self.element,
|
||||||
"Woke up at {}, earliest_pts {}",
|
"Woke up at {}, earliest_pts {}",
|
||||||
now.display(),
|
now.display(),
|
||||||
state.earliest_pts.display()
|
state.earliest_pts.display()
|
||||||
|
@ -1179,13 +1190,13 @@ impl TaskImpl for JitterBufferTask {
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
match err {
|
match err {
|
||||||
gst::FlowError::Eos => {
|
gst::FlowError::Eos => {
|
||||||
gst::debug!(CAT, obj: self.element, "Pushing EOS event");
|
gst::debug!(CAT, obj = self.element, "Pushing EOS event");
|
||||||
let _ = jb.src_pad.push_event(gst::event::Eos::new()).await;
|
let _ = jb.src_pad.push_event(gst::event::Eos::new()).await;
|
||||||
}
|
}
|
||||||
gst::FlowError::Flushing => {
|
gst::FlowError::Flushing => {
|
||||||
gst::debug!(CAT, obj: self.element, "Flushing")
|
gst::debug!(CAT, obj = self.element, "Flushing")
|
||||||
}
|
}
|
||||||
err => gst::error!(CAT, obj: self.element, "Error {}", err),
|
err => gst::error!(CAT, obj = self.element, "Error {}", err),
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(err);
|
return Err(err);
|
||||||
|
@ -1201,7 +1212,7 @@ impl TaskImpl for JitterBufferTask {
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Stopping task");
|
gst::log!(CAT, obj = self.element, "Stopping task");
|
||||||
|
|
||||||
let jb = self.element.imp();
|
let jb = self.element.imp();
|
||||||
let mut jb_state = jb.state.lock().unwrap();
|
let mut jb_state = jb.state.lock().unwrap();
|
||||||
|
@ -1215,7 +1226,7 @@ impl TaskImpl for JitterBufferTask {
|
||||||
|
|
||||||
*jb_state = State::default();
|
*jb_state = State::default();
|
||||||
|
|
||||||
gst::log!(CAT, obj: self.element, "Task stopped");
|
gst::log!(CAT, obj = self.element, "Task stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -1242,7 +1253,7 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
|
||||||
impl JitterBuffer {
|
impl JitterBuffer {
|
||||||
fn clear_pt_map(&self) {
|
fn clear_pt_map(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Clearing PT map");
|
gst::debug!(CAT, imp = self, "Clearing PT map");
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
state.clock_rate = None;
|
state.clock_rate = None;
|
||||||
|
@ -1250,7 +1261,7 @@ impl JitterBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Preparing");
|
gst::debug!(CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let context = {
|
let context = {
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
|
@ -1264,28 +1275,28 @@ impl JitterBuffer {
|
||||||
)
|
)
|
||||||
.block_on()?;
|
.block_on()?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Prepared");
|
gst::debug!(CAT, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Unpreparing");
|
gst::debug!(CAT, imp = self, "Unpreparing");
|
||||||
self.task.unprepare().block_on().unwrap();
|
self.task.unprepare().block_on().unwrap();
|
||||||
gst::debug!(CAT, imp: self, "Unprepared");
|
gst::debug!(CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Starting");
|
gst::debug!(CAT, imp = self, "Starting");
|
||||||
self.task.start().block_on()?;
|
self.task.start().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Started");
|
gst::debug!(CAT, imp = self, "Started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Stopping");
|
gst::debug!(CAT, imp = self, "Stopping");
|
||||||
self.task.stop().block_on()?;
|
self.task.stop().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Stopped");
|
gst::debug!(CAT, imp = self, "Stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1528,7 +1539,7 @@ impl ElementImpl for JitterBuffer {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -217,7 +217,7 @@ impl PadSinkHandler for ProxySinkPadHandler {
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(SINK_CAT, obj: pad, "Handling {:?}", buffer);
|
gst::log!(SINK_CAT, obj = pad, "Handling {:?}", buffer);
|
||||||
let imp = elem.imp();
|
let imp = elem.imp();
|
||||||
imp.enqueue_item(DataQueueItem::Buffer(buffer)).await
|
imp.enqueue_item(DataQueueItem::Buffer(buffer)).await
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ impl PadSinkHandler for ProxySinkPadHandler {
|
||||||
list: gst::BufferList,
|
list: gst::BufferList,
|
||||||
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(SINK_CAT, obj: pad, "Handling {:?}", list);
|
gst::log!(SINK_CAT, obj = pad, "Handling {:?}", list);
|
||||||
let imp = elem.imp();
|
let imp = elem.imp();
|
||||||
imp.enqueue_item(DataQueueItem::BufferList(list)).await
|
imp.enqueue_item(DataQueueItem::BufferList(list)).await
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ impl PadSinkHandler for ProxySinkPadHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_event(self, pad: &gst::Pad, imp: &ProxySink, event: gst::Event) -> bool {
|
fn sink_event(self, pad: &gst::Pad, imp: &ProxySink, event: gst::Event) -> bool {
|
||||||
gst::debug!(SINK_CAT, obj: pad, "Handling non-serialized {:?}", event);
|
gst::debug!(SINK_CAT, obj = pad, "Handling non-serialized {:?}", event);
|
||||||
|
|
||||||
let src_pad = {
|
let src_pad = {
|
||||||
let proxy_ctx = imp.proxy_ctx.lock().unwrap();
|
let proxy_ctx = imp.proxy_ctx.lock().unwrap();
|
||||||
|
@ -257,12 +257,12 @@ impl PadSinkHandler for ProxySinkPadHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(src_pad) = src_pad {
|
if let Some(src_pad) = src_pad {
|
||||||
gst::log!(SINK_CAT, obj: pad, "Forwarding non-serialized {:?}", event);
|
gst::log!(SINK_CAT, obj = pad, "Forwarding non-serialized {:?}", event);
|
||||||
src_pad.push_event(event)
|
src_pad.push_event(event)
|
||||||
} else {
|
} else {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
SINK_CAT,
|
SINK_CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"No src pad to forward non-serialized {:?} to",
|
"No src pad to forward non-serialized {:?} to",
|
||||||
event
|
event
|
||||||
);
|
);
|
||||||
|
@ -277,7 +277,7 @@ impl PadSinkHandler for ProxySinkPadHandler {
|
||||||
event: gst::Event,
|
event: gst::Event,
|
||||||
) -> BoxFuture<'static, bool> {
|
) -> BoxFuture<'static, bool> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(SINK_CAT, obj: pad, "Handling serialized {:?}", event);
|
gst::log!(SINK_CAT, obj = pad, "Handling serialized {:?}", event);
|
||||||
|
|
||||||
let imp = elem.imp();
|
let imp = elem.imp();
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ impl PadSinkHandler for ProxySinkPadHandler {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(SINK_CAT, obj: pad, "Queuing serialized {:?}", event);
|
gst::log!(SINK_CAT, obj = pad, "Queuing serialized {:?}", event);
|
||||||
imp.enqueue_item(DataQueueItem::Event(event)).await.is_ok()
|
imp.enqueue_item(DataQueueItem::Event(event)).await.is_ok()
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -319,7 +319,7 @@ impl ProxySink {
|
||||||
let proxy_ctx = self.proxy_ctx.lock().unwrap();
|
let proxy_ctx = self.proxy_ctx.lock().unwrap();
|
||||||
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
||||||
|
|
||||||
gst::log!(SINK_CAT, imp: self, "Trying to empty pending queue");
|
gst::log!(SINK_CAT, imp = self, "Trying to empty pending queue");
|
||||||
|
|
||||||
let ProxyContextInner {
|
let ProxyContextInner {
|
||||||
pending_queue: ref mut pq,
|
pending_queue: ref mut pq,
|
||||||
|
@ -344,7 +344,7 @@ impl ProxySink {
|
||||||
|
|
||||||
receiver
|
receiver
|
||||||
} else {
|
} else {
|
||||||
gst::log!(SINK_CAT, imp: self, "Pending queue is empty now");
|
gst::log!(SINK_CAT, imp = self, "Pending queue is empty now");
|
||||||
*pq = None;
|
*pq = None;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -355,13 +355,13 @@ impl ProxySink {
|
||||||
receiver
|
receiver
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::log!(SINK_CAT, imp: self, "Flushing, dropping pending queue");
|
gst::log!(SINK_CAT, imp = self, "Flushing, dropping pending queue");
|
||||||
*pq = None;
|
*pq = None;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::log!(SINK_CAT, imp: self, "Waiting for more queue space");
|
gst::log!(SINK_CAT, imp = self, "Waiting for more queue space");
|
||||||
let _ = more_queue_space_receiver.await;
|
let _ = more_queue_space_receiver.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -431,18 +431,18 @@ impl ProxySink {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
SINK_CAT,
|
SINK_CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Proxy is full - Pushing first item on pending queue"
|
"Proxy is full - Pushing first item on pending queue"
|
||||||
);
|
);
|
||||||
|
|
||||||
if schedule_now {
|
if schedule_now {
|
||||||
gst::log!(SINK_CAT, imp: self, "Scheduling pending queue now");
|
gst::log!(SINK_CAT, imp = self, "Scheduling pending queue now");
|
||||||
pending_queue.scheduled = true;
|
pending_queue.scheduled = true;
|
||||||
|
|
||||||
let wait_fut = self.schedule_pending_queue();
|
let wait_fut = self.schedule_pending_queue();
|
||||||
Some(wait_fut)
|
Some(wait_fut)
|
||||||
} else {
|
} else {
|
||||||
gst::log!(SINK_CAT, imp: self, "Scheduling pending queue later");
|
gst::log!(SINK_CAT, imp = self, "Scheduling pending queue later");
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -462,7 +462,7 @@ impl ProxySink {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(wait_fut) = wait_fut {
|
if let Some(wait_fut) = wait_fut {
|
||||||
gst::log!(SINK_CAT, imp: self, "Blocking until queue has space again");
|
gst::log!(SINK_CAT, imp = self, "Blocking until queue has space again");
|
||||||
wait_fut.await;
|
wait_fut.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ impl ProxySink {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(SINK_CAT, imp: self, "Preparing");
|
gst::debug!(SINK_CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let proxy_context = self.settings.lock().unwrap().proxy_context.to_string();
|
let proxy_context = self.settings.lock().unwrap().proxy_context.to_string();
|
||||||
|
|
||||||
|
@ -491,22 +491,22 @@ impl ProxySink {
|
||||||
|
|
||||||
*self.proxy_ctx.lock().unwrap() = Some(proxy_ctx);
|
*self.proxy_ctx.lock().unwrap() = Some(proxy_ctx);
|
||||||
|
|
||||||
gst::debug!(SINK_CAT, imp: self, "Prepared");
|
gst::debug!(SINK_CAT, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(SINK_CAT, imp: self, "Unpreparing");
|
gst::debug!(SINK_CAT, imp = self, "Unpreparing");
|
||||||
*self.proxy_ctx.lock().unwrap() = None;
|
*self.proxy_ctx.lock().unwrap() = None;
|
||||||
gst::debug!(SINK_CAT, imp: self, "Unprepared");
|
gst::debug!(SINK_CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) {
|
fn start(&self) {
|
||||||
let proxy_ctx = self.proxy_ctx.lock().unwrap();
|
let proxy_ctx = self.proxy_ctx.lock().unwrap();
|
||||||
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
||||||
|
|
||||||
gst::debug!(SINK_CAT, imp: self, "Starting");
|
gst::debug!(SINK_CAT, imp = self, "Starting");
|
||||||
|
|
||||||
{
|
{
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
|
@ -516,19 +516,19 @@ impl ProxySink {
|
||||||
|
|
||||||
shared_ctx.last_res = Ok(gst::FlowSuccess::Ok);
|
shared_ctx.last_res = Ok(gst::FlowSuccess::Ok);
|
||||||
|
|
||||||
gst::debug!(SINK_CAT, imp: self, "Started");
|
gst::debug!(SINK_CAT, imp = self, "Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) {
|
fn stop(&self) {
|
||||||
let proxy_ctx = self.proxy_ctx.lock().unwrap();
|
let proxy_ctx = self.proxy_ctx.lock().unwrap();
|
||||||
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
||||||
|
|
||||||
gst::debug!(SINK_CAT, imp: self, "Stopping");
|
gst::debug!(SINK_CAT, imp = self, "Stopping");
|
||||||
|
|
||||||
let _ = shared_ctx.pending_queue.take();
|
let _ = shared_ctx.pending_queue.take();
|
||||||
shared_ctx.last_res = Err(gst::FlowError::Flushing);
|
shared_ctx.last_res = Err(gst::FlowError::Flushing);
|
||||||
|
|
||||||
gst::debug!(SINK_CAT, imp: self, "Stopped");
|
gst::debug!(SINK_CAT, imp = self, "Stopped");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +631,7 @@ impl ElementImpl for ProxySink {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(SINK_CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(SINK_CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
@ -666,7 +666,7 @@ impl PadSrcHandler for ProxySrcPadHandler {
|
||||||
type ElementImpl = ProxySrc;
|
type ElementImpl = ProxySrc;
|
||||||
|
|
||||||
fn src_event(self, pad: &gst::Pad, imp: &ProxySrc, event: gst::Event) -> bool {
|
fn src_event(self, pad: &gst::Pad, imp: &ProxySrc, event: gst::Event) -> bool {
|
||||||
gst::log!(SRC_CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(SRC_CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
let sink_pad = {
|
let sink_pad = {
|
||||||
let proxy_ctx = imp.proxy_ctx.lock().unwrap();
|
let proxy_ctx = imp.proxy_ctx.lock().unwrap();
|
||||||
|
@ -683,7 +683,7 @@ impl PadSrcHandler for ProxySrcPadHandler {
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::FlushStart(..) => {
|
EventView::FlushStart(..) => {
|
||||||
if let Err(err) = imp.task.flush_start().await_maybe_on_context() {
|
if let Err(err) = imp.task.flush_start().await_maybe_on_context() {
|
||||||
gst::error!(SRC_CAT, obj: pad, "FlushStart failed {:?}", err);
|
gst::error!(SRC_CAT, obj = pad, "FlushStart failed {:?}", err);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
imp,
|
imp,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -695,7 +695,7 @@ impl PadSrcHandler for ProxySrcPadHandler {
|
||||||
}
|
}
|
||||||
EventView::FlushStop(..) => {
|
EventView::FlushStop(..) => {
|
||||||
if let Err(err) = imp.task.flush_stop().await_maybe_on_context() {
|
if let Err(err) = imp.task.flush_stop().await_maybe_on_context() {
|
||||||
gst::error!(SRC_CAT, obj: pad, "FlushStop failed {:?}", err);
|
gst::error!(SRC_CAT, obj = pad, "FlushStop failed {:?}", err);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
imp,
|
imp,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -709,16 +709,16 @@ impl PadSrcHandler for ProxySrcPadHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sink_pad) = sink_pad {
|
if let Some(sink_pad) = sink_pad {
|
||||||
gst::log!(SRC_CAT, obj: pad, "Forwarding {:?}", event);
|
gst::log!(SRC_CAT, obj = pad, "Forwarding {:?}", event);
|
||||||
sink_pad.push_event(event)
|
sink_pad.push_event(event)
|
||||||
} else {
|
} else {
|
||||||
gst::error!(SRC_CAT, obj: pad, "No sink pad to forward {:?} to", event);
|
gst::error!(SRC_CAT, obj = pad, "No sink pad to forward {:?} to", event);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(self, pad: &gst::Pad, _proxysrc: &ProxySrc, query: &mut gst::QueryRef) -> bool {
|
fn src_query(self, pad: &gst::Pad, _proxysrc: &ProxySrc, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(SRC_CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(SRC_CAT, obj = pad, "Handling {:?}", query);
|
||||||
|
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
let ret = match query.view_mut() {
|
let ret = match query.view_mut() {
|
||||||
|
@ -750,9 +750,9 @@ impl PadSrcHandler for ProxySrcPadHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret {
|
if ret {
|
||||||
gst::log!(SRC_CAT, obj: pad, "Handled {:?}", query);
|
gst::log!(SRC_CAT, obj = pad, "Handled {:?}", query);
|
||||||
} else {
|
} else {
|
||||||
gst::log!(SRC_CAT, obj: pad, "Didn't handle {:?}", query);
|
gst::log!(SRC_CAT, obj = pad, "Didn't handle {:?}", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -783,15 +783,15 @@ impl ProxySrcTask {
|
||||||
|
|
||||||
match item {
|
match item {
|
||||||
DataQueueItem::Buffer(buffer) => {
|
DataQueueItem::Buffer(buffer) => {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Forwarding {:?}", buffer);
|
gst::log!(SRC_CAT, obj = self.element, "Forwarding {:?}", buffer);
|
||||||
proxysrc.src_pad.push(buffer).await.map(drop)
|
proxysrc.src_pad.push(buffer).await.map(drop)
|
||||||
}
|
}
|
||||||
DataQueueItem::BufferList(list) => {
|
DataQueueItem::BufferList(list) => {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Forwarding {:?}", list);
|
gst::log!(SRC_CAT, obj = self.element, "Forwarding {:?}", list);
|
||||||
proxysrc.src_pad.push_list(list).await.map(drop)
|
proxysrc.src_pad.push_list(list).await.map(drop)
|
||||||
}
|
}
|
||||||
DataQueueItem::Event(event) => {
|
DataQueueItem::Event(event) => {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Forwarding {:?}", event);
|
gst::log!(SRC_CAT, obj = self.element, "Forwarding {:?}", event);
|
||||||
proxysrc.src_pad.push_event(event).await;
|
proxysrc.src_pad.push_event(event).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -804,7 +804,7 @@ impl TaskImpl for ProxySrcTask {
|
||||||
|
|
||||||
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Starting task");
|
gst::log!(SRC_CAT, obj = self.element, "Starting task");
|
||||||
|
|
||||||
let proxysrc = self.element.imp();
|
let proxysrc = self.element.imp();
|
||||||
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
||||||
|
@ -818,7 +818,7 @@ impl TaskImpl for ProxySrcTask {
|
||||||
|
|
||||||
self.dataqueue.start();
|
self.dataqueue.start();
|
||||||
|
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Task started");
|
gst::log!(SRC_CAT, obj = self.element, "Task started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -840,25 +840,25 @@ impl TaskImpl for ProxySrcTask {
|
||||||
let proxysrc = self.element.imp();
|
let proxysrc = self.element.imp();
|
||||||
match res {
|
match res {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Successfully pushed item");
|
gst::log!(SRC_CAT, obj = self.element, "Successfully pushed item");
|
||||||
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
||||||
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
||||||
shared_ctx.last_res = Ok(gst::FlowSuccess::Ok);
|
shared_ctx.last_res = Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Flushing) => {
|
Err(gst::FlowError::Flushing) => {
|
||||||
gst::debug!(SRC_CAT, obj: self.element, "Flushing");
|
gst::debug!(SRC_CAT, obj = self.element, "Flushing");
|
||||||
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
||||||
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
||||||
shared_ctx.last_res = Err(gst::FlowError::Flushing);
|
shared_ctx.last_res = Err(gst::FlowError::Flushing);
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Eos) => {
|
Err(gst::FlowError::Eos) => {
|
||||||
gst::debug!(SRC_CAT, obj: self.element, "EOS");
|
gst::debug!(SRC_CAT, obj = self.element, "EOS");
|
||||||
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
||||||
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
let mut shared_ctx = proxy_ctx.as_ref().unwrap().lock_shared();
|
||||||
shared_ctx.last_res = Err(gst::FlowError::Eos);
|
shared_ctx.last_res = Err(gst::FlowError::Eos);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(SRC_CAT, obj: self.element, "Got error {}", err);
|
gst::error!(SRC_CAT, obj = self.element, "Got error {}", err);
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
&self.element,
|
&self.element,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -878,7 +878,7 @@ impl TaskImpl for ProxySrcTask {
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Stopping task");
|
gst::log!(SRC_CAT, obj = self.element, "Stopping task");
|
||||||
|
|
||||||
let proxysrc = self.element.imp();
|
let proxysrc = self.element.imp();
|
||||||
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
||||||
|
@ -893,7 +893,7 @@ impl TaskImpl for ProxySrcTask {
|
||||||
pending_queue.notify_more_queue_space();
|
pending_queue.notify_more_queue_space();
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Task stopped");
|
gst::log!(SRC_CAT, obj = self.element, "Task stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -901,7 +901,7 @@ impl TaskImpl for ProxySrcTask {
|
||||||
|
|
||||||
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Starting task flush");
|
gst::log!(SRC_CAT, obj = self.element, "Starting task flush");
|
||||||
|
|
||||||
let proxysrc = self.element.imp();
|
let proxysrc = self.element.imp();
|
||||||
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
let proxy_ctx = proxysrc.proxy_ctx.lock().unwrap();
|
||||||
|
@ -911,7 +911,7 @@ impl TaskImpl for ProxySrcTask {
|
||||||
|
|
||||||
shared_ctx.last_res = Err(gst::FlowError::Flushing);
|
shared_ctx.last_res = Err(gst::FlowError::Flushing);
|
||||||
|
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Task flush started");
|
gst::log!(SRC_CAT, obj = self.element, "Task flush started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -937,7 +937,7 @@ static SRC_CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
|
||||||
impl ProxySrc {
|
impl ProxySrc {
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Preparing");
|
gst::debug!(SRC_CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
|
|
||||||
|
@ -991,13 +991,13 @@ impl ProxySrc {
|
||||||
.prepare(ProxySrcTask::new(self.obj().clone(), dataqueue), ts_ctx)
|
.prepare(ProxySrcTask::new(self.obj().clone(), dataqueue), ts_ctx)
|
||||||
.block_on()?;
|
.block_on()?;
|
||||||
|
|
||||||
gst::debug!(SRC_CAT, imp: self, "Prepared");
|
gst::debug!(SRC_CAT, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Unpreparing");
|
gst::debug!(SRC_CAT, imp = self, "Unpreparing");
|
||||||
|
|
||||||
{
|
{
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
|
@ -1010,27 +1010,27 @@ impl ProxySrc {
|
||||||
*self.dataqueue.lock().unwrap() = None;
|
*self.dataqueue.lock().unwrap() = None;
|
||||||
*self.proxy_ctx.lock().unwrap() = None;
|
*self.proxy_ctx.lock().unwrap() = None;
|
||||||
|
|
||||||
gst::debug!(SRC_CAT, imp: self, "Unprepared");
|
gst::debug!(SRC_CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Stopping");
|
gst::debug!(SRC_CAT, imp = self, "Stopping");
|
||||||
self.task.stop().await_maybe_on_context()?;
|
self.task.stop().await_maybe_on_context()?;
|
||||||
gst::debug!(SRC_CAT, imp: self, "Stopped");
|
gst::debug!(SRC_CAT, imp = self, "Stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Starting");
|
gst::debug!(SRC_CAT, imp = self, "Starting");
|
||||||
self.task.start().await_maybe_on_context()?;
|
self.task.start().await_maybe_on_context()?;
|
||||||
gst::debug!(SRC_CAT, imp: self, "Started");
|
gst::debug!(SRC_CAT, imp = self, "Started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Pausing");
|
gst::debug!(SRC_CAT, imp = self, "Pausing");
|
||||||
self.task.pause().block_on()?;
|
self.task.pause().block_on()?;
|
||||||
gst::debug!(SRC_CAT, imp: self, "Paused");
|
gst::debug!(SRC_CAT, imp = self, "Paused");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1190,7 +1190,7 @@ impl ElementImpl for ProxySrc {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(SRC_CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(SRC_CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -89,7 +89,7 @@ impl PadSinkHandler for QueuePadSinkHandler {
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", buffer);
|
gst::log!(CAT, obj = pad, "Handling {:?}", buffer);
|
||||||
let imp = elem.imp();
|
let imp = elem.imp();
|
||||||
imp.enqueue_item(DataQueueItem::Buffer(buffer)).await
|
imp.enqueue_item(DataQueueItem::Buffer(buffer)).await
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ impl PadSinkHandler for QueuePadSinkHandler {
|
||||||
list: gst::BufferList,
|
list: gst::BufferList,
|
||||||
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
) -> BoxFuture<'static, Result<gst::FlowSuccess, gst::FlowError>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", list);
|
gst::log!(CAT, obj = pad, "Handling {:?}", list);
|
||||||
let imp = elem.imp();
|
let imp = elem.imp();
|
||||||
imp.enqueue_item(DataQueueItem::BufferList(list)).await
|
imp.enqueue_item(DataQueueItem::BufferList(list)).await
|
||||||
}
|
}
|
||||||
|
@ -111,11 +111,11 @@ impl PadSinkHandler for QueuePadSinkHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_event(self, pad: &gst::Pad, imp: &Queue, event: gst::Event) -> bool {
|
fn sink_event(self, pad: &gst::Pad, imp: &Queue, event: gst::Event) -> bool {
|
||||||
gst::debug!(CAT, obj: pad, "Handling non-serialized {:?}", event);
|
gst::debug!(CAT, obj = pad, "Handling non-serialized {:?}", event);
|
||||||
|
|
||||||
if let gst::EventView::FlushStart(..) = event.view() {
|
if let gst::EventView::FlushStart(..) = event.view() {
|
||||||
if let Err(err) = imp.task.flush_start().await_maybe_on_context() {
|
if let Err(err) = imp.task.flush_start().await_maybe_on_context() {
|
||||||
gst::error!(CAT, obj: pad, "FlushStart failed {:?}", err);
|
gst::error!(CAT, obj = pad, "FlushStart failed {:?}", err);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
imp,
|
imp,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -126,7 +126,7 @@ impl PadSinkHandler for QueuePadSinkHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Forwarding non-serialized {:?}", event);
|
gst::log!(CAT, obj = pad, "Forwarding non-serialized {:?}", event);
|
||||||
imp.src_pad.gst_pad().push_event(event)
|
imp.src_pad.gst_pad().push_event(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,13 +137,13 @@ impl PadSinkHandler for QueuePadSinkHandler {
|
||||||
event: gst::Event,
|
event: gst::Event,
|
||||||
) -> BoxFuture<'static, bool> {
|
) -> BoxFuture<'static, bool> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: pad, "Handling serialized {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling serialized {:?}", event);
|
||||||
|
|
||||||
let imp = elem.imp();
|
let imp = elem.imp();
|
||||||
|
|
||||||
if let gst::EventView::FlushStop(..) = event.view() {
|
if let gst::EventView::FlushStop(..) = event.view() {
|
||||||
if let Err(err) = imp.task.flush_stop().await_maybe_on_context() {
|
if let Err(err) = imp.task.flush_stop().await_maybe_on_context() {
|
||||||
gst::error!(CAT, obj: pad, "FlushStop failed {:?}", err);
|
gst::error!(CAT, obj = pad, "FlushStop failed {:?}", err);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
imp,
|
imp,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -154,21 +154,21 @@ impl PadSinkHandler for QueuePadSinkHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Queuing serialized {:?}", event);
|
gst::log!(CAT, obj = pad, "Queuing serialized {:?}", event);
|
||||||
imp.enqueue_item(DataQueueItem::Event(event)).await.is_ok()
|
imp.enqueue_item(DataQueueItem::Event(event)).await.is_ok()
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_query(self, pad: &gst::Pad, imp: &Queue, query: &mut gst::QueryRef) -> bool {
|
fn sink_query(self, pad: &gst::Pad, imp: &Queue, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling {:?}", query);
|
||||||
|
|
||||||
if query.is_serialized() {
|
if query.is_serialized() {
|
||||||
// FIXME: How can we do this?
|
// FIXME: How can we do this?
|
||||||
gst::log!(CAT, obj: pad, "Dropping serialized {:?}", query);
|
gst::log!(CAT, obj = pad, "Dropping serialized {:?}", query);
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, obj: pad, "Forwarding {:?}", query);
|
gst::log!(CAT, obj = pad, "Forwarding {:?}", query);
|
||||||
imp.src_pad.gst_pad().peer_query(query)
|
imp.src_pad.gst_pad().peer_query(query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,18 +181,18 @@ impl PadSrcHandler for QueuePadSrcHandler {
|
||||||
type ElementImpl = Queue;
|
type ElementImpl = Queue;
|
||||||
|
|
||||||
fn src_event(self, pad: &gst::Pad, imp: &Queue, event: gst::Event) -> bool {
|
fn src_event(self, pad: &gst::Pad, imp: &Queue, event: gst::Event) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::FlushStart(..) => {
|
EventView::FlushStart(..) => {
|
||||||
if let Err(err) = imp.task.flush_start().await_maybe_on_context() {
|
if let Err(err) = imp.task.flush_start().await_maybe_on_context() {
|
||||||
gst::error!(CAT, obj: pad, "FlushStart failed {:?}", err);
|
gst::error!(CAT, obj = pad, "FlushStart failed {:?}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EventView::FlushStop(..) => {
|
EventView::FlushStop(..) => {
|
||||||
if let Err(err) = imp.task.flush_stop().await_maybe_on_context() {
|
if let Err(err) = imp.task.flush_stop().await_maybe_on_context() {
|
||||||
gst::error!(CAT, obj: pad, "FlushStop failed {:?}", err);
|
gst::error!(CAT, obj = pad, "FlushStop failed {:?}", err);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
imp,
|
imp,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -205,12 +205,12 @@ impl PadSrcHandler for QueuePadSrcHandler {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Forwarding {:?}", event);
|
gst::log!(CAT, obj = pad, "Forwarding {:?}", event);
|
||||||
imp.sink_pad.gst_pad().push_event(event)
|
imp.sink_pad.gst_pad().push_event(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(self, pad: &gst::Pad, imp: &Queue, query: &mut gst::QueryRef) -> bool {
|
fn src_query(self, pad: &gst::Pad, imp: &Queue, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling {:?}", query);
|
||||||
|
|
||||||
if let gst::QueryViewMut::Scheduling(q) = query.view_mut() {
|
if let gst::QueryViewMut::Scheduling(q) = query.view_mut() {
|
||||||
let mut new_query = gst::query::Scheduling::new();
|
let mut new_query = gst::query::Scheduling::new();
|
||||||
|
@ -219,7 +219,7 @@ impl PadSrcHandler for QueuePadSrcHandler {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Upstream returned {:?}", new_query);
|
gst::log!(CAT, obj = pad, "Upstream returned {:?}", new_query);
|
||||||
|
|
||||||
let (flags, min, max, align) = new_query.result();
|
let (flags, min, max, align) = new_query.result();
|
||||||
q.set(flags, min, max, align);
|
q.set(flags, min, max, align);
|
||||||
|
@ -231,11 +231,11 @@ impl PadSrcHandler for QueuePadSrcHandler {
|
||||||
.filter(|m| m != &gst::PadMode::Pull)
|
.filter(|m| m != &gst::PadMode::Pull)
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
gst::log!(CAT, obj: pad, "Returning {:?}", q.query_mut());
|
gst::log!(CAT, obj = pad, "Returning {:?}", q.query_mut());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Forwarding {:?}", query);
|
gst::log!(CAT, obj = pad, "Forwarding {:?}", query);
|
||||||
imp.sink_pad.gst_pad().peer_query(query)
|
imp.sink_pad.gst_pad().peer_query(query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,15 +260,15 @@ impl QueueTask {
|
||||||
|
|
||||||
match item {
|
match item {
|
||||||
DataQueueItem::Buffer(buffer) => {
|
DataQueueItem::Buffer(buffer) => {
|
||||||
gst::log!(CAT, obj: self.element, "Forwarding {:?}", buffer);
|
gst::log!(CAT, obj = self.element, "Forwarding {:?}", buffer);
|
||||||
queue.src_pad.push(buffer).await.map(drop)
|
queue.src_pad.push(buffer).await.map(drop)
|
||||||
}
|
}
|
||||||
DataQueueItem::BufferList(list) => {
|
DataQueueItem::BufferList(list) => {
|
||||||
gst::log!(CAT, obj: self.element, "Forwarding {:?}", list);
|
gst::log!(CAT, obj = self.element, "Forwarding {:?}", list);
|
||||||
queue.src_pad.push_list(list).await.map(drop)
|
queue.src_pad.push_list(list).await.map(drop)
|
||||||
}
|
}
|
||||||
DataQueueItem::Event(event) => {
|
DataQueueItem::Event(event) => {
|
||||||
gst::log!(CAT, obj: self.element, "Forwarding {:?}", event);
|
gst::log!(CAT, obj = self.element, "Forwarding {:?}", event);
|
||||||
queue.src_pad.push_event(event).await;
|
queue.src_pad.push_event(event).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ impl TaskImpl for QueueTask {
|
||||||
|
|
||||||
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Starting task");
|
gst::log!(CAT, obj = self.element, "Starting task");
|
||||||
|
|
||||||
let queue = self.element.imp();
|
let queue = self.element.imp();
|
||||||
let mut last_res = queue.last_res.lock().unwrap();
|
let mut last_res = queue.last_res.lock().unwrap();
|
||||||
|
@ -290,7 +290,7 @@ impl TaskImpl for QueueTask {
|
||||||
|
|
||||||
*last_res = Ok(gst::FlowSuccess::Ok);
|
*last_res = Ok(gst::FlowSuccess::Ok);
|
||||||
|
|
||||||
gst::log!(CAT, obj: self.element, "Task started");
|
gst::log!(CAT, obj = self.element, "Task started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -312,20 +312,20 @@ impl TaskImpl for QueueTask {
|
||||||
let queue = self.element.imp();
|
let queue = self.element.imp();
|
||||||
match res {
|
match res {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
gst::log!(CAT, obj: self.element, "Successfully pushed item");
|
gst::log!(CAT, obj = self.element, "Successfully pushed item");
|
||||||
*queue.last_res.lock().unwrap() = Ok(gst::FlowSuccess::Ok);
|
*queue.last_res.lock().unwrap() = Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Flushing) => {
|
Err(gst::FlowError::Flushing) => {
|
||||||
gst::debug!(CAT, obj: self.element, "Flushing");
|
gst::debug!(CAT, obj = self.element, "Flushing");
|
||||||
*queue.last_res.lock().unwrap() = Err(gst::FlowError::Flushing);
|
*queue.last_res.lock().unwrap() = Err(gst::FlowError::Flushing);
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Eos) => {
|
Err(gst::FlowError::Eos) => {
|
||||||
gst::debug!(CAT, obj: self.element, "EOS");
|
gst::debug!(CAT, obj = self.element, "EOS");
|
||||||
*queue.last_res.lock().unwrap() = Err(gst::FlowError::Eos);
|
*queue.last_res.lock().unwrap() = Err(gst::FlowError::Eos);
|
||||||
queue.src_pad.push_event(gst::event::Eos::new()).await;
|
queue.src_pad.push_event(gst::event::Eos::new()).await;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, obj: self.element, "Got error {}", err);
|
gst::error!(CAT, obj = self.element, "Got error {}", err);
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
&self.element,
|
&self.element,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -343,7 +343,7 @@ impl TaskImpl for QueueTask {
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Stopping task");
|
gst::log!(CAT, obj = self.element, "Stopping task");
|
||||||
|
|
||||||
let queue = self.element.imp();
|
let queue = self.element.imp();
|
||||||
let mut last_res = queue.last_res.lock().unwrap();
|
let mut last_res = queue.last_res.lock().unwrap();
|
||||||
|
@ -357,7 +357,7 @@ impl TaskImpl for QueueTask {
|
||||||
|
|
||||||
*last_res = Err(gst::FlowError::Flushing);
|
*last_res = Err(gst::FlowError::Flushing);
|
||||||
|
|
||||||
gst::log!(CAT, obj: self.element, "Task stopped");
|
gst::log!(CAT, obj = self.element, "Task stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -365,7 +365,7 @@ impl TaskImpl for QueueTask {
|
||||||
|
|
||||||
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Starting task flush");
|
gst::log!(CAT, obj = self.element, "Starting task flush");
|
||||||
|
|
||||||
let queue = self.element.imp();
|
let queue = self.element.imp();
|
||||||
let mut last_res = queue.last_res.lock().unwrap();
|
let mut last_res = queue.last_res.lock().unwrap();
|
||||||
|
@ -378,7 +378,7 @@ impl TaskImpl for QueueTask {
|
||||||
|
|
||||||
*last_res = Err(gst::FlowError::Flushing);
|
*last_res = Err(gst::FlowError::Flushing);
|
||||||
|
|
||||||
gst::log!(CAT, obj: self.element, "Task flush started");
|
gst::log!(CAT, obj = self.element, "Task flush started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -453,7 +453,7 @@ impl Queue {
|
||||||
}
|
}
|
||||||
let mut pending_queue_grd = self.pending_queue.lock().unwrap();
|
let mut pending_queue_grd = self.pending_queue.lock().unwrap();
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "Trying to empty pending queue");
|
gst::log!(CAT, imp = self, "Trying to empty pending queue");
|
||||||
|
|
||||||
if let Some(pending_queue) = pending_queue_grd.as_mut() {
|
if let Some(pending_queue) = pending_queue_grd.as_mut() {
|
||||||
let mut failed_item = None;
|
let mut failed_item = None;
|
||||||
|
@ -470,17 +470,17 @@ impl Queue {
|
||||||
|
|
||||||
receiver
|
receiver
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, imp: self, "Pending queue is empty now");
|
gst::log!(CAT, imp = self, "Pending queue is empty now");
|
||||||
*pending_queue_grd = None;
|
*pending_queue_grd = None;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, imp: self, "Flushing, dropping pending queue");
|
gst::log!(CAT, imp = self, "Flushing, dropping pending queue");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "Waiting for more queue space");
|
gst::log!(CAT, imp = self, "Waiting for more queue space");
|
||||||
let _ = more_queue_space_receiver.await;
|
let _ = more_queue_space_receiver.await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,7 +489,7 @@ impl Queue {
|
||||||
let wait_fut = {
|
let wait_fut = {
|
||||||
let dataqueue = self.dataqueue.lock().unwrap();
|
let dataqueue = self.dataqueue.lock().unwrap();
|
||||||
let dataqueue = dataqueue.as_ref().ok_or_else(|| {
|
let dataqueue = dataqueue.as_ref().ok_or_else(|| {
|
||||||
gst::error!(CAT, imp: self, "No DataQueue");
|
gst::error!(CAT, imp = self, "No DataQueue");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -518,18 +518,18 @@ impl Queue {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Queue is full - Pushing first item on pending queue"
|
"Queue is full - Pushing first item on pending queue"
|
||||||
);
|
);
|
||||||
|
|
||||||
if schedule_now {
|
if schedule_now {
|
||||||
gst::log!(CAT, imp: self, "Scheduling pending queue now");
|
gst::log!(CAT, imp = self, "Scheduling pending queue now");
|
||||||
pending_queue.as_mut().unwrap().scheduled = true;
|
pending_queue.as_mut().unwrap().scheduled = true;
|
||||||
|
|
||||||
let wait_fut = self.schedule_pending_queue();
|
let wait_fut = self.schedule_pending_queue();
|
||||||
Some(wait_fut)
|
Some(wait_fut)
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, imp: self, "Scheduling pending queue later");
|
gst::log!(CAT, imp = self, "Scheduling pending queue later");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -542,7 +542,7 @@ impl Queue {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(wait_fut) = wait_fut {
|
if let Some(wait_fut) = wait_fut {
|
||||||
gst::log!(CAT, imp: self, "Blocking until queue has space again");
|
gst::log!(CAT, imp = self, "Blocking until queue has space again");
|
||||||
wait_fut.await;
|
wait_fut.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,7 +550,7 @@ impl Queue {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Preparing");
|
gst::debug!(CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
|
|
||||||
|
@ -588,13 +588,13 @@ impl Queue {
|
||||||
.prepare(QueueTask::new(self.obj().clone(), dataqueue), context)
|
.prepare(QueueTask::new(self.obj().clone(), dataqueue), context)
|
||||||
.block_on()?;
|
.block_on()?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Prepared");
|
gst::debug!(CAT, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Unpreparing");
|
gst::debug!(CAT, imp = self, "Unpreparing");
|
||||||
|
|
||||||
self.task.unprepare().block_on().unwrap();
|
self.task.unprepare().block_on().unwrap();
|
||||||
|
|
||||||
|
@ -603,20 +603,20 @@ impl Queue {
|
||||||
|
|
||||||
*self.last_res.lock().unwrap() = Ok(gst::FlowSuccess::Ok);
|
*self.last_res.lock().unwrap() = Ok(gst::FlowSuccess::Ok);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Unprepared");
|
gst::debug!(CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Stopping");
|
gst::debug!(CAT, imp = self, "Stopping");
|
||||||
self.task.stop().await_maybe_on_context()?;
|
self.task.stop().await_maybe_on_context()?;
|
||||||
gst::debug!(CAT, imp: self, "Stopped");
|
gst::debug!(CAT, imp = self, "Stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Starting");
|
gst::debug!(CAT, imp = self, "Starting");
|
||||||
self.task.start().await_maybe_on_context()?;
|
self.task.start().await_maybe_on_context()?;
|
||||||
gst::debug!(CAT, imp: self, "Started");
|
gst::debug!(CAT, imp = self, "Started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -777,7 +777,7 @@ impl ElementImpl for Queue {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -129,7 +129,7 @@ pub trait PadSrcHandler: Clone + Send + Sync + 'static {
|
||||||
if pad.is_active() {
|
if pad.is_active() {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Already activated in {:?} mode ",
|
"Already activated in {:?} mode ",
|
||||||
pad.mode()
|
pad.mode()
|
||||||
);
|
);
|
||||||
|
@ -137,7 +137,12 @@ pub trait PadSrcHandler: Clone + Send + Sync + 'static {
|
||||||
}
|
}
|
||||||
|
|
||||||
pad.activate_mode(gst::PadMode::Push, true).map_err(|err| {
|
pad.activate_mode(gst::PadMode::Push, true).map_err(|err| {
|
||||||
gst::error!(RUNTIME_CAT, obj: pad, "Error in PadSrc activate: {:?}", err);
|
gst::error!(
|
||||||
|
RUNTIME_CAT,
|
||||||
|
obj = pad,
|
||||||
|
"Error in PadSrc activate: {:?}",
|
||||||
|
err
|
||||||
|
);
|
||||||
gst::loggable_error!(RUNTIME_CAT, "Error in PadSrc activate: {:?}", err)
|
gst::loggable_error!(RUNTIME_CAT, "Error in PadSrc activate: {:?}", err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -153,7 +158,7 @@ pub trait PadSrcHandler: Clone + Send + Sync + 'static {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_event(self, pad: &gst::Pad, imp: &Self::ElementImpl, event: gst::Event) -> bool {
|
fn src_event(self, pad: &gst::Pad, imp: &Self::ElementImpl, event: gst::Event) -> bool {
|
||||||
gst::log!(RUNTIME_CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(RUNTIME_CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
let elem = imp.obj();
|
let elem = imp.obj();
|
||||||
// FIXME with GAT on `Self::ElementImpl`, we should be able to
|
// FIXME with GAT on `Self::ElementImpl`, we should be able to
|
||||||
|
@ -178,13 +183,13 @@ pub trait PadSrcHandler: Clone + Send + Sync + 'static {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(self, pad: &gst::Pad, imp: &Self::ElementImpl, query: &mut gst::QueryRef) -> bool {
|
fn src_query(self, pad: &gst::Pad, imp: &Self::ElementImpl, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(RUNTIME_CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(RUNTIME_CAT, obj = pad, "Handling {:?}", query);
|
||||||
if query.is_serialized() {
|
if query.is_serialized() {
|
||||||
// FIXME serialized queries should be handled with the dataflow
|
// FIXME serialized queries should be handled with the dataflow
|
||||||
// but we can't return a `Future` because we couldn't honor QueryRef's lifetime
|
// but we can't return a `Future` because we couldn't honor QueryRef's lifetime
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
gst::log!(RUNTIME_CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(RUNTIME_CAT, obj = pad, "Handling {:?}", query);
|
||||||
|
|
||||||
let elem = imp.obj();
|
let elem = imp.obj();
|
||||||
// FIXME with GAT on `Self::ElementImpl`, we should be able to
|
// FIXME with GAT on `Self::ElementImpl`, we should be able to
|
||||||
|
@ -217,48 +222,61 @@ impl PadSrcInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn push(&self, buffer: gst::Buffer) -> Result<FlowSuccess, FlowError> {
|
pub async fn push(&self, buffer: gst::Buffer) -> Result<FlowSuccess, FlowError> {
|
||||||
gst::log!(RUNTIME_CAT, obj: self.gst_pad, "Pushing {:?}", buffer);
|
gst::log!(RUNTIME_CAT, obj = self.gst_pad, "Pushing {:?}", buffer);
|
||||||
|
|
||||||
let success = self.gst_pad.push(buffer).map_err(|err| {
|
let success = self.gst_pad.push(buffer).map_err(|err| {
|
||||||
gst::error!(RUNTIME_CAT,
|
gst::error!(
|
||||||
obj: self.gst_pad,
|
RUNTIME_CAT,
|
||||||
|
obj = self.gst_pad,
|
||||||
"Failed to push Buffer to PadSrc: {:?}",
|
"Failed to push Buffer to PadSrc: {:?}",
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::log!(RUNTIME_CAT, obj: self.gst_pad, "Processing any pending sub tasks");
|
gst::log!(
|
||||||
|
RUNTIME_CAT,
|
||||||
|
obj = self.gst_pad,
|
||||||
|
"Processing any pending sub tasks"
|
||||||
|
);
|
||||||
Context::drain_sub_tasks().await?;
|
Context::drain_sub_tasks().await?;
|
||||||
|
|
||||||
Ok(success)
|
Ok(success)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn push_list(&self, list: gst::BufferList) -> Result<FlowSuccess, FlowError> {
|
pub async fn push_list(&self, list: gst::BufferList) -> Result<FlowSuccess, FlowError> {
|
||||||
gst::log!(RUNTIME_CAT, obj: self.gst_pad, "Pushing {:?}", list);
|
gst::log!(RUNTIME_CAT, obj = self.gst_pad, "Pushing {:?}", list);
|
||||||
|
|
||||||
let success = self.gst_pad.push_list(list).map_err(|err| {
|
let success = self.gst_pad.push_list(list).map_err(|err| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: self.gst_pad,
|
obj = self.gst_pad,
|
||||||
"Failed to push BufferList to PadSrc: {:?}",
|
"Failed to push BufferList to PadSrc: {:?}",
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::log!(RUNTIME_CAT, obj: self.gst_pad, "Processing any pending sub tasks");
|
gst::log!(
|
||||||
|
RUNTIME_CAT,
|
||||||
|
obj = self.gst_pad,
|
||||||
|
"Processing any pending sub tasks"
|
||||||
|
);
|
||||||
Context::drain_sub_tasks().await?;
|
Context::drain_sub_tasks().await?;
|
||||||
|
|
||||||
Ok(success)
|
Ok(success)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn push_event(&self, event: gst::Event) -> bool {
|
pub async fn push_event(&self, event: gst::Event) -> bool {
|
||||||
gst::log!(RUNTIME_CAT, obj: self.gst_pad, "Pushing {:?}", event);
|
gst::log!(RUNTIME_CAT, obj = self.gst_pad, "Pushing {:?}", event);
|
||||||
|
|
||||||
let was_handled = self.gst_pad.push_event(event);
|
let was_handled = self.gst_pad.push_event(event);
|
||||||
|
|
||||||
gst::log!(RUNTIME_CAT, obj: self.gst_pad, "Processing any pending sub tasks");
|
gst::log!(
|
||||||
|
RUNTIME_CAT,
|
||||||
|
obj = self.gst_pad,
|
||||||
|
"Processing any pending sub tasks"
|
||||||
|
);
|
||||||
if Context::drain_sub_tasks().await.is_err() {
|
if Context::drain_sub_tasks().await.is_err() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +383,7 @@ impl PadSrc {
|
||||||
H::ElementImpl::catch_panic_pad_function(
|
H::ElementImpl::catch_panic_pad_function(
|
||||||
parent,
|
parent,
|
||||||
|| {
|
|| {
|
||||||
gst::error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSrc activate");
|
gst::error!(RUNTIME_CAT, obj = gst_pad, "Panic in PadSrc activate");
|
||||||
Err(gst::loggable_error!(
|
Err(gst::loggable_error!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
"Panic in PadSrc activate"
|
"Panic in PadSrc activate"
|
||||||
|
@ -383,7 +401,7 @@ impl PadSrc {
|
||||||
H::ElementImpl::catch_panic_pad_function(
|
H::ElementImpl::catch_panic_pad_function(
|
||||||
parent,
|
parent,
|
||||||
|| {
|
|| {
|
||||||
gst::error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSrc activatemode");
|
gst::error!(RUNTIME_CAT, obj = gst_pad, "Panic in PadSrc activatemode");
|
||||||
Err(gst::loggable_error!(
|
Err(gst::loggable_error!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
"Panic in PadSrc activatemode"
|
"Panic in PadSrc activatemode"
|
||||||
|
@ -392,7 +410,7 @@ impl PadSrc {
|
||||||
move |imp| {
|
move |imp| {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: gst_pad,
|
obj = gst_pad,
|
||||||
"ActivateMode {:?}, {}",
|
"ActivateMode {:?}, {}",
|
||||||
mode,
|
mode,
|
||||||
active
|
active
|
||||||
|
@ -401,7 +419,7 @@ impl PadSrc {
|
||||||
if mode == gst::PadMode::Pull {
|
if mode == gst::PadMode::Pull {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: gst_pad,
|
obj = gst_pad,
|
||||||
"Pull mode not supported by PadSrc"
|
"Pull mode not supported by PadSrc"
|
||||||
);
|
);
|
||||||
return Err(gst::loggable_error!(
|
return Err(gst::loggable_error!(
|
||||||
|
@ -442,7 +460,7 @@ impl PadSrc {
|
||||||
} else {
|
} else {
|
||||||
gst::fixme!(
|
gst::fixme!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: gst_pad,
|
obj = gst_pad,
|
||||||
"Serialized Query not supported"
|
"Serialized Query not supported"
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
|
@ -507,7 +525,7 @@ pub trait PadSinkHandler: Clone + Send + Sync + 'static {
|
||||||
if pad.is_active() {
|
if pad.is_active() {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Already activated in {:?} mode ",
|
"Already activated in {:?} mode ",
|
||||||
pad.mode()
|
pad.mode()
|
||||||
);
|
);
|
||||||
|
@ -517,7 +535,7 @@ pub trait PadSinkHandler: Clone + Send + Sync + 'static {
|
||||||
pad.activate_mode(gst::PadMode::Push, true).map_err(|err| {
|
pad.activate_mode(gst::PadMode::Push, true).map_err(|err| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Error in PadSink activate: {:?}",
|
"Error in PadSink activate: {:?}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
|
@ -555,7 +573,7 @@ pub trait PadSinkHandler: Clone + Send + Sync + 'static {
|
||||||
|
|
||||||
fn sink_event(self, pad: &gst::Pad, imp: &Self::ElementImpl, event: gst::Event) -> bool {
|
fn sink_event(self, pad: &gst::Pad, imp: &Self::ElementImpl, event: gst::Event) -> bool {
|
||||||
assert!(!event.is_serialized());
|
assert!(!event.is_serialized());
|
||||||
gst::log!(RUNTIME_CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(RUNTIME_CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
let elem = imp.obj();
|
let elem = imp.obj();
|
||||||
// FIXME with GAT on `Self::ElementImpl`, we should be able to
|
// FIXME with GAT on `Self::ElementImpl`, we should be able to
|
||||||
|
@ -581,7 +599,7 @@ pub trait PadSinkHandler: Clone + Send + Sync + 'static {
|
||||||
let element = unsafe { elem.unsafe_cast::<gst::Element>() };
|
let element = unsafe { elem.unsafe_cast::<gst::Element>() };
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
gst::log!(RUNTIME_CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(RUNTIME_CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
gst::Pad::event_default(&pad, Some(&element), event)
|
gst::Pad::event_default(&pad, Some(&element), event)
|
||||||
}
|
}
|
||||||
|
@ -624,12 +642,12 @@ pub trait PadSinkHandler: Clone + Send + Sync + 'static {
|
||||||
query: &mut gst::QueryRef,
|
query: &mut gst::QueryRef,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if query.is_serialized() {
|
if query.is_serialized() {
|
||||||
gst::log!(RUNTIME_CAT, obj: pad, "Dropping {:?}", query);
|
gst::log!(RUNTIME_CAT, obj = pad, "Dropping {:?}", query);
|
||||||
// FIXME serialized queries should be handled with the dataflow
|
// FIXME serialized queries should be handled with the dataflow
|
||||||
// but we can't return a `Future` because we couldn't honor QueryRef's lifetime
|
// but we can't return a `Future` because we couldn't honor QueryRef's lifetime
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
gst::log!(RUNTIME_CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(RUNTIME_CAT, obj = pad, "Handling {:?}", query);
|
||||||
|
|
||||||
let elem = imp.obj();
|
let elem = imp.obj();
|
||||||
// FIXME with GAT on `Self::ElementImpl`, we should be able to
|
// FIXME with GAT on `Self::ElementImpl`, we should be able to
|
||||||
|
@ -764,7 +782,7 @@ impl PadSink {
|
||||||
H::ElementImpl::catch_panic_pad_function(
|
H::ElementImpl::catch_panic_pad_function(
|
||||||
parent,
|
parent,
|
||||||
|| {
|
|| {
|
||||||
gst::error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSink activate");
|
gst::error!(RUNTIME_CAT, obj = gst_pad, "Panic in PadSink activate");
|
||||||
Err(gst::loggable_error!(
|
Err(gst::loggable_error!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
"Panic in PadSink activate"
|
"Panic in PadSink activate"
|
||||||
|
@ -782,7 +800,11 @@ impl PadSink {
|
||||||
H::ElementImpl::catch_panic_pad_function(
|
H::ElementImpl::catch_panic_pad_function(
|
||||||
parent,
|
parent,
|
||||||
|| {
|
|| {
|
||||||
gst::error!(RUNTIME_CAT, obj: gst_pad, "Panic in PadSink activatemode");
|
gst::error!(
|
||||||
|
RUNTIME_CAT,
|
||||||
|
obj = gst_pad,
|
||||||
|
"Panic in PadSink activatemode"
|
||||||
|
);
|
||||||
Err(gst::loggable_error!(
|
Err(gst::loggable_error!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
"Panic in PadSink activatemode"
|
"Panic in PadSink activatemode"
|
||||||
|
@ -791,7 +813,7 @@ impl PadSink {
|
||||||
move |imp| {
|
move |imp| {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: gst_pad,
|
obj = gst_pad,
|
||||||
"ActivateMode {:?}, {}",
|
"ActivateMode {:?}, {}",
|
||||||
mode,
|
mode,
|
||||||
active
|
active
|
||||||
|
@ -800,7 +822,7 @@ impl PadSink {
|
||||||
if mode == gst::PadMode::Pull {
|
if mode == gst::PadMode::Pull {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: gst_pad,
|
obj = gst_pad,
|
||||||
"Pull mode not supported by PadSink"
|
"Pull mode not supported by PadSink"
|
||||||
);
|
);
|
||||||
return Err(gst::loggable_error!(
|
return Err(gst::loggable_error!(
|
||||||
|
@ -923,7 +945,7 @@ impl PadSink {
|
||||||
} else {
|
} else {
|
||||||
gst::fixme!(
|
gst::fixme!(
|
||||||
RUNTIME_CAT,
|
RUNTIME_CAT,
|
||||||
obj: gst_pad,
|
obj = gst_pad,
|
||||||
"Serialized Query not supported"
|
"Serialized Query not supported"
|
||||||
);
|
);
|
||||||
false
|
false
|
||||||
|
|
|
@ -74,7 +74,7 @@ impl<T: SocketRead> Socket<T> {
|
||||||
buffer_pool.set_active(true).map_err(|err| {
|
buffer_pool.set_active(true).map_err(|err| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
SOCKET_CAT,
|
SOCKET_CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Failed to prepare socket: {}",
|
"Failed to prepare socket: {}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
|
@ -122,7 +122,7 @@ impl<T: SocketRead> Socket<T> {
|
||||||
pub async fn try_next(
|
pub async fn try_next(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> Result<(gst::Buffer, Option<std::net::SocketAddr>), SocketError> {
|
) -> Result<(gst::Buffer, Option<std::net::SocketAddr>), SocketError> {
|
||||||
gst::log!(SOCKET_CAT, obj: self.element, "Trying to read data");
|
gst::log!(SOCKET_CAT, obj = self.element, "Trying to read data");
|
||||||
|
|
||||||
if self.mapped_buffer.is_none() {
|
if self.mapped_buffer.is_none() {
|
||||||
match self.buffer_pool.acquire_buffer(None) {
|
match self.buffer_pool.acquire_buffer(None) {
|
||||||
|
@ -130,7 +130,12 @@ impl<T: SocketRead> Socket<T> {
|
||||||
self.mapped_buffer = Some(buffer.into_mapped_buffer_writable().unwrap());
|
self.mapped_buffer = Some(buffer.into_mapped_buffer_writable().unwrap());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::debug!(SOCKET_CAT, obj: self.element, "Failed to acquire buffer {:?}", err);
|
gst::debug!(
|
||||||
|
SOCKET_CAT,
|
||||||
|
obj = self.element,
|
||||||
|
"Failed to acquire buffer {:?}",
|
||||||
|
err
|
||||||
|
);
|
||||||
return Err(SocketError::Gst(err));
|
return Err(SocketError::Gst(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +154,7 @@ impl<T: SocketRead> Socket<T> {
|
||||||
// so as to display another message
|
// so as to display another message
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
SOCKET_CAT,
|
SOCKET_CAT,
|
||||||
obj: self.element,
|
obj = self.element,
|
||||||
"Read {} bytes at {} (clock {})",
|
"Read {} bytes at {} (clock {})",
|
||||||
len,
|
len,
|
||||||
running_time.display(),
|
running_time.display(),
|
||||||
|
@ -157,7 +162,7 @@ impl<T: SocketRead> Socket<T> {
|
||||||
);
|
);
|
||||||
running_time
|
running_time
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(SOCKET_CAT, obj: self.element, "Read {} bytes", len);
|
gst::debug!(SOCKET_CAT, obj = self.element, "Read {} bytes", len);
|
||||||
gst::ClockTime::NONE
|
gst::ClockTime::NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -173,7 +178,7 @@ impl<T: SocketRead> Socket<T> {
|
||||||
Ok((buffer, saddr))
|
Ok((buffer, saddr))
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::debug!(SOCKET_CAT, obj: self.element, "Read error {:?}", err);
|
gst::debug!(SOCKET_CAT, obj = self.element, "Read error {:?}", err);
|
||||||
|
|
||||||
Err(SocketError::Io(err))
|
Err(SocketError::Io(err))
|
||||||
}
|
}
|
||||||
|
@ -184,7 +189,12 @@ impl<T: SocketRead> Socket<T> {
|
||||||
impl<T: SocketRead> Drop for Socket<T> {
|
impl<T: SocketRead> Drop for Socket<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Err(err) = self.buffer_pool.set_active(false) {
|
if let Err(err) = self.buffer_pool.set_active(false) {
|
||||||
gst::error!(SOCKET_CAT, obj: self.element, "Failed to unprepare socket: {}", err);
|
gst::error!(
|
||||||
|
SOCKET_CAT,
|
||||||
|
obj = self.element,
|
||||||
|
"Failed to unprepare socket: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ impl PadSrcHandler for TcpClientSrcPadHandler {
|
||||||
type ElementImpl = TcpClientSrc;
|
type ElementImpl = TcpClientSrc;
|
||||||
|
|
||||||
fn src_event(self, pad: &gst::Pad, imp: &TcpClientSrc, event: gst::Event) -> bool {
|
fn src_event(self, pad: &gst::Pad, imp: &TcpClientSrc, event: gst::Event) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
let ret = match event.view() {
|
let ret = match event.view() {
|
||||||
|
@ -114,16 +114,16 @@ impl PadSrcHandler for TcpClientSrcPadHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret {
|
if ret {
|
||||||
gst::log!(CAT, obj: pad, "Handled {:?}", event);
|
gst::log!(CAT, obj = pad, "Handled {:?}", event);
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, obj: pad, "Didn't handle {:?}", event);
|
gst::log!(CAT, obj = pad, "Didn't handle {:?}", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(self, pad: &gst::Pad, imp: &TcpClientSrc, query: &mut gst::QueryRef) -> bool {
|
fn src_query(self, pad: &gst::Pad, imp: &TcpClientSrc, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling {:?}", query);
|
||||||
|
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
let ret = match query.view_mut() {
|
let ret = match query.view_mut() {
|
||||||
|
@ -155,9 +155,9 @@ impl PadSrcHandler for TcpClientSrcPadHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret {
|
if ret {
|
||||||
gst::log!(CAT, obj: pad, "Handled {:?}", query);
|
gst::log!(CAT, obj = pad, "Handled {:?}", query);
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, obj: pad, "Didn't handle {:?}", query);
|
gst::log!(CAT, obj = pad, "Didn't handle {:?}", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -196,12 +196,12 @@ impl TcpClientSrcTask {
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(CAT, obj: self.element, "Handling {:?}", buffer);
|
gst::log!(CAT, obj = self.element, "Handling {:?}", buffer);
|
||||||
|
|
||||||
let tcpclientsrc = self.element.imp();
|
let tcpclientsrc = self.element.imp();
|
||||||
|
|
||||||
if self.need_initial_events {
|
if self.need_initial_events {
|
||||||
gst::debug!(CAT, obj: self.element, "Pushing initial events");
|
gst::debug!(CAT, obj = self.element, "Pushing initial events");
|
||||||
|
|
||||||
let stream_id = format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
let stream_id = format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
||||||
let stream_start_evt = gst::event::StreamStart::builder(&stream_id)
|
let stream_start_evt = gst::event::StreamStart::builder(&stream_id)
|
||||||
|
@ -240,20 +240,20 @@ impl TcpClientSrcTask {
|
||||||
let res = tcpclientsrc.src_pad.push(buffer).await;
|
let res = tcpclientsrc.src_pad.push(buffer).await;
|
||||||
match res {
|
match res {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
gst::log!(CAT, obj: self.element, "Successfully pushed buffer");
|
gst::log!(CAT, obj = self.element, "Successfully pushed buffer");
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Flushing) => {
|
Err(gst::FlowError::Flushing) => {
|
||||||
gst::debug!(CAT, obj: self.element, "Flushing");
|
gst::debug!(CAT, obj = self.element, "Flushing");
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Eos) => {
|
Err(gst::FlowError::Eos) => {
|
||||||
gst::debug!(CAT, obj: self.element, "EOS");
|
gst::debug!(CAT, obj = self.element, "EOS");
|
||||||
tcpclientsrc
|
tcpclientsrc
|
||||||
.src_pad
|
.src_pad
|
||||||
.push_event(gst::event::Eos::new())
|
.push_event(gst::event::Eos::new())
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, obj: self.element, "Got error {}", err);
|
gst::error!(CAT, obj = self.element, "Got error {}", err);
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
self.element,
|
self.element,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -272,7 +272,12 @@ impl TaskImpl for TcpClientSrcTask {
|
||||||
|
|
||||||
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn prepare(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Preparing task connecting to {:?}", self.saddr);
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
obj = self.element,
|
||||||
|
"Preparing task connecting to {:?}",
|
||||||
|
self.saddr
|
||||||
|
);
|
||||||
|
|
||||||
let socket = Async::<TcpStream>::connect(self.saddr)
|
let socket = Async::<TcpStream>::connect(self.saddr)
|
||||||
.await
|
.await
|
||||||
|
@ -297,7 +302,7 @@ impl TaskImpl for TcpClientSrcTask {
|
||||||
})?,
|
})?,
|
||||||
);
|
);
|
||||||
|
|
||||||
gst::log!(CAT, obj: self.element, "Task prepared");
|
gst::log!(CAT, obj = self.element, "Task prepared");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -334,25 +339,25 @@ impl TaskImpl for TcpClientSrcTask {
|
||||||
futures::select! {
|
futures::select! {
|
||||||
event_res = event_fut => match event_res {
|
event_res = event_fut => match event_res {
|
||||||
Some(event) => {
|
Some(event) => {
|
||||||
gst::debug!(CAT, obj: self.element, "Handling element level event {event:?}");
|
gst::debug!(CAT, obj = self.element, "Handling element level event {event:?}");
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
gst::EventView::Eos(_) => Err(gst::FlowError::Eos),
|
gst::EventView::Eos(_) => Err(gst::FlowError::Eos),
|
||||||
ev => {
|
ev => {
|
||||||
gst::error!(CAT, obj: self.element, "Unexpected event {ev:?} on channel");
|
gst::error!(CAT, obj = self.element, "Unexpected event {ev:?} on channel");
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, obj: self.element, "Unexpected return on event channel");
|
gst::error!(CAT, obj = self.element, "Unexpected return on event channel");
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
socket_res = socket_fut => match socket_res {
|
socket_res = socket_fut => match socket_res {
|
||||||
Ok((buffer, _saddr)) => Ok(buffer),
|
Ok((buffer, _saddr)) => Ok(buffer),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, obj: self.element, "Got error {err:#}");
|
gst::error!(CAT, obj = self.element, "Got error {err:#}");
|
||||||
|
|
||||||
match err {
|
match err {
|
||||||
SocketError::Gst(err) => {
|
SocketError::Gst(err) => {
|
||||||
|
@ -387,9 +392,9 @@ impl TaskImpl for TcpClientSrcTask {
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Stopping task");
|
gst::log!(CAT, obj = self.element, "Stopping task");
|
||||||
self.need_initial_events = true;
|
self.need_initial_events = true;
|
||||||
gst::log!(CAT, obj: self.element, "Task stopped");
|
gst::log!(CAT, obj = self.element, "Task stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -397,9 +402,9 @@ impl TaskImpl for TcpClientSrcTask {
|
||||||
|
|
||||||
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Stopping task flush");
|
gst::log!(CAT, obj = self.element, "Stopping task flush");
|
||||||
self.need_initial_events = true;
|
self.need_initial_events = true;
|
||||||
gst::log!(CAT, obj: self.element, "Task flush stopped");
|
gst::log!(CAT, obj = self.element, "Task flush stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -409,12 +414,12 @@ impl TaskImpl for TcpClientSrcTask {
|
||||||
async move {
|
async move {
|
||||||
match err {
|
match err {
|
||||||
gst::FlowError::Flushing => {
|
gst::FlowError::Flushing => {
|
||||||
gst::debug!(CAT, obj: self.element, "Flushing");
|
gst::debug!(CAT, obj = self.element, "Flushing");
|
||||||
|
|
||||||
task::Trigger::FlushStart
|
task::Trigger::FlushStart
|
||||||
}
|
}
|
||||||
gst::FlowError::Eos => {
|
gst::FlowError::Eos => {
|
||||||
gst::debug!(CAT, obj: self.element, "EOS");
|
gst::debug!(CAT, obj = self.element, "EOS");
|
||||||
self.element
|
self.element
|
||||||
.imp()
|
.imp()
|
||||||
.src_pad
|
.src_pad
|
||||||
|
@ -424,7 +429,7 @@ impl TaskImpl for TcpClientSrcTask {
|
||||||
task::Trigger::Stop
|
task::Trigger::Stop
|
||||||
}
|
}
|
||||||
err => {
|
err => {
|
||||||
gst::error!(CAT, obj: self.element, "Got error {err}");
|
gst::error!(CAT, obj = self.element, "Got error {err}");
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
&self.element,
|
&self.element,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -458,7 +463,7 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
|
||||||
impl TcpClientSrc {
|
impl TcpClientSrc {
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Preparing");
|
gst::debug!(CAT, imp = self, "Preparing");
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
|
|
||||||
let context =
|
let context =
|
||||||
|
@ -520,35 +525,35 @@ impl TcpClientSrc {
|
||||||
state.event_sender = Some(sender);
|
state.event_sender = Some(sender);
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Preparing asynchronously");
|
gst::debug!(CAT, imp = self, "Preparing asynchronously");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Unpreparing");
|
gst::debug!(CAT, imp = self, "Unpreparing");
|
||||||
self.task.unprepare().block_on().unwrap();
|
self.task.unprepare().block_on().unwrap();
|
||||||
gst::debug!(CAT, imp: self, "Unprepared");
|
gst::debug!(CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Stopping");
|
gst::debug!(CAT, imp = self, "Stopping");
|
||||||
self.task.stop().block_on()?;
|
self.task.stop().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Stopped");
|
gst::debug!(CAT, imp = self, "Stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Starting");
|
gst::debug!(CAT, imp = self, "Starting");
|
||||||
self.task.start().block_on()?;
|
self.task.start().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Started");
|
gst::debug!(CAT, imp = self, "Started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Pausing");
|
gst::debug!(CAT, imp = self, "Pausing");
|
||||||
self.task.pause().block_on()?;
|
self.task.pause().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Paused");
|
gst::debug!(CAT, imp = self, "Paused");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,7 +713,7 @@ impl ElementImpl for TcpClientSrc {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
@ -750,13 +755,13 @@ impl ElementImpl for TcpClientSrc {
|
||||||
fn send_event(&self, event: gst::Event) -> bool {
|
fn send_event(&self, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Handling element level event {event:?}");
|
gst::debug!(CAT, imp = self, "Handling element level event {event:?}");
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Eos(_) => {
|
EventView::Eos(_) => {
|
||||||
if self.state() != TaskState::Started {
|
if self.state() != TaskState::Started {
|
||||||
if let Err(err) = self.start() {
|
if let Err(err) = self.start() {
|
||||||
gst::error!(CAT, imp: self, "Failed to start task thread {err:?}");
|
gst::error!(CAT, imp = self, "Failed to start task thread {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,17 +200,17 @@ impl UdpSinkPadHandler {
|
||||||
futures::executor::block_on(async move {
|
futures::executor::block_on(async move {
|
||||||
let mut inner = self.0.lock().await;
|
let mut inner = self.0.lock().await;
|
||||||
if inner.clients.contains(&addr) {
|
if inner.clients.contains(&addr) {
|
||||||
gst::warning!(CAT, imp: imp, "Not adding client {addr:?} again");
|
gst::warning!(CAT, imp = imp, "Not adding client {addr:?} again");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match inner.configure_client(&addr) {
|
match inner.configure_client(&addr) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
gst::info!(CAT, imp: imp, "Added client {addr:?}");
|
gst::info!(CAT, imp = imp, "Added client {addr:?}");
|
||||||
inner.clients.insert(addr);
|
inner.clients.insert(addr);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: imp, "Failed to add client {addr:?}: {err}");
|
gst::error!(CAT, imp = imp, "Failed to add client {addr:?}: {err}");
|
||||||
imp.obj().post_error_message(err);
|
imp.obj().post_error_message(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,16 +221,16 @@ impl UdpSinkPadHandler {
|
||||||
futures::executor::block_on(async move {
|
futures::executor::block_on(async move {
|
||||||
let mut inner = self.0.lock().await;
|
let mut inner = self.0.lock().await;
|
||||||
if inner.clients.take(&addr).is_none() {
|
if inner.clients.take(&addr).is_none() {
|
||||||
gst::warning!(CAT, imp: imp, "Not removing unknown client {addr:?}");
|
gst::warning!(CAT, imp = imp, "Not removing unknown client {addr:?}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match inner.unconfigure_client(&addr) {
|
match inner.unconfigure_client(&addr) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
gst::info!(CAT, imp: imp, "Removed client {addr:?}");
|
gst::info!(CAT, imp = imp, "Removed client {addr:?}");
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: imp, "Failed to remove client {addr:?}: {err}");
|
gst::error!(CAT, imp = imp, "Failed to remove client {addr:?}: {err}");
|
||||||
imp.obj().post_error_message(err);
|
imp.obj().post_error_message(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,9 +241,9 @@ impl UdpSinkPadHandler {
|
||||||
futures::executor::block_on(async move {
|
futures::executor::block_on(async move {
|
||||||
let mut inner = self.0.lock().await;
|
let mut inner = self.0.lock().await;
|
||||||
if new_clients.is_empty() {
|
if new_clients.is_empty() {
|
||||||
gst::info!(CAT, imp: imp, "Clearing clients");
|
gst::info!(CAT, imp = imp, "Clearing clients");
|
||||||
} else {
|
} else {
|
||||||
gst::info!(CAT, imp: imp, "Replacing clients");
|
gst::info!(CAT, imp = imp, "Replacing clients");
|
||||||
}
|
}
|
||||||
|
|
||||||
let old_clients = std::mem::take(&mut inner.clients);
|
let old_clients = std::mem::take(&mut inner.clients);
|
||||||
|
@ -255,19 +255,19 @@ impl UdpSinkPadHandler {
|
||||||
// client is already configured
|
// client is already configured
|
||||||
inner.clients.insert(*addr);
|
inner.clients.insert(*addr);
|
||||||
} else if let Err(err) = inner.unconfigure_client(addr) {
|
} else if let Err(err) = inner.unconfigure_client(addr) {
|
||||||
gst::error!(CAT, imp: imp, "Failed to remove client {addr:?}: {err}");
|
gst::error!(CAT, imp = imp, "Failed to remove client {addr:?}: {err}");
|
||||||
res = Err(err);
|
res = Err(err);
|
||||||
} else {
|
} else {
|
||||||
gst::info!(CAT, imp: imp, "Removed client {addr:?}");
|
gst::info!(CAT, imp = imp, "Removed client {addr:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for addr in new_clients.into_iter() {
|
for addr in new_clients.into_iter() {
|
||||||
if let Err(err) = inner.configure_client(&addr) {
|
if let Err(err) = inner.configure_client(&addr) {
|
||||||
gst::error!(CAT, imp: imp, "Failed to add client {addr:?}: {err}");
|
gst::error!(CAT, imp = imp, "Failed to add client {addr:?}: {err}");
|
||||||
res = Err(err);
|
res = Err(err);
|
||||||
} else {
|
} else {
|
||||||
gst::info!(CAT, imp: imp, "Added client {addr:?}");
|
gst::info!(CAT, imp = imp, "Added client {addr:?}");
|
||||||
inner.clients.insert(addr);
|
inner.clients.insert(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,7 @@ impl PadSinkHandler for UdpSinkPadHandler {
|
||||||
event: gst::Event,
|
event: gst::Event,
|
||||||
) -> BoxFuture<'static, bool> {
|
) -> BoxFuture<'static, bool> {
|
||||||
async move {
|
async move {
|
||||||
gst::debug!(CAT, obj: elem, "Handling {event:?}");
|
gst::debug!(CAT, obj = elem, "Handling {event:?}");
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Eos(_) => {
|
EventView::Eos(_) => {
|
||||||
|
@ -343,7 +343,7 @@ impl PadSinkHandler for UdpSinkPadHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_event(self, _pad: &gst::Pad, imp: &UdpSink, event: gst::Event) -> bool {
|
fn sink_event(self, _pad: &gst::Pad, imp: &UdpSink, event: gst::Event) -> bool {
|
||||||
gst::debug!(CAT, imp: imp, "Handling {event:?}");
|
gst::debug!(CAT, imp = imp, "Handling {event:?}");
|
||||||
|
|
||||||
if let EventView::FlushStart(..) = event.view() {
|
if let EventView::FlushStart(..) = event.view() {
|
||||||
block_on_or_add_sub_task(async move {
|
block_on_or_add_sub_task(async move {
|
||||||
|
@ -554,7 +554,7 @@ impl UdpSinkPadHandlerInner {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(socket) = socket.as_mut() {
|
if let Some(socket) = socket.as_mut() {
|
||||||
gst::log!(CAT, obj: elem, "Sending to {client:?}");
|
gst::log!(CAT, obj = elem, "Sending to {client:?}");
|
||||||
socket.send_to(&data, *client).await.map_err(|err| {
|
socket.send_to(&data, *client).await.map_err(|err| {
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
elem,
|
elem,
|
||||||
|
@ -575,7 +575,7 @@ impl UdpSinkPadHandlerInner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, obj: elem, "Sent buffer {buffer:?} to all clients");
|
gst::log!(CAT, obj = elem, "Sent buffer {buffer:?} to all clients");
|
||||||
|
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
}
|
}
|
||||||
|
@ -585,7 +585,7 @@ impl UdpSinkPadHandlerInner {
|
||||||
let now = elem.current_running_time();
|
let now = elem.current_running_time();
|
||||||
|
|
||||||
if let Ok(Some(delay)) = running_time.opt_checked_sub(now) {
|
if let Ok(Some(delay)) = running_time.opt_checked_sub(now) {
|
||||||
gst::trace!(CAT, obj: elem, "sync: waiting {delay}");
|
gst::trace!(CAT, obj = elem, "sync: waiting {delay}");
|
||||||
runtime::timer::delay_for(delay.into()).await;
|
runtime::timer::delay_for(delay.into()).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -596,7 +596,7 @@ impl UdpSinkPadHandlerInner {
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
if self.is_flushing {
|
if self.is_flushing {
|
||||||
gst::info!(CAT, obj: elem, "Discarding {buffer:?} (flushing)");
|
gst::info!(CAT, obj = elem, "Discarding {buffer:?} (flushing)");
|
||||||
|
|
||||||
return Err(gst::FlowError::Flushing);
|
return Err(gst::FlowError::Flushing);
|
||||||
}
|
}
|
||||||
|
@ -612,14 +612,14 @@ impl UdpSinkPadHandlerInner {
|
||||||
self.sync(elem, rtime).await;
|
self.sync(elem, rtime).await;
|
||||||
|
|
||||||
if self.is_flushing {
|
if self.is_flushing {
|
||||||
gst::info!(CAT, obj: elem, "Discarding {buffer:?} (flushing)");
|
gst::info!(CAT, obj = elem, "Discarding {buffer:?} (flushing)");
|
||||||
|
|
||||||
return Err(gst::FlowError::Flushing);
|
return Err(gst::FlowError::Flushing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, obj: elem, "Handling {buffer:?}");
|
gst::debug!(CAT, obj = elem, "Handling {buffer:?}");
|
||||||
|
|
||||||
self.render(elem, buffer).await.map_err(|err| {
|
self.render(elem, buffer).await.map_err(|err| {
|
||||||
element_error!(
|
element_error!(
|
||||||
|
@ -698,7 +698,7 @@ impl UdpSink {
|
||||||
};
|
};
|
||||||
|
|
||||||
let saddr = SocketAddr::new(bind_addr, bind_port as u16);
|
let saddr = SocketAddr::new(bind_addr, bind_port as u16);
|
||||||
gst::debug!(CAT, imp: self, "Binding to {:?}", saddr);
|
gst::debug!(CAT, imp = self, "Binding to {:?}", saddr);
|
||||||
|
|
||||||
let socket = match family {
|
let socket = match family {
|
||||||
SocketFamily::Ipv4 => socket2::Socket::new(
|
SocketFamily::Ipv4 => socket2::Socket::new(
|
||||||
|
@ -718,7 +718,7 @@ impl UdpSink {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to create {} socket: {}",
|
"Failed to create {} socket: {}",
|
||||||
match family {
|
match family {
|
||||||
SocketFamily::Ipv4 => "IPv4",
|
SocketFamily::Ipv4 => "IPv4",
|
||||||
|
@ -771,7 +771,7 @@ impl UdpSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Preparing");
|
gst::debug!(CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let mut settings = self.settings.lock().unwrap();
|
let mut settings = self.settings.lock().unwrap();
|
||||||
|
|
||||||
|
@ -789,36 +789,36 @@ impl UdpSink {
|
||||||
.prepare(self, socket, socket_v6, &settings)?;
|
.prepare(self, socket, socket_v6, &settings)?;
|
||||||
*self.ts_ctx.lock().unwrap() = Some(ts_ctx);
|
*self.ts_ctx.lock().unwrap() = Some(ts_ctx);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Started preparation");
|
gst::debug!(CAT, imp = self, "Started preparation");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Unpreparing");
|
gst::debug!(CAT, imp = self, "Unpreparing");
|
||||||
self.sink_pad_handler.unprepare();
|
self.sink_pad_handler.unprepare();
|
||||||
*self.ts_ctx.lock().unwrap() = None;
|
*self.ts_ctx.lock().unwrap() = None;
|
||||||
gst::debug!(CAT, imp: self, "Unprepared");
|
gst::debug!(CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Stopping");
|
gst::debug!(CAT, imp = self, "Stopping");
|
||||||
self.sink_pad_handler.stop();
|
self.sink_pad_handler.stop();
|
||||||
gst::debug!(CAT, imp: self, "Stopped");
|
gst::debug!(CAT, imp = self, "Stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Starting");
|
gst::debug!(CAT, imp = self, "Starting");
|
||||||
self.sink_pad_handler.start();
|
self.sink_pad_handler.start();
|
||||||
gst::debug!(CAT, imp: self, "Started");
|
gst::debug!(CAT, imp = self, "Started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_into_socket_addr(&self, host: &str, port: i32) -> Result<SocketAddr, ()> {
|
fn try_into_socket_addr(&self, host: &str, port: i32) -> Result<SocketAddr, ()> {
|
||||||
let addr: IpAddr = match host.parse() {
|
let addr: IpAddr = match host.parse() {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to parse host {}: {}", host, err);
|
gst::error!(CAT, imp = self, "Failed to parse host {}: {}", host, err);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
Ok(addr) => addr,
|
Ok(addr) => addr,
|
||||||
|
@ -826,7 +826,7 @@ impl UdpSink {
|
||||||
|
|
||||||
let port: u16 = match port.try_into() {
|
let port: u16 = match port.try_into() {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Invalid port {}: {}", port, err);
|
gst::error!(CAT, imp = self, "Invalid port {}: {}", port, err);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
Ok(port) => port,
|
Ok(port) => port,
|
||||||
|
@ -1088,19 +1088,19 @@ impl ObjectImpl for UdpSink {
|
||||||
Err(()) => {
|
Err(()) => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Invalid socket address {addr}:{port}"
|
"Invalid socket address {addr}:{port}"
|
||||||
);
|
);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Invalid port {err}");
|
gst::error!(CAT, imp = self, "Invalid port {err}");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Invalid client {client}");
|
gst::error!(CAT, imp = self, "Invalid client {client}");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1215,7 +1215,7 @@ impl ElementImpl for UdpSink {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
|
|
@ -119,7 +119,7 @@ impl PadSrcHandler for UdpSrcPadHandler {
|
||||||
type ElementImpl = UdpSrc;
|
type ElementImpl = UdpSrc;
|
||||||
|
|
||||||
fn src_event(self, pad: &gst::Pad, imp: &UdpSrc, event: gst::Event) -> bool {
|
fn src_event(self, pad: &gst::Pad, imp: &UdpSrc, event: gst::Event) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
let ret = match event.view() {
|
let ret = match event.view() {
|
||||||
|
@ -131,16 +131,16 @@ impl PadSrcHandler for UdpSrcPadHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret {
|
if ret {
|
||||||
gst::log!(CAT, obj: pad, "Handled {:?}", event);
|
gst::log!(CAT, obj = pad, "Handled {:?}", event);
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, obj: pad, "Didn't handle {:?}", event);
|
gst::log!(CAT, obj = pad, "Didn't handle {:?}", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(self, pad: &gst::Pad, imp: &UdpSrc, query: &mut gst::QueryRef) -> bool {
|
fn src_query(self, pad: &gst::Pad, imp: &UdpSrc, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling {:?}", query);
|
||||||
|
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
let ret = match query.view_mut() {
|
let ret = match query.view_mut() {
|
||||||
|
@ -172,9 +172,9 @@ impl PadSrcHandler for UdpSrcPadHandler {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret {
|
if ret {
|
||||||
gst::log!(CAT, obj: pad, "Handled {:?}", query);
|
gst::log!(CAT, obj = pad, "Handled {:?}", query);
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, obj: pad, "Didn't handle {:?}", query);
|
gst::log!(CAT, obj = pad, "Didn't handle {:?}", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -211,7 +211,7 @@ impl TaskImpl for UdpSrcTask {
|
||||||
let udpsrc = self.element.imp();
|
let udpsrc = self.element.imp();
|
||||||
let mut settings = udpsrc.settings.lock().unwrap();
|
let mut settings = udpsrc.settings.lock().unwrap();
|
||||||
|
|
||||||
gst::debug!(CAT, obj: self.element, "Preparing Task");
|
gst::debug!(CAT, obj = self.element, "Preparing Task");
|
||||||
|
|
||||||
self.retrieve_sender_address = settings.retrieve_sender_address;
|
self.retrieve_sender_address = settings.retrieve_sender_address;
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ impl TaskImpl for UdpSrcTask {
|
||||||
let saddr = SocketAddr::new(bind_addr, port as u16);
|
let saddr = SocketAddr::new(bind_addr, port as u16);
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: self.element,
|
obj = self.element,
|
||||||
"Binding to {:?} for multicast group {:?}",
|
"Binding to {:?} for multicast group {:?}",
|
||||||
saddr,
|
saddr,
|
||||||
addr
|
addr
|
||||||
|
@ -277,7 +277,7 @@ impl TaskImpl for UdpSrcTask {
|
||||||
saddr
|
saddr
|
||||||
} else {
|
} else {
|
||||||
let saddr = SocketAddr::new(addr, port as u16);
|
let saddr = SocketAddr::new(addr, port as u16);
|
||||||
gst::debug!(CAT, obj: self.element, "Binding to {:?}", saddr);
|
gst::debug!(CAT, obj = self.element, "Binding to {:?}", saddr);
|
||||||
|
|
||||||
saddr
|
saddr
|
||||||
};
|
};
|
||||||
|
@ -407,7 +407,7 @@ impl TaskImpl for UdpSrcTask {
|
||||||
|
|
||||||
fn unprepare(&mut self) -> BoxFuture<'_, ()> {
|
fn unprepare(&mut self) -> BoxFuture<'_, ()> {
|
||||||
async move {
|
async move {
|
||||||
gst::debug!(CAT, obj: self.element, "Unpreparing Task");
|
gst::debug!(CAT, obj = self.element, "Unpreparing Task");
|
||||||
let udpsrc = self.element.imp();
|
let udpsrc = self.element.imp();
|
||||||
udpsrc.settings.lock().unwrap().used_socket = None;
|
udpsrc.settings.lock().unwrap().used_socket = None;
|
||||||
self.element.notify("used-socket");
|
self.element.notify("used-socket");
|
||||||
|
@ -417,12 +417,12 @@ impl TaskImpl for UdpSrcTask {
|
||||||
|
|
||||||
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Starting task");
|
gst::log!(CAT, obj = self.element, "Starting task");
|
||||||
self.socket
|
self.socket
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_clock(self.element.clock(), self.element.base_time());
|
.set_clock(self.element.clock(), self.element.base_time());
|
||||||
gst::log!(CAT, obj: self.element, "Task started");
|
gst::log!(CAT, obj = self.element, "Task started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -439,18 +439,18 @@ impl TaskImpl for UdpSrcTask {
|
||||||
futures::select! {
|
futures::select! {
|
||||||
event_res = event_fut => match event_res {
|
event_res = event_fut => match event_res {
|
||||||
Some(event) => {
|
Some(event) => {
|
||||||
gst::debug!(CAT, obj: self.element, "Handling element level event {event:?}");
|
gst::debug!(CAT, obj = self.element, "Handling element level event {event:?}");
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
gst::EventView::Eos(_) => Err(gst::FlowError::Eos),
|
gst::EventView::Eos(_) => Err(gst::FlowError::Eos),
|
||||||
ev => {
|
ev => {
|
||||||
gst::error!(CAT, obj: self.element, "Unexpected event {ev:?} on channel");
|
gst::error!(CAT, obj = self.element, "Unexpected event {ev:?} on channel");
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, obj: self.element, "Unexpected return on event channel");
|
gst::error!(CAT, obj = self.element, "Unexpected return on event channel");
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -468,7 +468,7 @@ impl TaskImpl for UdpSrcTask {
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, obj: self.element, "Got error {err:#}");
|
gst::error!(CAT, obj = self.element, "Got error {err:#}");
|
||||||
|
|
||||||
match err {
|
match err {
|
||||||
SocketError::Gst(err) => {
|
SocketError::Gst(err) => {
|
||||||
|
@ -499,11 +499,11 @@ impl TaskImpl for UdpSrcTask {
|
||||||
|
|
||||||
fn handle_item(&mut self, buffer: gst::Buffer) -> BoxFuture<'_, Result<(), gst::FlowError>> {
|
fn handle_item(&mut self, buffer: gst::Buffer) -> BoxFuture<'_, Result<(), gst::FlowError>> {
|
||||||
async {
|
async {
|
||||||
gst::log!(CAT, obj: self.element, "Handling {:?}", buffer);
|
gst::log!(CAT, obj = self.element, "Handling {:?}", buffer);
|
||||||
let udpsrc = self.element.imp();
|
let udpsrc = self.element.imp();
|
||||||
|
|
||||||
if self.need_initial_events {
|
if self.need_initial_events {
|
||||||
gst::debug!(CAT, obj: self.element, "Pushing initial events");
|
gst::debug!(CAT, obj = self.element, "Pushing initial events");
|
||||||
|
|
||||||
let stream_id =
|
let stream_id =
|
||||||
format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
format!("{:08x}{:08x}", rand::random::<u32>(), rand::random::<u32>());
|
||||||
|
@ -534,14 +534,14 @@ impl TaskImpl for UdpSrcTask {
|
||||||
|
|
||||||
let res = udpsrc.src_pad.push(buffer).await.map(drop);
|
let res = udpsrc.src_pad.push(buffer).await.map(drop);
|
||||||
match res {
|
match res {
|
||||||
Ok(_) => gst::log!(CAT, obj: self.element, "Successfully pushed buffer"),
|
Ok(_) => gst::log!(CAT, obj = self.element, "Successfully pushed buffer"),
|
||||||
Err(gst::FlowError::Flushing) => gst::debug!(CAT, obj: self.element, "Flushing"),
|
Err(gst::FlowError::Flushing) => gst::debug!(CAT, obj = self.element, "Flushing"),
|
||||||
Err(gst::FlowError::Eos) => {
|
Err(gst::FlowError::Eos) => {
|
||||||
gst::debug!(CAT, obj: self.element, "EOS");
|
gst::debug!(CAT, obj = self.element, "EOS");
|
||||||
udpsrc.src_pad.push_event(gst::event::Eos::new()).await;
|
udpsrc.src_pad.push_event(gst::event::Eos::new()).await;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, obj: self.element, "Got error {}", err);
|
gst::error!(CAT, obj = self.element, "Got error {}", err);
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
self.element,
|
self.element,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -558,10 +558,10 @@ impl TaskImpl for UdpSrcTask {
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Stopping task");
|
gst::log!(CAT, obj = self.element, "Stopping task");
|
||||||
self.need_initial_events = true;
|
self.need_initial_events = true;
|
||||||
self.need_segment = true;
|
self.need_segment = true;
|
||||||
gst::log!(CAT, obj: self.element, "Task stopped");
|
gst::log!(CAT, obj = self.element, "Task stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -569,9 +569,9 @@ impl TaskImpl for UdpSrcTask {
|
||||||
|
|
||||||
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn flush_stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(CAT, obj: self.element, "Stopping task flush");
|
gst::log!(CAT, obj = self.element, "Stopping task flush");
|
||||||
self.need_segment = true;
|
self.need_segment = true;
|
||||||
gst::log!(CAT, obj: self.element, "Stopped task flush");
|
gst::log!(CAT, obj = self.element, "Stopped task flush");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -581,12 +581,12 @@ impl TaskImpl for UdpSrcTask {
|
||||||
async move {
|
async move {
|
||||||
match err {
|
match err {
|
||||||
gst::FlowError::Flushing => {
|
gst::FlowError::Flushing => {
|
||||||
gst::debug!(CAT, obj: self.element, "Flushing");
|
gst::debug!(CAT, obj = self.element, "Flushing");
|
||||||
|
|
||||||
task::Trigger::FlushStart
|
task::Trigger::FlushStart
|
||||||
}
|
}
|
||||||
gst::FlowError::Eos => {
|
gst::FlowError::Eos => {
|
||||||
gst::debug!(CAT, obj: self.element, "EOS");
|
gst::debug!(CAT, obj = self.element, "EOS");
|
||||||
self.element
|
self.element
|
||||||
.imp()
|
.imp()
|
||||||
.src_pad
|
.src_pad
|
||||||
|
@ -596,7 +596,7 @@ impl TaskImpl for UdpSrcTask {
|
||||||
task::Trigger::Stop
|
task::Trigger::Stop
|
||||||
}
|
}
|
||||||
err => {
|
err => {
|
||||||
gst::error!(CAT, obj: self.element, "Got error {err}");
|
gst::error!(CAT, obj = self.element, "Got error {err}");
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
&self.element,
|
&self.element,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -630,7 +630,7 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
|
||||||
impl UdpSrc {
|
impl UdpSrc {
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Preparing");
|
gst::debug!(CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
let context =
|
let context =
|
||||||
|
@ -653,35 +653,35 @@ impl UdpSrc {
|
||||||
state.event_sender = Some(sender);
|
state.event_sender = Some(sender);
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Prepared");
|
gst::debug!(CAT, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Unpreparing");
|
gst::debug!(CAT, imp = self, "Unpreparing");
|
||||||
self.task.unprepare().block_on().unwrap();
|
self.task.unprepare().block_on().unwrap();
|
||||||
gst::debug!(CAT, imp: self, "Unprepared");
|
gst::debug!(CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Stopping");
|
gst::debug!(CAT, imp = self, "Stopping");
|
||||||
self.task.stop().block_on()?;
|
self.task.stop().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Stopped");
|
gst::debug!(CAT, imp = self, "Stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Starting");
|
gst::debug!(CAT, imp = self, "Starting");
|
||||||
self.task.start().block_on()?;
|
self.task.start().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Started");
|
gst::debug!(CAT, imp = self, "Started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
fn pause(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Pausing");
|
gst::debug!(CAT, imp = self, "Pausing");
|
||||||
self.task.pause().block_on()?;
|
self.task.pause().block_on()?;
|
||||||
gst::debug!(CAT, imp: self, "Paused");
|
gst::debug!(CAT, imp = self, "Paused");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -898,7 +898,7 @@ impl ElementImpl for UdpSrc {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
@ -940,13 +940,13 @@ impl ElementImpl for UdpSrc {
|
||||||
fn send_event(&self, event: gst::Event) -> bool {
|
fn send_event(&self, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Handling element level event {event:?}");
|
gst::debug!(CAT, imp = self, "Handling element level event {event:?}");
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Eos(_) => {
|
EventView::Eos(_) => {
|
||||||
if self.state() != TaskState::Started {
|
if self.state() != TaskState::Started {
|
||||||
if let Err(err) = self.start() {
|
if let Err(err) = self.start() {
|
||||||
gst::error!(CAT, imp: self, "Failed to start task thread {err:?}");
|
gst::error!(CAT, imp = self, "Failed to start task thread {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ mod imp_src {
|
||||||
type ElementImpl = ElementSrcTest;
|
type ElementImpl = ElementSrcTest;
|
||||||
|
|
||||||
fn src_event(self, pad: &gst::Pad, imp: &ElementSrcTest, event: gst::Event) -> bool {
|
fn src_event(self, pad: &gst::Pad, imp: &ElementSrcTest, event: gst::Event) -> bool {
|
||||||
gst::log!(SRC_CAT, obj: pad, "Handling {:?}", event);
|
gst::log!(SRC_CAT, obj = pad, "Handling {:?}", event);
|
||||||
|
|
||||||
let ret = match event.view() {
|
let ret = match event.view() {
|
||||||
EventView::FlushStart(..) => {
|
EventView::FlushStart(..) => {
|
||||||
|
@ -100,9 +100,9 @@ mod imp_src {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret {
|
if ret {
|
||||||
gst::log!(SRC_CAT, obj: pad, "Handled {:?}", event);
|
gst::log!(SRC_CAT, obj = pad, "Handled {:?}", event);
|
||||||
} else {
|
} else {
|
||||||
gst::log!(SRC_CAT, obj: pad, "Didn't handle {:?}", event);
|
gst::log!(SRC_CAT, obj = pad, "Didn't handle {:?}", event);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -127,7 +127,7 @@ mod imp_src {
|
||||||
while let Ok(Some(_item)) = self.receiver.try_next() {}
|
while let Ok(Some(_item)) = self.receiver.try_next() {}
|
||||||
}
|
}
|
||||||
async fn push_item(&self, item: Item) -> Result<gst::FlowSuccess, gst::FlowError> {
|
async fn push_item(&self, item: Item) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::debug!(SRC_CAT, obj: self.element, "Handling {:?}", item);
|
gst::debug!(SRC_CAT, obj = self.element, "Handling {:?}", item);
|
||||||
|
|
||||||
let elementsrctest = self.element.imp();
|
let elementsrctest = self.element.imp();
|
||||||
match item {
|
match item {
|
||||||
|
@ -148,7 +148,7 @@ mod imp_src {
|
||||||
fn try_next(&mut self) -> BoxFuture<'_, Result<Item, gst::FlowError>> {
|
fn try_next(&mut self) -> BoxFuture<'_, Result<Item, gst::FlowError>> {
|
||||||
async move {
|
async move {
|
||||||
self.receiver.next().await.ok_or_else(|| {
|
self.receiver.next().await.ok_or_else(|| {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "SrcPad channel aborted");
|
gst::log!(SRC_CAT, obj = self.element, "SrcPad channel aborted");
|
||||||
gst::FlowError::Eos
|
gst::FlowError::Eos
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -159,9 +159,9 @@ mod imp_src {
|
||||||
async move {
|
async move {
|
||||||
let res = self.push_item(item).await.map(drop);
|
let res = self.push_item(item).await.map(drop);
|
||||||
match res {
|
match res {
|
||||||
Ok(_) => gst::log!(SRC_CAT, obj: self.element, "Successfully pushed item"),
|
Ok(_) => gst::log!(SRC_CAT, obj = self.element, "Successfully pushed item"),
|
||||||
Err(gst::FlowError::Flushing) => {
|
Err(gst::FlowError::Flushing) => {
|
||||||
gst::debug!(SRC_CAT, obj: self.element, "Flushing")
|
gst::debug!(SRC_CAT, obj = self.element, "Flushing")
|
||||||
}
|
}
|
||||||
Err(err) => panic!("Got error {err}"),
|
Err(err) => panic!("Got error {err}"),
|
||||||
}
|
}
|
||||||
|
@ -173,9 +173,9 @@ mod imp_src {
|
||||||
|
|
||||||
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn stop(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Stopping task");
|
gst::log!(SRC_CAT, obj = self.element, "Stopping task");
|
||||||
self.flush();
|
self.flush();
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Task stopped");
|
gst::log!(SRC_CAT, obj = self.element, "Task stopped");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -183,9 +183,9 @@ mod imp_src {
|
||||||
|
|
||||||
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
fn flush_start(&mut self) -> BoxFuture<'_, Result<(), gst::ErrorMessage>> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Starting task flush");
|
gst::log!(SRC_CAT, obj = self.element, "Starting task flush");
|
||||||
self.flush();
|
self.flush();
|
||||||
gst::log!(SRC_CAT, obj: self.element, "Task flush started");
|
gst::log!(SRC_CAT, obj = self.element, "Task flush started");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -219,7 +219,7 @@ mod imp_src {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Preparing");
|
gst::debug!(SRC_CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
let context =
|
let context =
|
||||||
|
@ -240,36 +240,36 @@ mod imp_src {
|
||||||
)
|
)
|
||||||
.block_on()?;
|
.block_on()?;
|
||||||
|
|
||||||
gst::debug!(SRC_CAT, imp: self, "Prepared");
|
gst::debug!(SRC_CAT, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unprepare(&self) {
|
fn unprepare(&self) {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Unpreparing");
|
gst::debug!(SRC_CAT, imp = self, "Unpreparing");
|
||||||
|
|
||||||
*self.sender.lock().unwrap() = None;
|
*self.sender.lock().unwrap() = None;
|
||||||
self.task.unprepare().block_on().unwrap();
|
self.task.unprepare().block_on().unwrap();
|
||||||
|
|
||||||
gst::debug!(SRC_CAT, imp: self, "Unprepared");
|
gst::debug!(SRC_CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) {
|
fn stop(&self) {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Stopping");
|
gst::debug!(SRC_CAT, imp = self, "Stopping");
|
||||||
self.task.stop().await_maybe_on_context().unwrap();
|
self.task.stop().await_maybe_on_context().unwrap();
|
||||||
gst::debug!(SRC_CAT, imp: self, "Stopped");
|
gst::debug!(SRC_CAT, imp = self, "Stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) {
|
fn start(&self) {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Starting");
|
gst::debug!(SRC_CAT, imp = self, "Starting");
|
||||||
self.task.start().await_maybe_on_context().unwrap();
|
self.task.start().await_maybe_on_context().unwrap();
|
||||||
gst::debug!(SRC_CAT, imp: self, "Started");
|
gst::debug!(SRC_CAT, imp = self, "Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause(&self) {
|
fn pause(&self) {
|
||||||
gst::debug!(SRC_CAT, imp: self, "Pausing");
|
gst::debug!(SRC_CAT, imp = self, "Pausing");
|
||||||
self.task.pause().block_on().unwrap();
|
self.task.pause().block_on().unwrap();
|
||||||
gst::debug!(SRC_CAT, imp: self, "Paused");
|
gst::debug!(SRC_CAT, imp = self, "Paused");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ mod imp_src {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::log!(SRC_CAT, imp: self, "Changing state {:?}", transition);
|
gst::log!(SRC_CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::NullToReady => {
|
gst::StateChange::NullToReady => {
|
||||||
|
@ -464,7 +464,7 @@ mod imp_sink {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_event(self, pad: &gst::Pad, imp: &ElementSinkTest, event: gst::Event) -> bool {
|
fn sink_event(self, pad: &gst::Pad, imp: &ElementSinkTest, event: gst::Event) -> bool {
|
||||||
gst::debug!(SINK_CAT, obj: pad, "Handling non-serialized {:?}", event);
|
gst::debug!(SINK_CAT, obj = pad, "Handling non-serialized {:?}", event);
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::FlushStart(..) => {
|
EventView::FlushStart(..) => {
|
||||||
|
@ -482,7 +482,7 @@ mod imp_sink {
|
||||||
event: gst::Event,
|
event: gst::Event,
|
||||||
) -> BoxFuture<'static, bool> {
|
) -> BoxFuture<'static, bool> {
|
||||||
async move {
|
async move {
|
||||||
gst::log!(SINK_CAT, obj: pad, "Handling serialized {:?}", event);
|
gst::log!(SINK_CAT, obj = pad, "Handling serialized {:?}", event);
|
||||||
|
|
||||||
let imp = elem.imp();
|
let imp = elem.imp();
|
||||||
if let EventView::FlushStop(..) = event.view() {
|
if let EventView::FlushStop(..) = event.view() {
|
||||||
|
@ -505,7 +505,7 @@ mod imp_sink {
|
||||||
impl ElementSinkTest {
|
impl ElementSinkTest {
|
||||||
async fn forward_item(&self, item: Item) -> Result<gst::FlowSuccess, gst::FlowError> {
|
async fn forward_item(&self, item: Item) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
if !self.flushing.load(Ordering::SeqCst) {
|
if !self.flushing.load(Ordering::SeqCst) {
|
||||||
gst::debug!(SINK_CAT, imp: self, "Forwarding {:?}", item);
|
gst::debug!(SINK_CAT, imp = self, "Forwarding {:?}", item);
|
||||||
let mut sender = self
|
let mut sender = self
|
||||||
.sender
|
.sender
|
||||||
.lock()
|
.lock()
|
||||||
|
@ -521,7 +521,7 @@ mod imp_sink {
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
SINK_CAT,
|
SINK_CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Not forwarding {:?} due to flushing",
|
"Not forwarding {:?} due to flushing",
|
||||||
item
|
item
|
||||||
);
|
);
|
||||||
|
@ -530,31 +530,31 @@ mod imp_sink {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) {
|
fn start(&self) {
|
||||||
gst::debug!(SINK_CAT, imp: self, "Starting");
|
gst::debug!(SINK_CAT, imp = self, "Starting");
|
||||||
self.flushing.store(false, Ordering::SeqCst);
|
self.flushing.store(false, Ordering::SeqCst);
|
||||||
gst::debug!(SINK_CAT, imp: self, "Started");
|
gst::debug!(SINK_CAT, imp = self, "Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) {
|
fn stop(&self) {
|
||||||
gst::debug!(SINK_CAT, imp: self, "Stopping");
|
gst::debug!(SINK_CAT, imp = self, "Stopping");
|
||||||
self.flushing.store(true, Ordering::SeqCst);
|
self.flushing.store(true, Ordering::SeqCst);
|
||||||
gst::debug!(SINK_CAT, imp: self, "Stopped");
|
gst::debug!(SINK_CAT, imp = self, "Stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_flush_start(&self) {
|
pub fn push_flush_start(&self) {
|
||||||
gst::debug!(SINK_CAT, imp: self, "Pushing FlushStart");
|
gst::debug!(SINK_CAT, imp = self, "Pushing FlushStart");
|
||||||
self.sink_pad
|
self.sink_pad
|
||||||
.gst_pad()
|
.gst_pad()
|
||||||
.push_event(gst::event::FlushStart::new());
|
.push_event(gst::event::FlushStart::new());
|
||||||
gst::debug!(SINK_CAT, imp: self, "FlushStart pushed");
|
gst::debug!(SINK_CAT, imp = self, "FlushStart pushed");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_flush_stop(&self) {
|
pub fn push_flush_stop(&self) {
|
||||||
gst::debug!(SINK_CAT, imp: self, "Pushing FlushStop");
|
gst::debug!(SINK_CAT, imp = self, "Pushing FlushStop");
|
||||||
self.sink_pad
|
self.sink_pad
|
||||||
.gst_pad()
|
.gst_pad()
|
||||||
.push_event(gst::event::FlushStop::new(true));
|
.push_event(gst::event::FlushStop::new(true));
|
||||||
gst::debug!(SINK_CAT, imp: self, "FlushStop pushed");
|
gst::debug!(SINK_CAT, imp = self, "FlushStop pushed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,7 +657,7 @@ mod imp_sink {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::log!(SINK_CAT, imp: self, "Changing state {:?}", transition);
|
gst::log!(SINK_CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
if let gst::StateChange::PausedToReady = transition {
|
if let gst::StateChange::PausedToReady = transition {
|
||||||
self.stop();
|
self.stop();
|
||||||
|
|
|
@ -364,7 +364,7 @@ fn eos() {
|
||||||
sink.set_callbacks(
|
sink.set_callbacks(
|
||||||
gst_app::AppSinkCallbacks::builder()
|
gst_app::AppSinkCallbacks::builder()
|
||||||
.new_sample(move |appsink| {
|
.new_sample(move |appsink| {
|
||||||
gst::debug!(CAT, obj: appsink, "eos: pulling sample");
|
gst::debug!(CAT, obj = appsink, "eos: pulling sample");
|
||||||
let _ = appsink.pull_sample().unwrap();
|
let _ = appsink.pull_sample().unwrap();
|
||||||
|
|
||||||
sample_notifier.send(()).unwrap();
|
sample_notifier.send(()).unwrap();
|
||||||
|
@ -376,7 +376,7 @@ fn eos() {
|
||||||
);
|
);
|
||||||
|
|
||||||
fn push_buffer(src: &gst::Element) -> bool {
|
fn push_buffer(src: &gst::Element) -> bool {
|
||||||
gst::debug!(CAT, obj: src, "eos: pushing buffer");
|
gst::debug!(CAT, obj = src, "eos: pushing buffer");
|
||||||
src.emit_by_name::<bool>("push-buffer", &[&gst::Buffer::from_slice(vec![0; 1024])])
|
src.emit_by_name::<bool>("push-buffer", &[&gst::Buffer::from_slice(vec![0; 1024])])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ fn premature_shutdown() {
|
||||||
sink.set_callbacks(
|
sink.set_callbacks(
|
||||||
gst_app::AppSinkCallbacks::builder()
|
gst_app::AppSinkCallbacks::builder()
|
||||||
.new_sample(move |appsink| {
|
.new_sample(move |appsink| {
|
||||||
gst::debug!(CAT, obj: appsink, "premature_shutdown: pulling sample");
|
gst::debug!(CAT, obj = appsink, "premature_shutdown: pulling sample");
|
||||||
let _sample = appsink.pull_sample().unwrap();
|
let _sample = appsink.pull_sample().unwrap();
|
||||||
|
|
||||||
appsink_sender.send(()).unwrap();
|
appsink_sender.send(()).unwrap();
|
||||||
|
@ -511,7 +511,7 @@ fn premature_shutdown() {
|
||||||
fn push_buffer(src: &gst::Element, intent: &str) -> bool {
|
fn push_buffer(src: &gst::Element, intent: &str) -> bool {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: src,
|
obj = src,
|
||||||
"premature_shutdown: pushing buffer {}",
|
"premature_shutdown: pushing buffer {}",
|
||||||
intent
|
intent
|
||||||
);
|
);
|
||||||
|
|
|
@ -311,10 +311,10 @@ impl FlvDemux {
|
||||||
// gst::SchedulingFlags::SEEKABLE,
|
// gst::SchedulingFlags::SEEKABLE,
|
||||||
// )
|
// )
|
||||||
// {
|
// {
|
||||||
// gst::debug!(CAT, obj: pad, "Activating in Pull mode");
|
// gst::debug!(CAT, obj = pad, "Activating in Pull mode");
|
||||||
// gst::PadMode::Pull
|
// gst::PadMode::Pull
|
||||||
// } else {
|
// } else {
|
||||||
gst::debug!(CAT, obj: pad, "Activating in Push mode");
|
gst::debug!(CAT, obj = pad, "Activating in Push mode");
|
||||||
gst::PadMode::Push
|
gst::PadMode::Push
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
@ -366,7 +366,7 @@ impl FlvDemux {
|
||||||
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling event {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling event {:?}", event);
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Eos(..) => {
|
EventView::Eos(..) => {
|
||||||
// TODO implement
|
// TODO implement
|
||||||
|
@ -453,7 +453,7 @@ impl FlvDemux {
|
||||||
pad: &gst::Pad,
|
pad: &gst::Pad,
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(CAT, obj: pad, "Handling buffer {:?}", buffer);
|
gst::log!(CAT, obj = pad, "Handling buffer {:?}", buffer);
|
||||||
|
|
||||||
let mut adapter = self.adapter.lock().unwrap();
|
let mut adapter = self.adapter.lock().unwrap();
|
||||||
adapter.push(buffer);
|
adapter.push(buffer);
|
||||||
|
@ -466,7 +466,7 @@ impl FlvDemux {
|
||||||
let header = match self.find_header(&mut adapter) {
|
let header = match self.find_header(&mut adapter) {
|
||||||
Ok(header) => header,
|
Ok(header) => header,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::trace!(CAT, imp: self, "Need more data");
|
gst::trace!(CAT, imp = self, "Need more data");
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -495,7 +495,7 @@ impl FlvDemux {
|
||||||
} => {
|
} => {
|
||||||
let avail = adapter.available();
|
let avail = adapter.available();
|
||||||
if avail == 0 {
|
if avail == 0 {
|
||||||
gst::trace!(CAT, imp: self, "Need more data");
|
gst::trace!(CAT, imp = self, "Need more data");
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
let skip = cmp::min(avail, *skip_left as usize);
|
let skip = cmp::min(avail, *skip_left as usize);
|
||||||
|
@ -507,7 +507,7 @@ impl FlvDemux {
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
gst::trace!(CAT, imp: self, "Need more data");
|
gst::trace!(CAT, imp = self, "Need more data");
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
Ok(Some(events)) => {
|
Ok(Some(events)) => {
|
||||||
|
@ -534,7 +534,7 @@ impl FlvDemux {
|
||||||
let data = adapter.map(9).unwrap();
|
let data = adapter.map(9).unwrap();
|
||||||
|
|
||||||
if let Ok((_, header)) = flavors::header(&data) {
|
if let Ok((_, header)) = flavors::header(&data) {
|
||||||
gst::debug!(CAT, imp: self, "Found FLV header: {:?}", header);
|
gst::debug!(CAT, imp = self, "Found FLV header: {:?}", header);
|
||||||
drop(data);
|
drop(data);
|
||||||
adapter.flush(9);
|
adapter.flush(9);
|
||||||
|
|
||||||
|
@ -597,7 +597,7 @@ impl FlvDemux {
|
||||||
let res = pad.push(buffer);
|
let res = pad.push(buffer);
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Pushing buffer for stream {:?} returned {:?}",
|
"Pushing buffer for stream {:?} returned {:?}",
|
||||||
stream,
|
stream,
|
||||||
res
|
res
|
||||||
|
@ -687,7 +687,7 @@ impl StreamingState {
|
||||||
match be_u32::<_, (_, nom::error::ErrorKind)>(&data[0..4]) {
|
match be_u32::<_, (_, nom::error::ErrorKind)>(&data[0..4]) {
|
||||||
Err(_) => unreachable!(),
|
Err(_) => unreachable!(),
|
||||||
Ok((_, previous_size)) => {
|
Ok((_, previous_size)) => {
|
||||||
gst::trace!(CAT, imp: imp, "Previous tag size {}", previous_size);
|
gst::trace!(CAT, imp = imp, "Previous tag size {}", previous_size);
|
||||||
// Nothing to do here, we just consume it for now
|
// Nothing to do here, we just consume it for now
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -703,7 +703,7 @@ impl StreamingState {
|
||||||
Ok((_, tag_header)) => tag_header,
|
Ok((_, tag_header)) => tag_header,
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(CAT, imp: imp, "Parsed tag header {:?}", tag_header);
|
gst::trace!(CAT, imp = imp, "Parsed tag header {:?}", tag_header);
|
||||||
|
|
||||||
drop(data);
|
drop(data);
|
||||||
|
|
||||||
|
@ -715,17 +715,17 @@ impl StreamingState {
|
||||||
|
|
||||||
match tag_header.tag_type {
|
match tag_header.tag_type {
|
||||||
flavors::TagType::Script => {
|
flavors::TagType::Script => {
|
||||||
gst::trace!(CAT, imp: imp, "Found script tag");
|
gst::trace!(CAT, imp = imp, "Found script tag");
|
||||||
|
|
||||||
Ok(self.handle_script_tag(imp, &tag_header, adapter))
|
Ok(self.handle_script_tag(imp, &tag_header, adapter))
|
||||||
}
|
}
|
||||||
flavors::TagType::Audio => {
|
flavors::TagType::Audio => {
|
||||||
gst::trace!(CAT, imp: imp, "Found audio tag");
|
gst::trace!(CAT, imp = imp, "Found audio tag");
|
||||||
|
|
||||||
self.handle_audio_tag(imp, &tag_header, adapter)
|
self.handle_audio_tag(imp, &tag_header, adapter)
|
||||||
}
|
}
|
||||||
flavors::TagType::Video => {
|
flavors::TagType::Video => {
|
||||||
gst::trace!(CAT, imp: imp, "Found video tag");
|
gst::trace!(CAT, imp = imp, "Found video tag");
|
||||||
|
|
||||||
self.handle_video_tag(imp, &tag_header, adapter)
|
self.handle_video_tag(imp, &tag_header, adapter)
|
||||||
}
|
}
|
||||||
|
@ -747,10 +747,10 @@ impl StreamingState {
|
||||||
|
|
||||||
match flavors::script_data(&data) {
|
match flavors::script_data(&data) {
|
||||||
Ok((_, ref script_data)) if script_data.name == "onMetaData" => {
|
Ok((_, ref script_data)) if script_data.name == "onMetaData" => {
|
||||||
gst::trace!(CAT, imp: imp, "Got script tag: {:?}", script_data);
|
gst::trace!(CAT, imp = imp, "Got script tag: {:?}", script_data);
|
||||||
|
|
||||||
let metadata = Metadata::new(script_data);
|
let metadata = Metadata::new(script_data);
|
||||||
gst::debug!(CAT, imp: imp, "Got metadata: {:?}", metadata);
|
gst::debug!(CAT, imp = imp, "Got metadata: {:?}", metadata);
|
||||||
|
|
||||||
let audio_changed = self
|
let audio_changed = self
|
||||||
.audio
|
.audio
|
||||||
|
@ -778,10 +778,10 @@ impl StreamingState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((_, ref script_data)) => {
|
Ok((_, ref script_data)) => {
|
||||||
gst::trace!(CAT, imp: imp, "Got script tag: {:?}", script_data);
|
gst::trace!(CAT, imp = imp, "Got script tag: {:?}", script_data);
|
||||||
}
|
}
|
||||||
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
||||||
gst::error!(CAT, imp: imp, "Error parsing script tag: {:?}", err);
|
gst::error!(CAT, imp = imp, "Error parsing script tag: {:?}", err);
|
||||||
}
|
}
|
||||||
Err(nom::Err::Incomplete(_)) => {
|
Err(nom::Err::Incomplete(_)) => {
|
||||||
// ignore
|
// ignore
|
||||||
|
@ -801,7 +801,7 @@ impl StreamingState {
|
||||||
) -> SmallVec<[Event; 4]> {
|
) -> SmallVec<[Event; 4]> {
|
||||||
let mut events = SmallVec::new();
|
let mut events = SmallVec::new();
|
||||||
|
|
||||||
gst::trace!(CAT, imp: imp, "Got audio data header: {:?}", data_header);
|
gst::trace!(CAT, imp = imp, "Got audio data header: {:?}", data_header);
|
||||||
|
|
||||||
let new_audio_format =
|
let new_audio_format =
|
||||||
AudioFormat::new(data_header, &self.metadata, &self.aac_sequence_header);
|
AudioFormat::new(data_header, &self.metadata, &self.aac_sequence_header);
|
||||||
|
@ -809,7 +809,7 @@ impl StreamingState {
|
||||||
if self.audio.as_ref() != Some(&new_audio_format) {
|
if self.audio.as_ref() != Some(&new_audio_format) {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Got new audio format: {:?}",
|
"Got new audio format: {:?}",
|
||||||
new_audio_format
|
new_audio_format
|
||||||
);
|
);
|
||||||
|
@ -827,7 +827,7 @@ impl StreamingState {
|
||||||
&& self.audio.is_some()
|
&& self.audio.is_some()
|
||||||
&& !self.got_all_streams
|
&& !self.got_all_streams
|
||||||
{
|
{
|
||||||
gst::debug!(CAT, imp: imp, "Have all expected streams now");
|
gst::debug!(CAT, imp = imp, "Have all expected streams now");
|
||||||
self.got_all_streams = true;
|
self.got_all_streams = true;
|
||||||
events.push(Event::HaveAllStreams);
|
events.push(Event::HaveAllStreams);
|
||||||
}
|
}
|
||||||
|
@ -846,7 +846,7 @@ impl StreamingState {
|
||||||
adapter.flush((tag_header.data_size - 1) as usize);
|
adapter.flush((tag_header.data_size - 1) as usize);
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Too small packet for AAC packet header {}",
|
"Too small packet for AAC packet header {}",
|
||||||
tag_header.data_size
|
tag_header.data_size
|
||||||
);
|
);
|
||||||
|
@ -857,14 +857,14 @@ impl StreamingState {
|
||||||
|
|
||||||
match flavors::aac_audio_packet_header(&data) {
|
match flavors::aac_audio_packet_header(&data) {
|
||||||
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
||||||
gst::error!(CAT, imp: imp, "Invalid AAC audio packet header: {:?}", err);
|
gst::error!(CAT, imp = imp, "Invalid AAC audio packet header: {:?}", err);
|
||||||
drop(data);
|
drop(data);
|
||||||
adapter.flush((tag_header.data_size - 1) as usize);
|
adapter.flush((tag_header.data_size - 1) as usize);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
Err(nom::Err::Incomplete(_)) => unreachable!(),
|
Err(nom::Err::Incomplete(_)) => unreachable!(),
|
||||||
Ok((_, header)) => {
|
Ok((_, header)) => {
|
||||||
gst::trace!(CAT, imp: imp, "Got AAC packet header {:?}", header);
|
gst::trace!(CAT, imp = imp, "Got AAC packet header {:?}", header);
|
||||||
match header.packet_type {
|
match header.packet_type {
|
||||||
flavors::AACPacketType::SequenceHeader => {
|
flavors::AACPacketType::SequenceHeader => {
|
||||||
drop(data);
|
drop(data);
|
||||||
|
@ -872,7 +872,7 @@ impl StreamingState {
|
||||||
let buffer = adapter
|
let buffer = adapter
|
||||||
.take_buffer((tag_header.data_size - 1 - 1) as usize)
|
.take_buffer((tag_header.data_size - 1 - 1) as usize)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
gst::debug!(CAT, imp: imp, "Got AAC sequence header {:?}", buffer,);
|
gst::debug!(CAT, imp = imp, "Got AAC sequence header {:?}", buffer,);
|
||||||
|
|
||||||
self.aac_sequence_header = Some(buffer);
|
self.aac_sequence_header = Some(buffer);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
|
@ -898,7 +898,7 @@ impl StreamingState {
|
||||||
let data = adapter.map(1).unwrap();
|
let data = adapter.map(1).unwrap();
|
||||||
let data_header = match flavors::audio_data_header(&data) {
|
let data_header = match flavors::audio_data_header(&data) {
|
||||||
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
||||||
gst::error!(CAT, imp: imp, "Invalid audio data header: {:?}", err);
|
gst::error!(CAT, imp = imp, "Invalid audio data header: {:?}", err);
|
||||||
drop(data);
|
drop(data);
|
||||||
adapter.flush(tag_header.data_size as usize);
|
adapter.flush(tag_header.data_size as usize);
|
||||||
return Ok(SmallVec::new());
|
return Ok(SmallVec::new());
|
||||||
|
@ -943,7 +943,7 @@ impl StreamingState {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Outputting audio buffer {:?} for tag {:?}",
|
"Outputting audio buffer {:?} for tag {:?}",
|
||||||
buffer,
|
buffer,
|
||||||
tag_header,
|
tag_header,
|
||||||
|
@ -963,7 +963,7 @@ impl StreamingState {
|
||||||
) -> SmallVec<[Event; 4]> {
|
) -> SmallVec<[Event; 4]> {
|
||||||
let mut events = SmallVec::new();
|
let mut events = SmallVec::new();
|
||||||
|
|
||||||
gst::trace!(CAT, imp: imp, "Got video data header: {:?}", data_header);
|
gst::trace!(CAT, imp = imp, "Got video data header: {:?}", data_header);
|
||||||
|
|
||||||
let new_video_format =
|
let new_video_format =
|
||||||
VideoFormat::new(data_header, &self.metadata, &self.avc_sequence_header);
|
VideoFormat::new(data_header, &self.metadata, &self.avc_sequence_header);
|
||||||
|
@ -971,7 +971,7 @@ impl StreamingState {
|
||||||
if self.video.as_ref() != Some(&new_video_format) {
|
if self.video.as_ref() != Some(&new_video_format) {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Got new video format: {:?}",
|
"Got new video format: {:?}",
|
||||||
new_video_format
|
new_video_format
|
||||||
);
|
);
|
||||||
|
@ -989,7 +989,7 @@ impl StreamingState {
|
||||||
&& self.video.is_some()
|
&& self.video.is_some()
|
||||||
&& !self.got_all_streams
|
&& !self.got_all_streams
|
||||||
{
|
{
|
||||||
gst::debug!(CAT, imp: imp, "Have all expected streams now");
|
gst::debug!(CAT, imp = imp, "Have all expected streams now");
|
||||||
self.got_all_streams = true;
|
self.got_all_streams = true;
|
||||||
events.push(Event::HaveAllStreams);
|
events.push(Event::HaveAllStreams);
|
||||||
}
|
}
|
||||||
|
@ -1008,7 +1008,7 @@ impl StreamingState {
|
||||||
adapter.flush((tag_header.data_size - 1) as usize);
|
adapter.flush((tag_header.data_size - 1) as usize);
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Too small packet for AVC packet header {}",
|
"Too small packet for AVC packet header {}",
|
||||||
tag_header.data_size
|
tag_header.data_size
|
||||||
);
|
);
|
||||||
|
@ -1018,14 +1018,14 @@ impl StreamingState {
|
||||||
let data = adapter.map(4).unwrap();
|
let data = adapter.map(4).unwrap();
|
||||||
match flavors::avc_video_packet_header(&data) {
|
match flavors::avc_video_packet_header(&data) {
|
||||||
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
||||||
gst::error!(CAT, imp: imp, "Invalid AVC video packet header: {:?}", err);
|
gst::error!(CAT, imp = imp, "Invalid AVC video packet header: {:?}", err);
|
||||||
drop(data);
|
drop(data);
|
||||||
adapter.flush((tag_header.data_size - 1) as usize);
|
adapter.flush((tag_header.data_size - 1) as usize);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
Err(nom::Err::Incomplete(_)) => unreachable!(),
|
Err(nom::Err::Incomplete(_)) => unreachable!(),
|
||||||
Ok((_, header)) => {
|
Ok((_, header)) => {
|
||||||
gst::trace!(CAT, imp: imp, "Got AVC packet header {:?}", header);
|
gst::trace!(CAT, imp = imp, "Got AVC packet header {:?}", header);
|
||||||
match header.packet_type {
|
match header.packet_type {
|
||||||
flavors::AVCPacketType::SequenceHeader => {
|
flavors::AVCPacketType::SequenceHeader => {
|
||||||
drop(data);
|
drop(data);
|
||||||
|
@ -1035,7 +1035,7 @@ impl StreamingState {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Got AVC sequence header {:?} of size {}",
|
"Got AVC sequence header {:?} of size {}",
|
||||||
buffer,
|
buffer,
|
||||||
tag_header.data_size - 1 - 4
|
tag_header.data_size - 1 - 4
|
||||||
|
@ -1071,7 +1071,7 @@ impl StreamingState {
|
||||||
let data = adapter.map(1).unwrap();
|
let data = adapter.map(1).unwrap();
|
||||||
let data_header = match flavors::video_data_header(&data) {
|
let data_header = match flavors::video_data_header(&data) {
|
||||||
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
Err(nom::Err::Error(err)) | Err(nom::Err::Failure(err)) => {
|
||||||
gst::error!(CAT, imp: imp, "Invalid video data header: {:?}", err);
|
gst::error!(CAT, imp = imp, "Invalid video data header: {:?}", err);
|
||||||
drop(data);
|
drop(data);
|
||||||
adapter.flush(tag_header.data_size as usize);
|
adapter.flush(tag_header.data_size as usize);
|
||||||
return Ok(SmallVec::new());
|
return Ok(SmallVec::new());
|
||||||
|
@ -1147,7 +1147,7 @@ impl StreamingState {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Outputting video buffer {:?} for tag {:?}, keyframe: {}",
|
"Outputting video buffer {:?} for tag {:?}, keyframe: {}",
|
||||||
buffer,
|
buffer,
|
||||||
tag_header,
|
tag_header,
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -180,17 +180,17 @@ impl MP4Mux {
|
||||||
}
|
}
|
||||||
|
|
||||||
if delta_frames.requires_dts() && buffer.dts().is_none() {
|
if delta_frames.requires_dts() && buffer.dts().is_none() {
|
||||||
gst::error!(CAT, obj: sinkpad, "Require DTS for video streams");
|
gst::error!(CAT, obj = sinkpad, "Require DTS for video streams");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if buffer.pts().is_none() {
|
if buffer.pts().is_none() {
|
||||||
gst::error!(CAT, obj: sinkpad, "Require timestamped buffers");
|
gst::error!(CAT, obj = sinkpad, "Require timestamped buffers");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if delta_frames.intra_only() && buffer.flags().contains(gst::BufferFlags::DELTA_UNIT) {
|
if delta_frames.intra_only() && buffer.flags().contains(gst::BufferFlags::DELTA_UNIT) {
|
||||||
gst::error!(CAT, obj: sinkpad, "Intra-only stream with delta units");
|
gst::error!(CAT, obj = sinkpad, "Intra-only stream with delta units");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ impl MP4Mux {
|
||||||
let mut segment = match sinkpad.segment().downcast::<gst::ClockTime>().ok() {
|
let mut segment = match sinkpad.segment().downcast::<gst::ClockTime>().ok() {
|
||||||
Some(segment) => segment,
|
Some(segment) => segment,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, obj: sinkpad, "Got buffer before segment");
|
gst::error!(CAT, obj = sinkpad, "Got buffer before segment");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -242,7 +242,7 @@ impl MP4Mux {
|
||||||
// Calculate from the mapping
|
// Calculate from the mapping
|
||||||
running_time_to_utc_time(pts, running_time_utc_time_mapping).ok_or_else(
|
running_time_to_utc_time(pts, running_time_utc_time_mapping).ok_or_else(
|
||||||
|| {
|
|| {
|
||||||
gst::error!(CAT, obj: sinkpad, "Stream has negative PTS UTC time");
|
gst::error!(CAT, obj = sinkpad, "Stream has negative PTS UTC time");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
},
|
},
|
||||||
)?
|
)?
|
||||||
|
@ -252,7 +252,7 @@ impl MP4Mux {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: sinkpad,
|
obj = sinkpad,
|
||||||
"Mapped PTS running time {pts} to UTC time {utc_time}"
|
"Mapped PTS running time {pts} to UTC time {utc_time}"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -263,12 +263,12 @@ impl MP4Mux {
|
||||||
if let Some(dts) = dts {
|
if let Some(dts) = dts {
|
||||||
let dts_utc_time =
|
let dts_utc_time =
|
||||||
running_time_to_utc_time(dts, (pts, utc_time)).ok_or_else(|| {
|
running_time_to_utc_time(dts, (pts, utc_time)).ok_or_else(|| {
|
||||||
gst::error!(CAT, obj: sinkpad, "Stream has negative DTS UTC time");
|
gst::error!(CAT, obj = sinkpad, "Stream has negative DTS UTC time");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: sinkpad,
|
obj = sinkpad,
|
||||||
"Mapped DTS running time {dts} to UTC time {dts_utc_time}"
|
"Mapped DTS running time {dts} to UTC time {dts_utc_time}"
|
||||||
);
|
);
|
||||||
buffer.set_dts(dts_utc_time);
|
buffer.set_dts(dts_utc_time);
|
||||||
|
@ -317,7 +317,7 @@ impl MP4Mux {
|
||||||
{
|
{
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: sinkpad,
|
obj = sinkpad,
|
||||||
"Got no UTC time in the first 6s of the stream"
|
"Got no UTC time in the first 6s of the stream"
|
||||||
);
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
|
@ -326,7 +326,7 @@ impl MP4Mux {
|
||||||
|
|
||||||
let Some(buffer) = sinkpad.pop_buffer() else {
|
let Some(buffer) = sinkpad.pop_buffer() else {
|
||||||
if sinkpad.is_eos() {
|
if sinkpad.is_eos() {
|
||||||
gst::error!(CAT, obj: sinkpad, "Got no UTC time before EOS");
|
gst::error!(CAT, obj = sinkpad, "Got no UTC time before EOS");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
} else {
|
} else {
|
||||||
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
||||||
|
@ -342,7 +342,7 @@ impl MP4Mux {
|
||||||
let segment = match sinkpad.segment().downcast::<gst::ClockTime>().ok() {
|
let segment = match sinkpad.segment().downcast::<gst::ClockTime>().ok() {
|
||||||
Some(segment) => segment,
|
Some(segment) => segment,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, obj: sinkpad, "Got buffer before segment");
|
gst::error!(CAT, obj = sinkpad, "Got buffer before segment");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -358,7 +358,7 @@ impl MP4Mux {
|
||||||
let running_time = segment.to_running_time_full(buffer.pts().unwrap()).unwrap();
|
let running_time = segment.to_running_time_full(buffer.pts().unwrap()).unwrap();
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: sinkpad,
|
obj = sinkpad,
|
||||||
"Got initial UTC time {utc_time} at PTS running time {running_time}",
|
"Got initial UTC time {utc_time} at PTS running time {running_time}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -374,12 +374,12 @@ impl MP4Mux {
|
||||||
|
|
||||||
let pts = segment.to_running_time_full(buffer.pts().unwrap()).unwrap();
|
let pts = segment.to_running_time_full(buffer.pts().unwrap()).unwrap();
|
||||||
let pts_utc_time = running_time_to_utc_time(pts, mapping).ok_or_else(|| {
|
let pts_utc_time = running_time_to_utc_time(pts, mapping).ok_or_else(|| {
|
||||||
gst::error!(CAT, obj: sinkpad, "Stream has negative PTS UTC time");
|
gst::error!(CAT, obj = sinkpad, "Stream has negative PTS UTC time");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: sinkpad,
|
obj = sinkpad,
|
||||||
"Mapped PTS running time {pts} to UTC time {pts_utc_time}"
|
"Mapped PTS running time {pts} to UTC time {pts_utc_time}"
|
||||||
);
|
);
|
||||||
buffer.set_pts(pts_utc_time);
|
buffer.set_pts(pts_utc_time);
|
||||||
|
@ -387,12 +387,12 @@ impl MP4Mux {
|
||||||
if let Some(dts) = buffer.dts() {
|
if let Some(dts) = buffer.dts() {
|
||||||
let dts = segment.to_running_time_full(dts).unwrap();
|
let dts = segment.to_running_time_full(dts).unwrap();
|
||||||
let dts_utc_time = running_time_to_utc_time(dts, mapping).ok_or_else(|| {
|
let dts_utc_time = running_time_to_utc_time(dts, mapping).ok_or_else(|| {
|
||||||
gst::error!(CAT, obj: sinkpad, "Stream has negative DTS UTC time");
|
gst::error!(CAT, obj = sinkpad, "Stream has negative DTS UTC time");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: sinkpad,
|
obj = sinkpad,
|
||||||
"Mapped DTS running time {dts} to UTC time {dts_utc_time}"
|
"Mapped DTS running time {dts} to UTC time {dts_utc_time}"
|
||||||
);
|
);
|
||||||
buffer.set_dts(dts_utc_time);
|
buffer.set_dts(dts_utc_time);
|
||||||
|
@ -432,7 +432,7 @@ impl MP4Mux {
|
||||||
let segment = match stream.sinkpad.segment().downcast::<gst::ClockTime>().ok() {
|
let segment = match stream.sinkpad.segment().downcast::<gst::ClockTime>().ok() {
|
||||||
Some(segment) => segment,
|
Some(segment) => segment,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, obj: stream.sinkpad, "Got buffer before segment");
|
gst::error!(CAT, obj = stream.sinkpad, "Got buffer before segment");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -486,13 +486,13 @@ impl MP4Mux {
|
||||||
let dur = buffer.duration().unwrap_or(gst::ClockTime::ZERO);
|
let dur = buffer.duration().unwrap_or(gst::ClockTime::ZERO);
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: stream.sinkpad,
|
obj = stream.sinkpad,
|
||||||
"Stream is EOS, using {dur} as duration for queued buffer",
|
"Stream is EOS, using {dur} as duration for queued buffer",
|
||||||
);
|
);
|
||||||
|
|
||||||
let pts = pts + dur;
|
let pts = pts + dur;
|
||||||
if stream.end_pts.map_or(true, |end_pts| end_pts < pts) {
|
if stream.end_pts.map_or(true, |end_pts| end_pts < pts) {
|
||||||
gst::trace!(CAT, obj: stream.sinkpad, "Stream end PTS {pts}");
|
gst::trace!(CAT, obj = stream.sinkpad, "Stream end PTS {pts}");
|
||||||
stream.end_pts = Some(pts);
|
stream.end_pts = Some(pts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +500,11 @@ impl MP4Mux {
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, obj: stream.sinkpad, "Stream has no buffer queued");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
obj = stream.sinkpad,
|
||||||
|
"Stream has no buffer queued"
|
||||||
|
);
|
||||||
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -521,7 +525,7 @@ impl MP4Mux {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: stream.sinkpad,
|
obj = stream.sinkpad,
|
||||||
"Stream has buffer with timestamp {next_timestamp} queued",
|
"Stream has buffer with timestamp {next_timestamp} queued",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -531,7 +535,7 @@ impl MP4Mux {
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: stream.sinkpad,
|
obj = stream.sinkpad,
|
||||||
"Stream timestamps going backwards {next_timestamp} < {timestamp}",
|
"Stream timestamps going backwards {next_timestamp} < {timestamp}",
|
||||||
);
|
);
|
||||||
gst::ClockTime::ZERO
|
gst::ClockTime::ZERO
|
||||||
|
@ -539,13 +543,13 @@ impl MP4Mux {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: stream.sinkpad,
|
obj = stream.sinkpad,
|
||||||
"Using {dur} as duration for queued buffer",
|
"Using {dur} as duration for queued buffer",
|
||||||
);
|
);
|
||||||
|
|
||||||
let pts = pts + dur;
|
let pts = pts + dur;
|
||||||
if stream.end_pts.map_or(true, |end_pts| end_pts < pts) {
|
if stream.end_pts.map_or(true, |end_pts| end_pts < pts) {
|
||||||
gst::trace!(CAT, obj: stream.sinkpad, "Stream end PTS {pts}");
|
gst::trace!(CAT, obj = stream.sinkpad, "Stream end PTS {pts}");
|
||||||
stream.end_pts = Some(pts);
|
stream.end_pts = Some(pts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,11 +562,16 @@ impl MP4Mux {
|
||||||
&& s.name().as_str() == "video/x-av1"
|
&& s.name().as_str() == "video/x-av1"
|
||||||
{
|
{
|
||||||
let buf_map = buffer.map_readable().map_err(|_| {
|
let buf_map = buffer.map_readable().map_err(|_| {
|
||||||
gst::error!(CAT, obj: stream.sinkpad, "Failed to map buffer");
|
gst::error!(CAT, obj = stream.sinkpad, "Failed to map buffer");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
stream.extra_header_data = read_seq_header_obu_bytes(buf_map.as_slice()).map_err(|_| {
|
stream.extra_header_data = read_seq_header_obu_bytes(buf_map.as_slice())
|
||||||
gst::error!(CAT, obj: stream.sinkpad, "Failed to parse AV1 SequenceHeader OBU");
|
.map_err(|_| {
|
||||||
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
obj = stream.sinkpad,
|
||||||
|
"Failed to parse AV1 SequenceHeader OBU"
|
||||||
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
@ -576,15 +585,15 @@ impl MP4Mux {
|
||||||
Some(res) => res,
|
Some(res) => res,
|
||||||
None => {
|
None => {
|
||||||
if stream.sinkpad.is_eos() {
|
if stream.sinkpad.is_eos() {
|
||||||
gst::trace!(
|
gst::trace!(CAT, obj = stream.sinkpad, "Stream is EOS",);
|
||||||
CAT,
|
|
||||||
obj: stream.sinkpad,
|
|
||||||
"Stream is EOS",
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(gst::FlowError::Eos);
|
return Err(gst::FlowError::Eos);
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, obj: stream.sinkpad, "Stream has no buffer queued");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
obj = stream.sinkpad,
|
||||||
|
"Stream has no buffer queued"
|
||||||
|
);
|
||||||
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -594,9 +603,16 @@ impl MP4Mux {
|
||||||
let pts_position = buffer.pts().unwrap();
|
let pts_position = buffer.pts().unwrap();
|
||||||
let dts_position = buffer.dts();
|
let dts_position = buffer.dts();
|
||||||
|
|
||||||
let pts = segment.to_running_time_full(pts_position).unwrap()
|
let pts = segment
|
||||||
.positive().unwrap_or_else(|| {
|
.to_running_time_full(pts_position)
|
||||||
gst::error!(CAT, obj: stream.sinkpad, "Stream has negative PTS running time");
|
.unwrap()
|
||||||
|
.positive()
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
obj = stream.sinkpad,
|
||||||
|
"Stream has negative PTS running time"
|
||||||
|
);
|
||||||
gst::ClockTime::ZERO
|
gst::ClockTime::ZERO
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -608,7 +624,7 @@ impl MP4Mux {
|
||||||
let dts = dts.unwrap();
|
let dts = dts.unwrap();
|
||||||
|
|
||||||
if stream.start_dts.is_none() {
|
if stream.start_dts.is_none() {
|
||||||
gst::debug!(CAT, obj: stream.sinkpad, "Stream start DTS {dts}");
|
gst::debug!(CAT, obj = stream.sinkpad, "Stream start DTS {dts}");
|
||||||
stream.start_dts = Some(dts);
|
stream.start_dts = Some(dts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,7 +637,7 @@ impl MP4Mux {
|
||||||
.earliest_pts
|
.earliest_pts
|
||||||
.map_or(true, |earliest_pts| earliest_pts > pts)
|
.map_or(true, |earliest_pts| earliest_pts > pts)
|
||||||
{
|
{
|
||||||
gst::debug!(CAT, obj: stream.sinkpad, "Stream earliest PTS {pts}");
|
gst::debug!(CAT, obj = stream.sinkpad, "Stream earliest PTS {pts}");
|
||||||
stream.earliest_pts = Some(pts);
|
stream.earliest_pts = Some(pts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,7 +646,7 @@ impl MP4Mux {
|
||||||
let dts = dts.unwrap(); // set above
|
let dts = dts.unwrap(); // set above
|
||||||
|
|
||||||
Some(i64::try_from((pts - dts).nseconds()).map_err(|_| {
|
Some(i64::try_from((pts - dts).nseconds()).map_err(|_| {
|
||||||
gst::error!(CAT, obj: stream.sinkpad, "Too big PTS/DTS difference");
|
gst::error!(CAT, obj = stream.sinkpad, "Too big PTS/DTS difference");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?)
|
})?)
|
||||||
} else {
|
} else {
|
||||||
|
@ -639,7 +655,7 @@ impl MP4Mux {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: stream.sinkpad,
|
obj = stream.sinkpad,
|
||||||
"Stream has buffer of size {} with timestamp {timestamp} pending",
|
"Stream has buffer of size {} with timestamp {timestamp} pending",
|
||||||
buffer.size(),
|
buffer.size(),
|
||||||
);
|
);
|
||||||
|
@ -686,7 +702,7 @@ impl MP4Mux {
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
gst::trace!(CAT,
|
gst::trace!(CAT,
|
||||||
obj: stream.sinkpad,
|
obj = stream.sinkpad,
|
||||||
"Continuing current chunk: single stream {single_stream}, or {} >= {} and {} >= {}",
|
"Continuing current chunk: single stream {single_stream}, or {} >= {} and {} >= {}",
|
||||||
gst::format::Bytes::from_u64(stream.queued_chunk_bytes),
|
gst::format::Bytes::from_u64(stream.queued_chunk_bytes),
|
||||||
settings.interleave_bytes.map(gst::format::Bytes::from_u64).display(),
|
settings.interleave_bytes.map(gst::format::Bytes::from_u64).display(),
|
||||||
|
@ -696,16 +712,25 @@ impl MP4Mux {
|
||||||
}
|
}
|
||||||
|
|
||||||
state.current_stream_idx = None;
|
state.current_stream_idx = None;
|
||||||
gst::debug!(CAT,
|
gst::debug!(
|
||||||
obj: stream.sinkpad,
|
CAT,
|
||||||
|
obj = stream.sinkpad,
|
||||||
"Switching to next chunk: {} < {} and {} < {}",
|
"Switching to next chunk: {} < {} and {} < {}",
|
||||||
gst::format::Bytes::from_u64(stream.queued_chunk_bytes),
|
gst::format::Bytes::from_u64(stream.queued_chunk_bytes),
|
||||||
settings.interleave_bytes.map(gst::format::Bytes::from_u64).display(),
|
settings
|
||||||
stream.queued_chunk_time, settings.interleave_time.display(),
|
.interleave_bytes
|
||||||
|
.map(gst::format::Bytes::from_u64)
|
||||||
|
.display(),
|
||||||
|
stream.queued_chunk_time,
|
||||||
|
settings.interleave_time.display(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Eos) => {
|
Err(gst::FlowError::Eos) => {
|
||||||
gst::debug!(CAT, obj: stream.sinkpad, "Stream is EOS, switching to next stream");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
obj = stream.sinkpad,
|
||||||
|
"Stream is EOS, switching to next stream"
|
||||||
|
);
|
||||||
state.current_stream_idx = None;
|
state.current_stream_idx = None;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
@ -734,10 +759,7 @@ impl MP4Mux {
|
||||||
|
|
||||||
let timestamp = stream.pending_buffer.as_ref().unwrap().timestamp;
|
let timestamp = stream.pending_buffer.as_ref().unwrap().timestamp;
|
||||||
|
|
||||||
gst::trace!(CAT,
|
gst::trace!(CAT, obj = stream.sinkpad, "Stream at timestamp {timestamp}",);
|
||||||
obj: stream.sinkpad,
|
|
||||||
"Stream at timestamp {timestamp}",
|
|
||||||
);
|
|
||||||
|
|
||||||
all_eos = false;
|
all_eos = false;
|
||||||
|
|
||||||
|
@ -765,21 +787,21 @@ impl MP4Mux {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !all_have_data_or_eos {
|
if !all_have_data_or_eos {
|
||||||
gst::trace!(CAT, imp: self, "Not all streams have a buffer or are EOS");
|
gst::trace!(CAT, imp = self, "Not all streams have a buffer or are EOS");
|
||||||
Err(gst_base::AGGREGATOR_FLOW_NEED_DATA)
|
Err(gst_base::AGGREGATOR_FLOW_NEED_DATA)
|
||||||
} else if all_eos {
|
} else if all_eos {
|
||||||
gst::info!(CAT, imp: self, "All streams are EOS");
|
gst::info!(CAT, imp = self, "All streams are EOS");
|
||||||
Err(gst::FlowError::Eos)
|
Err(gst::FlowError::Eos)
|
||||||
} else if let Some((idx, stream, earliest_timestamp)) = earliest_stream {
|
} else if let Some((idx, stream, earliest_timestamp)) = earliest_stream {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: stream.sinkpad,
|
obj = stream.sinkpad,
|
||||||
"Stream is earliest stream with timestamp {earliest_timestamp}",
|
"Stream is earliest stream with timestamp {earliest_timestamp}",
|
||||||
);
|
);
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: stream.sinkpad,
|
obj = stream.sinkpad,
|
||||||
"Starting new chunk at offset {}",
|
"Starting new chunk at offset {}",
|
||||||
state.current_offset,
|
state.current_offset,
|
||||||
);
|
);
|
||||||
|
@ -813,7 +835,7 @@ impl MP4Mux {
|
||||||
&& buffer.buffer.flags().contains(gst::BufferFlags::DROPPABLE)
|
&& buffer.buffer.flags().contains(gst::BufferFlags::DROPPABLE)
|
||||||
&& buffer.buffer.size() == 0
|
&& buffer.buffer.size() == 0
|
||||||
{
|
{
|
||||||
gst::trace!(CAT, obj: stream.sinkpad, "Skipping gap buffer {buffer:?}");
|
gst::trace!(CAT, obj = stream.sinkpad, "Skipping gap buffer {buffer:?}");
|
||||||
|
|
||||||
// If a new chunk was just started for the gap buffer, don't bother and get rid
|
// If a new chunk was just started for the gap buffer, don't bother and get rid
|
||||||
// of this chunk again for now and search for the next stream.
|
// of this chunk again for now and search for the next stream.
|
||||||
|
@ -831,10 +853,19 @@ impl MP4Mux {
|
||||||
if let Some(previous_sample) =
|
if let Some(previous_sample) =
|
||||||
stream.chunks.last_mut().and_then(|c| c.samples.last_mut())
|
stream.chunks.last_mut().and_then(|c| c.samples.last_mut())
|
||||||
{
|
{
|
||||||
gst::trace!(CAT, obj: stream.sinkpad, "Adding gap duration {} to previous sample", buffer.duration.unwrap());
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
obj = stream.sinkpad,
|
||||||
|
"Adding gap duration {} to previous sample",
|
||||||
|
buffer.duration.unwrap()
|
||||||
|
);
|
||||||
previous_sample.duration += buffer.duration.unwrap();
|
previous_sample.duration += buffer.duration.unwrap();
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, obj: stream.sinkpad, "Resetting stream start time because it started with a gap");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
obj = stream.sinkpad,
|
||||||
|
"Resetting stream start time because it started with a gap"
|
||||||
|
);
|
||||||
// If there was no previous sample yet then the next sample needs to start
|
// If there was no previous sample yet then the next sample needs to start
|
||||||
// earlier or alternatively we change the start PTS. We do the latter here
|
// earlier or alternatively we change the start PTS. We do the latter here
|
||||||
// as otherwise the first sample would be displayed too early.
|
// as otherwise the first sample would be displayed too early.
|
||||||
|
@ -846,7 +877,12 @@ impl MP4Mux {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, obj: stream.sinkpad, "Handling buffer {buffer:?} at offset {}", state.current_offset);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
obj = stream.sinkpad,
|
||||||
|
"Handling buffer {buffer:?} at offset {}",
|
||||||
|
state.current_offset
|
||||||
|
);
|
||||||
|
|
||||||
let duration = buffer.duration.unwrap();
|
let duration = buffer.duration.unwrap();
|
||||||
let composition_time_offset = buffer.composition_time_offset;
|
let composition_time_offset = buffer.composition_time_offset;
|
||||||
|
@ -884,7 +920,7 @@ impl MP4Mux {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_streams(&self, state: &mut State) -> Result<(), gst::FlowError> {
|
fn create_streams(&self, state: &mut State) -> Result<(), gst::FlowError> {
|
||||||
gst::info!(CAT, imp: self, "Creating streams");
|
gst::info!(CAT, imp = self, "Creating streams");
|
||||||
|
|
||||||
for pad in self
|
for pad in self
|
||||||
.obj()
|
.obj()
|
||||||
|
@ -895,12 +931,12 @@ impl MP4Mux {
|
||||||
let caps = match pad.current_caps() {
|
let caps = match pad.current_caps() {
|
||||||
Some(caps) => caps,
|
Some(caps) => caps,
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(CAT, obj: pad, "Skipping pad without caps");
|
gst::warning!(CAT, obj = pad, "Skipping pad without caps");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::info!(CAT, obj: pad, "Configuring caps {caps:?}");
|
gst::info!(CAT, obj = pad, "Configuring caps {caps:?}");
|
||||||
|
|
||||||
let s = caps.structure(0).unwrap();
|
let s = caps.structure(0).unwrap();
|
||||||
|
|
||||||
|
@ -909,7 +945,7 @@ impl MP4Mux {
|
||||||
match s.name().as_str() {
|
match s.name().as_str() {
|
||||||
"video/x-h264" | "video/x-h265" => {
|
"video/x-h264" | "video/x-h265" => {
|
||||||
if !s.has_field_with_type("codec_data", gst::Buffer::static_type()) {
|
if !s.has_field_with_type("codec_data", gst::Buffer::static_type()) {
|
||||||
gst::error!(CAT, obj: pad, "Received caps without codec_data");
|
gst::error!(CAT, obj = pad, "Received caps without codec_data");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
delta_frames = super::DeltaFrames::Bidirectional;
|
delta_frames = super::DeltaFrames::Bidirectional;
|
||||||
|
@ -919,7 +955,7 @@ impl MP4Mux {
|
||||||
}
|
}
|
||||||
"video/x-vp9" => {
|
"video/x-vp9" => {
|
||||||
if !s.has_field_with_type("colorimetry", str::static_type()) {
|
if !s.has_field_with_type("colorimetry", str::static_type()) {
|
||||||
gst::error!(CAT, obj: pad, "Received caps without colorimetry");
|
gst::error!(CAT, obj = pad, "Received caps without colorimetry");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
delta_frames = super::DeltaFrames::PredictiveOnly;
|
delta_frames = super::DeltaFrames::PredictiveOnly;
|
||||||
|
@ -930,7 +966,7 @@ impl MP4Mux {
|
||||||
"image/jpeg" => (),
|
"image/jpeg" => (),
|
||||||
"audio/mpeg" => {
|
"audio/mpeg" => {
|
||||||
if !s.has_field_with_type("codec_data", gst::Buffer::static_type()) {
|
if !s.has_field_with_type("codec_data", gst::Buffer::static_type()) {
|
||||||
gst::error!(CAT, obj: pad, "Received caps without codec_data");
|
gst::error!(CAT, obj = pad, "Received caps without codec_data");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -941,18 +977,23 @@ impl MP4Mux {
|
||||||
.and_then(|a| a.first().and_then(|v| v.get::<gst::Buffer>().ok()))
|
.and_then(|a| a.first().and_then(|v| v.get::<gst::Buffer>().ok()))
|
||||||
{
|
{
|
||||||
if gst_pbutils::codec_utils_opus_parse_header(&header, None).is_err() {
|
if gst_pbutils::codec_utils_opus_parse_header(&header, None).is_err() {
|
||||||
gst::error!(CAT, obj: pad, "Received invalid Opus header");
|
gst::error!(CAT, obj = pad, "Received invalid Opus header");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
} else if gst_pbutils::codec_utils_opus_parse_caps(&caps, None).is_err() {
|
} else if gst_pbutils::codec_utils_opus_parse_caps(&caps, None).is_err() {
|
||||||
gst::error!(CAT, obj: pad, "Received invalid Opus caps");
|
gst::error!(CAT, obj = pad, "Received invalid Opus caps");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"audio/x-flac" => {
|
"audio/x-flac" => {
|
||||||
discard_header_buffers = true;
|
discard_header_buffers = true;
|
||||||
if let Err(e) = s.get::<gst::ArrayRef>("streamheader") {
|
if let Err(e) = s.get::<gst::ArrayRef>("streamheader") {
|
||||||
gst::error!(CAT, obj: pad, "Muxing FLAC into MP4 needs streamheader: {}", e);
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
obj = pad,
|
||||||
|
"Muxing FLAC into MP4 needs streamheader: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -981,7 +1022,7 @@ impl MP4Mux {
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.streams.is_empty() {
|
if state.streams.is_empty() {
|
||||||
gst::error!(CAT, imp: self, "No streams available");
|
gst::error!(CAT, imp = self, "No streams available");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1116,7 +1157,7 @@ impl ElementImpl for MP4Mux {
|
||||||
if !state.streams.is_empty() {
|
if !state.streams.is_empty() {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Can't request new pads after stream was started"
|
"Can't request new pads after stream was started"
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
|
@ -1138,7 +1179,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
|
|
||||||
gst::trace!(CAT, obj: aggregator_pad, "Handling query {query:?}");
|
gst::trace!(CAT, obj = aggregator_pad, "Handling query {query:?}");
|
||||||
|
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
QueryViewMut::Caps(q) => {
|
QueryViewMut::Caps(q) => {
|
||||||
|
@ -1172,14 +1213,14 @@ impl AggregatorImpl for MP4Mux {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::trace!(CAT, obj: aggregator_pad, "Handling event {event:?}");
|
gst::trace!(CAT, obj = aggregator_pad, "Handling event {event:?}");
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Segment(ev) => {
|
EventView::Segment(ev) => {
|
||||||
if ev.segment().format() != gst::Format::Time {
|
if ev.segment().format() != gst::Format::Time {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: aggregator_pad,
|
obj = aggregator_pad,
|
||||||
"Received non-TIME segment, replacing with default TIME segment"
|
"Received non-TIME segment, replacing with default TIME segment"
|
||||||
);
|
);
|
||||||
let segment = gst::FormattedSegment::<gst::ClockTime>::new();
|
let segment = gst::FormattedSegment::<gst::ClockTime>::new();
|
||||||
|
@ -1192,7 +1233,12 @@ impl AggregatorImpl for MP4Mux {
|
||||||
EventView::Tag(ev) => {
|
EventView::Tag(ev) => {
|
||||||
if let Some(tag_value) = ev.tag().get::<gst::tags::LanguageCode>() {
|
if let Some(tag_value) = ev.tag().get::<gst::tags::LanguageCode>() {
|
||||||
let lang = tag_value.get();
|
let lang = tag_value.get();
|
||||||
gst::trace!(CAT, imp: self, "Received language code from tags: {:?}", lang);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Received language code from tags: {:?}",
|
||||||
|
lang
|
||||||
|
);
|
||||||
|
|
||||||
// Language as ISO-639-2/T
|
// Language as ISO-639-2/T
|
||||||
if lang.len() == 3 && lang.chars().all(|c| c.is_ascii_lowercase()) {
|
if lang.len() == 3 && lang.chars().all(|c| c.is_ascii_lowercase()) {
|
||||||
|
@ -1215,7 +1261,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
fn sink_event(&self, aggregator_pad: &gst_base::AggregatorPad, event: gst::Event) -> bool {
|
fn sink_event(&self, aggregator_pad: &gst_base::AggregatorPad, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::trace!(CAT, obj: aggregator_pad, "Handling event {event:?}");
|
gst::trace!(CAT, obj = aggregator_pad, "Handling event {event:?}");
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Tag(_ev) => {
|
EventView::Tag(_ev) => {
|
||||||
|
@ -1230,7 +1276,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
fn src_query(&self, query: &mut gst::QueryRef) -> bool {
|
fn src_query(&self, query: &mut gst::QueryRef) -> bool {
|
||||||
use gst::QueryViewMut;
|
use gst::QueryViewMut;
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Handling query {query:?}");
|
gst::trace!(CAT, imp = self, "Handling query {query:?}");
|
||||||
|
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
QueryViewMut::Seeking(q) => {
|
QueryViewMut::Seeking(q) => {
|
||||||
|
@ -1245,7 +1291,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
fn src_event(&self, event: gst::Event) -> bool {
|
fn src_event(&self, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Handling event {event:?}");
|
gst::trace!(CAT, imp = self, "Handling event {event:?}");
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Seek(_ev) => false,
|
EventView::Seek(_ev) => false,
|
||||||
|
@ -1254,7 +1300,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
|
fn flush(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::info!(CAT, imp: self, "Flushing");
|
gst::info!(CAT, imp = self, "Flushing");
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
for stream in &mut state.streams {
|
for stream in &mut state.streams {
|
||||||
|
@ -1268,7 +1314,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::trace!(CAT, imp: self, "Stopping");
|
gst::trace!(CAT, imp = self, "Stopping");
|
||||||
|
|
||||||
let _ = self.parent_stop();
|
let _ = self.parent_stop();
|
||||||
|
|
||||||
|
@ -1278,7 +1324,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::trace!(CAT, imp: self, "Starting");
|
gst::trace!(CAT, imp = self, "Starting");
|
||||||
|
|
||||||
self.parent_start()?;
|
self.parent_start()?;
|
||||||
|
|
||||||
|
@ -1319,7 +1365,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Can't query downstream, have to assume downstream is seekable
|
// Can't query downstream, have to assume downstream is seekable
|
||||||
gst::warning!(CAT, imp: self, "Can't query downstream for seekability");
|
gst::warning!(CAT, imp = self, "Can't query downstream for seekability");
|
||||||
}
|
}
|
||||||
|
|
||||||
state = self.state.lock().unwrap();
|
state = self.state.lock().unwrap();
|
||||||
|
@ -1334,7 +1380,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Creating ftyp box at offset {}",
|
"Creating ftyp box at offset {}",
|
||||||
state.current_offset
|
state.current_offset
|
||||||
);
|
);
|
||||||
|
@ -1350,7 +1396,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
)
|
)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to create ftyp box: {err}");
|
gst::error!(CAT, imp = self, "Failed to create ftyp box: {err}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
state.current_offset += ftyp.size() as u64;
|
state.current_offset += ftyp.size() as u64;
|
||||||
|
@ -1358,13 +1404,13 @@ impl AggregatorImpl for MP4Mux {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Creating mdat box header at offset {}",
|
"Creating mdat box header at offset {}",
|
||||||
state.current_offset
|
state.current_offset
|
||||||
);
|
);
|
||||||
state.mdat_offset = Some(state.current_offset);
|
state.mdat_offset = Some(state.current_offset);
|
||||||
let mdat = boxes::create_mdat_header(None).map_err(|err| {
|
let mdat = boxes::create_mdat_header(None).map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to create mdat box header: {err}");
|
gst::error!(CAT, imp = self, "Failed to create mdat box header: {err}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
state.current_offset += mdat.size() as u64;
|
state.current_offset += mdat.size() as u64;
|
||||||
|
@ -1385,7 +1431,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Creating moov box now, mdat ends at offset {} with size {}",
|
"Creating moov box now, mdat ends at offset {} with size {}",
|
||||||
state.current_offset,
|
state.current_offset,
|
||||||
state.mdat_size
|
state.mdat_size
|
||||||
|
@ -1419,7 +1465,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
language_code: state.language_code,
|
language_code: state.language_code,
|
||||||
})
|
})
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to create moov box: {err}");
|
gst::error!(CAT, imp = self, "Failed to create moov box: {err}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
state.current_offset += moov.size() as u64;
|
state.current_offset += moov.size() as u64;
|
||||||
|
@ -1434,7 +1480,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
|
|
||||||
if !buffers.is_empty() {
|
if !buffers.is_empty() {
|
||||||
if let Err(err) = self.obj().finish_buffer_list(buffers) {
|
if let Err(err) = self.obj().finish_buffer_list(buffers) {
|
||||||
gst::error!(CAT, imp: self, "Failed pushing buffers: {err:?}");
|
gst::error!(CAT, imp = self, "Failed pushing buffers: {err:?}");
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1445,7 +1491,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
if let Some(mdat_offset) = state.mdat_offset {
|
if let Some(mdat_offset) = state.mdat_offset {
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Rewriting mdat box header at offset {mdat_offset} with size {} now",
|
"Rewriting mdat box header at offset {mdat_offset} with size {} now",
|
||||||
state.mdat_size,
|
state.mdat_size,
|
||||||
);
|
);
|
||||||
|
@ -1453,7 +1499,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
segment.set_start(gst::format::Bytes::from_u64(mdat_offset));
|
segment.set_start(gst::format::Bytes::from_u64(mdat_offset));
|
||||||
state.current_offset = mdat_offset;
|
state.current_offset = mdat_offset;
|
||||||
let mdat = boxes::create_mdat_header(Some(state.mdat_size)).map_err(|err| {
|
let mdat = boxes::create_mdat_header(Some(state.mdat_size)).map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to create mdat box header: {err}");
|
gst::error!(CAT, imp = self, "Failed to create mdat box header: {err}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
drop(state);
|
drop(state);
|
||||||
|
@ -1462,7 +1508,7 @@ impl AggregatorImpl for MP4Mux {
|
||||||
if let Err(err) = self.obj().finish_buffer(mdat) {
|
if let Err(err) = self.obj().finish_buffer(mdat) {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed pushing updated mdat box header buffer downstream: {err:?}",
|
"Failed pushing updated mdat box header buffer downstream: {err:?}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1788,7 +1834,7 @@ impl AggregatorPadImpl for MP4MuxPad {
|
||||||
let mux = aggregator.downcast_ref::<super::MP4Mux>().unwrap();
|
let mux = aggregator.downcast_ref::<super::MP4Mux>().unwrap();
|
||||||
let mut mux_state = mux.imp().state.lock().unwrap();
|
let mut mux_state = mux.imp().state.lock().unwrap();
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Flushing");
|
gst::info!(CAT, imp = self, "Flushing");
|
||||||
|
|
||||||
for stream in &mut mux_state.streams {
|
for stream in &mut mux_state.streams {
|
||||||
if stream.sinkpad == *self.obj() {
|
if stream.sinkpad == *self.obj() {
|
||||||
|
|
|
@ -237,10 +237,10 @@ impl S3HlsSink {
|
||||||
match rxc.try_recv() {
|
match rxc.try_recv() {
|
||||||
Ok(S3RequestControl::Continue) => (),
|
Ok(S3RequestControl::Continue) => (),
|
||||||
Ok(S3RequestControl::Pause) => {
|
Ok(S3RequestControl::Pause) => {
|
||||||
gst::debug!(CAT, imp: self, "Pausing S3 request thread.");
|
gst::debug!(CAT, imp = self, "Pausing S3 request thread.");
|
||||||
match rxc.recv() {
|
match rxc.recv() {
|
||||||
Ok(S3RequestControl::Continue) => {
|
Ok(S3RequestControl::Continue) => {
|
||||||
gst::debug!(CAT, imp: self, "Continuing S3 request thread.")
|
gst::debug!(CAT, imp = self, "Continuing S3 request thread.")
|
||||||
}
|
}
|
||||||
// We do not expect another pause request here.
|
// We do not expect another pause request here.
|
||||||
Ok(S3RequestControl::Pause) => unreachable!(),
|
Ok(S3RequestControl::Pause) => unreachable!(),
|
||||||
|
@ -262,7 +262,7 @@ impl S3HlsSink {
|
||||||
let s3_acl = data.s3_acl;
|
let s3_acl = data.s3_acl;
|
||||||
let s3_data_len = data.s3_data.len();
|
let s3_data_len = data.s3_data.len();
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Uploading key {}", s3_key);
|
gst::debug!(CAT, imp = self, "Uploading key {}", s3_key);
|
||||||
|
|
||||||
let put_object_req = s3_client
|
let put_object_req = s3_client
|
||||||
.put_object()
|
.put_object()
|
||||||
|
@ -277,7 +277,7 @@ impl S3HlsSink {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Put object request for S3 key {} of data length {} failed with error {err}",
|
"Put object request for S3 key {} of data length {} failed with error {err}",
|
||||||
s3_key,
|
s3_key,
|
||||||
s3_data_len,
|
s3_data_len,
|
||||||
|
@ -308,7 +308,7 @@ impl S3HlsSink {
|
||||||
let s3_bucket = data.s3_bucket.clone();
|
let s3_bucket = data.s3_bucket.clone();
|
||||||
let s3_key = data.s3_key.clone();
|
let s3_key = data.s3_key.clone();
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Deleting key {}", s3_key);
|
gst::debug!(CAT, imp = self, "Deleting key {}", s3_key);
|
||||||
|
|
||||||
let delete_object_req = s3_client
|
let delete_object_req = s3_client
|
||||||
.delete_object()
|
.delete_object()
|
||||||
|
@ -320,7 +320,7 @@ impl S3HlsSink {
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Delete object request for S3 key {} failed with error {err}",
|
"Delete object request for S3 key {} failed with error {err}",
|
||||||
s3_key,
|
s3_key,
|
||||||
);
|
);
|
||||||
|
@ -334,14 +334,14 @@ impl S3HlsSink {
|
||||||
}
|
}
|
||||||
Ok(S3Request::Stop) => break,
|
Ok(S3Request::Stop) => break,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "S3 channel error: {}", err);
|
gst::error!(CAT, imp = self, "S3 channel error: {}", err);
|
||||||
element_imp_error!(self, gst::ResourceError::Write, ["S3 channel error"]);
|
element_imp_error!(self, gst::ResourceError::Write, ["S3 channel error"]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Exiting S3 request thread",);
|
gst::info!(CAT, imp = self, "Exiting S3 request thread",);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn s3client_from_settings(&self) -> Client {
|
fn s3client_from_settings(&self) -> Client {
|
||||||
|
@ -397,17 +397,22 @@ impl S3HlsSink {
|
||||||
let s3_tx = settings.s3_tx.clone();
|
let s3_tx = settings.s3_tx.clone();
|
||||||
|
|
||||||
if let (Some(handle), Some(tx)) = (s3_handle, s3_tx) {
|
if let (Some(handle), Some(tx)) = (s3_handle, s3_tx) {
|
||||||
gst::info!(CAT, imp: self, "Stopping S3 request thread");
|
gst::info!(CAT, imp = self, "Stopping S3 request thread");
|
||||||
match tx.send(S3Request::Stop) {
|
match tx.send(S3Request::Stop) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
gst::info!(CAT, imp: self, "Joining S3 request thread");
|
gst::info!(CAT, imp = self, "Joining S3 request thread");
|
||||||
if let Err(err) = handle.join() {
|
if let Err(err) = handle.join() {
|
||||||
gst::error!(CAT, imp: self, "S3 upload thread failed to exit: {:?}", err);
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"S3 upload thread failed to exit: {:?}",
|
||||||
|
err
|
||||||
|
);
|
||||||
}
|
}
|
||||||
drop(tx);
|
drop(tx);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to stop S3 request thread: {}", err)
|
gst::error!(CAT, imp = self, "Failed to stop S3 request thread: {}", err)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -552,7 +557,7 @@ impl ObjectImpl for S3HlsSink {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Setting property '{}' to '{:?}'",
|
"Setting property '{}' to '{:?}'",
|
||||||
pspec.name(),
|
pspec.name(),
|
||||||
value
|
value
|
||||||
|
@ -651,7 +656,7 @@ impl ObjectImpl for S3HlsSink {
|
||||||
settings.s3_txc = Some(txc);
|
settings.s3_txc = Some(txc);
|
||||||
drop(settings);
|
drop(settings);
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Constructed");
|
gst::info!(CAT, imp = self, "Constructed");
|
||||||
|
|
||||||
self.hlssink.connect("get-playlist-stream", false, {
|
self.hlssink.connect("get-playlist-stream", false, {
|
||||||
let self_weak = self.downgrade();
|
let self_weak = self.downgrade();
|
||||||
|
@ -674,7 +679,7 @@ impl ObjectImpl for S3HlsSink {
|
||||||
playlist_tx.clone(),
|
playlist_tx.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self_, "New upload for {}", s3_location);
|
gst::debug!(CAT, imp = self_, "New upload for {}", s3_location);
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
gio::WriteOutputStream::new(upload)
|
gio::WriteOutputStream::new(upload)
|
||||||
|
@ -705,7 +710,7 @@ impl ObjectImpl for S3HlsSink {
|
||||||
fragment_tx.clone(),
|
fragment_tx.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self_, "New upload for {}", s3_location);
|
gst::debug!(CAT, imp = self_, "New upload for {}", s3_location);
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
gio::WriteOutputStream::new(upload)
|
gio::WriteOutputStream::new(upload)
|
||||||
|
@ -732,7 +737,7 @@ impl ObjectImpl for S3HlsSink {
|
||||||
s3_location.to_string()
|
s3_location.to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self_, "Deleting {}", s3_location);
|
gst::debug!(CAT, imp = self_, "Deleting {}", s3_location);
|
||||||
|
|
||||||
let delete = S3DeleteReq {
|
let delete = S3DeleteReq {
|
||||||
s3_client,
|
s3_client,
|
||||||
|
@ -752,7 +757,7 @@ impl ObjectImpl for S3HlsSink {
|
||||||
if res.is_ok() {
|
if res.is_ok() {
|
||||||
Some(true.to_value())
|
Some(true.to_value())
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self_, "Failed deleting {}", s3_location);
|
gst::error!(CAT, imp = self_, "Failed deleting {}", s3_location);
|
||||||
element_imp_error!(
|
element_imp_error!(
|
||||||
self_,
|
self_,
|
||||||
gst::ResourceError::Write,
|
gst::ResourceError::Write,
|
||||||
|
@ -839,11 +844,11 @@ impl ElementImpl for S3HlsSink {
|
||||||
if let Some(tx) = s3_txc {
|
if let Some(tx) = s3_txc {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Sending continue request to S3 request thread."
|
"Sending continue request to S3 request thread."
|
||||||
);
|
);
|
||||||
if tx.send(S3RequestControl::Continue).is_err() {
|
if tx.send(S3RequestControl::Continue).is_err() {
|
||||||
gst::error!(CAT, imp: self, "Could not send continue request.");
|
gst::error!(CAT, imp = self, "Could not send continue request.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -853,13 +858,13 @@ impl ElementImpl for S3HlsSink {
|
||||||
if let Some(tx) = s3_txc {
|
if let Some(tx) = s3_txc {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Sending pause request to S3 request thread."
|
"Sending pause request to S3 request thread."
|
||||||
);
|
);
|
||||||
if settings.s3_upload_handle.is_some()
|
if settings.s3_upload_handle.is_some()
|
||||||
&& tx.send(S3RequestControl::Pause).is_err()
|
&& tx.send(S3RequestControl::Pause).is_err()
|
||||||
{
|
{
|
||||||
gst::error!(CAT, imp: self, "Could not send pause request.");
|
gst::error!(CAT, imp = self, "Could not send pause request.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -890,7 +895,7 @@ impl ElementImpl for S3HlsSink {
|
||||||
if settings.audio_sink {
|
if settings.audio_sink {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"requested_new_pad: audio pad is already set"
|
"requested_new_pad: audio pad is already set"
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
|
@ -908,7 +913,7 @@ impl ElementImpl for S3HlsSink {
|
||||||
if settings.video_sink {
|
if settings.video_sink {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"requested_new_pad: video pad is already set"
|
"requested_new_pad: video pad is already set"
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
|
@ -923,7 +928,7 @@ impl ElementImpl for S3HlsSink {
|
||||||
Some(sink_pad.upcast())
|
Some(sink_pad.upcast())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::debug!(CAT, imp: self, "requested_new_pad is not audio or video");
|
gst::debug!(CAT, imp = self, "requested_new_pad is not audio or video");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -945,7 +950,7 @@ impl BinImpl for S3HlsSink {
|
||||||
* unblock the S3 request thread from waiting for a Continue request
|
* unblock the S3 request thread from waiting for a Continue request
|
||||||
* on the control channel.
|
* on the control channel.
|
||||||
*/
|
*/
|
||||||
gst::debug!(CAT, imp: self, "Got EOS, dropping control channel");
|
gst::debug!(CAT, imp = self, "Got EOS, dropping control channel");
|
||||||
drop(txc);
|
drop(txc);
|
||||||
}
|
}
|
||||||
drop(settings);
|
drop(settings);
|
||||||
|
|
|
@ -136,12 +136,12 @@ impl Settings {
|
||||||
|
|
||||||
for (key, value) in structure.iter() {
|
for (key, value) in structure.iter() {
|
||||||
if let Ok(Ok(value_str)) = value.transform::<String>().map(|v| v.get()) {
|
if let Ok(Ok(value_str)) = value.transform::<String>().map(|v| v.get()) {
|
||||||
gst::log!(CAT, imp: imp, "metadata '{}' -> '{}'", key, value_str);
|
gst::log!(CAT, imp = imp, "metadata '{}' -> '{}'", key, value_str);
|
||||||
hash.insert(key.to_string(), value_str);
|
hash.insert(key.to_string(), value_str);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Failed to convert metadata '{}' to string ('{:?}')",
|
"Failed to convert metadata '{}' to string ('{:?}')",
|
||||||
key,
|
key,
|
||||||
value
|
value
|
||||||
|
@ -203,7 +203,7 @@ impl S3Sink {
|
||||||
OnError::Abort => {
|
OnError::Abort => {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Aborting multipart upload request with id: {}",
|
"Aborting multipart upload request with id: {}",
|
||||||
state.upload_id
|
state.upload_id
|
||||||
);
|
);
|
||||||
|
@ -211,13 +211,13 @@ impl S3Sink {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Aborting multipart upload request succeeded."
|
"Aborting multipart upload request succeeded."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(err) => gst::error!(
|
Err(err) => gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Aborting multipart upload failed: {}",
|
"Aborting multipart upload failed: {}",
|
||||||
err.to_string()
|
err.to_string()
|
||||||
),
|
),
|
||||||
|
@ -226,7 +226,7 @@ impl S3Sink {
|
||||||
OnError::Complete => {
|
OnError::Complete => {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Completing multipart upload request with id: {}",
|
"Completing multipart upload request with id: {}",
|
||||||
state.upload_id
|
state.upload_id
|
||||||
);
|
);
|
||||||
|
@ -234,13 +234,13 @@ impl S3Sink {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Complete multipart upload request succeeded."
|
"Complete multipart upload request succeeded."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(err) => gst::error!(
|
Err(err) => gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Completing multipart upload failed: {}",
|
"Completing multipart upload failed: {}",
|
||||||
err.to_string()
|
err.to_string()
|
||||||
),
|
),
|
||||||
|
@ -285,7 +285,7 @@ impl S3Sink {
|
||||||
.build();
|
.build();
|
||||||
state.completed_parts.push(completed_part);
|
state.completed_parts.push(completed_part);
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Uploaded part {}", part_number);
|
gst::info!(CAT, imp = self, "Uploaded part {}", part_number);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -633,7 +633,7 @@ impl S3Sink {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Setting uri to {:?}", url_str);
|
gst::debug!(CAT, imp = self, "Setting uri to {:?}", url_str);
|
||||||
|
|
||||||
let url_str = url_str.unwrap();
|
let url_str = url_str.unwrap();
|
||||||
match parse_s3_url(url_str) {
|
match parse_s3_url(url_str) {
|
||||||
|
@ -804,7 +804,7 @@ impl ObjectImpl for S3Sink {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Setting property '{}' to '{:?}'",
|
"Setting property '{}' to '{:?}'",
|
||||||
pspec.name(),
|
pspec.name(),
|
||||||
value
|
value
|
||||||
|
@ -1030,7 +1030,7 @@ impl BaseSinkImpl for S3Sink {
|
||||||
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
fn start(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
let res = self.start();
|
let res = self.start();
|
||||||
if let Err(ref err) = res {
|
if let Err(ref err) = res {
|
||||||
gst::error!(CAT, imp: self, "Failed to start: {err}");
|
gst::error!(CAT, imp = self, "Failed to start: {err}");
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -1040,7 +1040,7 @@ impl BaseSinkImpl for S3Sink {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
if let State::Started(ref mut state) = *state {
|
if let State::Started(ref mut state) = *state {
|
||||||
gst::warning!(CAT, imp: self, "Stopped without EOS");
|
gst::warning!(CAT, imp = self, "Stopped without EOS");
|
||||||
|
|
||||||
// We're stopping without an EOS -- treat this as an error and deal with the open
|
// We're stopping without an EOS -- treat this as an error and deal with the open
|
||||||
// multipart upload accordingly _if_ we managed to upload any parts
|
// multipart upload accordingly _if_ we managed to upload any parts
|
||||||
|
@ -1050,7 +1050,7 @@ impl BaseSinkImpl for S3Sink {
|
||||||
}
|
}
|
||||||
|
|
||||||
*state = State::Stopped;
|
*state = State::Stopped;
|
||||||
gst::info!(CAT, imp: self, "Stopped");
|
gst::info!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1070,7 +1070,7 @@ impl BaseSinkImpl for S3Sink {
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Rendering {:?}", buffer);
|
gst::trace!(CAT, imp = self, "Rendering {:?}", buffer);
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::element_imp_error!(self, gst::CoreError::Failed, ["Failed to map buffer"]);
|
gst::element_imp_error!(self, gst::CoreError::Failed, ["Failed to map buffer"]);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
|
@ -1080,12 +1080,17 @@ impl BaseSinkImpl for S3Sink {
|
||||||
Ok(_) => Ok(gst::FlowSuccess::Ok),
|
Ok(_) => Ok(gst::FlowSuccess::Ok),
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
Some(error_message) => {
|
Some(error_message) => {
|
||||||
gst::error!(CAT, imp: self, "Multipart upload failed: {}", error_message);
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Multipart upload failed: {}",
|
||||||
|
error_message
|
||||||
|
);
|
||||||
self.post_error_message(error_message);
|
self.post_error_message(error_message);
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::info!(CAT, imp: self, "Upload interrupted. Flushing...");
|
gst::info!(CAT, imp = self, "Upload interrupted. Flushing...");
|
||||||
Err(gst::FlowError::Flushing)
|
Err(gst::FlowError::Flushing)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1113,7 +1118,7 @@ impl BaseSinkImpl for S3Sink {
|
||||||
if let Err(error_message) = self.finalize_upload() {
|
if let Err(error_message) = self.finalize_upload() {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to finalize the upload: {}",
|
"Failed to finalize the upload: {}",
|
||||||
error_message
|
error_message
|
||||||
);
|
);
|
||||||
|
|
|
@ -106,12 +106,12 @@ impl Settings {
|
||||||
|
|
||||||
for (key, value) in structure.iter() {
|
for (key, value) in structure.iter() {
|
||||||
if let Ok(Ok(value_str)) = value.transform::<String>().map(|v| v.get()) {
|
if let Ok(Ok(value_str)) = value.transform::<String>().map(|v| v.get()) {
|
||||||
gst::log!(CAT, imp: imp, "metadata '{}' -> '{}'", key, value_str);
|
gst::log!(CAT, imp = imp, "metadata '{}' -> '{}'", key, value_str);
|
||||||
hash.insert(key.to_string(), value_str);
|
hash.insert(key.to_string(), value_str);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Failed to convert metadata '{}' to string ('{:?}')",
|
"Failed to convert metadata '{}' to string ('{:?}')",
|
||||||
key,
|
key,
|
||||||
value
|
value
|
||||||
|
@ -215,7 +215,7 @@ impl S3PutObjectSink {
|
||||||
WaitError::Cancelled => None,
|
WaitError::Cancelled => None,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Upload complete");
|
gst::debug!(CAT, imp = self, "Upload complete");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -343,7 +343,7 @@ impl S3PutObjectSink {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Setting uri to {:?}", url_str);
|
gst::debug!(CAT, imp = self, "Setting uri to {:?}", url_str);
|
||||||
|
|
||||||
let url_str = url_str.unwrap();
|
let url_str = url_str.unwrap();
|
||||||
match parse_s3_url(url_str) {
|
match parse_s3_url(url_str) {
|
||||||
|
@ -484,7 +484,7 @@ impl ObjectImpl for S3PutObjectSink {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Setting property '{}' to '{:?}'",
|
"Setting property '{}' to '{:?}'",
|
||||||
pspec.name(),
|
pspec.name(),
|
||||||
value
|
value
|
||||||
|
@ -677,11 +677,11 @@ impl BaseSinkImpl for S3PutObjectSink {
|
||||||
drop(settings);
|
drop(settings);
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
gst::warning!(CAT, imp: self, "Stopped without EOS, but flushing");
|
gst::warning!(CAT, imp = self, "Stopped without EOS, but flushing");
|
||||||
if let Err(error_message) = self.flush_buffer() {
|
if let Err(error_message) = self.flush_buffer() {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to finalize the upload: {:?}",
|
"Failed to finalize the upload: {:?}",
|
||||||
error_message
|
error_message
|
||||||
);
|
);
|
||||||
|
@ -692,7 +692,7 @@ impl BaseSinkImpl for S3PutObjectSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
*state = State::Stopped;
|
*state = State::Stopped;
|
||||||
gst::info!(CAT, imp: self, "Stopped");
|
gst::info!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -715,7 +715,7 @@ impl BaseSinkImpl for S3PutObjectSink {
|
||||||
started_state.num_buffers += 1;
|
started_state.num_buffers += 1;
|
||||||
started_state.need_flush = true;
|
started_state.need_flush = true;
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Rendering {:?}", buffer);
|
gst::trace!(CAT, imp = self, "Rendering {:?}", buffer);
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::element_imp_error!(self, gst::CoreError::Failed, ["Failed to map buffer"]);
|
gst::element_imp_error!(self, gst::CoreError::Failed, ["Failed to map buffer"]);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
|
@ -733,12 +733,12 @@ impl BaseSinkImpl for S3PutObjectSink {
|
||||||
Ok(_) => Ok(gst::FlowSuccess::Ok),
|
Ok(_) => Ok(gst::FlowSuccess::Ok),
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
Some(error_message) => {
|
Some(error_message) => {
|
||||||
gst::error!(CAT, imp: self, "Upload failed: {}", error_message);
|
gst::error!(CAT, imp = self, "Upload failed: {}", error_message);
|
||||||
self.post_error_message(error_message);
|
self.post_error_message(error_message);
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::info!(CAT, imp: self, "Upload interrupted. Flushing...");
|
gst::info!(CAT, imp = self, "Upload interrupted. Flushing...");
|
||||||
Err(gst::FlowError::Flushing)
|
Err(gst::FlowError::Flushing)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -770,7 +770,7 @@ impl BaseSinkImpl for S3PutObjectSink {
|
||||||
if let Err(error_message) = self.flush_buffer() {
|
if let Err(error_message) = self.flush_buffer() {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to finalize the upload: {:?}",
|
"Failed to finalize the upload: {:?}",
|
||||||
error_message
|
error_message
|
||||||
);
|
);
|
||||||
|
|
|
@ -191,7 +191,7 @@ impl S3Src {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"HEAD success, content length = {:?}",
|
"HEAD success, content length = {:?}",
|
||||||
output.content_length
|
output.content_length
|
||||||
);
|
);
|
||||||
|
@ -226,7 +226,7 @@ impl S3Src {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Requesting range: {}-{}",
|
"Requesting range: {}-{}",
|
||||||
offset,
|
offset,
|
||||||
offset + length - 1
|
offset + length - 1
|
||||||
|
@ -243,7 +243,7 @@ impl S3Src {
|
||||||
WaitError::Cancelled => None,
|
WaitError::Cancelled => None,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Read {:?} bytes", output.content_length);
|
gst::debug!(CAT, imp = self, "Read {:?} bytes", output.content_length);
|
||||||
|
|
||||||
s3utils::wait_stream(&self.canceller, &mut output.body).map_err(|err| match err {
|
s3utils::wait_stream(&self.canceller, &mut output.body).map_err(|err| match err {
|
||||||
WaitError::FutureError(err) => Some(gst::error_msg!(
|
WaitError::FutureError(err) => Some(gst::error_msg!(
|
||||||
|
@ -562,7 +562,7 @@ impl BaseSrcImpl for S3Src {
|
||||||
Err(None) => Err(gst::FlowError::Flushing),
|
Err(None) => Err(gst::FlowError::Flushing),
|
||||||
/* Actual Error */
|
/* Actual Error */
|
||||||
Err(Some(err)) => {
|
Err(Some(err)) => {
|
||||||
gst::error!(CAT, imp: self, "Could not GET: {}", err);
|
gst::error!(CAT, imp = self, "Could not GET: {}", err);
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ impl TranscribeParse {
|
||||||
pad: &gst::Pad,
|
pad: &gst::Pad,
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(CAT, obj: pad, "Handling buffer {:?}", buffer);
|
gst::log!(CAT, obj = pad, "Handling buffer {:?}", buffer);
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ impl TranscribeParse {
|
||||||
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling event {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling event {:?}", event);
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::FlushStop(..) => {
|
EventView::FlushStop(..) => {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
@ -228,7 +228,7 @@ impl TranscribeParse {
|
||||||
EventView::Eos(..) => match self.drain() {
|
EventView::Eos(..) => match self.drain() {
|
||||||
Ok(()) => gst::Pad::event_default(pad, Some(&*self.obj()), event),
|
Ok(()) => gst::Pad::event_default(pad, Some(&*self.obj()), event),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "failed to drain on EOS: {}", err);
|
gst::error!(CAT, imp = self, "failed to drain on EOS: {}", err);
|
||||||
element_imp_error!(
|
element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -338,7 +338,7 @@ impl ElementImpl for TranscribeParse {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::ReadyToPaused | gst::StateChange::PausedToReady => {
|
gst::StateChange::ReadyToPaused | gst::StateChange::PausedToReady => {
|
||||||
|
|
|
@ -184,7 +184,7 @@ pub struct Transcriber {
|
||||||
|
|
||||||
impl Transcriber {
|
impl Transcriber {
|
||||||
fn start_srcpad_tasks(&self, state: &State) -> Result<(), gst::LoggableError> {
|
fn start_srcpad_tasks(&self, state: &State) -> Result<(), gst::LoggableError> {
|
||||||
gst::debug!(CAT, imp: self, "Starting tasks");
|
gst::debug!(CAT, imp = self, "Starting tasks");
|
||||||
|
|
||||||
if self.static_srcpad.is_linked() {
|
if self.static_srcpad.is_linked() {
|
||||||
self.static_srcpad.imp().start_task()?;
|
self.static_srcpad.imp().start_task()?;
|
||||||
|
@ -194,13 +194,13 @@ impl Transcriber {
|
||||||
pad.imp().start_task()?;
|
pad.imp().start_task()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Tasks Started");
|
gst::debug!(CAT, imp = self, "Tasks Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop_tasks(&self, state: &mut State) {
|
fn stop_tasks(&self, state: &mut State) {
|
||||||
gst::debug!(CAT, imp: self, "Stopping tasks");
|
gst::debug!(CAT, imp = self, "Stopping tasks");
|
||||||
|
|
||||||
if self.static_srcpad.is_linked() {
|
if self.static_srcpad.is_linked() {
|
||||||
self.static_srcpad.imp().stop_task();
|
self.static_srcpad.imp().stop_task();
|
||||||
|
@ -219,11 +219,11 @@ impl Transcriber {
|
||||||
|
|
||||||
state.start_time = None;
|
state.start_time = None;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Tasks Stopped");
|
gst::debug!(CAT, imp = self, "Tasks Stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling event {event:?}");
|
gst::log!(CAT, obj = pad, "Handling event {event:?}");
|
||||||
|
|
||||||
use gst::EventView::*;
|
use gst::EventView::*;
|
||||||
match event.view() {
|
match event.view() {
|
||||||
|
@ -234,20 +234,20 @@ impl Transcriber {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
FlushStart(_) => {
|
FlushStart(_) => {
|
||||||
gst::info!(CAT, imp: self, "Received flush start, disconnecting");
|
gst::info!(CAT, imp = self, "Received flush start, disconnecting");
|
||||||
let ret = gst::Pad::event_default(pad, Some(&*self.obj()), event);
|
let ret = gst::Pad::event_default(pad, Some(&*self.obj()), event);
|
||||||
self.stop_tasks(&mut self.state.lock().unwrap());
|
self.stop_tasks(&mut self.state.lock().unwrap());
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
FlushStop(_) => {
|
FlushStop(_) => {
|
||||||
gst::info!(CAT, imp: self, "Received flush stop, restarting task");
|
gst::info!(CAT, imp = self, "Received flush stop, restarting task");
|
||||||
|
|
||||||
if gst::Pad::event_default(pad, Some(&*self.obj()), event) {
|
if gst::Pad::event_default(pad, Some(&*self.obj()), event) {
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
match self.start_srcpad_tasks(&state) {
|
match self.start_srcpad_tasks(&state) {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to start srcpad tasks: {err}");
|
gst::error!(CAT, imp = self, "Failed to start srcpad tasks: {err}");
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
Ok(_) => true,
|
Ok(_) => true,
|
||||||
|
@ -290,7 +290,7 @@ impl Transcriber {
|
||||||
pad: &gst::Pad,
|
pad: &gst::Pad,
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(CAT, obj: pad, "Handling {buffer:?}");
|
gst::log!(CAT, obj = pad, "Handling {buffer:?}");
|
||||||
|
|
||||||
if buffer.pts().is_none() {
|
if buffer.pts().is_none() {
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
|
@ -322,7 +322,7 @@ impl Transcriber {
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(mut buffer_tx) = self.state.lock().unwrap().buffer_tx.take() else {
|
let Some(mut buffer_tx) = self.state.lock().unwrap().buffer_tx.take() else {
|
||||||
gst::log!(CAT, obj: pad, "Flushing");
|
gst::log!(CAT, obj = pad, "Flushing");
|
||||||
return Err(gst::FlowError::Flushing);
|
return Err(gst::FlowError::Flushing);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -474,7 +474,7 @@ impl Transcriber {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Eos) => {
|
Some(Eos) => {
|
||||||
gst::debug!(CAT, imp: imp, "Transcriber loop sending EOS");
|
gst::debug!(CAT, imp = imp, "Transcriber loop sending EOS");
|
||||||
|
|
||||||
if imp.transcript_event_tx.receiver_count() > 0 {
|
if imp.transcript_event_tx.receiver_count() > 0 {
|
||||||
let _ = imp.transcript_event_tx.send(Eos);
|
let _ = imp.transcript_event_tx.send(Eos);
|
||||||
|
@ -509,7 +509,7 @@ impl Transcriber {
|
||||||
{
|
{
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Forcing to translation (threshold {threshold}): {items_to_translate:?}"
|
"Forcing to translation (threshold {threshold}): {items_to_translate:?}"
|
||||||
);
|
);
|
||||||
let _ = imp
|
let _ = imp
|
||||||
|
@ -520,7 +520,7 @@ impl Transcriber {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: imp, "Exiting transcriber loop");
|
gst::debug!(CAT, imp = imp, "Exiting transcriber loop");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
@ -532,7 +532,7 @@ impl Transcriber {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
fn prepare(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Preparing");
|
gst::debug!(CAT, imp = self, "Preparing");
|
||||||
|
|
||||||
let (access_key, secret_access_key, session_token) = {
|
let (access_key, secret_access_key, session_token) = {
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
|
@ -543,12 +543,12 @@ impl Transcriber {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Loading aws config...");
|
gst::info!(CAT, imp = self, "Loading aws config...");
|
||||||
let _enter_guard = RUNTIME.enter();
|
let _enter_guard = RUNTIME.enter();
|
||||||
|
|
||||||
let config_loader = match (access_key, secret_access_key) {
|
let config_loader = match (access_key, secret_access_key) {
|
||||||
(Some(key), Some(secret_key)) => {
|
(Some(key), Some(secret_key)) => {
|
||||||
gst::debug!(CAT, imp: self, "Using settings credentials");
|
gst::debug!(CAT, imp = self, "Using settings credentials");
|
||||||
aws_config::defaults(AWS_BEHAVIOR_VERSION.clone()).credentials_provider(
|
aws_config::defaults(AWS_BEHAVIOR_VERSION.clone()).credentials_provider(
|
||||||
aws_transcribe::config::Credentials::new(
|
aws_transcribe::config::Credentials::new(
|
||||||
key,
|
key,
|
||||||
|
@ -560,7 +560,7 @@ impl Transcriber {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::debug!(CAT, imp: self, "Attempting to get credentials from env...");
|
gst::debug!(CAT, imp = self, "Attempting to get credentials from env...");
|
||||||
aws_config::defaults(AWS_BEHAVIOR_VERSION.clone())
|
aws_config::defaults(AWS_BEHAVIOR_VERSION.clone())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -571,17 +571,17 @@ impl Transcriber {
|
||||||
);
|
);
|
||||||
|
|
||||||
let config = futures::executor::block_on(config_loader.load());
|
let config = futures::executor::block_on(config_loader.load());
|
||||||
gst::debug!(CAT, imp: self, "Using region {}", config.region().unwrap());
|
gst::debug!(CAT, imp = self, "Using region {}", config.region().unwrap());
|
||||||
|
|
||||||
*self.aws_config.lock().unwrap() = Some(config);
|
*self.aws_config.lock().unwrap() = Some(config);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Prepared");
|
gst::debug!(CAT, imp = self, "Prepared");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disconnect(&self) {
|
fn disconnect(&self) {
|
||||||
gst::info!(CAT, imp: self, "Unpreparing");
|
gst::info!(CAT, imp = self, "Unpreparing");
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
self.stop_tasks(&mut state);
|
self.stop_tasks(&mut state);
|
||||||
|
@ -589,7 +589,7 @@ impl Transcriber {
|
||||||
for pad in state.srcpads.iter() {
|
for pad in state.srcpads.iter() {
|
||||||
pad.imp().set_discont();
|
pad.imp().set_discont();
|
||||||
}
|
}
|
||||||
gst::info!(CAT, imp: self, "Unprepared");
|
gst::info!(CAT, imp = self, "Unprepared");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_start_time_and_now(&self) -> Option<(gst::ClockTime, gst::ClockTime)> {
|
fn get_start_time_and_now(&self) -> Option<(gst::ClockTime, gst::ClockTime)> {
|
||||||
|
@ -975,7 +975,7 @@ impl ElementImpl for Transcriber {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::info!(CAT, imp: self, "Changing state {transition:?}");
|
gst::info!(CAT, imp = self, "Changing state {transition:?}");
|
||||||
|
|
||||||
if let gst::StateChange::NullToReady = transition {
|
if let gst::StateChange::NullToReady = transition {
|
||||||
self.prepare().map_err(|err| {
|
self.prepare().map_err(|err| {
|
||||||
|
@ -1131,7 +1131,7 @@ impl TranslationPadTask {
|
||||||
"total latency + lateness must be greater than {}",
|
"total latency + lateness must be greater than {}",
|
||||||
2 * GRANULARITY
|
2 * GRANULARITY
|
||||||
);
|
);
|
||||||
gst::error!(CAT, imp: pad, "{err}");
|
gst::error!(CAT, imp = pad, "{err}");
|
||||||
return Err(gst::error_msg!(gst::LibraryError::Settings, ["{err}"]));
|
return Err(gst::error_msg!(gst::LibraryError::Settings, ["{err}"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,7 +1205,7 @@ impl TranslationPadTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.dequeue().await {
|
if !self.dequeue().await {
|
||||||
gst::info!(CAT, imp: self.pad, "Failed to dequeue buffer, pausing");
|
gst::info!(CAT, imp = self.pad, "Failed to dequeue buffer, pausing");
|
||||||
let _ = self.pad.obj().pause_task();
|
let _ = self.pad.obj().pause_task();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1231,14 +1231,14 @@ impl TranslationPadTask {
|
||||||
self.output_items.extend(transcript_items.iter().map(Into::into));
|
self.output_items.extend(transcript_items.iter().map(Into::into));
|
||||||
}
|
}
|
||||||
Ok(Eos) => {
|
Ok(Eos) => {
|
||||||
gst::debug!(CAT, imp: self.pad, "Got eos");
|
gst::debug!(CAT, imp = self.pad, "Got eos");
|
||||||
self.send_eos = true;
|
self.send_eos = true;
|
||||||
}
|
}
|
||||||
Err(RecvError::Lagged(nb_msg)) => {
|
Err(RecvError::Lagged(nb_msg)) => {
|
||||||
gst::warning!(CAT, imp: self.pad, "Missed {nb_msg} transcript sets");
|
gst::warning!(CAT, imp = self.pad, "Missed {nb_msg} transcript sets");
|
||||||
}
|
}
|
||||||
Err(RecvError::Closed) => {
|
Err(RecvError::Closed) => {
|
||||||
gst::debug!(CAT, imp: self.pad, "Transcript chan terminated: setting eos");
|
gst::debug!(CAT, imp = self.pad, "Transcript chan terminated: setting eos");
|
||||||
self.send_eos = true;
|
self.send_eos = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1256,7 +1256,7 @@ impl TranslationPadTask {
|
||||||
.map_or(true, task::JoinHandle::is_finished)
|
.map_or(true, task::JoinHandle::is_finished)
|
||||||
{
|
{
|
||||||
const ERR: &str = "Translate loop is not running";
|
const ERR: &str = "Translate loop is not running";
|
||||||
gst::error!(CAT, imp: self.pad, "{ERR}");
|
gst::error!(CAT, imp = self.pad, "{ERR}");
|
||||||
return Err(gst::error_msg!(gst::StreamError::Failed, ["{ERR}"]));
|
return Err(gst::error_msg!(gst::StreamError::Failed, ["{ERR}"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1277,16 +1277,16 @@ impl TranslationPadTask {
|
||||||
match items_res {
|
match items_res {
|
||||||
Ok(Items(items_to_translate)) => Some(items_to_translate),
|
Ok(Items(items_to_translate)) => Some(items_to_translate),
|
||||||
Ok(Eos) => {
|
Ok(Eos) => {
|
||||||
gst::debug!(CAT, imp: self.pad, "Got eos");
|
gst::debug!(CAT, imp = self.pad, "Got eos");
|
||||||
self.send_eos = true;
|
self.send_eos = true;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Err(RecvError::Lagged(nb_msg)) => {
|
Err(RecvError::Lagged(nb_msg)) => {
|
||||||
gst::warning!(CAT, imp: self.pad, "Missed {nb_msg} transcript sets");
|
gst::warning!(CAT, imp = self.pad, "Missed {nb_msg} transcript sets");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Err(RecvError::Closed) => {
|
Err(RecvError::Closed) => {
|
||||||
gst::debug!(CAT, imp: self.pad, "Transcript chan terminated: setting eos");
|
gst::debug!(CAT, imp = self.pad, "Transcript chan terminated: setting eos");
|
||||||
self.send_eos = true;
|
self.send_eos = true;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -1307,7 +1307,7 @@ impl TranslationPadTask {
|
||||||
|
|
||||||
if res.is_err() {
|
if res.is_err() {
|
||||||
const ERR: &str = "to_translation chan terminated";
|
const ERR: &str = "to_translation chan terminated";
|
||||||
gst::debug!(CAT, imp: self.pad, "{ERR}");
|
gst::debug!(CAT, imp = self.pad, "{ERR}");
|
||||||
return Err(gst::error_msg!(gst::StreamError::Failed, ["{ERR}"]));
|
return Err(gst::error_msg!(gst::StreamError::Failed, ["{ERR}"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1324,7 +1324,7 @@ impl TranslationPadTask {
|
||||||
while let Ok(translated_items) = from_translate_rx.try_next() {
|
while let Ok(translated_items) = from_translate_rx.try_next() {
|
||||||
let Some(translated_items) = translated_items else {
|
let Some(translated_items) = translated_items else {
|
||||||
const ERR: &str = "translation chan terminated";
|
const ERR: &str = "translation chan terminated";
|
||||||
gst::debug!(CAT, imp: self.pad, "{ERR}");
|
gst::debug!(CAT, imp = self.pad, "{ERR}");
|
||||||
return Err(gst::error_msg!(gst::StreamError::Failed, ["{ERR}"]));
|
return Err(gst::error_msg!(gst::StreamError::Failed, ["{ERR}"]));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1360,7 +1360,7 @@ impl TranslationPadTask {
|
||||||
// Note: items pts start from 0 + lateness
|
// Note: items pts start from 0 + lateness
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self.pad,
|
imp = self.pad,
|
||||||
"Checking now {now} if item is ready for dequeuing, PTS {}, threshold {} vs {}",
|
"Checking now {now} if item is ready for dequeuing, PTS {}, threshold {} vs {}",
|
||||||
item.pts,
|
item.pts,
|
||||||
item.pts + self.our_latency.saturating_sub(3 * GRANULARITY),
|
item.pts + self.our_latency.saturating_sub(3 * GRANULARITY),
|
||||||
|
@ -1402,7 +1402,11 @@ impl TranslationPadTask {
|
||||||
.duration(pts - last_position)
|
.duration(pts - last_position)
|
||||||
.seqnum(self.seqnum)
|
.seqnum(self.seqnum)
|
||||||
.build();
|
.build();
|
||||||
gst::log!(CAT, imp: self.pad, "Pushing gap: {last_position} -> {pts}");
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self.pad,
|
||||||
|
"Pushing gap: {last_position} -> {pts}"
|
||||||
|
);
|
||||||
if !self.pad.obj().push_event(gap_event) {
|
if !self.pad.obj().push_event(gap_event) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1415,7 +1419,7 @@ impl TranslationPadTask {
|
||||||
|
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self.pad,
|
imp = self.pad,
|
||||||
"Updating item PTS ({pts} < {last_position}), consider increasing latency",
|
"Updating item PTS ({pts} < {last_position}), consider increasing latency",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1435,7 +1439,12 @@ impl TranslationPadTask {
|
||||||
|
|
||||||
last_position = pts + duration;
|
last_position = pts + duration;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self.pad, "Pushing buffer with content {content}: {pts} -> {}", pts + duration);
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self.pad,
|
||||||
|
"Pushing buffer with content {content}: {pts} -> {}",
|
||||||
|
pts + duration
|
||||||
|
);
|
||||||
|
|
||||||
if self.pad.obj().push(buf).is_err() {
|
if self.pad.obj().push(buf).is_err() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1450,7 +1459,7 @@ impl TranslationPadTask {
|
||||||
/* We're EOS, we can pause and exit early */
|
/* We're EOS, we can pause and exit early */
|
||||||
let _ = self.pad.obj().pause_task();
|
let _ = self.pad.obj().pause_task();
|
||||||
|
|
||||||
gst::info!(CAT, imp: self.pad, "Sending eos");
|
gst::info!(CAT, imp = self.pad, "Sending eos");
|
||||||
return self
|
return self
|
||||||
.pad
|
.pad
|
||||||
.obj()
|
.obj()
|
||||||
|
@ -1460,7 +1469,7 @@ impl TranslationPadTask {
|
||||||
/* next, push a gap if we're lagging behind the target position */
|
/* next, push a gap if we're lagging behind the target position */
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self.pad,
|
imp = self.pad,
|
||||||
"Checking now: {now} if we need to push a gap, last_position: {last_position}, threshold: {}",
|
"Checking now: {now} if we need to push a gap, last_position: {last_position}, threshold: {}",
|
||||||
last_position + self.our_latency.saturating_sub(GRANULARITY)
|
last_position + self.our_latency.saturating_sub(GRANULARITY)
|
||||||
);
|
);
|
||||||
|
@ -1478,7 +1487,7 @@ impl TranslationPadTask {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self.pad,
|
imp = self.pad,
|
||||||
"Pushing gap: {last_position} -> {}",
|
"Pushing gap: {last_position} -> {}",
|
||||||
last_position + duration
|
last_position + duration
|
||||||
);
|
);
|
||||||
|
@ -1533,10 +1542,10 @@ impl TranslationPadTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
for event in events.drain(..) {
|
for event in events.drain(..) {
|
||||||
gst::info!(CAT, imp: self.pad, "Sending {event:?}");
|
gst::info!(CAT, imp = self.pad, "Sending {event:?}");
|
||||||
if !self.pad.obj().push_event(event) {
|
if !self.pad.obj().push_event(event) {
|
||||||
const ERR: &str = "Failed to send initial";
|
const ERR: &str = "Failed to send initial";
|
||||||
gst::error!(CAT, imp: self.pad, "{ERR}");
|
gst::error!(CAT, imp = self.pad, "{ERR}");
|
||||||
return Err(gst::error_msg!(gst::StreamError::Failed, ["{ERR}"]));
|
return Err(gst::error_msg!(gst::StreamError::Failed, ["{ERR}"]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1580,7 +1589,7 @@ pub struct TranslateSrcPad {
|
||||||
|
|
||||||
impl TranslateSrcPad {
|
impl TranslateSrcPad {
|
||||||
fn start_task(&self) -> Result<(), gst::LoggableError> {
|
fn start_task(&self) -> Result<(), gst::LoggableError> {
|
||||||
gst::debug!(CAT, imp: self, "Starting task");
|
gst::debug!(CAT, imp = self, "Starting task");
|
||||||
|
|
||||||
let elem = self.parent();
|
let elem = self.parent();
|
||||||
let _enter = RUNTIME.enter();
|
let _enter = RUNTIME.enter();
|
||||||
|
@ -1598,10 +1607,10 @@ impl TranslateSrcPad {
|
||||||
Ok(Err(err)) => {
|
Ok(Err(err)) => {
|
||||||
// Don't bring down the whole element if this Pad fails
|
// Don't bring down the whole element if this Pad fails
|
||||||
// FIXME is there a way to mark the Pad in error though?
|
// FIXME is there a way to mark the Pad in error though?
|
||||||
gst::info!(CAT, imp: imp, "Pausing task due to: {err}");
|
gst::info!(CAT, imp = imp, "Pausing task due to: {err}");
|
||||||
let _ = imp.obj().pause_task();
|
let _ = imp.obj().pause_task();
|
||||||
}
|
}
|
||||||
Err(_) => gst::debug!(CAT, imp: imp, "task iter aborted"),
|
Err(_) => gst::debug!(CAT, imp = imp, "task iter aborted"),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1609,13 +1618,13 @@ impl TranslateSrcPad {
|
||||||
return Err(gst::loggable_error!(CAT, "Failed to start pad task"));
|
return Err(gst::loggable_error!(CAT, "Failed to start pad task"));
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Task started");
|
gst::debug!(CAT, imp = self, "Task started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop_task(&self) {
|
fn stop_task(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Stopping task");
|
gst::debug!(CAT, imp = self, "Stopping task");
|
||||||
|
|
||||||
// See also the note in `start_task()`:
|
// See also the note in `start_task()`:
|
||||||
// 1. Mark the task as stopped so no further iteration is executed.
|
// 1. Mark the task as stopped so no further iteration is executed.
|
||||||
|
@ -1626,7 +1635,7 @@ impl TranslateSrcPad {
|
||||||
task_abort_handle.abort();
|
task_abort_handle.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Task stopped");
|
gst::debug!(CAT, imp = self, "Task stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_discont(&self) {
|
fn set_discont(&self) {
|
||||||
|
@ -1688,7 +1697,7 @@ impl TranslateSrcPad {
|
||||||
pad: &super::TranslateSrcPad,
|
pad: &super::TranslateSrcPad,
|
||||||
query: &mut gst::QueryRef,
|
query: &mut gst::QueryRef,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling query {query:?}");
|
gst::log!(CAT, obj = pad, "Handling query {query:?}");
|
||||||
|
|
||||||
use gst::QueryViewMut::*;
|
use gst::QueryViewMut::*;
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
|
@ -1707,7 +1716,7 @@ impl TranslateSrcPad {
|
||||||
Self::our_latency(&elem_settings, &pad_settings)
|
Self::our_latency(&elem_settings, &pad_settings)
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::info!(CAT, obj: pad, "Our latency {our_latency}");
|
gst::info!(CAT, obj = pad, "Our latency {our_latency}");
|
||||||
q.set(true, our_latency + min, gst::ClockTime::NONE);
|
q.set(true, our_latency + min, gst::ClockTime::NONE);
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -167,7 +167,7 @@ impl TranscriberStream {
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
let err = format!("Transcribe ws init error: {err}: {}", err.meta());
|
let err = format!("Transcribe ws init error: {err}: {}", err.meta());
|
||||||
gst::error!(CAT, imp: imp, "{err}");
|
gst::error!(CAT, imp = imp, "{err}");
|
||||||
gst::error_msg!(gst::LibraryError::Init, ["{err}"])
|
gst::error_msg!(gst::LibraryError::Init, ["{err}"])
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -189,12 +189,12 @@ impl TranscriberStream {
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
let err = format!("Transcribe ws stream error: {err}: {}", err.meta());
|
let err = format!("Transcribe ws stream error: {err}: {}", err.meta());
|
||||||
gst::error!(CAT, imp: self.imp, "{err}");
|
gst::error!(CAT, imp = self.imp, "{err}");
|
||||||
gst::error_msg!(gst::LibraryError::Failed, ["{err}"])
|
gst::error_msg!(gst::LibraryError::Failed, ["{err}"])
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let Some(event) = event else {
|
let Some(event) = event else {
|
||||||
gst::debug!(CAT, imp: self.imp, "Transcriber loop sending EOS");
|
gst::debug!(CAT, imp = self.imp, "Transcriber loop sending EOS");
|
||||||
return Ok(TranscriptEvent::Eos);
|
return Ok(TranscriptEvent::Eos);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ impl TranscriberStream {
|
||||||
.and_then(|transcript| transcript.results)
|
.and_then(|transcript| transcript.results)
|
||||||
.and_then(|mut results| results.drain(..).next())
|
.and_then(|mut results| results.drain(..).next())
|
||||||
{
|
{
|
||||||
gst::trace!(CAT, imp: self.imp, "Received: {result:?}");
|
gst::trace!(CAT, imp = self.imp, "Received: {result:?}");
|
||||||
|
|
||||||
if let Some(alternative) = result
|
if let Some(alternative) = result
|
||||||
.alternatives
|
.alternatives
|
||||||
|
@ -224,7 +224,7 @@ impl TranscriberStream {
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self.imp,
|
imp = self.imp,
|
||||||
"Transcribe ws returned unknown event: consider upgrading the SDK"
|
"Transcribe ws returned unknown event: consider upgrading the SDK"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ impl TranscriberStream {
|
||||||
if items.len() <= self.partial_index {
|
if items.len() <= self.partial_index {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self.imp,
|
imp = self.imp,
|
||||||
"sanity check failed, alternative length {} < partial_index {}",
|
"sanity check failed, alternative length {} < partial_index {}",
|
||||||
items.len(),
|
items.len(),
|
||||||
self.partial_index
|
self.partial_index
|
||||||
|
@ -267,7 +267,7 @@ impl TranscriberStream {
|
||||||
};
|
};
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self.imp,
|
imp = self.imp,
|
||||||
"Item is ready for queuing: {}, PTS {}",
|
"Item is ready for queuing: {}, PTS {}",
|
||||||
item.content,
|
item.content,
|
||||||
item.pts,
|
item.pts,
|
||||||
|
|
|
@ -83,7 +83,7 @@ impl TranslateLoop {
|
||||||
"Failed to call list_languages service: {err}: {}",
|
"Failed to call list_languages service: {err}: {}",
|
||||||
err.meta()
|
err.meta()
|
||||||
);
|
);
|
||||||
gst::info!(CAT, imp: self.pad, "{err}");
|
gst::info!(CAT, imp = self.pad, "{err}");
|
||||||
gst::error_msg!(gst::LibraryError::Failed, ["{err}"])
|
gst::error_msg!(gst::LibraryError::Failed, ["{err}"])
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ impl TranslateLoop {
|
||||||
|
|
||||||
if !found_output_lang {
|
if !found_output_lang {
|
||||||
let err = format!("Unknown output languages: {}", self.output_lang);
|
let err = format!("Unknown output languages: {}", self.output_lang);
|
||||||
gst::info!(CAT, imp: self.pad, "{err}");
|
gst::info!(CAT, imp = self.pad, "{err}");
|
||||||
return Err(gst::error_msg!(gst::LibraryError::Failed, ["{err}"]));
|
return Err(gst::error_msg!(gst::LibraryError::Failed, ["{err}"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +136,11 @@ impl TranslateLoop {
|
||||||
|
|
||||||
let content: String = content.join("");
|
let content: String = content.join("");
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self.pad, "Translating {content} with {ts_duration_list:?}");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self.pad,
|
||||||
|
"Translating {content} with {ts_duration_list:?}"
|
||||||
|
);
|
||||||
|
|
||||||
let translated_text = self
|
let translated_text = self
|
||||||
.client
|
.client
|
||||||
|
@ -148,12 +152,12 @@ impl TranslateLoop {
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
let err = format!("Failed to call translation service: {err}: {}", err.meta());
|
let err = format!("Failed to call translation service: {err}: {}", err.meta());
|
||||||
gst::info!(CAT, imp: self.pad, "{err}");
|
gst::info!(CAT, imp = self.pad, "{err}");
|
||||||
gst::error_msg!(gst::LibraryError::Failed, ["{err}"])
|
gst::error_msg!(gst::LibraryError::Failed, ["{err}"])
|
||||||
})?
|
})?
|
||||||
.translated_text;
|
.translated_text;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self.pad, "Got translation {translated_text}");
|
gst::debug!(CAT, imp = self.pad, "Got translation {translated_text}");
|
||||||
|
|
||||||
let translated_items = match self.tokenization_method {
|
let translated_items = match self.tokenization_method {
|
||||||
Tokenization::None => {
|
Tokenization::None => {
|
||||||
|
@ -173,12 +177,12 @@ impl TranslateLoop {
|
||||||
Tokenization::SpanBased => span_tokenize_items(&translated_text, ts_duration_list),
|
Tokenization::SpanBased => span_tokenize_items(&translated_text, ts_duration_list),
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self.pad, "Sending {translated_items:?}");
|
gst::trace!(CAT, imp = self.pad, "Sending {translated_items:?}");
|
||||||
|
|
||||||
if self.translate_tx.send(translated_items).await.is_err() {
|
if self.translate_tx.send(translated_items).await.is_err() {
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self.pad,
|
imp = self.pad,
|
||||||
"translation chan terminated, exiting translation loop"
|
"translation chan terminated, exiting translation loop"
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -324,11 +324,7 @@ impl HlsBaseSink {
|
||||||
let context = match state.context.as_mut() {
|
let context = match state.context.as_mut() {
|
||||||
Some(context) => context,
|
Some(context) => context,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(
|
gst::error!(CAT, imp = self, "Playlist is not configured",);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Playlist is not configured",
|
|
||||||
);
|
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -337,22 +333,13 @@ impl HlsBaseSink {
|
||||||
let location = match sprintf::sprintf!(&context.segment_template, fragment_id) {
|
let location = match sprintf::sprintf!(&context.segment_template, fragment_id) {
|
||||||
Ok(file_name) => file_name,
|
Ok(file_name) => file_name,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(
|
gst::error!(CAT, imp = self, "Couldn't build file name, err: {:?}", err,);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Couldn't build file name, err: {:?}", err,
|
|
||||||
);
|
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(CAT, imp = self, "Segment location formatted: {}", location);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Segment location formatted: {}",
|
|
||||||
location
|
|
||||||
);
|
|
||||||
|
|
||||||
let stream = match self
|
let stream = match self
|
||||||
.obj()
|
.obj()
|
||||||
|
@ -390,11 +377,7 @@ impl HlsBaseSink {
|
||||||
let context = match state.context.as_mut() {
|
let context = match state.context.as_mut() {
|
||||||
Some(context) => context,
|
Some(context) => context,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(
|
gst::error!(CAT, imp = self, "Playlist is not configured",);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Playlist is not configured",
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
@ -459,7 +442,12 @@ impl HlsBaseSink {
|
||||||
&self,
|
&self,
|
||||||
context: &mut PlaylistContext,
|
context: &mut PlaylistContext,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::info!(CAT, imp: self, "Preparing to write new playlist, COUNT {}", context.playlist.len());
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Preparing to write new playlist, COUNT {}",
|
||||||
|
context.playlist.len()
|
||||||
|
);
|
||||||
|
|
||||||
context
|
context
|
||||||
.playlist
|
.playlist
|
||||||
|
@ -476,7 +464,7 @@ impl HlsBaseSink {
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Could not get stream to write playlist content",
|
"Could not get stream to write playlist content",
|
||||||
);
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
|
@ -489,7 +477,7 @@ impl HlsBaseSink {
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Could not write new playlist: {}",
|
"Could not write new playlist: {}",
|
||||||
err.to_string()
|
err.to_string()
|
||||||
);
|
);
|
||||||
|
@ -498,7 +486,7 @@ impl HlsBaseSink {
|
||||||
playlist_stream.flush().map_err(|err| {
|
playlist_stream.flush().map_err(|err| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Could not flush playlist: {}",
|
"Could not flush playlist: {}",
|
||||||
err.to_string()
|
err.to_string()
|
||||||
);
|
);
|
||||||
|
@ -513,12 +501,12 @@ impl HlsBaseSink {
|
||||||
.obj()
|
.obj()
|
||||||
.emit_by_name::<bool>(SIGNAL_DELETE_FRAGMENT, &[&old_segment_location])
|
.emit_by_name::<bool>(SIGNAL_DELETE_FRAGMENT, &[&old_segment_location])
|
||||||
{
|
{
|
||||||
gst::error!(CAT, imp: self, "Could not delete fragment");
|
gst::error!(CAT, imp = self, "Could not delete fragment");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Wrote new playlist file!");
|
gst::debug!(CAT, imp = self, "Wrote new playlist file!");
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,7 +536,7 @@ impl HlsBaseSink {
|
||||||
let _ = fs::remove_file(location).map_err(|err| {
|
let _ = fs::remove_file(location).map_err(|err| {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Could not delete segment file: {}",
|
"Could not delete segment file: {}",
|
||||||
err.to_string()
|
err.to_string()
|
||||||
);
|
);
|
||||||
|
|
|
@ -341,7 +341,7 @@ impl HlsBaseSinkImpl for HlsCmafSink {}
|
||||||
|
|
||||||
impl HlsCmafSink {
|
impl HlsCmafSink {
|
||||||
fn start(&self, target_duration: u32, playlist_type: Option<MediaPlaylistType>) -> Playlist {
|
fn start(&self, target_duration: u32, playlist_type: Option<MediaPlaylistType>) -> Playlist {
|
||||||
gst::info!(CAT, imp: self, "Starting");
|
gst::info!(CAT, imp = self, "Starting");
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
*state = HlsCmafSinkState::default();
|
*state = HlsCmafSinkState::default();
|
||||||
|
@ -369,11 +369,7 @@ impl HlsCmafSink {
|
||||||
let location = match sprintf::sprintf!(&settings.init_location, state.init_idx) {
|
let location = match sprintf::sprintf!(&settings.init_location, state.init_idx) {
|
||||||
Ok(location) => location,
|
Ok(location) => location,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(
|
gst::error!(CAT, imp = self, "Couldn't build file name, err: {:?}", err,);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Couldn't build file name, err: {:?}", err,
|
|
||||||
);
|
|
||||||
return Err(String::from("Invalid init segment file pattern"));
|
return Err(String::from("Invalid init segment file pattern"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -448,7 +444,7 @@ impl HlsCmafSink {
|
||||||
let mut stream = self.on_init_segment().map_err(|err| {
|
let mut stream = self.on_init_segment().map_err(|err| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Couldn't get output stream for init segment, {err}",
|
"Couldn't get output stream for init segment, {err}",
|
||||||
);
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
|
@ -458,18 +454,14 @@ impl HlsCmafSink {
|
||||||
stream.write(&map).map_err(|_| {
|
stream.write(&map).map_err(|_| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Couldn't write init segment to output stream",
|
"Couldn't write init segment to output stream",
|
||||||
);
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
stream.flush().map_err(|_| {
|
stream.flush().map_err(|_| {
|
||||||
gst::error!(
|
gst::error!(CAT, imp = self, "Couldn't flush output stream",);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Couldn't flush output stream",
|
|
||||||
);
|
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -494,7 +486,7 @@ impl HlsCmafSink {
|
||||||
let (mut stream, location) = self.on_new_fragment().map_err(|err| {
|
let (mut stream, location) = self.on_new_fragment().map_err(|err| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Couldn't get output stream for segment, {err}",
|
"Couldn't get output stream for segment, {err}",
|
||||||
);
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
|
@ -504,21 +496,13 @@ impl HlsCmafSink {
|
||||||
let map = buffer.map_readable().unwrap();
|
let map = buffer.map_readable().unwrap();
|
||||||
|
|
||||||
stream.write(&map).map_err(|_| {
|
stream.write(&map).map_err(|_| {
|
||||||
gst::error!(
|
gst::error!(CAT, imp = self, "Couldn't write segment to output stream",);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Couldn't write segment to output stream",
|
|
||||||
);
|
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.flush().map_err(|_| {
|
stream.flush().map_err(|_| {
|
||||||
gst::error!(
|
gst::error!(CAT, imp = self, "Couldn't flush output stream",);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Couldn't flush output stream",
|
|
||||||
);
|
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
|
@ -251,7 +251,7 @@ impl ObjectImpl for HlsSink3 {
|
||||||
return Some(None::<String>.to_value());
|
return Some(None::<String>.to_value());
|
||||||
};
|
};
|
||||||
let fragment_id = args[1].get::<u32>().unwrap();
|
let fragment_id = args[1].get::<u32>().unwrap();
|
||||||
gst::info!(CAT, imp: imp, "Got fragment-id: {}", fragment_id);
|
gst::info!(CAT, imp = imp, "Got fragment-id: {}", fragment_id);
|
||||||
|
|
||||||
let sample = args[2].get::<gst::Sample>().unwrap();
|
let sample = args[2].get::<gst::Sample>().unwrap();
|
||||||
let buffer = sample.buffer();
|
let buffer = sample.buffer();
|
||||||
|
@ -265,7 +265,7 @@ impl ObjectImpl for HlsSink3 {
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"buffer null for fragment-id: {}",
|
"buffer null for fragment-id: {}",
|
||||||
fragment_id
|
fragment_id
|
||||||
);
|
);
|
||||||
|
@ -275,7 +275,7 @@ impl ObjectImpl for HlsSink3 {
|
||||||
match imp.on_format_location(fragment_id, running_time) {
|
match imp.on_format_location(fragment_id, running_time) {
|
||||||
Ok(segment_location) => Some(segment_location.to_value()),
|
Ok(segment_location) => Some(segment_location.to_value()),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: imp, "on format-location handler: {}", err);
|
gst::error!(CAT, imp = imp, "on format-location handler: {}", err);
|
||||||
Some("unknown_segment".to_value())
|
Some("unknown_segment".to_value())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ impl ElementImpl for HlsSink3 {
|
||||||
if settings.audio_sink {
|
if settings.audio_sink {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"requested_new_pad: audio pad is already set"
|
"requested_new_pad: audio pad is already set"
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
|
@ -389,7 +389,7 @@ impl ElementImpl for HlsSink3 {
|
||||||
if settings.video_sink {
|
if settings.video_sink {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"requested_new_pad: video pad is already set"
|
"requested_new_pad: video pad is already set"
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
|
@ -406,7 +406,7 @@ impl ElementImpl for HlsSink3 {
|
||||||
other_name => {
|
other_name => {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"requested_new_pad: name \"{}\" is not audio or video",
|
"requested_new_pad: name \"{}\" is not audio or video",
|
||||||
other_name
|
other_name
|
||||||
);
|
);
|
||||||
|
@ -486,7 +486,7 @@ impl HlsSink3 {
|
||||||
playlist_type: Option<MediaPlaylistType>,
|
playlist_type: Option<MediaPlaylistType>,
|
||||||
i_frames_only: bool,
|
i_frames_only: bool,
|
||||||
) -> Playlist {
|
) -> Playlist {
|
||||||
gst::info!(CAT, imp: self, "Starting");
|
gst::info!(CAT, imp = self, "Starting");
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
*state = HlsSink3State::default();
|
*state = HlsSink3State::default();
|
||||||
|
@ -515,7 +515,7 @@ impl HlsSink3 {
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Starting the formatting of the fragment-id: {}",
|
"Starting the formatting of the fragment-id: {}",
|
||||||
fragment_id
|
fragment_id
|
||||||
);
|
);
|
||||||
|
@ -535,7 +535,7 @@ impl HlsSink3 {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"New segment location: {:?}",
|
"New segment location: {:?}",
|
||||||
state.current_segment_location.as_ref()
|
state.current_segment_location.as_ref()
|
||||||
);
|
);
|
||||||
|
@ -548,7 +548,7 @@ impl HlsSink3 {
|
||||||
let location = match state.current_segment_location.take() {
|
let location = match state.current_segment_location.take() {
|
||||||
Some(location) => location,
|
Some(location) => location,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, imp: self, "Unknown segment location");
|
gst::error!(CAT, imp = self, "Unknown segment location");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -556,7 +556,7 @@ impl HlsSink3 {
|
||||||
let opened_at = match state.fragment_opened_at.take() {
|
let opened_at = match state.fragment_opened_at.take() {
|
||||||
Some(opened_at) => opened_at,
|
Some(opened_at) => opened_at,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, imp: self, "Unknown segment duration");
|
gst::error!(CAT, imp = self, "Unknown segment duration");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -259,7 +259,7 @@ fn find_pcr(slice: &[u8], imp: &MpegTsLiveSource) -> Result<Option<u64>> {
|
||||||
reader.skip(6)?;
|
reader.skip(6)?;
|
||||||
let pcr_ext = reader.read::<u64>(9).context("PCR_ext")?;
|
let pcr_ext = reader.read::<u64>(9).context("PCR_ext")?;
|
||||||
let pcr = pcr_base * 300 + pcr_ext;
|
let pcr = pcr_base * 300 + pcr_ext;
|
||||||
gst::debug!(CAT, imp:imp, "PID {pid} PCR {pcr}");
|
gst::debug!(CAT, imp = imp, "PID {pid} PCR {pcr}");
|
||||||
buffer_pcr = Some(pcr);
|
buffer_pcr = Some(pcr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -277,13 +277,13 @@ fn get_pcr_from_buffer(imp: &MpegTsLiveSource, buffer: &gst::Buffer) -> Option<u
|
||||||
let buffer_pcr = match find_pcr(range.as_slice(), imp) {
|
let buffer_pcr = match find_pcr(range.as_slice(), imp) {
|
||||||
Ok(pcr) => pcr,
|
Ok(pcr) => pcr,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp:imp, "Failed parsing MPEG-TS packets: {err}");
|
gst::error!(CAT, imp = imp, "Failed parsing MPEG-TS packets: {err}");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(raw_pcr) = buffer_pcr else {
|
let Some(raw_pcr) = buffer_pcr else {
|
||||||
gst::debug!(CAT, imp:imp, "No PCR observed in {:?}", buffer);
|
gst::debug!(CAT, imp = imp, "No PCR observed in {:?}", buffer);
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some(raw_pcr)
|
Some(raw_pcr)
|
||||||
|
@ -466,20 +466,20 @@ impl ObjectImpl for MpegTsLiveSource {
|
||||||
.expect("type checked upstream")
|
.expect("type checked upstream")
|
||||||
{
|
{
|
||||||
if self.obj().add(&source).is_err() {
|
if self.obj().add(&source).is_err() {
|
||||||
gst::warning!(CAT, imp:self, "Failed to add source");
|
gst::warning!(CAT, imp = self, "Failed to add source");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if source.set_clock(Some(&self.internal_clock)).is_err() {
|
if source.set_clock(Some(&self.internal_clock)).is_err() {
|
||||||
gst::warning!(CAT, imp:self, "Failed to set clock on source");
|
gst::warning!(CAT, imp = self, "Failed to set clock on source");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(target_pad) = source.static_pad("src") else {
|
let Some(target_pad) = source.static_pad("src") else {
|
||||||
gst::warning!(CAT, imp:self, "Source element has no 'src' pad");
|
gst::warning!(CAT, imp = self, "Source element has no 'src' pad");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if self.srcpad.set_target(Some(&target_pad)).is_err() {
|
if self.srcpad.set_target(Some(&target_pad)).is_err() {
|
||||||
gst::warning!(CAT, imp:self, "Failed to set ghost pad target");
|
gst::warning!(CAT, imp = self, "Failed to set ghost pad target");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.source = Some(source);
|
state.source = Some(source);
|
||||||
|
|
|
@ -76,7 +76,7 @@ impl DeviceProviderImpl for DeviceProvider {
|
||||||
|
|
||||||
let mut thread_guard = self.thread.lock().unwrap();
|
let mut thread_guard = self.thread.lock().unwrap();
|
||||||
if thread_guard.is_some() {
|
if thread_guard.is_some() {
|
||||||
gst::log!(CAT, imp: self, "Device provider already started");
|
gst::log!(CAT, imp = self, "Device provider already started");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,13 +92,13 @@ impl DeviceProviderImpl for DeviceProvider {
|
||||||
|
|
||||||
let mut find_guard = imp.find.lock().unwrap();
|
let mut find_guard = imp.find.lock().unwrap();
|
||||||
if find_guard.is_some() {
|
if find_guard.is_some() {
|
||||||
gst::log!(CAT, imp: imp, "Already started");
|
gst::log!(CAT, imp = imp, "Already started");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let find = match ndi::FindInstance::builder().build() {
|
let find = match ndi::FindInstance::builder().build() {
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, imp: imp, "Failed to create Find instance");
|
gst::error!(CAT, imp = imp, "Failed to create Find instance");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Some(find) => find,
|
Some(find) => find,
|
||||||
|
@ -140,7 +140,7 @@ impl DeviceProvider {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !find.wait_for_sources(if first { 1000 } else { 5000 }) {
|
if !find.wait_for_sources(if first { 1000 } else { 5000 }) {
|
||||||
gst::trace!(CAT, imp: self, "No new sources found");
|
gst::trace!(CAT, imp = self, "No new sources found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ impl DeviceProvider {
|
||||||
let old_source = old_device_imp.source.get().unwrap();
|
let old_source = old_device_imp.source.get().unwrap();
|
||||||
|
|
||||||
if !sources.contains(old_source) {
|
if !sources.contains(old_source) {
|
||||||
gst::log!(CAT, imp: self, "Source {:?} disappeared", old_source);
|
gst::log!(CAT, imp = self, "Source {:?} disappeared", old_source);
|
||||||
expired_devices.push(old_device.clone());
|
expired_devices.push(old_device.clone());
|
||||||
} else {
|
} else {
|
||||||
// Otherwise remember that we had it before already and don't have to announce it
|
// Otherwise remember that we had it before already and don't have to announce it
|
||||||
|
@ -179,7 +179,7 @@ impl DeviceProvider {
|
||||||
|
|
||||||
// Now go through all new devices and announce them
|
// Now go through all new devices and announce them
|
||||||
for source in sources {
|
for source in sources {
|
||||||
gst::log!(CAT, imp: self, "Source {:?} appeared", source);
|
gst::log!(CAT, imp = self, "Source {:?} appeared", source);
|
||||||
let device = super::Device::new(&source);
|
let device = super::Device::new(&source);
|
||||||
self.obj().device_add(&device);
|
self.obj().device_add(&device);
|
||||||
current_devices_guard.push(device);
|
current_devices_guard.push(device);
|
||||||
|
|
|
@ -209,7 +209,7 @@ impl BaseSinkImpl for NdiSink {
|
||||||
audio_info: None,
|
audio_info: None,
|
||||||
};
|
};
|
||||||
*state_storage = Some(state);
|
*state_storage = Some(state);
|
||||||
gst::info!(CAT, imp: self, "Started");
|
gst::info!(CAT, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ impl BaseSinkImpl for NdiSink {
|
||||||
let mut state_storage = self.state.lock().unwrap();
|
let mut state_storage = self.state.lock().unwrap();
|
||||||
|
|
||||||
*state_storage = None;
|
*state_storage = None;
|
||||||
gst::info!(CAT, imp: self, "Stopped");
|
gst::info!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ impl BaseSinkImpl for NdiSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
|
fn set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
|
||||||
gst::debug!(CAT, imp: self, "Setting caps {}", caps);
|
gst::debug!(CAT, imp = self, "Setting caps {}", caps);
|
||||||
|
|
||||||
let mut state_storage = self.state.lock().unwrap();
|
let mut state_storage = self.state.lock().unwrap();
|
||||||
let state = match &mut *state_storage {
|
let state = match &mut *state_storage {
|
||||||
|
@ -272,13 +272,13 @@ impl BaseSinkImpl for NdiSink {
|
||||||
for (buffer, info, timecode) in audio_meta.buffers() {
|
for (buffer, info, timecode) in audio_meta.buffers() {
|
||||||
let frame = crate::ndi::AudioFrame::try_from_buffer(info, buffer, *timecode)
|
let frame = crate::ndi::AudioFrame::try_from_buffer(info, buffer, *timecode)
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Unsupported audio frame");
|
gst::error!(CAT, imp = self, "Unsupported audio frame");
|
||||||
gst::FlowError::NotNegotiated
|
gst::FlowError::NotNegotiated
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Sending audio buffer {:?} with timecode {} and format {:?}",
|
"Sending audio buffer {:?} with timecode {} and format {:?}",
|
||||||
buffer,
|
buffer,
|
||||||
if *timecode < 0 {
|
if *timecode < 0 {
|
||||||
|
@ -317,19 +317,19 @@ impl BaseSinkImpl for NdiSink {
|
||||||
|
|
||||||
let frame = gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info)
|
let frame = gst_video::VideoFrame::from_buffer_readable(buffer.clone(), info)
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map buffer");
|
gst::error!(CAT, imp = self, "Failed to map buffer");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let frame = crate::ndi::VideoFrame::try_from_video_frame(frame, ndi_meta, timecode)
|
let frame = crate::ndi::VideoFrame::try_from_video_frame(frame, ndi_meta, timecode)
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Unsupported video frame");
|
gst::error!(CAT, imp = self, "Unsupported video frame");
|
||||||
gst::FlowError::NotNegotiated
|
gst::FlowError::NotNegotiated
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Sending video buffer {:?} with timecode {} and format {:?}",
|
"Sending video buffer {:?} with timecode {} and format {:?}",
|
||||||
buffer,
|
buffer,
|
||||||
if timecode < 0 {
|
if timecode < 0 {
|
||||||
|
@ -358,13 +358,13 @@ impl BaseSinkImpl for NdiSink {
|
||||||
|
|
||||||
let frame =
|
let frame =
|
||||||
crate::ndi::AudioFrame::try_from_buffer(info, buffer, timecode).map_err(|_| {
|
crate::ndi::AudioFrame::try_from_buffer(info, buffer, timecode).map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Unsupported audio frame");
|
gst::error!(CAT, imp = self, "Unsupported audio frame");
|
||||||
gst::FlowError::NotNegotiated
|
gst::FlowError::NotNegotiated
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Sending audio buffer {:?} with timecode {} and format {:?}",
|
"Sending audio buffer {:?} with timecode {} and format {:?}",
|
||||||
buffer,
|
buffer,
|
||||||
if timecode < 0 {
|
if timecode < 0 {
|
||||||
|
|
|
@ -147,7 +147,7 @@ impl ElementImpl for NdiSinkCombiner {
|
||||||
let mut audio_pad_storage = self.audio_pad.lock().unwrap();
|
let mut audio_pad_storage = self.audio_pad.lock().unwrap();
|
||||||
|
|
||||||
if audio_pad_storage.as_ref().map(|p| p.upcast_ref()) == Some(pad) {
|
if audio_pad_storage.as_ref().map(|p| p.upcast_ref()) == Some(pad) {
|
||||||
gst::debug!(CAT, obj: pad, "Release audio pad");
|
gst::debug!(CAT, obj = pad, "Release audio pad");
|
||||||
self.parent_release_pad(pad);
|
self.parent_release_pad(pad);
|
||||||
*audio_pad_storage = None;
|
*audio_pad_storage = None;
|
||||||
}
|
}
|
||||||
|
@ -164,20 +164,20 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
let mut audio_pad_storage = self.audio_pad.lock().unwrap();
|
let mut audio_pad_storage = self.audio_pad.lock().unwrap();
|
||||||
|
|
||||||
if audio_pad_storage.is_some() {
|
if audio_pad_storage.is_some() {
|
||||||
gst::error!(CAT, imp: self, "Audio pad already requested");
|
gst::error!(CAT, imp = self, "Audio pad already requested");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sink_templ = self.obj().pad_template("audio").unwrap();
|
let sink_templ = self.obj().pad_template("audio").unwrap();
|
||||||
if templ != &sink_templ {
|
if templ != &sink_templ {
|
||||||
gst::error!(CAT, imp: self, "Wrong pad template");
|
gst::error!(CAT, imp = self, "Wrong pad template");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pad = gst::PadBuilder::<gst_base::AggregatorPad>::from_template(templ).build();
|
let pad = gst::PadBuilder::<gst_base::AggregatorPad>::from_template(templ).build();
|
||||||
*audio_pad_storage = Some(pad.clone());
|
*audio_pad_storage = Some(pad.clone());
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Requested audio pad");
|
gst::debug!(CAT, imp = self, "Requested audio pad");
|
||||||
|
|
||||||
Some(pad)
|
Some(pad)
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
current_audio_buffers: Vec::new(),
|
current_audio_buffers: Vec::new(),
|
||||||
});
|
});
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Started");
|
gst::debug!(CAT, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
// Drop our state now
|
// Drop our state now
|
||||||
let _ = self.state.lock().unwrap().take();
|
let _ = self.state.lock().unwrap().take();
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Stopped");
|
gst::debug!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -220,14 +220,14 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
let segment = match agg_pad.segment().downcast::<gst::ClockTime>() {
|
let segment = match agg_pad.segment().downcast::<gst::ClockTime>() {
|
||||||
Ok(segment) => segment,
|
Ok(segment) => segment,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::error!(CAT, obj: agg_pad, "Only TIME segments supported");
|
gst::error!(CAT, obj = agg_pad, "Only TIME segments supported");
|
||||||
return Some(buffer);
|
return Some(buffer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let pts = buffer.pts();
|
let pts = buffer.pts();
|
||||||
if pts.is_none() {
|
if pts.is_none() {
|
||||||
gst::error!(CAT, obj: agg_pad, "Only buffers with PTS supported");
|
gst::error!(CAT, obj = agg_pad, "Only buffers with PTS supported");
|
||||||
return Some(buffer);
|
return Some(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: agg_pad,
|
obj = agg_pad,
|
||||||
"Clipping buffer {:?} with PTS {} and duration {}",
|
"Clipping buffer {:?} with PTS {} and duration {}",
|
||||||
buffer,
|
buffer,
|
||||||
pts.display(),
|
pts.display(),
|
||||||
|
@ -270,7 +270,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: agg_pad,
|
obj = agg_pad,
|
||||||
"Clipping buffer {:?} with PTS {} and duration {}",
|
"Clipping buffer {:?} with PTS {} and duration {}",
|
||||||
buffer,
|
buffer,
|
||||||
pts.display(),
|
pts.display(),
|
||||||
|
@ -322,7 +322,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
Err(video_segment) => {
|
Err(video_segment) => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Video segment of wrong format {:?}",
|
"Video segment of wrong format {:?}",
|
||||||
video_segment.format()
|
video_segment.format()
|
||||||
);
|
);
|
||||||
|
@ -333,7 +333,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
Some((video_buffer, video_segment))
|
Some((video_buffer, video_segment))
|
||||||
}
|
}
|
||||||
None if !self.video_pad.is_eos() => {
|
None if !self.video_pad.is_eos() => {
|
||||||
gst::trace!(CAT, imp: self, "Waiting for video buffer");
|
gst::trace!(CAT, imp = self, "Waiting for video buffer");
|
||||||
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
|
@ -345,7 +345,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
Some(audio_buffer) if audio_buffer.size() == 0 => {
|
Some(audio_buffer) if audio_buffer.size() == 0 => {
|
||||||
// Skip empty/gap audio buffer
|
// Skip empty/gap audio buffer
|
||||||
audio_pad.drop_buffer();
|
audio_pad.drop_buffer();
|
||||||
gst::trace!(CAT, imp: self, "Empty audio buffer, waiting for next");
|
gst::trace!(CAT, imp = self, "Empty audio buffer, waiting for next");
|
||||||
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
||||||
}
|
}
|
||||||
Some(audio_buffer) => {
|
Some(audio_buffer) => {
|
||||||
|
@ -355,7 +355,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
Err(audio_segment) => {
|
Err(audio_segment) => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Audio segment of wrong format {:?}",
|
"Audio segment of wrong format {:?}",
|
||||||
audio_segment.format()
|
audio_segment.format()
|
||||||
);
|
);
|
||||||
|
@ -366,7 +366,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
Some((audio_buffer, audio_segment, audio_pad))
|
Some((audio_buffer, audio_segment, audio_pad))
|
||||||
}
|
}
|
||||||
None if !audio_pad.is_eos() => {
|
None if !audio_pad.is_eos() => {
|
||||||
gst::trace!(CAT, imp: self, "Waiting for audio buffer");
|
gst::trace!(CAT, imp = self, "Waiting for audio buffer");
|
||||||
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
return Err(gst_base::AGGREGATOR_FLOW_NEED_DATA);
|
||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
|
@ -395,7 +395,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
|
|
||||||
match &state.current_video_buffer {
|
match &state.current_video_buffer {
|
||||||
None => {
|
None => {
|
||||||
gst::trace!(CAT, imp: self, "First video buffer, waiting for second");
|
gst::trace!(CAT, imp = self, "First video buffer, waiting for second");
|
||||||
state.current_video_buffer = Some((
|
state.current_video_buffer = Some((
|
||||||
video_buffer,
|
video_buffer,
|
||||||
video_running_time,
|
video_running_time,
|
||||||
|
@ -419,7 +419,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
(None, None) => {
|
(None, None) => {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"All pads are EOS and no buffers are queued, finishing"
|
"All pads are EOS and no buffers are queued, finishing"
|
||||||
);
|
);
|
||||||
return Err(gst::FlowError::Eos);
|
return Err(gst::FlowError::Eos);
|
||||||
|
@ -436,7 +436,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
Err(video_segment) => {
|
Err(video_segment) => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Video segment of wrong format {:?}",
|
"Video segment of wrong format {:?}",
|
||||||
video_segment.format()
|
video_segment.format()
|
||||||
);
|
);
|
||||||
|
@ -445,7 +445,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
};
|
};
|
||||||
let video_pts = video_segment.position_from_running_time(audio_running_time);
|
let video_pts = video_segment.position_from_running_time(audio_running_time);
|
||||||
if video_pts.is_none() {
|
if video_pts.is_none() {
|
||||||
gst::warning!(CAT, imp: self, "Can't output more audio after video EOS");
|
gst::warning!(CAT, imp = self, "Can't output more audio after video EOS");
|
||||||
return Err(gst::FlowError::Eos);
|
return Err(gst::FlowError::Eos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
let audio_info = match state.audio_info {
|
let audio_info = match state.audio_info {
|
||||||
Some(ref audio_info) => audio_info,
|
Some(ref audio_info) => audio_info,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, imp: self, "Have no audio caps");
|
gst::error!(CAT, imp = self, "Have no audio caps");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -497,7 +497,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Including audio buffer {:?} with timecode {}: {} <= {}",
|
"Including audio buffer {:?} with timecode {}: {} <= {}",
|
||||||
audio_buffer,
|
audio_buffer,
|
||||||
timecode,
|
timecode,
|
||||||
|
@ -538,7 +538,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Finishing video buffer {:?}",
|
"Finishing video buffer {:?}",
|
||||||
current_video_buffer
|
current_video_buffer
|
||||||
);
|
);
|
||||||
|
@ -570,7 +570,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
let info = match gst_video::VideoInfo::from_caps(&caps) {
|
let info = match gst_video::VideoInfo::from_caps(&caps) {
|
||||||
Ok(info) => info,
|
Ok(info) => info,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::error!(CAT, obj: pad, "Failed to parse caps {:?}", caps);
|
gst::error!(CAT, obj = pad, "Failed to parse caps {:?}", caps);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -606,7 +606,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
let info = match gst_audio::AudioInfo::from_caps(&caps) {
|
let info = match gst_audio::AudioInfo::from_caps(&caps) {
|
||||||
Ok(info) => info,
|
Ok(info) => info,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::error!(CAT, obj: pad, "Failed to parse caps {:?}", caps);
|
gst::error!(CAT, obj = pad, "Failed to parse caps {:?}", caps);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -617,7 +617,7 @@ impl AggregatorImpl for NdiSinkCombiner {
|
||||||
// The video segment is passed through as-is and the video timestamps are preserved
|
// The video segment is passed through as-is and the video timestamps are preserved
|
||||||
EventView::Segment(segment) if pad == &self.video_pad => {
|
EventView::Segment(segment) if pad == &self.video_pad => {
|
||||||
let segment = segment.segment();
|
let segment = segment.segment();
|
||||||
gst::debug!(CAT, obj: pad, "Updating segment {:?}", segment);
|
gst::debug!(CAT, obj = pad, "Updating segment {:?}", segment);
|
||||||
let mut state_storage = self.state.lock().unwrap();
|
let mut state_storage = self.state.lock().unwrap();
|
||||||
let state = match &mut *state_storage {
|
let state = match &mut *state_storage {
|
||||||
Some(ref mut state) => state,
|
Some(ref mut state) => state,
|
||||||
|
|
|
@ -169,7 +169,7 @@ impl ObjectImpl for NdiSrc {
|
||||||
let ndi_name = value.get().unwrap();
|
let ndi_name = value.get().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing ndi-name from {:?} to {:?}",
|
"Changing ndi-name from {:?} to {:?}",
|
||||||
settings.ndi_name,
|
settings.ndi_name,
|
||||||
ndi_name,
|
ndi_name,
|
||||||
|
@ -181,7 +181,7 @@ impl ObjectImpl for NdiSrc {
|
||||||
let url_address = value.get().unwrap();
|
let url_address = value.get().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing url-address from {:?} to {:?}",
|
"Changing url-address from {:?} to {:?}",
|
||||||
settings.url_address,
|
settings.url_address,
|
||||||
url_address,
|
url_address,
|
||||||
|
@ -193,7 +193,7 @@ impl ObjectImpl for NdiSrc {
|
||||||
let receiver_ndi_name = value.get::<Option<String>>().unwrap();
|
let receiver_ndi_name = value.get::<Option<String>>().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing receiver-ndi-name from {:?} to {:?}",
|
"Changing receiver-ndi-name from {:?} to {:?}",
|
||||||
settings.receiver_ndi_name,
|
settings.receiver_ndi_name,
|
||||||
receiver_ndi_name,
|
receiver_ndi_name,
|
||||||
|
@ -206,7 +206,7 @@ impl ObjectImpl for NdiSrc {
|
||||||
let connect_timeout = value.get().unwrap();
|
let connect_timeout = value.get().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing connect-timeout from {} to {}",
|
"Changing connect-timeout from {} to {}",
|
||||||
settings.connect_timeout,
|
settings.connect_timeout,
|
||||||
connect_timeout,
|
connect_timeout,
|
||||||
|
@ -218,7 +218,7 @@ impl ObjectImpl for NdiSrc {
|
||||||
let timeout = value.get().unwrap();
|
let timeout = value.get().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing timeout from {} to {}",
|
"Changing timeout from {} to {}",
|
||||||
settings.timeout,
|
settings.timeout,
|
||||||
timeout,
|
timeout,
|
||||||
|
@ -230,7 +230,7 @@ impl ObjectImpl for NdiSrc {
|
||||||
let max_queue_length = value.get().unwrap();
|
let max_queue_length = value.get().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing max-queue-length from {} to {}",
|
"Changing max-queue-length from {} to {}",
|
||||||
settings.max_queue_length,
|
settings.max_queue_length,
|
||||||
max_queue_length,
|
max_queue_length,
|
||||||
|
@ -242,7 +242,7 @@ impl ObjectImpl for NdiSrc {
|
||||||
let bandwidth = value.get().unwrap();
|
let bandwidth = value.get().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing bandwidth from {} to {}",
|
"Changing bandwidth from {} to {}",
|
||||||
settings.bandwidth,
|
settings.bandwidth,
|
||||||
bandwidth,
|
bandwidth,
|
||||||
|
@ -254,7 +254,7 @@ impl ObjectImpl for NdiSrc {
|
||||||
let color_format = value.get().unwrap();
|
let color_format = value.get().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing color format from {:?} to {:?}",
|
"Changing color format from {:?} to {:?}",
|
||||||
settings.color_format,
|
settings.color_format,
|
||||||
color_format,
|
color_format,
|
||||||
|
@ -266,7 +266,7 @@ impl ObjectImpl for NdiSrc {
|
||||||
let timestamp_mode = value.get().unwrap();
|
let timestamp_mode = value.get().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Changing timestamp mode from {:?} to {:?}",
|
"Changing timestamp mode from {:?} to {:?}",
|
||||||
settings.timestamp_mode,
|
settings.timestamp_mode,
|
||||||
timestamp_mode
|
timestamp_mode
|
||||||
|
@ -398,7 +398,7 @@ impl BaseSrcImpl for NdiSrc {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unlock(&self) -> Result<(), gst::ErrorMessage> {
|
fn unlock(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Unlocking",);
|
gst::debug!(CAT, imp = self, "Unlocking",);
|
||||||
if let Some(ref controller) = *self.receiver_controller.lock().unwrap() {
|
if let Some(ref controller) = *self.receiver_controller.lock().unwrap() {
|
||||||
controller.set_flushing(true);
|
controller.set_flushing(true);
|
||||||
}
|
}
|
||||||
|
@ -406,7 +406,7 @@ impl BaseSrcImpl for NdiSrc {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unlock_stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn unlock_stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Stop unlocking",);
|
gst::debug!(CAT, imp = self, "Stop unlocking",);
|
||||||
if let Some(ref controller) = *self.receiver_controller.lock().unwrap() {
|
if let Some(ref controller) = *self.receiver_controller.lock().unwrap() {
|
||||||
controller.set_flushing(false);
|
controller.set_flushing(false);
|
||||||
}
|
}
|
||||||
|
@ -488,7 +488,7 @@ impl BaseSrcImpl for NdiSrc {
|
||||||
|
|
||||||
let max = settings.max_queue_length as u64 * latency;
|
let max = settings.max_queue_length as u64 * latency;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Returning latency min {} max {}", min, max);
|
gst::debug!(CAT, imp = self, "Returning latency min {} max {}", min, max);
|
||||||
q.set(true, min, max);
|
q.set(true, min, max);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
@ -510,7 +510,7 @@ impl BaseSrcImpl for NdiSrc {
|
||||||
match state.receiver.take() {
|
match state.receiver.take() {
|
||||||
Some(recv) => recv,
|
Some(recv) => recv,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, imp: self, "Have no receiver");
|
gst::error!(CAT, imp = self, "Have no receiver");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl Drop for ReceiverInner {
|
||||||
let element = self.element.upgrade();
|
let element = self.element.upgrade();
|
||||||
|
|
||||||
if let Some(ref element) = element {
|
if let Some(ref element) = element {
|
||||||
gst::debug!(CAT, obj: element, "Closed NDI connection");
|
gst::debug!(CAT, obj = element, "Closed NDI connection");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,13 +220,13 @@ impl Receiver {
|
||||||
timeout: u32,
|
timeout: u32,
|
||||||
max_queue_length: usize,
|
max_queue_length: usize,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
gst::debug!(CAT, obj: element, "Starting NDI connection...");
|
gst::debug!(CAT, obj = element, "Starting NDI connection...");
|
||||||
|
|
||||||
assert!(ndi_name.is_some() || url_address.is_some());
|
assert!(ndi_name.is_some() || url_address.is_some());
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Connecting to NDI source with NDI name '{:?}' and URL/Address {:?}",
|
"Connecting to NDI source with NDI name '{:?}' and URL/Address {:?}",
|
||||||
ndi_name,
|
ndi_name,
|
||||||
url_address,
|
url_address,
|
||||||
|
@ -281,13 +281,13 @@ impl Receiver {
|
||||||
let flushing = {
|
let flushing = {
|
||||||
let queue = (receiver.0.queue.0).0.lock().unwrap();
|
let queue = (receiver.0.queue.0).0.lock().unwrap();
|
||||||
if queue.shutdown {
|
if queue.shutdown {
|
||||||
gst::debug!(CAT, obj: element, "Shutting down");
|
gst::debug!(CAT, obj = element, "Shutting down");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If an error happened in the meantime, just go out of here
|
// If an error happened in the meantime, just go out of here
|
||||||
if queue.error.is_some() {
|
if queue.error.is_some() {
|
||||||
gst::error!(CAT, obj: element, "Error while waiting for connection");
|
gst::error!(CAT, obj = element, "Error while waiting for connection");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ impl Receiver {
|
||||||
|
|
||||||
let res = match recv.capture(50) {
|
let res = match recv.capture(50) {
|
||||||
_ if flushing => {
|
_ if flushing => {
|
||||||
gst::debug!(CAT, obj: element, "Flushing");
|
gst::debug!(CAT, obj = element, "Flushing");
|
||||||
Err(gst::FlowError::Flushing)
|
Err(gst::FlowError::Flushing)
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -314,11 +314,11 @@ impl Receiver {
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
Ok(None) if timeout > 0 && timer.elapsed().as_millis() >= timeout as u128 => {
|
Ok(None) if timeout > 0 && timer.elapsed().as_millis() >= timeout as u128 => {
|
||||||
gst::debug!(CAT, obj: element, "Timed out -- assuming EOS",);
|
gst::debug!(CAT, obj = element, "Timed out -- assuming EOS",);
|
||||||
Err(gst::FlowError::Eos)
|
Err(gst::FlowError::Eos)
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
gst::debug!(CAT, obj: element, "No frame received yet, retry");
|
gst::debug!(CAT, obj = element, "No frame received yet, retry");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Ok(Some(Frame::Video(frame))) => {
|
Ok(Some(Frame::Video(frame))) => {
|
||||||
|
@ -331,7 +331,7 @@ impl Receiver {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Received video frame at timecode {}: {:?}",
|
"Received video frame at timecode {}: {:?}",
|
||||||
(frame.timecode() as u64 * 100).nseconds(),
|
(frame.timecode() as u64 * 100).nseconds(),
|
||||||
frame,
|
frame,
|
||||||
|
@ -356,7 +356,7 @@ impl Receiver {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Received audio frame at timecode {}: {:?}",
|
"Received audio frame at timecode {}: {:?}",
|
||||||
(frame.timecode() as u64 * 100).nseconds(),
|
(frame.timecode() as u64 * 100).nseconds(),
|
||||||
frame,
|
frame,
|
||||||
|
@ -377,7 +377,7 @@ impl Receiver {
|
||||||
let receive_time_real = (glib::real_time() as u64 * 1000).nseconds();
|
let receive_time_real = (glib::real_time() as u64 * 1000).nseconds();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Received metadata frame at timecode {}: {:?}",
|
"Received metadata frame at timecode {}: {:?}",
|
||||||
(frame.timecode() as u64 * 100).nseconds(),
|
(frame.timecode() as u64 * 100).nseconds(),
|
||||||
frame,
|
frame,
|
||||||
|
@ -399,7 +399,7 @@ impl Receiver {
|
||||||
while queue.buffer_queue.len() > receiver.0.max_queue_length {
|
while queue.buffer_queue.len() > receiver.0.max_queue_length {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Dropping old buffer -- queue has {} items",
|
"Dropping old buffer -- queue has {} items",
|
||||||
queue.buffer_queue.len()
|
queue.buffer_queue.len()
|
||||||
);
|
);
|
||||||
|
@ -410,7 +410,7 @@ impl Receiver {
|
||||||
timer = time::Instant::now();
|
timer = time::Instant::now();
|
||||||
}
|
}
|
||||||
Err(gst::FlowError::Eos) => {
|
Err(gst::FlowError::Eos) => {
|
||||||
gst::debug!(CAT, obj: element, "Signalling EOS");
|
gst::debug!(CAT, obj = element, "Signalling EOS");
|
||||||
let mut queue = (receiver.0.queue.0).0.lock().unwrap();
|
let mut queue = (receiver.0.queue.0).0.lock().unwrap();
|
||||||
queue.timeout = true;
|
queue.timeout = true;
|
||||||
(receiver.0.queue.0).1.notify_one();
|
(receiver.0.queue.0).1.notify_one();
|
||||||
|
@ -427,7 +427,7 @@ impl Receiver {
|
||||||
first_video_frame = true;
|
first_video_frame = true;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, obj: element, "Signalling error");
|
gst::error!(CAT, obj = element, "Signalling error");
|
||||||
let mut queue = (receiver.0.queue.0).0.lock().unwrap();
|
let mut queue = (receiver.0.queue.0).0.lock().unwrap();
|
||||||
if queue.error.is_none() {
|
if queue.error.is_none() {
|
||||||
queue.error = Some(err);
|
queue.error = Some(err);
|
||||||
|
|
|
@ -210,13 +210,13 @@ impl NdiSrcDemux {
|
||||||
_pad: &gst::Pad,
|
_pad: &gst::Pad,
|
||||||
mut buffer: gst::Buffer,
|
mut buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(CAT, imp: self, "Handling buffer {:?}", buffer);
|
gst::log!(CAT, imp = self, "Handling buffer {:?}", buffer);
|
||||||
|
|
||||||
let mut meta = buffer
|
let mut meta = buffer
|
||||||
.make_mut()
|
.make_mut()
|
||||||
.meta_mut::<ndisrcmeta::NdiSrcMeta>()
|
.meta_mut::<ndisrcmeta::NdiSrcMeta>()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::error!(CAT, imp: self, "Buffer without NDI source meta");
|
gst::error!(CAT, imp = self, "Buffer without NDI source meta");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ impl NdiSrcDemux {
|
||||||
|
|
||||||
match ndi_buffer {
|
match ndi_buffer {
|
||||||
Buffer::Audio { ref frame, .. } => {
|
Buffer::Audio { ref frame, .. } => {
|
||||||
gst::debug!(CAT, imp: self, "Received audio frame {:?}", frame);
|
gst::debug!(CAT, imp = self, "Received audio frame {:?}", frame);
|
||||||
|
|
||||||
let mut reconfigure = false;
|
let mut reconfigure = false;
|
||||||
let info = self.create_audio_info(frame)?;
|
let info = self.create_audio_info(frame)?;
|
||||||
|
@ -239,7 +239,7 @@ impl NdiSrcDemux {
|
||||||
gst::FlowError::NotNegotiated
|
gst::FlowError::NotNegotiated
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Audio caps changed to {}", caps);
|
gst::debug!(CAT, imp = self, "Audio caps changed to {}", caps);
|
||||||
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
if let AudioInfo::Audio(ref info) = info {
|
if let AudioInfo::Audio(ref info) = info {
|
||||||
|
@ -274,7 +274,7 @@ impl NdiSrcDemux {
|
||||||
srcpad = pad.clone();
|
srcpad = pad.clone();
|
||||||
reconfigure |= pad.check_reconfigure();
|
reconfigure |= pad.check_reconfigure();
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Adding audio pad");
|
gst::debug!(CAT, imp = self, "Adding audio pad");
|
||||||
|
|
||||||
let templ = self.obj().element_class().pad_template("audio").unwrap();
|
let templ = self.obj().element_class().pad_template("audio").unwrap();
|
||||||
let pad = gst::Pad::builder_from_template(&templ)
|
let pad = gst::Pad::builder_from_template(&templ)
|
||||||
|
@ -297,7 +297,7 @@ impl NdiSrcDemux {
|
||||||
.flags(ev.stream_flags())
|
.flags(ev.stream_flags())
|
||||||
.group_id(ev.group_id().unwrap_or_else(|| {
|
.group_id(ev.group_id().unwrap_or_else(|| {
|
||||||
// This can't really happen as ndisrc would provide one!
|
// This can't really happen as ndisrc would provide one!
|
||||||
gst::error!(CAT, imp: self, "Upstream provided no group id");
|
gst::error!(CAT, imp = self, "Upstream provided no group id");
|
||||||
gst::GroupId::next()
|
gst::GroupId::next()
|
||||||
}))
|
}))
|
||||||
.build();
|
.build();
|
||||||
|
@ -351,16 +351,20 @@ impl NdiSrcDemux {
|
||||||
let allowed_caps = srcpad.peer().map(|peer| peer.query_caps(Some(&caps)));
|
let allowed_caps = srcpad.peer().map(|peer| peer.query_caps(Some(&caps)));
|
||||||
state = self.state.lock().unwrap();
|
state = self.state.lock().unwrap();
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Allowed audio caps {allowed_caps:?}");
|
gst::info!(CAT, imp = self, "Allowed audio caps {allowed_caps:?}");
|
||||||
|
|
||||||
state.audio_non_interleaved = allowed_caps
|
state.audio_non_interleaved = allowed_caps
|
||||||
.is_some_and(|allowed_caps| allowed_caps.can_intersect(&caps));
|
.is_some_and(|allowed_caps| allowed_caps.can_intersect(&caps));
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Non-interleaved caps{} supported",
|
"Non-interleaved caps{} supported",
|
||||||
if state.audio_non_interleaved { "" } else { "not" },
|
if state.audio_non_interleaved {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
"not"
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +379,7 @@ impl NdiSrcDemux {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Buffer::Video { ref frame, .. } => {
|
Buffer::Video { ref frame, .. } => {
|
||||||
gst::debug!(CAT, imp: self, "Received video frame {:?}", frame);
|
gst::debug!(CAT, imp = self, "Received video frame {:?}", frame);
|
||||||
|
|
||||||
let mut reconfigure = false;
|
let mut reconfigure = false;
|
||||||
let info = self.create_video_info(frame)?;
|
let info = self.create_video_info(frame)?;
|
||||||
|
@ -393,7 +397,7 @@ impl NdiSrcDemux {
|
||||||
state.ndi_cc_decoder = Some(NDICCMetaDecoder::new(info.width()));
|
state.ndi_cc_decoder = Some(NDICCMetaDecoder::new(info.width()));
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Video caps changed to {}", caps);
|
gst::debug!(CAT, imp = self, "Video caps changed to {}", caps);
|
||||||
state.video_info = Some(info);
|
state.video_info = Some(info);
|
||||||
state.video_caps = Some(caps);
|
state.video_caps = Some(caps);
|
||||||
state.video_buffer_pool = None;
|
state.video_buffer_pool = None;
|
||||||
|
@ -405,7 +409,7 @@ impl NdiSrcDemux {
|
||||||
srcpad = pad.clone();
|
srcpad = pad.clone();
|
||||||
reconfigure |= pad.check_reconfigure();
|
reconfigure |= pad.check_reconfigure();
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Adding video pad");
|
gst::debug!(CAT, imp = self, "Adding video pad");
|
||||||
|
|
||||||
let templ = self.obj().element_class().pad_template("video").unwrap();
|
let templ = self.obj().element_class().pad_template("video").unwrap();
|
||||||
let pad = gst::Pad::builder_from_template(&templ)
|
let pad = gst::Pad::builder_from_template(&templ)
|
||||||
|
@ -428,7 +432,7 @@ impl NdiSrcDemux {
|
||||||
.flags(ev.stream_flags())
|
.flags(ev.stream_flags())
|
||||||
.group_id(ev.group_id().unwrap_or_else(|| {
|
.group_id(ev.group_id().unwrap_or_else(|| {
|
||||||
// This can't really happen as ndisrc would provide one!
|
// This can't really happen as ndisrc would provide one!
|
||||||
gst::error!(CAT, imp: self, "Upstream provided no group id");
|
gst::error!(CAT, imp = self, "Upstream provided no group id");
|
||||||
gst::GroupId::next()
|
gst::GroupId::next()
|
||||||
}))
|
}))
|
||||||
.build();
|
.build();
|
||||||
|
@ -501,13 +505,13 @@ impl NdiSrcDemux {
|
||||||
&frame,
|
&frame,
|
||||||
)
|
)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::debug!(CAT, imp: self, "Flushing, dropping buffer");
|
gst::debug!(CAT, imp = self, "Flushing, dropping buffer");
|
||||||
gst::FlowError::Flushing
|
gst::FlowError::Flushing
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
buffer = self.create_audio_buffer(&state, pts, duration, discont, resync, frame)?;
|
buffer = self.create_audio_buffer(&state, pts, duration, discont, resync, frame)?;
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "Produced audio buffer {:?}", buffer);
|
gst::log!(CAT, imp = self, "Produced audio buffer {:?}", buffer);
|
||||||
}
|
}
|
||||||
Buffer::Video {
|
Buffer::Video {
|
||||||
frame,
|
frame,
|
||||||
|
@ -524,14 +528,14 @@ impl NdiSrcDemux {
|
||||||
&frame,
|
&frame,
|
||||||
)
|
)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::debug!(CAT, imp: self, "Flushing, dropping buffer");
|
gst::debug!(CAT, imp = self, "Flushing, dropping buffer");
|
||||||
gst::FlowError::Flushing
|
gst::FlowError::Flushing
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
buffer =
|
buffer =
|
||||||
self.create_video_buffer(&mut state, pts, duration, discont, resync, frame)?;
|
self.create_video_buffer(&mut state, pts, duration, discont, resync, frame)?;
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "Produced video buffer {:?}", buffer);
|
gst::log!(CAT, imp = self, "Produced video buffer {:?}", buffer);
|
||||||
}
|
}
|
||||||
Buffer::Metadata { frame, .. } => {
|
Buffer::Metadata { frame, .. } => {
|
||||||
// Only closed caption meta are supported,
|
// Only closed caption meta are supported,
|
||||||
|
@ -553,7 +557,7 @@ impl NdiSrcDemux {
|
||||||
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "Handling event {:?}", event);
|
gst::log!(CAT, imp = self, "Handling event {:?}", event);
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::StreamStart(ev) => {
|
EventView::StreamStart(ev) => {
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
|
@ -576,7 +580,7 @@ impl NdiSrcDemux {
|
||||||
.flags(ev.stream_flags())
|
.flags(ev.stream_flags())
|
||||||
.group_id(ev.group_id().unwrap_or_else(|| {
|
.group_id(ev.group_id().unwrap_or_else(|| {
|
||||||
// This can't really happen as ndisrc would provide one!
|
// This can't really happen as ndisrc would provide one!
|
||||||
gst::error!(CAT, imp: self, "Upstream provided no group id");
|
gst::error!(CAT, imp = self, "Upstream provided no group id");
|
||||||
gst::GroupId::next()
|
gst::GroupId::next()
|
||||||
}))
|
}))
|
||||||
.build();
|
.build();
|
||||||
|
@ -626,7 +630,7 @@ impl NdiSrcDemux {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Received frame with timecode {}, timestamp {}, duration {}, receive time {}, local time now {}",
|
"Received frame with timecode {}, timestamp {}, duration {}, receive time {}, local time now {}",
|
||||||
timecode,
|
timecode,
|
||||||
timestamp.display(),
|
timestamp.display(),
|
||||||
|
@ -653,7 +657,7 @@ impl NdiSrcDemux {
|
||||||
TimestampMode::ReceiveTimeTimecode => match res_timecode {
|
TimestampMode::ReceiveTimeTimecode => match res_timecode {
|
||||||
Some((pts, duration, discont)) => (pts, duration, discont),
|
Some((pts, duration, discont)) => (pts, duration, discont),
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(CAT, imp: self, "Can't calculate timestamp");
|
gst::warning!(CAT, imp = self, "Can't calculate timestamp");
|
||||||
(receive_time_gst, duration, false)
|
(receive_time_gst, duration, false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -661,7 +665,7 @@ impl NdiSrcDemux {
|
||||||
Some((pts, duration, discont)) => (pts, duration, discont),
|
Some((pts, duration, discont)) => (pts, duration, discont),
|
||||||
None => {
|
None => {
|
||||||
if timestamp.is_some() {
|
if timestamp.is_some() {
|
||||||
gst::warning!(CAT, imp: self, "Can't calculate timestamp");
|
gst::warning!(CAT, imp = self, "Can't calculate timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
(receive_time_gst, duration, false)
|
(receive_time_gst, duration, false)
|
||||||
|
@ -694,7 +698,7 @@ impl NdiSrcDemux {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Calculated PTS {}, duration {}",
|
"Calculated PTS {}, duration {}",
|
||||||
pts.display(),
|
pts.display(),
|
||||||
duration.display(),
|
duration.display(),
|
||||||
|
@ -879,7 +883,7 @@ impl NdiSrcDemux {
|
||||||
let compressed_packet = video_frame.compressed_packet().ok_or_else(|| {
|
let compressed_packet = video_frame.compressed_packet().ok_or_else(|| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Video packet doesn't have compressed packet start"
|
"Video packet doesn't have compressed packet start"
|
||||||
);
|
);
|
||||||
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid video packet"]);
|
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid video packet"]);
|
||||||
|
@ -888,7 +892,7 @@ impl NdiSrcDemux {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if compressed_packet.fourcc != ndisys::NDIlib_compressed_FourCC_type_H264 {
|
if compressed_packet.fourcc != ndisys::NDIlib_compressed_FourCC_type_H264 {
|
||||||
gst::error!(CAT, imp: self, "Non-H264 video packet");
|
gst::error!(CAT, imp = self, "Non-H264 video packet");
|
||||||
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid video packet"]);
|
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid video packet"]);
|
||||||
|
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
|
@ -917,7 +921,7 @@ impl NdiSrcDemux {
|
||||||
let compressed_packet = video_frame.compressed_packet().ok_or_else(|| {
|
let compressed_packet = video_frame.compressed_packet().ok_or_else(|| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Video packet doesn't have compressed packet start"
|
"Video packet doesn't have compressed packet start"
|
||||||
);
|
);
|
||||||
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid video packet"]);
|
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid video packet"]);
|
||||||
|
@ -926,7 +930,7 @@ impl NdiSrcDemux {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if compressed_packet.fourcc != ndisys::NDIlib_compressed_FourCC_type_HEVC {
|
if compressed_packet.fourcc != ndisys::NDIlib_compressed_FourCC_type_HEVC {
|
||||||
gst::error!(CAT, imp: self, "Non-H265 video packet");
|
gst::error!(CAT, imp = self, "Non-H265 video packet");
|
||||||
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid video packet"]);
|
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid video packet"]);
|
||||||
|
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
|
@ -975,7 +979,7 @@ impl NdiSrcDemux {
|
||||||
if let Some(meta) = metadata.metadata() {
|
if let Some(meta) = metadata.metadata() {
|
||||||
let res = ndi_cc_decoder.decode(meta);
|
let res = ndi_cc_decoder.decode(meta);
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::debug!(CAT, imp: self, "Failed to parse NDI metadata: {err}");
|
gst::debug!(CAT, imp = self, "Failed to parse NDI metadata: {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -987,7 +991,11 @@ impl NdiSrcDemux {
|
||||||
captions.extend_from_slice(&c);
|
captions.extend_from_slice(&c);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::debug!(CAT, imp: self, "Failed to parse NDI video frame metadata: {err}");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse NDI video frame metadata: {err}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1093,7 +1101,11 @@ impl NdiSrcDemux {
|
||||||
if src_stride == info.stride()[0] as usize {
|
if src_stride == info.stride()[0] as usize {
|
||||||
Ok(gst::Buffer::from_slice(WrappedVideoFrame(video_frame)))
|
Ok(gst::Buffer::from_slice(WrappedVideoFrame(video_frame)))
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(gst::CAT_PERFORMANCE, imp: self, "Copying raw video frame");
|
gst::debug!(
|
||||||
|
gst::CAT_PERFORMANCE,
|
||||||
|
imp = self,
|
||||||
|
"Copying raw video frame"
|
||||||
|
);
|
||||||
|
|
||||||
let src = video_frame.data().ok_or(gst::FlowError::Error)?;
|
let src = video_frame.data().ok_or(gst::FlowError::Error)?;
|
||||||
|
|
||||||
|
@ -1117,7 +1129,11 @@ impl NdiSrcDemux {
|
||||||
let plane_size = video_frame.yres() as usize * src_stride;
|
let plane_size = video_frame.yres() as usize * src_stride;
|
||||||
|
|
||||||
if src.len() < plane_size || src_stride < line_bytes {
|
if src.len() < plane_size || src_stride < line_bytes {
|
||||||
gst::error!(CAT, imp: self, "Video packet has wrong stride or size");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Video packet has wrong stride or size"
|
||||||
|
);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::StreamError::Format,
|
gst::StreamError::Format,
|
||||||
|
@ -1142,7 +1158,11 @@ impl NdiSrcDemux {
|
||||||
if src_stride == info.stride()[0] as usize {
|
if src_stride == info.stride()[0] as usize {
|
||||||
Ok(gst::Buffer::from_slice(WrappedVideoFrame(video_frame)))
|
Ok(gst::Buffer::from_slice(WrappedVideoFrame(video_frame)))
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(gst::CAT_PERFORMANCE, imp: self, "Copying raw video frame");
|
gst::debug!(
|
||||||
|
gst::CAT_PERFORMANCE,
|
||||||
|
imp = self,
|
||||||
|
"Copying raw video frame"
|
||||||
|
);
|
||||||
|
|
||||||
let src = video_frame.data().ok_or(gst::FlowError::Error)?;
|
let src = video_frame.data().ok_or(gst::FlowError::Error)?;
|
||||||
|
|
||||||
|
@ -1159,7 +1179,11 @@ impl NdiSrcDemux {
|
||||||
let plane_size = video_frame.yres() as usize * src_stride;
|
let plane_size = video_frame.yres() as usize * src_stride;
|
||||||
|
|
||||||
if src.len() < 2 * plane_size || src_stride < line_bytes {
|
if src.len() < 2 * plane_size || src_stride < line_bytes {
|
||||||
gst::error!(CAT, imp: self, "Video packet has wrong stride or size");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Video packet has wrong stride or size"
|
||||||
|
);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::StreamError::Format,
|
gst::StreamError::Format,
|
||||||
|
@ -1208,7 +1232,11 @@ impl NdiSrcDemux {
|
||||||
{
|
{
|
||||||
Ok(gst::Buffer::from_slice(WrappedVideoFrame(video_frame)))
|
Ok(gst::Buffer::from_slice(WrappedVideoFrame(video_frame)))
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(gst::CAT_PERFORMANCE, imp: self, "Copying raw video frame");
|
gst::debug!(
|
||||||
|
gst::CAT_PERFORMANCE,
|
||||||
|
imp = self,
|
||||||
|
"Copying raw video frame"
|
||||||
|
);
|
||||||
|
|
||||||
let src = video_frame.data().ok_or(gst::FlowError::Error)?;
|
let src = video_frame.data().ok_or(gst::FlowError::Error)?;
|
||||||
|
|
||||||
|
@ -1228,7 +1256,11 @@ impl NdiSrcDemux {
|
||||||
let plane_size1 = ((video_frame.yres() as usize + 1) / 2) * src_stride1;
|
let plane_size1 = ((video_frame.yres() as usize + 1) / 2) * src_stride1;
|
||||||
|
|
||||||
if src.len() < plane_size + 2 * plane_size1 || src_stride < line_bytes {
|
if src.len() < plane_size + 2 * plane_size1 || src_stride < line_bytes {
|
||||||
gst::error!(CAT, imp: self, "Video packet has wrong stride or size");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Video packet has wrong stride or size"
|
||||||
|
);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::StreamError::Format,
|
gst::StreamError::Format,
|
||||||
|
@ -1294,7 +1326,7 @@ impl NdiSrcDemux {
|
||||||
let compressed_packet = video_frame.compressed_packet().ok_or_else(|| {
|
let compressed_packet = video_frame.compressed_packet().ok_or_else(|| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Video packet doesn't have compressed packet start"
|
"Video packet doesn't have compressed packet start"
|
||||||
);
|
);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
|
@ -1388,7 +1420,7 @@ impl NdiSrcDemux {
|
||||||
let compressed_packet = audio_frame.compressed_packet().ok_or_else(|| {
|
let compressed_packet = audio_frame.compressed_packet().ok_or_else(|| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Audio packet doesn't have compressed packet start"
|
"Audio packet doesn't have compressed packet start"
|
||||||
);
|
);
|
||||||
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid audio packet"]);
|
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid audio packet"]);
|
||||||
|
@ -1397,7 +1429,7 @@ impl NdiSrcDemux {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if compressed_packet.fourcc != ndisys::NDIlib_compressed_FourCC_type_AAC {
|
if compressed_packet.fourcc != ndisys::NDIlib_compressed_FourCC_type_AAC {
|
||||||
gst::error!(CAT, imp: self, "Non-AAC audio packet");
|
gst::error!(CAT, imp = self, "Non-AAC audio packet");
|
||||||
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid audio packet"]);
|
gst::element_imp_error!(self, gst::StreamError::Format, ["Invalid audio packet"]);
|
||||||
|
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
|
@ -1462,7 +1494,7 @@ impl NdiSrcDemux {
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(gst::CAT_PERFORMANCE, imp: self, "Copying raw audio frame");
|
gst::debug!(gst::CAT_PERFORMANCE, imp = self, "Copying raw audio frame");
|
||||||
|
|
||||||
let src = audio_frame.data().ok_or(gst::FlowError::Error)?;
|
let src = audio_frame.data().ok_or(gst::FlowError::Error)?;
|
||||||
let mut buffer = gst::Buffer::with_size(buff_size).unwrap();
|
let mut buffer = gst::Buffer::with_size(buff_size).unwrap();
|
||||||
|
@ -1536,7 +1568,7 @@ impl NdiSrcDemux {
|
||||||
#[cfg(feature = "advanced-sdk")]
|
#[cfg(feature = "advanced-sdk")]
|
||||||
AudioInfo::Opus { .. } => {
|
AudioInfo::Opus { .. } => {
|
||||||
let data = audio_frame.data().ok_or_else(|| {
|
let data = audio_frame.data().ok_or_else(|| {
|
||||||
gst::error!(CAT, imp: self, "Audio packet has no data");
|
gst::error!(CAT, imp = self, "Audio packet has no data");
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::StreamError::Format,
|
gst::StreamError::Format,
|
||||||
|
@ -1553,7 +1585,7 @@ impl NdiSrcDemux {
|
||||||
let compressed_packet = audio_frame.compressed_packet().ok_or_else(|| {
|
let compressed_packet = audio_frame.compressed_packet().ok_or_else(|| {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Audio packet doesn't have compressed packet start"
|
"Audio packet doesn't have compressed packet start"
|
||||||
);
|
);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
|
@ -1798,7 +1830,7 @@ impl Observations {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Local time {}, remote time {}, slope correct {}/{}",
|
"Local time {}, remote time {}, slope correct {}/{}",
|
||||||
local_time.nseconds(),
|
local_time.nseconds(),
|
||||||
remote_time.nseconds(),
|
remote_time.nseconds(),
|
||||||
|
@ -1832,7 +1864,7 @@ impl Observations {
|
||||||
_ => {
|
_ => {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Initializing base time: local {}, remote {}",
|
"Initializing base time: local {}, remote {}",
|
||||||
local_time.nseconds(),
|
local_time.nseconds(),
|
||||||
remote_time.nseconds(),
|
remote_time.nseconds(),
|
||||||
|
@ -1880,7 +1912,7 @@ impl Observations {
|
||||||
if !(0.5..1.5).contains(&scaled_slope) {
|
if !(0.5..1.5).contains(&scaled_slope) {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Too small/big slope {}, resetting",
|
"Too small/big slope {}, resetting",
|
||||||
scaled_slope
|
scaled_slope
|
||||||
);
|
);
|
||||||
|
@ -1921,7 +1953,7 @@ impl Observations {
|
||||||
.mul_div_round(inner.slope_correction.0, inner.slope_correction.1)?;
|
.mul_div_round(inner.slope_correction.0, inner.slope_correction.1)?;
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Initializing base time: local {}, remote {}, slope correction {}/{}",
|
"Initializing base time: local {}, remote {}, slope correction {}/{}",
|
||||||
local_time.nseconds(),
|
local_time.nseconds(),
|
||||||
remote_time.nseconds(),
|
remote_time.nseconds(),
|
||||||
|
@ -1942,7 +1974,7 @@ impl Observations {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Local diff {}, remote diff {}, delta {}",
|
"Local diff {}, remote diff {}, delta {}",
|
||||||
local_diff.nseconds(),
|
local_diff.nseconds(),
|
||||||
remote_diff.nseconds(),
|
remote_diff.nseconds(),
|
||||||
|
@ -1954,7 +1986,7 @@ impl Observations {
|
||||||
{
|
{
|
||||||
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
|
inner.skew
|
||||||
|
@ -1964,7 +1996,7 @@ impl Observations {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Initializing base time: local {}, remote {}",
|
"Initializing base time: local {}, remote {}",
|
||||||
local_time.nseconds(),
|
local_time.nseconds(),
|
||||||
remote_time.nseconds(),
|
remote_time.nseconds(),
|
||||||
|
@ -2018,12 +2050,12 @@ impl Observations {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Skew {}, min delta {}",
|
"Skew {}, min delta {}",
|
||||||
inner.skew,
|
inner.skew,
|
||||||
inner.min_delta
|
inner.min_delta
|
||||||
);
|
);
|
||||||
gst::trace!(CAT, obj: element, "Outputting {}", out_time.nseconds());
|
gst::trace!(CAT, obj = element, "Outputting {}", out_time.nseconds());
|
||||||
|
|
||||||
Some((out_time.nseconds(), duration, false))
|
Some((out_time.nseconds(), duration, false))
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ impl ElementImpl for OnvifMetadataCombiner {
|
||||||
) -> Option<gst::Pad> {
|
) -> Option<gst::Pad> {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"onvifmetadatacombiner doesn't expose request pads"
|
"onvifmetadatacombiner doesn't expose request pads"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ impl ElementImpl for OnvifMetadataCombiner {
|
||||||
fn release_pad(&self, _pad: &gst::Pad) {
|
fn release_pad(&self, _pad: &gst::Pad) {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"onvifmetadatacombiner doesn't expose request pads"
|
"onvifmetadatacombiner doesn't expose request pads"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ impl OnvifMetadataCombiner {
|
||||||
if meta_ts <= end {
|
if meta_ts <= end {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Consuming meta buffer at {} before the media end timestamp {}",
|
"Consuming meta buffer at {} before the media end timestamp {}",
|
||||||
meta_ts,
|
meta_ts,
|
||||||
end
|
end
|
||||||
|
@ -182,7 +182,7 @@ impl OnvifMetadataCombiner {
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Consumed all meta buffers before the media end timestamp {}",
|
"Consumed all meta buffers before the media end timestamp {}",
|
||||||
end
|
end
|
||||||
);
|
);
|
||||||
|
@ -192,9 +192,9 @@ impl OnvifMetadataCombiner {
|
||||||
|
|
||||||
let is_eos = self.meta_sink_pad.is_eos();
|
let is_eos = self.meta_sink_pad.is_eos();
|
||||||
if is_eos {
|
if is_eos {
|
||||||
gst::debug!(CAT, imp: self, "Meta pad is EOS");
|
gst::debug!(CAT, imp = self, "Meta pad is EOS");
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, imp: self, "Need more meta until time {}", end);
|
gst::trace!(CAT, imp = self, "Need more meta until time {}", end);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(is_eos)
|
Ok(is_eos)
|
||||||
|
@ -209,7 +209,7 @@ impl OnvifMetadataCombiner {
|
||||||
Some(duration) => {
|
Some(duration) => {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Current media buffer has a duration, using it: {}",
|
"Current media buffer has a duration, using it: {}",
|
||||||
duration
|
duration
|
||||||
);
|
);
|
||||||
|
@ -223,7 +223,7 @@ impl OnvifMetadataCombiner {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"calculated duration for current media buffer from next buffer: {}",
|
"calculated duration for current media buffer from next buffer: {}",
|
||||||
duration
|
duration
|
||||||
);
|
);
|
||||||
|
@ -233,7 +233,7 @@ impl OnvifMetadataCombiner {
|
||||||
None => {
|
None => {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"could not calculate duration for current media buffer"
|
"could not calculate duration for current media buffer"
|
||||||
);
|
);
|
||||||
Some(gst::ClockTime::ZERO)
|
Some(gst::ClockTime::ZERO)
|
||||||
|
@ -242,14 +242,14 @@ impl OnvifMetadataCombiner {
|
||||||
} else if timeout {
|
} else if timeout {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"could not calculate duration for current media buffer"
|
"could not calculate duration for current media buffer"
|
||||||
);
|
);
|
||||||
Some(gst::ClockTime::ZERO)
|
Some(gst::ClockTime::ZERO)
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"No next buffer to peek at yet to calculate duration"
|
"No next buffer to peek at yet to calculate duration"
|
||||||
);
|
);
|
||||||
None
|
None
|
||||||
|
@ -273,7 +273,7 @@ impl OnvifMetadataCombiner {
|
||||||
{
|
{
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Handling media buffer with reference timestamp {}",
|
"Handling media buffer with reference timestamp {}",
|
||||||
current_media_start
|
current_media_start
|
||||||
);
|
);
|
||||||
|
@ -284,7 +284,7 @@ impl OnvifMetadataCombiner {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Consuming meta for media buffer from {}-{}",
|
"Consuming meta for media buffer from {}-{}",
|
||||||
current_media_start,
|
current_media_start,
|
||||||
end
|
end
|
||||||
|
@ -293,7 +293,7 @@ impl OnvifMetadataCombiner {
|
||||||
if self.consume_meta(state, end)? {
|
if self.consume_meta(state, end)? {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Consumed all meta for media buffer from {}-{}",
|
"Consumed all meta for media buffer from {}-{}",
|
||||||
current_media_start,
|
current_media_start,
|
||||||
end
|
end
|
||||||
|
@ -302,7 +302,7 @@ impl OnvifMetadataCombiner {
|
||||||
} else if timeout {
|
} else if timeout {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Timed out but did not receive all meta for media buffer from {}-{} yet",
|
"Timed out but did not receive all meta for media buffer from {}-{} yet",
|
||||||
current_media_start,
|
current_media_start,
|
||||||
end
|
end
|
||||||
|
@ -311,7 +311,7 @@ impl OnvifMetadataCombiner {
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Waiting for more meta for media buffer from {}-{}",
|
"Waiting for more meta for media buffer from {}-{}",
|
||||||
current_media_start,
|
current_media_start,
|
||||||
end
|
end
|
||||||
|
@ -323,7 +323,7 @@ impl OnvifMetadataCombiner {
|
||||||
None => {
|
None => {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Can't calculate media buffer duration yet, waiting for next"
|
"Can't calculate media buffer duration yet, waiting for next"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -334,14 +334,14 @@ impl OnvifMetadataCombiner {
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Returning media buffer without reference timestamp"
|
"Returning media buffer without reference timestamp"
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Some(current_media_buffer))
|
Ok(Some(current_media_buffer))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, imp: self, "No media buffer queued currently");
|
gst::trace!(CAT, imp = self, "No media buffer queued currently");
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,7 @@ impl OnvifMetadataCombiner {
|
||||||
|
|
||||||
impl AggregatorImpl for OnvifMetadataCombiner {
|
impl AggregatorImpl for OnvifMetadataCombiner {
|
||||||
fn aggregate(&self, timeout: bool) -> Result<gst::FlowSuccess, gst::FlowError> {
|
fn aggregate(&self, timeout: bool) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::trace!(CAT, imp: self, "aggregate, timeout: {}", timeout);
|
gst::trace!(CAT, imp = self, "aggregate, timeout: {}", timeout);
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
|
@ -378,16 +378,16 @@ impl AggregatorImpl for OnvifMetadataCombiner {
|
||||||
.pts()
|
.pts()
|
||||||
.opt_add(buffer.duration().unwrap_or(gst::ClockTime::ZERO));
|
.opt_add(buffer.duration().unwrap_or(gst::ClockTime::ZERO));
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "Updating position: {:?}", position);
|
gst::log!(CAT, imp = self, "Updating position: {:?}", position);
|
||||||
|
|
||||||
self.obj().set_position(position);
|
self.obj().set_position(position);
|
||||||
|
|
||||||
self.finish_buffer(buffer)
|
self.finish_buffer(buffer)
|
||||||
} else if self.media_sink_pad.is_eos() {
|
} else if self.media_sink_pad.is_eos() {
|
||||||
gst::debug!(CAT, imp: self, "EOS");
|
gst::debug!(CAT, imp = self, "EOS");
|
||||||
Err(gst::FlowError::Eos)
|
Err(gst::FlowError::Eos)
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, imp: self, "Need more data");
|
gst::trace!(CAT, imp = self, "Need more data");
|
||||||
Err(AGGREGATOR_FLOW_NEED_DATA)
|
Err(AGGREGATOR_FLOW_NEED_DATA)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,7 @@ impl AggregatorImpl for OnvifMetadataCombiner {
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Caps(e) => {
|
EventView::Caps(e) => {
|
||||||
if aggregator_pad.upcast_ref::<gst::Pad>() == &self.media_sink_pad {
|
if aggregator_pad.upcast_ref::<gst::Pad>() == &self.media_sink_pad {
|
||||||
gst::info!(CAT, imp: self, "Pushing caps {}", e.caps());
|
gst::info!(CAT, imp = self, "Pushing caps {}", e.caps());
|
||||||
self.obj().set_src_caps(&e.caps_owned());
|
self.obj().set_src_caps(&e.caps_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ impl RTPBaseDepayloadImpl for OnvifMetadataDepay {
|
||||||
.flags()
|
.flags()
|
||||||
.contains(gst::BufferFlags::DISCONT)
|
.contains(gst::BufferFlags::DISCONT)
|
||||||
{
|
{
|
||||||
gst::debug!(CAT, imp: self, "processing discont RTP buffer");
|
gst::debug!(CAT, imp = self, "processing discont RTP buffer");
|
||||||
state.adapter.clear();
|
state.adapter.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,12 @@ impl RTPBaseDepayloadImpl for OnvifMetadataDepay {
|
||||||
let utf8 = match std::str::from_utf8(map.as_ref()) {
|
let utf8 = match std::str::from_utf8(map.as_ref()) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Failed to decode payload as UTF-8: {}", err);
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to decode payload as UTF-8: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -178,7 +183,7 @@ impl RTPBaseDepayloadImpl for OnvifMetadataDepay {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Invalid XML in payload: {}", err);
|
gst::warning!(CAT, imp = self, "Invalid XML in payload: {}", err);
|
||||||
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +197,7 @@ impl RTPBaseDepayloadImpl for OnvifMetadataDepay {
|
||||||
if !forward {
|
if !forward {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"document must start with tt:MetadataStream element",
|
"document must start with tt:MetadataStream element",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ impl OnvifMetadataOverlay {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"upstream has meta: {}, downstream accepts meta: {}",
|
"upstream has meta: {}, downstream accepts meta: {}",
|
||||||
upstream_has_meta,
|
upstream_has_meta,
|
||||||
downstream_accepts_meta
|
downstream_accepts_meta
|
||||||
|
@ -133,7 +133,7 @@ impl OnvifMetadataOverlay {
|
||||||
.find_allocation_meta::<gst_video::VideoOverlayCompositionMeta>()
|
.find_allocation_meta::<gst_video::VideoOverlayCompositionMeta>()
|
||||||
.is_some();
|
.is_some();
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "attach meta: {}", attach);
|
gst::debug!(CAT, imp = self, "attach meta: {}", attach);
|
||||||
|
|
||||||
self.state.lock().unwrap().attach = attach;
|
self.state.lock().unwrap().attach = attach;
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ impl OnvifMetadataOverlay {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Rendering shape with tag {:?} x {} y {} width {} height {}",
|
"Rendering shape with tag {:?} x {} y {} width {} height {}",
|
||||||
shape.tag,
|
shape.tag,
|
||||||
shape.x,
|
shape.x,
|
||||||
|
@ -334,7 +334,7 @@ impl OnvifMetadataOverlay {
|
||||||
) {
|
) {
|
||||||
Some(ret) => ret,
|
Some(ret) => ret,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, imp: self, "Failed to render buffer");
|
gst::error!(CAT, imp = self, "Failed to render buffer");
|
||||||
state.composition = None;
|
state.composition = None;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ impl OnvifMetadataOverlay {
|
||||||
pad: &gst::Pad,
|
pad: &gst::Pad,
|
||||||
mut buffer: gst::Buffer,
|
mut buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::trace!(CAT, obj: pad, "Handling buffer {:?}", buffer);
|
gst::trace!(CAT, obj = pad, "Handling buffer {:?}", buffer);
|
||||||
|
|
||||||
if self.srcpad.check_reconfigure() {
|
if self.srcpad.check_reconfigure() {
|
||||||
if let Err(err) = self.negotiate() {
|
if let Err(err) = self.negotiate() {
|
||||||
|
@ -384,7 +384,7 @@ impl OnvifMetadataOverlay {
|
||||||
let mut shapes: Vec<Shape> = Vec::new();
|
let mut shapes: Vec<Shape> = Vec::new();
|
||||||
|
|
||||||
if let Ok(frames) = s.get::<gst::BufferList>("frames") {
|
if let Ok(frames) = s.get::<gst::BufferList>("frames") {
|
||||||
gst::log!(CAT, imp: self, "Overlaying {} frames", frames.len());
|
gst::log!(CAT, imp = self, "Overlaying {} frames", frames.len());
|
||||||
|
|
||||||
// Metadata for multiple frames may be attached to this frame, either because:
|
// Metadata for multiple frames may be attached to this frame, either because:
|
||||||
//
|
//
|
||||||
|
@ -451,14 +451,14 @@ impl OnvifMetadataOverlay {
|
||||||
== Some(crate::ONVIF_METADATA_SCHEMA)
|
== Some(crate::ONVIF_METADATA_SCHEMA)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
gst::trace!(CAT, imp: self, "Handling object {:?}", object);
|
gst::trace!(CAT, imp = self, "Handling object {:?}", object);
|
||||||
|
|
||||||
let object_id = match object.attributes.get("ObjectId") {
|
let object_id = match object.attributes.get("ObjectId") {
|
||||||
Some(id) => id.to_string(),
|
Some(id) => id.to_string(),
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"XML Object with no ObjectId"
|
"XML Object with no ObjectId"
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
@ -503,7 +503,7 @@ impl OnvifMetadataOverlay {
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"XML Shape with no BoundingBox"
|
"XML Shape with no BoundingBox"
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
@ -519,7 +519,7 @@ impl OnvifMetadataOverlay {
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"BoundingBox with no left attribute"
|
"BoundingBox with no left attribute"
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
@ -535,7 +535,7 @@ impl OnvifMetadataOverlay {
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"BoundingBox with no right attribute"
|
"BoundingBox with no right attribute"
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
@ -551,7 +551,7 @@ impl OnvifMetadataOverlay {
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"BoundingBox with no top attribute"
|
"BoundingBox with no top attribute"
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
@ -567,7 +567,7 @@ impl OnvifMetadataOverlay {
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"BoundingBox with no bottom attribute"
|
"BoundingBox with no bottom attribute"
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
@ -603,7 +603,7 @@ impl OnvifMetadataOverlay {
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Point with no x attribute"
|
"Point with no x attribute"
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
@ -619,7 +619,7 @@ impl OnvifMetadataOverlay {
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Point with no y attribute"
|
"Point with no y attribute"
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
|
@ -669,7 +669,7 @@ impl OnvifMetadataOverlay {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if composition.blend(&mut frame).is_err() {
|
if composition.blend(&mut frame).is_err() {
|
||||||
gst::error!(CAT, obj: pad, "Failed to blend composition");
|
gst::error!(CAT, obj = pad, "Failed to blend composition");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -681,7 +681,7 @@ impl OnvifMetadataOverlay {
|
||||||
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
use gst::EventView;
|
use gst::EventView;
|
||||||
|
|
||||||
gst::log!(CAT, obj: pad, "Handling event {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling event {:?}", event);
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
EventView::Caps(c) => {
|
EventView::Caps(c) => {
|
||||||
|
@ -840,7 +840,7 @@ impl ElementImpl for OnvifMetadataOverlay {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::ReadyToPaused | gst::StateChange::PausedToReady => {
|
gst::StateChange::ReadyToPaused | gst::StateChange::PausedToReady => {
|
||||||
|
|
|
@ -177,7 +177,7 @@ impl OnvifMetadataParse {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Handling buffer {:?} with UTC time {}",
|
"Handling buffer {:?} with UTC time {}",
|
||||||
buffer,
|
buffer,
|
||||||
crate::lookup_reference_timestamp(&buffer).display()
|
crate::lookup_reference_timestamp(&buffer).display()
|
||||||
|
@ -188,7 +188,7 @@ impl OnvifMetadataParse {
|
||||||
let pts = match buffer.pts() {
|
let pts = match buffer.pts() {
|
||||||
Some(pts) => pts,
|
Some(pts) => pts,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, obj: pad, "Need buffers with PTS");
|
gst::error!(CAT, obj = pad, "Need buffers with PTS");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -200,7 +200,7 @@ impl OnvifMetadataParse {
|
||||||
.position()
|
.position()
|
||||||
.map_or(true, |position| position < pts)
|
.map_or(true, |position| position < pts)
|
||||||
{
|
{
|
||||||
gst::trace!(CAT, imp: self, "Input position updated to {}", pts);
|
gst::trace!(CAT, imp = self, "Input position updated to {}", pts);
|
||||||
state.in_segment.set_position(pts);
|
state.in_segment.set_position(pts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ impl OnvifMetadataParse {
|
||||||
None => {
|
None => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Too big running time difference between initial running time {:?} and current running time {:?}",
|
"Too big running time difference between initial running time {:?} and current running time {:?}",
|
||||||
initial_running_time,
|
initial_running_time,
|
||||||
running_time,
|
running_time,
|
||||||
|
@ -243,7 +243,7 @@ impl OnvifMetadataParse {
|
||||||
Some(Negative(initial_utc_time)) => {
|
Some(Negative(initial_utc_time)) => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Initial UTC time is negative: -{}, dropping buffer",
|
"Initial UTC time is negative: -{}, dropping buffer",
|
||||||
initial_utc_time
|
initial_utc_time
|
||||||
);
|
);
|
||||||
|
@ -254,7 +254,7 @@ impl OnvifMetadataParse {
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Can't calculate initial UTC time, dropping buffer"
|
"Can't calculate initial UTC time, dropping buffer"
|
||||||
);
|
);
|
||||||
state.pre_queued_buffers.remove(idx.unwrap());
|
state.pre_queued_buffers.remove(idx.unwrap());
|
||||||
|
@ -267,7 +267,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Calculated initial UTC/running time mapping: {}/{:?}",
|
"Calculated initial UTC/running time mapping: {}/{:?}",
|
||||||
initial_utc_time,
|
initial_utc_time,
|
||||||
initial_running_time
|
initial_running_time
|
||||||
|
@ -294,7 +294,7 @@ impl OnvifMetadataParse {
|
||||||
if running_time.saturating_sub(front_running_time) >= state.configured_latency {
|
if running_time.saturating_sub(front_running_time) >= state.configured_latency {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Received no UTC time in the first {}",
|
"Received no UTC time in the first {}",
|
||||||
state.configured_latency
|
state.configured_latency
|
||||||
);
|
);
|
||||||
|
@ -310,7 +310,7 @@ impl OnvifMetadataParse {
|
||||||
self.queue(&mut state, buffer, running_time)?;
|
self.queue(&mut state, buffer, running_time)?;
|
||||||
let res = self.wake_up_output(state);
|
let res = self.wake_up_output(state);
|
||||||
|
|
||||||
gst::trace!(CAT, obj: pad, "Returning {:?}", res);
|
gst::trace!(CAT, obj = pad, "Returning {:?}", res);
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -373,8 +373,9 @@ impl OnvifMetadataParse {
|
||||||
.and_then(|ns| ns.nseconds().checked_add(crate::PRIME_EPOCH_OFFSET));
|
.and_then(|ns| ns.nseconds().checked_add(crate::PRIME_EPOCH_OFFSET));
|
||||||
|
|
||||||
let Some(dt_unix_ns) = dt_unix_ns else {
|
let Some(dt_unix_ns) = dt_unix_ns else {
|
||||||
gst::warning!(CAT,
|
gst::warning!(
|
||||||
imp: self,
|
CAT,
|
||||||
|
imp = self,
|
||||||
"Frame with unrepresentable UTC time {}",
|
"Frame with unrepresentable UTC time {}",
|
||||||
dt,
|
dt,
|
||||||
);
|
);
|
||||||
|
@ -383,7 +384,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Queueing frame with UTC time {}",
|
"Queueing frame with UTC time {}",
|
||||||
dt_unix_ns
|
dt_unix_ns
|
||||||
);
|
);
|
||||||
|
@ -435,7 +436,7 @@ impl OnvifMetadataParse {
|
||||||
if state.upstream_latency.is_none() {
|
if state.upstream_latency.is_none() {
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Have no upstream latency yet, querying");
|
gst::debug!(CAT, imp = self, "Have no upstream latency yet, querying");
|
||||||
let mut q = gst::query::Latency::new();
|
let mut q = gst::query::Latency::new();
|
||||||
let res = self.sinkpad.peer_query(&mut q);
|
let res = self.sinkpad.peer_query(&mut q);
|
||||||
|
|
||||||
|
@ -446,7 +447,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Latency query response: live {} min {} max {}",
|
"Latency query response: live {} min {} max {}",
|
||||||
live,
|
live,
|
||||||
min,
|
min,
|
||||||
|
@ -457,7 +458,7 @@ impl OnvifMetadataParse {
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Can't query upstream latency -- assuming non-live upstream for now"
|
"Can't query upstream latency -- assuming non-live upstream for now"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -465,7 +466,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
// Consider waking up the source element thread
|
// Consider waking up the source element thread
|
||||||
if self.sinkpad.pad_flags().contains(gst::PadFlags::EOS) {
|
if self.sinkpad.pad_flags().contains(gst::PadFlags::EOS) {
|
||||||
gst::trace!(CAT, imp: self, "Scheduling immediate wakeup at EOS",);
|
gst::trace!(CAT, imp = self, "Scheduling immediate wakeup at EOS",);
|
||||||
|
|
||||||
if let Some(clock_wait) = state.clock_wait.take() {
|
if let Some(clock_wait) = state.clock_wait.take() {
|
||||||
clock_wait.unschedule();
|
clock_wait.unschedule();
|
||||||
|
@ -483,7 +484,7 @@ impl OnvifMetadataParse {
|
||||||
if queued_time.is_some_and(|queued_time| queued_time >= state.configured_latency) {
|
if queued_time.is_some_and(|queued_time| queued_time >= state.configured_latency) {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Scheduling immediate wakeup -- queued time {}",
|
"Scheduling immediate wakeup -- queued time {}",
|
||||||
queued_time.display()
|
queued_time.display()
|
||||||
);
|
);
|
||||||
|
@ -520,7 +521,12 @@ impl OnvifMetadataParse {
|
||||||
.and_then(|queued_time| queued_time.positive())
|
.and_then(|queued_time| queued_time.positive())
|
||||||
.unwrap_or(gst::ClockTime::ZERO);
|
.unwrap_or(gst::ClockTime::ZERO);
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Currently queued {}", queued_time.display());
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Currently queued {}",
|
||||||
|
queued_time.display()
|
||||||
|
);
|
||||||
|
|
||||||
Some(queued_time)
|
Some(queued_time)
|
||||||
}
|
}
|
||||||
|
@ -546,7 +552,7 @@ impl OnvifMetadataParse {
|
||||||
_ => {
|
_ => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Upstream is live but have no clock -- assuming non-live for now"
|
"Upstream is live but have no clock -- assuming non-live for now"
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
|
@ -572,7 +578,7 @@ impl OnvifMetadataParse {
|
||||||
}
|
}
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Scheduling timer for {} / running time {}, now {}",
|
"Scheduling timer for {} / running time {}, now {}",
|
||||||
earliest_clock_time,
|
earliest_clock_time,
|
||||||
earliest_running_time.unwrap().display(),
|
earliest_running_time.unwrap().display(),
|
||||||
|
@ -585,7 +591,7 @@ impl OnvifMetadataParse {
|
||||||
if let Some(clock_wait) = state.clock_wait.take() {
|
if let Some(clock_wait) = state.clock_wait.take() {
|
||||||
clock_wait.unschedule();
|
clock_wait.unschedule();
|
||||||
}
|
}
|
||||||
gst::trace!(CAT, imp: self, "Scheduling immediate wakeup");
|
gst::trace!(CAT, imp = self, "Scheduling immediate wakeup");
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@ -610,7 +616,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Draining up to UTC time {} / running time {} from current position {} / running time {}",
|
"Draining up to UTC time {} / running time {} from current position {} / running time {}",
|
||||||
drain_utc_time.display(),
|
drain_utc_time.display(),
|
||||||
drain_utc_time
|
drain_utc_time
|
||||||
|
@ -658,7 +664,7 @@ impl OnvifMetadataParse {
|
||||||
});
|
});
|
||||||
segment.set_position(current_position);
|
segment.set_position(current_position);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Configuring output segment {:?}", segment);
|
gst::debug!(CAT, imp = self, "Configuring output segment {:?}", segment);
|
||||||
|
|
||||||
*out_segment = segment;
|
*out_segment = segment;
|
||||||
|
|
||||||
|
@ -680,7 +686,7 @@ impl OnvifMetadataParse {
|
||||||
{
|
{
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Output position updated to {}",
|
"Output position updated to {}",
|
||||||
current_position
|
current_position
|
||||||
);
|
);
|
||||||
|
@ -703,7 +709,7 @@ impl OnvifMetadataParse {
|
||||||
match utc_time_to_pts(out_segment, utc_time_running_time_mapping, utc_time) {
|
match utc_time_to_pts(out_segment, utc_time_running_time_mapping, utc_time) {
|
||||||
Some(frame_pts) => frame_pts,
|
Some(frame_pts) => frame_pts,
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(CAT, imp: self, "UTC time {} outside segment", utc_time);
|
gst::warning!(CAT, imp = self, "UTC time {} outside segment", utc_time);
|
||||||
gst::ClockTime::ZERO
|
gst::ClockTime::ZERO
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -732,7 +738,7 @@ impl OnvifMetadataParse {
|
||||||
{
|
{
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Dropping frame with UTC time {} / PTS {} that is too late by {} at current position {}",
|
"Dropping frame with UTC time {} / PTS {} that is too late by {} at current position {}",
|
||||||
utc_time,
|
utc_time,
|
||||||
frame_pts,
|
frame_pts,
|
||||||
|
@ -748,7 +754,7 @@ impl OnvifMetadataParse {
|
||||||
} else if diff > gst::ClockTime::ZERO {
|
} else if diff > gst::ClockTime::ZERO {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Frame in the past by {} with UTC time {} / PTS {} at current position {}",
|
"Frame in the past by {} with UTC time {} / PTS {} at current position {}",
|
||||||
diff,
|
diff,
|
||||||
utc_time,
|
utc_time,
|
||||||
|
@ -764,7 +770,7 @@ impl OnvifMetadataParse {
|
||||||
.position()
|
.position()
|
||||||
.map_or(true, |position| position < frame_pts)
|
.map_or(true, |position| position < frame_pts)
|
||||||
{
|
{
|
||||||
gst::trace!(CAT, imp: self, "Output position updated to {}", frame_pts);
|
gst::trace!(CAT, imp = self, "Output position updated to {}", frame_pts);
|
||||||
out_segment.set_position(frame_pts);
|
out_segment.set_position(frame_pts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -776,7 +782,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Producing frame with UTC time {} / PTS {}",
|
"Producing frame with UTC time {} / PTS {}",
|
||||||
utc_time,
|
utc_time,
|
||||||
frame_pts
|
frame_pts
|
||||||
|
@ -806,7 +812,7 @@ impl OnvifMetadataParse {
|
||||||
..xmltree::EmitterConfig::default()
|
..xmltree::EmitterConfig::default()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
gst::error!(CAT, imp: self, "Can't serialize XML element: {}", err);
|
gst::error!(CAT, imp = self, "Can't serialize XML element: {}", err);
|
||||||
for event in eos_events {
|
for event in eos_events {
|
||||||
data.push(BufferOrEvent::Event(event));
|
data.push(BufferOrEvent::Event(event));
|
||||||
}
|
}
|
||||||
|
@ -833,7 +839,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Position after draining {} / running time {} -- queued now {} / {} items",
|
"Position after draining {} / running time {} -- queued now {} / {} items",
|
||||||
out_segment.position().display(),
|
out_segment.position().display(),
|
||||||
out_segment
|
out_segment
|
||||||
|
@ -847,7 +853,7 @@ impl OnvifMetadataParse {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn sink_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling event {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling event {:?}", event);
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
gst::EventView::FlushStart(_) => {
|
gst::EventView::FlushStart(_) => {
|
||||||
|
@ -902,14 +908,14 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Configuring input segment {:?}",
|
"Configuring input segment {:?}",
|
||||||
segment
|
segment
|
||||||
);
|
);
|
||||||
state.in_segment = segment;
|
state.in_segment = segment;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, obj: pad, "Non-TIME segment");
|
gst::error!(CAT, obj = pad, "Non-TIME segment");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -934,7 +940,7 @@ impl OnvifMetadataParse {
|
||||||
state.configured_latency = latency;
|
state.configured_latency = latency;
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
gst::debug!(CAT, obj: pad, "Configuring latency of {}", latency);
|
gst::debug!(CAT, obj = pad, "Configuring latency of {}", latency);
|
||||||
if previous_latency != latency {
|
if previous_latency != latency {
|
||||||
let element = self.obj();
|
let element = self.obj();
|
||||||
let _ = element.post_message(
|
let _ = element.post_message(
|
||||||
|
@ -957,7 +963,7 @@ impl OnvifMetadataParse {
|
||||||
{
|
{
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Input position updated to {}",
|
"Input position updated to {}",
|
||||||
current_position
|
current_position
|
||||||
);
|
);
|
||||||
|
@ -983,7 +989,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Queueing EOS event with UTC time {} / running time {}",
|
"Queueing EOS event with UTC time {} / running time {}",
|
||||||
eos_utc_time,
|
eos_utc_time,
|
||||||
utc_time_to_running_time(*utc_time_running_time_mapping, eos_utc_time)
|
utc_time_to_running_time(*utc_time_running_time_mapping, eos_utc_time)
|
||||||
|
@ -1003,7 +1009,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Queueing event with UTC time {} / running time {}",
|
"Queueing event with UTC time {} / running time {}",
|
||||||
current_utc_time,
|
current_utc_time,
|
||||||
current_running_time.display(),
|
current_running_time.display(),
|
||||||
|
@ -1021,7 +1027,7 @@ impl OnvifMetadataParse {
|
||||||
if matches!(ev, gst::EventView::Eos(_)) {
|
if matches!(ev, gst::EventView::Eos(_)) {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Got EOS event before creating UTC/running time mapping"
|
"Got EOS event before creating UTC/running time mapping"
|
||||||
);
|
);
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
|
@ -1038,7 +1044,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Pre-queueing event with running time {}",
|
"Pre-queueing event with running time {}",
|
||||||
current_running_time.display()
|
current_running_time.display()
|
||||||
);
|
);
|
||||||
|
@ -1052,7 +1058,7 @@ impl OnvifMetadataParse {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
fn sink_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling query {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling query {:?}", query);
|
||||||
|
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
gst::QueryViewMut::Caps(q) => {
|
gst::QueryViewMut::Caps(q) => {
|
||||||
|
@ -1075,7 +1081,7 @@ impl OnvifMetadataParse {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
gst::QueryViewMut::Allocation(_) => {
|
gst::QueryViewMut::Allocation(_) => {
|
||||||
gst::fixme!(CAT, obj: pad, "Dropping allocation query");
|
gst::fixme!(CAT, obj = pad, "Dropping allocation query");
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
_ => gst::Pad::query_default(pad, Some(&*self.obj()), query),
|
_ => gst::Pad::query_default(pad, Some(&*self.obj()), query),
|
||||||
|
@ -1083,7 +1089,7 @@ impl OnvifMetadataParse {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
fn src_event(&self, pad: &gst::Pad, event: gst::Event) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling event {:?}", event);
|
gst::log!(CAT, obj = pad, "Handling event {:?}", event);
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
gst::EventView::FlushStart(_) => {
|
gst::EventView::FlushStart(_) => {
|
||||||
|
@ -1120,7 +1126,7 @@ impl OnvifMetadataParse {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling query {:?}", query);
|
gst::log!(CAT, obj = pad, "Handling query {:?}", query);
|
||||||
|
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
gst::QueryViewMut::Caps(q) => {
|
gst::QueryViewMut::Caps(q) => {
|
||||||
|
@ -1158,7 +1164,7 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Latency query response: live {} min {} max {}",
|
"Latency query response: live {} min {} max {}",
|
||||||
live,
|
live,
|
||||||
min,
|
min,
|
||||||
|
@ -1181,17 +1187,17 @@ impl OnvifMetadataParse {
|
||||||
if let Err(err) = self_.src_loop() {
|
if let Err(err) = self_.src_loop() {
|
||||||
match err {
|
match err {
|
||||||
gst::FlowError::Flushing => {
|
gst::FlowError::Flushing => {
|
||||||
gst::debug!(CAT, imp: self_, "Pausing after flow {:?}", err);
|
gst::debug!(CAT, imp = self_, "Pausing after flow {:?}", err);
|
||||||
}
|
}
|
||||||
gst::FlowError::Eos => {
|
gst::FlowError::Eos => {
|
||||||
let _ = self_.srcpad.push_event(gst::event::Eos::builder().build());
|
let _ = self_.srcpad.push_event(gst::event::Eos::builder().build());
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self_, "Pausing after flow {:?}", err);
|
gst::debug!(CAT, imp = self_, "Pausing after flow {:?}", err);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let _ = self_.srcpad.push_event(gst::event::Eos::builder().build());
|
let _ = self_.srcpad.push_event(gst::event::Eos::builder().build());
|
||||||
|
|
||||||
gst::error!(CAT, imp: self_, "Pausing after flow {:?}", err);
|
gst::error!(CAT, imp = self_, "Pausing after flow {:?}", err);
|
||||||
|
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self_,
|
self_,
|
||||||
|
@ -1269,7 +1275,7 @@ impl OnvifMetadataParse {
|
||||||
let mut drain_running_time = None;
|
let mut drain_running_time = None;
|
||||||
if self.sinkpad.pad_flags().contains(gst::PadFlags::EOS) {
|
if self.sinkpad.pad_flags().contains(gst::PadFlags::EOS) {
|
||||||
// Drain completely
|
// Drain completely
|
||||||
gst::debug!(CAT, imp: self, "Sink pad is EOS, draining");
|
gst::debug!(CAT, imp = self, "Sink pad is EOS, draining");
|
||||||
} else if let Some((true, min_latency)) = state.upstream_latency {
|
} else if let Some((true, min_latency)) = state.upstream_latency {
|
||||||
// Drain until the current clock running time minus the configured latency when
|
// Drain until the current clock running time minus the configured latency when
|
||||||
// live
|
// live
|
||||||
|
@ -1279,7 +1285,7 @@ impl OnvifMetadataParse {
|
||||||
) {
|
) {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Clock time now {}, last timer was at {} and current timer at {}",
|
"Clock time now {}, last timer was at {} and current timer at {}",
|
||||||
now,
|
now,
|
||||||
last_clock_wait_time.display(),
|
last_clock_wait_time.display(),
|
||||||
|
@ -1333,13 +1339,13 @@ impl OnvifMetadataParse {
|
||||||
if data.is_empty() {
|
if data.is_empty() {
|
||||||
if self.sinkpad.pad_flags().contains(gst::PadFlags::EOS) {
|
if self.sinkpad.pad_flags().contains(gst::PadFlags::EOS) {
|
||||||
state.last_flow_ret = Err(gst::FlowError::Eos);
|
state.last_flow_ret = Err(gst::FlowError::Eos);
|
||||||
gst::debug!(CAT, imp: self, "EOS, waiting on cond");
|
gst::debug!(CAT, imp = self, "EOS, waiting on cond");
|
||||||
state = self.cond.wait(state).unwrap();
|
state = self.cond.wait(state).unwrap();
|
||||||
gst::trace!(CAT, imp: self, "Woke up");
|
gst::trace!(CAT, imp = self, "Woke up");
|
||||||
} else if let Some(clock_wait) = state.clock_wait.clone() {
|
} else if let Some(clock_wait) = state.clock_wait.clone() {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Waiting on timer with time {}, now {}",
|
"Waiting on timer with time {}, now {}",
|
||||||
clock_wait.time(),
|
clock_wait.time(),
|
||||||
clock_wait.clock().and_then(|clock| clock.time()).display(),
|
clock_wait.clock().and_then(|clock| clock.time()).display(),
|
||||||
|
@ -1358,13 +1364,13 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
(Ok(_), jitter) => {
|
(Ok(_), jitter) => {
|
||||||
gst::trace!(CAT, imp: self, "Woke up after waiting for {}", jitter);
|
gst::trace!(CAT, imp = self, "Woke up after waiting for {}", jitter);
|
||||||
last_clock_wait_time = Some(clock_wait.time());
|
last_clock_wait_time = Some(clock_wait.time());
|
||||||
}
|
}
|
||||||
(Err(err), jitter) => {
|
(Err(err), jitter) => {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Woke up with error {:?} and jitter {}",
|
"Woke up with error {:?} and jitter {}",
|
||||||
err,
|
err,
|
||||||
jitter
|
jitter
|
||||||
|
@ -1372,9 +1378,9 @@ impl OnvifMetadataParse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Waiting on cond");
|
gst::debug!(CAT, imp = self, "Waiting on cond");
|
||||||
state = self.cond.wait(state).unwrap();
|
state = self.cond.wait(state).unwrap();
|
||||||
gst::trace!(CAT, imp: self, "Woke up");
|
gst::trace!(CAT, imp = self, "Woke up");
|
||||||
}
|
}
|
||||||
|
|
||||||
// And retry if there's anything to drain now.
|
// And retry if there's anything to drain now.
|
||||||
|
@ -1385,15 +1391,15 @@ impl OnvifMetadataParse {
|
||||||
|
|
||||||
let mut res = Ok(());
|
let mut res = Ok(());
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Pushing {} items downstream", data.len());
|
gst::trace!(CAT, imp = self, "Pushing {} items downstream", data.len());
|
||||||
for data in data {
|
for data in data {
|
||||||
match data {
|
match data {
|
||||||
BufferOrEvent::Event(event) => {
|
BufferOrEvent::Event(event) => {
|
||||||
gst::trace!(CAT, imp: self, "Pushing event {:?}", event);
|
gst::trace!(CAT, imp = self, "Pushing event {:?}", event);
|
||||||
self.srcpad.push_event(event);
|
self.srcpad.push_event(event);
|
||||||
}
|
}
|
||||||
BufferOrEvent::Buffer(buffer) => {
|
BufferOrEvent::Buffer(buffer) => {
|
||||||
gst::trace!(CAT, imp: self, "Pushing buffer {:?}", buffer);
|
gst::trace!(CAT, imp = self, "Pushing buffer {:?}", buffer);
|
||||||
if let Err(err) = self.srcpad.push(buffer) {
|
if let Err(err) = self.srcpad.push(buffer) {
|
||||||
res = Err(err);
|
res = Err(err);
|
||||||
break;
|
break;
|
||||||
|
@ -1401,7 +1407,7 @@ impl OnvifMetadataParse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst::trace!(CAT, imp: self, "Pushing returned {:?}", res);
|
gst::trace!(CAT, imp = self, "Pushing returned {:?}", res);
|
||||||
|
|
||||||
state = self.state.lock().unwrap();
|
state = self.state.lock().unwrap();
|
||||||
// If flushing or any other error then just return here
|
// If flushing or any other error then just return here
|
||||||
|
@ -1601,7 +1607,7 @@ impl ElementImpl for OnvifMetadataParse {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
if matches!(transition, gst::StateChange::ReadyToPaused) {
|
if matches!(transition, gst::StateChange::ReadyToPaused) {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
|
@ -147,7 +147,7 @@ impl ElementImpl for QuinnQuicSink {
|
||||||
{
|
{
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Certificate or private key file not provided for secure connection"
|
"Certificate or private key file not provided for secure connection"
|
||||||
);
|
);
|
||||||
return Err(gst::StateChangeError);
|
return Err(gst::StateChangeError);
|
||||||
|
@ -456,17 +456,17 @@ impl BaseSinkImpl for QuinnQuicSink {
|
||||||
stream: s,
|
stream: s,
|
||||||
});
|
});
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Started");
|
gst::info!(CAT, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Ok(Err(e)) => match e {
|
Ok(Err(e)) => match e {
|
||||||
WaitError::FutureAborted => {
|
WaitError::FutureAborted => {
|
||||||
gst::warning!(CAT, imp: self, "Connection aborted");
|
gst::warning!(CAT, imp = self, "Connection aborted");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
WaitError::FutureError(err) => {
|
WaitError::FutureError(err) => {
|
||||||
gst::error!(CAT, imp: self, "Connection request failed: {}", err);
|
gst::error!(CAT, imp = self, "Connection request failed: {}", err);
|
||||||
Err(gst::error_msg!(
|
Err(gst::error_msg!(
|
||||||
gst::ResourceError::Failed,
|
gst::ResourceError::Failed,
|
||||||
["Connection request failed: {}", err]
|
["Connection request failed: {}", err]
|
||||||
|
@ -474,7 +474,7 @@ impl BaseSinkImpl for QuinnQuicSink {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to establish a connection: {:?}", e);
|
gst::error!(CAT, imp = self, "Failed to establish a connection: {:?}", e);
|
||||||
Err(gst::error_msg!(
|
Err(gst::error_msg!(
|
||||||
gst::ResourceError::Failed,
|
gst::ResourceError::Failed,
|
||||||
["Failed to establish a connection: {:?}", e]
|
["Failed to establish a connection: {:?}", e]
|
||||||
|
@ -505,17 +505,17 @@ impl BaseSinkImpl for QuinnQuicSink {
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
if let Err(e) = r {
|
if let Err(e) = r {
|
||||||
close_msg = format!("Stream finish request error: {}", e);
|
close_msg = format!("Stream finish request error: {}", e);
|
||||||
gst::error!(CAT, imp: self, "{}", close_msg);
|
gst::error!(CAT, imp = self, "{}", close_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
WaitError::FutureAborted => {
|
WaitError::FutureAborted => {
|
||||||
close_msg = "Stream finish request aborted".to_string();
|
close_msg = "Stream finish request aborted".to_string();
|
||||||
gst::warning!(CAT, imp: self, "{}", close_msg);
|
gst::warning!(CAT, imp = self, "{}", close_msg);
|
||||||
}
|
}
|
||||||
WaitError::FutureError(e) => {
|
WaitError::FutureError(e) => {
|
||||||
close_msg = format!("Stream finish request future error: {}", e);
|
close_msg = format!("Stream finish request future error: {}", e);
|
||||||
gst::error!(CAT, imp: self, "{}", close_msg);
|
gst::error!(CAT, imp = self, "{}", close_msg);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -526,7 +526,7 @@ impl BaseSinkImpl for QuinnQuicSink {
|
||||||
|
|
||||||
*state = State::Stopped;
|
*state = State::Stopped;
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Stopped");
|
gst::info!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -537,7 +537,7 @@ impl BaseSinkImpl for QuinnQuicSink {
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Rendering {:?}", buffer);
|
gst::trace!(CAT, imp = self, "Rendering {:?}", buffer);
|
||||||
|
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::element_imp_error!(self, gst::CoreError::Failed, ["Failed to map buffer"]);
|
gst::element_imp_error!(self, gst::CoreError::Failed, ["Failed to map buffer"]);
|
||||||
|
@ -548,12 +548,12 @@ impl BaseSinkImpl for QuinnQuicSink {
|
||||||
Ok(_) => Ok(gst::FlowSuccess::Ok),
|
Ok(_) => Ok(gst::FlowSuccess::Ok),
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
Some(error_message) => {
|
Some(error_message) => {
|
||||||
gst::error!(CAT, imp: self, "Data sending failed: {}", error_message);
|
gst::error!(CAT, imp = self, "Data sending failed: {}", error_message);
|
||||||
self.post_error_message(error_message);
|
self.post_error_message(error_message);
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::info!(CAT, imp: self, "Send interrupted. Flushing...");
|
gst::info!(CAT, imp = self, "Send interrupted. Flushing...");
|
||||||
Err(gst::FlowError::Flushing)
|
Err(gst::FlowError::Flushing)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -603,7 +603,7 @@ impl QuinnQuicSink {
|
||||||
Some(size) => {
|
Some(size) => {
|
||||||
if src.len() > size {
|
if src.len() > size {
|
||||||
if drop_buffer_for_datagram {
|
if drop_buffer_for_datagram {
|
||||||
gst::warning!(CAT, imp: self, "Buffer dropped, current max datagram size: {size} > buffer size: {}", src.len());
|
gst::warning!(CAT, imp = self, "Buffer dropped, current max datagram size: {size} > buffer size: {}", src.len());
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else {
|
} else {
|
||||||
return Err(Some(gst::error_msg!(
|
return Err(Some(gst::error_msg!(
|
||||||
|
@ -638,7 +638,7 @@ impl QuinnQuicSink {
|
||||||
))),
|
))),
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
WaitError::FutureAborted => {
|
WaitError::FutureAborted => {
|
||||||
gst::warning!(CAT, imp: self, "Sending aborted");
|
gst::warning!(CAT, imp = self, "Sending aborted");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
WaitError::FutureError(e) => Err(Some(gst::error_msg!(
|
WaitError::FutureError(e) => Err(Some(gst::error_msg!(
|
||||||
|
@ -738,7 +738,11 @@ impl QuinnQuicSink {
|
||||||
} else {
|
} else {
|
||||||
match connection.max_datagram_size() {
|
match connection.max_datagram_size() {
|
||||||
Some(datagram_size) => {
|
Some(datagram_size) => {
|
||||||
gst::info!(CAT, imp: self, "Datagram size reported by peer: {datagram_size}");
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Datagram size reported by peer: {datagram_size}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
return Err(WaitError::FutureError(gst::error_msg!(
|
return Err(WaitError::FutureError(gst::error_msg!(
|
||||||
|
|
|
@ -149,7 +149,7 @@ impl ElementImpl for QuinnQuicSrc {
|
||||||
{
|
{
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Certificate or private key file not provided for secure connection"
|
"Certificate or private key file not provided for secure connection"
|
||||||
);
|
);
|
||||||
return Err(gst::StateChangeError);
|
return Err(gst::StateChangeError);
|
||||||
|
@ -468,17 +468,17 @@ impl BaseSrcImpl for QuinnQuicSrc {
|
||||||
stream: s,
|
stream: s,
|
||||||
});
|
});
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Started");
|
gst::info!(CAT, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Ok(Err(e)) | Err(e) => match e {
|
Ok(Err(e)) | Err(e) => match e {
|
||||||
WaitError::FutureAborted => {
|
WaitError::FutureAborted => {
|
||||||
gst::warning!(CAT, imp: self, "Connection aborted");
|
gst::warning!(CAT, imp = self, "Connection aborted");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
WaitError::FutureError(err) => {
|
WaitError::FutureError(err) => {
|
||||||
gst::error!(CAT, imp: self, "Connection request failed: {}", err);
|
gst::error!(CAT, imp = self, "Connection request failed: {}", err);
|
||||||
Err(gst::error_msg!(
|
Err(gst::error_msg!(
|
||||||
gst::ResourceError::Failed,
|
gst::ResourceError::Failed,
|
||||||
["Connection request failed: {}", err]
|
["Connection request failed: {}", err]
|
||||||
|
@ -531,7 +531,7 @@ impl BaseSrcImpl for QuinnQuicSrc {
|
||||||
match data {
|
match data {
|
||||||
Ok(bytes) => {
|
Ok(bytes) => {
|
||||||
if bytes.is_empty() {
|
if bytes.is_empty() {
|
||||||
gst::debug!(CAT, imp: self, "End of stream");
|
gst::debug!(CAT, imp = self, "End of stream");
|
||||||
return Err(gst::FlowError::Eos);
|
return Err(gst::FlowError::Eos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,7 +546,7 @@ impl BaseSrcImpl for QuinnQuicSrc {
|
||||||
}
|
}
|
||||||
Err(None) => Err(gst::FlowError::Flushing),
|
Err(None) => Err(gst::FlowError::Flushing),
|
||||||
Err(Some(err)) => {
|
Err(Some(err)) => {
|
||||||
gst::error!(CAT, imp: self, "Could not GET: {}", err);
|
gst::error!(CAT, imp = self, "Could not GET: {}", err);
|
||||||
Err(gst::FlowError::Error)
|
Err(gst::FlowError::Error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -571,12 +571,12 @@ impl BaseSrcImpl for QuinnQuicSrc {
|
||||||
|
|
||||||
let mut tmp_caps = settings.caps.clone();
|
let mut tmp_caps = settings.caps.clone();
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Advertising our own caps: {:?}", &tmp_caps);
|
gst::debug!(CAT, imp = self, "Advertising our own caps: {:?}", &tmp_caps);
|
||||||
|
|
||||||
if let Some(filter_caps) = filter {
|
if let Some(filter_caps) = filter {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Intersecting with filter caps: {:?}",
|
"Intersecting with filter caps: {:?}",
|
||||||
&filter_caps
|
&filter_caps
|
||||||
);
|
);
|
||||||
|
@ -584,7 +584,7 @@ impl BaseSrcImpl for QuinnQuicSrc {
|
||||||
tmp_caps = filter_caps.intersect_with_mode(&tmp_caps, gst::CapsIntersectMode::First);
|
tmp_caps = filter_caps.intersect_with_mode(&tmp_caps, gst::CapsIntersectMode::First);
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Returning caps: {:?}", &tmp_caps);
|
gst::debug!(CAT, imp = self, "Returning caps: {:?}", &tmp_caps);
|
||||||
|
|
||||||
Some(tmp_caps)
|
Some(tmp_caps)
|
||||||
}
|
}
|
||||||
|
@ -618,11 +618,11 @@ impl QuinnQuicSrc {
|
||||||
Ok(bytes) => Ok(bytes),
|
Ok(bytes) => Ok(bytes),
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
ConnectionError::ApplicationClosed(ac) => {
|
ConnectionError::ApplicationClosed(ac) => {
|
||||||
gst::info!(CAT, imp: self, "Application closed connection, {}", ac);
|
gst::info!(CAT, imp = self, "Application closed connection, {}", ac);
|
||||||
Ok(Bytes::new())
|
Ok(Bytes::new())
|
||||||
}
|
}
|
||||||
ConnectionError::ConnectionClosed(cc) => {
|
ConnectionError::ConnectionClosed(cc) => {
|
||||||
gst::info!(CAT, imp: self, "Transport closed connection, {}", cc);
|
gst::info!(CAT, imp = self, "Transport closed connection, {}", cc);
|
||||||
Ok(Bytes::new())
|
Ok(Bytes::new())
|
||||||
}
|
}
|
||||||
_ => Err(WaitError::FutureError(gst::error_msg!(
|
_ => Err(WaitError::FutureError(gst::error_msg!(
|
||||||
|
@ -640,11 +640,16 @@ impl QuinnQuicSrc {
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
ReadError::ConnectionLost(conn_err) => match conn_err {
|
ReadError::ConnectionLost(conn_err) => match conn_err {
|
||||||
ConnectionError::ConnectionClosed(cc) => {
|
ConnectionError::ConnectionClosed(cc) => {
|
||||||
gst::info!(CAT, imp: self, "Transport closed connection, {}", cc);
|
gst::info!(CAT, imp = self, "Transport closed connection, {}", cc);
|
||||||
Ok(Bytes::new())
|
Ok(Bytes::new())
|
||||||
}
|
}
|
||||||
ConnectionError::ApplicationClosed(ac) => {
|
ConnectionError::ApplicationClosed(ac) => {
|
||||||
gst::info!(CAT, imp: self, "Application closed connection, {}", ac);
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Application closed connection, {}",
|
||||||
|
ac
|
||||||
|
);
|
||||||
Ok(Bytes::new())
|
Ok(Bytes::new())
|
||||||
}
|
}
|
||||||
_ => Err(WaitError::FutureError(gst::error_msg!(
|
_ => Err(WaitError::FutureError(gst::error_msg!(
|
||||||
|
@ -653,7 +658,7 @@ impl QuinnQuicSrc {
|
||||||
))),
|
))),
|
||||||
},
|
},
|
||||||
ReadError::ClosedStream => {
|
ReadError::ClosedStream => {
|
||||||
gst::info!(CAT, imp: self, "Stream closed");
|
gst::info!(CAT, imp = self, "Stream closed");
|
||||||
Ok(Bytes::new())
|
Ok(Bytes::new())
|
||||||
}
|
}
|
||||||
_ => Err(WaitError::FutureError(gst::error_msg!(
|
_ => Err(WaitError::FutureError(gst::error_msg!(
|
||||||
|
@ -669,11 +674,11 @@ impl QuinnQuicSrc {
|
||||||
Ok(Ok(bytes)) => Ok(bytes),
|
Ok(Ok(bytes)) => Ok(bytes),
|
||||||
Ok(Err(e)) | Err(e) => match e {
|
Ok(Err(e)) | Err(e) => match e {
|
||||||
WaitError::FutureAborted => {
|
WaitError::FutureAborted => {
|
||||||
gst::warning!(CAT, imp: self, "Read from stream request aborted");
|
gst::warning!(CAT, imp = self, "Read from stream request aborted");
|
||||||
Err(None)
|
Err(None)
|
||||||
}
|
}
|
||||||
WaitError::FutureError(e) => {
|
WaitError::FutureError(e) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to read from stream: {}", e);
|
gst::error!(CAT, imp = self, "Failed to read from stream: {}", e);
|
||||||
Err(Some(e))
|
Err(Some(e))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -768,7 +773,11 @@ impl QuinnQuicSrc {
|
||||||
} else {
|
} else {
|
||||||
match connection.max_datagram_size() {
|
match connection.max_datagram_size() {
|
||||||
Some(datagram_size) => {
|
Some(datagram_size) => {
|
||||||
gst::info!(CAT, imp: self, "Datagram size reported by peer: {datagram_size}");
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Datagram size reported by peer: {datagram_size}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
return Err(WaitError::FutureError(gst::error_msg!(
|
return Err(WaitError::FutureError(gst::error_msg!(
|
||||||
|
@ -783,7 +792,7 @@ impl QuinnQuicSrc {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Remote connection accepted: {}",
|
"Remote connection accepted: {}",
|
||||||
connection.remote_address()
|
connection.remote_address()
|
||||||
);
|
);
|
||||||
|
|
|
@ -165,7 +165,7 @@ impl RaptorqDec {
|
||||||
if data_packets_num == n {
|
if data_packets_num == n {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"All packets ({}) received, dropping Source Block ({})",
|
"All packets ({}) received, dropping Source Block ({})",
|
||||||
data_packets_num,
|
data_packets_num,
|
||||||
seq_lo
|
seq_lo
|
||||||
|
@ -300,7 +300,7 @@ impl RaptorqDec {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Successfully recovered packet: seqnum: {}, len: {}, ts: {}",
|
"Successfully recovered packet: seqnum: {}, len: {}, ts: {}",
|
||||||
rtpbuf.seq(),
|
rtpbuf.seq(),
|
||||||
rtpbuf.payload_size(),
|
rtpbuf.payload_size(),
|
||||||
|
@ -324,13 +324,13 @@ impl RaptorqDec {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let this_seq = {
|
let this_seq = {
|
||||||
let rtpbuf = RTPBuffer::from_buffer_readable(buffer).map_err(|err| {
|
let rtpbuf = RTPBuffer::from_buffer_readable(buffer).map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map rtp buffer : {}", err);
|
gst::error!(CAT, imp = self, "Failed to map rtp buffer : {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"New data packet, seq {}, ts {}",
|
"New data packet, seq {}, ts {}",
|
||||||
rtpbuf.seq(),
|
rtpbuf.seq(),
|
||||||
rtpbuf.timestamp()
|
rtpbuf.timestamp()
|
||||||
|
@ -388,7 +388,7 @@ impl RaptorqDec {
|
||||||
for seq in expired {
|
for seq in expired {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Source Block ({}) dropped, because max wait time has been exceeded",
|
"Source Block ({}) dropped, because max wait time has been exceeded",
|
||||||
seq as u16
|
seq as u16
|
||||||
);
|
);
|
||||||
|
@ -399,7 +399,7 @@ impl RaptorqDec {
|
||||||
if thresh > 0 && state.media_packets.len() >= thresh {
|
if thresh > 0 && state.media_packets.len() >= thresh {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Too many buffered media packets, resetting decoder. This might \
|
"Too many buffered media packets, resetting decoder. This might \
|
||||||
be because we haven't received a repair packet for too long, or \
|
be because we haven't received a repair packet for too long, or \
|
||||||
repair packets have no valid timestamps.",
|
repair packets have no valid timestamps.",
|
||||||
|
@ -420,13 +420,13 @@ impl RaptorqDec {
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let rtpbuf = RTPBuffer::from_buffer_readable(&buffer).map_err(|err| {
|
let rtpbuf = RTPBuffer::from_buffer_readable(&buffer).map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map rtp buffer : {}", err);
|
gst::error!(CAT, imp = self, "Failed to map rtp buffer : {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let payload = rtpbuf.payload().unwrap();
|
let payload = rtpbuf.payload().unwrap();
|
||||||
let payload_id = payload[0..7].try_into().map_err(|err| {
|
let payload_id = payload[0..7].try_into().map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Unexpected rtp fec payload : {}", err);
|
gst::error!(CAT, imp = self, "Unexpected rtp fec payload : {}", err);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -440,7 +440,7 @@ impl RaptorqDec {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"New repair packet, I: {}, LP: {}, LB: {}",
|
"New repair packet, I: {}, LP: {}, LB: {}",
|
||||||
i,
|
i,
|
||||||
lp,
|
lp,
|
||||||
|
@ -553,7 +553,7 @@ impl RaptorqDec {
|
||||||
|
|
||||||
let media_packets_reset_threshold = settings.media_packets_reset_threshold as usize;
|
let media_packets_reset_threshold = settings.media_packets_reset_threshold as usize;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Configured for caps {}", incaps);
|
gst::debug!(CAT, imp = self, "Configured for caps {}", incaps);
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
|
@ -788,7 +788,7 @@ impl ElementImpl for RaptorqDec {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::ReadyToPaused => {
|
gst::StateChange::ReadyToPaused => {
|
||||||
|
|
|
@ -132,7 +132,13 @@ impl RaptorqEnc {
|
||||||
// placed in each repair packet.
|
// placed in each repair packet.
|
||||||
let si = state.symbols_per_packet;
|
let si = state.symbols_per_packet;
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Source Block add ADU: si {}, li {}", si, li);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Source Block add ADU: si {}, li {}",
|
||||||
|
si,
|
||||||
|
li
|
||||||
|
);
|
||||||
|
|
||||||
let mut data = vec![0; si * state.symbol_size];
|
let mut data = vec![0; si * state.symbol_size];
|
||||||
|
|
||||||
|
@ -397,21 +403,21 @@ impl RaptorqEnc {
|
||||||
let state = state_guard.as_mut().ok_or(gst::FlowError::NotNegotiated)?;
|
let state = state_guard.as_mut().ok_or(gst::FlowError::NotNegotiated)?;
|
||||||
|
|
||||||
if buffer.size() > state.mtu {
|
if buffer.size() > state.mtu {
|
||||||
gst::error!(CAT, imp: self, "Packet length exceeds configured MTU");
|
gst::error!(CAT, imp = self, "Packet length exceeds configured MTU");
|
||||||
return Err(gst::FlowError::NotSupported);
|
return Err(gst::FlowError::NotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (curr_seq, now_rtpts) = match RTPBuffer::from_buffer_readable(&buffer) {
|
let (curr_seq, now_rtpts) = match RTPBuffer::from_buffer_readable(&buffer) {
|
||||||
Ok(rtpbuf) => (rtpbuf.seq(), rtpbuf.timestamp()),
|
Ok(rtpbuf) => (rtpbuf.seq(), rtpbuf.timestamp()),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::error!(CAT, imp: self, "Mapping to RTP packet failed");
|
gst::error!(CAT, imp = self, "Mapping to RTP packet failed");
|
||||||
return Err(gst::FlowError::NotSupported);
|
return Err(gst::FlowError::NotSupported);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(last_seq) = state.seqnums.last() {
|
if let Some(last_seq) = state.seqnums.last() {
|
||||||
if last_seq.overflowing_add(1).0 != curr_seq {
|
if last_seq.overflowing_add(1).0 != curr_seq {
|
||||||
gst::error!(CAT, imp: self, "Got out of sequence packets");
|
gst::error!(CAT, imp = self, "Got out of sequence packets");
|
||||||
return Err(gst::FlowError::NotSupported);
|
return Err(gst::FlowError::NotSupported);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,7 +470,7 @@ impl RaptorqEnc {
|
||||||
}
|
}
|
||||||
EventView::Caps(ev) => {
|
EventView::Caps(ev) => {
|
||||||
let caps = ev.caps();
|
let caps = ev.caps();
|
||||||
gst::info!(CAT, obj: pad, "Got caps {:?}", caps);
|
gst::info!(CAT, obj = pad, "Got caps {:?}", caps);
|
||||||
|
|
||||||
let mut state_guard = self.state.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
|
|
||||||
|
@ -605,7 +611,7 @@ impl RaptorqEnc {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Starting RaptorQ Encoder, Symbols per Block: {}, Symbol Size: {}",
|
"Starting RaptorQ Encoder, Symbols per Block: {}, Symbol Size: {}",
|
||||||
symbols_per_block,
|
symbols_per_block,
|
||||||
symbol_size
|
symbol_size
|
||||||
|
@ -909,7 +915,7 @@ impl ElementImpl for RaptorqEnc {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::trace!(CAT, imp: self, "Changing state {:?}", transition);
|
gst::trace!(CAT, imp = self, "Changing state {:?}", transition);
|
||||||
|
|
||||||
match transition {
|
match transition {
|
||||||
gst::StateChange::ReadyToPaused => {
|
gst::StateChange::ReadyToPaused => {
|
||||||
|
|
|
@ -264,7 +264,7 @@ impl ReqwestHttpSrc {
|
||||||
) -> Result<ClientContext, gst::ErrorMessage> {
|
) -> Result<ClientContext, gst::ErrorMessage> {
|
||||||
let mut client_guard = self.client.lock().unwrap();
|
let mut client_guard = self.client.lock().unwrap();
|
||||||
if let Some(ref client) = *client_guard {
|
if let Some(ref client) = *client_guard {
|
||||||
gst::debug!(CAT, imp: self, "Using already configured client");
|
gst::debug!(CAT, imp = self, "Using already configured client");
|
||||||
return Ok(client.clone());
|
return Ok(client.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ impl ReqwestHttpSrc {
|
||||||
|
|
||||||
// Hopefully now, self.set_context will have been synchronously called
|
// Hopefully now, self.set_context will have been synchronously called
|
||||||
if let Some(client) = self.external_client.lock().unwrap().clone() {
|
if let Some(client) = self.external_client.lock().unwrap().clone() {
|
||||||
gst::debug!(CAT, imp: self, "Using shared client");
|
gst::debug!(CAT, imp = self, "Using shared client");
|
||||||
*client_guard = Some(client.clone());
|
*client_guard = Some(client.clone());
|
||||||
|
|
||||||
return Ok(client);
|
return Ok(client);
|
||||||
|
@ -307,7 +307,7 @@ impl ReqwestHttpSrc {
|
||||||
builder = builder.proxy(p);
|
builder = builder.proxy(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Creating new client");
|
gst::debug!(CAT, imp = self, "Creating new client");
|
||||||
let client = ClientContext(Arc::new(ClientContextInner {
|
let client = ClientContext(Arc::new(ClientContextInner {
|
||||||
client: builder.build().map_err(|err| {
|
client: builder.build().map_err(|err| {
|
||||||
gst::error_msg!(
|
gst::error_msg!(
|
||||||
|
@ -321,7 +321,7 @@ impl ReqwestHttpSrc {
|
||||||
// The alternative would be different contexts for different proxy settings, or one context with a
|
// The alternative would be different contexts for different proxy settings, or one context with a
|
||||||
// map from proxy settings to client, but then, how and when to discard those, retaining reuse benefits?
|
// map from proxy settings to client, but then, how and when to discard those, retaining reuse benefits?
|
||||||
if proxy.is_none() {
|
if proxy.is_none() {
|
||||||
gst::debug!(CAT, imp: self, "Sharing new client with other elements");
|
gst::debug!(CAT, imp = self, "Sharing new client with other elements");
|
||||||
let mut context = gst::Context::new(REQWEST_CLIENT_CONTEXT, true);
|
let mut context = gst::Context::new(REQWEST_CLIENT_CONTEXT, true);
|
||||||
{
|
{
|
||||||
let context = context.get_mut().unwrap();
|
let context = context.get_mut().unwrap();
|
||||||
|
@ -350,7 +350,7 @@ impl ReqwestHttpSrc {
|
||||||
use headers::{Connection, ContentLength, ContentRange, HeaderMapExt, Range, UserAgent};
|
use headers::{Connection, ContentLength, ContentRange, HeaderMapExt, Range, UserAgent};
|
||||||
use reqwest::header::{self, HeaderMap, HeaderName, HeaderValue};
|
use reqwest::header::{self, HeaderMap, HeaderName, HeaderValue};
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Creating new request for {}", uri);
|
gst::debug!(CAT, imp = self, "Creating new request for {}", uri);
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
|
|
||||||
|
@ -395,7 +395,7 @@ impl ReqwestHttpSrc {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to transform extra-header field name '{}' to header name: {}",
|
"Failed to transform extra-header field name '{}' to header name: {}",
|
||||||
field,
|
field,
|
||||||
err,
|
err,
|
||||||
|
@ -411,7 +411,7 @@ impl ReqwestHttpSrc {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to transform extra-header '{}' value to string",
|
"Failed to transform extra-header '{}' value to string",
|
||||||
field
|
field
|
||||||
);
|
);
|
||||||
|
@ -426,7 +426,7 @@ impl ReqwestHttpSrc {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to transform extra-header '{}' value to header value",
|
"Failed to transform extra-header '{}' value to header value",
|
||||||
field
|
field
|
||||||
);
|
);
|
||||||
|
@ -472,7 +472,7 @@ impl ReqwestHttpSrc {
|
||||||
req
|
req
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Sending new request: {:?}", req);
|
gst::debug!(CAT, imp = self, "Sending new request: {:?}", req);
|
||||||
|
|
||||||
let future = async {
|
let future = async {
|
||||||
req.send().await.map_err(|err| {
|
req.send().await.map_err(|err| {
|
||||||
|
@ -487,21 +487,21 @@ impl ReqwestHttpSrc {
|
||||||
let res = match res {
|
let res = match res {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(Some(err)) => {
|
Err(Some(err)) => {
|
||||||
gst::debug!(CAT, imp: self, "Error {:?}", err);
|
gst::debug!(CAT, imp = self, "Error {:?}", err);
|
||||||
return Err(Some(err));
|
return Err(Some(err));
|
||||||
}
|
}
|
||||||
Err(None) => {
|
Err(None) => {
|
||||||
gst::debug!(CAT, imp: self, "Flushing");
|
gst::debug!(CAT, imp = self, "Flushing");
|
||||||
return Err(None);
|
return Err(None);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Received response: {:?}", res);
|
gst::debug!(CAT, imp = self, "Received response: {:?}", res);
|
||||||
|
|
||||||
if !res.status().is_success() {
|
if !res.status().is_success() {
|
||||||
match res.status() {
|
match res.status() {
|
||||||
StatusCode::NOT_FOUND => {
|
StatusCode::NOT_FOUND => {
|
||||||
gst::error!(CAT, imp: self, "Resource not found");
|
gst::error!(CAT, imp = self, "Resource not found");
|
||||||
return Err(Some(gst::error_msg!(
|
return Err(Some(gst::error_msg!(
|
||||||
gst::ResourceError::NotFound,
|
gst::ResourceError::NotFound,
|
||||||
["Resource '{}' not found", uri]
|
["Resource '{}' not found", uri]
|
||||||
|
@ -511,14 +511,14 @@ impl ReqwestHttpSrc {
|
||||||
| StatusCode::PAYMENT_REQUIRED
|
| StatusCode::PAYMENT_REQUIRED
|
||||||
| StatusCode::FORBIDDEN
|
| StatusCode::FORBIDDEN
|
||||||
| StatusCode::PROXY_AUTHENTICATION_REQUIRED => {
|
| StatusCode::PROXY_AUTHENTICATION_REQUIRED => {
|
||||||
gst::error!(CAT, imp: self, "Not authorized: {}", res.status());
|
gst::error!(CAT, imp = self, "Not authorized: {}", res.status());
|
||||||
return Err(Some(gst::error_msg!(
|
return Err(Some(gst::error_msg!(
|
||||||
gst::ResourceError::NotAuthorized,
|
gst::ResourceError::NotAuthorized,
|
||||||
["Not Authorized for resource '{}': {}", uri, res.status()]
|
["Not Authorized for resource '{}': {}", uri, res.status()]
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::error!(CAT, imp: self, "Request failed: {}", res.status());
|
gst::error!(CAT, imp = self, "Request failed: {}", res.status());
|
||||||
return Err(Some(gst::error_msg!(
|
return Err(Some(gst::error_msg!(
|
||||||
gst::ResourceError::OpenRead,
|
gst::ResourceError::OpenRead,
|
||||||
["Request for '{}' failed: {}", uri, res.status()]
|
["Request for '{}' failed: {}", uri, res.status()]
|
||||||
|
@ -571,7 +571,7 @@ impl ReqwestHttpSrc {
|
||||||
.and_then(|content_type| content_type.to_str().ok())
|
.and_then(|content_type| content_type.to_str().ok())
|
||||||
.and_then(|content_type| content_type.parse::<mime::Mime>().ok())
|
.and_then(|content_type| content_type.parse::<mime::Mime>().ok())
|
||||||
{
|
{
|
||||||
gst::debug!(CAT, imp: self, "Got content type {}", content_type);
|
gst::debug!(CAT, imp = self, "Got content type {}", content_type);
|
||||||
if let Some(ref mut caps) = caps {
|
if let Some(ref mut caps) = caps {
|
||||||
let caps = caps.get_mut().unwrap();
|
let caps = caps.get_mut().unwrap();
|
||||||
let s = caps.structure_mut(0).unwrap();
|
let s = caps.structure_mut(0).unwrap();
|
||||||
|
@ -614,7 +614,7 @@ impl ReqwestHttpSrc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Request successful");
|
gst::debug!(CAT, imp = self, "Request successful");
|
||||||
|
|
||||||
Ok(State::Started {
|
Ok(State::Started {
|
||||||
uri,
|
uri,
|
||||||
|
@ -897,7 +897,7 @@ impl ObjectImpl for ReqwestHttpSrc {
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to set property `{}`: {:?}",
|
"Failed to set property `{}`: {:?}",
|
||||||
pspec.name(),
|
pspec.name(),
|
||||||
err
|
err
|
||||||
|
@ -1077,7 +1077,7 @@ impl BaseSrcImpl for ReqwestHttpSrc {
|
||||||
})
|
})
|
||||||
.cloned()?;
|
.cloned()?;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Starting for URI {}", uri);
|
gst::debug!(CAT, imp = self, "Starting for URI {}", uri);
|
||||||
|
|
||||||
*state = self.do_request(uri, 0, None).map_err(|err| {
|
*state = self.do_request(uri, 0, None).map_err(|err| {
|
||||||
err.unwrap_or_else(|| {
|
err.unwrap_or_else(|| {
|
||||||
|
@ -1089,7 +1089,7 @@ impl BaseSrcImpl for ReqwestHttpSrc {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
fn stop(&self) -> Result<(), gst::ErrorMessage> {
|
||||||
gst::debug!(CAT, imp: self, "Stopping");
|
gst::debug!(CAT, imp = self, "Stopping");
|
||||||
*self.state.lock().unwrap() = State::Stopped;
|
*self.state.lock().unwrap() = State::Stopped;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1135,10 +1135,10 @@ impl BaseSrcImpl for ReqwestHttpSrc {
|
||||||
let start = *segment.start().expect("No start position given");
|
let start = *segment.start().expect("No start position given");
|
||||||
let stop = segment.stop().map(|stop| *stop);
|
let stop = segment.stop().map(|stop| *stop);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Seeking to {}-{:?}", start, stop);
|
gst::debug!(CAT, imp = self, "Seeking to {}-{:?}", start, stop);
|
||||||
|
|
||||||
if position == start && old_stop == stop {
|
if position == start && old_stop == stop {
|
||||||
gst::debug!(CAT, imp: self, "No change to current request");
|
gst::debug!(CAT, imp = self, "No change to current request");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,7 +1184,7 @@ impl PushSrcImpl for ReqwestHttpSrc {
|
||||||
let mut current_response = match response.take() {
|
let mut current_response = match response.take() {
|
||||||
Some(response) => response,
|
Some(response) => response,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, imp: self, "Don't have a response");
|
gst::error!(CAT, imp = self, "Don't have a response");
|
||||||
gst::element_imp_error!(self, gst::ResourceError::Read, ["Don't have a response"]);
|
gst::element_imp_error!(self, gst::ResourceError::Read, ["Don't have a response"]);
|
||||||
|
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
|
@ -1196,14 +1196,14 @@ impl PushSrcImpl for ReqwestHttpSrc {
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
if let Some(caps) = caps {
|
if let Some(caps) = caps {
|
||||||
gst::debug!(CAT, imp: self, "Setting caps {:?}", caps);
|
gst::debug!(CAT, imp = self, "Setting caps {:?}", caps);
|
||||||
self.obj()
|
self.obj()
|
||||||
.set_caps(&caps)
|
.set_caps(&caps)
|
||||||
.map_err(|_| gst::FlowError::NotNegotiated)?;
|
.map_err(|_| gst::FlowError::NotNegotiated)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(tags) = tags {
|
if let Some(tags) = tags {
|
||||||
gst::debug!(CAT, imp: self, "Sending iradio tags {:?}", tags);
|
gst::debug!(CAT, imp = self, "Sending iradio tags {:?}", tags);
|
||||||
self.obj().src_pad().push_event(gst::event::Tag::new(tags));
|
self.obj().src_pad().push_event(gst::event::Tag::new(tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1220,12 +1220,12 @@ impl PushSrcImpl for ReqwestHttpSrc {
|
||||||
let res = match res {
|
let res = match res {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(Some(err)) => {
|
Err(Some(err)) => {
|
||||||
gst::debug!(CAT, imp: self, "Error {:?}", err);
|
gst::debug!(CAT, imp = self, "Error {:?}", err);
|
||||||
self.post_error_message(err);
|
self.post_error_message(err);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
Err(None) => {
|
Err(None) => {
|
||||||
gst::debug!(CAT, imp: self, "Flushing");
|
gst::debug!(CAT, imp = self, "Flushing");
|
||||||
return Err(gst::FlowError::Flushing);
|
return Err(gst::FlowError::Flushing);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1250,7 +1250,7 @@ impl PushSrcImpl for ReqwestHttpSrc {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Chunk of {} bytes received at offset {}",
|
"Chunk of {} bytes received at offset {}",
|
||||||
chunk.len(),
|
chunk.len(),
|
||||||
offset
|
offset
|
||||||
|
@ -1274,7 +1274,7 @@ impl PushSrcImpl for ReqwestHttpSrc {
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
/* No further data, end of stream */
|
/* No further data, end of stream */
|
||||||
gst::debug!(CAT, imp: self, "End of stream");
|
gst::debug!(CAT, imp = self, "End of stream");
|
||||||
*response = Some(current_response);
|
*response = Some(current_response);
|
||||||
Err(gst::FlowError::Eos)
|
Err(gst::FlowError::Eos)
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
if payload.len() < 2 + 6 {
|
if payload.len() < 2 + 6 {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Payload too small: {} bytes, but need at least 8 bytes",
|
"Payload too small: {} bytes, but need at least 8 bytes",
|
||||||
payload.len(),
|
payload.len(),
|
||||||
);
|
);
|
||||||
|
@ -173,7 +173,7 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Have payload of {} bytes, header {:02x?} {:02x?}",
|
"Have payload of {} bytes, header {:02x?} {:02x?}",
|
||||||
payload.len(),
|
payload.len(),
|
||||||
payload[0],
|
payload[0],
|
||||||
|
@ -201,7 +201,7 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
|
|
||||||
if frag_type == FragType::Start || frag_type == FragType::NotFragmented {
|
if frag_type == FragType::Start || frag_type == FragType::NotFragmented {
|
||||||
if let Some(partial_frame) = state.partial_frame.as_ref() {
|
if let Some(partial_frame) = state.partial_frame.as_ref() {
|
||||||
gst::warning!(CAT, imp: self, "Dropping unfinished partial frame");
|
gst::warning!(CAT, imp = self, "Dropping unfinished partial frame");
|
||||||
|
|
||||||
self.obj()
|
self.obj()
|
||||||
.drop_packets(partial_frame.ext_seqnum..=packet.ext_seqnum() - 1);
|
.drop_packets(partial_frame.ext_seqnum..=packet.ext_seqnum() - 1);
|
||||||
|
@ -225,7 +225,7 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
ext_timestamp: packet.ext_timestamp(),
|
ext_timestamp: packet.ext_timestamp(),
|
||||||
});
|
});
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Partial frame {:?}", state.partial_frame);
|
gst::trace!(CAT, imp = self, "Partial frame {:?}", state.partial_frame);
|
||||||
|
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
let Some(partial_frame) = state.partial_frame.as_mut() else {
|
let Some(partial_frame) = state.partial_frame.as_mut() else {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"{frag_type:?} packet but no partial frame (most likely indicates packet loss)",
|
"{frag_type:?} packet but no partial frame (most likely indicates packet loss)",
|
||||||
);
|
);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
|
@ -245,7 +245,7 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
if partial_frame.ext_timestamp != packet.ext_timestamp() {
|
if partial_frame.ext_timestamp != packet.ext_timestamp() {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"{frag_type:?} packet timestamp {} doesn't match existing partial fragment timestamp {}",
|
"{frag_type:?} packet timestamp {} doesn't match existing partial fragment timestamp {}",
|
||||||
packet.ext_timestamp(),
|
packet.ext_timestamp(),
|
||||||
partial_frame.ext_timestamp,
|
partial_frame.ext_timestamp,
|
||||||
|
@ -259,7 +259,7 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Added {frag_type:?} packet payload, assembled {} bytes now",
|
"Added {frag_type:?} packet payload, assembled {} bytes now",
|
||||||
partial_frame.data.len()
|
partial_frame.data.len()
|
||||||
);
|
);
|
||||||
|
@ -268,18 +268,22 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
let partial_frame = state.partial_frame.take().unwrap();
|
let partial_frame = state.partial_frame.take().unwrap();
|
||||||
|
|
||||||
let Ok(hdr) = ac3_audio_utils::peek_frame_header(&partial_frame.data) else {
|
let Ok(hdr) = ac3_audio_utils::peek_frame_header(&partial_frame.data) else {
|
||||||
gst::warning!(CAT, imp: self, "Could not parse frame header, dropping frame");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Could not parse frame header, dropping frame"
|
||||||
|
);
|
||||||
self.obj()
|
self.obj()
|
||||||
.drop_packets(partial_frame.ext_seqnum..=packet.ext_seqnum());
|
.drop_packets(partial_frame.ext_seqnum..=packet.ext_seqnum());
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "{hdr:?}");
|
gst::trace!(CAT, imp = self, "{hdr:?}");
|
||||||
|
|
||||||
if partial_frame.data.len() != hdr.frame_len {
|
if partial_frame.data.len() != hdr.frame_len {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Partial frame finished, but have {} bytes, and expected {} bytes!",
|
"Partial frame finished, but have {} bytes, and expected {} bytes!",
|
||||||
partial_frame.data.len(),
|
partial_frame.data.len(),
|
||||||
hdr.frame_len,
|
hdr.frame_len,
|
||||||
|
@ -294,7 +298,7 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
|
|
||||||
outbuf_ref.set_duration(gst::ClockTime::from_nseconds(hdr.duration()));
|
outbuf_ref.set_duration(gst::ClockTime::from_nseconds(hdr.duration()));
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Finishing buffer {outbuf:?}");
|
gst::trace!(CAT, imp = self, "Finishing buffer {outbuf:?}");
|
||||||
|
|
||||||
return self.obj().queue_buffer(
|
return self.obj().queue_buffer(
|
||||||
PacketToBufferRelation::Seqnums(
|
PacketToBufferRelation::Seqnums(
|
||||||
|
@ -314,18 +318,22 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
|
|
||||||
while offset < payload.len() {
|
while offset < payload.len() {
|
||||||
let Ok(hdr) = ac3_audio_utils::peek_frame_header(&payload[offset..]) else {
|
let Ok(hdr) = ac3_audio_utils::peek_frame_header(&payload[offset..]) else {
|
||||||
gst::warning!(CAT, imp: self, "Could not parse frame header at offset {offset}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Could not parse frame header at offset {offset}"
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "{hdr:?} at offset {offset}");
|
gst::trace!(CAT, imp = self, "{hdr:?} at offset {offset}");
|
||||||
|
|
||||||
let frame_len = if offset + hdr.frame_len <= payload.len() {
|
let frame_len = if offset + hdr.frame_len <= payload.len() {
|
||||||
hdr.frame_len
|
hdr.frame_len
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Frame at offset {offset} is {} bytes, but we have only {} bytes left!",
|
"Frame at offset {offset} is {} bytes, but we have only {} bytes left!",
|
||||||
hdr.frame_len,
|
hdr.frame_len,
|
||||||
payload.len() - offset,
|
payload.len() - offset,
|
||||||
|
@ -336,7 +344,7 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
|
|
||||||
self.ensure_output_caps(&mut state, &hdr);
|
self.ensure_output_caps(&mut state, &hdr);
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Getting frame @ {offset}+{frame_len}");
|
gst::trace!(CAT, imp = self, "Getting frame @ {offset}+{frame_len}");
|
||||||
|
|
||||||
let mut outbuf =
|
let mut outbuf =
|
||||||
packet.payload_subbuffer_from_offset_with_length(offset, frame_len);
|
packet.payload_subbuffer_from_offset_with_length(offset, frame_len);
|
||||||
|
@ -345,7 +353,11 @@ impl RtpBaseDepay2Impl for RtpAc3Depay {
|
||||||
|
|
||||||
outbuf_ref.set_duration(gst::ClockTime::from_nseconds(hdr.duration()));
|
outbuf_ref.set_duration(gst::ClockTime::from_nseconds(hdr.duration()));
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Finishing frame @ {offset}, buffer {outbuf:?}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Finishing frame @ {offset}, buffer {outbuf:?}"
|
||||||
|
);
|
||||||
|
|
||||||
self.obj().queue_buffer(
|
self.obj().queue_buffer(
|
||||||
PacketToBufferRelation::SeqnumsWithOffset {
|
PacketToBufferRelation::SeqnumsWithOffset {
|
||||||
|
@ -381,7 +393,7 @@ impl RtpAc3Depay {
|
||||||
if state.clock_rate != Some(frame_header.sample_rate as i32) {
|
if state.clock_rate != Some(frame_header.sample_rate as i32) {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"clock-rate {} does not match sample rate {}!",
|
"clock-rate {} does not match sample rate {}!",
|
||||||
state.clock_rate.unwrap(),
|
state.clock_rate.unwrap(),
|
||||||
frame_header.sample_rate,
|
frame_header.sample_rate,
|
||||||
|
@ -395,7 +407,7 @@ impl RtpAc3Depay {
|
||||||
.field("alignment", "frame")
|
.field("alignment", "frame")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Setting output caps {src_caps}..");
|
gst::info!(CAT, imp = self, "Setting output caps {src_caps}..");
|
||||||
|
|
||||||
// Ignore failure here and let the next buffer push yield an appropriate flow return
|
// Ignore failure here and let the next buffer push yield an appropriate flow return
|
||||||
self.obj().set_src_caps(&src_caps);
|
self.obj().set_src_caps(&src_caps);
|
||||||
|
|
|
@ -326,12 +326,16 @@ impl RtpBasePay2Impl for RtpAc3Pay {
|
||||||
let mut settings = self.settings.lock().unwrap();
|
let mut settings = self.settings.lock().unwrap();
|
||||||
|
|
||||||
if buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
if buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
||||||
gst::debug!(CAT, imp: self, "Discont on {buffer:?}, pushing out any pending frames");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Discont on {buffer:?}, pushing out any pending frames"
|
||||||
|
);
|
||||||
self.send_packets(&settings, &mut state, SendPacketMode::ForcePending)?;
|
self.send_packets(&settings, &mut state, SendPacketMode::ForcePending)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let map = buffer.clone().into_mapped_buffer_readable().map_err(|_| {
|
let map = buffer.clone().into_mapped_buffer_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Can't map buffer readable");
|
gst::error!(CAT, imp = self, "Can't map buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -350,7 +354,7 @@ impl RtpBasePay2Impl for RtpAc3Pay {
|
||||||
let Ok(frame_hdr) = ac3_audio_utils::peek_frame_header(&data[map_offset..]) else {
|
let Ok(frame_hdr) = ac3_audio_utils::peek_frame_header(&data[map_offset..]) else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to parse AC-3 audio frame header for {buffer:?} at offset {map_offset}",
|
"Failed to parse AC-3 audio frame header for {buffer:?} at offset {map_offset}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -376,7 +380,11 @@ impl RtpBasePay2Impl for RtpAc3Pay {
|
||||||
let frame_dur = queued_frame.duration();
|
let frame_dur = queued_frame.duration();
|
||||||
|
|
||||||
if map_offset + frame_len > data.len() {
|
if map_offset + frame_len > data.len() {
|
||||||
gst::warning!(CAT, imp: self, "Short audio frame for {buffer:?} at offset {map_offset}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Short audio frame for {buffer:?} at offset {map_offset}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pts_offset += frame_dur;
|
pts_offset += frame_dur;
|
||||||
|
@ -426,7 +434,7 @@ impl RtpBasePay2Impl for RtpAc3Pay {
|
||||||
let mut live_guard = self.is_live.lock().unwrap();
|
let mut live_guard = self.is_live.lock().unwrap();
|
||||||
|
|
||||||
if Some(is_live) != *live_guard {
|
if Some(is_live) != *live_guard {
|
||||||
gst::info!(CAT, imp: self, "Upstream is live: {is_live}");
|
gst::info!(CAT, imp = self, "Upstream is live: {is_live}");
|
||||||
*live_guard = Some(is_live);
|
*live_guard = Some(is_live);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,7 +446,7 @@ impl RtpBasePay2Impl for RtpAc3Pay {
|
||||||
} else if is_live {
|
} else if is_live {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Aggregating packets in live mode, but no max_ptime configured. \
|
"Aggregating packets in live mode, but no max_ptime configured. \
|
||||||
Configured latency may be too low!",
|
Configured latency may be too low!",
|
||||||
);
|
);
|
||||||
|
@ -565,19 +573,20 @@ impl RtpAc3Pay {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Queued: size {queue_size}, duration ~{}ms, mode: {:?} + {:?} => ready: {}",
|
"Queued: size {queue_size}, duration ~{}ms, mode: {:?} + {:?} => ready: {}",
|
||||||
queue_duration / 1_000_000,
|
queue_duration / 1_000_000,
|
||||||
agg_mode,
|
agg_mode,
|
||||||
send_mode,
|
send_mode,
|
||||||
is_ready);
|
is_ready
|
||||||
|
);
|
||||||
|
|
||||||
if !is_ready {
|
if !is_ready {
|
||||||
gst::log!(CAT, imp: self, "Not ready yet, waiting for more data");
|
gst::log!(CAT, imp = self, "Not ready yet, waiting for more data");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Creating packet..");
|
gst::trace!(CAT, imp = self, "Creating packet..");
|
||||||
|
|
||||||
let pts_offset = gst::ClockTime::from_nseconds(first.pts_offset);
|
let pts_offset = gst::ClockTime::from_nseconds(first.pts_offset);
|
||||||
|
|
||||||
|
@ -593,9 +602,10 @@ impl RtpAc3Pay {
|
||||||
for frame in &state.queued_frames {
|
for frame in &state.queued_frames {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"{frame:?}, accumulated size {acc_size} duration ~{}ms",
|
"{frame:?}, accumulated size {acc_size} duration ~{}ms",
|
||||||
acc_duration / 1_000_000);
|
acc_duration / 1_000_000
|
||||||
|
);
|
||||||
|
|
||||||
// If this frame would overflow the packet, bail out and send out what we have.
|
// If this frame would overflow the packet, bail out and send out what we have.
|
||||||
//
|
//
|
||||||
|
@ -651,7 +661,12 @@ impl RtpAc3Pay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "All done for now, {} frames queued", state.queued_frames.len());
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"All done for now, {} frames queued",
|
||||||
|
state.queued_frames.len()
|
||||||
|
);
|
||||||
|
|
||||||
if send_mode == SendPacketMode::ForcePending {
|
if send_mode == SendPacketMode::ForcePending {
|
||||||
self.obj().finish_pending_packets()?;
|
self.obj().finish_pending_packets()?;
|
||||||
|
@ -691,7 +706,7 @@ impl RtpAc3Pay {
|
||||||
|
|
||||||
*self.is_live.lock().unwrap() = Some(is_live);
|
*self.is_live.lock().unwrap() = Some(is_live);
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Upstream is live: {is_live}");
|
gst::info!(CAT, imp = self, "Upstream is live: {is_live}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can get max ptime or ptime recommendations/restrictions from multiple places, e.g. the
|
// We can get max ptime or ptime recommendations/restrictions from multiple places, e.g. the
|
||||||
|
|
|
@ -10,14 +10,14 @@
|
||||||
macro_rules! err_flow {
|
macro_rules! err_flow {
|
||||||
($imp:ident, read, $msg:literal) => {
|
($imp:ident, read, $msg:literal) => {
|
||||||
|err| {
|
|err| {
|
||||||
gst::warning!(CAT, imp: $imp, $msg, err);
|
gst::warning!(CAT, imp = $imp, $msg, err);
|
||||||
gst::element_imp_warning!($imp, gst::ResourceError::Read, [$msg, err]);
|
gst::element_imp_warning!($imp, gst::ResourceError::Read, [$msg, err]);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($imp:ident, write, $msg:literal) => {
|
($imp:ident, write, $msg:literal) => {
|
||||||
|err| {
|
|err| {
|
||||||
gst::warning!(CAT, imp: $imp, $msg, err);
|
gst::warning!(CAT, imp = $imp, $msg, err);
|
||||||
gst::element_imp_warning!($imp, gst::ResourceError::Write, [$msg, err]);
|
gst::element_imp_warning!($imp, gst::ResourceError::Write, [$msg, err]);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ static TEMPORAL_DELIMITER: [u8; 2] = [0b0001_0010, 0];
|
||||||
|
|
||||||
impl RTPAv1Depay {
|
impl RTPAv1Depay {
|
||||||
fn reset(&self, state: &mut State) {
|
fn reset(&self, state: &mut State) {
|
||||||
gst::debug!(CAT, imp: self, "resetting state");
|
gst::debug!(CAT, imp = self, "resetting state");
|
||||||
|
|
||||||
*state = State::default()
|
*state = State::default()
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RTPAv1Depay {
|
||||||
.queue_buffer(PacketToBufferRelation::Seqnums(seqnums), buffer),
|
.queue_buffer(PacketToBufferRelation::Seqnums(seqnums), buffer),
|
||||||
Ok(None) => Ok(gst::FlowSuccess::Ok),
|
Ok(None) => Ok(gst::FlowSuccess::Ok),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Failed to handle RTP packet: {err:?}");
|
gst::warning!(CAT, imp = self, "Failed to handle RTP packet: {err:?}");
|
||||||
self.reset(&mut self.state.borrow_mut());
|
self.reset(&mut self.state.borrow_mut());
|
||||||
self.obj().drop_packets(..=packet.ext_seqnum());
|
self.obj().drop_packets(..=packet.ext_seqnum());
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
|
@ -191,11 +191,7 @@ impl RTPAv1Depay {
|
||||||
&self,
|
&self,
|
||||||
packet: &crate::basedepay::Packet,
|
packet: &crate::basedepay::Packet,
|
||||||
) -> Result<Option<(RangeInclusive<u64>, gst::Buffer)>, gst::FlowError> {
|
) -> Result<Option<(RangeInclusive<u64>, gst::Buffer)>, gst::FlowError> {
|
||||||
gst::trace!(
|
gst::trace!(CAT, imp = self, "Processing RTP packet {packet:?}",);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Processing RTP packet {packet:?}",
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
|
|
||||||
|
@ -210,14 +206,14 @@ impl RTPAv1Depay {
|
||||||
AggregationHeader::from(&byte)
|
AggregationHeader::from(&byte)
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Aggregation header {aggr_header:?}");
|
gst::trace!(CAT, imp = self, "Aggregation header {aggr_header:?}");
|
||||||
|
|
||||||
// handle new temporal units
|
// handle new temporal units
|
||||||
if state.marked_packet || state.last_timestamp != Some(packet.ext_timestamp()) {
|
if state.marked_packet || state.last_timestamp != Some(packet.ext_timestamp()) {
|
||||||
if state.last_timestamp.is_some() && state.obu_fragment.is_some() {
|
if state.last_timestamp.is_some() && state.obu_fragment.is_some() {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
concat!(
|
concat!(
|
||||||
"invalid packet: packet is part of a new TU but ",
|
"invalid packet: packet is part of a new TU but ",
|
||||||
"the previous TU still has an incomplete OBU",
|
"the previous TU still has an incomplete OBU",
|
||||||
|
@ -243,7 +239,7 @@ impl RTPAv1Depay {
|
||||||
if state.obu_fragment.is_some() && !aggr_header.leading_fragment {
|
if state.obu_fragment.is_some() && !aggr_header.leading_fragment {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"invalid packet: dropping unclosed OBU fragment"
|
"invalid packet: dropping unclosed OBU fragment"
|
||||||
);
|
);
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
|
@ -294,7 +290,7 @@ impl RTPAv1Depay {
|
||||||
if state.found_valid_obu {
|
if state.found_valid_obu {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"invalid packet: unexpected leading OBU fragment"
|
"invalid packet: unexpected leading OBU fragment"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -327,7 +323,7 @@ impl RTPAv1Depay {
|
||||||
if remaining_slice.len() < element_size as usize {
|
if remaining_slice.len() < element_size as usize {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"invalid packet: not enough data left for OBU {idx} (needed {element_size}, have {})",
|
"invalid packet: not enough data left for OBU {idx} (needed {element_size}, have {})",
|
||||||
remaining_slice.len(),
|
remaining_slice.len(),
|
||||||
);
|
);
|
||||||
|
@ -355,7 +351,7 @@ impl RTPAv1Depay {
|
||||||
let buffer = if !ready_obus.is_empty() && ready_obus != TEMPORAL_DELIMITER {
|
let buffer = if !ready_obus.is_empty() && ready_obus != TEMPORAL_DELIMITER {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Creating buffer containing {} bytes of data (marker {}, discont {})...",
|
"Creating buffer containing {} bytes of data (marker {}, discont {})...",
|
||||||
ready_obus.len(),
|
ready_obus.len(),
|
||||||
state.marked_packet,
|
state.marked_packet,
|
||||||
|
@ -384,7 +380,7 @@ impl RTPAv1Depay {
|
||||||
if state.marked_packet && state.obu_fragment.is_some() {
|
if state.marked_packet && state.obu_fragment.is_some() {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
concat!(
|
concat!(
|
||||||
"invalid packet: has marker bit set, but ",
|
"invalid packet: has marker bit set, but ",
|
||||||
"last OBU is not yet complete. Dropping incomplete OBU."
|
"last OBU is not yet complete. Dropping incomplete OBU."
|
||||||
|
@ -437,7 +433,7 @@ impl RTPAv1Depay {
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"invalid packet: size field gives impossibly large OBU size"
|
"invalid packet: size field gives impossibly large OBU size"
|
||||||
);
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
|
@ -516,7 +512,7 @@ impl RTPAv1Depay {
|
||||||
if first {
|
if first {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Trailing payload unit is not a valid OBU");
|
gst::warning!(CAT, imp = self, "Trailing payload unit is not a valid OBU");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -526,23 +522,31 @@ impl RTPAv1Depay {
|
||||||
.seek(SeekFrom::Start(header_pos))
|
.seek(SeekFrom::Start(header_pos))
|
||||||
.map_err(err_flow!(self, buf_read))?;
|
.map_err(err_flow!(self, buf_read))?;
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Handling OBU {obu:?}");
|
gst::trace!(CAT, imp = self, "Handling OBU {obu:?}");
|
||||||
|
|
||||||
let remaining_slice = &reader.get_ref()[reader.position() as usize..];
|
let remaining_slice = &reader.get_ref()[reader.position() as usize..];
|
||||||
let element_size = if let Some((size, leb_size)) = obu.size {
|
let element_size = if let Some((size, leb_size)) = obu.size {
|
||||||
let size = (size + leb_size + obu.header_len) as usize;
|
let size = (size + leb_size + obu.header_len) as usize;
|
||||||
if size > remaining_slice.len() {
|
if size > remaining_slice.len() {
|
||||||
if first {
|
if first {
|
||||||
gst::warning!(CAT, imp: self, "Payload unit starts with an incomplete OBU");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Payload unit starts with an incomplete OBU"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Trailing payload unit is an incomplete OBU");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Trailing payload unit is an incomplete OBU"
|
||||||
|
);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !first {
|
if !first {
|
||||||
gst::debug!(CAT, imp: self, "Multiple OBUs in a single payload unit");
|
gst::debug!(CAT, imp = self, "Multiple OBUs in a single payload unit");
|
||||||
}
|
}
|
||||||
size
|
size
|
||||||
} else {
|
} else {
|
||||||
|
@ -557,7 +561,12 @@ impl RTPAv1Depay {
|
||||||
obu.obu_type,
|
obu.obu_type,
|
||||||
ObuType::TemporalDelimiter | ObuType::TileList | ObuType::Padding
|
ObuType::TemporalDelimiter | ObuType::TileList | ObuType::Padding
|
||||||
) {
|
) {
|
||||||
gst::trace!(CAT, imp: self, "Dropping {:?} of size {element_size}", obu.obu_type);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Dropping {:?} of size {element_size}",
|
||||||
|
obu.obu_type
|
||||||
|
);
|
||||||
reader
|
reader
|
||||||
.seek(SeekFrom::Current(element_size as i64))
|
.seek(SeekFrom::Current(element_size as i64))
|
||||||
.map_err(err_flow!(self, buf_read))?;
|
.map_err(err_flow!(self, buf_read))?;
|
||||||
|
|
|
@ -84,7 +84,7 @@ pub struct RTPAv1Pay {
|
||||||
|
|
||||||
impl RTPAv1Pay {
|
impl RTPAv1Pay {
|
||||||
fn reset(&self, state: &mut State, full: bool) {
|
fn reset(&self, state: &mut State, full: bool) {
|
||||||
gst::debug!(CAT, imp: self, "resetting state");
|
gst::debug!(CAT, imp = self, "resetting state");
|
||||||
|
|
||||||
if full {
|
if full {
|
||||||
*state = State::default();
|
*state = State::default();
|
||||||
|
@ -118,7 +118,7 @@ impl RTPAv1Pay {
|
||||||
match obu.obu_type {
|
match obu.obu_type {
|
||||||
// completely ignore tile lists and padding
|
// completely ignore tile lists and padding
|
||||||
ObuType::TileList | ObuType::Padding => {
|
ObuType::TileList | ObuType::Padding => {
|
||||||
gst::log!(CAT, imp: self, "ignoring {:?} OBU", obu.obu_type);
|
gst::log!(CAT, imp = self, "ignoring {:?} OBU", obu.obu_type);
|
||||||
reader
|
reader
|
||||||
.seek(SeekFrom::Current(obu.size as i64))
|
.seek(SeekFrom::Current(obu.size as i64))
|
||||||
.map_err(err_flow!(self, buf_read))?;
|
.map_err(err_flow!(self, buf_read))?;
|
||||||
|
@ -200,7 +200,7 @@ impl RTPAv1Pay {
|
||||||
) -> Option<PacketOBUData> {
|
) -> Option<PacketOBUData> {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"{} new packet, currently storing {} OBUs (marker {})",
|
"{} new packet, currently storing {} OBUs (marker {})",
|
||||||
if force { "forcing" } else { "considering" },
|
if force { "forcing" } else { "considering" },
|
||||||
state.obus.len(),
|
state.obus.len(),
|
||||||
|
@ -239,13 +239,13 @@ impl RTPAv1Pay {
|
||||||
if current.obu_type == ObuType::TemporalDelimiter {
|
if current.obu_type == ObuType::TemporalDelimiter {
|
||||||
// ignore the temporal delimiter, it is not supposed to be transmitted,
|
// ignore the temporal delimiter, it is not supposed to be transmitted,
|
||||||
// it will be skipped later when building the packet
|
// it will be skipped later when building the packet
|
||||||
gst::log!(CAT, imp: self, "ignoring temporal delimiter OBU");
|
gst::log!(CAT, imp = self, "ignoring temporal delimiter OBU");
|
||||||
|
|
||||||
if packet.obu_count > 0 {
|
if packet.obu_count > 0 {
|
||||||
if marker {
|
if marker {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Temporal delimited in the middle of a frame"
|
"Temporal delimited in the middle of a frame"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ impl RTPAv1Pay {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"constructing new RTP packet with {} OBUs",
|
"constructing new RTP packet with {} OBUs",
|
||||||
packet.obu_count
|
packet.obu_count
|
||||||
);
|
);
|
||||||
|
@ -475,7 +475,7 @@ impl RTPAv1Pay {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"generated RTP packet of size {}",
|
"generated RTP packet of size {}",
|
||||||
payload.len()
|
payload.len()
|
||||||
);
|
);
|
||||||
|
@ -567,7 +567,7 @@ impl crate::basepay::RtpBasePay2Impl for RTPAv1Pay {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_sink_caps(&self, caps: &gst::Caps) -> bool {
|
fn set_sink_caps(&self, caps: &gst::Caps) -> bool {
|
||||||
gst::debug!(CAT, imp: self, "received caps {caps:?}");
|
gst::debug!(CAT, imp = self, "received caps {caps:?}");
|
||||||
|
|
||||||
self.obj().set_src_caps(
|
self.obj().set_src_caps(
|
||||||
&gst::Caps::builder("application/x-rtp")
|
&gst::Caps::builder("application/x-rtp")
|
||||||
|
@ -596,7 +596,7 @@ impl crate::basepay::RtpBasePay2Impl for RTPAv1Pay {
|
||||||
buffer: &gst::Buffer,
|
buffer: &gst::Buffer,
|
||||||
id: u64,
|
id: u64,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::trace!(CAT, imp: self, "received buffer of size {}", buffer.size());
|
gst::trace!(CAT, imp = self, "received buffer of size {}", buffer.size());
|
||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
|
|
|
@ -271,7 +271,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpBaseAudioPay2 {
|
||||||
id: u64,
|
id: u64,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let buffer = buffer.clone().into_mapped_buffer_readable().map_err(|_| {
|
let buffer = buffer.clone().into_mapped_buffer_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Can't map buffer readable");
|
gst::error!(CAT, imp = self, "Can't map buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let pts = buffer.buffer().pts().unwrap();
|
let pts = buffer.buffer().pts().unwrap();
|
||||||
|
@ -297,7 +297,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpBaseAudioPay2 {
|
||||||
|
|
||||||
if discont {
|
if discont {
|
||||||
if state.audio_discont.base_pts().is_some() {
|
if state.audio_discont.base_pts().is_some() {
|
||||||
gst::debug!(CAT, imp: self, "Draining because of discontinuity");
|
gst::debug!(CAT, imp = self, "Draining because of discontinuity");
|
||||||
self.drain_packets(&settings, &mut state, true)?;
|
self.drain_packets(&settings, &mut state, true)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ impl RtpBaseAudioPay2 {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"min ptime {} (frames: {}), max ptime {} (frames: {}), ptime multiple {} (frames {})",
|
"min ptime {} (frames: {}), max ptime {} (frames: {}), ptime multiple {} (frames {})",
|
||||||
settings.min_ptime,
|
settings.min_ptime,
|
||||||
min_pframes,
|
min_pframes,
|
||||||
|
@ -426,7 +426,7 @@ impl RtpBaseAudioPay2 {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Currently {} bytes queued, min packet size {min_packet_size}, max packet size {max_packet_size}, force {force}",
|
"Currently {} bytes queued, min packet size {min_packet_size}, max packet size {max_packet_size}, force {force}",
|
||||||
state.queued_bytes,
|
state.queued_bytes,
|
||||||
);
|
);
|
||||||
|
@ -440,7 +440,7 @@ impl RtpBaseAudioPay2 {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Creating packet of size {packet_size} ({} frames), marker {}",
|
"Creating packet of size {packet_size} ({} frames), marker {}",
|
||||||
packet_size / bpf,
|
packet_size / bpf,
|
||||||
state.audio_discont.next_output_offset().is_none(),
|
state.audio_discont.next_output_offset().is_none(),
|
||||||
|
@ -502,7 +502,13 @@ impl RtpBaseAudioPay2 {
|
||||||
state.audio_discont.process_output(packet_size / bpf);
|
state.audio_discont.process_output(packet_size / bpf);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Currently {} bytes / {} frames queued", state.queued_bytes, state.queued_bytes / bpf);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Currently {} bytes / {} frames queued",
|
||||||
|
state.queued_bytes,
|
||||||
|
state.queued_bytes / bpf
|
||||||
|
);
|
||||||
|
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,11 +224,11 @@ impl Ord for CapsOrd {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl RtpBaseDepay2 {
|
impl RtpBaseDepay2 {
|
||||||
pub(super) fn set_src_caps(&self, src_caps: &gst::Caps) {
|
pub(super) fn set_src_caps(&self, src_caps: &gst::Caps) {
|
||||||
gst::debug!(CAT, imp: self, "Setting caps {src_caps:?}");
|
gst::debug!(CAT, imp = self, "Setting caps {src_caps:?}");
|
||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
if Some(src_caps) == state.src_caps.as_ref() {
|
if Some(src_caps) == state.src_caps.as_ref() {
|
||||||
gst::debug!(CAT, imp: self, "Setting same caps {src_caps:?} again");
|
gst::debug!(CAT, imp = self, "Setting same caps {src_caps:?} again");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,12 @@ impl RtpBaseDepay2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn drop_packets(&self, ext_seqnum: impl RangeBounds<u64>) {
|
pub(super) fn drop_packets(&self, ext_seqnum: impl RangeBounds<u64>) {
|
||||||
gst::trace!(CAT, imp: self, "Dropping packets up to ext seqnum {:?}", ext_seqnum.end_bound());
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Dropping packets up to ext seqnum {:?}",
|
||||||
|
ext_seqnum.end_bound()
|
||||||
|
);
|
||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
state.discont_pending = true;
|
state.discont_pending = true;
|
||||||
|
@ -378,7 +383,11 @@ impl RtpBaseDepay2 {
|
||||||
0xBEDE => gst_rtp::RTPHeaderExtensionFlags::ONE_BYTE,
|
0xBEDE => gst_rtp::RTPHeaderExtensionFlags::ONE_BYTE,
|
||||||
x if x >> 4 == 0x100 => gst_rtp::RTPHeaderExtensionFlags::TWO_BYTE,
|
x if x >> 4 == 0x100 => gst_rtp::RTPHeaderExtensionFlags::TWO_BYTE,
|
||||||
_ => {
|
_ => {
|
||||||
gst::trace!(CAT, imp: self, "Unknown extension pattern {extension_pattern:04X}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Unknown extension pattern {extension_pattern:04X}"
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -425,7 +434,11 @@ impl RtpBaseDepay2 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Handling RTP header extension with id {id} and length {len}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Handling RTP header extension with id {id} and length {len}"
|
||||||
|
);
|
||||||
|
|
||||||
let (extension_data, remainder) = extensions_data.split_at(len);
|
let (extension_data, remainder) = extensions_data.split_at(len);
|
||||||
extensions_data = remainder;
|
extensions_data = remainder;
|
||||||
|
@ -435,7 +448,11 @@ impl RtpBaseDepay2 {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !extension.read(extension_flags, extension_data, buffer) {
|
if !extension.read(extension_flags, extension_data, buffer) {
|
||||||
gst::warning!(CAT, imp: self, "Failed reading RTP header extension with id {id} and length {len}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed reading RTP header extension with id {id} and length {len}"
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,16 +495,24 @@ impl RtpBaseDepay2 {
|
||||||
buffer_ref.set_dts(None);
|
buffer_ref.set_dts(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Queueing buffer {buffer:?} for seqnum range {packet_to_buffer_relation:?}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Queueing buffer {buffer:?} for seqnum range {packet_to_buffer_relation:?}"
|
||||||
|
);
|
||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
if state.src_caps.is_none() {
|
if state.src_caps.is_none() {
|
||||||
gst::error!(CAT, imp: self, "No source pad caps negotiated yet");
|
gst::error!(CAT, imp = self, "No source pad caps negotiated yet");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(packet_to_buffer_relation, PacketToBufferRelation::OutOfBand) {
|
if matches!(packet_to_buffer_relation, PacketToBufferRelation::OutOfBand) {
|
||||||
gst::trace!(CAT, imp: self, "Keeping buffer without associated seqnums until next buffer or EOS");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Keeping buffer without associated seqnums until next buffer or EOS"
|
||||||
|
);
|
||||||
|
|
||||||
state.pending_buffers.push_back(PendingBuffer {
|
state.pending_buffers.push_back(PendingBuffer {
|
||||||
metadata_set: false,
|
metadata_set: false,
|
||||||
|
@ -506,7 +531,7 @@ impl RtpBaseDepay2 {
|
||||||
};
|
};
|
||||||
|
|
||||||
if seqnums.is_empty() {
|
if seqnums.is_empty() {
|
||||||
gst::error!(CAT, imp: self, "Empty packet ext seqnum range provided");
|
gst::error!(CAT, imp = self, "Empty packet ext seqnum range provided");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,16 +545,29 @@ impl RtpBaseDepay2 {
|
||||||
.is_some_and(|p| p.ext_seqnum < seqnum_start)
|
.is_some_and(|p| p.ext_seqnum < seqnum_start)
|
||||||
{
|
{
|
||||||
let p = state.pending_packets.pop_front().unwrap();
|
let p = state.pending_packets.pop_front().unwrap();
|
||||||
gst::trace!(CAT, imp: self, "Dropping packet with extended seqnum {}", p.ext_seqnum);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Dropping packet with extended seqnum {}",
|
||||||
|
p.ext_seqnum
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.pending_packets.is_empty() {
|
if state.pending_packets.is_empty() {
|
||||||
gst::error!(CAT, imp: self, "Queueing buffers for future ext seqnums not allowed");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Queueing buffers for future ext seqnums not allowed"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
};
|
};
|
||||||
|
|
||||||
if seqnum_end > state.pending_packets.back().unwrap().ext_seqnum {
|
if seqnum_end > state.pending_packets.back().unwrap().ext_seqnum {
|
||||||
gst::error!(CAT, imp: self, "Queueing buffers for future ext seqnums not allowed");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Queueing buffers for future ext seqnums not allowed"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +589,12 @@ impl RtpBaseDepay2 {
|
||||||
if let Some(ts) = pts_signed.positive() {
|
if let Some(ts) = pts_signed.positive() {
|
||||||
pts = Some(ts);
|
pts = Some(ts);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Negative PTS {} calculated, not supported", pts_signed);
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Negative PTS {} calculated, not supported",
|
||||||
|
pts_signed
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,7 +604,12 @@ impl RtpBaseDepay2 {
|
||||||
if let Some(ts) = pts_signed.positive() {
|
if let Some(ts) = pts_signed.positive() {
|
||||||
pts = Some(ts);
|
pts = Some(ts);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Negative PTS {} calculated, not supported", pts_signed);
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Negative PTS {} calculated, not supported",
|
||||||
|
pts_signed
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,7 +618,12 @@ impl RtpBaseDepay2 {
|
||||||
if let Some(ts) = dts_signed.positive() {
|
if let Some(ts) = dts_signed.positive() {
|
||||||
dts = Some(ts);
|
dts = Some(ts);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Negative DTS {} calculated, not supported", dts_signed);
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Negative DTS {} calculated, not supported",
|
||||||
|
dts_signed
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,7 +676,12 @@ impl RtpBaseDepay2 {
|
||||||
let extensions = self.extensions.lock().unwrap();
|
let extensions = self.extensions.lock().unwrap();
|
||||||
for extension in extensions.values() {
|
for extension in extensions.values() {
|
||||||
if !extension.update_non_rtp_src_caps(src_caps) {
|
if !extension.update_non_rtp_src_caps(src_caps) {
|
||||||
gst::error!(CAT, imp: self, "RTP header extension {} could not update caps", extension.name());
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"RTP header extension {} could not update caps",
|
||||||
|
extension.name()
|
||||||
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -679,7 +737,7 @@ impl RtpBaseDepay2 {
|
||||||
|
|
||||||
assert_ne!(num_buffers, 0);
|
assert_ne!(num_buffers, 0);
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Flushing {num_buffers} buffers");
|
gst::trace!(CAT, imp = self, "Flushing {num_buffers} buffers");
|
||||||
|
|
||||||
let segment_event = self.retrieve_pending_segment_event(&mut state);
|
let segment_event = self.retrieve_pending_segment_event(&mut state);
|
||||||
|
|
||||||
|
@ -690,7 +748,7 @@ impl RtpBaseDepay2 {
|
||||||
|
|
||||||
let buffers = if num_buffers == 1 {
|
let buffers = if num_buffers == 1 {
|
||||||
let buffer = state.pending_buffers.pop_front().unwrap().buffer;
|
let buffer = state.pending_buffers.pop_front().unwrap().buffer;
|
||||||
gst::trace!(CAT, imp: self, "Finishing buffer {buffer:?}");
|
gst::trace!(CAT, imp = self, "Finishing buffer {buffer:?}");
|
||||||
BufferOrList::Buffer(buffer)
|
BufferOrList::Buffer(buffer)
|
||||||
} else {
|
} else {
|
||||||
let mut list = gst::BufferList::new_sized(num_buffers);
|
let mut list = gst::BufferList::new_sized(num_buffers);
|
||||||
|
@ -700,7 +758,7 @@ impl RtpBaseDepay2 {
|
||||||
b.metadata_set && (b.buffer.pts() == pts || b.buffer.pts().is_none())
|
b.metadata_set && (b.buffer.pts() == pts || b.buffer.pts().is_none())
|
||||||
}) {
|
}) {
|
||||||
let buffer = state.pending_buffers.pop_front().unwrap().buffer;
|
let buffer = state.pending_buffers.pop_front().unwrap().buffer;
|
||||||
gst::trace!(CAT, imp: self, "Finishing buffer {buffer:?}");
|
gst::trace!(CAT, imp = self, "Finishing buffer {buffer:?}");
|
||||||
list.add(buffer);
|
list.add(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -721,9 +779,9 @@ impl RtpBaseDepay2 {
|
||||||
|
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
||||||
gst::warning!(CAT, imp: self, "Failed pushing buffers: {err:?}");
|
gst::warning!(CAT, imp = self, "Failed pushing buffers: {err:?}");
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Failed pushing buffers: {err:?}");
|
gst::debug!(CAT, imp = self, "Failed pushing buffers: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -782,7 +840,7 @@ impl RtpBaseDepay2 {
|
||||||
|
|
||||||
let state = self.state.borrow();
|
let state = self.state.borrow();
|
||||||
if state.sink_caps.is_none() {
|
if state.sink_caps.is_none() {
|
||||||
gst::warning!(CAT, imp: self, "Received segment before caps");
|
gst::warning!(CAT, imp = self, "Received segment before caps");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,14 +856,14 @@ impl RtpBaseDepay2 {
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
if !same_segment {
|
if !same_segment {
|
||||||
gst::debug!(CAT, imp: self, "Received segment {segment:?}");
|
gst::debug!(CAT, imp = self, "Received segment {segment:?}");
|
||||||
|
|
||||||
if drain {
|
if drain {
|
||||||
if let Err(err) = self.drain() {
|
if let Err(err) = self.drain() {
|
||||||
// Just continue here. The depayloader is now flushed and can proceed below,
|
// Just continue here. The depayloader is now flushed and can proceed below,
|
||||||
// and if there was a serious error downstream it will happen on the next
|
// and if there was a serious error downstream it will happen on the next
|
||||||
// buffer pushed downstream
|
// buffer pushed downstream
|
||||||
gst::debug!(CAT, imp: self, "Draining failed: {err:?}");
|
gst::debug!(CAT, imp = self, "Draining failed: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,7 +872,11 @@ impl RtpBaseDepay2 {
|
||||||
state.segment = Some((event.seqnum(), segment.clone()));
|
state.segment = Some((event.seqnum(), segment.clone()));
|
||||||
state.pending_segment = true;
|
state.pending_segment = true;
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Segments in non-TIME format are not supported");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Segments in non-TIME format are not supported"
|
||||||
|
);
|
||||||
state.segment = None;
|
state.segment = None;
|
||||||
// FIXME: Forget everything here?
|
// FIXME: Forget everything here?
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
|
@ -825,7 +887,7 @@ impl RtpBaseDepay2 {
|
||||||
}
|
}
|
||||||
gst::EventView::Eos(_) => {
|
gst::EventView::Eos(_) => {
|
||||||
if let Err(err) = self.drain() {
|
if let Err(err) = self.drain() {
|
||||||
gst::debug!(CAT, imp: self, "Draining on EOS failed: {err:?}");
|
gst::debug!(CAT, imp = self, "Draining on EOS failed: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst::EventView::FlushStop(_) => {
|
gst::EventView::FlushStop(_) => {
|
||||||
|
@ -844,7 +906,7 @@ impl RtpBaseDepay2 {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Forwarding event: {event:?}");
|
gst::debug!(CAT, imp = self, "Forwarding event: {event:?}");
|
||||||
if self.src_pad.push_event(event) {
|
if self.src_pad.push_event(event) {
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
} else if self.src_pad.pad_flags().contains(gst::PadFlags::FLUSHING) {
|
} else if self.src_pad.pad_flags().contains(gst::PadFlags::FLUSHING) {
|
||||||
|
@ -883,7 +945,7 @@ impl RtpBaseDepay2 {
|
||||||
if tags.len() > 1 {
|
if tags.len() > 1 {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Not copying meta {}: has multiple tags {tags:?}",
|
"Not copying meta {}: has multiple tags {tags:?}",
|
||||||
meta.api(),
|
meta.api(),
|
||||||
);
|
);
|
||||||
|
@ -897,7 +959,7 @@ impl RtpBaseDepay2 {
|
||||||
if !allowed_tags.iter().copied().any(|tag| tag == *meta_tag) {
|
if !allowed_tags.iter().copied().any(|tag| tag == *meta_tag) {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Not copying meta {}: tag '{meta_tag}' not allowed",
|
"Not copying meta {}: tag '{meta_tag}' not allowed",
|
||||||
meta.api(),
|
meta.api(),
|
||||||
);
|
);
|
||||||
|
@ -905,10 +967,10 @@ impl RtpBaseDepay2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Copying meta {}", meta.api());
|
gst::trace!(CAT, imp = self, "Copying meta {}", meta.api());
|
||||||
|
|
||||||
if let Err(err) = meta.transform(out_buf, &gst::meta::MetaTransformCopy::new(false, ..)) {
|
if let Err(err) = meta.transform(out_buf, &gst::meta::MetaTransformCopy::new(false, ..)) {
|
||||||
gst::trace!(CAT, imp: self, "Could not copy meta {}: {err}", meta.api());
|
gst::trace!(CAT, imp = self, "Could not copy meta {}: {err}", meta.api());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,7 +1004,7 @@ impl RtpBaseDepay2 {
|
||||||
let Some(ext) = gst_rtp::RTPHeaderExtension::create_from_uri(uri) else {
|
let Some(ext) = gst_rtp::RTPHeaderExtension::create_from_uri(uri) else {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Didn't find any extension implementing URI {uri}",
|
"Didn't find any extension implementing URI {uri}",
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
|
@ -950,7 +1012,7 @@ impl RtpBaseDepay2 {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Automatically enabling extension {} for URI {uri}",
|
"Automatically enabling extension {} for URI {uri}",
|
||||||
ext.name(),
|
ext.name(),
|
||||||
);
|
);
|
||||||
|
@ -968,7 +1030,7 @@ impl RtpBaseDepay2 {
|
||||||
_pad: &gst::Pad,
|
_pad: &gst::Pad,
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::trace!(CAT, imp: self, "Received buffer {buffer:?}");
|
gst::trace!(CAT, imp = self, "Received buffer {buffer:?}");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
self.handle_buffer(&settings, buffer)
|
self.handle_buffer(&settings, buffer)
|
||||||
|
@ -979,7 +1041,7 @@ impl RtpBaseDepay2 {
|
||||||
_pad: &gst::Pad,
|
_pad: &gst::Pad,
|
||||||
list: gst::BufferList,
|
list: gst::BufferList,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::trace!(CAT, imp: self, "Received buffer list {list:?}");
|
gst::trace!(CAT, imp = self, "Received buffer list {list:?}");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
for buffer in list.iter_owned() {
|
for buffer in list.iter_owned() {
|
||||||
|
@ -994,7 +1056,7 @@ impl RtpBaseDepay2 {
|
||||||
pad: &gst::Pad,
|
pad: &gst::Pad,
|
||||||
event: gst::Event,
|
event: gst::Event,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::debug!(CAT, obj: pad, "Received event: {event:?}");
|
gst::debug!(CAT, obj = pad, "Received event: {event:?}");
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
(obj.class().as_ref().sink_event)(&obj, event)
|
(obj.class().as_ref().sink_event)(&obj, event)
|
||||||
|
@ -1005,21 +1067,21 @@ impl RtpBaseDepay2 {
|
||||||
pad: &gst::Pad,
|
pad: &gst::Pad,
|
||||||
event: gst::Event,
|
event: gst::Event,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::debug!(CAT, obj: pad, "Received event: {event:?}");
|
gst::debug!(CAT, obj = pad, "Received event: {event:?}");
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
(obj.class().as_ref().src_event)(&obj, event)
|
(obj.class().as_ref().src_event)(&obj, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
fn sink_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::trace!(CAT, obj: pad, "Received query: {query:?}");
|
gst::trace!(CAT, obj = pad, "Received query: {query:?}");
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
(obj.class().as_ref().sink_query)(&obj, query)
|
(obj.class().as_ref().sink_query)(&obj, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::trace!(CAT, obj: pad, "Received query: {query:?}");
|
gst::trace!(CAT, obj = pad, "Received query: {query:?}");
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
(obj.class().as_ref().src_query)(&obj, query)
|
(obj.class().as_ref().src_query)(&obj, query)
|
||||||
|
@ -1056,7 +1118,7 @@ impl RtpBaseDepay2 {
|
||||||
if pts > gap {
|
if pts > gap {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Found gap of {}, adjusting start: {} = {} - {}",
|
"Found gap of {}, adjusting start: {} = {} - {}",
|
||||||
gap.display(),
|
gap.display(),
|
||||||
(pts - gap).display(),
|
(pts - gap).display(),
|
||||||
|
@ -1095,7 +1157,7 @@ impl RtpBaseDepay2 {
|
||||||
state.pending_segment = false;
|
state.pending_segment = false;
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Created segment event {segment:?} with seqnum {seqnum:?}",
|
"Created segment event {segment:?} with seqnum {seqnum:?}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1110,7 +1172,7 @@ impl RtpBaseDepay2 {
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
|
|
||||||
if state.sink_caps.is_none() {
|
if state.sink_caps.is_none() {
|
||||||
gst::error!(CAT, imp: self, "No sink pad caps");
|
gst::error!(CAT, imp = self, "No sink pad caps");
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::CoreError::Negotiation,
|
gst::CoreError::Negotiation,
|
||||||
|
@ -1142,13 +1204,21 @@ impl RtpBaseDepay2 {
|
||||||
|
|
||||||
if let Some(rtp_diff) = rtp_diff {
|
if let Some(rtp_diff) = rtp_diff {
|
||||||
if rtp_diff > gst::ClockTime::SECOND {
|
if rtp_diff > gst::ClockTime::SECOND {
|
||||||
gst::warning!(CAT, imp: self, "More than {rtp_diff} of RTP time queued, probably a bug in the subclass");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"More than {rtp_diff} of RTP time queued, probably a bug in the subclass"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(pts_diff) = pts_diff {
|
if let Some(pts_diff) = pts_diff {
|
||||||
if pts_diff > gst::ClockTime::SECOND {
|
if pts_diff > gst::ClockTime::SECOND {
|
||||||
gst::warning!(CAT, imp: self, "More than {pts_diff} of PTS time queued, probably a bug in the subclass");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"More than {pts_diff} of PTS time queued, probably a bug in the subclass"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1156,7 +1226,7 @@ impl RtpBaseDepay2 {
|
||||||
let buffer = match buffer.into_mapped_buffer_readable() {
|
let buffer = match buffer.into_mapped_buffer_readable() {
|
||||||
Ok(buffer) => buffer,
|
Ok(buffer) => buffer,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to map buffer");
|
gst::error!(CAT, imp = self, "Failed to map buffer");
|
||||||
gst::element_imp_error!(self, gst::StreamError::Failed, ["Failed to map buffer"]);
|
gst::element_imp_error!(self, gst::StreamError::Failed, ["Failed to map buffer"]);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
@ -1166,7 +1236,7 @@ impl RtpBaseDepay2 {
|
||||||
let packet = match rtp_types::RtpPacket::parse(&buffer) {
|
let packet = match rtp_types::RtpPacket::parse(&buffer) {
|
||||||
Ok(packet) => packet,
|
Ok(packet) => packet,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Failed to parse RTP packet: {err:?}");
|
gst::warning!(CAT, imp = self, "Failed to parse RTP packet: {err:?}");
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1198,7 +1268,7 @@ impl RtpBaseDepay2 {
|
||||||
// FIXME: Allow subclasses to decide not to flush on DISCONTs and handle the situation
|
// FIXME: Allow subclasses to decide not to flush on DISCONTs and handle the situation
|
||||||
// themselves, e.g. to be able to continue reconstructing frames despite missing data.
|
// themselves, e.g. to be able to continue reconstructing frames despite missing data.
|
||||||
if buffer.buffer().flags().contains(gst::BufferFlags::DISCONT) {
|
if buffer.buffer().flags().contains(gst::BufferFlags::DISCONT) {
|
||||||
gst::info!(CAT, imp: self, "Discont received");
|
gst::info!(CAT, imp = self, "Discont received");
|
||||||
state.current_stream = None;
|
state.current_stream = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1206,15 +1276,31 @@ impl RtpBaseDepay2 {
|
||||||
// having a gap compared to the previous packet.
|
// having a gap compared to the previous packet.
|
||||||
if let Some(ref mut current_stream) = state.current_stream {
|
if let Some(ref mut current_stream) = state.current_stream {
|
||||||
if current_stream.ssrc != ssrc {
|
if current_stream.ssrc != ssrc {
|
||||||
gst::info!(CAT, imp: self, "Stream SSRC changed from {:08x} to {:08x}", current_stream.ssrc, ssrc);
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Stream SSRC changed from {:08x} to {:08x}",
|
||||||
|
current_stream.ssrc,
|
||||||
|
ssrc
|
||||||
|
);
|
||||||
state.current_stream = None;
|
state.current_stream = None;
|
||||||
} else if current_stream.pt != pt {
|
} else if current_stream.pt != pt {
|
||||||
gst::info!(CAT, imp: self, "Stream payload type changed from {} to {}", current_stream.pt, pt);
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Stream payload type changed from {} to {}",
|
||||||
|
current_stream.pt,
|
||||||
|
pt
|
||||||
|
);
|
||||||
state.current_stream = None;
|
state.current_stream = None;
|
||||||
} else {
|
} else {
|
||||||
let expected_seqnum = (current_stream.ext_seqnum + 1) & 0xffff;
|
let expected_seqnum = (current_stream.ext_seqnum + 1) & 0xffff;
|
||||||
if expected_seqnum != seqnum as u64 {
|
if expected_seqnum != seqnum as u64 {
|
||||||
gst::info!(CAT, imp: self, "Got seqnum {seqnum} but expected {expected_seqnum}");
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Got seqnum {seqnum} but expected {expected_seqnum}"
|
||||||
|
);
|
||||||
|
|
||||||
let mut ext_seqnum = seqnum as u64 + (current_stream.ext_seqnum & !0xffff);
|
let mut ext_seqnum = seqnum as u64 + (current_stream.ext_seqnum & !0xffff);
|
||||||
|
|
||||||
|
@ -1236,13 +1322,13 @@ impl RtpBaseDepay2 {
|
||||||
};
|
};
|
||||||
|
|
||||||
if diff > 0 {
|
if diff > 0 {
|
||||||
gst::info!(CAT, imp: self, "{diff} missing packets or sender restart");
|
gst::info!(CAT, imp = self, "{diff} missing packets or sender restart");
|
||||||
state.current_stream = None;
|
state.current_stream = None;
|
||||||
} else if diff >= -(settings.max_reorder as i32) {
|
} else if diff >= -(settings.max_reorder as i32) {
|
||||||
gst::info!(CAT, imp: self, "Got old packet, dropping");
|
gst::info!(CAT, imp = self, "Got old packet, dropping");
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
} else {
|
} else {
|
||||||
gst::info!(CAT, imp: self, "Sender restart");
|
gst::info!(CAT, imp = self, "Sender restart");
|
||||||
state.current_stream = None;
|
state.current_stream = None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1271,7 +1357,7 @@ impl RtpBaseDepay2 {
|
||||||
current_stream.ext_rtptime = ext_rtptime;
|
current_stream.ext_rtptime = ext_rtptime;
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Handling packet with extended seqnum {} and extended RTP time {}",
|
"Handling packet with extended seqnum {} and extended RTP time {}",
|
||||||
current_stream.ext_seqnum,
|
current_stream.ext_seqnum,
|
||||||
current_stream.ext_rtptime,
|
current_stream.ext_rtptime,
|
||||||
|
@ -1284,13 +1370,13 @@ impl RtpBaseDepay2 {
|
||||||
let discont = state.current_stream.is_none();
|
let discont = state.current_stream.is_none();
|
||||||
if discont && !state.pending_packets.is_empty() {
|
if discont && !state.pending_packets.is_empty() {
|
||||||
drop(state);
|
drop(state);
|
||||||
gst::info!(CAT, imp: self, "Got discontinuity, draining");
|
gst::info!(CAT, imp = self, "Got discontinuity, draining");
|
||||||
|
|
||||||
if let Err(err) = self.drain() {
|
if let Err(err) = self.drain() {
|
||||||
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
||||||
gst::warning!(CAT, imp: self, "Error while draining: {err:?}");
|
gst::warning!(CAT, imp = self, "Error while draining: {err:?}");
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Error while draining: {err:?}");
|
gst::debug!(CAT, imp = self, "Error while draining: {err:?}");
|
||||||
}
|
}
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
@ -1309,7 +1395,7 @@ impl RtpBaseDepay2 {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Starting stream with SSRC {ssrc:08x} at extended seqnum {ext_seqnum} with extended RTP time {ext_rtptime}",
|
"Starting stream with SSRC {ssrc:08x} at extended seqnum {ext_seqnum} with extended RTP time {ext_rtptime}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1383,12 +1469,12 @@ impl RtpBaseDepay2 {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::error!(CAT, imp: self, "Failed handling packet: {err:?}");
|
gst::error!(CAT, imp = self, "Failed handling packet: {err:?}");
|
||||||
} else {
|
} else {
|
||||||
res = self.finish_pending_buffers();
|
res = self.finish_pending_buffers();
|
||||||
|
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::debug!(CAT, imp: self, "Failed finishing pending buffers: {err:?}");
|
gst::debug!(CAT, imp = self, "Failed finishing pending buffers: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1424,7 +1510,11 @@ impl RtpBaseDepay2 {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let Ok(ext_id) = ext_id.parse::<u8>() else {
|
let Ok(ext_id) = ext_id.parse::<u8>() else {
|
||||||
gst::error!(CAT, imp: self, "Can't parse RTP header extension id from caps {sink_caps:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Can't parse RTP header extension id from caps {sink_caps:?}"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1434,11 +1524,15 @@ impl RtpBaseDepay2 {
|
||||||
if let Some(uri) = arr.get(1).and_then(|v| v.get::<String>().ok()) {
|
if let Some(uri) = arr.get(1).and_then(|v| v.get::<String>().ok()) {
|
||||||
uri
|
uri
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Couldn't get URI for RTP header extension id {ext_id} from caps {sink_caps:?}");
|
gst::error!(CAT, imp = self, "Couldn't get URI for RTP header extension id {ext_id} from caps {sink_caps:?}");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Couldn't get URI for RTP header extension id {ext_id} from caps {sink_caps:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Couldn't get URI for RTP header extension id {ext_id} from caps {sink_caps:?}"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1456,13 +1550,17 @@ impl RtpBaseDepay2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to get a new one for this extension ID instead
|
// Try to get a new one for this extension ID instead
|
||||||
gst::warning!(CAT, imp: self, "Failed to configure extension {ext_id} from caps {sink_caps}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to configure extension {ext_id} from caps {sink_caps}"
|
||||||
|
);
|
||||||
extensions_changed |= true;
|
extensions_changed |= true;
|
||||||
extensions.remove(ext_id);
|
extensions.remove(ext_id);
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Extension ID {ext_id} changed from {:?} to {uri}",
|
"Extension ID {ext_id} changed from {:?} to {uri}",
|
||||||
extension.uri(),
|
extension.uri(),
|
||||||
);
|
);
|
||||||
|
@ -1471,7 +1569,11 @@ impl RtpBaseDepay2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Requesting extension {uri} for ID {ext_id}");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Requesting extension {uri} for ID {ext_id}"
|
||||||
|
);
|
||||||
let ext = self
|
let ext = self
|
||||||
.obj()
|
.obj()
|
||||||
.emit_by_name::<Option<gst_rtp::RTPHeaderExtension>>(
|
.emit_by_name::<Option<gst_rtp::RTPHeaderExtension>>(
|
||||||
|
@ -1480,17 +1582,25 @@ impl RtpBaseDepay2 {
|
||||||
);
|
);
|
||||||
|
|
||||||
let Some(ext) = ext else {
|
let Some(ext) = ext else {
|
||||||
gst::warning!(CAT, imp: self, "Couldn't create extension for {uri} with ID {ext_id}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Couldn't create extension for {uri} with ID {ext_id}"
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if ext.id() != *ext_id as u32 {
|
if ext.id() != *ext_id as u32 {
|
||||||
gst::warning!(CAT, imp: self, "Created extension has wrong ID");
|
gst::warning!(CAT, imp = self, "Created extension has wrong ID");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ext.set_attributes_from_caps(sink_caps) {
|
if !ext.set_attributes_from_caps(sink_caps) {
|
||||||
gst::warning!(CAT, imp: self, "Failed to configure extension {ext_id} from caps {sink_caps}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to configure extension {ext_id} from caps {sink_caps}"
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1517,19 +1627,23 @@ impl RtpBaseDepay2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_sink_caps(&self, sink_caps: gst::Caps) -> Result<gst::FlowSuccess, gst::FlowError> {
|
fn set_sink_caps(&self, sink_caps: gst::Caps) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::debug!(CAT, imp: self, "Received caps {sink_caps:?}");
|
gst::debug!(CAT, imp = self, "Received caps {sink_caps:?}");
|
||||||
|
|
||||||
let s = sink_caps.structure(0).unwrap();
|
let s = sink_caps.structure(0).unwrap();
|
||||||
|
|
||||||
if !s.has_name("application/x-rtp") {
|
if !s.has_name("application/x-rtp") {
|
||||||
gst::error!(CAT, imp: self, "Non-RTP caps {sink_caps:?} not supported");
|
gst::error!(CAT, imp = self, "Non-RTP caps {sink_caps:?} not supported");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
|
|
||||||
let clock_rate = match s.get::<i32>("clock-rate") {
|
let clock_rate = match s.get::<i32>("clock-rate") {
|
||||||
Ok(clock_rate) if clock_rate > 0 => clock_rate,
|
Ok(clock_rate) if clock_rate > 0 => clock_rate,
|
||||||
_ => {
|
_ => {
|
||||||
gst::error!(CAT, imp: self, "RTP caps {sink_caps:?} without 'clock-rate'");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"RTP caps {sink_caps:?} without 'clock-rate'"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1558,14 +1672,14 @@ impl RtpBaseDepay2 {
|
||||||
// Just continue here. The depayloader is now flushed and can proceed below,
|
// Just continue here. The depayloader is now flushed and can proceed below,
|
||||||
// and if there was a serious error downstream it will happen on the next
|
// and if there was a serious error downstream it will happen on the next
|
||||||
// buffer pushed downstream
|
// buffer pushed downstream
|
||||||
gst::debug!(CAT, imp: self, "Draining failed: {err:?}");
|
gst::debug!(CAT, imp = self, "Draining failed: {err:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
let set_sink_caps_res = if (obj.class().as_ref().set_sink_caps)(&obj, &sink_caps) {
|
let set_sink_caps_res = if (obj.class().as_ref().set_sink_caps)(&obj, &sink_caps) {
|
||||||
gst::debug!(CAT, imp: self, "Caps {sink_caps:?} accepted");
|
gst::debug!(CAT, imp = self, "Caps {sink_caps:?} accepted");
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Caps {sink_caps:?} not accepted");
|
gst::warning!(CAT, imp = self, "Caps {sink_caps:?} not accepted");
|
||||||
Err(gst::FlowError::NotNegotiated)
|
Err(gst::FlowError::NotNegotiated)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1613,9 +1727,9 @@ impl RtpBaseDepay2 {
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
if let Err(err) = (obj.class().as_ref().drain)(&obj) {
|
if let Err(err) = (obj.class().as_ref().drain)(&obj) {
|
||||||
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
||||||
gst::warning!(CAT, imp: self, "Draining failed: {err:?}");
|
gst::warning!(CAT, imp = self, "Draining failed: {err:?}");
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Draining failed: {err:?}");
|
gst::debug!(CAT, imp = self, "Draining failed: {err:?}");
|
||||||
}
|
}
|
||||||
self.flush();
|
self.flush();
|
||||||
return Err(err);
|
return Err(err);
|
||||||
|
@ -1912,7 +2026,7 @@ impl ElementImpl for RtpBaseDepay2 {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::debug!(CAT, imp: self, "Changing state: {transition}");
|
gst::debug!(CAT, imp = self, "Changing state: {transition}");
|
||||||
|
|
||||||
if transition == gst::StateChange::ReadyToPaused {
|
if transition == gst::StateChange::ReadyToPaused {
|
||||||
*self.state.borrow_mut() = State::default();
|
*self.state.borrow_mut() = State::default();
|
||||||
|
|
|
@ -211,7 +211,7 @@ impl RtpBasePay2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn set_src_caps(&self, src_caps: &gst::Caps) {
|
pub(super) fn set_src_caps(&self, src_caps: &gst::Caps) {
|
||||||
gst::debug!(CAT, imp: self, "Setting src caps {src_caps:?}");
|
gst::debug!(CAT, imp = self, "Setting src caps {src_caps:?}");
|
||||||
|
|
||||||
let s = src_caps.structure(0).unwrap();
|
let s = src_caps.structure(0).unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -229,22 +229,22 @@ impl RtpBasePay2 {
|
||||||
fn negotiate(&self) {
|
fn negotiate(&self) {
|
||||||
let state = self.state.borrow_mut();
|
let state = self.state.borrow_mut();
|
||||||
let Some(ref src_caps) = state.src_caps else {
|
let Some(ref src_caps) = state.src_caps else {
|
||||||
gst::debug!(CAT, imp: self, "No src caps set yet, can't negotiate");
|
gst::debug!(CAT, imp = self, "No src caps set yet, can't negotiate");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let mut src_caps = src_caps.clone();
|
let mut src_caps = src_caps.clone();
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Configured src caps: {src_caps:?}");
|
gst::debug!(CAT, imp = self, "Configured src caps: {src_caps:?}");
|
||||||
|
|
||||||
let peer_caps = self.src_pad.peer_query_caps(Some(&src_caps));
|
let peer_caps = self.src_pad.peer_query_caps(Some(&src_caps));
|
||||||
if !peer_caps.is_empty() {
|
if !peer_caps.is_empty() {
|
||||||
gst::debug!(CAT, imp: self, "Peer caps: {peer_caps:?}");
|
gst::debug!(CAT, imp = self, "Peer caps: {peer_caps:?}");
|
||||||
src_caps = peer_caps;
|
src_caps = peer_caps;
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Empty peer caps");
|
gst::debug!(CAT, imp = self, "Empty peer caps");
|
||||||
}
|
}
|
||||||
gst::debug!(CAT, imp: self, "Negotiating with caps {src_caps:?}");
|
gst::debug!(CAT, imp = self, "Negotiating with caps {src_caps:?}");
|
||||||
|
|
||||||
src_caps.make_mut();
|
src_caps.make_mut();
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
|
@ -252,7 +252,12 @@ impl RtpBasePay2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn drop_buffers(&self, ids: impl RangeBounds<u64>) {
|
pub(super) fn drop_buffers(&self, ids: impl RangeBounds<u64>) {
|
||||||
gst::trace!(CAT, imp: self, "Dropping buffers up to {:?}", ids.end_bound());
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Dropping buffers up to {:?}",
|
||||||
|
ids.end_bound()
|
||||||
|
);
|
||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
let end = match ids.end_bound() {
|
let end = match ids.end_bound() {
|
||||||
|
@ -286,7 +291,7 @@ impl RtpBasePay2 {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Queueing packet for {packet_to_buffer_relation:?}",
|
"Queueing packet for {packet_to_buffer_relation:?}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -294,14 +299,14 @@ impl RtpBasePay2 {
|
||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
if state.negotiated_src_caps.is_none() {
|
if state.negotiated_src_caps.is_none() {
|
||||||
gst::error!(CAT, imp: self, "No source pad caps negotiated yet");
|
gst::error!(CAT, imp = self, "No source pad caps negotiated yet");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.last_seqnum += 1;
|
state.last_seqnum += 1;
|
||||||
let stream = state.stream.as_ref().unwrap();
|
let stream = state.stream.as_ref().unwrap();
|
||||||
let seqnum = state.last_seqnum.0;
|
let seqnum = state.last_seqnum.0;
|
||||||
gst::trace!(CAT, imp: self, "Using seqnum {seqnum}");
|
gst::trace!(CAT, imp = self, "Using seqnum {seqnum}");
|
||||||
packet = packet
|
packet = packet
|
||||||
.payload_type(stream.pt)
|
.payload_type(stream.pt)
|
||||||
.ssrc(stream.ssrc)
|
.ssrc(stream.ssrc)
|
||||||
|
@ -311,23 +316,32 @@ impl RtpBasePay2 {
|
||||||
// Queue up packet for later if it doesn't have any associated buffers that could be used
|
// Queue up packet for later if it doesn't have any associated buffers that could be used
|
||||||
// for figuring out the timestamp.
|
// for figuring out the timestamp.
|
||||||
if matches!(packet_to_buffer_relation, PacketToBufferRelation::OutOfBand) {
|
if matches!(packet_to_buffer_relation, PacketToBufferRelation::OutOfBand) {
|
||||||
gst::trace!(CAT, imp: self, "Keeping packet without associated buffer until next packet or EOS");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Keeping packet without associated buffer until next packet or EOS"
|
||||||
|
);
|
||||||
|
|
||||||
// FIXME: Use more optimal packet writing API once available
|
// FIXME: Use more optimal packet writing API once available
|
||||||
// https://github.com/ystreet/rtp-types/issues/4
|
// https://github.com/ystreet/rtp-types/issues/4
|
||||||
// https://github.com/ystreet/rtp-types/issues/5
|
// https://github.com/ystreet/rtp-types/issues/5
|
||||||
// TODO: Maybe use an MTU-sized buffer pool?
|
// TODO: Maybe use an MTU-sized buffer pool?
|
||||||
let packet_buffer = packet.write_vec().map_err(|err| {
|
let packet_buffer = packet.write_vec().map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Can't write packet: {err}");
|
gst::error!(CAT, imp = self, "Can't write packet: {err}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let packet_len = packet_buffer.len();
|
let packet_len = packet_buffer.len();
|
||||||
|
|
||||||
if (settings.mtu as usize) < packet_len {
|
if (settings.mtu as usize) < packet_len {
|
||||||
gst::warning!(CAT, imp: self, "Generated packet has bigger size {packet_len} than MTU {}", settings.mtu);
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Generated packet has bigger size {packet_len} than MTU {}",
|
||||||
|
settings.mtu
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Queueing packet of size {packet_len}");
|
gst::trace!(CAT, imp = self, "Queueing packet of size {packet_len}");
|
||||||
|
|
||||||
let marker = {
|
let marker = {
|
||||||
let packet = rtp_types::RtpPacket::parse(&packet_buffer).unwrap();
|
let packet = rtp_types::RtpPacket::parse(&packet_buffer).unwrap();
|
||||||
|
@ -363,7 +377,7 @@ impl RtpBasePay2 {
|
||||||
};
|
};
|
||||||
|
|
||||||
if ids.is_empty() {
|
if ids.is_empty() {
|
||||||
gst::error!(CAT, imp: self, "Empty buffer id range provided");
|
gst::error!(CAT, imp = self, "Empty buffer id range provided");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,16 +391,24 @@ impl RtpBasePay2 {
|
||||||
.is_some_and(|b| b.id < id_start)
|
.is_some_and(|b| b.id < id_start)
|
||||||
{
|
{
|
||||||
let b = state.pending_buffers.pop_front().unwrap();
|
let b = state.pending_buffers.pop_front().unwrap();
|
||||||
gst::trace!(CAT, imp: self, "Dropping buffer with id {}", b.id);
|
gst::trace!(CAT, imp = self, "Dropping buffer with id {}", b.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(front) = state.pending_buffers.front() else {
|
let Some(front) = state.pending_buffers.front() else {
|
||||||
gst::error!(CAT, imp: self, "Queueing packet for future buffer ids not allowed");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Queueing packet for future buffer ids not allowed"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
};
|
};
|
||||||
|
|
||||||
if id_end > state.pending_buffers.back().unwrap().id {
|
if id_end > state.pending_buffers.back().unwrap().id {
|
||||||
gst::error!(CAT, imp: self, "Queueing packet for future buffer ids not allowed");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Queueing packet for future buffer ids not allowed"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,7 +471,7 @@ impl RtpBasePay2 {
|
||||||
}
|
}
|
||||||
crate::basepay::TimestampOffset::Rtp(rtp_diff) => {
|
crate::basepay::TimestampOffset::Rtp(rtp_diff) => {
|
||||||
let Some((base_pts, base_rtptime)) = state.last_pts_rtp_mapping else {
|
let Some((base_pts, base_rtptime)) = state.last_pts_rtp_mapping else {
|
||||||
gst::error!(CAT, imp: self, "Have no base PTS / RTP time mapping");
|
gst::error!(CAT, imp = self, "Have no base PTS / RTP time mapping");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -624,7 +646,7 @@ impl RtpBasePay2 {
|
||||||
// https://github.com/ystreet/rtp-types/issues/5
|
// https://github.com/ystreet/rtp-types/issues/5
|
||||||
// TODO: Maybe use an MTU-sized buffer pool?
|
// TODO: Maybe use an MTU-sized buffer pool?
|
||||||
let packet_buffer = packet.write_vec().map_err(|err| {
|
let packet_buffer = packet.write_vec().map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Can't write packet: {err}");
|
gst::error!(CAT, imp = self, "Can't write packet: {err}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let packet_len = packet_buffer.len();
|
let packet_len = packet_buffer.len();
|
||||||
|
@ -632,12 +654,17 @@ impl RtpBasePay2 {
|
||||||
// FIXME: See comment in `max_payload_size()`. We currently don't provide a way to the
|
// FIXME: See comment in `max_payload_size()`. We currently don't provide a way to the
|
||||||
// subclass to know how much space will be used up by extensions.
|
// subclass to know how much space will be used up by extensions.
|
||||||
if (settings.mtu as usize) < packet_len - extension_size {
|
if (settings.mtu as usize) < packet_len - extension_size {
|
||||||
gst::warning!(CAT, imp: self, "Generated packet has bigger size {packet_len} than MTU {}", settings.mtu);
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Generated packet has bigger size {packet_len} than MTU {}",
|
||||||
|
settings.mtu
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Queueing packet of size {packet_len} with RTP timestamp {packet_rtptime} and PTS {packet_pts}",
|
"Queueing packet of size {packet_len} with RTP timestamp {packet_rtptime} and PTS {packet_pts}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -701,7 +728,11 @@ impl RtpBasePay2 {
|
||||||
};
|
};
|
||||||
|
|
||||||
if extension_data.len() < offset {
|
if extension_data.len() < offset {
|
||||||
gst::error!(CAT, imp: self, "No space left for writing RTP header extension {ext_id}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"No space left for writing RTP header extension {ext_id}"
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,7 +758,11 @@ impl RtpBasePay2 {
|
||||||
|
|
||||||
extension_data = &mut extension_data[offset + written..];
|
extension_data = &mut extension_data[offset + written..];
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Writing RTP header extension {ext_id} failed");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Writing RTP header extension {ext_id} failed"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -773,7 +808,7 @@ impl RtpBasePay2 {
|
||||||
|
|
||||||
assert_ne!(num_buffers, 0);
|
assert_ne!(num_buffers, 0);
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Flushing {num_buffers} packets");
|
gst::trace!(CAT, imp = self, "Flushing {num_buffers} packets");
|
||||||
|
|
||||||
let segment_event = self.retrieve_pending_segment_event(&mut state);
|
let segment_event = self.retrieve_pending_segment_event(&mut state);
|
||||||
|
|
||||||
|
@ -784,7 +819,7 @@ impl RtpBasePay2 {
|
||||||
|
|
||||||
let packets = if num_buffers == 1 {
|
let packets = if num_buffers == 1 {
|
||||||
let buffer = state.pending_packets.pop_front().unwrap().buffer;
|
let buffer = state.pending_packets.pop_front().unwrap().buffer;
|
||||||
gst::trace!(CAT, imp: self, "Finishing buffer {buffer:?}");
|
gst::trace!(CAT, imp = self, "Finishing buffer {buffer:?}");
|
||||||
BufferOrList::Buffer(buffer)
|
BufferOrList::Buffer(buffer)
|
||||||
} else {
|
} else {
|
||||||
let mut list = gst::BufferList::new_sized(num_buffers);
|
let mut list = gst::BufferList::new_sized(num_buffers);
|
||||||
|
@ -796,7 +831,7 @@ impl RtpBasePay2 {
|
||||||
.is_some_and(|p| p.buffer.pts() == Some(pts))
|
.is_some_and(|p| p.buffer.pts() == Some(pts))
|
||||||
{
|
{
|
||||||
let buffer = state.pending_packets.pop_front().unwrap().buffer;
|
let buffer = state.pending_packets.pop_front().unwrap().buffer;
|
||||||
gst::trace!(CAT, imp: self, "Finishing buffer {buffer:?}");
|
gst::trace!(CAT, imp = self, "Finishing buffer {buffer:?}");
|
||||||
list.add(buffer);
|
list.add(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -817,9 +852,9 @@ impl RtpBasePay2 {
|
||||||
|
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
||||||
gst::warning!(CAT, imp: self, "Failed pushing packets: {err:?}");
|
gst::warning!(CAT, imp = self, "Failed pushing packets: {err:?}");
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Failed pushing packets: {err:?}");
|
gst::debug!(CAT, imp = self, "Failed pushing packets: {err:?}");
|
||||||
}
|
}
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
@ -874,7 +909,11 @@ impl RtpBasePay2 {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let Ok(ext_id) = ext_id.parse::<u8>() else {
|
let Ok(ext_id) = ext_id.parse::<u8>() else {
|
||||||
gst::error!(CAT, imp: self, "Can't parse RTP header extension id from caps {src_caps:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Can't parse RTP header extension id from caps {src_caps:?}"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -884,11 +923,15 @@ impl RtpBasePay2 {
|
||||||
if let Some(uri) = arr.get(1).and_then(|v| v.get::<String>().ok()) {
|
if let Some(uri) = arr.get(1).and_then(|v| v.get::<String>().ok()) {
|
||||||
uri
|
uri
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Couldn't get URI for RTP header extension id {ext_id} from caps {src_caps:?}");
|
gst::error!(CAT, imp = self, "Couldn't get URI for RTP header extension id {ext_id} from caps {src_caps:?}");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Couldn't get URI for RTP header extension id {ext_id} from caps {src_caps:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Couldn't get URI for RTP header extension id {ext_id} from caps {src_caps:?}"
|
||||||
|
);
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -906,13 +949,17 @@ impl RtpBasePay2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to get a new one for this extension ID instead
|
// Try to get a new one for this extension ID instead
|
||||||
gst::warning!(CAT, imp: self, "Failed to configure extension {ext_id} from caps {src_caps}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to configure extension {ext_id} from caps {src_caps}"
|
||||||
|
);
|
||||||
extensions_changed |= true;
|
extensions_changed |= true;
|
||||||
extensions.remove(ext_id);
|
extensions.remove(ext_id);
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Extension ID {ext_id} changed from {:?} to {uri}",
|
"Extension ID {ext_id} changed from {:?} to {uri}",
|
||||||
extension.uri(),
|
extension.uri(),
|
||||||
);
|
);
|
||||||
|
@ -921,7 +968,11 @@ impl RtpBasePay2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Requesting extension {uri} for ID {ext_id}");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Requesting extension {uri} for ID {ext_id}"
|
||||||
|
);
|
||||||
let ext = self
|
let ext = self
|
||||||
.obj()
|
.obj()
|
||||||
.emit_by_name::<Option<gst_rtp::RTPHeaderExtension>>(
|
.emit_by_name::<Option<gst_rtp::RTPHeaderExtension>>(
|
||||||
|
@ -930,17 +981,25 @@ impl RtpBasePay2 {
|
||||||
);
|
);
|
||||||
|
|
||||||
let Some(ext) = ext else {
|
let Some(ext) = ext else {
|
||||||
gst::warning!(CAT, imp: self, "Couldn't create extension for {uri} with ID {ext_id}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Couldn't create extension for {uri} with ID {ext_id}"
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if ext.id() != *ext_id as u32 {
|
if ext.id() != *ext_id as u32 {
|
||||||
gst::warning!(CAT, imp: self, "Created extension has wrong ID");
|
gst::warning!(CAT, imp = self, "Created extension has wrong ID");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ext.set_attributes_from_caps(src_caps) {
|
if !ext.set_attributes_from_caps(src_caps) {
|
||||||
gst::warning!(CAT, imp: self, "Failed to configure extension {ext_id} from caps {src_caps}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to configure extension {ext_id} from caps {src_caps}"
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,7 +1011,11 @@ impl RtpBasePay2 {
|
||||||
let mut to_remove = vec![];
|
let mut to_remove = vec![];
|
||||||
for (ext_id, ext) in extensions.iter() {
|
for (ext_id, ext) in extensions.iter() {
|
||||||
if !ext.set_non_rtp_sink_caps(sink_caps) {
|
if !ext.set_non_rtp_sink_caps(sink_caps) {
|
||||||
gst::warning!(CAT, imp: self, "Failed to configure extension {ext_id} from sink caps {sink_caps}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to configure extension {ext_id} from sink caps {sink_caps}"
|
||||||
|
);
|
||||||
to_remove.push(*ext_id);
|
to_remove.push(*ext_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -982,7 +1045,7 @@ impl RtpBasePay2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn negotiate_default(&self, mut src_caps: gst::Caps) {
|
fn negotiate_default(&self, mut src_caps: gst::Caps) {
|
||||||
gst::debug!(CAT, imp: self, "Negotiating caps {src_caps:?}");
|
gst::debug!(CAT, imp = self, "Negotiating caps {src_caps:?}");
|
||||||
|
|
||||||
// Fixate what is left to fixate.
|
// Fixate what is left to fixate.
|
||||||
src_caps.fixate();
|
src_caps.fixate();
|
||||||
|
@ -1021,7 +1084,7 @@ impl RtpBasePay2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
if Some(&src_caps) == state.negotiated_src_caps.as_ref() {
|
if Some(&src_caps) == state.negotiated_src_caps.as_ref() {
|
||||||
gst::debug!(CAT, imp: self, "Setting same caps {src_caps:?} again");
|
gst::debug!(CAT, imp = self, "Setting same caps {src_caps:?} again");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1052,7 +1115,7 @@ impl RtpBasePay2 {
|
||||||
// Just continue here. The payloader is now flushed and can proceed below,
|
// Just continue here. The payloader is now flushed and can proceed below,
|
||||||
// and if there was a serious error downstream it will happen on the next
|
// and if there was a serious error downstream it will happen on the next
|
||||||
// buffer pushed downstream
|
// buffer pushed downstream
|
||||||
gst::debug!(CAT, imp: self, "Draining failed: {err:?}");
|
gst::debug!(CAT, imp = self, "Draining failed: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,7 +1158,7 @@ impl RtpBasePay2 {
|
||||||
|
|
||||||
let state = self.state.borrow();
|
let state = self.state.borrow();
|
||||||
if state.sink_caps.is_none() {
|
if state.sink_caps.is_none() {
|
||||||
gst::warning!(CAT, imp: self, "Received segment before caps");
|
gst::warning!(CAT, imp = self, "Received segment before caps");
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1111,14 +1174,14 @@ impl RtpBasePay2 {
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
if !same_segment {
|
if !same_segment {
|
||||||
gst::debug!(CAT, imp: self, "Received segment {segment:?}");
|
gst::debug!(CAT, imp = self, "Received segment {segment:?}");
|
||||||
|
|
||||||
if drain {
|
if drain {
|
||||||
if let Err(err) = self.drain() {
|
if let Err(err) = self.drain() {
|
||||||
// Just continue here. The payloader is now flushed and can proceed below,
|
// Just continue here. The payloader is now flushed and can proceed below,
|
||||||
// and if there was a serious error downstream it will happen on the next
|
// and if there was a serious error downstream it will happen on the next
|
||||||
// buffer pushed downstream
|
// buffer pushed downstream
|
||||||
gst::debug!(CAT, imp: self, "Draining failed: {err:?}");
|
gst::debug!(CAT, imp = self, "Draining failed: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1126,7 +1189,11 @@ impl RtpBasePay2 {
|
||||||
if let Some(segment) = segment.downcast_ref::<gst::ClockTime>() {
|
if let Some(segment) = segment.downcast_ref::<gst::ClockTime>() {
|
||||||
state.segment = Some((event.seqnum(), segment.clone()));
|
state.segment = Some((event.seqnum(), segment.clone()));
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Segments in non-TIME format are not supported");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Segments in non-TIME format are not supported"
|
||||||
|
);
|
||||||
state.segment = None;
|
state.segment = None;
|
||||||
// FIXME: Forget everything here?
|
// FIXME: Forget everything here?
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
|
@ -1134,7 +1201,11 @@ impl RtpBasePay2 {
|
||||||
|
|
||||||
if state.negotiated_src_caps.is_none() {
|
if state.negotiated_src_caps.is_none() {
|
||||||
state.pending_segment = true;
|
state.pending_segment = true;
|
||||||
gst::debug!(CAT, imp: self, "Received segment before knowing src caps, delaying");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Received segment before knowing src caps, delaying"
|
||||||
|
);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1143,7 +1214,7 @@ impl RtpBasePay2 {
|
||||||
}
|
}
|
||||||
gst::EventView::Eos(_) => {
|
gst::EventView::Eos(_) => {
|
||||||
if let Err(err) = self.drain() {
|
if let Err(err) = self.drain() {
|
||||||
gst::debug!(CAT, imp: self, "Draining on EOS failed: {err:?}");
|
gst::debug!(CAT, imp = self, "Draining on EOS failed: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst::EventView::FlushStop(_) => {
|
gst::EventView::FlushStop(_) => {
|
||||||
|
@ -1163,7 +1234,7 @@ impl RtpBasePay2 {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Forwarding event: {event:?}");
|
gst::debug!(CAT, imp = self, "Forwarding event: {event:?}");
|
||||||
if self.src_pad.push_event(event) {
|
if self.src_pad.push_event(event) {
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
} else if self.src_pad.pad_flags().contains(gst::PadFlags::FLUSHING) {
|
} else if self.src_pad.pad_flags().contains(gst::PadFlags::FLUSHING) {
|
||||||
|
@ -1244,7 +1315,7 @@ impl RtpBasePay2 {
|
||||||
if tags.len() > 1 {
|
if tags.len() > 1 {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Not copying meta {}: has multiple tags {tags:?}",
|
"Not copying meta {}: has multiple tags {tags:?}",
|
||||||
meta.api(),
|
meta.api(),
|
||||||
);
|
);
|
||||||
|
@ -1258,7 +1329,7 @@ impl RtpBasePay2 {
|
||||||
if !allowed_tags.iter().copied().any(|tag| tag == *meta_tag) {
|
if !allowed_tags.iter().copied().any(|tag| tag == *meta_tag) {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Not copying meta {}: tag '{meta_tag}' not allowed",
|
"Not copying meta {}: tag '{meta_tag}' not allowed",
|
||||||
meta.api(),
|
meta.api(),
|
||||||
);
|
);
|
||||||
|
@ -1266,10 +1337,10 @@ impl RtpBasePay2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Copying meta {}", meta.api());
|
gst::trace!(CAT, imp = self, "Copying meta {}", meta.api());
|
||||||
|
|
||||||
if let Err(err) = meta.transform(out_buf, &gst::meta::MetaTransformCopy::new(false, ..)) {
|
if let Err(err) = meta.transform(out_buf, &gst::meta::MetaTransformCopy::new(false, ..)) {
|
||||||
gst::trace!(CAT, imp: self, "Could not copy meta {}: {err}", meta.api());
|
gst::trace!(CAT, imp = self, "Could not copy meta {}: {err}", meta.api());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1303,7 +1374,7 @@ impl RtpBasePay2 {
|
||||||
let Some(ext) = gst_rtp::RTPHeaderExtension::create_from_uri(uri) else {
|
let Some(ext) = gst_rtp::RTPHeaderExtension::create_from_uri(uri) else {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Didn't find any extension implementing URI {uri}",
|
"Didn't find any extension implementing URI {uri}",
|
||||||
);
|
);
|
||||||
return None;
|
return None;
|
||||||
|
@ -1311,7 +1382,7 @@ impl RtpBasePay2 {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Automatically enabling extension {} for URI {uri}",
|
"Automatically enabling extension {} for URI {uri}",
|
||||||
ext.name(),
|
ext.name(),
|
||||||
);
|
);
|
||||||
|
@ -1329,7 +1400,7 @@ impl RtpBasePay2 {
|
||||||
_pad: &gst::Pad,
|
_pad: &gst::Pad,
|
||||||
buffer: gst::Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::trace!(CAT, imp: self, "Received buffer {buffer:?}");
|
gst::trace!(CAT, imp = self, "Received buffer {buffer:?}");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
self.handle_buffer(&settings, buffer)
|
self.handle_buffer(&settings, buffer)
|
||||||
|
@ -1340,7 +1411,7 @@ impl RtpBasePay2 {
|
||||||
_pad: &gst::Pad,
|
_pad: &gst::Pad,
|
||||||
list: gst::BufferList,
|
list: gst::BufferList,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::trace!(CAT, imp: self, "Received buffer list {list:?}");
|
gst::trace!(CAT, imp = self, "Received buffer list {list:?}");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
for buffer in list.iter_owned() {
|
for buffer in list.iter_owned() {
|
||||||
|
@ -1355,7 +1426,7 @@ impl RtpBasePay2 {
|
||||||
pad: &gst::Pad,
|
pad: &gst::Pad,
|
||||||
event: gst::Event,
|
event: gst::Event,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::debug!(CAT, obj: pad, "Received event: {event:?}");
|
gst::debug!(CAT, obj = pad, "Received event: {event:?}");
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
(obj.class().as_ref().sink_event)(&obj, event)
|
(obj.class().as_ref().sink_event)(&obj, event)
|
||||||
|
@ -1366,21 +1437,21 @@ impl RtpBasePay2 {
|
||||||
pad: &gst::Pad,
|
pad: &gst::Pad,
|
||||||
event: gst::Event,
|
event: gst::Event,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::debug!(CAT, obj: pad, "Received event: {event:?}");
|
gst::debug!(CAT, obj = pad, "Received event: {event:?}");
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
(obj.class().as_ref().src_event)(&obj, event)
|
(obj.class().as_ref().src_event)(&obj, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
fn sink_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::trace!(CAT, obj: pad, "Received query: {query:?}");
|
gst::trace!(CAT, obj = pad, "Received query: {query:?}");
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
(obj.class().as_ref().sink_query)(&obj, query)
|
(obj.class().as_ref().sink_query)(&obj, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::trace!(CAT, obj: pad, "Received query: {query:?}");
|
gst::trace!(CAT, obj = pad, "Received query: {query:?}");
|
||||||
|
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
(obj.class().as_ref().src_query)(&obj, query)
|
(obj.class().as_ref().src_query)(&obj, query)
|
||||||
|
@ -1400,7 +1471,11 @@ impl RtpBasePay2 {
|
||||||
.build();
|
.build();
|
||||||
state.pending_segment = false;
|
state.pending_segment = false;
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Created segment event {segment:?} with seqnum {seqnum:?}");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Created segment event {segment:?} with seqnum {seqnum:?}"
|
||||||
|
);
|
||||||
|
|
||||||
Some(segment_event)
|
Some(segment_event)
|
||||||
}
|
}
|
||||||
|
@ -1418,7 +1493,7 @@ impl RtpBasePay2 {
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
|
|
||||||
if state.sink_caps.is_none() {
|
if state.sink_caps.is_none() {
|
||||||
gst::error!(CAT, imp: self, "No sink pad caps");
|
gst::error!(CAT, imp = self, "No sink pad caps");
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::CoreError::Negotiation,
|
gst::CoreError::Negotiation,
|
||||||
|
@ -1433,12 +1508,12 @@ impl RtpBasePay2 {
|
||||||
if buffer.flags().contains(gst::BufferFlags::HEADER)
|
if buffer.flags().contains(gst::BufferFlags::HEADER)
|
||||||
&& self.obj().class().as_ref().drop_header_buffers
|
&& self.obj().class().as_ref().drop_header_buffers
|
||||||
{
|
{
|
||||||
gst::trace!(CAT, imp: self, "Dropping buffer with HEADER flag");
|
gst::trace!(CAT, imp = self, "Dropping buffer with HEADER flag");
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
if buffer.pts().is_none() {
|
if buffer.pts().is_none() {
|
||||||
gst::error!(CAT, imp: self, "Buffers without PTS");
|
gst::error!(CAT, imp = self, "Buffers without PTS");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1452,7 +1527,11 @@ impl RtpBasePay2 {
|
||||||
|
|
||||||
if let Some(pts_diff) = pts_diff {
|
if let Some(pts_diff) = pts_diff {
|
||||||
if pts_diff > gst::ClockTime::SECOND {
|
if pts_diff > gst::ClockTime::SECOND {
|
||||||
gst::warning!(CAT, imp: self, "More than {pts_diff} of PTS time queued, probably a bug in the subclass");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"More than {pts_diff} of PTS time queued, probably a bug in the subclass"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1462,7 +1541,7 @@ impl RtpBasePay2 {
|
||||||
let stream = state.stream.as_mut().unwrap();
|
let stream = state.stream.as_mut().unwrap();
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Switching from SSRC {} to {} because of SSRC collision",
|
"Switching from SSRC {} to {} because of SSRC collision",
|
||||||
stream.ssrc,
|
stream.ssrc,
|
||||||
new_ssrc,
|
new_ssrc,
|
||||||
|
@ -1501,7 +1580,7 @@ impl RtpBasePay2 {
|
||||||
let id = state.current_buffer_id;
|
let id = state.current_buffer_id;
|
||||||
state.current_buffer_id += 1;
|
state.current_buffer_id += 1;
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Handling buffer {buffer:?} with id {id}");
|
gst::trace!(CAT, imp = self, "Handling buffer {buffer:?} with id {id}");
|
||||||
state.pending_buffers.push_back(PendingBuffer {
|
state.pending_buffers.push_back(PendingBuffer {
|
||||||
id,
|
id,
|
||||||
buffer: buffer.clone(),
|
buffer: buffer.clone(),
|
||||||
|
@ -1511,12 +1590,12 @@ impl RtpBasePay2 {
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
let mut res = (obj.class().as_ref().handle_buffer)(&obj, &buffer, id);
|
let mut res = (obj.class().as_ref().handle_buffer)(&obj, &buffer, id);
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::error!(CAT, imp: self, "Failed handling buffer: {err:?}");
|
gst::error!(CAT, imp = self, "Failed handling buffer: {err:?}");
|
||||||
} else {
|
} else {
|
||||||
res = self.finish_pending_packets();
|
res = self.finish_pending_packets();
|
||||||
|
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::debug!(CAT, imp: self, "Failed finishing pending packets: {err:?}");
|
gst::debug!(CAT, imp = self, "Failed finishing pending packets: {err:?}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1538,7 +1617,7 @@ impl RtpBasePay2 {
|
||||||
/// Other methods.
|
/// Other methods.
|
||||||
impl RtpBasePay2 {
|
impl RtpBasePay2 {
|
||||||
fn set_sink_caps(&self, caps: gst::Caps) -> Result<gst::FlowSuccess, gst::FlowError> {
|
fn set_sink_caps(&self, caps: gst::Caps) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::debug!(CAT, imp: self, "Received caps {caps:?}");
|
gst::debug!(CAT, imp = self, "Received caps {caps:?}");
|
||||||
|
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
let same_caps = state
|
let same_caps = state
|
||||||
|
@ -1552,10 +1631,10 @@ impl RtpBasePay2 {
|
||||||
if !same_caps {
|
if !same_caps {
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
let set_sink_caps_res = if (obj.class().as_ref().set_sink_caps)(&obj, &caps) {
|
let set_sink_caps_res = if (obj.class().as_ref().set_sink_caps)(&obj, &caps) {
|
||||||
gst::debug!(CAT, imp: self, "Caps {caps:?} accepted");
|
gst::debug!(CAT, imp = self, "Caps {caps:?} accepted");
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Caps {caps:?} not accepted");
|
gst::warning!(CAT, imp = self, "Caps {caps:?} not accepted");
|
||||||
Err(gst::FlowError::NotNegotiated)
|
Err(gst::FlowError::NotNegotiated)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1575,9 +1654,9 @@ impl RtpBasePay2 {
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
if let Err(err) = (obj.class().as_ref().drain)(&obj) {
|
if let Err(err) = (obj.class().as_ref().drain)(&obj) {
|
||||||
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
if ![gst::FlowError::Flushing, gst::FlowError::Eos].contains(&err) {
|
||||||
gst::warning!(CAT, imp: self, "Draining failed: {err:?}");
|
gst::warning!(CAT, imp = self, "Draining failed: {err:?}");
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Draining failed: {err:?}");
|
gst::debug!(CAT, imp = self, "Draining failed: {err:?}");
|
||||||
}
|
}
|
||||||
self.flush();
|
self.flush();
|
||||||
return Err(err);
|
return Err(err);
|
||||||
|
@ -1587,7 +1666,7 @@ impl RtpBasePay2 {
|
||||||
state.pending_buffers.clear();
|
state.pending_buffers.clear();
|
||||||
|
|
||||||
if !state.pending_packets.is_empty() {
|
if !state.pending_packets.is_empty() {
|
||||||
gst::debug!(CAT, imp: self, "Pushing all pending packets");
|
gst::debug!(CAT, imp = self, "Pushing all pending packets");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update PTS and RTP timestamp of all pending packets that have none yet
|
// Update PTS and RTP timestamp of all pending packets that have none yet
|
||||||
|
@ -2021,7 +2100,7 @@ impl ElementImpl for RtpBasePay2 {
|
||||||
&self,
|
&self,
|
||||||
transition: gst::StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::debug!(CAT, imp: self, "Changing state: {transition}");
|
gst::debug!(CAT, imp = self, "Changing state: {transition}");
|
||||||
|
|
||||||
if transition == gst::StateChange::ReadyToPaused {
|
if transition == gst::StateChange::ReadyToPaused {
|
||||||
{
|
{
|
||||||
|
@ -2044,7 +2123,7 @@ impl ElementImpl for RtpBasePay2 {
|
||||||
use_stream_time: settings.onvif_no_rate_control || !settings.scale_rtptime,
|
use_stream_time: settings.onvif_no_rate_control || !settings.scale_rtptime,
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Configuring {stream:?}");
|
gst::info!(CAT, imp = self, "Configuring {stream:?}");
|
||||||
|
|
||||||
*self.state.borrow_mut() = State {
|
*self.state.borrow_mut() = State {
|
||||||
stream: Some(stream),
|
stream: Some(stream),
|
||||||
|
|
|
@ -795,7 +795,7 @@ impl State {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: bwe,
|
obj = bwe,
|
||||||
"{} bitrate: {}ps budget: {}/{} sending: {} Remaining: {}/{}",
|
"{} bitrate: {}ps budget: {}/{} sending: {} Remaining: {}/{}",
|
||||||
elapsed,
|
elapsed,
|
||||||
human_kbits(self.estimated_bitrate),
|
human_kbits(self.estimated_bitrate),
|
||||||
|
@ -882,7 +882,7 @@ impl State {
|
||||||
if rate > received_max && received_max > self.target_bitrate_on_delay as f64 {
|
if rate > received_max && received_max > self.target_bitrate_on_delay as f64 {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: bwe,
|
obj = bwe,
|
||||||
"Increasing == received_max rate: {}ps - effective bitrate: {}ps",
|
"Increasing == received_max rate: {}ps - effective bitrate: {}ps",
|
||||||
human_kbits(received_max),
|
human_kbits(received_max),
|
||||||
human_kbits(effective_bitrate),
|
human_kbits(effective_bitrate),
|
||||||
|
@ -896,7 +896,7 @@ impl State {
|
||||||
} else if rate < self.target_bitrate_on_delay as f64 {
|
} else if rate < self.target_bitrate_on_delay as f64 {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: bwe,
|
obj = bwe,
|
||||||
"Rate < target, returning {}ps - effective bitrate: {}ps",
|
"Rate < target, returning {}ps - effective bitrate: {}ps",
|
||||||
human_kbits(self.target_bitrate_on_delay),
|
human_kbits(self.target_bitrate_on_delay),
|
||||||
human_kbits(effective_bitrate),
|
human_kbits(effective_bitrate),
|
||||||
|
@ -906,7 +906,7 @@ impl State {
|
||||||
} else {
|
} else {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: bwe,
|
obj = bwe,
|
||||||
"Increase mult {eta}x{}ps={}ps - effective bitrate: {}ps",
|
"Increase mult {eta}x{}ps={}ps - effective bitrate: {}ps",
|
||||||
human_kbits(self.target_bitrate_on_delay),
|
human_kbits(self.target_bitrate_on_delay),
|
||||||
human_kbits(rate),
|
human_kbits(rate),
|
||||||
|
@ -948,7 +948,7 @@ impl State {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: bwe,
|
obj = bwe,
|
||||||
"{controller_type:?}: {}ps => {}ps ({:?}) - effective bitrate: {}ps",
|
"{controller_type:?}: {}ps => {}ps ({:?}) - effective bitrate: {}ps",
|
||||||
human_kbits(prev_bitrate),
|
human_kbits(prev_bitrate),
|
||||||
human_kbits(target_bitrate),
|
human_kbits(target_bitrate),
|
||||||
|
@ -1110,7 +1110,7 @@ impl BandwidthEstimator {
|
||||||
if !list.is_empty() {
|
if !list.is_empty() {
|
||||||
if let Err(err) = bwe.imp().push_list(list) {
|
if let Err(err) = bwe.imp().push_list(list) {
|
||||||
if err != gst::FlowError::Flushing {
|
if err != gst::FlowError::Flushing {
|
||||||
gst::error!(CAT, obj: bwe, "pause task, reason: {err:?}");
|
gst::error!(CAT, obj = bwe, "pause task, reason: {err:?}");
|
||||||
}
|
}
|
||||||
pause()
|
pause()
|
||||||
}
|
}
|
||||||
|
@ -1218,7 +1218,7 @@ impl ObjectSubclass for BandwidthEstimator {
|
||||||
if let Some(bitrates) = logged_bitrates {
|
if let Some(bitrates) = logged_bitrates {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: bwe,
|
obj = bwe,
|
||||||
"target bitrate on delay: {}ps - target bitrate on loss: {}ps",
|
"target bitrate on delay: {}ps - target bitrate on loss: {}ps",
|
||||||
human_kbits(bitrates.0),
|
human_kbits(bitrates.0),
|
||||||
human_kbits(bitrates.1),
|
human_kbits(bitrates.1),
|
||||||
|
|
|
@ -180,10 +180,14 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((width, height)) = dimensions {
|
if let Some((width, height)) = dimensions {
|
||||||
gst::debug!(CAT, imp: self, "Parsed SDP dimensions {width}x{height}");
|
gst::debug!(CAT, imp = self, "Parsed SDP dimensions {width}x{height}");
|
||||||
state.sdp_dimensions = dimensions;
|
state.sdp_dimensions = dimensions;
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Failed to parse 'x-dimensions' attribute: {dimensions_str}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse 'x-dimensions' attribute: {dimensions_str}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,10 +204,14 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(gst::Fraction::approximate_f64)
|
.and_then(gst::Fraction::approximate_f64)
|
||||||
{
|
{
|
||||||
gst::debug!(CAT, imp: self, "Parsed SDP framerate {framerate}");
|
gst::debug!(CAT, imp = self, "Parsed SDP framerate {framerate}");
|
||||||
state.sdp_framerate = Some(framerate);
|
state.sdp_framerate = Some(framerate);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Failed to parse 'a-framerate' attribute: {framerate_str}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse 'a-framerate' attribute: {framerate_str}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,17 +242,17 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
let main_header = match r.parse::<MainHeader>() {
|
let main_header = match r.parse::<MainHeader>() {
|
||||||
Ok(main_header) => main_header,
|
Ok(main_header) => main_header,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Failed to parse main header: {err}");
|
gst::warning!(CAT, imp = self, "Failed to parse main header: {err}");
|
||||||
state.pending_frame = None;
|
state.pending_frame = None;
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Parsed main header {main_header:?}");
|
gst::trace!(CAT, imp = self, "Parsed main header {main_header:?}");
|
||||||
|
|
||||||
if state.pending_frame.is_none() && main_header.fragment_offset > 0 {
|
if state.pending_frame.is_none() && main_header.fragment_offset > 0 {
|
||||||
gst::trace!(CAT, imp: self, "Waiting for start of frame");
|
gst::trace!(CAT, imp = self, "Waiting for start of frame");
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
@ -253,7 +261,7 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
match r.parse::<RestartHeader>() {
|
match r.parse::<RestartHeader>() {
|
||||||
Ok(restart_header) => Some(restart_header),
|
Ok(restart_header) => Some(restart_header),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Failed to parse restart header: {err}");
|
gst::warning!(CAT, imp = self, "Failed to parse restart header: {err}");
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
@ -265,7 +273,7 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
// Handle initial setup for a frame
|
// Handle initial setup for a frame
|
||||||
if main_header.fragment_offset == 0 {
|
if main_header.fragment_offset == 0 {
|
||||||
if state.pending_frame.is_some() {
|
if state.pending_frame.is_some() {
|
||||||
gst::warning!(CAT, imp: self, "Dropping incomplete pending frame");
|
gst::warning!(CAT, imp = self, "Dropping incomplete pending frame");
|
||||||
state.pending_frame = None;
|
state.pending_frame = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,13 +297,22 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
Ok(_) => match state.quant_tables.get(&main_header.q) {
|
Ok(_) => match state.quant_tables.get(&main_header.q) {
|
||||||
Some(quant) => quant.clone(),
|
Some(quant) => quant.clone(),
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(CAT, imp: self, "Have no quantization table for Q {} yet", main_header.q);
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Have no quantization table for Q {} yet",
|
||||||
|
main_header.q
|
||||||
|
);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Failed to parse quantization table header: {err}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse quantization table header: {err}"
|
||||||
|
);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
@ -319,7 +336,7 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
} else if let Some((width, _)) = state.sdp_dimensions {
|
} else if let Some((width, _)) = state.sdp_dimensions {
|
||||||
width as i32
|
width as i32
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Can't determine valid width for frame");
|
gst::warning!(CAT, imp = self, "Can't determine valid width for frame");
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
};
|
};
|
||||||
|
@ -329,7 +346,7 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
} else if let Some((height, _)) = state.sdp_dimensions {
|
} else if let Some((height, _)) = state.sdp_dimensions {
|
||||||
height as i32
|
height as i32
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Can't determine valid height for frame");
|
gst::warning!(CAT, imp = self, "Can't determine valid height for frame");
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
};
|
};
|
||||||
|
@ -357,7 +374,7 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
}
|
}
|
||||||
|
|
||||||
let caps = caps_builder.build();
|
let caps = caps_builder.build();
|
||||||
gst::debug!(CAT, imp: self, "Setting caps {caps:?}");
|
gst::debug!(CAT, imp = self, "Setting caps {caps:?}");
|
||||||
self.obj().set_src_caps(&caps);
|
self.obj().set_src_caps(&caps);
|
||||||
state.dimensions = Some((width, height));
|
state.dimensions = Some((width, height));
|
||||||
state.framerate = state.sdp_framerate;
|
state.framerate = state.sdp_framerate;
|
||||||
|
@ -376,7 +393,7 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
) {
|
) {
|
||||||
Ok(jpeg_header) => jpeg_header,
|
Ok(jpeg_header) => jpeg_header,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Can't create JPEG header for frame: {err}");
|
gst::warning!(CAT, imp = self, "Can't create JPEG header for frame: {err}");
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
@ -384,7 +401,11 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
let mut w = ByteWriter::endian(&mut data, BigEndian);
|
let mut w = ByteWriter::endian(&mut data, BigEndian);
|
||||||
|
|
||||||
if let Err(err) = w.build::<JpegHeader>(&jpeg_header) {
|
if let Err(err) = w.build::<JpegHeader>(&jpeg_header) {
|
||||||
gst::warning!(CAT, imp: self, "Failed to write JPEG header for frame: {err}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write JPEG header for frame: {err}"
|
||||||
|
);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
@ -399,7 +420,10 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
|
|
||||||
let pending_frame = state.pending_frame.as_mut().expect("no pending frame");
|
let pending_frame = state.pending_frame.as_mut().expect("no pending frame");
|
||||||
if pending_frame.expected_fragment_offset != main_header.fragment_offset {
|
if pending_frame.expected_fragment_offset != main_header.fragment_offset {
|
||||||
gst::warning!(CAT, imp: self, "Expected fragment offset {} but got {}",
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Expected fragment offset {} but got {}",
|
||||||
pending_frame.expected_fragment_offset,
|
pending_frame.expected_fragment_offset,
|
||||||
main_header.fragment_offset,
|
main_header.fragment_offset,
|
||||||
);
|
);
|
||||||
|
@ -416,7 +440,7 @@ impl RtpBaseDepay2Impl for RtpJpegDepay {
|
||||||
{
|
{
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Main header changed in incompatible ways from {:?} to {:?} during a frame",
|
"Main header changed in incompatible ways from {:?} to {:?} during a frame",
|
||||||
pending_frame.main_header,
|
pending_frame.main_header,
|
||||||
main_header,
|
main_header,
|
||||||
|
|
|
@ -154,7 +154,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpJpegPay {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_sink_caps(&self, caps: &gst::Caps) -> bool {
|
fn set_sink_caps(&self, caps: &gst::Caps) -> bool {
|
||||||
gst::debug!(CAT, imp: self, "received caps {caps:?}");
|
gst::debug!(CAT, imp = self, "received caps {caps:?}");
|
||||||
|
|
||||||
let s = caps.structure(0).unwrap();
|
let s = caps.structure(0).unwrap();
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpJpegPay {
|
||||||
|
|
||||||
let max_payload_size = self.obj().max_payload_size();
|
let max_payload_size = self.obj().max_payload_size();
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "received buffer of size {}", buffer.size());
|
gst::trace!(CAT, imp = self, "received buffer of size {}", buffer.size());
|
||||||
|
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
|
@ -231,12 +231,16 @@ impl crate::basepay::RtpBasePay2Impl for RtpJpegPay {
|
||||||
let jpeg_header = match r.parse::<JpegHeader>() {
|
let jpeg_header = match r.parse::<JpegHeader>() {
|
||||||
Ok(header) => header,
|
Ok(header) => header,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed parsing JPEG header: {err}");
|
gst::error!(CAT, imp = self, "Failed parsing JPEG header: {err}");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let data_offset = cursor.position() as usize;
|
let data_offset = cursor.position() as usize;
|
||||||
gst::trace!(CAT, imp: self, "Parsed JPEG header {jpeg_header:?}, data starts at offset {data_offset}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Parsed JPEG header {jpeg_header:?}, data starts at offset {data_offset}"
|
||||||
|
);
|
||||||
|
|
||||||
// Try detecting static quantization headers
|
// Try detecting static quantization headers
|
||||||
let luma_quant = &jpeg_header.quant.luma_quant[..jpeg_header.quant.luma_len as usize];
|
let luma_quant = &jpeg_header.quant.luma_quant[..jpeg_header.quant.luma_len as usize];
|
||||||
|
@ -251,7 +255,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpJpegPay {
|
||||||
255
|
255
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Using Q {q}");
|
gst::trace!(CAT, imp = self, "Using Q {q}");
|
||||||
|
|
||||||
let mut data = &map[data_offset..];
|
let mut data = &map[data_offset..];
|
||||||
let mut fragment_offset = 0;
|
let mut fragment_offset = 0;
|
||||||
|
@ -265,7 +269,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpJpegPay {
|
||||||
height,
|
height,
|
||||||
};
|
};
|
||||||
let main_header_size = main_header.size().map_err(|err| {
|
let main_header_size = main_header.size().map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to write main header: {err:?}");
|
gst::error!(CAT, imp = self, "Failed to write main header: {err:?}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -281,7 +285,11 @@ impl crate::basepay::RtpBasePay2Impl for RtpJpegPay {
|
||||||
.map(|q| q.size(&main_header))
|
.map(|q| q.size(&main_header))
|
||||||
.unwrap_or(Ok(0))
|
.unwrap_or(Ok(0))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to write quantization table header: {err:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write quantization table header: {err:?}"
|
||||||
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -289,7 +297,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpJpegPay {
|
||||||
let payload_size = (max_payload_size as usize)
|
let payload_size = (max_payload_size as usize)
|
||||||
.checked_sub(overhead + 1)
|
.checked_sub(overhead + 1)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::error!(CAT, imp: self, "Too small MTU configured for stream");
|
gst::error!(CAT, imp = self, "Too small MTU configured for stream");
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::LibraryError::Settings,
|
gst::LibraryError::Settings,
|
||||||
|
@ -302,7 +310,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpJpegPay {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Writing packet with main header {main_header:?}, quantization table header {quant_table_header:?} and payload size {payload_size}",
|
"Writing packet with main header {main_header:?}, quantization table header {quant_table_header:?} and payload size {payload_size}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -314,13 +322,17 @@ impl crate::basepay::RtpBasePay2Impl for RtpJpegPay {
|
||||||
|
|
||||||
let mut w = ByteWriter::endian(&mut headers_buffer, BigEndian);
|
let mut w = ByteWriter::endian(&mut headers_buffer, BigEndian);
|
||||||
w.build::<MainHeader>(&main_header).map_err(|err| {
|
w.build::<MainHeader>(&main_header).map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to write main header: {err:?}");
|
gst::error!(CAT, imp = self, "Failed to write main header: {err:?}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
if let Some(quant_table_header) = quant_table_header {
|
if let Some(quant_table_header) = quant_table_header {
|
||||||
w.build_with::<QuantizationTableHeader>(&quant_table_header, &main_header)
|
w.build_with::<QuantizationTableHeader>(&quant_table_header, &main_header)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to write quantization table header: {err:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write quantization table header: {err:?}"
|
||||||
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
{
|
{
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Discontinuity, discarding {} bytes in accumulator",
|
"Discontinuity, discarding {} bytes in accumulator",
|
||||||
state.accumulator.len(),
|
state.accumulator.len(),
|
||||||
);
|
);
|
||||||
|
@ -189,7 +189,11 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
|
|
||||||
let end = packet.marker_bit() || looks_like == LooksLike::SelfContained;
|
let end = packet.marker_bit() || looks_like == LooksLike::SelfContained;
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "start: {start}, end: {end}, looks like: {looks_like:?}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"start: {start}, end: {end}, looks like: {looks_like:?}"
|
||||||
|
);
|
||||||
|
|
||||||
if end {
|
if end {
|
||||||
state.prev_marker_seqnum = Some(packet.ext_seqnum());
|
state.prev_marker_seqnum = Some(packet.ext_seqnum());
|
||||||
|
@ -198,7 +202,7 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
if start && looks_like == LooksLike::Undetermined {
|
if start && looks_like == LooksLike::Undetermined {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"New start, but data doesn't look like the start of a KLV unit?! Discarding",
|
"New start, but data doesn't look like the start of a KLV unit?! Discarding",
|
||||||
);
|
);
|
||||||
state.clear_accumulator();
|
state.clear_accumulator();
|
||||||
|
@ -210,7 +214,12 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
|
|
||||||
if looks_like == LooksLike::SelfContained {
|
if looks_like == LooksLike::SelfContained {
|
||||||
state.clear_accumulator();
|
state.clear_accumulator();
|
||||||
gst::debug!(CAT, imp: self, "Finished KLV unit, pushing out {} bytes", payload.len());
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Finished KLV unit, pushing out {} bytes",
|
||||||
|
payload.len()
|
||||||
|
);
|
||||||
return self
|
return self
|
||||||
.obj()
|
.obj()
|
||||||
.queue_buffer(packet.into(), packet.payload_buffer());
|
.queue_buffer(packet.into(), packet.payload_buffer());
|
||||||
|
@ -222,7 +231,7 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
if !state.accumulator.is_empty() {
|
if !state.accumulator.is_empty() {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"New start, but still {} bytes in accumulator, discarding",
|
"New start, but still {} bytes in accumulator, discarding",
|
||||||
state.accumulator.len(),
|
state.accumulator.len(),
|
||||||
);
|
);
|
||||||
|
@ -236,7 +245,7 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
// if it looks like a start we know we don't have enough bytes yet
|
// if it looks like a start we know we don't have enough bytes yet
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Start. Have {} bytes, but want {} bytes, waiting for more data",
|
"Start. Have {} bytes, but want {} bytes, waiting for more data",
|
||||||
state.accumulator.len(),
|
state.accumulator.len(),
|
||||||
klv_utils::peek_klv(payload).unwrap(),
|
klv_utils::peek_klv(payload).unwrap(),
|
||||||
|
@ -252,7 +261,7 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
if state.accumulator.is_empty() {
|
if state.accumulator.is_empty() {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Continuation fragment, but no data in accumulator. Need to wait for start of next unit, discarding.",
|
"Continuation fragment, but no data in accumulator. Need to wait for start of next unit, discarding.",
|
||||||
);
|
);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
|
@ -264,7 +273,7 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
let Ok(klv_unit_size) = klv_utils::peek_klv(&state.accumulator) else {
|
let Ok(klv_unit_size) = klv_utils::peek_klv(&state.accumulator) else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Accumulator does not contain KLV unit start?! Clearing.",
|
"Accumulator does not contain KLV unit start?! Clearing.",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -275,7 +284,7 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Continuation. Have {} bytes, want {} bytes",
|
"Continuation. Have {} bytes, want {} bytes",
|
||||||
state.accumulator.len(),
|
state.accumulator.len(),
|
||||||
klv_unit_size,
|
klv_unit_size,
|
||||||
|
@ -285,12 +294,12 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
if state.accumulator.len() >= klv_unit_size || end {
|
if state.accumulator.len() >= klv_unit_size || end {
|
||||||
if state.accumulator.len() != klv_unit_size {
|
if state.accumulator.len() != klv_unit_size {
|
||||||
if state.accumulator.len() > klv_unit_size {
|
if state.accumulator.len() > klv_unit_size {
|
||||||
gst::warning!(CAT, imp: self, "More bytes than expected in accumulator!");
|
gst::warning!(CAT, imp = self, "More bytes than expected in accumulator!");
|
||||||
} else {
|
} else {
|
||||||
// For now we'll honour the marker bit unconditionally and don't second-guess it
|
// For now we'll honour the marker bit unconditionally and don't second-guess it
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Fewer bytes than expected in accumulator, but marker bit set!",
|
"Fewer bytes than expected in accumulator, but marker bit set!",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -303,7 +312,7 @@ impl RtpBaseDepay2Impl for RtpKlvDepay {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Finished KLV unit, pushing out {} bytes",
|
"Finished KLV unit, pushing out {} bytes",
|
||||||
accumulator.len(),
|
accumulator.len(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -132,12 +132,12 @@ impl RtpBasePay2Impl for RtpKlvPay {
|
||||||
id: u64,
|
id: u64,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Can't map buffer readable");
|
gst::error!(CAT, imp = self, "Can't map buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if map.size() == 0 {
|
if map.size() == 0 {
|
||||||
gst::log!(CAT, imp: self, "Empty buffer, skipping");
|
gst::log!(CAT, imp = self, "Empty buffer, skipping");
|
||||||
self.obj().drop_buffers(id..=id);
|
self.obj().drop_buffers(id..=id);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ impl RtpBasePay2Impl for RtpKlvPay {
|
||||||
// Also post warning message?
|
// Also post warning message?
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Input doesn't look like a KLV unit, ignoring. {err:?}",
|
"Input doesn't look like a KLV unit, ignoring. {err:?}",
|
||||||
);
|
);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
|
@ -164,7 +164,7 @@ impl RtpBasePay2Impl for RtpKlvPay {
|
||||||
if unit_len != data.len() {
|
if unit_len != data.len() {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Input is not properly framed: KLV unit of size {unit_len} but buffer is {} bytes",
|
"Input is not properly framed: KLV unit of size {unit_len} but buffer is {} bytes",
|
||||||
data.len(),
|
data.len(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -210,9 +210,12 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMP2TDepay {
|
||||||
let payload = packet.payload();
|
let payload = packet.payload();
|
||||||
|
|
||||||
if payload.len() < 188 + bytes_to_skip {
|
if payload.len() < 188 + bytes_to_skip {
|
||||||
gst::warning!(CAT, imp: self,
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"Payload too small: {} bytes, but need at least {} bytes",
|
"Payload too small: {} bytes, but need at least {} bytes",
|
||||||
payload.len(), 188 + bytes_to_skip
|
payload.len(),
|
||||||
|
188 + bytes_to_skip
|
||||||
);
|
);
|
||||||
|
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
|
@ -236,7 +239,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMP2TDepay {
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(packet_size) = state.packet_size else {
|
let Some(packet_size) = state.packet_size else {
|
||||||
gst::debug!(CAT, imp: self, "Could not determine packet size, dropping packet {packet:?}");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Could not determine packet size, dropping packet {packet:?}"
|
||||||
|
);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
};
|
};
|
||||||
|
@ -248,14 +255,21 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMP2TDepay {
|
||||||
let n_packets = payload.len() / packet_size;
|
let n_packets = payload.len() / packet_size;
|
||||||
|
|
||||||
if payload.len() % packet_size != 0 {
|
if payload.len() % packet_size != 0 {
|
||||||
gst::warning!(CAT, imp: self,
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"Payload does not contain an integral number of MPEG-TS packets! ({} left over)",
|
"Payload does not contain an integral number of MPEG-TS packets! ({} left over)",
|
||||||
payload.len() % packet_size);
|
payload.len() % packet_size
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let output_size = n_packets * packet_size;
|
let output_size = n_packets * packet_size;
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Packet with {n_packets} MPEG-TS packets of size {packet_size}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Packet with {n_packets} MPEG-TS packets of size {packet_size}"
|
||||||
|
);
|
||||||
|
|
||||||
let mut buffer =
|
let mut buffer =
|
||||||
packet.payload_subbuffer_from_offset_with_length(bytes_to_skip, output_size);
|
packet.payload_subbuffer_from_offset_with_length(bytes_to_skip, output_size);
|
||||||
|
@ -266,7 +280,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMP2TDepay {
|
||||||
buffer_ref.set_flags(gst::BufferFlags::RESYNC);
|
buffer_ref.set_flags(gst::BufferFlags::RESYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Finishing buffer {buffer:?}");
|
gst::trace!(CAT, imp = self, "Finishing buffer {buffer:?}");
|
||||||
|
|
||||||
self.obj().queue_buffer(packet.into(), buffer)
|
self.obj().queue_buffer(packet.into(), buffer)
|
||||||
}
|
}
|
||||||
|
@ -277,7 +291,11 @@ impl RtpMP2TDepay {
|
||||||
const PACKET_SIZES: [(usize, usize); 4] = [(188, 0), (192, 4), (204, 0), (208, 0)];
|
const PACKET_SIZES: [(usize, usize); 4] = [(188, 0), (192, 4), (204, 0), (208, 0)];
|
||||||
|
|
||||||
for (size, offset) in PACKET_SIZES {
|
for (size, offset) in PACKET_SIZES {
|
||||||
gst::debug!(CAT, imp: self, "Trying MPEG-TS packet size of {size} bytes..");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Trying MPEG-TS packet size of {size} bytes.."
|
||||||
|
);
|
||||||
|
|
||||||
// Try exact size match for the payload first
|
// Try exact size match for the payload first
|
||||||
if payload.len() >= size
|
if payload.len() >= size
|
||||||
|
@ -286,16 +304,29 @@ impl RtpMP2TDepay {
|
||||||
.chunks_exact(size)
|
.chunks_exact(size)
|
||||||
.all(|packet| packet[offset] == TS_PACKET_SYNC)
|
.all(|packet| packet[offset] == TS_PACKET_SYNC)
|
||||||
{
|
{
|
||||||
gst::info!(CAT, imp: self, "Detected MPEG-TS packet size of {size} bytes, {} packets", payload.len() / size);
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Detected MPEG-TS packet size of {size} bytes, {} packets",
|
||||||
|
payload.len() / size
|
||||||
|
);
|
||||||
return NonZeroUsize::new(size);
|
return NonZeroUsize::new(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::warning!(CAT, imp: self, "Could not detect MPEG-TS packet size using full payload");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Could not detect MPEG-TS packet size using full payload"
|
||||||
|
);
|
||||||
|
|
||||||
// No match? Try if we find a size if we ignore any leftover bytes
|
// No match? Try if we find a size if we ignore any leftover bytes
|
||||||
for (size, offset) in PACKET_SIZES {
|
for (size, offset) in PACKET_SIZES {
|
||||||
gst::debug!(CAT, imp: self, "Trying MPEG-TS packet size of {size} bytes with remainder..");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Trying MPEG-TS packet size of {size} bytes with remainder.."
|
||||||
|
);
|
||||||
|
|
||||||
if payload.len() >= size
|
if payload.len() >= size
|
||||||
&& payload.len() % size != 0
|
&& payload.len() % size != 0
|
||||||
|
@ -303,13 +334,18 @@ impl RtpMP2TDepay {
|
||||||
.chunks_exact(size)
|
.chunks_exact(size)
|
||||||
.all(|packet| packet[offset] == TS_PACKET_SYNC)
|
.all(|packet| packet[offset] == TS_PACKET_SYNC)
|
||||||
{
|
{
|
||||||
gst::info!(CAT, imp: self, "Detected MPEG-TS packet size of {size} bytes, {} packets, {} bytes leftover",
|
gst::info!(
|
||||||
payload.len() / size, payload.len() % size);
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Detected MPEG-TS packet size of {size} bytes, {} packets, {} bytes leftover",
|
||||||
|
payload.len() / size,
|
||||||
|
payload.len() % size
|
||||||
|
);
|
||||||
return NonZeroUsize::new(size);
|
return NonZeroUsize::new(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::warning!(CAT, imp: self, "Could not detect MPEG-TS packet size");
|
gst::warning!(CAT, imp = self, "Could not detect MPEG-TS packet size");
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,14 +248,14 @@ impl crate::basepay::RtpBasePay2Impl for RtpMP2TPay {
|
||||||
//
|
//
|
||||||
// Set marker flag whenever the timestamp is discontinuous.
|
// Set marker flag whenever the timestamp is discontinuous.
|
||||||
if buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
if buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
||||||
gst::debug!(CAT, imp: self, "discont, pushing out pending packets");
|
gst::debug!(CAT, imp = self, "discont, pushing out pending packets");
|
||||||
self.send_pending_data(&mut state)?;
|
self.send_pending_data(&mut state)?;
|
||||||
self.obj().finish_pending_packets()?;
|
self.obj().finish_pending_packets()?;
|
||||||
state.discont_pending = true;
|
state.discont_pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Can't map buffer readable");
|
gst::error!(CAT, imp = self, "Can't map buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -292,7 +292,9 @@ impl crate::basepay::RtpBasePay2Impl for RtpMP2TPay {
|
||||||
let n_bytes_from_new_data_in_first_packet =
|
let n_bytes_from_new_data_in_first_packet =
|
||||||
target_payload_size - state.pending_data.len();
|
target_payload_size - state.pending_data.len();
|
||||||
|
|
||||||
gst::log!(CAT, imp: self,
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"Using {} bytes ({} packets) of old data and {} bytes ({} packets) from new buffer",
|
"Using {} bytes ({} packets) of old data and {} bytes ({} packets) from new buffer",
|
||||||
state.pending_data.len(),
|
state.pending_data.len(),
|
||||||
state.pending_data.len() / packet_size,
|
state.pending_data.len() / packet_size,
|
||||||
|
@ -321,7 +323,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpMP2TPay {
|
||||||
|
|
||||||
let remainder = iter.remainder();
|
let remainder = iter.remainder();
|
||||||
|
|
||||||
gst::log!(CAT, imp: self,
|
gst::log!(CAT, imp = self,
|
||||||
"Sending {} bytes ({} packets) in {} RTP packets with max payload size {}, {} bytes ({} packets) remaining for next time",
|
"Sending {} bytes ({} packets) in {} RTP packets with max payload size {}, {} bytes ({} packets) remaining for next time",
|
||||||
data.len() - remainder.len(),
|
data.len() - remainder.len(),
|
||||||
(data.len() - remainder.len()) / packet_size, data.len() / target_payload_size,
|
(data.len() - remainder.len()) / packet_size, data.len() / target_payload_size,
|
||||||
|
@ -364,11 +366,16 @@ impl crate::basepay::RtpBasePay2Impl for RtpMP2TPay {
|
||||||
impl RtpMP2TPay {
|
impl RtpMP2TPay {
|
||||||
fn send_pending_data(&self, state: &mut State) -> Result<gst::FlowSuccess, gst::FlowError> {
|
fn send_pending_data(&self, state: &mut State) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
if state.pending_data.is_empty() {
|
if state.pending_data.is_empty() {
|
||||||
gst::log!(CAT, imp: self, "No pending data, nothing to do");
|
gst::log!(CAT, imp = self, "No pending data, nothing to do");
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "Sending {} bytes of old data", state.pending_data.len());
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Sending {} bytes of old data",
|
||||||
|
state.pending_data.len()
|
||||||
|
);
|
||||||
|
|
||||||
let pending_id = state.pending_data.id();
|
let pending_id = state.pending_data.id();
|
||||||
|
|
||||||
|
|
|
@ -218,7 +218,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4AudioDepay {
|
||||||
|
|
||||||
let mut config = match ConfigWithCodecData::from_caps_structure(s) {
|
let mut config = match ConfigWithCodecData::from_caps_structure(s) {
|
||||||
Ok(Some(c)) => {
|
Ok(Some(c)) => {
|
||||||
gst::log!(CAT, imp: self, "{:?}", c.config);
|
gst::log!(CAT, imp = self, "{:?}", c.config);
|
||||||
|
|
||||||
caps_builder = caps_builder
|
caps_builder = caps_builder
|
||||||
.field("channels", c.config.prog.channel_conf as i32)
|
.field("channels", c.config.prog.channel_conf as i32)
|
||||||
|
@ -229,11 +229,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4AudioDepay {
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
// In-band StreamMuxConfig not supported yet
|
// In-band StreamMuxConfig not supported yet
|
||||||
gst::log!(CAT, imp: self, "config field not found");
|
gst::log!(CAT, imp = self, "config field not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Error parsing StreamMuxConfig: {err}");
|
gst::error!(CAT, imp = self, "Error parsing StreamMuxConfig: {err}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -249,7 +249,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4AudioDepay {
|
||||||
{
|
{
|
||||||
// FIXME this is a workaround for forward compatibility with AAC SBR & HE
|
// FIXME this is a workaround for forward compatibility with AAC SBR & HE
|
||||||
// see also comment in the parsers module.
|
// see also comment in the parsers module.
|
||||||
gst::warning!(CAT, imp: self, concat!(
|
gst::warning!(CAT, imp = self, concat!(
|
||||||
"Found audio object type {}, which uses a specific extension for samplingFrequency. ",
|
"Found audio object type {}, which uses a specific extension for samplingFrequency. ",
|
||||||
"This extension is not supported yet. ",
|
"This extension is not supported yet. ",
|
||||||
"Will use 'clock-rate' {} as a workaround.",
|
"Will use 'clock-rate' {} as a workaround.",
|
||||||
|
@ -258,7 +258,10 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4AudioDepay {
|
||||||
clock_rate,
|
clock_rate,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, concat!(
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
concat!(
|
||||||
"Caps 'clock-rate' {} and 'codec-data' sample rate {} mismatch. ",
|
"Caps 'clock-rate' {} and 'codec-data' sample rate {} mismatch. ",
|
||||||
"Will use 'clock-rate'",
|
"Will use 'clock-rate'",
|
||||||
),
|
),
|
||||||
|
@ -283,7 +286,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4AudioDepay {
|
||||||
|
|
||||||
// Can't push incomplete frames, so draining is the same as flushing.
|
// Can't push incomplete frames, so draining is the same as flushing.
|
||||||
fn flush(&self) {
|
fn flush(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Flushing");
|
gst::debug!(CAT, imp = self, "Flushing");
|
||||||
self.state.borrow_mut().flush();
|
self.state.borrow_mut().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +326,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4AudioDepay {
|
||||||
// See also: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1173
|
// See also: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1173
|
||||||
|
|
||||||
let Some(config) = state.config.as_ref() else {
|
let Some(config) = state.config.as_ref() else {
|
||||||
gst::error!(CAT, imp: self, "In-band StreamMuxConfig not supported");
|
gst::error!(CAT, imp = self, "In-band StreamMuxConfig not supported");
|
||||||
return Err(gst::FlowError::NotSupported);
|
return Err(gst::FlowError::NotSupported);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -334,7 +337,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4AudioDepay {
|
||||||
for (idx, subframe) in frame.take_subframes(config).enumerate() {
|
for (idx, subframe) in frame.take_subframes(config).enumerate() {
|
||||||
match subframe {
|
match subframe {
|
||||||
Ok(subframe) => {
|
Ok(subframe) => {
|
||||||
gst::log!(CAT, imp: self, "subframe {idx}: len {}", subframe.size());
|
gst::log!(CAT, imp = self, "subframe {idx}: len {}", subframe.size());
|
||||||
// The duration is always set by the subframes iterator
|
// The duration is always set by the subframes iterator
|
||||||
let duration = subframe.duration().expect("no duration set");
|
let duration = subframe.duration().expect("no duration set");
|
||||||
|
|
||||||
|
@ -351,11 +354,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4AudioDepay {
|
||||||
accumulated_duration.opt_add_assign(duration);
|
accumulated_duration.opt_add_assign(duration);
|
||||||
}
|
}
|
||||||
Err(err) if err.is_zero_length_subframe() => {
|
Err(err) if err.is_zero_length_subframe() => {
|
||||||
gst::warning!(CAT, imp: self, "{err}");
|
gst::warning!(CAT, imp = self, "{err}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "{err}");
|
gst::warning!(CAT, imp = self, "{err}");
|
||||||
self.obj().drop_packets(..=packet.ext_seqnum());
|
self.obj().drop_packets(..=packet.ext_seqnum());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -379,8 +382,11 @@ impl RtpMpeg4AudioDepay {
|
||||||
let delta = crate::utils::seqnum_distance(seqnum, seqnum_base);
|
let delta = crate::utils::seqnum_distance(seqnum, seqnum_base);
|
||||||
|
|
||||||
if delta == 0 {
|
if delta == 0 {
|
||||||
gst::debug!(CAT, imp: self,
|
gst::debug!(
|
||||||
"Got initial packet {seqnum_base} @ ext seqnum {}", packet.ext_seqnum(),
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Got initial packet {seqnum_base} @ ext seqnum {}",
|
||||||
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
state.can_parse = true;
|
state.can_parse = true;
|
||||||
|
|
||||||
|
@ -388,7 +394,9 @@ impl RtpMpeg4AudioDepay {
|
||||||
}
|
}
|
||||||
|
|
||||||
if delta < 0 {
|
if delta < 0 {
|
||||||
gst::log!(CAT, imp: self,
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"Waiting for initial packet {seqnum_base}, got {seqnum} (ext seqnum {})",
|
"Waiting for initial packet {seqnum_base}, got {seqnum} (ext seqnum {})",
|
||||||
packet.ext_seqnum(),
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
|
@ -396,7 +404,7 @@ impl RtpMpeg4AudioDepay {
|
||||||
return ControlFlow::Break(());
|
return ControlFlow::Break(());
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self,
|
gst::debug!(CAT, imp = self,
|
||||||
"Packet {seqnum} (ext seqnum {}) passed expected initial packet {seqnum_base}, will sync on next marker",
|
"Packet {seqnum} (ext seqnum {}) passed expected initial packet {seqnum_base}, will sync on next marker",
|
||||||
packet.ext_seqnum(),
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
|
@ -407,7 +415,7 @@ impl RtpMpeg4AudioDepay {
|
||||||
// AudioMuxElement doesn't come with a frame start marker
|
// AudioMuxElement doesn't come with a frame start marker
|
||||||
// so wait until a marked packet is found and start parsing from the next packet
|
// so wait until a marked packet is found and start parsing from the next packet
|
||||||
if packet.marker_bit() {
|
if packet.marker_bit() {
|
||||||
gst::debug!(CAT, imp: self,
|
gst::debug!(CAT, imp = self,
|
||||||
"Found first marked packet {seqnum} (ext seqnum {}). Will start parsing from next packet",
|
"Found first marked packet {seqnum} (ext seqnum {}). Will start parsing from next packet",
|
||||||
packet.ext_seqnum(),
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
|
@ -415,7 +423,9 @@ impl RtpMpeg4AudioDepay {
|
||||||
assert!(state.frame_acc.is_none());
|
assert!(state.frame_acc.is_none());
|
||||||
state.can_parse = true;
|
state.can_parse = true;
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, imp: self,
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"First marked packet not found yet, skipping packet {seqnum} (ext seqnum {})",
|
"First marked packet not found yet, skipping packet {seqnum} (ext seqnum {})",
|
||||||
packet.ext_seqnum(),
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -175,7 +175,7 @@ impl RtpBasePay2Impl for RtpMpeg4AudioPay {
|
||||||
let (config, config_data) = match ConfigWithCodecData::from_codec_data(s) {
|
let (config, config_data) = match ConfigWithCodecData::from_codec_data(s) {
|
||||||
Ok(c) => (c.audio_config, c.config_data),
|
Ok(c) => (c.audio_config, c.config_data),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Unusable codec_data: {err:#}");
|
gst::error!(CAT, imp = self, "Unusable codec_data: {err:#}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -212,14 +212,14 @@ impl RtpBasePay2Impl for RtpMpeg4AudioPay {
|
||||||
id: u64,
|
id: u64,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
if buffer.size() == 0 {
|
if buffer.size() == 0 {
|
||||||
gst::info!(CAT, imp: self, "Dropping empty buffer {id}");
|
gst::info!(CAT, imp = self, "Dropping empty buffer {id}");
|
||||||
self.obj().drop_buffers(..=id);
|
self.obj().drop_buffers(..=id);
|
||||||
|
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
let Ok(buffer_ref) = buffer.map_readable() else {
|
let Ok(buffer_ref) = buffer.map_readable() else {
|
||||||
gst::error!(CAT, imp: self, "Failed to map buffer {id} readable");
|
gst::error!(CAT, imp = self, "Failed to map buffer {id} readable");
|
||||||
|
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
};
|
};
|
||||||
|
@ -237,7 +237,7 @@ impl RtpBasePay2Impl for RtpMpeg4AudioPay {
|
||||||
if max_payload_size < size_prefix.len() {
|
if max_payload_size < size_prefix.len() {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Insufficient max-payload-size {} for buffer {id} at least {} bytes needed",
|
"Insufficient max-payload-size {} for buffer {id} at least {} bytes needed",
|
||||||
self.obj().max_payload_size(),
|
self.obj().max_payload_size(),
|
||||||
size_prefix.len() + 1,
|
size_prefix.len() + 1,
|
||||||
|
@ -268,10 +268,17 @@ impl RtpBasePay2Impl for RtpMpeg4AudioPay {
|
||||||
// audioMuxElement or the last fragment of an audioMuxElement.
|
// audioMuxElement or the last fragment of an audioMuxElement.
|
||||||
let marker = rem_data.is_empty();
|
let marker = rem_data.is_empty();
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "Queuing {}packet with size {} for {}buffer {id}",
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Queuing {}packet with size {} for {}buffer {id}",
|
||||||
if marker { "marked " } else { "" },
|
if marker { "marked " } else { "" },
|
||||||
payload.len(),
|
payload.len(),
|
||||||
if !marker || !is_first { "fragmented " } else { "" },
|
if !marker || !is_first {
|
||||||
|
"fragmented "
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
self.obj()
|
self.obj()
|
||||||
|
|
|
@ -274,7 +274,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&self) {
|
fn flush(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Flushing");
|
gst::debug!(CAT, imp = self, "Flushing");
|
||||||
self.state.borrow_mut().flush();
|
self.state.borrow_mut().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
|
|
||||||
let mode = s.get::<&str>("mode").expect("Required by Caps");
|
let mode = s.get::<&str>("mode").expect("Required by Caps");
|
||||||
if mode.starts_with("CELP") {
|
if mode.starts_with("CELP") {
|
||||||
gst::error!(CAT, imp: self, "{mode} not supported yet");
|
gst::error!(CAT, imp = self, "{mode} not supported yet");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
let mode_config = match ModeConfig::from_caps(s) {
|
let mode_config = match ModeConfig::from_caps(s) {
|
||||||
Ok(h) => h,
|
Ok(h) => h,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Error parsing Header in Caps: {err:#}");
|
gst::error!(CAT, imp = self, "Error parsing Header in Caps: {err:#}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -311,7 +311,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
caps_builder = caps_builder.field("codec_data", codec_data);
|
caps_builder = caps_builder.field("codec_data", codec_data);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Error parsing Caps: {err:#}");
|
gst::error!(CAT, imp = self, "Error parsing Caps: {err:#}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +324,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
state.seqnum_base = s.get_optional::<u32>("seqnum-base").unwrap();
|
state.seqnum_base = s.get_optional::<u32>("seqnum-base").unwrap();
|
||||||
if let Some(seqnum_base) = state.seqnum_base {
|
if let Some(seqnum_base) = state.seqnum_base {
|
||||||
gst::info!(CAT, imp: self, "Got seqnum_base {seqnum_base}");
|
gst::info!(CAT, imp = self, "Got seqnum_base {seqnum_base}");
|
||||||
}
|
}
|
||||||
state.clock_rate = clock_rate;
|
state.clock_rate = clock_rate;
|
||||||
|
|
||||||
|
@ -364,7 +364,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
let au_iter = match parser.parse(payload, ext_seqnum, packet_ts) {
|
let au_iter = match parser.parse(payload, ext_seqnum, packet_ts) {
|
||||||
Ok(au_iter) => au_iter,
|
Ok(au_iter) => au_iter,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Failed to parse payload for packet {ext_seqnum}: {err:#}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse payload for packet {ext_seqnum}: {err:#}"
|
||||||
|
);
|
||||||
*au_acc = None;
|
*au_acc = None;
|
||||||
self.obj().drop_packets(..=packet.ext_seqnum());
|
self.obj().drop_packets(..=packet.ext_seqnum());
|
||||||
|
|
||||||
|
@ -377,8 +381,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
let au = match au {
|
let au = match au {
|
||||||
Ok(au) => au,
|
Ok(au) => au,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self,
|
gst::warning!(
|
||||||
"Failed to parse AU from packet {}: {err:#}", packet.ext_seqnum(),
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse AU from packet {}: {err:#}",
|
||||||
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -390,13 +397,17 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
// > a fragmented Access Unit or one or more complete Access Units
|
// > a fragmented Access Unit or one or more complete Access Units
|
||||||
if !packet.marker_bit() {
|
if !packet.marker_bit() {
|
||||||
if !au.is_fragment {
|
if !au.is_fragment {
|
||||||
gst::warning!(CAT, imp: self, "Dropping non fragmented AU {au} in un-marked packet");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Dropping non fragmented AU {au} in un-marked packet"
|
||||||
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref mut acc) = au_acc {
|
if let Some(ref mut acc) = au_acc {
|
||||||
if let Err(err) = acc.try_append(au) {
|
if let Err(err) = acc.try_append(au) {
|
||||||
gst::warning!(CAT, imp: self, "Discarding pending fragmented AU: {err}");
|
gst::warning!(CAT, imp = self, "Discarding pending fragmented AU: {err}");
|
||||||
*au_acc = None;
|
*au_acc = None;
|
||||||
parser.reset();
|
parser.reset();
|
||||||
self.obj().drop_packets(..=packet.ext_seqnum());
|
self.obj().drop_packets(..=packet.ext_seqnum());
|
||||||
|
@ -407,7 +418,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
*au_acc = Some(AuAccumulator::new(au));
|
*au_acc = Some(AuAccumulator::new(au));
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Non-final fragment");
|
gst::trace!(CAT, imp = self, "Non-final fragment");
|
||||||
|
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
@ -418,7 +429,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
Some(mut acc) => {
|
Some(mut acc) => {
|
||||||
if au.is_fragment {
|
if au.is_fragment {
|
||||||
if let Err(err) = acc.try_append(au) {
|
if let Err(err) = acc.try_append(au) {
|
||||||
gst::warning!(CAT, imp: self, "Discarding pending fragmented AU: {err}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Discarding pending fragmented AU: {err}"
|
||||||
|
);
|
||||||
parser.reset();
|
parser.reset();
|
||||||
self.obj().drop_packets(..=packet.ext_seqnum());
|
self.obj().drop_packets(..=packet.ext_seqnum());
|
||||||
|
|
||||||
|
@ -428,7 +443,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
match acc.try_into_au() {
|
match acc.try_into_au() {
|
||||||
Ok(au) => au,
|
Ok(au) => au,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Discarding pending fragmented AU: {err}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Discarding pending fragmented AU: {err}"
|
||||||
|
);
|
||||||
let Mpeg4GenericDepayError::FragmentedAuSizeMismatch { .. } = err
|
let Mpeg4GenericDepayError::FragmentedAuSizeMismatch { .. } = err
|
||||||
else {
|
else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
|
@ -440,7 +459,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self,
|
gst::warning!(CAT, imp = self,
|
||||||
"Discarding pending fragmented AU {} due to incoming non fragmented AU {au}",
|
"Discarding pending fragmented AU {} due to incoming non fragmented AU {au}",
|
||||||
acc.0,
|
acc.0,
|
||||||
);
|
);
|
||||||
|
@ -454,7 +473,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
|
|
||||||
if let Some(ref mut deint_buf) = deint_buf {
|
if let Some(ref mut deint_buf) = deint_buf {
|
||||||
if let Err(err) = deint_buf.push_and_pop(au, &mut aus) {
|
if let Err(err) = deint_buf.push_and_pop(au, &mut aus) {
|
||||||
gst::warning!(CAT, imp: self, "Failed to push AU to deinterleave buffer: {err}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to push AU to deinterleave buffer: {err}"
|
||||||
|
);
|
||||||
// The AU has been dropped, just keep going
|
// The AU has been dropped, just keep going
|
||||||
// Packet will be dropped eventually
|
// Packet will be dropped eventually
|
||||||
}
|
}
|
||||||
|
@ -467,7 +490,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpMpeg4GenericDepay {
|
||||||
// > some broken non-interleaved streams have AU-index jumping around
|
// > some broken non-interleaved streams have AU-index jumping around
|
||||||
// > all over the place, apparently assuming receiver disregards
|
// > all over the place, apparently assuming receiver disregards
|
||||||
|
|
||||||
gst::warning!(CAT, imp: self, "Interleaved AU, but no `max_displacement` was defined");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Interleaved AU, but no `max_displacement` was defined"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
aus.push(au);
|
aus.push(au);
|
||||||
|
@ -498,8 +525,11 @@ impl RtpMpeg4GenericDepay {
|
||||||
let delta = crate::utils::seqnum_distance(seqnum, seqnum_base);
|
let delta = crate::utils::seqnum_distance(seqnum, seqnum_base);
|
||||||
|
|
||||||
if delta == 0 {
|
if delta == 0 {
|
||||||
gst::debug!(CAT, imp: self,
|
gst::debug!(
|
||||||
"Got initial packet {seqnum_base} @ ext seqnum {}", packet.ext_seqnum(),
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Got initial packet {seqnum_base} @ ext seqnum {}",
|
||||||
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
state.can_parse = true;
|
state.can_parse = true;
|
||||||
|
|
||||||
|
@ -507,7 +537,9 @@ impl RtpMpeg4GenericDepay {
|
||||||
}
|
}
|
||||||
|
|
||||||
if delta < 0 {
|
if delta < 0 {
|
||||||
gst::log!(CAT, imp: self,
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"Waiting for initial packet {seqnum_base}, got {seqnum} (ext seqnum {})",
|
"Waiting for initial packet {seqnum_base}, got {seqnum} (ext seqnum {})",
|
||||||
packet.ext_seqnum(),
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
|
@ -515,7 +547,7 @@ impl RtpMpeg4GenericDepay {
|
||||||
return ControlFlow::Break(());
|
return ControlFlow::Break(());
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self,
|
gst::debug!(CAT, imp = self,
|
||||||
"Packet {seqnum} (ext seqnum {}) passed expected initial packet {seqnum_base}, will sync on next marker",
|
"Packet {seqnum} (ext seqnum {}) passed expected initial packet {seqnum_base}, will sync on next marker",
|
||||||
packet.ext_seqnum(),
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
|
@ -525,7 +557,7 @@ impl RtpMpeg4GenericDepay {
|
||||||
|
|
||||||
// Wait until a marked packet is found and start parsing from the next packet
|
// Wait until a marked packet is found and start parsing from the next packet
|
||||||
if packet.marker_bit() {
|
if packet.marker_bit() {
|
||||||
gst::debug!(CAT, imp: self,
|
gst::debug!(CAT, imp = self,
|
||||||
"Found first marked packet {seqnum} (ext seqnum {}). Will start parsing from next packet",
|
"Found first marked packet {seqnum} (ext seqnum {}). Will start parsing from next packet",
|
||||||
packet.ext_seqnum(),
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
|
@ -533,7 +565,9 @@ impl RtpMpeg4GenericDepay {
|
||||||
assert!(state.au_acc.is_none());
|
assert!(state.au_acc.is_none());
|
||||||
state.can_parse = true;
|
state.can_parse = true;
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, imp: self,
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"First marked packet not found yet, skipping packet {seqnum} (ext seqnum {})",
|
"First marked packet not found yet, skipping packet {seqnum} (ext seqnum {})",
|
||||||
packet.ext_seqnum(),
|
packet.ext_seqnum(),
|
||||||
);
|
);
|
||||||
|
@ -590,7 +624,11 @@ impl RtpMpeg4GenericDepay {
|
||||||
let packet_to_buffer_relation =
|
let packet_to_buffer_relation =
|
||||||
get_packet_to_buffer_relation(&au, state.clock_rate, range);
|
get_packet_to_buffer_relation(&au, state.clock_rate, range);
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Finishing AU buffer {packet_to_buffer_relation:?}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Finishing AU buffer {packet_to_buffer_relation:?}"
|
||||||
|
);
|
||||||
|
|
||||||
let buffer = Self::new_buffer(au, state);
|
let buffer = Self::new_buffer(au, state);
|
||||||
|
|
||||||
|
@ -607,7 +645,11 @@ impl RtpMpeg4GenericDepay {
|
||||||
let packet_to_buffer_relation =
|
let packet_to_buffer_relation =
|
||||||
get_packet_to_buffer_relation(&au, state.clock_rate, range);
|
get_packet_to_buffer_relation(&au, state.clock_rate, range);
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Finishing AU buffer {packet_to_buffer_relation:?}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Finishing AU buffer {packet_to_buffer_relation:?}"
|
||||||
|
);
|
||||||
|
|
||||||
let buffer = Self::new_buffer(au, state);
|
let buffer = Self::new_buffer(au, state);
|
||||||
|
|
||||||
|
|
|
@ -334,13 +334,13 @@ impl RtpBasePay2Impl for RtpMpeg4GenericPay {
|
||||||
let codec_data = match s.get::<&gst::BufferRef>("codec_data") {
|
let codec_data = match s.get::<&gst::BufferRef>("codec_data") {
|
||||||
Ok(codec_data) => codec_data,
|
Ok(codec_data) => codec_data,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Error getting codec_data from Caps: {err}");
|
gst::error!(CAT, imp = self, "Error getting codec_data from Caps: {err}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(codec_data) = codec_data.map_readable() else {
|
let Ok(codec_data) = codec_data.map_readable() else {
|
||||||
gst::error!(CAT, imp: self, "Failed to map codec_data as readable");
|
gst::error!(CAT, imp = self, "Failed to map codec_data as readable");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -358,25 +358,34 @@ impl RtpBasePay2Impl for RtpMpeg4GenericPay {
|
||||||
let config = match r.parse::<AudioSpecificConfig>() {
|
let config = match r.parse::<AudioSpecificConfig>() {
|
||||||
Ok(config) => config,
|
Ok(config) => config,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Error parsing audio codec_data: {err:#}");
|
gst::error!(CAT, imp = self, "Error parsing audio codec_data: {err:#}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if config.audio_object_type == 0 || config.audio_object_type > 6 {
|
if config.audio_object_type == 0 || config.audio_object_type > 6 {
|
||||||
gst::error!(CAT, imp: self, "Unsupported Audio Object Type {}", config.audio_object_type);
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Unsupported Audio Object Type {}",
|
||||||
|
config.audio_object_type
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let profile_level = match ProfileLevel::from_caps(s) {
|
let profile_level = match ProfileLevel::from_caps(s) {
|
||||||
Ok(profile_level) => profile_level,
|
Ok(profile_level) => profile_level,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Error getting profile level from Caps: {err:#}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Error getting profile level from Caps: {err:#}"
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "Using audio codec_data {config:?}");
|
gst::log!(CAT, imp = self, "Using audio codec_data {config:?}");
|
||||||
|
|
||||||
// AAC-hbr: also used by rtpmp4gpay
|
// AAC-hbr: also used by rtpmp4gpay
|
||||||
// RFC 3640 also defines AAC-lbr, with a maximum encoded buffer
|
// RFC 3640 also defines AAC-lbr, with a maximum encoded buffer
|
||||||
|
@ -411,18 +420,22 @@ impl RtpBasePay2Impl for RtpMpeg4GenericPay {
|
||||||
}
|
}
|
||||||
"video/mpeg" => {
|
"video/mpeg" => {
|
||||||
if codec_data.len() < 5 {
|
if codec_data.len() < 5 {
|
||||||
gst::error!(CAT, imp: self, "Error parsing video codec_data: too short");
|
gst::error!(CAT, imp = self, "Error parsing video codec_data: too short");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let code = u32::from_be_bytes(codec_data[..4].try_into().unwrap());
|
let code = u32::from_be_bytes(codec_data[..4].try_into().unwrap());
|
||||||
let profile = if code == VOS_STARTCODE {
|
let profile = if code == VOS_STARTCODE {
|
||||||
let profile = codec_data[4];
|
let profile = codec_data[4];
|
||||||
gst::log!(CAT, imp: self, "Using video codec_data profile {profile}");
|
gst::log!(CAT, imp = self, "Using video codec_data profile {profile}");
|
||||||
|
|
||||||
profile
|
profile
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Unexpected VOS startcode in video codec_data. Assuming profile '1'");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Unexpected VOS startcode in video codec_data. Assuming profile '1'"
|
||||||
|
);
|
||||||
|
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
|
@ -510,8 +523,14 @@ impl RtpBasePay2Impl for RtpMpeg4GenericPay {
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
let mut settings = self.settings.lock().unwrap();
|
let mut settings = self.settings.lock().unwrap();
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Handling buffer {id} duration {} pts {} dts {}, len {}",
|
gst::trace!(
|
||||||
buffer.duration().display(), buffer.pts().display(), buffer.dts().display(), buffer.size(),
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Handling buffer {id} duration {} pts {} dts {}, len {}",
|
||||||
|
buffer.duration().display(),
|
||||||
|
buffer.pts().display(),
|
||||||
|
buffer.dts().display(),
|
||||||
|
buffer.size(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let maybe_random_access = if state.mode.random_access_indication {
|
let maybe_random_access = if state.mode.random_access_indication {
|
||||||
|
@ -520,17 +539,23 @@ impl RtpBasePay2Impl for RtpMpeg4GenericPay {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let dts_delta = ct_delta_to_rtp(buffer.dts(), buffer.pts(), state.clock_rate).and_then(|dts_delta_res| {
|
let dts_delta = ct_delta_to_rtp(buffer.dts(), buffer.pts(), state.clock_rate).and_then(
|
||||||
|
|dts_delta_res| {
|
||||||
if dts_delta_res.is_none() {
|
if dts_delta_res.is_none() {
|
||||||
gst::warning!(CAT, imp: self, "Overflow computing DTS-delta between pts {} & dts {}",
|
gst::warning!(
|
||||||
buffer.dts().display(), buffer.pts().display(),
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Overflow computing DTS-delta between pts {} & dts {}",
|
||||||
|
buffer.dts().display(),
|
||||||
|
buffer.pts().display(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
dts_delta_res
|
dts_delta_res
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self,
|
gst::trace!(CAT, imp = self,
|
||||||
"Pushing AU from buffer {id} dts_delta {dts_delta:?} random access {maybe_random_access:?}",
|
"Pushing AU from buffer {id} dts_delta {dts_delta:?} random access {maybe_random_access:?}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -540,7 +565,7 @@ impl RtpBasePay2Impl for RtpMpeg4GenericPay {
|
||||||
pts: buffer.pts(),
|
pts: buffer.pts(),
|
||||||
dts_delta,
|
dts_delta,
|
||||||
buffer: buffer.clone().into_mapped_buffer_readable().map_err(|_| {
|
buffer: buffer.clone().into_mapped_buffer_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Can't map incoming buffer readable");
|
gst::error!(CAT, imp = self, "Can't map incoming buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?,
|
})?,
|
||||||
maybe_random_access,
|
maybe_random_access,
|
||||||
|
@ -585,7 +610,7 @@ impl RtpBasePay2Impl for RtpMpeg4GenericPay {
|
||||||
let mut live_guard = self.is_live.lock().unwrap();
|
let mut live_guard = self.is_live.lock().unwrap();
|
||||||
|
|
||||||
if Some(is_live) != *live_guard {
|
if Some(is_live) != *live_guard {
|
||||||
gst::info!(CAT, imp: self, "Upstream is live: {is_live}");
|
gst::info!(CAT, imp = self, "Upstream is live: {is_live}");
|
||||||
*live_guard = Some(is_live);
|
*live_guard = Some(is_live);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,7 +622,9 @@ impl RtpBasePay2Impl for RtpMpeg4GenericPay {
|
||||||
min += max_ptime;
|
min += max_ptime;
|
||||||
max.opt_add_assign(max_ptime);
|
max.opt_add_assign(max_ptime);
|
||||||
} else if is_live {
|
} else if is_live {
|
||||||
gst::warning!(CAT, imp: self,
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"Aggregating packets in live mode, but no max_ptime configured. \
|
"Aggregating packets in live mode, but no max_ptime configured. \
|
||||||
Configured latency may be too low!"
|
Configured latency may be too low!"
|
||||||
);
|
);
|
||||||
|
@ -642,7 +669,13 @@ impl RtpMpeg4GenericPay {
|
||||||
let agg_mode = self.effective_aggregate_mode(settings);
|
let agg_mode = self.effective_aggregate_mode(settings);
|
||||||
|
|
||||||
if (self.obj().mtu() as usize) < state.min_mtu {
|
if (self.obj().mtu() as usize) < state.min_mtu {
|
||||||
gst::error!(CAT, imp: self, "Insufficient mtu {} at least {} bytes needed", self.obj().mtu(), state.min_mtu);
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Insufficient mtu {} at least {} bytes needed",
|
||||||
|
self.obj().mtu(),
|
||||||
|
state.min_mtu
|
||||||
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,7 +726,13 @@ impl RtpMpeg4GenericPay {
|
||||||
res = w.write(7, 0).map_err(Into::into);
|
res = w.write(7, 0).map_err(Into::into);
|
||||||
}
|
}
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::error!(CAT, imp: self, "Failed to write header for AU {} in buffer {}: {err:#}", header.index, au.id);
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write header for AU {} in buffer {}: {err:#}",
|
||||||
|
header.index,
|
||||||
|
au.id
|
||||||
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,18 +787,24 @@ impl RtpMpeg4GenericPay {
|
||||||
.opt_gt(max_ptime)
|
.opt_gt(max_ptime)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
|
|
||||||
gst::log!(CAT, imp: self,
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"Pending: size {}, duration ~{:.3}, mode: {agg_mode:?} + {send_mode:?} => {}",
|
"Pending: size {}, duration ~{:.3}, mode: {agg_mode:?} + {send_mode:?} => {}",
|
||||||
state.pending_size,
|
state.pending_size,
|
||||||
state.pending_duration.display(),
|
state.pending_duration.display(),
|
||||||
if is_ready { "ready" } else { "not ready, waiting for more data" },
|
if is_ready {
|
||||||
|
"ready"
|
||||||
|
} else {
|
||||||
|
"not ready, waiting for more data"
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if !is_ready {
|
if !is_ready {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Creating packet..");
|
gst::trace!(CAT, imp = self, "Creating packet..");
|
||||||
|
|
||||||
let id = front.id;
|
let id = front.id;
|
||||||
let mut end_id = front.id;
|
let mut end_id = front.id;
|
||||||
|
@ -776,7 +821,11 @@ impl RtpMpeg4GenericPay {
|
||||||
au_data_list.clear();
|
au_data_list.clear();
|
||||||
|
|
||||||
while let Some(front) = state.pending_aus.front() {
|
while let Some(front) = state.pending_aus.front() {
|
||||||
gst::trace!(CAT, imp: self, "{front:?}, accumulated size {acc_size} duration ~{acc_duration:.3}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"{front:?}, accumulated size {acc_size} duration ~{acc_duration:.3}"
|
||||||
|
);
|
||||||
|
|
||||||
// If this AU would overflow the packet, bail out and send out what we have.
|
// If this AU would overflow the packet, bail out and send out what we have.
|
||||||
//
|
//
|
||||||
|
@ -790,15 +839,21 @@ impl RtpMpeg4GenericPay {
|
||||||
// No CTS-delta for the first AU in the packet
|
// No CTS-delta for the first AU in the packet
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
ct_delta_to_rtp(front.pts, previous_pts, state.clock_rate).and_then(|dts_delta_res| {
|
ct_delta_to_rtp(front.pts, previous_pts, state.clock_rate).and_then(
|
||||||
|
|dts_delta_res| {
|
||||||
if dts_delta_res.is_none() {
|
if dts_delta_res.is_none() {
|
||||||
gst::warning!(CAT, imp: self, "Overflow computing CTS-delta between pts {} & previous pts {}",
|
gst::warning!(
|
||||||
front.pts.display(), previous_pts.display(),
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Overflow computing CTS-delta between pts {} & previous pts {}",
|
||||||
|
front.pts.display(),
|
||||||
|
previous_pts.display(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
dts_delta_res
|
dts_delta_res
|
||||||
})
|
},
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
previous_pts = front.pts;
|
previous_pts = front.pts;
|
||||||
|
@ -813,8 +868,12 @@ impl RtpMpeg4GenericPay {
|
||||||
};
|
};
|
||||||
|
|
||||||
w.build_with(&header, &ctx).map_err(|err| {
|
w.build_with(&header, &ctx).map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to write header for AU {} in buffer {}: {err:#}",
|
gst::error!(
|
||||||
header.index, front.id,
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write header for AU {} in buffer {}: {err:#}",
|
||||||
|
header.index,
|
||||||
|
front.id,
|
||||||
);
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
@ -852,7 +911,10 @@ impl RtpMpeg4GenericPay {
|
||||||
|
|
||||||
// add final padding
|
// add final padding
|
||||||
if let Err(err) = w.write(7, 0) {
|
if let Err(err) = w.write(7, 0) {
|
||||||
gst::error!(CAT, imp: self, "Failed to write padding for final AU {} in buffer {end_id}: {err}",
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write padding for final AU {} in buffer {end_id}: {err}",
|
||||||
ctx.prev_index.expect("at least one AU"),
|
ctx.prev_index.expect("at least one AU"),
|
||||||
);
|
);
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
|
@ -874,7 +936,12 @@ impl RtpMpeg4GenericPay {
|
||||||
.queue_packet(PacketToBufferRelation::Ids(id..=end_id), packet)?;
|
.queue_packet(PacketToBufferRelation::Ids(id..=end_id), packet)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::log!(CAT, imp: self, "All done for now, {} pending AUs", state.pending_aus.len());
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"All done for now, {} pending AUs",
|
||||||
|
state.pending_aus.len()
|
||||||
|
);
|
||||||
|
|
||||||
if send_mode == SendPacketMode::ForcePending {
|
if send_mode == SendPacketMode::ForcePending {
|
||||||
self.obj().finish_pending_packets()?;
|
self.obj().finish_pending_packets()?;
|
||||||
|
@ -916,6 +983,6 @@ impl RtpMpeg4GenericPay {
|
||||||
|
|
||||||
*self.is_live.lock().unwrap() = Some(is_live);
|
*self.is_live.lock().unwrap() = Some(is_live);
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Upstream is live: {is_live}");
|
gst::info!(CAT, imp = self, "Upstream is live: {is_live}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,9 +118,12 @@ impl RtpBaseDepay2Impl for RtpOpusDepay {
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(src_caps) = res else {
|
let Ok(src_caps) = res else {
|
||||||
gst::warning!(CAT, imp: self,
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
"Failed to parse {encoding_name} RTP input caps {s}: {}",
|
"Failed to parse {encoding_name} RTP input caps {s}: {}",
|
||||||
res.unwrap_err());
|
res.unwrap_err()
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -150,7 +153,7 @@ impl RtpBaseDepay2Impl for RtpOpusDepay {
|
||||||
outbuf_ref.set_flags(gst::BufferFlags::RESYNC);
|
outbuf_ref.set_flags(gst::BufferFlags::RESYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Finishing buffer {outbuf:?}");
|
gst::trace!(CAT, imp = self, "Finishing buffer {outbuf:?}");
|
||||||
|
|
||||||
self.obj().queue_buffer(packet.into(), outbuf)
|
self.obj().queue_buffer(packet.into(), outbuf)
|
||||||
}
|
}
|
||||||
|
@ -175,7 +178,11 @@ impl RtpOpusDepay {
|
||||||
0 => 1, // mono
|
0 => 1, // mono
|
||||||
1 => 2, // stereo
|
1 => 2, // stereo
|
||||||
_ => {
|
_ => {
|
||||||
gst::warning!(CAT, imp: self, "Unexpected sprop-stereo value {v} in input caps {s}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Unexpected sprop-stereo value {v} in input caps {s}"
|
||||||
|
);
|
||||||
DEFAULT_CHANNELS
|
DEFAULT_CHANNELS
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -293,7 +300,11 @@ impl RtpOpusDepay {
|
||||||
let duration = frame_duration * n_frames;
|
let duration = frame_duration * n_frames;
|
||||||
|
|
||||||
if duration > gst::ClockTime::from_mseconds(120) {
|
if duration > gst::ClockTime::from_mseconds(120) {
|
||||||
gst::warning!(CAT, imp: self, "Opus packet with frame duration {duration:?} > 120ms");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Opus packet with frame duration {duration:?} > 120ms"
|
||||||
|
);
|
||||||
return gst::ClockTime::NONE;
|
return gst::ClockTime::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,11 @@ impl RtpBasePay2Impl for RtpOpusPay {
|
||||||
// Can't use .collect().map_err()? because it doesn't work for funcs with bool returns
|
// Can't use .collect().map_err()? because it doesn't work for funcs with bool returns
|
||||||
match res {
|
match res {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
gst::error!(CAT, imp: self, "Invalid 'channel-mapping' field types");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Invalid 'channel-mapping' field types"
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Ok(num_strings) => num_strings.join(","),
|
Ok(num_strings) => num_strings.join(","),
|
||||||
|
@ -289,7 +293,7 @@ impl RtpBasePay2Impl for RtpOpusPay {
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
|
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::error!(CAT, imp: self, "Can't map buffer readable");
|
gst::error!(CAT, imp = self, "Can't map buffer readable");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -303,7 +307,12 @@ impl RtpBasePay2Impl for RtpOpusPay {
|
||||||
//
|
//
|
||||||
// Even in DTX mode there will still be a non-DTX packet going through every 400ms.
|
// Even in DTX mode there will still be a non-DTX packet going through every 400ms.
|
||||||
if dtx && data.len() <= 2 {
|
if dtx && data.len() <= 2 {
|
||||||
gst::log!(CAT, imp: self, "Not sending out empty DTX packet {:?}", buffer);
|
gst::log!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Not sending out empty DTX packet {:?}",
|
||||||
|
buffer
|
||||||
|
);
|
||||||
// The first non-DTX packet will be the start of a talkspurt
|
// The first non-DTX packet will be the start of a talkspurt
|
||||||
state.marker_pending = true;
|
state.marker_pending = true;
|
||||||
self.obj().drop_buffers(..=id);
|
self.obj().drop_buffers(..=id);
|
||||||
|
@ -370,22 +379,27 @@ impl RtpBasePay2Impl for RtpOpusPay {
|
||||||
if s.get::<i32>("channel-mapping-family") == Ok(0) {
|
if s.get::<i32>("channel-mapping-family") == Ok(0) {
|
||||||
let peer_s = peer_caps.structure(0).unwrap();
|
let peer_s = peer_caps.structure(0).unwrap();
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Peer preference structure: {peer_s}");
|
gst::trace!(CAT, imp = self, "Peer preference structure: {peer_s}");
|
||||||
|
|
||||||
let pref_chans = peer_s.get::<&str>("stereo")
|
let pref_chans = peer_s
|
||||||
|
.get::<&str>("stereo")
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|params| params.trim().parse::<i32>().ok())
|
.and_then(|params| params.trim().parse::<i32>().ok())
|
||||||
.map(|v| match v {
|
.map(|v| match v {
|
||||||
0 => 1, // mono
|
0 => 1, // mono
|
||||||
1 => 2, // stereo
|
1 => 2, // stereo
|
||||||
_ => {
|
_ => {
|
||||||
gst::warning!(CAT, imp: self, "Unexpected stereo value {v} in peer caps {s}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Unexpected stereo value {v} in peer caps {s}"
|
||||||
|
);
|
||||||
2 // default is stereo
|
2 // default is stereo
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(pref_chans) = pref_chans {
|
if let Some(pref_chans) = pref_chans {
|
||||||
gst::trace!(CAT, imp: self, "Peer preference: channels={pref_chans}");
|
gst::trace!(CAT, imp = self, "Peer preference: channels={pref_chans}");
|
||||||
|
|
||||||
let mut pref_caps = gst::Caps::builder("audio/x-opus")
|
let mut pref_caps = gst::Caps::builder("audio/x-opus")
|
||||||
.field("channel-mapping-family", 0i32)
|
.field("channel-mapping-family", 0i32)
|
||||||
|
|
|
@ -93,7 +93,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpPcmauDepay {
|
||||||
buffer_ref.set_flags(gst::BufferFlags::RESYNC);
|
buffer_ref.set_flags(gst::BufferFlags::RESYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Finishing buffer {buffer:?}");
|
gst::trace!(CAT, imp = self, "Finishing buffer {buffer:?}");
|
||||||
|
|
||||||
self.obj().queue_buffer(packet.into(), buffer)
|
self.obj().queue_buffer(packet.into(), buffer)
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,7 +318,7 @@ impl RecvSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_rtp_task(&mut self, pad: &gst::Pad) -> Result<(), glib::BoolError> {
|
fn start_rtp_task(&mut self, pad: &gst::Pad) -> Result<(), glib::BoolError> {
|
||||||
gst::debug!(CAT, obj: pad, "Starting rtp recv src task");
|
gst::debug!(CAT, obj = pad, "Starting rtp recv src task");
|
||||||
|
|
||||||
let recv_pad = self
|
let recv_pad = self
|
||||||
.rtp_recv_srcpads
|
.rtp_recv_srcpads
|
||||||
|
@ -354,21 +354,21 @@ impl RecvSession {
|
||||||
match item {
|
match item {
|
||||||
JitterBufferItem::PacketList(list) => {
|
JitterBufferItem::PacketList(list) => {
|
||||||
let flow = pad.push_list(list);
|
let flow = pad.push_list(list);
|
||||||
gst::trace!(CAT, obj: pad, "Pushed buffer list, flow ret {:?}", flow);
|
gst::trace!(CAT, obj = pad, "Pushed buffer list, flow ret {:?}", flow);
|
||||||
let mut recv_flow_combiner = recv_flow_combiner.lock().unwrap();
|
let mut recv_flow_combiner = recv_flow_combiner.lock().unwrap();
|
||||||
let _combined_flow = recv_flow_combiner.update_pad_flow(&pad, flow);
|
let _combined_flow = recv_flow_combiner.update_pad_flow(&pad, flow);
|
||||||
// TODO: store flow, return only on session pads?
|
// TODO: store flow, return only on session pads?
|
||||||
}
|
}
|
||||||
JitterBufferItem::Packet(buffer) => {
|
JitterBufferItem::Packet(buffer) => {
|
||||||
let flow = pad.push(buffer);
|
let flow = pad.push(buffer);
|
||||||
gst::trace!(CAT, obj: pad, "Pushed buffer, flow ret {:?}", flow);
|
gst::trace!(CAT, obj = pad, "Pushed buffer, flow ret {:?}", flow);
|
||||||
let mut recv_flow_combiner = recv_flow_combiner.lock().unwrap();
|
let mut recv_flow_combiner = recv_flow_combiner.lock().unwrap();
|
||||||
let _combined_flow = recv_flow_combiner.update_pad_flow(&pad, flow);
|
let _combined_flow = recv_flow_combiner.update_pad_flow(&pad, flow);
|
||||||
// TODO: store flow, return only on session pads?
|
// TODO: store flow, return only on session pads?
|
||||||
}
|
}
|
||||||
JitterBufferItem::Event(event) => {
|
JitterBufferItem::Event(event) => {
|
||||||
let res = pad.push_event(event);
|
let res = pad.push_event(event);
|
||||||
gst::trace!(CAT, obj: pad, "Pushed serialized event, result: {}", res);
|
gst::trace!(CAT, obj = pad, "Pushed serialized event, result: {}", res);
|
||||||
}
|
}
|
||||||
JitterBufferItem::Query(mut query, tx) => {
|
JitterBufferItem::Query(mut query, tx) => {
|
||||||
// This is safe because the thread holding the original reference is waiting
|
// This is safe because the thread holding the original reference is waiting
|
||||||
|
@ -381,13 +381,13 @@ impl RecvSession {
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
gst::debug!(CAT, obj: pad, "Task started");
|
gst::debug!(CAT, obj = pad, "Task started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop_rtp_task(&mut self, pad: &gst::Pad) -> Result<(), glib::BoolError> {
|
fn stop_rtp_task(&mut self, pad: &gst::Pad) -> Result<(), glib::BoolError> {
|
||||||
gst::debug!(CAT, obj: pad, "Stopping rtp recv src task");
|
gst::debug!(CAT, obj = pad, "Stopping rtp recv src task");
|
||||||
let recv_pad = self
|
let recv_pad = self
|
||||||
.rtp_recv_srcpads
|
.rtp_recv_srcpads
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
@ -561,7 +561,7 @@ impl RtpRecv {
|
||||||
} else {
|
} else {
|
||||||
session.stop_rtp_task(pad)?;
|
session.stop_rtp_task(pad)?;
|
||||||
|
|
||||||
gst::debug!(CAT, obj: pad, "Stopping task");
|
gst::debug!(CAT, obj = pad, "Stopping task");
|
||||||
|
|
||||||
let _ = pad.stop_task();
|
let _ = pad.stop_task();
|
||||||
}
|
}
|
||||||
|
@ -576,7 +576,7 @@ impl RtpRecv {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
pub fn src_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling query {query:?}");
|
gst::log!(CAT, obj = pad, "Handling query {query:?}");
|
||||||
|
|
||||||
use gst::QueryViewMut::*;
|
use gst::QueryViewMut::*;
|
||||||
match query.view_mut() {
|
match query.view_mut() {
|
||||||
|
@ -594,7 +594,11 @@ impl RtpRecv {
|
||||||
our_latency
|
our_latency
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::info!(CAT, obj: pad, "Handled latency query, our latency {our_latency}, minimum latency: {min}");
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
obj = pad,
|
||||||
|
"Handled latency query, our latency {our_latency}, minimum latency: {min}"
|
||||||
|
);
|
||||||
q.set(true, min, gst::ClockTime::NONE);
|
q.set(true, min, gst::ClockTime::NONE);
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -649,7 +653,7 @@ impl RtpRecv {
|
||||||
match segment.to_running_time(dts) {
|
match segment.to_running_time(dts) {
|
||||||
Some(time) => time,
|
Some(time) => time,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, obj: pad, "out of segment DTS are not supported");
|
gst::error!(CAT, obj = pad, "out of segment DTS are not supported");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,7 +661,7 @@ impl RtpRecv {
|
||||||
None => match self.obj().current_running_time() {
|
None => match self.obj().current_running_time() {
|
||||||
Some(time) => time,
|
Some(time) => time,
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, obj: pad, "Failed to get current time");
|
gst::error!(CAT, obj = pad, "Failed to get current time");
|
||||||
return Err(gst::FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -674,7 +678,7 @@ impl RtpRecv {
|
||||||
.ok()
|
.ok()
|
||||||
});
|
});
|
||||||
let mapped = buffer.map_readable().map_err(|e| {
|
let mapped = buffer.map_readable().map_err(|e| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map input buffer {e:?}");
|
gst::error!(CAT, imp = self, "Failed to map input buffer {e:?}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -690,12 +694,16 @@ impl RtpRecv {
|
||||||
return Ok(RecvRtpBuffer::IsRtcp(buffer));
|
return Ok(RecvRtpBuffer::IsRtcp(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::error!(CAT, imp: self, "Failed to parse input as valid rtp packet: {e:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse input as valid rtp packet: {e:?}"
|
||||||
|
);
|
||||||
return Ok(RecvRtpBuffer::Drop);
|
return Ok(RecvRtpBuffer::Drop);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::trace!(CAT, obj: pad, "using arrival time {}", arrival_time);
|
gst::trace!(CAT, obj = pad, "using arrival time {}", arrival_time);
|
||||||
|
|
||||||
let internal_session = session.internal_session.clone();
|
let internal_session = session.internal_session.clone();
|
||||||
let mut session_inner = internal_session.inner.lock().unwrap();
|
let mut session_inner = internal_session.inner.lock().unwrap();
|
||||||
|
@ -721,11 +729,11 @@ impl RtpRecv {
|
||||||
let pts = segment
|
let pts = segment
|
||||||
.position_from_running_time(gst::ClockTime::from_nseconds(pts))
|
.position_from_running_time(gst::ClockTime::from_nseconds(pts))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
gst::debug!(CAT, obj: pad, "Calculated PTS: {}", pts);
|
gst::debug!(CAT, obj = pad, "Calculated PTS: {}", pts);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let recv_ret = session_inner.session.handle_recv(&rtp, addr, now);
|
let recv_ret = session_inner.session.handle_recv(&rtp, addr, now);
|
||||||
gst::trace!(CAT, obj: pad, "session handle_recv ret: {recv_ret:?}");
|
gst::trace!(CAT, obj = pad, "session handle_recv ret: {recv_ret:?}");
|
||||||
match recv_ret {
|
match recv_ret {
|
||||||
RecvReply::SsrcCollision(ssrc) => return Ok(RecvRtpBuffer::SsrcCollision(ssrc)),
|
RecvReply::SsrcCollision(ssrc) => return Ok(RecvRtpBuffer::SsrcCollision(ssrc)),
|
||||||
RecvReply::NewSsrc(ssrc, _pt) => {
|
RecvReply::NewSsrc(ssrc, _pt) => {
|
||||||
|
@ -849,13 +857,17 @@ impl RtpRecv {
|
||||||
}
|
}
|
||||||
HeldRecvItem::Buffer(buffer) => {
|
HeldRecvItem::Buffer(buffer) => {
|
||||||
let mapped = buffer.buffer.map_readable().map_err(|e| {
|
let mapped = buffer.buffer.map_readable().map_err(|e| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map input buffer {e:?}");
|
gst::error!(CAT, imp = self, "Failed to map input buffer {e:?}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let rtp = match rtp_types::RtpPacket::parse(&mapped) {
|
let rtp = match rtp_types::RtpPacket::parse(&mapped) {
|
||||||
Ok(rtp) => rtp,
|
Ok(rtp) => rtp,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to parse input as valid rtp packet: {e:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse input as valid rtp packet: {e:?}"
|
||||||
|
);
|
||||||
return Ok(state);
|
return Ok(state);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -899,13 +911,17 @@ impl RtpRecv {
|
||||||
|
|
||||||
for buffer in list.list.iter_owned() {
|
for buffer in list.list.iter_owned() {
|
||||||
let mapped = buffer.map_readable().map_err(|e| {
|
let mapped = buffer.map_readable().map_err(|e| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map input buffer {e:?}");
|
gst::error!(CAT, imp = self, "Failed to map input buffer {e:?}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let rtp = match rtp_types::RtpPacket::parse(&mapped) {
|
let rtp = match rtp_types::RtpPacket::parse(&mapped) {
|
||||||
Ok(rtp) => rtp,
|
Ok(rtp) => rtp,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to parse input as valid rtp packet: {e:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse input as valid rtp packet: {e:?}"
|
||||||
|
);
|
||||||
return Ok(state);
|
return Ok(state);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1131,13 +1147,17 @@ impl RtpRecv {
|
||||||
.ok()
|
.ok()
|
||||||
});
|
});
|
||||||
let mapped = buffer.map_readable().map_err(|e| {
|
let mapped = buffer.map_readable().map_err(|e| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map input buffer {e:?}");
|
gst::error!(CAT, imp = self, "Failed to map input buffer {e:?}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let rtcp = match rtcp_types::Compound::parse(&mapped) {
|
let rtcp = match rtcp_types::Compound::parse(&mapped) {
|
||||||
Ok(rtcp) => rtcp,
|
Ok(rtcp) => rtcp,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to parse input as valid rtcp packet: {e:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse input as valid rtcp packet: {e:?}"
|
||||||
|
);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1187,7 +1207,11 @@ impl RtpRecv {
|
||||||
}
|
}
|
||||||
RtcpRecvReply::RequestKeyUnit { ssrcs, fir } => {
|
RtcpRecvReply::RequestKeyUnit { ssrcs, fir } => {
|
||||||
if let Some(ref rtp_send_sinkpad) = rtp_send_sinkpad {
|
if let Some(ref rtp_send_sinkpad) = rtp_send_sinkpad {
|
||||||
gst::debug!(CAT, imp: self, "Sending force-keyunit event for ssrcs {ssrcs:?} (all headers: {fir})");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Sending force-keyunit event for ssrcs {ssrcs:?} (all headers: {fir})"
|
||||||
|
);
|
||||||
// TODO what to do with the ssrc?
|
// TODO what to do with the ssrc?
|
||||||
let event = gst_video::UpstreamForceKeyUnitEvent::builder()
|
let event = gst_video::UpstreamForceKeyUnitEvent::builder()
|
||||||
.all_headers(fir)
|
.all_headers(fir)
|
||||||
|
@ -1196,7 +1220,11 @@ impl RtpRecv {
|
||||||
|
|
||||||
let _ = rtp_send_sinkpad.push_event(event);
|
let _ = rtp_send_sinkpad.push_event(event);
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Can't send force-keyunit event because of missing sinkpad");
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Can't send force-keyunit event because of missing sinkpad"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RtcpRecvReply::NewCName((cname, ssrc)) => {
|
RtcpRecvReply::NewCName((cname, ssrc)) => {
|
||||||
|
@ -1223,7 +1251,7 @@ impl RtpRecv {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rtp_sink_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef, id: usize) -> bool {
|
pub fn rtp_sink_query(&self, pad: &gst::Pad, query: &mut gst::QueryRef, id: usize) -> bool {
|
||||||
gst::log!(CAT, obj: pad, "Handling query {query:?}");
|
gst::log!(CAT, obj = pad, "Handling query {query:?}");
|
||||||
|
|
||||||
if query.is_serialized() {
|
if query.is_serialized() {
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
|
@ -1352,7 +1380,11 @@ impl RtpRecv {
|
||||||
session_inner.add_caps(caps);
|
session_inner.add_caps(caps);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, obj: pad, "input caps are missing payload or clock-rate fields");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
obj = pad,
|
||||||
|
"input caps are missing payload or clock-rate fields"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -1364,7 +1396,7 @@ impl RtpRecv {
|
||||||
let segment = match segment.downcast_ref::<gst::ClockTime>() {
|
let segment = match segment.downcast_ref::<gst::ClockTime>() {
|
||||||
Some(segment) => segment.clone(),
|
Some(segment) => segment.clone(),
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(CAT, obj: pad, "Only TIME segments are supported");
|
gst::warning!(CAT, obj = pad, "Only TIME segments are supported");
|
||||||
|
|
||||||
let segment = gst::FormattedSegment::new();
|
let segment = gst::FormattedSegment::new();
|
||||||
let seqnum = event.seqnum();
|
let seqnum = event.seqnum();
|
||||||
|
|
|
@ -227,7 +227,11 @@ impl SendSession {
|
||||||
RUNTIME.spawn_blocking(move || {
|
RUNTIME.spawn_blocking(move || {
|
||||||
let buffer = gst::Buffer::from_mut_slice(data);
|
let buffer = gst::Buffer::from_mut_slice(data);
|
||||||
if let Err(e) = rtcp_srcpad.push(buffer) {
|
if let Err(e) = rtcp_srcpad.push(buffer) {
|
||||||
gst::warning!(CAT, obj: rtcp_srcpad, "Failed to send rtcp data: flow return {e:?}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
obj = rtcp_srcpad,
|
||||||
|
"Failed to send rtcp data: flow return {e:?}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
drop(acquired);
|
drop(acquired);
|
||||||
});
|
});
|
||||||
|
@ -316,13 +320,17 @@ impl RtpSend {
|
||||||
now: Instant,
|
now: Instant,
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let mapped = buffer.map_readable().map_err(|e| {
|
let mapped = buffer.map_readable().map_err(|e| {
|
||||||
gst::error!(CAT, imp: self, "Failed to map input buffer {e:?}");
|
gst::error!(CAT, imp = self, "Failed to map input buffer {e:?}");
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let rtp = match rtp_types::RtpPacket::parse(&mapped) {
|
let rtp = match rtp_types::RtpPacket::parse(&mapped) {
|
||||||
Ok(rtp) => rtp,
|
Ok(rtp) => rtp,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
gst::error!(CAT, imp: self, "Failed to parse input as valid rtp packet: {e:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to parse input as valid rtp packet: {e:?}"
|
||||||
|
);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -422,7 +430,11 @@ impl RtpSend {
|
||||||
session.add_caps(caps.caps_owned());
|
session.add_caps(caps.caps_owned());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, obj: pad, "input caps are missing payload or clock-rate fields");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
obj = pad,
|
||||||
|
"input caps are missing payload or clock-rate fields"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
gst::Pad::event_default(pad, Some(&*self.obj()), event)
|
gst::Pad::event_default(pad, Some(&*self.obj()), event)
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
|
||||||
impl RtpVp8Depay {
|
impl RtpVp8Depay {
|
||||||
fn reset(&self, state: &mut State) {
|
fn reset(&self, state: &mut State) {
|
||||||
gst::debug!(CAT, imp: self, "resetting state");
|
gst::debug!(CAT, imp = self, "resetting state");
|
||||||
|
|
||||||
*state = State::default()
|
*state = State::default()
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp8Depay {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Handling RTP packet {packet:?}");
|
gst::trace!(CAT, imp = self, "Handling RTP packet {packet:?}");
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
|
|
||||||
let payload = packet.payload();
|
let payload = packet.payload();
|
||||||
|
@ -250,7 +250,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp8Depay {
|
||||||
let payload_descriptor = match r.parse::<PayloadDescriptor>() {
|
let payload_descriptor = match r.parse::<PayloadDescriptor>() {
|
||||||
Ok(payload_descriptor) => payload_descriptor,
|
Ok(payload_descriptor) => payload_descriptor,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Invalid VP8 RTP packet: {err}");
|
gst::warning!(CAT, imp = self, "Invalid VP8 RTP packet: {err}");
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
|
@ -258,8 +258,17 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp8Depay {
|
||||||
};
|
};
|
||||||
|
|
||||||
let payload_start_index = cursor.position() as usize;
|
let payload_start_index = cursor.position() as usize;
|
||||||
gst::trace!(CAT, imp: self, "VP8 RTP payload descriptor size: {}", payload_start_index);
|
gst::trace!(
|
||||||
gst::trace!(CAT, imp: self, "Received VP8 RTP payload descriptor: {payload_descriptor:?}");
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"VP8 RTP payload descriptor size: {}",
|
||||||
|
payload_start_index
|
||||||
|
);
|
||||||
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Received VP8 RTP payload descriptor: {payload_descriptor:?}"
|
||||||
|
);
|
||||||
|
|
||||||
// This is the start of a frame if it is the start of a partition and the partition index
|
// This is the start of a frame if it is the start of a partition and the partition index
|
||||||
// is 0.
|
// is 0.
|
||||||
|
@ -269,9 +278,9 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp8Depay {
|
||||||
// If this is not the start of a picture then we have to wait for one
|
// If this is not the start of a picture then we have to wait for one
|
||||||
if state.current_frame_payload_descriptor.is_none() && !is_start_of_frame {
|
if state.current_frame_payload_descriptor.is_none() && !is_start_of_frame {
|
||||||
if state.last_timestamp.is_some() {
|
if state.last_timestamp.is_some() {
|
||||||
gst::warning!(CAT, imp: self, "Waiting for start of picture");
|
gst::warning!(CAT, imp = self, "Waiting for start of picture");
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, imp: self, "Waiting for start of picture");
|
gst::trace!(CAT, imp = self, "Waiting for start of picture");
|
||||||
}
|
}
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
|
@ -285,7 +294,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp8Depay {
|
||||||
let frame_header = match r.parse::<UncompressedFrameHeader>() {
|
let frame_header = match r.parse::<UncompressedFrameHeader>() {
|
||||||
Ok(frame_header) => frame_header,
|
Ok(frame_header) => frame_header,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Failed to read frame header: {err}");
|
gst::warning!(CAT, imp = self, "Failed to read frame header: {err}");
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
|
@ -296,7 +305,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp8Depay {
|
||||||
// from upstream.
|
// from upstream.
|
||||||
if !frame_header.is_keyframe && state.last_keyframe_frame_header.is_none() {
|
if !frame_header.is_keyframe && state.last_keyframe_frame_header.is_none() {
|
||||||
if settings.request_keyframe {
|
if settings.request_keyframe {
|
||||||
gst::debug!(CAT, imp: self, "Requesting keyframe from upstream");
|
gst::debug!(CAT, imp = self, "Requesting keyframe from upstream");
|
||||||
let event = gst_video::UpstreamForceKeyUnitEvent::builder()
|
let event = gst_video::UpstreamForceKeyUnitEvent::builder()
|
||||||
.all_headers(true)
|
.all_headers(true)
|
||||||
.build();
|
.build();
|
||||||
|
@ -304,7 +313,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp8Depay {
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.wait_for_keyframe {
|
if settings.wait_for_keyframe {
|
||||||
gst::trace!(CAT, imp: self, "Waiting for keyframe");
|
gst::trace!(CAT, imp = self, "Waiting for keyframe");
|
||||||
// TODO: Could potentially drain here?
|
// TODO: Could potentially drain here?
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
|
@ -362,13 +371,13 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp8Depay {
|
||||||
|
|
||||||
if !state.pending_frame_is_keyframe {
|
if !state.pending_frame_is_keyframe {
|
||||||
buffer.set_flags(gst::BufferFlags::DELTA_UNIT);
|
buffer.set_flags(gst::BufferFlags::DELTA_UNIT);
|
||||||
gst::trace!(CAT, imp: self, "Finishing delta-frame");
|
gst::trace!(CAT, imp = self, "Finishing delta-frame");
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, imp: self, "Finishing keyframe");
|
gst::trace!(CAT, imp = self, "Finishing keyframe");
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.needs_discont {
|
if state.needs_discont {
|
||||||
gst::trace!(CAT, imp: self, "Setting DISCONT");
|
gst::trace!(CAT, imp = self, "Setting DISCONT");
|
||||||
buffer.set_flags(gst::BufferFlags::DISCONT);
|
buffer.set_flags(gst::BufferFlags::DISCONT);
|
||||||
state.needs_discont = false;
|
state.needs_discont = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,7 +242,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp8Pay {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_sink_caps(&self, caps: &gst::Caps) -> bool {
|
fn set_sink_caps(&self, caps: &gst::Caps) -> bool {
|
||||||
gst::debug!(CAT, imp: self, "received caps {caps:?}");
|
gst::debug!(CAT, imp = self, "received caps {caps:?}");
|
||||||
|
|
||||||
let caps_builder = gst::Caps::builder("application/x-rtp")
|
let caps_builder = gst::Caps::builder("application/x-rtp")
|
||||||
.field("media", "video")
|
.field("media", "video")
|
||||||
|
@ -280,7 +280,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp8Pay {
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
let max_payload_size = self.obj().max_payload_size();
|
let max_payload_size = self.obj().max_payload_size();
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "received buffer of size {}", buffer.size());
|
gst::trace!(CAT, imp = self, "received buffer of size {}", buffer.size());
|
||||||
|
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
|
@ -306,7 +306,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp8Pay {
|
||||||
if meta.as_ref().map(|meta| meta.layer_id.is_some()) == Some(true)
|
if meta.as_ref().map(|meta| meta.layer_id.is_some()) == Some(true)
|
||||||
&& state.temporal_layer_zero_index.is_none()
|
&& state.temporal_layer_zero_index.is_none()
|
||||||
{
|
{
|
||||||
gst::trace!(CAT, imp: self, "Detected stream with temporal scalability");
|
gst::trace!(CAT, imp = self, "Detected stream with temporal scalability");
|
||||||
state.temporal_layer_zero_index = Some(0);
|
state.temporal_layer_zero_index = Some(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,12 +314,12 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp8Pay {
|
||||||
let partition_offsets = if state.temporal_layer_zero_index.is_none() {
|
let partition_offsets = if state.temporal_layer_zero_index.is_none() {
|
||||||
match FrameInfo::parse(&map) {
|
match FrameInfo::parse(&map) {
|
||||||
Ok(frame_info) => {
|
Ok(frame_info) => {
|
||||||
gst::trace!(CAT, imp: self, "Parsed frame info {frame_info:?}");
|
gst::trace!(CAT, imp = self, "Parsed frame info {frame_info:?}");
|
||||||
|
|
||||||
Some(frame_info.partition_offsets)
|
Some(frame_info.partition_offsets)
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::error!(CAT, imp: self, "Failed parsing frame info: {err}");
|
gst::error!(CAT, imp = self, "Failed parsing frame info: {err}");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,14 +354,18 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp8Pay {
|
||||||
};
|
};
|
||||||
|
|
||||||
let payload_descriptor_size = payload_descriptor.size().map_err(|err| {
|
let payload_descriptor_size = payload_descriptor.size().map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to write payload descriptor: {err:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write payload descriptor: {err:?}"
|
||||||
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let overhead = payload_descriptor_size;
|
let overhead = payload_descriptor_size;
|
||||||
let payload_size = (max_payload_size as usize)
|
let payload_size = (max_payload_size as usize)
|
||||||
.checked_sub(overhead + 1)
|
.checked_sub(overhead + 1)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::error!(CAT, imp: self, "Too small MTU configured for stream");
|
gst::error!(CAT, imp = self, "Too small MTU configured for stream");
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::LibraryError::Settings,
|
gst::LibraryError::Settings,
|
||||||
|
@ -442,7 +446,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp8Pay {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Writing packet with payload descriptor {payload_descriptor:?} and payload size {payload_size} at offset {current_offset}",
|
"Writing packet with payload descriptor {payload_descriptor:?} and payload size {payload_size} at offset {current_offset}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -453,7 +457,11 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp8Pay {
|
||||||
let mut w = ByteWriter::endian(&mut payload_descriptor_buffer, BigEndian);
|
let mut w = ByteWriter::endian(&mut payload_descriptor_buffer, BigEndian);
|
||||||
w.build::<PayloadDescriptor>(&payload_descriptor)
|
w.build::<PayloadDescriptor>(&payload_descriptor)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to write payload descriptor: {err:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write payload descriptor: {err:?}"
|
||||||
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
assert_eq!(payload_descriptor_buffer.len(), payload_descriptor_size);
|
assert_eq!(payload_descriptor_buffer.len(), payload_descriptor_size);
|
||||||
|
@ -478,7 +486,11 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp8Pay {
|
||||||
if meta.map_or(true, |meta| matches!(meta.layer_id, Some((0, _)))) {
|
if meta.map_or(true, |meta| matches!(meta.layer_id, Some((0, _)))) {
|
||||||
if let Some(ref mut temporal_layer_zero_index) = state.temporal_layer_zero_index {
|
if let Some(ref mut temporal_layer_zero_index) = state.temporal_layer_zero_index {
|
||||||
*temporal_layer_zero_index = temporal_layer_zero_index.wrapping_add(1);
|
*temporal_layer_zero_index = temporal_layer_zero_index.wrapping_add(1);
|
||||||
gst::trace!(CAT, imp: self, "Updated temporal layer zero index to {temporal_layer_zero_index}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Updated temporal layer zero index to {temporal_layer_zero_index}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
|
||||||
impl RtpVp9Depay {
|
impl RtpVp9Depay {
|
||||||
fn reset(&self, state: &mut State) {
|
fn reset(&self, state: &mut State) {
|
||||||
gst::debug!(CAT, imp: self, "resetting state");
|
gst::debug!(CAT, imp = self, "resetting state");
|
||||||
|
|
||||||
*state = State::default()
|
*state = State::default()
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let settings = self.settings.lock().unwrap().clone();
|
let settings = self.settings.lock().unwrap().clone();
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Handling RTP packet {packet:?}");
|
gst::trace!(CAT, imp = self, "Handling RTP packet {packet:?}");
|
||||||
let mut state = self.state.borrow_mut();
|
let mut state = self.state.borrow_mut();
|
||||||
|
|
||||||
let payload = packet.payload();
|
let payload = packet.payload();
|
||||||
|
@ -270,7 +270,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
let payload_descriptor = match r.parse::<PayloadDescriptor>() {
|
let payload_descriptor = match r.parse::<PayloadDescriptor>() {
|
||||||
Ok(payload_descriptor) => payload_descriptor,
|
Ok(payload_descriptor) => payload_descriptor,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Invalid VP9 RTP packet: {err}");
|
gst::warning!(CAT, imp = self, "Invalid VP9 RTP packet: {err}");
|
||||||
// TODO: Could potentially drain here?
|
// TODO: Could potentially drain here?
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
|
@ -280,8 +280,17 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
|
|
||||||
let payload_start_index = cursor.position() as usize;
|
let payload_start_index = cursor.position() as usize;
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "VP9 RTP payload descriptor size: {}", payload_start_index);
|
gst::trace!(
|
||||||
gst::trace!(CAT, imp: self, "Received VP9 RTP payload descriptor: {payload_descriptor:?}");
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"VP9 RTP payload descriptor size: {}",
|
||||||
|
payload_start_index
|
||||||
|
);
|
||||||
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Received VP9 RTP payload descriptor: {payload_descriptor:?}"
|
||||||
|
);
|
||||||
|
|
||||||
// This is the start of a picture if this is the start of the frame and either there is no
|
// This is the start of a picture if this is the start of the frame and either there is no
|
||||||
// layer information or this is the first spatial layer.
|
// layer information or this is the first spatial layer.
|
||||||
|
@ -305,7 +314,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
{
|
{
|
||||||
// Missed the marker packet for the last picture
|
// Missed the marker packet for the last picture
|
||||||
if state.current_picture_payload_descriptor.is_some() {
|
if state.current_picture_payload_descriptor.is_some() {
|
||||||
gst::warning!(CAT, imp: self, "Packet is part of a new picture but didn't receive last packet of previous picture");
|
gst::warning!(CAT, imp = self, "Packet is part of a new picture but didn't receive last packet of previous picture");
|
||||||
// TODO: Could potentially drain here?
|
// TODO: Could potentially drain here?
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
}
|
}
|
||||||
|
@ -334,7 +343,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
{
|
{
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Scalability structure present and non-flexible scalability mode used but no picture ID present",
|
"Scalability structure present and non-flexible scalability mode used but no picture ID present",
|
||||||
);
|
);
|
||||||
// TODO: Could potentially drain here?
|
// TODO: Could potentially drain here?
|
||||||
|
@ -357,7 +366,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
&& last_keyframe_payloader_descriptor.flexible_mode
|
&& last_keyframe_payloader_descriptor.flexible_mode
|
||||||
!= payload_descriptor.flexible_mode
|
!= payload_descriptor.flexible_mode
|
||||||
{
|
{
|
||||||
gst::warning!(CAT, imp: self, "Flexible scalability mode can only change on key pictures");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Flexible scalability mode can only change on key pictures"
|
||||||
|
);
|
||||||
|
|
||||||
// TODO: Could potentially drain here?
|
// TODO: Could potentially drain here?
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
|
@ -376,7 +389,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.is_some_and(|layer_index| layer_index.temporal_layer_id != 0)
|
.is_some_and(|layer_index| layer_index.temporal_layer_id != 0)
|
||||||
{
|
{
|
||||||
gst::warning!(CAT, imp: self, "Temporal layer ID of non-inter-predicted frame must be 0");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Temporal layer ID of non-inter-predicted frame must be 0"
|
||||||
|
);
|
||||||
// TODO: Could potentially drain here?
|
// TODO: Could potentially drain here?
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
|
@ -388,7 +405,11 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
// > This MUST only be set to 1 if the I bit is also set to one; if the I bit is set to
|
// > This MUST only be set to 1 if the I bit is also set to one; if the I bit is set to
|
||||||
// > zero, then this MUST also be set to zero and ignored by receivers.
|
// > zero, then this MUST also be set to zero and ignored by receivers.
|
||||||
if payload_descriptor.flexible_mode && payload_descriptor.picture_id.is_none() {
|
if payload_descriptor.flexible_mode && payload_descriptor.picture_id.is_none() {
|
||||||
gst::warning!(CAT, imp: self, "Flexible scalability mode but no picture ID present");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Flexible scalability mode but no picture ID present"
|
||||||
|
);
|
||||||
// TODO: Could potentially drain here?
|
// TODO: Could potentially drain here?
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
|
@ -398,9 +419,9 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
// If this is not the start of a picture then we have to wait for one
|
// If this is not the start of a picture then we have to wait for one
|
||||||
if state.current_picture_payload_descriptor.is_none() && !is_start_of_picture {
|
if state.current_picture_payload_descriptor.is_none() && !is_start_of_picture {
|
||||||
if state.last_timestamp.is_some() {
|
if state.last_timestamp.is_some() {
|
||||||
gst::warning!(CAT, imp: self, "Waiting for start of picture");
|
gst::warning!(CAT, imp = self, "Waiting for start of picture");
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, imp: self, "Waiting for start of picture");
|
gst::trace!(CAT, imp = self, "Waiting for start of picture");
|
||||||
}
|
}
|
||||||
// TODO: Could potentially drain here?
|
// TODO: Could potentially drain here?
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
|
@ -415,7 +436,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
&& state.last_key_picture_payload_descriptor.is_none()
|
&& state.last_key_picture_payload_descriptor.is_none()
|
||||||
{
|
{
|
||||||
if settings.request_keyframe {
|
if settings.request_keyframe {
|
||||||
gst::debug!(CAT, imp: self, "Requesting keyframe from upstream");
|
gst::debug!(CAT, imp = self, "Requesting keyframe from upstream");
|
||||||
let event = gst_video::UpstreamForceKeyUnitEvent::builder()
|
let event = gst_video::UpstreamForceKeyUnitEvent::builder()
|
||||||
.all_headers(true)
|
.all_headers(true)
|
||||||
.build();
|
.build();
|
||||||
|
@ -423,7 +444,7 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
}
|
}
|
||||||
|
|
||||||
if settings.wait_for_keyframe {
|
if settings.wait_for_keyframe {
|
||||||
gst::trace!(CAT, imp: self, "Waiting for keyframe");
|
gst::trace!(CAT, imp = self, "Waiting for keyframe");
|
||||||
// TODO: Could potentially drain here?
|
// TODO: Could potentially drain here?
|
||||||
self.reset(&mut state);
|
self.reset(&mut state);
|
||||||
self.obj().drop_packet(packet);
|
self.obj().drop_packet(packet);
|
||||||
|
@ -463,12 +484,12 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
// We assume that the beginning of the frame header fits into the first packet
|
// We assume that the beginning of the frame header fits into the first packet
|
||||||
match r.parse::<FrameHeader>() {
|
match r.parse::<FrameHeader>() {
|
||||||
Ok(frame_header) => {
|
Ok(frame_header) => {
|
||||||
gst::trace!(CAT, imp: self, "Parsed frame header: {frame_header:?}");
|
gst::trace!(CAT, imp = self, "Parsed frame header: {frame_header:?}");
|
||||||
state.current_keyframe_frame_header = Some(frame_header);
|
state.current_keyframe_frame_header = Some(frame_header);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// Don't consider this a fatal error
|
// Don't consider this a fatal error
|
||||||
gst::warning!(CAT, imp: self, "Failed to read frame header: {err}");
|
gst::warning!(CAT, imp = self, "Failed to read frame header: {err}");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -529,13 +550,13 @@ impl crate::basedepay::RtpBaseDepay2Impl for RtpVp9Depay {
|
||||||
|
|
||||||
if current_picture_payload_descriptor.inter_picture_predicted_frame {
|
if current_picture_payload_descriptor.inter_picture_predicted_frame {
|
||||||
buffer.set_flags(gst::BufferFlags::DELTA_UNIT);
|
buffer.set_flags(gst::BufferFlags::DELTA_UNIT);
|
||||||
gst::trace!(CAT, imp: self, "Finishing delta-frame");
|
gst::trace!(CAT, imp = self, "Finishing delta-frame");
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, imp: self, "Finishing keyframe");
|
gst::trace!(CAT, imp = self, "Finishing keyframe");
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.needs_discont {
|
if state.needs_discont {
|
||||||
gst::trace!(CAT, imp: self, "Setting DISCONT");
|
gst::trace!(CAT, imp = self, "Setting DISCONT");
|
||||||
buffer.set_flags(gst::BufferFlags::DISCONT);
|
buffer.set_flags(gst::BufferFlags::DISCONT);
|
||||||
state.needs_discont = false;
|
state.needs_discont = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,7 +219,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp9Pay {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_sink_caps(&self, caps: &gst::Caps) -> bool {
|
fn set_sink_caps(&self, caps: &gst::Caps) -> bool {
|
||||||
gst::debug!(CAT, imp: self, "received caps {caps:?}");
|
gst::debug!(CAT, imp = self, "received caps {caps:?}");
|
||||||
|
|
||||||
let caps_builder = gst::Caps::builder("application/x-rtp")
|
let caps_builder = gst::Caps::builder("application/x-rtp")
|
||||||
.field("media", "video")
|
.field("media", "video")
|
||||||
|
@ -254,7 +254,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp9Pay {
|
||||||
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
let max_payload_size = self.obj().max_payload_size();
|
let max_payload_size = self.obj().max_payload_size();
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "received buffer of size {}", buffer.size());
|
gst::trace!(CAT, imp = self, "received buffer of size {}", buffer.size());
|
||||||
|
|
||||||
let map = buffer.map_readable().map_err(|_| {
|
let map = buffer.map_readable().map_err(|_| {
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
|
@ -284,13 +284,13 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp9Pay {
|
||||||
let mut r = BitReader::endian(map.as_slice(), BigEndian);
|
let mut r = BitReader::endian(map.as_slice(), BigEndian);
|
||||||
let key_frame = match r.parse::<FrameHeader>() {
|
let key_frame = match r.parse::<FrameHeader>() {
|
||||||
Ok(frame_header) => {
|
Ok(frame_header) => {
|
||||||
gst::trace!(CAT, imp: self, "Parsed frame header: {frame_header:?}");
|
gst::trace!(CAT, imp = self, "Parsed frame header: {frame_header:?}");
|
||||||
// show_existing_frame assumes that there is an existing frame to show so this is
|
// show_existing_frame assumes that there is an existing frame to show so this is
|
||||||
// clearly not a keyframe
|
// clearly not a keyframe
|
||||||
frame_header.is_keyframe.unwrap_or(false)
|
frame_header.is_keyframe.unwrap_or(false)
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::trace!(CAT, imp: self, "Failed parsing frame header: {err:?}");
|
gst::trace!(CAT, imp = self, "Failed parsing frame header: {err:?}");
|
||||||
!buffer.flags().contains(gst::BufferFlags::DELTA_UNIT)
|
!buffer.flags().contains(gst::BufferFlags::DELTA_UNIT)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -311,14 +311,18 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp9Pay {
|
||||||
};
|
};
|
||||||
|
|
||||||
let payload_descriptor_size = payload_descriptor.size().map_err(|err| {
|
let payload_descriptor_size = payload_descriptor.size().map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to write payload descriptor: {err:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write payload descriptor: {err:?}"
|
||||||
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
let overhead = payload_descriptor_size;
|
let overhead = payload_descriptor_size;
|
||||||
let payload_size = (max_payload_size as usize)
|
let payload_size = (max_payload_size as usize)
|
||||||
.checked_sub(overhead + 1)
|
.checked_sub(overhead + 1)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
gst::error!(CAT, imp: self, "Too small MTU configured for stream");
|
gst::error!(CAT, imp = self, "Too small MTU configured for stream");
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::LibraryError::Settings,
|
gst::LibraryError::Settings,
|
||||||
|
@ -333,7 +337,7 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp9Pay {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Writing packet with payload descriptor {payload_descriptor:?} and payload size {payload_size}",
|
"Writing packet with payload descriptor {payload_descriptor:?} and payload size {payload_size}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -342,7 +346,11 @@ impl crate::basepay::RtpBasePay2Impl for RtpVp9Pay {
|
||||||
let mut w = ByteWriter::endian(&mut payload_descriptor_buffer, BigEndian);
|
let mut w = ByteWriter::endian(&mut payload_descriptor_buffer, BigEndian);
|
||||||
w.build::<PayloadDescriptor>(&payload_descriptor)
|
w.build::<PayloadDescriptor>(&payload_descriptor)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to write payload descriptor: {err:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to write payload descriptor: {err:?}"
|
||||||
|
);
|
||||||
gst::FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
assert_eq!(payload_descriptor_buffer.len(), payload_descriptor_size);
|
assert_eq!(payload_descriptor_buffer.len(), payload_descriptor_size);
|
||||||
|
|
|
@ -354,7 +354,7 @@ impl ObjectImpl for RtspSrc {
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to set property `{}`: {:?}",
|
"Failed to set property `{}`: {:?}",
|
||||||
pspec.name(),
|
pspec.name(),
|
||||||
err
|
err
|
||||||
|
@ -537,17 +537,9 @@ impl RtspSrc {
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(CAT, imp = self, "Location: {url}",);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Location: {url}",
|
|
||||||
);
|
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(CAT, imp = self, "Starting RTSP connection thread.. ");
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Starting RTSP connection thread.. "
|
|
||||||
);
|
|
||||||
|
|
||||||
let task_src = self.ref_counted();
|
let task_src = self.ref_counted();
|
||||||
|
|
||||||
|
@ -635,7 +627,7 @@ impl RtspSrc {
|
||||||
debug_assert!(task_handle.is_none());
|
debug_assert!(task_handle.is_none());
|
||||||
task_handle.replace(join_handle);
|
task_handle.replace(join_handle);
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Started");
|
gst::info!(CAT, imp = self, "Started");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -664,7 +656,7 @@ impl RtspSrc {
|
||||||
|
|
||||||
self.command_queue.lock().unwrap().take();
|
self.command_queue.lock().unwrap().take();
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Stopped");
|
gst::info!(CAT, imp = self, "Stopped");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl Signaller {
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to parse SDP_OFFER: {payload}"
|
"Failed to parse SDP_OFFER: {payload}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ impl Signaller {
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to parse ICE_CANDIDATE: {payload}"
|
"Failed to parse ICE_CANDIDATE: {payload}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ impl Signaller {
|
||||||
_ => {
|
_ => {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Ignoring unsupported message type {}",
|
"Ignoring unsupported message type {}",
|
||||||
msg.message_type
|
msg.message_type
|
||||||
);
|
);
|
||||||
|
@ -160,7 +160,7 @@ impl Signaller {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to decode message payload from server: {e}"
|
"Failed to decode message payload from server: {e}"
|
||||||
);
|
);
|
||||||
self.obj().emit_by_name::<()>(
|
self.obj().emit_by_name::<()>(
|
||||||
|
@ -173,7 +173,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::log!(CAT, imp: self, "Unknown message from server: [{msg}]");
|
gst::log!(CAT, imp = self, "Unknown message from server: [{msg}]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ impl Signaller {
|
||||||
(Some(key), Some(secret_key)) => {
|
(Some(key), Some(secret_key)) => {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Using provided access and secret access key"
|
"Using provided access and secret access key"
|
||||||
);
|
);
|
||||||
Ok(Credentials::new(
|
Ok(Credentials::new(
|
||||||
|
@ -215,7 +215,7 @@ impl Signaller {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::debug!(CAT, imp: self, "Using default AWS credentials");
|
gst::debug!(CAT, imp = self, "Using default AWS credentials");
|
||||||
let cred = DefaultCredentialsChain::builder()
|
let cred = DefaultCredentialsChain::builder()
|
||||||
.region(region.clone())
|
.region(region.clone())
|
||||||
.build()
|
.build()
|
||||||
|
@ -387,7 +387,7 @@ impl Signaller {
|
||||||
))
|
))
|
||||||
.build()
|
.build()
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
gst::error!(CAT, imp: self, "Failed to build HTTP request URI: {err}");
|
gst::error!(CAT, imp = self, "Failed to build HTTP request URI: {err}");
|
||||||
anyhow!("Failed to build HTTP request URI: {err}")
|
anyhow!("Failed to build HTTP request URI: {err}")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ impl Signaller {
|
||||||
let (ws, _) =
|
let (ws, _) =
|
||||||
async_tungstenite::tokio::connect_async_with_tls_connector(url, connector).await?;
|
async_tungstenite::tokio::connect_async_with_tls_connector(url, connector).await?;
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "connected");
|
gst::info!(CAT, imp = self, "connected");
|
||||||
|
|
||||||
// Channel for asynchronously sending out websocket message
|
// Channel for asynchronously sending out websocket message
|
||||||
let (mut ws_sink, mut ws_stream) = ws.split();
|
let (mut ws_sink, mut ws_stream) = ws.split();
|
||||||
|
@ -439,7 +439,7 @@ impl Signaller {
|
||||||
if let Some(imp) = imp.upgrade() {
|
if let Some(imp) = imp.upgrade() {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Sending websocket message {}",
|
"Sending websocket message {}",
|
||||||
serde_json::to_string(&msg).unwrap()
|
serde_json::to_string(&msg).unwrap()
|
||||||
);
|
);
|
||||||
|
@ -458,7 +458,7 @@ impl Signaller {
|
||||||
|
|
||||||
if let Err(ref err) = res {
|
if let Err(ref err) = res {
|
||||||
if let Some(imp) = imp.upgrade() {
|
if let Some(imp) = imp.upgrade() {
|
||||||
gst::error!(CAT, imp: imp, "Quitting send loop: {err}");
|
gst::error!(CAT, imp = imp, "Quitting send loop: {err}");
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, "Quitting send loop: {err}");
|
gst::error!(CAT, "Quitting send loop: {err}");
|
||||||
}
|
}
|
||||||
|
@ -468,7 +468,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(imp) = imp.upgrade() {
|
if let Some(imp) = imp.upgrade() {
|
||||||
gst::debug!(CAT, imp: imp, "Done sending");
|
gst::debug!(CAT, imp = imp, "Done sending");
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, "Done sending");
|
gst::debug!(CAT, "Done sending");
|
||||||
}
|
}
|
||||||
|
@ -488,7 +488,7 @@ impl Signaller {
|
||||||
imp.handle_message(msg);
|
imp.handle_message(msg);
|
||||||
}
|
}
|
||||||
Ok(WsMessage::Close(reason)) => {
|
Ok(WsMessage::Close(reason)) => {
|
||||||
gst::info!(CAT, imp: imp, "websocket connection closed: {:?}", reason);
|
gst::info!(CAT, imp = imp, "websocket connection closed: {:?}", reason);
|
||||||
imp.obj().emit_by_name::<()>("shutdown", &[]);
|
imp.obj().emit_by_name::<()>("shutdown", &[]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -507,7 +507,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(imp) = imp.upgrade() {
|
if let Some(imp) = imp.upgrade() {
|
||||||
gst::info!(CAT, imp: imp, "Stopped websocket receiving");
|
gst::info!(CAT, imp = imp, "Stopped websocket receiving");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -603,7 +603,7 @@ impl SignallableImpl for Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) {
|
fn stop(&self) {
|
||||||
gst::info!(CAT, imp: self, "Stopping now");
|
gst::info!(CAT, imp = self, "Stopping now");
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
let send_task_handle = state.send_task_handle.take();
|
let send_task_handle = state.send_task_handle.take();
|
||||||
|
@ -616,7 +616,7 @@ impl SignallableImpl for Signaller {
|
||||||
if let Some(handle) = send_task_handle {
|
if let Some(handle) = send_task_handle {
|
||||||
if let Err(err) = handle.await {
|
if let Err(err) = handle.await {
|
||||||
if let Some(imp) = imp.upgrade() {
|
if let Some(imp) = imp.upgrade() {
|
||||||
gst::warning!(CAT, imp: imp, "Error while joining send task: {err}");
|
gst::warning!(CAT, imp = imp, "Error while joining send task: {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -624,7 +624,11 @@ impl SignallableImpl for Signaller {
|
||||||
if let Some(handle) = receive_task_handle {
|
if let Some(handle) = receive_task_handle {
|
||||||
if let Err(err) = handle.await {
|
if let Err(err) = handle.await {
|
||||||
if let Some(imp) = imp.upgrade() {
|
if let Some(imp) = imp.upgrade() {
|
||||||
gst::warning!(CAT, imp: imp, "Error while joining receive task: {err}");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = imp,
|
||||||
|
"Error while joining receive task: {err}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -633,7 +637,7 @@ impl SignallableImpl for Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_session(&self, session_id: &str) {
|
fn end_session(&self, session_id: &str) {
|
||||||
gst::info!(CAT, imp: self, "Signalling session {session_id} ended");
|
gst::info!(CAT, imp = self, "Signalling session {session_id} ended");
|
||||||
|
|
||||||
// We can seemingly not do anything beyond that
|
// We can seemingly not do anything beyond that
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,12 +373,12 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(ref err) = res {
|
if let Err(ref err) = res {
|
||||||
gst::error!(CAT, imp: this, "Quitting send task: {err}");
|
gst::error!(CAT, imp = this, "Quitting send task: {err}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: this, "Done sending");
|
gst::debug!(CAT, imp = this, "Done sending");
|
||||||
|
|
||||||
let _ = ws_sink.close().await;
|
let _ = ws_sink.close().await;
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg = "Stopped websocket receiving";
|
let msg = "Stopped websocket receiving";
|
||||||
gst::info!(CAT, imp: this, "{msg}");
|
gst::info!(CAT, imp = this, "{msg}");
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -415,15 +415,15 @@ impl Signaller {
|
||||||
) -> ControlFlow<()> {
|
) -> ControlFlow<()> {
|
||||||
match msg {
|
match msg {
|
||||||
Ok(WsMessage::Text(msg)) => {
|
Ok(WsMessage::Text(msg)) => {
|
||||||
gst::trace!(CAT, imp: self, "Received message {}", msg);
|
gst::trace!(CAT, imp = self, "Received message {}", msg);
|
||||||
if let Ok(reply) = serde_json::from_str::<JsonReply>(&msg) {
|
if let Ok(reply) = serde_json::from_str::<JsonReply>(&msg) {
|
||||||
self.handle_reply(reply);
|
self.handle_reply(reply);
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Unknown message from server: {}", msg);
|
gst::error!(CAT, imp = self, "Unknown message from server: {}", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(WsMessage::Close(reason)) => {
|
Ok(WsMessage::Close(reason)) => {
|
||||||
gst::info!(CAT, imp: self, "websocket connection closed: {:?}", reason);
|
gst::info!(CAT, imp = self, "websocket connection closed: {:?}", reason);
|
||||||
return ControlFlow::Break(());
|
return ControlFlow::Break(());
|
||||||
}
|
}
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
@ -438,16 +438,26 @@ impl Signaller {
|
||||||
fn handle_reply(&self, reply: JsonReply) {
|
fn handle_reply(&self, reply: JsonReply) {
|
||||||
match reply {
|
match reply {
|
||||||
JsonReply::WebRTCUp => {
|
JsonReply::WebRTCUp => {
|
||||||
gst::trace!(CAT, imp: self, "WebRTC streaming is working!");
|
gst::trace!(CAT, imp = self, "WebRTC streaming is working!");
|
||||||
}
|
}
|
||||||
JsonReply::Success(success) => {
|
JsonReply::Success(success) => {
|
||||||
if let Some(data) = success.data {
|
if let Some(data) = success.data {
|
||||||
if success.session_id.is_none() {
|
if success.session_id.is_none() {
|
||||||
gst::trace!(CAT, imp: self, "Janus session {} was created successfully", data.id);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Janus session {} was created successfully",
|
||||||
|
data.id
|
||||||
|
);
|
||||||
self.set_session_id(data.id);
|
self.set_session_id(data.id);
|
||||||
self.attach_plugin();
|
self.attach_plugin();
|
||||||
} else {
|
} else {
|
||||||
gst::trace!(CAT, imp: self, "Attached to Janus Video Room plugin successfully, handle: {}", data.id);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Attached to Janus Video Room plugin successfully, handle: {}",
|
||||||
|
data.id
|
||||||
|
);
|
||||||
self.set_handle_id(data.id);
|
self.set_handle_id(data.id);
|
||||||
self.join_room();
|
self.join_room();
|
||||||
}
|
}
|
||||||
|
@ -475,7 +485,12 @@ impl Signaller {
|
||||||
self.obj().notify("feed-id");
|
self.obj().notify("feed-id");
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::trace!(CAT, imp: self, "Joined room {:?} successfully", joined.room);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Joined room {:?} successfully",
|
||||||
|
joined.room
|
||||||
|
);
|
||||||
self.session_requested();
|
self.session_requested();
|
||||||
}
|
}
|
||||||
VideoRoomData::Event(room_event) => {
|
VideoRoomData::Event(room_event) => {
|
||||||
|
@ -490,13 +505,18 @@ impl Signaller {
|
||||||
|
|
||||||
if let Some(jsep) = event.jsep {
|
if let Some(jsep) = event.jsep {
|
||||||
if jsep.r#type == "answer" {
|
if jsep.r#type == "answer" {
|
||||||
gst::trace!(CAT, imp: self, "Session requested successfully");
|
gst::trace!(CAT, imp = self, "Session requested successfully");
|
||||||
self.handle_answer(jsep.sdp);
|
self.handle_answer(jsep.sdp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VideoRoomData::Destroyed(room_destroyed) => {
|
VideoRoomData::Destroyed(room_destroyed) => {
|
||||||
gst::trace!(CAT, imp: self, "Room {} has been destroyed", room_destroyed.room);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Room {} has been destroyed",
|
||||||
|
room_destroyed.room
|
||||||
|
);
|
||||||
|
|
||||||
self.raise_error(format!(
|
self.raise_error(format!(
|
||||||
"room {} has been destroyed",
|
"room {} has been destroyed",
|
||||||
|
@ -782,7 +802,12 @@ impl SignallableImpl for Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_sdp(&self, _session_id: &str, offer: &gst_webrtc::WebRTCSessionDescription) {
|
fn send_sdp(&self, _session_id: &str, offer: &gst_webrtc::WebRTCSessionDescription) {
|
||||||
gst::info!(CAT, imp: self, "sending SDP offer to peer: {:?}", offer.sdp().as_text());
|
gst::info!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"sending SDP offer to peer: {:?}",
|
||||||
|
offer.sdp().as_text()
|
||||||
|
);
|
||||||
|
|
||||||
self.publish(offer);
|
self.publish(offer);
|
||||||
}
|
}
|
||||||
|
@ -798,7 +823,7 @@ impl SignallableImpl for Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) {
|
fn stop(&self) {
|
||||||
gst::info!(CAT, imp: self, "Stopping now");
|
gst::info!(CAT, imp = self, "Stopping now");
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
let send_task_handle = state.send_task_handle.take();
|
let send_task_handle = state.send_task_handle.take();
|
||||||
|
@ -810,7 +835,7 @@ impl SignallableImpl for Signaller {
|
||||||
|
|
||||||
if let Some(handle) = send_task_handle {
|
if let Some(handle) = send_task_handle {
|
||||||
if let Err(err) = handle.await {
|
if let Err(err) = handle.await {
|
||||||
gst::warning!(CAT, imp: self, "Error while joining send task: {}", err);
|
gst::warning!(CAT, imp = self, "Error while joining send task: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ impl Signaller {
|
||||||
while let Some(candidate_str) = early_candidates.pop() {
|
while let Some(candidate_str) = early_candidates.pop() {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Sending delayed ice candidate {candidate_str:?}"
|
"Sending delayed ice candidate {candidate_str:?}"
|
||||||
);
|
);
|
||||||
self.send_trickle_request(&candidate_str).await;
|
self.send_trickle_request(&candidate_str).await;
|
||||||
|
@ -201,7 +201,7 @@ impl Signaller {
|
||||||
self.on_signal_event(*signal).await;
|
self.on_signal_event(*signal).await;
|
||||||
}
|
}
|
||||||
signal_client::SignalEvent::Close(reason) => {
|
signal_client::SignalEvent::Close(reason) => {
|
||||||
gst::debug!(CAT, imp: self, "Close: {reason}");
|
gst::debug!(CAT, imp = self, "Close: {reason}");
|
||||||
self.raise_error("Server disconnected".to_string());
|
self.raise_error("Server disconnected".to_string());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ impl Signaller {
|
||||||
Ok(None) => {}
|
Ok(None) => {}
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
WaitError::FutureAborted => {
|
WaitError::FutureAborted => {
|
||||||
gst::debug!(CAT, imp: self, "Closing signal_task");
|
gst::debug!(CAT, imp = self, "Closing signal_task");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
WaitError::FutureError(err) => self.raise_error(err.to_string()),
|
WaitError::FutureError(err) => self.raise_error(err.to_string()),
|
||||||
|
@ -221,7 +221,7 @@ impl Signaller {
|
||||||
async fn on_signal_event(&self, event: proto::signal_response::Message) {
|
async fn on_signal_event(&self, event: proto::signal_response::Message) {
|
||||||
match event {
|
match event {
|
||||||
proto::signal_response::Message::Answer(answer) => {
|
proto::signal_response::Message::Answer(answer) => {
|
||||||
gst::debug!(CAT, imp: self, "Received publisher answer: {:?}", answer);
|
gst::debug!(CAT, imp = self, "Received publisher answer: {:?}", answer);
|
||||||
let sdp = match gst_sdp::SDPMessage::parse_buffer(answer.sdp.as_bytes()) {
|
let sdp = match gst_sdp::SDPMessage::parse_buffer(answer.sdp.as_bytes()) {
|
||||||
Ok(sdp) => sdp,
|
Ok(sdp) => sdp,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -239,10 +239,15 @@ impl Signaller {
|
||||||
|
|
||||||
proto::signal_response::Message::Offer(offer) => {
|
proto::signal_response::Message::Offer(offer) => {
|
||||||
if !self.is_subscriber() {
|
if !self.is_subscriber() {
|
||||||
gst::warning!(CAT, imp: self, "Ignoring subscriber offer in non-subscriber mode: {:?}", offer);
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Ignoring subscriber offer in non-subscriber mode: {:?}",
|
||||||
|
offer
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gst::debug!(CAT, imp: self, "Received subscriber offer: {:?}", offer);
|
gst::debug!(CAT, imp = self, "Received subscriber offer: {:?}", offer);
|
||||||
let sdp = match gst_sdp::SDPMessage::parse_buffer(offer.sdp.as_bytes()) {
|
let sdp = match gst_sdp::SDPMessage::parse_buffer(offer.sdp.as_bytes()) {
|
||||||
Ok(sdp) => sdp,
|
Ok(sdp) => sdp,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -259,7 +264,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
proto::signal_response::Message::Trickle(trickle) => {
|
proto::signal_response::Message::Trickle(trickle) => {
|
||||||
gst::debug!(CAT, imp: self, "Received ice_candidate {:?}", trickle);
|
gst::debug!(CAT, imp = self, "Received ice_candidate {:?}", trickle);
|
||||||
|
|
||||||
let Some(target) = self.signal_target() else {
|
let Some(target) = self.signal_target() else {
|
||||||
return;
|
return;
|
||||||
|
@ -279,11 +284,11 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
proto::signal_response::Message::ConnectionQuality(quality) => {
|
proto::signal_response::Message::ConnectionQuality(quality) => {
|
||||||
gst::debug!(CAT, imp: self, "Connection quality: {:?}", quality);
|
gst::debug!(CAT, imp = self, "Connection quality: {:?}", quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
proto::signal_response::Message::TrackPublished(publish_res) => {
|
proto::signal_response::Message::TrackPublished(publish_res) => {
|
||||||
gst::debug!(CAT, imp: self, "Track published: {:?}", publish_res);
|
gst::debug!(CAT, imp = self, "Track published: {:?}", publish_res);
|
||||||
if let Some(connection) = &mut *self.connection.lock().unwrap() {
|
if let Some(connection) = &mut *self.connection.lock().unwrap() {
|
||||||
if let Some(tx) = connection.pending_tracks.remove(&publish_res.cid) {
|
if let Some(tx) = connection.pending_tracks.remove(&publish_res.cid) {
|
||||||
let _ = tx.send(publish_res.track.unwrap());
|
let _ = tx.send(publish_res.track.unwrap());
|
||||||
|
@ -293,17 +298,22 @@ impl Signaller {
|
||||||
|
|
||||||
proto::signal_response::Message::Update(update) => {
|
proto::signal_response::Message::Update(update) => {
|
||||||
if !self.is_subscriber() {
|
if !self.is_subscriber() {
|
||||||
gst::trace!(CAT, imp: self, "Ignoring update in non-subscriber mode: {:?}", update);
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Ignoring update in non-subscriber mode: {:?}",
|
||||||
|
update
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gst::debug!(CAT, imp: self, "Update: {:?}", update);
|
gst::debug!(CAT, imp = self, "Update: {:?}", update);
|
||||||
for participant in update.participants {
|
for participant in update.participants {
|
||||||
self.on_participant(&participant, true)
|
self.on_participant(&participant, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proto::signal_response::Message::Leave(leave) => {
|
proto::signal_response::Message::Leave(leave) => {
|
||||||
gst::debug!(CAT, imp: self, "Leave: {:?}", leave);
|
gst::debug!(CAT, imp = self, "Leave: {:?}", leave);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -317,7 +327,7 @@ impl Signaller {
|
||||||
RUNTIME.spawn(async move {
|
RUNTIME.spawn(async move {
|
||||||
if let Some(imp) = weak_imp.upgrade() {
|
if let Some(imp) = weak_imp.upgrade() {
|
||||||
let sdp = sessdesc.sdp();
|
let sdp = sessdesc.sdp();
|
||||||
gst::debug!(CAT, imp: imp, "Sending SDP {:?} now", &sdp);
|
gst::debug!(CAT, imp = imp, "Sending SDP {:?} now", &sdp);
|
||||||
let signal_client = imp.require_signal_client();
|
let signal_client = imp.require_signal_client();
|
||||||
signal_client
|
signal_client
|
||||||
.send(proto::signal_request::Message::Answer(
|
.send(proto::signal_request::Message::Answer(
|
||||||
|
@ -429,7 +439,7 @@ impl Signaller {
|
||||||
|
|
||||||
match err {
|
match err {
|
||||||
WaitError::FutureAborted => {
|
WaitError::FutureAborted => {
|
||||||
gst::warning!(CAT, imp: imp, "Future aborted")
|
gst::warning!(CAT, imp = imp, "Future aborted")
|
||||||
}
|
}
|
||||||
WaitError::FutureError(err) => imp.raise_error(err.to_string()),
|
WaitError::FutureError(err) => imp.raise_error(err.to_string()),
|
||||||
};
|
};
|
||||||
|
@ -437,7 +447,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: imp, "Sending SDP now");
|
gst::debug!(CAT, imp = imp, "Sending SDP now");
|
||||||
signal_client
|
signal_client
|
||||||
.send(proto::signal_request::Message::Offer(
|
.send(proto::signal_request::Message::Offer(
|
||||||
proto::SessionDescription {
|
proto::SessionDescription {
|
||||||
|
@ -455,7 +465,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_participant(&self, participant: &proto::ParticipantInfo, new_connection: bool) {
|
fn on_participant(&self, participant: &proto::ParticipantInfo, new_connection: bool) {
|
||||||
gst::debug!(CAT, imp: self, "{:?}", participant);
|
gst::debug!(CAT, imp = self, "{:?}", participant);
|
||||||
if !participant.is_publisher {
|
if !participant.is_publisher {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -463,17 +473,17 @@ impl Signaller {
|
||||||
let peer_identity = &participant.identity;
|
let peer_identity = &participant.identity;
|
||||||
match self.producer_peer_id() {
|
match self.producer_peer_id() {
|
||||||
Some(id) if id == *peer_sid => {
|
Some(id) if id == *peer_sid => {
|
||||||
gst::debug!(CAT, imp: self, "matching peer sid {id:?}");
|
gst::debug!(CAT, imp = self, "matching peer sid {id:?}");
|
||||||
}
|
}
|
||||||
Some(id) if id == *peer_identity => {
|
Some(id) if id == *peer_identity => {
|
||||||
gst::debug!(CAT, imp: self, "matching peer identity {id:?}");
|
gst::debug!(CAT, imp = self, "matching peer identity {id:?}");
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if self.is_peer_excluded(peer_sid) || self.is_peer_excluded(peer_identity) {
|
if self.is_peer_excluded(peer_sid) || self.is_peer_excluded(peer_identity) {
|
||||||
gst::debug!(CAT, imp: self, "ignoring excluded peer {participant:?}");
|
gst::debug!(CAT, imp = self, "ignoring excluded peer {participant:?}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gst::debug!(CAT, imp: self, "catch-all mode, matching {participant:?}");
|
gst::debug!(CAT, imp = self, "catch-all mode, matching {participant:?}");
|
||||||
}
|
}
|
||||||
_ => return,
|
_ => return,
|
||||||
}
|
}
|
||||||
|
@ -531,7 +541,7 @@ impl Signaller {
|
||||||
|
|
||||||
impl SignallableImpl for Signaller {
|
impl SignallableImpl for Signaller {
|
||||||
fn start(&self) {
|
fn start(&self) {
|
||||||
gst::debug!(CAT, imp: self, "Connecting");
|
gst::debug!(CAT, imp = self, "Connecting");
|
||||||
|
|
||||||
let wsurl = if let Some(wsurl) = &self.settings.lock().unwrap().wsurl {
|
let wsurl = if let Some(wsurl) = &self.settings.lock().unwrap().wsurl {
|
||||||
wsurl.clone()
|
wsurl.clone()
|
||||||
|
@ -585,7 +595,7 @@ impl SignallableImpl for Signaller {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "We have an authentication token");
|
gst::debug!(CAT, imp = self, "We have an authentication token");
|
||||||
|
|
||||||
let weak_imp = self.downgrade();
|
let weak_imp = self.downgrade();
|
||||||
RUNTIME.spawn(async move {
|
RUNTIME.spawn(async move {
|
||||||
|
@ -597,7 +607,7 @@ impl SignallableImpl for Signaller {
|
||||||
auto_subscribe: imp.auto_subscribe(),
|
auto_subscribe: imp.auto_subscribe(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
gst::debug!(CAT, imp: imp, "Connecting to {}", wsurl);
|
gst::debug!(CAT, imp = imp, "Connecting to {}", wsurl);
|
||||||
|
|
||||||
let res = signal_client::SignalClient::connect(&wsurl, &auth_token, options).await;
|
let res = signal_client::SignalClient::connect(&wsurl, &auth_token, options).await;
|
||||||
let (signal_client, join_response, signal_events) = match res {
|
let (signal_client, join_response, signal_events) = match res {
|
||||||
|
@ -612,7 +622,7 @@ impl SignallableImpl for Signaller {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: imp,
|
imp = imp,
|
||||||
"Connected with JoinResponse: {:?}",
|
"Connected with JoinResponse: {:?}",
|
||||||
join_response
|
join_response
|
||||||
);
|
);
|
||||||
|
@ -700,7 +710,7 @@ impl SignallableImpl for Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_sdp(&self, session_id: &str, sessdesc: &gst_webrtc::WebRTCSessionDescription) {
|
fn send_sdp(&self, session_id: &str, sessdesc: &gst_webrtc::WebRTCSessionDescription) {
|
||||||
gst::debug!(CAT, imp: self, "Created SDP {:?}", sessdesc.sdp());
|
gst::debug!(CAT, imp = self, "Created SDP {:?}", sessdesc.sdp());
|
||||||
|
|
||||||
match sessdesc.type_() {
|
match sessdesc.type_() {
|
||||||
gst_webrtc::WebRTCSDPType::Offer => {
|
gst_webrtc::WebRTCSDPType::Offer => {
|
||||||
|
@ -710,7 +720,7 @@ impl SignallableImpl for Signaller {
|
||||||
self.send_sdp_answer(session_id, sessdesc);
|
self.send_sdp_answer(session_id, sessdesc);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::debug!(CAT, imp: self, "Ignoring SDP {:?}", sessdesc.sdp());
|
gst::debug!(CAT, imp = self, "Ignoring SDP {:?}", sessdesc.sdp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -731,14 +741,14 @@ impl SignallableImpl for Signaller {
|
||||||
|
|
||||||
if let Some(connection) = &mut *self.connection.lock().unwrap() {
|
if let Some(connection) = &mut *self.connection.lock().unwrap() {
|
||||||
if let Some(early_candidates) = connection.early_candidates.as_mut() {
|
if let Some(early_candidates) = connection.early_candidates.as_mut() {
|
||||||
gst::debug!(CAT, imp: self, "Delaying ice candidate {candidate_str:?}");
|
gst::debug!(CAT, imp = self, "Delaying ice candidate {candidate_str:?}");
|
||||||
|
|
||||||
early_candidates.push(candidate_str);
|
early_candidates.push(candidate_str);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Sending ice candidate {candidate_str:?}");
|
gst::debug!(CAT, imp = self, "Sending ice candidate {candidate_str:?}");
|
||||||
|
|
||||||
let imp = self.downgrade();
|
let imp = self.downgrade();
|
||||||
RUNTIME.spawn(async move {
|
RUNTIME.spawn(async move {
|
||||||
|
|
|
@ -136,7 +136,7 @@ impl Signaller {
|
||||||
|
|
||||||
if insecure_tls {
|
if insecure_tls {
|
||||||
connector_builder.danger_accept_invalid_certs(true);
|
connector_builder.danger_accept_invalid_certs(true);
|
||||||
gst::warning!(CAT, imp: self, "insecure tls connections are allowed");
|
gst::warning!(CAT, imp = self, "insecure tls connections are allowed");
|
||||||
}
|
}
|
||||||
|
|
||||||
let connector = Some(tokio_native_tls::TlsConnector::from(
|
let connector = Some(tokio_native_tls::TlsConnector::from(
|
||||||
|
@ -146,7 +146,7 @@ impl Signaller {
|
||||||
let mut uri = self.uri();
|
let mut uri = self.uri();
|
||||||
uri.set_query(None);
|
uri.set_query(None);
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "connecting to {}", uri.to_string());
|
gst::info!(CAT, imp = self, "connecting to {}", uri.to_string());
|
||||||
|
|
||||||
let mut req = uri.into_client_request()?;
|
let mut req = uri.into_client_request()?;
|
||||||
let req_headers = req.headers_mut();
|
let req_headers = req.headers_mut();
|
||||||
|
@ -166,7 +166,7 @@ impl Signaller {
|
||||||
)
|
)
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "connected");
|
gst::info!(CAT, imp = self, "connected");
|
||||||
|
|
||||||
// Channel for asynchronously sending out websocket message
|
// Channel for asynchronously sending out websocket message
|
||||||
let (mut ws_sink, mut ws_stream) = ws.split();
|
let (mut ws_sink, mut ws_stream) = ws.split();
|
||||||
|
@ -186,12 +186,12 @@ impl Signaller {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Err(ref err) = res {
|
if let Err(ref err) = res {
|
||||||
gst::error!(CAT, imp: this, "Quitting send loop: {err}");
|
gst::error!(CAT, imp = this, "Quitting send loop: {err}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: this, "Done sending");
|
gst::debug!(CAT, imp = this, "Done sending");
|
||||||
|
|
||||||
let _ = ws_sink.close().await;
|
let _ = ws_sink.close().await;
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
let msg = "Stopped websocket receiving";
|
let msg = "Stopped websocket receiving";
|
||||||
gst::info!(CAT, imp: this, "{msg}");
|
gst::info!(CAT, imp = this, "{msg}");
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -274,12 +274,12 @@ impl Signaller {
|
||||||
|
|
||||||
for (key, value) in structure.iter() {
|
for (key, value) in structure.iter() {
|
||||||
if let Ok(Ok(value_str)) = value.transform::<String>().map(|v| v.get()) {
|
if let Ok(Ok(value_str)) = value.transform::<String>().map(|v| v.get()) {
|
||||||
gst::log!(CAT, imp: self, "headers '{}' -> '{}'", key, value_str);
|
gst::log!(CAT, imp = self, "headers '{}' -> '{}'", key, value_str);
|
||||||
hash.insert(key.to_string(), value_str);
|
hash.insert(key.to_string(), value_str);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to convert headers '{}' to string ('{:?}')",
|
"Failed to convert headers '{}' to string ('{:?}')",
|
||||||
key,
|
key,
|
||||||
value
|
value
|
||||||
|
@ -318,7 +318,7 @@ impl Signaller {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Started session with producer peer id {target_producer}",
|
"Started session with producer peer id {target_producer}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -331,7 +331,7 @@ impl Signaller {
|
||||||
) -> ControlFlow<()> {
|
) -> ControlFlow<()> {
|
||||||
match msg {
|
match msg {
|
||||||
Ok(WsMessage::Text(msg)) => {
|
Ok(WsMessage::Text(msg)) => {
|
||||||
gst::trace!(CAT, imp: self, "Received message {}", msg);
|
gst::trace!(CAT, imp = self, "Received message {}", msg);
|
||||||
|
|
||||||
if let Ok(msg) = serde_json::from_str::<p::OutgoingMessage>(&msg) {
|
if let Ok(msg) = serde_json::from_str::<p::OutgoingMessage>(&msg) {
|
||||||
match msg {
|
match msg {
|
||||||
|
@ -347,7 +347,7 @@ impl Signaller {
|
||||||
let meta = meta.and_then(|m| match m {
|
let meta = meta.and_then(|m| match m {
|
||||||
serde_json::Value::Object(v) => Some(serialize_json_object(&v)),
|
serde_json::Value::Object(v) => Some(serialize_json_object(&v)),
|
||||||
_ => {
|
_ => {
|
||||||
gst::error!(CAT, imp: self, "Invalid json value: {m:?}");
|
gst::error!(CAT, imp = self, "Invalid json value: {m:?}");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -398,7 +398,7 @@ impl Signaller {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
p::OutgoingMessage::EndSession(p::EndSessionMessage { session_id }) => {
|
p::OutgoingMessage::EndSession(p::EndSessionMessage { session_id }) => {
|
||||||
gst::info!(CAT, imp: self, "Session {session_id} ended");
|
gst::info!(CAT, imp = self, "Session {session_id} ended");
|
||||||
|
|
||||||
self.obj()
|
self.obj()
|
||||||
.emit_by_name::<bool>("session-ended", &[&session_id]);
|
.emit_by_name::<bool>("session-ended", &[&session_id]);
|
||||||
|
@ -454,9 +454,15 @@ impl Signaller {
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
let meta = producer.meta.and_then(|m| match m {
|
let meta = producer.meta.and_then(|m| match m {
|
||||||
serde_json::Value::Object(v) => Some(serialize_json_object(&v)),
|
serde_json::Value::Object(v) => {
|
||||||
|
Some(serialize_json_object(&v))
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::error!(CAT, imp: self, "Invalid json value: {m:?}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Invalid json value: {m:?}"
|
||||||
|
);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -476,7 +482,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, imp: self, "Unknown message from server: {}", msg);
|
gst::error!(CAT, imp = self, "Unknown message from server: {}", msg);
|
||||||
|
|
||||||
self.obj().emit_by_name::<()>(
|
self.obj().emit_by_name::<()>(
|
||||||
"error",
|
"error",
|
||||||
|
@ -485,7 +491,7 @@ impl Signaller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(WsMessage::Close(reason)) => {
|
Ok(WsMessage::Close(reason)) => {
|
||||||
gst::info!(CAT, imp: self, "websocket connection closed: {:?}", reason);
|
gst::info!(CAT, imp = self, "websocket connection closed: {:?}", reason);
|
||||||
return ControlFlow::Break(());
|
return ControlFlow::Break(());
|
||||||
}
|
}
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
@ -637,7 +643,7 @@ impl ObjectImpl for Signaller {
|
||||||
|
|
||||||
impl SignallableImpl for Signaller {
|
impl SignallableImpl for Signaller {
|
||||||
fn start(&self) {
|
fn start(&self) {
|
||||||
gst::info!(CAT, imp: self, "Starting");
|
gst::info!(CAT, imp = self, "Starting");
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
let connect_task_handle = RUNTIME.spawn(glib::clone!(
|
let connect_task_handle = RUNTIME.spawn(glib::clone!(
|
||||||
|
@ -655,7 +661,7 @@ impl SignallableImpl for Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) {
|
fn stop(&self) {
|
||||||
gst::info!(CAT, imp: self, "Stopping now");
|
gst::info!(CAT, imp = self, "Stopping now");
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
|
@ -677,7 +683,7 @@ impl SignallableImpl for Signaller {
|
||||||
|
|
||||||
if let Some(handle) = send_task_handle {
|
if let Some(handle) = send_task_handle {
|
||||||
if let Err(err) = handle.await {
|
if let Err(err) = handle.await {
|
||||||
gst::warning!(CAT, imp: self, "Error while joining send task: {}", err);
|
gst::warning!(CAT, imp = self, "Error while joining send task: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,7 +698,7 @@ impl SignallableImpl for Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_sdp(&self, session_id: &str, sdp: &gst_webrtc::WebRTCSessionDescription) {
|
fn send_sdp(&self, session_id: &str, sdp: &gst_webrtc::WebRTCSessionDescription) {
|
||||||
gst::debug!(CAT, imp: self, "Sending SDP {sdp:#?}");
|
gst::debug!(CAT, imp = self, "Sending SDP {sdp:#?}");
|
||||||
|
|
||||||
let role = self.settings.lock().unwrap().role;
|
let role = self.settings.lock().unwrap().role;
|
||||||
let is_consumer = matches!(role, super::WebRTCSignallerRole::Consumer);
|
let is_consumer = matches!(role, super::WebRTCSignallerRole::Consumer);
|
||||||
|
@ -722,7 +728,7 @@ impl SignallableImpl for Signaller {
|
||||||
) {
|
) {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Adding ice candidate {candidate:?} for {sdp_m_line_index:?} on session {session_id}"
|
"Adding ice candidate {candidate:?} for {sdp_m_line_index:?} on session {session_id}"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -738,7 +744,7 @@ impl SignallableImpl for Signaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_session(&self, session_id: &str) {
|
fn end_session(&self, session_id: &str) {
|
||||||
gst::debug!(CAT, imp: self, "Signalling session done {}", session_id);
|
gst::debug!(CAT, imp = self, "Signalling session done {}", session_id);
|
||||||
|
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
let session_id = session_id.to_string();
|
let session_id = session_id.to_string();
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl CongestionController {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"consumer {}: considering stats {}",
|
"consumer {}: considering stats {}",
|
||||||
self.peer_id,
|
self.peer_id,
|
||||||
twcc_stats
|
twcc_stats
|
||||||
|
@ -159,7 +159,7 @@ impl CongestionController {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"consumer {}: Old bitrate: {}, ema: {}, stddev: {}",
|
"consumer {}: Old bitrate: {}, ema: {}, stddev: {}",
|
||||||
self.peer_id,
|
self.peer_id,
|
||||||
target_bitrate,
|
target_bitrate,
|
||||||
|
@ -174,7 +174,7 @@ impl CongestionController {
|
||||||
if target_bitrate < ema - 7. * bitrate_stdev {
|
if target_bitrate < ema - 7. * bitrate_stdev {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"consumer {}: below last congestion window",
|
"consumer {}: below last congestion window",
|
||||||
self.peer_id
|
self.peer_id
|
||||||
);
|
);
|
||||||
|
@ -183,7 +183,7 @@ impl CongestionController {
|
||||||
} else if target_bitrate > ema + 7. * bitrate_stdev {
|
} else if target_bitrate > ema + 7. * bitrate_stdev {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"consumer {}: above last congestion window",
|
"consumer {}: above last congestion window",
|
||||||
self.peer_id
|
self.peer_id
|
||||||
);
|
);
|
||||||
|
@ -213,7 +213,7 @@ impl CongestionController {
|
||||||
|
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"consumer {}: still in last congestion window",
|
"consumer {}: still in last congestion window",
|
||||||
self.peer_id,
|
self.peer_id,
|
||||||
);
|
);
|
||||||
|
@ -225,7 +225,7 @@ impl CongestionController {
|
||||||
/* Multiplicative increase */
|
/* Multiplicative increase */
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"consumer {}: outside congestion window",
|
"consumer {}: outside congestion window",
|
||||||
self.peer_id
|
self.peer_id
|
||||||
);
|
);
|
||||||
|
@ -335,7 +335,7 @@ impl CongestionController {
|
||||||
) {
|
) {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"consumer {}: applying congestion control operation {:?}",
|
"consumer {}: applying congestion control operation {:?}",
|
||||||
self.peer_id,
|
self.peer_id,
|
||||||
control_op
|
control_op
|
||||||
|
|
|
@ -372,7 +372,7 @@ impl SessionWrapper {
|
||||||
if !cands.is_empty() {
|
if !cands.is_empty() {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"handling {} pending ice candidates for session {}",
|
"handling {} pending ice candidates for session {}",
|
||||||
cands.len(),
|
cands.len(),
|
||||||
session.id,
|
session.id,
|
||||||
|
@ -401,13 +401,21 @@ impl SessionWrapper {
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
SessionWrapper::InPlace(session) => {
|
SessionWrapper::InPlace(session) => {
|
||||||
gst::trace!(CAT, obj: element, "adding ice candidate for session {session_id}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
obj = element,
|
||||||
|
"adding ice candidate for session {session_id}"
|
||||||
|
);
|
||||||
session
|
session
|
||||||
.webrtcbin
|
.webrtcbin
|
||||||
.emit_by_name::<()>("add-ice-candidate", &[&sdp_m_line_index, &candidate]);
|
.emit_by_name::<()>("add-ice-candidate", &[&sdp_m_line_index, &candidate]);
|
||||||
}
|
}
|
||||||
SessionWrapper::Taken(cands) => {
|
SessionWrapper::Taken(cands) => {
|
||||||
gst::trace!(CAT, obj: element, "queueing ice candidate for session {session_id}");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
obj = element,
|
||||||
|
"queueing ice candidate for session {session_id}"
|
||||||
|
);
|
||||||
cands.push(IceCandidate {
|
cands.push(IceCandidate {
|
||||||
sdp_m_line_index,
|
sdp_m_line_index,
|
||||||
candidate: candidate.to_string(),
|
candidate: candidate.to_string(),
|
||||||
|
@ -449,7 +457,7 @@ fn create_navigation_event(sink: &super::BaseWebRTCSink, msg: &str) {
|
||||||
let event: Result<NavigationEvent, _> = serde_json::from_str(msg);
|
let event: Result<NavigationEvent, _> = serde_json::from_str(msg);
|
||||||
|
|
||||||
if let Ok(event) = event {
|
if let Ok(event) = event {
|
||||||
gst::log!(CAT, obj: sink, "Processing navigation event: {:?}", event);
|
gst::log!(CAT, obj = sink, "Processing navigation event: {:?}", event);
|
||||||
|
|
||||||
if let Some(mid) = event.mid {
|
if let Some(mid) = event.mid {
|
||||||
let this = sink.imp();
|
let this = sink.imp();
|
||||||
|
@ -460,7 +468,7 @@ fn create_navigation_event(sink: &super::BaseWebRTCSink, msg: &str) {
|
||||||
let event = gst::event::Navigation::new(event.event.structure());
|
let event = gst::event::Navigation::new(event.event.structure());
|
||||||
|
|
||||||
if !stream.sink_pad.push_event(event.clone()) {
|
if !stream.sink_pad.push_event(event.clone()) {
|
||||||
gst::info!(CAT, obj: sink, "Could not send event: {:?}", event);
|
gst::info!(CAT, obj = sink, "Could not send event: {:?}", event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -473,13 +481,13 @@ fn create_navigation_event(sink: &super::BaseWebRTCSink, msg: &str) {
|
||||||
if stream.sink_pad.name().starts_with("video_") {
|
if stream.sink_pad.name().starts_with("video_") {
|
||||||
gst::log!(CAT, "Navigating to: {:?}", event);
|
gst::log!(CAT, "Navigating to: {:?}", event);
|
||||||
if !stream.sink_pad.push_event(event.clone()) {
|
if !stream.sink_pad.push_event(event.clone()) {
|
||||||
gst::info!(CAT, obj: sink, "Could not send event: {:?}", event);
|
gst::info!(CAT, obj = sink, "Could not send event: {:?}", event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, obj: sink, "Invalid navigation event: {:?}", msg);
|
gst::error!(CAT, obj = sink, "Invalid navigation event: {:?}", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,7 +876,7 @@ impl PayloadChainBuilder {
|
||||||
fn build(self, pipeline: &gst::Pipeline, src: &gst::Element) -> Result<PayloadChain, Error> {
|
fn build(self, pipeline: &gst::Pipeline, src: &gst::Element) -> Result<PayloadChain, Error> {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pipeline,
|
obj = pipeline,
|
||||||
"Setting up encoding, input caps: {input_caps}, \
|
"Setting up encoding, input caps: {input_caps}, \
|
||||||
output caps: {output_caps}, codec: {codec:?}",
|
output caps: {output_caps}, codec: {codec:?}",
|
||||||
input_caps = self.input_caps,
|
input_caps = self.input_caps,
|
||||||
|
@ -1097,7 +1105,7 @@ impl VideoEncoder {
|
||||||
if !caps.is_strictly_equal(¤t_caps) {
|
if !caps.is_strictly_equal(¤t_caps) {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"session {}: setting bitrate {} and caps {} on encoder {:?}",
|
"session {}: setting bitrate {} and caps {} on encoder {:?}",
|
||||||
self.session_id,
|
self.session_id,
|
||||||
bitrate,
|
bitrate,
|
||||||
|
@ -1159,7 +1167,7 @@ impl State {
|
||||||
sessions.remove(&session_id);
|
sessions.remove(&session_id);
|
||||||
cvar.notify_one();
|
cvar.notify_one();
|
||||||
|
|
||||||
gst::debug!(CAT, obj: element, "Session {session_id} ended");
|
gst::debug!(CAT, obj = element, "Session {session_id} ended");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1270,7 +1278,7 @@ impl Session {
|
||||||
None => {
|
None => {
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Consumer {} not connecting any input stream for inactive media {}",
|
"Consumer {} not connecting any input stream for inactive media {}",
|
||||||
self.peer_id,
|
self.peer_id,
|
||||||
webrtc_pad.media_idx
|
webrtc_pad.media_idx
|
||||||
|
@ -1281,7 +1289,7 @@ impl Session {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Connecting input stream {} for consumer {} and media {}",
|
"Connecting input stream {} for consumer {} and media {}",
|
||||||
stream_name,
|
stream_name,
|
||||||
self.peer_id,
|
self.peer_id,
|
||||||
|
@ -1292,7 +1300,7 @@ impl Session {
|
||||||
|
|
||||||
let codec = match self.codecs {
|
let codec = match self.codecs {
|
||||||
Some(ref codecs) => {
|
Some(ref codecs) => {
|
||||||
gst::debug!(CAT, obj: element, "Picking codec from remote offer");
|
gst::debug!(CAT, obj = element, "Picking codec from remote offer");
|
||||||
|
|
||||||
codecs
|
codecs
|
||||||
.get(&payload)
|
.get(&payload)
|
||||||
|
@ -1300,7 +1308,7 @@ impl Session {
|
||||||
.ok_or_else(|| anyhow!("No codec for payload {}", payload))?
|
.ok_or_else(|| anyhow!("No codec for payload {}", payload))?
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
gst::debug!(CAT, obj: element, "Picking codec from local offer");
|
gst::debug!(CAT, obj = element, "Picking codec from local offer");
|
||||||
|
|
||||||
codecs
|
codecs
|
||||||
.get(&payload)
|
.get(&payload)
|
||||||
|
@ -1522,7 +1530,7 @@ impl InputStream {
|
||||||
|
|
||||||
impl NavigationEventHandler {
|
impl NavigationEventHandler {
|
||||||
fn new(element: &super::BaseWebRTCSink, webrtcbin: &gst::Element) -> Self {
|
fn new(element: &super::BaseWebRTCSink, webrtcbin: &gst::Element) -> Self {
|
||||||
gst::info!(CAT, obj: element, "Creating navigation data channel");
|
gst::info!(CAT, obj = element, "Creating navigation data channel");
|
||||||
let channel = webrtcbin.emit_by_name::<WebRTCDataChannel>(
|
let channel = webrtcbin.emit_by_name::<WebRTCDataChannel>(
|
||||||
"create-data-channel",
|
"create-data-channel",
|
||||||
&[
|
&[
|
||||||
|
@ -1576,7 +1584,11 @@ impl BaseWebRTCSink {
|
||||||
if codec.is_video() {
|
if codec.is_video() {
|
||||||
if let Some(enc_name) = codec.encoder_name().as_deref() {
|
if let Some(enc_name) = codec.encoder_name().as_deref() {
|
||||||
if !VideoEncoder::is_bitrate_supported(enc_name) {
|
if !VideoEncoder::is_bitrate_supported(enc_name) {
|
||||||
gst::error!(CAT, imp: self, "Bitrate handling is not supported yet for {enc_name}");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Bitrate handling is not supported yet for {enc_name}"
|
||||||
|
);
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -1592,7 +1604,12 @@ impl BaseWebRTCSink {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::debug!(CAT, obj: payloader, "Mapping TWCC extension to ID {}", twcc_id);
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
obj = payloader,
|
||||||
|
"Mapping TWCC extension to ID {}",
|
||||||
|
twcc_id
|
||||||
|
);
|
||||||
|
|
||||||
/* We only enforce TWCC in the offer caps, once a remote description
|
/* We only enforce TWCC in the offer caps, once a remote description
|
||||||
* has been set it will get automatically negotiated. This is necessary
|
* has been set it will get automatically negotiated. This is necessary
|
||||||
|
@ -1635,7 +1652,7 @@ impl BaseWebRTCSink {
|
||||||
// GstRTPBasePayload::extensions property is only available since GStreamer 1.24
|
// GstRTPBasePayload::extensions property is only available since GStreamer 1.24
|
||||||
if !payloader.has_property("extensions", Some(gst::Array::static_type())) {
|
if !payloader.has_property("extensions", Some(gst::Array::static_type())) {
|
||||||
if self.has_connected_payloader_setup_slots() {
|
if self.has_connected_payloader_setup_slots() {
|
||||||
gst::warning!(CAT, imp: self, "'extensions' property is not available: TWCC extension ID will default to 1. \
|
gst::warning!(CAT, imp = self, "'extensions' property is not available: TWCC extension ID will default to 1. \
|
||||||
Application code must ensure to pick non-conflicting IDs for any additionally configured extensions. \
|
Application code must ensure to pick non-conflicting IDs for any additionally configured extensions. \
|
||||||
Please consider updating GStreamer to 1.24.");
|
Please consider updating GStreamer to 1.24.");
|
||||||
}
|
}
|
||||||
|
@ -1658,7 +1675,12 @@ impl BaseWebRTCSink {
|
||||||
.map(|value| value.get::<gst_rtp::RTPHeaderExtension>().unwrap());
|
.map(|value| value.get::<gst_rtp::RTPHeaderExtension>().unwrap());
|
||||||
|
|
||||||
if let Some(ext) = twcc {
|
if let Some(ext) = twcc {
|
||||||
gst::debug!(CAT, obj: payloader, "TWCC extension is already mapped to id {} by application", ext.id());
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
obj = payloader,
|
||||||
|
"TWCC extension is already mapped to id {} by application",
|
||||||
|
ext.id()
|
||||||
|
);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1706,11 +1728,19 @@ impl BaseWebRTCSink {
|
||||||
payloader.set_property("ssrc", ssrc);
|
payloader.set_property("ssrc", ssrc);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
gst::warning!(CAT, imp: self, "Unsupported ssrc type (expected i64 or u32)");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Unsupported ssrc type (expected i64 or u32)"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Failed to find 'ssrc' property on payloader");
|
gst::warning!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Failed to find 'ssrc' property on payloader"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1757,7 +1787,7 @@ impl BaseWebRTCSink {
|
||||||
let ret = fastrand::u32(..);
|
let ret = fastrand::u32(..);
|
||||||
|
|
||||||
if !webrtc_pads.contains_key(&ret) {
|
if !webrtc_pads.contains_key(&ret) {
|
||||||
gst::trace!(CAT, imp: self, "Selected ssrc {}", ret);
|
gst::trace!(CAT, imp = self, "Selected ssrc {}", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1773,7 +1803,7 @@ impl BaseWebRTCSink {
|
||||||
let media_idx = webrtc_pads.len() as i32;
|
let media_idx = webrtc_pads.len() as i32;
|
||||||
|
|
||||||
let Some(pad) = webrtcbin.request_pad_simple(&format!("sink_{}", media_idx)) else {
|
let Some(pad) = webrtcbin.request_pad_simple(&format!("sink_{}", media_idx)) else {
|
||||||
gst::error!(CAT, imp: self, "Failed to request pad from webrtcbin");
|
gst::error!(CAT, imp = self, "Failed to request pad from webrtcbin");
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -1836,17 +1866,13 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
match codec {
|
match codec {
|
||||||
Some(codec) => {
|
Some(codec) => {
|
||||||
gst::debug!(
|
gst::debug!(CAT, imp = self, "Selected {codec:?} for media {media_idx}");
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Selected {codec:?} for media {media_idx}"
|
|
||||||
);
|
|
||||||
|
|
||||||
codecs.insert(codec.payload().unwrap(), codec.clone());
|
codecs.insert(codec.payload().unwrap(), codec.clone());
|
||||||
codec.output_filter().unwrap()
|
codec.output_filter().unwrap()
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
gst::error!(CAT, imp: self, "No codec selected for media {media_idx}");
|
gst::error!(CAT, imp = self, "No codec selected for media {media_idx}");
|
||||||
|
|
||||||
gst::Caps::new_empty()
|
gst::Caps::new_empty()
|
||||||
}
|
}
|
||||||
|
@ -1869,7 +1895,7 @@ impl BaseWebRTCSink {
|
||||||
.expect("element added and pipeline playing");
|
.expect("element added and pipeline playing");
|
||||||
|
|
||||||
let ts_refclk = if clock.is::<gst_net::NtpClock>() {
|
let ts_refclk = if clock.is::<gst_net::NtpClock>() {
|
||||||
gst::debug!(CAT, imp: self, "Found NTP clock");
|
gst::debug!(CAT, imp = self, "Found NTP clock");
|
||||||
|
|
||||||
let addr = clock.property::<String>("address");
|
let addr = clock.property::<String>("address");
|
||||||
let port = clock.property::<i32>("port");
|
let port = clock.property::<i32>("port");
|
||||||
|
@ -1880,7 +1906,7 @@ impl BaseWebRTCSink {
|
||||||
format!("ntp={addr}:{port}")
|
format!("ntp={addr}:{port}")
|
||||||
})
|
})
|
||||||
} else if clock.is::<gst_net::PtpClock>() {
|
} else if clock.is::<gst_net::PtpClock>() {
|
||||||
gst::debug!(CAT, imp: self, "Found PTP clock");
|
gst::debug!(CAT, imp = self, "Found PTP clock");
|
||||||
|
|
||||||
let clock_id = clock.property::<u64>("grandmaster-clock-id");
|
let clock_id = clock.property::<u64>("grandmaster-clock-id");
|
||||||
let domain = clock.property::<u32>("domain");
|
let domain = clock.property::<u32>("domain");
|
||||||
|
@ -1918,13 +1944,13 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Requesting WebRTC pad with caps {}",
|
"Requesting WebRTC pad with caps {}",
|
||||||
payloader_caps
|
payloader_caps
|
||||||
);
|
);
|
||||||
|
|
||||||
let Some(pad) = webrtcbin.request_pad_simple(&format!("sink_{}", media_idx)) else {
|
let Some(pad) = webrtcbin.request_pad_simple(&format!("sink_{}", media_idx)) else {
|
||||||
gst::error!(CAT, imp: self, "Failed to request pad from webrtcbin");
|
gst::error!(CAT, imp = self, "Failed to request pad from webrtcbin");
|
||||||
gst::element_imp_error!(
|
gst::element_imp_error!(
|
||||||
self,
|
self,
|
||||||
gst::StreamError::Failed,
|
gst::StreamError::Failed,
|
||||||
|
@ -1934,7 +1960,11 @@ impl BaseWebRTCSink {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(msid) = stream.msid() {
|
if let Some(msid) = stream.msid() {
|
||||||
gst::trace!(CAT, imp: self, "forwarding msid={msid:?} to webrtcbin sinkpad");
|
gst::trace!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"forwarding msid={msid:?} to webrtcbin sinkpad"
|
||||||
|
);
|
||||||
pad.set_property("msid", &msid);
|
pad.set_property("msid", &msid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1972,7 +2002,7 @@ impl BaseWebRTCSink {
|
||||||
/// Prepare for accepting consumers, by setting
|
/// Prepare for accepting consumers, by setting
|
||||||
/// up StreamProducers for each of our sink pads
|
/// up StreamProducers for each of our sink pads
|
||||||
fn prepare(&self) -> Result<(), Error> {
|
fn prepare(&self) -> Result<(), Error> {
|
||||||
gst::debug!(CAT, imp: self, "preparing");
|
gst::debug!(CAT, imp = self, "preparing");
|
||||||
|
|
||||||
self.state
|
self.state
|
||||||
.lock()
|
.lock()
|
||||||
|
@ -1987,7 +2017,7 @@ impl BaseWebRTCSink {
|
||||||
/// Unprepare by stopping consumers, then the signaller object.
|
/// Unprepare by stopping consumers, then the signaller object.
|
||||||
/// Might abort codec discovery
|
/// Might abort codec discovery
|
||||||
fn unprepare(&self) -> Result<(), Error> {
|
fn unprepare(&self) -> Result<(), Error> {
|
||||||
gst::info!(CAT, imp: self, "unpreparing");
|
gst::info!(CAT, imp = self, "unpreparing");
|
||||||
|
|
||||||
let settings = self.settings.lock().unwrap();
|
let settings = self.settings.lock().unwrap();
|
||||||
let signaller = settings.signaller.clone();
|
let signaller = settings.signaller.clone();
|
||||||
|
@ -2011,14 +2041,14 @@ impl BaseWebRTCSink {
|
||||||
handle.abort();
|
handle.abort();
|
||||||
});
|
});
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Waiting for codec discoveries to finish");
|
gst::debug!(CAT, imp = self, "Waiting for codec discoveries to finish");
|
||||||
let codecs_done_receiver = std::mem::take(&mut state.codecs_done_receivers);
|
let codecs_done_receiver = std::mem::take(&mut state.codecs_done_receivers);
|
||||||
codecs_done_receiver.into_iter().for_each(|receiver| {
|
codecs_done_receiver.into_iter().for_each(|receiver| {
|
||||||
RUNTIME.block_on(async {
|
RUNTIME.block_on(async {
|
||||||
let _ = receiver.await;
|
let _ = receiver.await;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
gst::debug!(CAT, imp: self, "No codec discovery is running anymore");
|
gst::debug!(CAT, imp = self, "No codec discovery is running anymore");
|
||||||
|
|
||||||
state.codec_discovery_done = false;
|
state.codec_discovery_done = false;
|
||||||
state.codecs = BTreeMap::new();
|
state.codecs = BTreeMap::new();
|
||||||
|
@ -2029,16 +2059,16 @@ impl BaseWebRTCSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
drop(state);
|
drop(state);
|
||||||
gst::debug!(CAT, imp: self, "Ending sessions");
|
gst::debug!(CAT, imp = self, "Ending sessions");
|
||||||
for session in sessions {
|
for session in sessions {
|
||||||
signaller.end_session(&session.id);
|
signaller.end_session(&session.id);
|
||||||
}
|
}
|
||||||
gst::debug!(CAT, imp: self, "All sessions have started finalizing");
|
gst::debug!(CAT, imp = self, "All sessions have started finalizing");
|
||||||
|
|
||||||
if signaller_state == SignallerState::Started {
|
if signaller_state == SignallerState::Started {
|
||||||
gst::info!(CAT, imp: self, "Stopping signaller");
|
gst::info!(CAT, imp = self, "Stopping signaller");
|
||||||
signaller.stop();
|
signaller.stop();
|
||||||
gst::info!(CAT, imp: self, "Stopped signaller");
|
gst::info!(CAT, imp = self, "Stopped signaller");
|
||||||
}
|
}
|
||||||
|
|
||||||
let finalizing_sessions = self.state.lock().unwrap().finalizing_sessions.clone();
|
let finalizing_sessions = self.state.lock().unwrap().finalizing_sessions.clone();
|
||||||
|
@ -2049,7 +2079,7 @@ impl BaseWebRTCSink {
|
||||||
sessions = cvar.wait(sessions).unwrap();
|
sessions = cvar.wait(sessions).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "All sessions are done finalizing");
|
gst::debug!(CAT, imp = self, "All sessions are done finalizing");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2085,7 +2115,7 @@ impl BaseWebRTCSink {
|
||||||
false,
|
false,
|
||||||
glib::closure!(#[watch] instance, move |_signaler: glib::Object, session_id: &str, peer_id: &str, offer: Option<&gst_webrtc::WebRTCSessionDescription>|{
|
glib::closure!(#[watch] instance, move |_signaler: glib::Object, session_id: &str, peer_id: &str, offer: Option<&gst_webrtc::WebRTCSessionDescription>|{
|
||||||
if let Err(err) = instance.imp().start_session(session_id, peer_id, offer) {
|
if let Err(err) = instance.imp().start_session(session_id, peer_id, offer) {
|
||||||
gst::warning!(CAT, obj: instance, "{}", err);
|
gst::warning!(CAT, obj = instance, "{}", err);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -2101,7 +2131,7 @@ impl BaseWebRTCSink {
|
||||||
if session_description.type_() == gst_webrtc::WebRTCSDPType::Answer {
|
if session_description.type_() == gst_webrtc::WebRTCSDPType::Answer {
|
||||||
instance.imp().handle_sdp_answer(session_id, session_description);
|
instance.imp().handle_sdp_answer(session_id, session_description);
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, obj: instance, "Unsupported SDP Type");
|
gst::error!(CAT, obj = instance, "Unsupported SDP Type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
@ -2127,7 +2157,7 @@ impl BaseWebRTCSink {
|
||||||
false,
|
false,
|
||||||
glib::closure!(#[watch] instance, move |_signaler: glib::Object, session_id: &str|{
|
glib::closure!(#[watch] instance, move |_signaler: glib::Object, session_id: &str|{
|
||||||
if let Err(err) = instance.imp().remove_session(session_id, false) {
|
if let Err(err) = instance.imp().remove_session(session_id, false) {
|
||||||
gst::warning!(CAT, obj: instance, "{}", err);
|
gst::warning!(CAT, obj = instance, "{}", err);
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}),
|
}),
|
||||||
|
@ -2156,7 +2186,7 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
/// Called by the signaller when it wants to shut down gracefully
|
/// Called by the signaller when it wants to shut down gracefully
|
||||||
fn shutdown(&self) {
|
fn shutdown(&self) {
|
||||||
gst::info!(CAT, imp: self, "Shutting down");
|
gst::info!(CAT, imp = self, "Shutting down");
|
||||||
let _ = self
|
let _ = self
|
||||||
.obj()
|
.obj()
|
||||||
.post_message(gst::message::Eos::builder().src(&*self.obj()).build());
|
.post_message(gst::message::Eos::builder().src(&*self.obj()).build());
|
||||||
|
@ -2220,7 +2250,7 @@ impl BaseWebRTCSink {
|
||||||
if let Some(session_wrapper) = state.sessions.get_mut(&session_id) {
|
if let Some(session_wrapper) = state.sessions.get_mut(&session_id) {
|
||||||
session_wrapper.restore(&self.obj(), session);
|
session_wrapper.restore(&self.obj(), session);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Session {session_id} was removed");
|
gst::warning!(CAT, imp = self, "Session {session_id} was removed");
|
||||||
}
|
}
|
||||||
|
|
||||||
drop(state);
|
drop(state);
|
||||||
|
@ -2246,21 +2276,26 @@ impl BaseWebRTCSink {
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
|
|
||||||
if let Some(session) = state.sessions.get(&session_id) {
|
if let Some(session) = state.sessions.get(&session_id) {
|
||||||
gst::debug!(CAT, imp: self, "Creating answer for session {}", session_id);
|
gst::debug!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"Creating answer for session {}",
|
||||||
|
session_id
|
||||||
|
);
|
||||||
let promise = gst::Promise::with_change_func(glib::clone!(
|
let promise = gst::Promise::with_change_func(glib::clone!(
|
||||||
#[weak(rename_to = this)]
|
#[weak(rename_to = this)]
|
||||||
self,
|
self,
|
||||||
#[strong]
|
#[strong]
|
||||||
session_id,
|
session_id,
|
||||||
move |reply| {
|
move |reply| {
|
||||||
gst::debug!(CAT, imp: this, "Created answer for session {}", session_id);
|
gst::debug!(CAT, imp = this, "Created answer for session {}", session_id);
|
||||||
|
|
||||||
let reply = match reply {
|
let reply = match reply {
|
||||||
Ok(Some(reply)) => reply,
|
Ok(Some(reply)) => reply,
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: this,
|
imp = this,
|
||||||
"Promise returned without a reply for {}",
|
"Promise returned without a reply for {}",
|
||||||
session_id
|
session_id
|
||||||
);
|
);
|
||||||
|
@ -2270,7 +2305,7 @@ impl BaseWebRTCSink {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: this,
|
imp = this,
|
||||||
"Promise returned with an error for {}: {:?}",
|
"Promise returned with an error for {}: {:?}",
|
||||||
session_id,
|
session_id,
|
||||||
err
|
err
|
||||||
|
@ -2289,7 +2324,7 @@ impl BaseWebRTCSink {
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: this,
|
imp = this,
|
||||||
"Reply without an answer for session {}: {:?}",
|
"Reply without an answer for session {}: {:?}",
|
||||||
session_id,
|
session_id,
|
||||||
reply
|
reply
|
||||||
|
@ -2383,7 +2418,7 @@ impl BaseWebRTCSink {
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to parse twcc index: {idx_str}"
|
"Failed to parse twcc index: {idx_str}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2430,11 +2465,11 @@ impl BaseWebRTCSink {
|
||||||
fn negotiate(&self, session_id: &str, offer: Option<&gst_webrtc::WebRTCSessionDescription>) {
|
fn negotiate(&self, session_id: &str, offer: Option<&gst_webrtc::WebRTCSessionDescription>) {
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Negotiating for session {}", session_id);
|
gst::debug!(CAT, imp = self, "Negotiating for session {}", session_id);
|
||||||
|
|
||||||
if let Some(session) = state.sessions.get(session_id) {
|
if let Some(session) = state.sessions.get(session_id) {
|
||||||
let session = session.unwrap();
|
let session = session.unwrap();
|
||||||
gst::trace!(CAT, imp: self, "WebRTC pads: {:?}", session.webrtc_pads);
|
gst::trace!(CAT, imp = self, "WebRTC pads: {:?}", session.webrtc_pads);
|
||||||
|
|
||||||
if let Some(offer) = offer {
|
if let Some(offer) = offer {
|
||||||
let promise = gst::Promise::with_change_func(glib::clone!(
|
let promise = gst::Promise::with_change_func(glib::clone!(
|
||||||
|
@ -2443,7 +2478,7 @@ impl BaseWebRTCSink {
|
||||||
#[to_owned]
|
#[to_owned]
|
||||||
session_id,
|
session_id,
|
||||||
move |reply| {
|
move |reply| {
|
||||||
gst::debug!(CAT, imp: this, "received reply {:?}", reply);
|
gst::debug!(CAT, imp = this, "received reply {:?}", reply);
|
||||||
this.on_remote_description_offer_set(session_id);
|
this.on_remote_description_offer_set(session_id);
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
@ -2452,21 +2487,21 @@ impl BaseWebRTCSink {
|
||||||
.webrtcbin
|
.webrtcbin
|
||||||
.emit_by_name::<()>("set-remote-description", &[&offer, &promise]);
|
.emit_by_name::<()>("set-remote-description", &[&offer, &promise]);
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(CAT, imp: self, "Creating offer for session {}", session_id);
|
gst::debug!(CAT, imp = self, "Creating offer for session {}", session_id);
|
||||||
let promise = gst::Promise::with_change_func(glib::clone!(
|
let promise = gst::Promise::with_change_func(glib::clone!(
|
||||||
#[weak(rename_to = this)]
|
#[weak(rename_to = this)]
|
||||||
self,
|
self,
|
||||||
#[to_owned]
|
#[to_owned]
|
||||||
session_id,
|
session_id,
|
||||||
move |reply| {
|
move |reply| {
|
||||||
gst::debug!(CAT, imp: this, "Created offer for session {}", session_id);
|
gst::debug!(CAT, imp = this, "Created offer for session {}", session_id);
|
||||||
|
|
||||||
let reply = match reply {
|
let reply = match reply {
|
||||||
Ok(Some(reply)) => reply,
|
Ok(Some(reply)) => reply,
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: this,
|
imp = this,
|
||||||
"Promise returned without a reply for {}",
|
"Promise returned without a reply for {}",
|
||||||
session_id
|
session_id
|
||||||
);
|
);
|
||||||
|
@ -2476,7 +2511,7 @@ impl BaseWebRTCSink {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: this,
|
imp = this,
|
||||||
"Promise returned with an error for {}: {:?}",
|
"Promise returned with an error for {}: {:?}",
|
||||||
session_id,
|
session_id,
|
||||||
err
|
err
|
||||||
|
@ -2509,7 +2544,7 @@ impl BaseWebRTCSink {
|
||||||
} else {
|
} else {
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"consumer for session {} no longer exists (sessions: {:?}",
|
"consumer for session {} no longer exists (sessions: {:?}",
|
||||||
session_id,
|
session_id,
|
||||||
state.sessions.keys()
|
state.sessions.keys()
|
||||||
|
@ -2550,7 +2585,7 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Adding session: {} for peer: {}",
|
"Adding session: {} for peer: {}",
|
||||||
session_id,
|
session_id,
|
||||||
peer_id,
|
peer_id,
|
||||||
|
@ -2696,7 +2731,7 @@ impl BaseWebRTCSink {
|
||||||
let this = element.imp();
|
let this = element.imp();
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Connection state for in session {} (peer {}) failed",
|
"Connection state for in session {} (peer {}) failed",
|
||||||
session_id,
|
session_id,
|
||||||
peer_id
|
peer_id
|
||||||
|
@ -2706,7 +2741,7 @@ impl BaseWebRTCSink {
|
||||||
_ => {
|
_ => {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Connection state in session {} (peer {}) changed: {:?}",
|
"Connection state in session {} (peer {}) changed: {:?}",
|
||||||
session_id,
|
session_id,
|
||||||
peer_id,
|
peer_id,
|
||||||
|
@ -2736,7 +2771,7 @@ impl BaseWebRTCSink {
|
||||||
gst_webrtc::WebRTCICEConnectionState::Failed => {
|
gst_webrtc::WebRTCICEConnectionState::Failed => {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Ice connection state in session {} (peer {}) failed",
|
"Ice connection state in session {} (peer {}) failed",
|
||||||
session_id,
|
session_id,
|
||||||
peer_id,
|
peer_id,
|
||||||
|
@ -2746,7 +2781,7 @@ impl BaseWebRTCSink {
|
||||||
_ => {
|
_ => {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Ice connection state in session {} (peer {}) changed: {:?}",
|
"Ice connection state in session {} (peer {}) changed: {:?}",
|
||||||
session_id,
|
session_id,
|
||||||
peer_id,
|
peer_id,
|
||||||
|
@ -2789,7 +2824,7 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Ice gathering state in session {} (peer {}) changed: {:?}",
|
"Ice gathering state in session {} (peer {}) changed: {:?}",
|
||||||
session_id,
|
session_id,
|
||||||
peer_id,
|
peer_id,
|
||||||
|
@ -2906,7 +2941,7 @@ impl BaseWebRTCSink {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst::MessageView::Latency(..) => {
|
gst::MessageView::Latency(..) => {
|
||||||
gst::info!(CAT, obj: pipeline, "Recalculating latency");
|
gst::info!(CAT, obj = pipeline, "Recalculating latency");
|
||||||
let _ = pipeline.recalculate_latency();
|
let _ = pipeline.recalculate_latency();
|
||||||
}
|
}
|
||||||
gst::MessageView::Eos(..) => {
|
gst::MessageView::Eos(..) => {
|
||||||
|
@ -3013,7 +3048,7 @@ impl BaseWebRTCSink {
|
||||||
if let Err(err) = pipeline.set_state(gst::State::Ready) {
|
if let Err(err) = pipeline.set_state(gst::State::Ready) {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Failed to bring {peer_id} pipeline to READY: {}",
|
"Failed to bring {peer_id} pipeline to READY: {}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
|
@ -3048,7 +3083,7 @@ impl BaseWebRTCSink {
|
||||||
if let Err(err) = pipeline.set_state(gst::State::Playing) {
|
if let Err(err) = pipeline.set_state(gst::State::Playing) {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Failed to bring {peer_id} pipeline to PLAYING: {}",
|
"Failed to bring {peer_id} pipeline to PLAYING: {}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
|
@ -3204,7 +3239,7 @@ impl BaseWebRTCSink {
|
||||||
{
|
{
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Failed to connect input stream {} for session {}: {}",
|
"Failed to connect input stream {} for session {}: {}",
|
||||||
stream_name,
|
stream_name,
|
||||||
session_id,
|
session_id,
|
||||||
|
@ -3218,7 +3253,7 @@ impl BaseWebRTCSink {
|
||||||
} else {
|
} else {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"No producer to connect session {} to",
|
"No producer to connect session {} to",
|
||||||
session_id,
|
session_id,
|
||||||
);
|
);
|
||||||
|
@ -3261,7 +3296,7 @@ impl BaseWebRTCSink {
|
||||||
} else if let Some(session_wrapper) = state.sessions.get_mut(&session_id) {
|
} else if let Some(session_wrapper) = state.sessions.get_mut(&session_id) {
|
||||||
session_wrapper.restore(&self.obj(), session);
|
session_wrapper.restore(&self.obj(), session);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "Session {session_id} was removed");
|
gst::warning!(CAT, imp = self, "Session {session_id} was removed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3279,7 +3314,7 @@ impl BaseWebRTCSink {
|
||||||
let sdp_m_line_index = match sdp_m_line_index {
|
let sdp_m_line_index = match sdp_m_line_index {
|
||||||
Some(sdp_m_line_index) => sdp_m_line_index,
|
Some(sdp_m_line_index) => sdp_m_line_index,
|
||||||
None => {
|
None => {
|
||||||
gst::warning!(CAT, imp: self, "No mandatory SDP m-line index");
|
gst::warning!(CAT, imp = self, "No mandatory SDP m-line index");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3287,7 +3322,7 @@ impl BaseWebRTCSink {
|
||||||
if let Some(session_wrapper) = state.sessions.get_mut(session_id) {
|
if let Some(session_wrapper) = state.sessions.get_mut(session_id) {
|
||||||
session_wrapper.add_ice_candidate(&self.obj(), session_id, sdp_m_line_index, candidate);
|
session_wrapper.add_ice_candidate(&self.obj(), session_id, sdp_m_line_index, candidate);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "No consumer with ID {session_id}");
|
gst::warning!(CAT, imp = self, "No consumer with ID {session_id}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3313,7 +3348,7 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"consumer from session {} refused media {}: {:?}",
|
"consumer from session {} refused media {}: {:?}",
|
||||||
session_id,
|
session_id,
|
||||||
media_idx,
|
media_idx,
|
||||||
|
@ -3329,7 +3364,7 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Consumer refused media {session_id}, {media_idx}"
|
"Consumer refused media {session_id}, {media_idx}"
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -3345,7 +3380,7 @@ impl BaseWebRTCSink {
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(
|
gst::warning!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"consumer from session {} did not provide valid payload for media index {} for session {}",
|
"consumer from session {} did not provide valid payload for media index {} for session {}",
|
||||||
session_id,
|
session_id,
|
||||||
media_idx,
|
media_idx,
|
||||||
|
@ -3360,7 +3395,7 @@ impl BaseWebRTCSink {
|
||||||
signaller.end_session(session_id);
|
signaller.end_session(session_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst::warning!(CAT, imp: self, "Consumer did not provide valid payload for media session: {session_id} media_ix: {media_idx}");
|
gst::warning!(CAT, imp = self, "Consumer did not provide valid payload for media session: {session_id} media_ix: {media_idx}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3371,7 +3406,7 @@ impl BaseWebRTCSink {
|
||||||
#[to_owned]
|
#[to_owned]
|
||||||
session_id,
|
session_id,
|
||||||
move |reply| {
|
move |reply| {
|
||||||
gst::debug!(CAT, imp: this, "received reply {:?}", reply);
|
gst::debug!(CAT, imp = this, "received reply {:?}", reply);
|
||||||
this.on_remote_description_set(session_id);
|
this.on_remote_description_set(session_id);
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
@ -3380,7 +3415,7 @@ impl BaseWebRTCSink {
|
||||||
.webrtcbin
|
.webrtcbin
|
||||||
.emit_by_name::<()>("set-remote-description", &[desc, &promise]);
|
.emit_by_name::<()>("set-remote-description", &[desc, &promise]);
|
||||||
} else {
|
} else {
|
||||||
gst::warning!(CAT, imp: self, "No consumer with ID {session_id}");
|
gst::warning!(CAT, imp = self, "No consumer with ID {session_id}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3411,11 +3446,11 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Running discovery pipeline for input caps {input_caps} and output caps {output_caps} with codec {codec:?}"
|
"Running discovery pipeline for input caps {input_caps} and output caps {output_caps} with codec {codec:?}"
|
||||||
);
|
);
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "Running discovery pipeline");
|
gst::debug!(CAT, imp = self, "Running discovery pipeline");
|
||||||
let elements_slice = &elements.iter().collect::<Vec<_>>();
|
let elements_slice = &elements.iter().collect::<Vec<_>>();
|
||||||
pipe.0.add_many(elements_slice).unwrap();
|
pipe.0.add_many(elements_slice).unwrap();
|
||||||
gst::Element::link_many(elements_slice)
|
gst::Element::link_many(elements_slice)
|
||||||
|
@ -3498,7 +3533,7 @@ impl BaseWebRTCSink {
|
||||||
if let Some(msg) = stream.next().await {
|
if let Some(msg) = stream.next().await {
|
||||||
match msg.view() {
|
match msg.view() {
|
||||||
gst::MessageView::Error(err) => {
|
gst::MessageView::Error(err) => {
|
||||||
gst::warning!(CAT, imp: self, "Error in discovery pipeline: {err:#?}");
|
gst::warning!(CAT, imp = self, "Error in discovery pipeline: {err:#?}");
|
||||||
pipe.0.debug_to_dot_file_with_ts(
|
pipe.0.debug_to_dot_file_with_ts(
|
||||||
gst::DebugGraphDetails::all(),
|
gst::DebugGraphDetails::all(),
|
||||||
"webrtcsink-discovery-error",
|
"webrtcsink-discovery-error",
|
||||||
|
@ -3531,7 +3566,7 @@ impl BaseWebRTCSink {
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
gst::info!(CAT, imp: self, "Discovery pipeline got caps {caps:?}");
|
gst::info!(CAT, imp = self, "Discovery pipeline got caps {caps:?}");
|
||||||
pipe.0.debug_to_dot_file_with_ts(
|
pipe.0.debug_to_dot_file_with_ts(
|
||||||
gst::DebugGraphDetails::all(),
|
gst::DebugGraphDetails::all(),
|
||||||
format!("webrtcsink-discovery-{}-done", pipe.0.name()),
|
format!("webrtcsink-discovery-{}-done", pipe.0.name()),
|
||||||
|
@ -3549,7 +3584,7 @@ impl BaseWebRTCSink {
|
||||||
s.set("payload", codec.payload().unwrap());
|
s.set("payload", codec.payload().unwrap());
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Codec discovery pipeline for caps {input_caps} with codec {codec:?} succeeded: {s}"
|
"Codec discovery pipeline for caps {input_caps} with codec {codec:?} succeeded: {s}"
|
||||||
);
|
);
|
||||||
break Ok(s);
|
break Ok(s);
|
||||||
|
@ -3585,7 +3620,7 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
gst::info!(
|
gst::info!(
|
||||||
CAT,
|
CAT,
|
||||||
imp: self,
|
imp = self,
|
||||||
"Stream is already encoded with codec {}, still need to payload it",
|
"Stream is already encoded with codec {}, still need to payload it",
|
||||||
codec.name
|
codec.name
|
||||||
);
|
);
|
||||||
|
@ -3646,12 +3681,7 @@ impl BaseWebRTCSink {
|
||||||
/* We don't consider this fatal, as long as we end up with one
|
/* We don't consider this fatal, as long as we end up with one
|
||||||
* potential codec for each input stream
|
* potential codec for each input stream
|
||||||
*/
|
*/
|
||||||
gst::warning!(
|
gst::warning!(CAT, imp = self, "Codec discovery pipeline failed: {}", err);
|
||||||
CAT,
|
|
||||||
imp: self,
|
|
||||||
"Codec discovery pipeline failed: {}",
|
|
||||||
err
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3729,7 +3759,7 @@ impl BaseWebRTCSink {
|
||||||
if !self.input_caps_change_allowed(&caps, e.caps()) {
|
if !self.input_caps_change_allowed(&caps, e.caps()) {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: pad,
|
obj = pad,
|
||||||
"Renegotiation is not supported (old: {}, new: {})",
|
"Renegotiation is not supported (old: {}, new: {})",
|
||||||
caps,
|
caps,
|
||||||
e.caps()
|
e.caps()
|
||||||
|
@ -3737,7 +3767,7 @@ impl BaseWebRTCSink {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst::info!(CAT, obj: pad, "Received caps event {:?}", e);
|
gst::info!(CAT, obj = pad, "Received caps event {:?}", e);
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
|
@ -3787,7 +3817,7 @@ impl BaseWebRTCSink {
|
||||||
for discovery_info in discos.iter() {
|
for discovery_info in discos.iter() {
|
||||||
for src in discovery_info.srcs() {
|
for src in discovery_info.srcs() {
|
||||||
if let Err(err) = src.push_buffer(buffer.clone()) {
|
if let Err(err) = src.push_buffer(buffer.clone()) {
|
||||||
gst::log!(CAT, obj: src, "Failed to push buffer: {}", err);
|
gst::log!(CAT, obj = src, "Failed to push buffer: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3854,7 +3884,7 @@ impl BaseWebRTCSink {
|
||||||
|
|
||||||
match fut.await {
|
match fut.await {
|
||||||
Ok(Err(err)) => {
|
Ok(Err(err)) => {
|
||||||
gst::error!(CAT, imp: this, "Error running discovery: {err:?}");
|
gst::error!(CAT, imp = this, "Error running discovery: {err:?}");
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
this.obj(),
|
this.obj(),
|
||||||
gst::StreamError::CodecNotFound,
|
gst::StreamError::CodecNotFound,
|
||||||
|
@ -4253,7 +4283,7 @@ impl ObjectImpl for BaseWebRTCSink {
|
||||||
|
|
||||||
gst::debug!(
|
gst::debug!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"applying default configuration on encoder {:?}",
|
"applying default configuration on encoder {:?}",
|
||||||
enc
|
enc
|
||||||
);
|
);
|
||||||
|
@ -4407,7 +4437,11 @@ impl ElementImpl for BaseWebRTCSink {
|
||||||
) -> Option<gst::Pad> {
|
) -> Option<gst::Pad> {
|
||||||
let element = self.obj();
|
let element = self.obj();
|
||||||
if element.current_state() > gst::State::Ready {
|
if element.current_state() > gst::State::Ready {
|
||||||
gst::error!(CAT, imp: self, "element pads can only be requested before starting");
|
gst::error!(
|
||||||
|
CAT,
|
||||||
|
imp = self,
|
||||||
|
"element pads can only be requested before starting"
|
||||||
|
);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4491,7 +4525,7 @@ impl ElementImpl for BaseWebRTCSink {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
gst::error!(
|
gst::error!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj = element,
|
||||||
"Trying to set state to NULL from an async \
|
"Trying to set state to NULL from an async \
|
||||||
tokio context, working around the panic but \
|
tokio context, working around the panic but \
|
||||||
you should refactor your code to make use of \
|
you should refactor your code to make use of \
|
||||||
|
@ -4566,7 +4600,7 @@ impl NavigationImpl for BaseWebRTCSink {
|
||||||
gst::log!(CAT, "Navigating to: {:?}", event);
|
gst::log!(CAT, "Navigating to: {:?}", event);
|
||||||
// FIXME: Handle multi tracks.
|
// FIXME: Handle multi tracks.
|
||||||
if !stream.sink_pad.push_event(event.clone()) {
|
if !stream.sink_pad.push_event(event.clone()) {
|
||||||
gst::info!(CAT, imp: self, "Could not send event: {:?}", event);
|
gst::info!(CAT, imp = self, "Could not send event: {:?}", event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue