use std::rc::Rc;
use crate::codec::av1::parser::FrameHeaderObu;
use crate::codec::av1::parser::ReferenceFrameType;
use crate::codec::av1::parser::SequenceHeaderObu;
use crate::codec::av1::parser::REFS_PER_FRAME;
use crate::encoder::av1::EncoderConfig;
use crate::encoder::av1::AV1;
use crate::encoder::stateless::av1::predictor::LowDelayAV1;
use crate::encoder::stateless::BitstreamPromise;
use crate::encoder::stateless::Predictor;
use crate::encoder::stateless::StatelessBackendResult;
use crate::encoder::stateless::StatelessCodec;
use crate::encoder::stateless::StatelessEncoderExecute;
use crate::encoder::stateless::StatelessVideoEncoderBackend;
use crate::encoder::EncodeResult;
use crate::encoder::FrameMetadata;
use crate::encoder::PredictionStructure;
use crate::encoder::Tunings;
use crate::BlockingMode;
mod predictor;
#[cfg(feature = "vaapi")]
pub mod vaapi;
pub struct BackendRequest<P, R> {
sequence: SequenceHeaderObu,
frame: FrameHeaderObu,
input: P,
input_meta: FrameMetadata,
references: [Option<Rc<R>>; REFS_PER_FRAME],
ref_frame_ctrl_l0: [ReferenceFrameType; REFS_PER_FRAME],
ref_frame_ctrl_l1: [ReferenceFrameType; REFS_PER_FRAME],
intra_period: u32,
ip_period: u32,
tunings: Tunings,
coded_output: Vec<u8>,
}
impl<Backend> StatelessCodec<Backend> for AV1
where
Backend: StatelessVideoEncoderBackend<AV1>,
{
type Reference = Backend::Reconstructed;
type Request = BackendRequest<Backend::Picture, Backend::Reconstructed>;
type CodedPromise = BitstreamPromise<Backend::CodedPromise>;
type ReferencePromise = Backend::ReconPromise;
}
pub trait StatelessAV1EncoderBackend: StatelessVideoEncoderBackend<AV1> {
fn encode_tile_group(
&mut self,
request: BackendRequest<Self::Picture, Self::Reconstructed>,
) -> StatelessBackendResult<(Self::ReconPromise, Self::CodedPromise)>;
}
pub type StatelessEncoder<Handle, Backend> =
crate::encoder::stateless::StatelessEncoder<AV1, Handle, Backend>;
impl<Handle, Backend> StatelessEncoderExecute<AV1, Handle, Backend>
for StatelessEncoder<Handle, Backend>
where
Backend: StatelessAV1EncoderBackend,
{
fn execute(
&mut self,
request: BackendRequest<Backend::Picture, Backend::Reconstructed>,
) -> EncodeResult<()> {
let meta = request.input_meta.clone();
self.predictor_frame_count -= 1;
log::trace!("submitting new request");
let (recon, bitstream) = self.backend.encode_tile_group(request)?;
let tilegroup_promise = BitstreamPromise { bitstream, meta };
self.output_queue.add_promise(tilegroup_promise);
self.recon_queue.add_promise(recon);
Ok(())
}
}
impl<Handle, Backend> StatelessEncoder<Handle, Backend>
where
Backend: StatelessAV1EncoderBackend,
{
fn new_av1(backend: Backend, config: EncoderConfig, mode: BlockingMode) -> EncodeResult<Self> {
let predictor: Box<dyn Predictor<_, _, _>> = match config.pred_structure {
PredictionStructure::LowDelay { limit } => Box::new(LowDelayAV1::new(config, limit)),
};
Self::new(backend, mode, predictor)
}
}