use anyhow::Result;
use crate::decode::Decoder;
use crate::frame::{StreamInfo, VideoFrame};
use super::eager::NvdecDecoder;
pub struct NvdecPushDecoder {
info: StreamInfo,
gpu_index: u32,
pending_samples: Vec<(Vec<u8>, u64)>,
decoded: Option<Box<dyn Decoder>>,
finished: bool,
}
impl NvdecPushDecoder {
pub fn new(info: StreamInfo, gpu_index: u32) -> Self {
Self {
info,
gpu_index,
pending_samples: Vec::new(),
decoded: None,
finished: false,
}
}
pub fn push_sample_with_pts(&mut self, data: &[u8], pts: u64) -> Result<()> {
if self.finished {
anyhow::bail!("NvdecPushDecoder: push_sample after finish");
}
self.pending_samples.push((data.to_vec(), pts));
Ok(())
}
}
impl Decoder for NvdecPushDecoder {
fn stream_info(&self) -> &StreamInfo {
&self.info
}
fn push_sample(&mut self, data: &[u8]) -> Result<()> {
if self.finished {
anyhow::bail!("NvdecPushDecoder: push_sample after finish");
}
let pts = self.pending_samples.len() as u64;
self.pending_samples.push((data.to_vec(), pts));
Ok(())
}
fn finish(&mut self) -> Result<()> {
if self.finished {
return Ok(());
}
self.finished = true;
let samples = std::mem::take(&mut self.pending_samples);
self.decoded = Some(NvdecDecoder::new_with_pts(
samples,
self.info.clone(),
self.gpu_index,
)?);
Ok(())
}
fn decode_next(&mut self) -> Result<Option<VideoFrame>> {
match self.decoded.as_mut() {
Some(inner) => inner.decode_next(),
None => {
Ok(None)
}
}
}
}