mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-02 00:11:01 +00:00
dav1d: Only drain at most one decoded frame per input frame unless the decoder requires more before accepting new data
This works around a race condition in dav1d where the decoder deadlocks if multiple threads are used, and also is generally beneficial as it allows for proper frame threading. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1055>
This commit is contained in:
parent
4582ae91ab
commit
d110977580
1 changed files with 11 additions and 8 deletions
|
@ -380,13 +380,13 @@ impl Dav1dDec {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drop_decoded_pictures(&self, state_guard: &mut MutexGuard<Option<State>>) {
|
fn drop_decoded_pictures(&self, state_guard: &mut MutexGuard<Option<State>>) {
|
||||||
while let Ok(Some(pic)) = self.pending_pictures(state_guard) {
|
while let Ok(Some(pic)) = self.pending_picture(state_guard) {
|
||||||
gst::debug!(CAT, imp: self, "Dropping picture {}", pic.offset());
|
gst::debug!(CAT, imp: self, "Dropping picture {}", pic.offset());
|
||||||
drop(pic);
|
drop(pic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pending_pictures(
|
fn pending_picture(
|
||||||
&self,
|
&self,
|
||||||
state_guard: &mut MutexGuard<Option<State>>,
|
state_guard: &mut MutexGuard<Option<State>>,
|
||||||
) -> Result<Option<dav1d::Picture>, gst::FlowError> {
|
) -> Result<Option<dav1d::Picture>, gst::FlowError> {
|
||||||
|
@ -425,9 +425,13 @@ impl Dav1dDec {
|
||||||
fn forward_pending_pictures<'s>(
|
fn forward_pending_pictures<'s>(
|
||||||
&'s self,
|
&'s self,
|
||||||
mut state_guard: MutexGuard<'s, Option<State>>,
|
mut state_guard: MutexGuard<'s, Option<State>>,
|
||||||
|
drain: bool,
|
||||||
) -> Result<MutexGuard<Option<State>>, gst::FlowError> {
|
) -> Result<MutexGuard<Option<State>>, gst::FlowError> {
|
||||||
while let Some(pic) = self.pending_pictures(&mut state_guard)? {
|
while let Some(pic) = self.pending_picture(&mut state_guard)? {
|
||||||
state_guard = self.handle_picture(state_guard, &pic)?;
|
state_guard = self.handle_picture(state_guard, &pic)?;
|
||||||
|
if !drain {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(state_guard)
|
Ok(state_guard)
|
||||||
|
@ -709,19 +713,18 @@ impl VideoDecoderImpl for Dav1dDec {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut state_guard = self.state.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
state_guard = self.forward_pending_pictures(state_guard)?;
|
|
||||||
if self.send_data(&mut state_guard, input_buffer, frame)?
|
if self.send_data(&mut state_guard, input_buffer, frame)?
|
||||||
== std::ops::ControlFlow::Continue(())
|
== std::ops::ControlFlow::Continue(())
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
state_guard = self.forward_pending_pictures(state_guard)?;
|
state_guard = self.forward_pending_pictures(state_guard, false)?;
|
||||||
if self.send_pending_data(&mut state_guard)? == std::ops::ControlFlow::Break(())
|
if self.send_pending_data(&mut state_guard)? == std::ops::ControlFlow::Break(())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _state_guard = self.forward_pending_pictures(state_guard)?;
|
let _state_guard = self.forward_pending_pictures(state_guard, false)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(gst::FlowSuccess::Ok)
|
Ok(gst::FlowSuccess::Ok)
|
||||||
|
@ -750,7 +753,7 @@ impl VideoDecoderImpl for Dav1dDec {
|
||||||
if state_guard.is_some() {
|
if state_guard.is_some() {
|
||||||
let state = state_guard.as_mut().unwrap();
|
let state = state_guard.as_mut().unwrap();
|
||||||
self.flush_decoder(state);
|
self.flush_decoder(state);
|
||||||
let _state_guard = self.forward_pending_pictures(state_guard)?;
|
let _state_guard = self.forward_pending_pictures(state_guard, true)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,7 +768,7 @@ impl VideoDecoderImpl for Dav1dDec {
|
||||||
if state_guard.is_some() {
|
if state_guard.is_some() {
|
||||||
let state = state_guard.as_mut().unwrap();
|
let state = state_guard.as_mut().unwrap();
|
||||||
self.flush_decoder(state);
|
self.flush_decoder(state);
|
||||||
let _state_guard = self.forward_pending_pictures(state_guard)?;
|
let _state_guard = self.forward_pending_pictures(state_guard, true)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue