mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-29 15:01:07 +00:00
dav1ddec: Clean up state tracking a bit
And especially don't keep a decoder instance around while in Null state.
This commit is contained in:
parent
6e28a17280
commit
b795c0c392
1 changed files with 80 additions and 44 deletions
|
@ -21,7 +21,8 @@ use std::i32;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct NegotiationInfos {
|
struct State {
|
||||||
|
decoder: dav1d::Decoder,
|
||||||
input_state:
|
input_state:
|
||||||
Option<gst_video::VideoCodecState<'static, gst_video::video_codec_state::Readable>>,
|
Option<gst_video::VideoCodecState<'static, gst_video::video_codec_state::Readable>>,
|
||||||
output_info: Option<gst_video::VideoInfo>,
|
output_info: Option<gst_video::VideoInfo>,
|
||||||
|
@ -30,8 +31,7 @@ struct NegotiationInfos {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Dav1dDec {
|
pub struct Dav1dDec {
|
||||||
decoder: Mutex<dav1d::Decoder>,
|
state: Mutex<Option<State>>,
|
||||||
negotiation_infos: Mutex<NegotiationInfos>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
|
@ -93,9 +93,11 @@ impl Dav1dDec {
|
||||||
pic: &dav1d::Picture,
|
pic: &dav1d::Picture,
|
||||||
format: gst_video::VideoFormat,
|
format: gst_video::VideoFormat,
|
||||||
) -> Result<(), gst::FlowError> {
|
) -> Result<(), gst::FlowError> {
|
||||||
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
|
let state = state_guard.as_mut().unwrap();
|
||||||
|
|
||||||
let negotiate = {
|
let negotiate = {
|
||||||
let negotiation_infos = self.negotiation_infos.lock().unwrap();
|
match state.output_info {
|
||||||
match negotiation_infos.output_info {
|
|
||||||
Some(ref i) => {
|
Some(ref i) => {
|
||||||
(i.width() != pic.width())
|
(i.width() != pic.width())
|
||||||
|| (i.height() != pic.height() || (i.format() != format))
|
|| (i.height() != pic.height() || (i.format() != format))
|
||||||
|
@ -113,24 +115,26 @@ impl Dav1dDec {
|
||||||
pic.width(),
|
pic.width(),
|
||||||
pic.height()
|
pic.height()
|
||||||
);
|
);
|
||||||
let output_state = {
|
|
||||||
let negotiation_infos = self.negotiation_infos.lock().unwrap();
|
let input_state = state.input_state.as_ref().cloned();
|
||||||
let input_state = negotiation_infos.input_state.as_ref();
|
drop(state_guard);
|
||||||
element.set_output_state(format, pic.width(), pic.height(), input_state)
|
|
||||||
}?;
|
let output_state =
|
||||||
|
element.set_output_state(format, pic.width(), pic.height(), input_state.as_ref())?;
|
||||||
element.negotiate(output_state)?;
|
element.negotiate(output_state)?;
|
||||||
let out_state = element.output_state().unwrap();
|
let out_state = element.output_state().unwrap();
|
||||||
{
|
|
||||||
let mut negotiation_infos = self.negotiation_infos.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
negotiation_infos.output_info = Some(out_state.info());
|
let state = state_guard.as_mut().unwrap();
|
||||||
}
|
state.output_info = Some(out_state.info());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush_decoder(&self, _element: &super::Dav1dDec) {
|
fn flush_decoder(&self, _element: &super::Dav1dDec) {
|
||||||
let decoder = self.decoder.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
decoder.flush();
|
let state = state_guard.as_mut().unwrap();
|
||||||
|
state.decoder.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(
|
fn decode(
|
||||||
|
@ -139,7 +143,9 @@ impl Dav1dDec {
|
||||||
input_buffer: &gst::BufferRef,
|
input_buffer: &gst::BufferRef,
|
||||||
frame: &gst_video::VideoCodecFrame,
|
frame: &gst_video::VideoCodecFrame,
|
||||||
) -> Result<Vec<(dav1d::Picture, gst_video::VideoFormat)>, gst::FlowError> {
|
) -> Result<Vec<(dav1d::Picture, gst_video::VideoFormat)>, gst::FlowError> {
|
||||||
let mut decoder = self.decoder.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
|
let state = state_guard.as_mut().unwrap();
|
||||||
|
|
||||||
let timestamp = frame.dts().map(|ts| *ts as i64);
|
let timestamp = frame.dts().map(|ts| *ts as i64);
|
||||||
let duration = frame.duration().map(|d| *d as i64);
|
let duration = frame.duration().map(|d| *d as i64);
|
||||||
|
|
||||||
|
@ -147,7 +153,11 @@ impl Dav1dDec {
|
||||||
let input_data = input_buffer
|
let input_data = input_buffer
|
||||||
.map_readable()
|
.map_readable()
|
||||||
.map_err(|_| gst::FlowError::Error)?;
|
.map_err(|_| gst::FlowError::Error)?;
|
||||||
let pictures = match decoder.decode(input_data, frame_number, timestamp, duration, || {}) {
|
let pictures =
|
||||||
|
match state
|
||||||
|
.decoder
|
||||||
|
.decode(input_data, frame_number, timestamp, duration, || {})
|
||||||
|
{
|
||||||
Ok(pictures) => pictures,
|
Ok(pictures) => pictures,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
gst_error!(CAT, "Decoding failed (error code: {})", err);
|
gst_error!(CAT, "Decoding failed (error code: {})", err);
|
||||||
|
@ -183,7 +193,10 @@ impl Dav1dDec {
|
||||||
let mut strides = vec![];
|
let mut strides = vec![];
|
||||||
let mut acc_offset: usize = 0;
|
let mut acc_offset: usize = 0;
|
||||||
|
|
||||||
let video_meta_supported = self.negotiation_infos.lock().unwrap().video_meta_supported;
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
|
let state = state_guard.as_mut().unwrap();
|
||||||
|
let video_meta_supported = state.video_meta_supported;
|
||||||
|
drop(state_guard);
|
||||||
|
|
||||||
let info = output_state.info();
|
let info = output_state.info();
|
||||||
let mut out_buffer = gst::Buffer::new();
|
let mut out_buffer = gst::Buffer::new();
|
||||||
|
@ -282,8 +295,10 @@ impl Dav1dDec {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drop_decoded_pictures(&self, element: &super::Dav1dDec) {
|
fn drop_decoded_pictures(&self, element: &super::Dav1dDec) {
|
||||||
let mut decoder = self.decoder.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
while let Ok(pic) = decoder.get_picture() {
|
let state = state_guard.as_mut().unwrap();
|
||||||
|
|
||||||
|
while let Ok(pic) = state.decoder.get_picture() {
|
||||||
gst_debug!(CAT, obj: element, "Dropping picture");
|
gst_debug!(CAT, obj: element, "Dropping picture");
|
||||||
drop(pic);
|
drop(pic);
|
||||||
}
|
}
|
||||||
|
@ -293,9 +308,11 @@ impl Dav1dDec {
|
||||||
&self,
|
&self,
|
||||||
element: &super::Dav1dDec,
|
element: &super::Dav1dDec,
|
||||||
) -> Result<Vec<(dav1d::Picture, gst_video::VideoFormat)>, gst::FlowError> {
|
) -> Result<Vec<(dav1d::Picture, gst_video::VideoFormat)>, gst::FlowError> {
|
||||||
let mut decoder = self.decoder.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
|
let state = state_guard.as_mut().unwrap();
|
||||||
|
|
||||||
let mut pictures = vec![];
|
let mut pictures = vec![];
|
||||||
while let Ok(pic) = decoder.get_picture() {
|
while let Ok(pic) = state.decoder.get_picture() {
|
||||||
let format = self.gst_video_format_from_dav1d_picture(element, &pic);
|
let format = self.gst_video_format_from_dav1d_picture(element, &pic);
|
||||||
if format == gst_video::VideoFormat::Unknown {
|
if format == gst_video::VideoFormat::Unknown {
|
||||||
return Err(gst::FlowError::NotNegotiated);
|
return Err(gst::FlowError::NotNegotiated);
|
||||||
|
@ -418,24 +435,39 @@ impl ElementImpl for Dav1dDec {
|
||||||
impl VideoDecoderImpl for Dav1dDec {
|
impl VideoDecoderImpl for Dav1dDec {
|
||||||
fn start(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
|
fn start(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
|
||||||
{
|
{
|
||||||
let mut infos = self.negotiation_infos.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
infos.output_info = None;
|
*state_guard = Some(State {
|
||||||
|
decoder: dav1d::Decoder::new(),
|
||||||
|
input_state: None,
|
||||||
|
output_info: None,
|
||||||
|
video_meta_supported: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
self.parent_start(element)
|
self.parent_start(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stop(&self, element: &Self::Type) -> Result<(), gst::ErrorMessage> {
|
||||||
|
{
|
||||||
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
|
*state_guard = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.parent_stop(element)
|
||||||
|
}
|
||||||
|
|
||||||
fn set_format(
|
fn set_format(
|
||||||
&self,
|
&self,
|
||||||
element: &Self::Type,
|
element: &Self::Type,
|
||||||
state: &gst_video::VideoCodecState<'static, gst_video::video_codec_state::Readable>,
|
input_state: &gst_video::VideoCodecState<'static, gst_video::video_codec_state::Readable>,
|
||||||
) -> Result<(), gst::LoggableError> {
|
) -> Result<(), gst::LoggableError> {
|
||||||
{
|
{
|
||||||
let mut infos = self.negotiation_infos.lock().unwrap();
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
infos.input_state = Some(state.clone());
|
let state = state_guard.as_mut().unwrap();
|
||||||
|
state.input_state = Some(input_state.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.parent_set_format(element, state)
|
self.parent_set_format(element, input_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_frame(
|
fn handle_frame(
|
||||||
|
@ -477,9 +509,13 @@ impl VideoDecoderImpl for Dav1dDec {
|
||||||
element: &Self::Type,
|
element: &Self::Type,
|
||||||
query: &mut gst::query::Allocation,
|
query: &mut gst::query::Allocation,
|
||||||
) -> Result<(), gst::LoggableError> {
|
) -> Result<(), gst::LoggableError> {
|
||||||
self.negotiation_infos.lock().unwrap().video_meta_supported = query
|
{
|
||||||
|
let mut state_guard = self.state.lock().unwrap();
|
||||||
|
let state = state_guard.as_mut().unwrap();
|
||||||
|
state.video_meta_supported = query
|
||||||
.find_allocation_meta::<gst_video::VideoMeta>()
|
.find_allocation_meta::<gst_video::VideoMeta>()
|
||||||
.is_some();
|
.is_some();
|
||||||
|
}
|
||||||
|
|
||||||
self.parent_decide_allocation(element, query)
|
self.parent_decide_allocation(element, query)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue