blob: 6d5b7add14f646c74499e7116475d1fef67114ce [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::cell::RefCell;
use std::collections::VecDeque;
use std::rc::Rc;
use crate::decoders::h264::dpb::Dpb;
use crate::decoders::h264::parser::Pps;
use crate::decoders::h264::parser::Slice;
use crate::decoders::h264::parser::Sps;
use crate::decoders::h264::picture::H264Picture;
use crate::decoders::BlockingMode;
use crate::decoders::DecodedHandle;
use crate::decoders::VideoDecoderBackend;
pub type Result<T> = std::result::Result<T, crate::decoders::StatelessBackendError>;
#[cfg(test)]
pub mod dummy;
#[cfg(feature = "vaapi")]
pub mod vaapi;
/// The container type for the picture. Pictures must offer interior mutability
/// as they may be shared. This is notably the case when two fields reference
/// each other.
///
/// Pictures are contained as soon as they are submitted to the accelerator.
pub type ContainedPicture<T> = Rc<RefCell<H264Picture<T>>>;
/// A convenience type that casts using fully-qualified syntax.
pub type AsBackendHandle<Handle> = <Handle as DecodedHandle>::BackendHandle;
/// Trait for stateless decoder backends. The decoder will call into the backend
/// to request decode operations. The backend can operate in blocking mode,
/// where it will wait until the current decode finishes, or in non-blocking
/// mode, where it should return immediately with any previously decoded frames
/// that happen to be ready.
pub(crate) trait StatelessDecoderBackend: VideoDecoderBackend {
/// The type that the backend returns as a result of a decode operation.
/// This will usually be some backend-specific type with a resource and a
/// resource pool so that said buffer can be reused for another decode
/// operation when it goes out of scope.
type Handle: DecodedHandle;
/// Called when a new SPS is parsed.
fn new_sequence(&mut self, sps: &Sps, dpb_size: usize) -> Result<()>;
/// Called when the decoder determines that a frame or field was found.
fn new_picture(
&mut self,
picture: &H264Picture<AsBackendHandle<Self::Handle>>,
timestamp: u64,
) -> Result<()>;
/// Called when the decoder determines that a second field was found.
/// Indicates that the underlying BackendHandle is to be shared between the
/// two pictures. This is so both fields decode to the same underlying
/// resource and can thus be presented together as a single frame.
fn new_field_picture(
&mut self,
picture: &H264Picture<AsBackendHandle<Self::Handle>>,
timestamp: u64,
first_field: &Self::Handle,
) -> Result<()>;
/// Called by the decoder for every frame or field found.
fn handle_picture(
&mut self,
picture: &H264Picture<AsBackendHandle<Self::Handle>>,
timestamp: u64,
sps: &Sps,
pps: &Pps,
dpb: &Dpb<Self::Handle>,
slice: &Slice<&dyn AsRef<[u8]>>,
) -> Result<()>;
/// Called to dispatch a decode operation to the backend.
fn decode_slice(
&mut self,
slice: &Slice<&dyn AsRef<[u8]>>,
sps: &Sps,
pps: &Pps,
dpb: &Dpb<Self::Handle>,
ref_pic_list0: &[Self::Handle],
ref_pic_list1: &[Self::Handle],
) -> Result<()>;
/// Called when the decoder has decided to split a frame into its
/// constituent fields. `new_picture` represents the newly-created field.
fn new_split_picture(
&mut self,
split_picture: ContainedPicture<AsBackendHandle<Self::Handle>>,
new_picture: ContainedPicture<AsBackendHandle<Self::Handle>>,
) -> Result<()>;
/// Called when the decoder wants the backend to finish the decoding
/// operations for `picture`. At this point, `decode_slice` has been called
/// for all slices. The argument `block` dictates whether this call should
/// wait until the current decode finishes, or whether it should return
/// immediately.
///
/// This call will assign the ownership of the BackendHandle to the Picture
/// and then assign the ownership of the Picture to the Handle.
fn submit_picture(
&mut self,
picture: H264Picture<AsBackendHandle<Self::Handle>>,
block: bool,
) -> Result<Self::Handle>;
/// Poll for any ready pictures. `block` dictates whether this call should
/// block on the operation or return immediately.
fn poll(&mut self, blocking_mode: BlockingMode) -> Result<VecDeque<Self::Handle>>;
/// Indicates that the decoder has split a picture and that a new Handle
/// must be obtained.
fn new_handle(
&mut self,
picture: ContainedPicture<AsBackendHandle<Self::Handle>>,
) -> Result<Self::Handle>;
/// Whether the handle is ready for presentation. The decoder will check
/// this before returning the handle to clients.
fn handle_is_ready(&self, handle: &Self::Handle) -> bool;
/// Block on handle `handle`.
fn block_on_handle(&mut self, handle: &Self::Handle) -> Result<()>;
/// Get the test parameters for the backend. The caller is reponsible for
/// downcasting them to the correct type, which is backend-dependent.
#[cfg(test)]
fn get_test_params(&self) -> &dyn std::any::Any;
}