dav1ddec: Store the output state instead of just the video info in the decoder state

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2190>
This commit is contained in:
Sebastian Dröge 2025-04-27 13:41:04 +03:00 committed by GStreamer Marge Bot
parent 6df4adac31
commit 52037c8aca

View file

@ -56,7 +56,8 @@ const DEFAULT_INLOOP_FILTERS: InloopFilterType = InloopFilterType::empty();
struct State { struct State {
decoder: dav1d::Decoder, decoder: dav1d::Decoder,
input_state: gst_video::VideoCodecState<'static, gst_video::video_codec_state::Readable>, input_state: gst_video::VideoCodecState<'static, gst_video::video_codec_state::Readable>,
output_info: Option<gst_video::VideoInfo>, output_state:
Option<gst_video::VideoCodecState<'static, gst_video::video_codec_state::Readable>>,
video_meta_supported: bool, video_meta_supported: bool,
n_cpus: usize, n_cpus: usize,
} }
@ -278,15 +279,11 @@ impl Dav1dDec {
return Err(gst::FlowError::NotNegotiated); return Err(gst::FlowError::NotNegotiated);
} }
let need_negotiate = { let need_negotiate = state.output_state.as_ref().is_none_or(|state| {
match state.output_info { let info = state.info();
Some(ref i) => { (info.width() != pic.width())
(i.width() != pic.width()) || (info.height() != pic.height() || (info.format() != format))
|| (i.height() != pic.height() || (i.format() != format)) });
}
None => true,
}
};
if !need_negotiate { if !need_negotiate {
return Ok(state_guard); return Ok(state_guard);
} }
@ -422,7 +419,7 @@ impl Dav1dDec {
state_guard = self.state.lock().unwrap(); state_guard = self.state.lock().unwrap();
let state = state_guard.as_mut().ok_or(gst::FlowError::Flushing)?; let state = state_guard.as_mut().ok_or(gst::FlowError::Flushing)?;
state.output_info = Some(out_state.info().clone()); state.output_state = Some(out_state.clone());
Ok(state_guard) Ok(state_guard)
} }
@ -520,14 +517,18 @@ impl Dav1dDec {
) )
.map(|_| std::ops::ControlFlow::Break(())) .map(|_| std::ops::ControlFlow::Break(()))
} }
} };
let res = res?;
Ok((state_guard, res))
} }
fn decoded_picture_as_buffer( fn decoded_picture_as_buffer(
&self, &self,
mut state_guard: MutexGuard<Option<State>>, mut state_guard: MutexGuard<Option<State>>,
pic: &dav1d::Picture, pic: &dav1d::Picture,
output_state: gst_video::VideoCodecState<gst_video::video_codec_state::Readable>, output_state: &gst_video::VideoCodecState<gst_video::video_codec_state::Readable>,
codec_frame: &mut gst_video::VideoCodecFrame, codec_frame: &mut gst_video::VideoCodecFrame,
) -> Result<(), gst::FlowError> { ) -> Result<(), gst::FlowError> {
let state = state_guard.as_mut().ok_or(gst::FlowError::Flushing)?; let state = state_guard.as_mut().ok_or(gst::FlowError::Flushing)?;
@ -673,7 +674,7 @@ impl Dav1dDec {
let frame = instance.frame(offset); let frame = instance.frame(offset);
if let Some(mut frame) = frame { if let Some(mut frame) = frame {
self.decoded_picture_as_buffer(state_guard, pic, output_state, &mut frame)?; self.decoded_picture_as_buffer(state_guard, pic, &output_state, &mut frame)?;
instance.finish_frame(frame)?; instance.finish_frame(frame)?;
Ok(self.state.lock().unwrap()) Ok(self.state.lock().unwrap())
} else { } else {
@ -925,7 +926,7 @@ impl VideoDecoderImpl for Dav1dDec {
}; };
match *state_guard { match *state_guard {
Some(ref state) => match state.output_info { Some(ref state) => match state.output_state.as_ref().map(|s| s.info()) {
Some(ref info) => { Some(ref info) => {
let mut upstream_latency = gst::query::Latency::new(); let mut upstream_latency = gst::query::Latency::new();
@ -1041,7 +1042,7 @@ impl VideoDecoderImpl for Dav1dDec {
*state_guard = Some(State { *state_guard = Some(State {
decoder, decoder,
input_state: input_state.clone(), input_state: input_state.clone(),
output_info: None, output_state: None,
video_meta_supported: false, video_meta_supported: false,
n_cpus, n_cpus,
}); });