mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-23 10:30:40 +00:00
fallbackswitch: Recheck active_sinkpad after schedule_timeout
`schedule_timeout` can synchronously call `handle_timeout` and change the active pad. We need to update `is_active` afterwards. After calling `schedule_timeout` with `end_running_time`, we used to assume there was no pad switch and reset `switched_pad` immediately. If the pad actually got switched, this would make us miss a sticky events update.
This commit is contained in:
parent
d77929252a
commit
68c55ca413
1 changed files with 17 additions and 15 deletions
|
@ -14,7 +14,7 @@ use gst::{debug, log, trace};
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::{Mutex, MutexGuard};
|
||||||
use std::sync::atomic::{AtomicU32, Ordering};
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
|
|
||||||
const PROP_PRIORITY: &str = "priority";
|
const PROP_PRIORITY: &str = "priority";
|
||||||
|
@ -689,18 +689,19 @@ impl FallbackSwitch {
|
||||||
* in case the initial active pad never receives a buffer */
|
* in case the initial active pad never receives a buffer */
|
||||||
if let Some(running_time) = start_running_time {
|
if let Some(running_time) = start_running_time {
|
||||||
if state.timeout_clock_id.is_none() && !is_active {
|
if state.timeout_clock_id.is_none() && !is_active {
|
||||||
|
// May change active pad immediately
|
||||||
self.schedule_timeout(element, &mut state, &settings, running_time);
|
self.schedule_timeout(element, &mut state, &settings, running_time);
|
||||||
|
is_active = self.active_sinkpad.lock().as_ref() == Some(pad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut state = if let Some(clock_id) = &output_clockid {
|
if let Some(clock_id) = &output_clockid {
|
||||||
drop(state);
|
MutexGuard::unlocked(&mut state, || {
|
||||||
|
|
||||||
let (_res, _) = clock_id.wait();
|
let (_res, _) = clock_id.wait();
|
||||||
self.state.lock()
|
});
|
||||||
} else {
|
|
||||||
state
|
is_active = self.active_sinkpad.lock().as_ref() == Some(pad);
|
||||||
};
|
}
|
||||||
|
|
||||||
let mut pad_state = pad_imp.state.lock();
|
let mut pad_state = pad_imp.state.lock();
|
||||||
if pad_state.flushing {
|
if pad_state.flushing {
|
||||||
|
@ -708,10 +709,6 @@ impl FallbackSwitch {
|
||||||
return Err(gst::FlowError::Flushing);
|
return Err(gst::FlowError::Flushing);
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_active = self.active_sinkpad.lock().as_ref() == Some(pad);
|
|
||||||
let switched_pad = state.switched_pad;
|
|
||||||
let discont_pending = state.discont_pending;
|
|
||||||
|
|
||||||
if is_active {
|
if is_active {
|
||||||
if Option::zip(start_running_time, state.output_running_time).map_or(
|
if Option::zip(start_running_time, state.output_running_time).map_or(
|
||||||
false,
|
false,
|
||||||
|
@ -749,13 +746,12 @@ impl FallbackSwitch {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(end_running_time) = end_running_time {
|
if let Some(end_running_time) = end_running_time {
|
||||||
|
// May change active pad immediately
|
||||||
self.schedule_timeout(element, &mut state, &settings, end_running_time);
|
self.schedule_timeout(element, &mut state, &settings, end_running_time);
|
||||||
|
is_active = self.active_sinkpad.lock().as_ref() == Some(pad);
|
||||||
} else {
|
} else {
|
||||||
state.cancel_timeout();
|
state.cancel_timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
state.switched_pad = false;
|
|
||||||
state.discont_pending = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(running_time) = end_running_time {
|
if let Some(running_time) = end_running_time {
|
||||||
|
@ -768,6 +764,12 @@ impl FallbackSwitch {
|
||||||
log!(CAT, obj: pad, "Dropping {:?} on inactive pad", buffer);
|
log!(CAT, obj: pad, "Dropping {:?} on inactive pad", buffer);
|
||||||
return Ok(gst::FlowSuccess::Ok);
|
return Ok(gst::FlowSuccess::Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let switched_pad = state.switched_pad;
|
||||||
|
let discont_pending = state.discont_pending;
|
||||||
|
state.switched_pad = false;
|
||||||
|
state.discont_pending = false;
|
||||||
|
|
||||||
let _stream_lock = self.src_pad.stream_lock();
|
let _stream_lock = self.src_pad.stream_lock();
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue