use std::collections::VecDeque;
use orfail::OrFail;
use crate::video::{VideoFormat, VideoFrame};
#[derive(Debug)]
pub struct Dav1dDecoder {
inner: shiguredo_dav1d::Decoder,
input_queue: VecDeque<VideoFrame>,
output_queue: VecDeque<VideoFrame>,
}
impl Dav1dDecoder {
pub fn new() -> orfail::Result<Self> {
Ok(Self {
inner: shiguredo_dav1d::Decoder::new().or_fail()?,
input_queue: VecDeque::new(),
output_queue: VecDeque::new(),
})
}
pub fn decode(&mut self, frame: &VideoFrame) -> orfail::Result<()> {
(frame.format == VideoFormat::Av1).or_fail()?;
self.inner.decode(&frame.data).or_fail()?;
self.input_queue.push_back(frame.to_stripped());
self.handle_decoded_frames().or_fail()?;
Ok(())
}
pub fn finish(&mut self) -> orfail::Result<()> {
self.inner.finish().or_fail()?;
self.handle_decoded_frames().or_fail()?;
Ok(())
}
fn handle_decoded_frames(&mut self) -> orfail::Result<()> {
while let Some(decoded) = self.inner.next_frame().or_fail()? {
self.output_queue.push_back(VideoFrame::new_i420(
self.input_queue.pop_front().or_fail()?,
decoded.width(),
decoded.height(),
decoded.y_plane(),
decoded.u_plane(),
decoded.v_plane(),
decoded.y_stride(),
decoded.u_stride(),
decoded.v_stride(),
));
}
Ok(())
}
pub fn next_decoded_frame(&mut self) -> Option<VideoFrame> {
self.output_queue.pop_front()
}
}