fallbackswitch: fix gap processing regression

This was broken by the rewrite, receiving gaps on the main pad
should let the position progress, reset timeouts and keep the main
pad active.

This picks the simplest solution, transforming gap events into GAP
buffers and letting them go through chain(), this achieves the desired
effect.
This commit is contained in:
Mathieu Duponchelle 2022-06-08 21:48:18 +02:00 committed by Sebastian Dröge
parent dfa5b9d8bb
commit abf872130a
2 changed files with 58 additions and 3 deletions

View file

@ -37,9 +37,10 @@ required-features = ["gtk", "gio"]
gst-plugin-version-helper = { path="../../version-helper" }
[features]
default = ["libc"]
default = ["libc", "v1_20"]
static = []
capi = []
v1_20 = ["gst/v1_20"]
[package.metadata.capi]
min_version = "0.8.0"

View file

@ -553,6 +553,16 @@ impl FallbackSwitch {
pad: &super::FallbackSwitchSinkPad,
element: &super::FallbackSwitch,
buffer: gst::Buffer,
) -> Result<gst::FlowSuccess, gst::FlowError> {
self.chain(pad, element, buffer, None)
}
fn chain(
&self,
pad: &super::FallbackSwitchSinkPad,
element: &super::FallbackSwitch,
buffer: gst::Buffer,
from_gap: Option<&gst::event::Gap>,
) -> Result<gst::FlowSuccess, gst::FlowError> {
let mut state = self.state.lock();
let settings = self.settings.lock().clone();
@ -792,7 +802,30 @@ impl FallbackSwitch {
/* TODO: Clip raw video and audio buffers to avoid going backward? */
log!(CAT, obj: pad, "Forwarding {:?}", buffer);
self.src_pad.push(buffer)
if let Some(in_gap_event) = from_gap {
// Safe unwrap: the buffer was constructed from a gap event with
// a timestamp, and even if its timestamp was adjusted it should never
// be NONE by now
let pts = buffer.pts().unwrap();
let mut builder = gst::event::Gap::builder(pts)
.duration(buffer.duration())
.seqnum(in_gap_event.seqnum());
#[cfg(feature = "v1_20")]
{
builder = builder.gap_flags(in_gap_event.gap_flags());
}
let out_gap_event = builder.build();
self.src_pad.push_event(out_gap_event);
Ok(gst::FlowSuccess::Ok)
} else {
self.src_pad.push(buffer)
}
}
fn sink_chain_list(
@ -805,7 +838,7 @@ impl FallbackSwitch {
// TODO: Keep the list intact and forward it in one go (or broken into several
// pieces if needed) when outputting to the active pad
for buffer in list.iter_owned() {
self.sink_chain(pad, element, buffer)?;
self.chain(pad, element, buffer, None)?;
}
Ok(gst::FlowSuccess::Ok)
@ -817,6 +850,27 @@ impl FallbackSwitch {
element: &super::FallbackSwitch,
event: gst::Event,
) -> bool {
if let gst::EventView::Gap(ev) = event.view() {
let mut buffer = gst::Buffer::new();
{
let buf_mut = buffer.get_mut().unwrap();
buf_mut.set_flags(gst::BufferFlags::GAP);
let (pts, duration) = ev.get();
buf_mut.set_pts(pts);
buf_mut.set_duration(duration);
}
return match self.chain(pad, element, buffer, Some(ev)) {
Ok(_) => true,
Err(gst::FlowError::Flushing) | Err(gst::FlowError::Eos) => true,
Err(err) => {
gst::error!(CAT, obj: pad, "Error processing gap event: {}", err);
false
}
};
}
let mut state = self.state.lock();
let forward = self.active_sinkpad.lock().as_ref() == Some(pad);