Skip to content

Commit

Permalink
decoder/stateless/av1: split backend picture creation from initializa…
Browse files Browse the repository at this point in the history
…tion

We want to create pictures early so the backend can check whether all
required resources are available before processing. This requires
splitting new_picture into a method that allocates the picture and its
resources, and another one that initializes the picture parameters, so
they can be called from two different sites.
  • Loading branch information
Gnurou committed Jul 12, 2024
1 parent c5473b8 commit 98eb82c
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 21 deletions.
27 changes: 20 additions & 7 deletions src/decoder/stateless/av1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,24 @@ pub trait StatelessAV1DecoderBackend:
highest_spatial_layer: Option<u32>,
) -> StatelessBackendResult<()>;

/// Called when the decoder determines that a new picture was found.
/// Called when the decoder determines that a new picture was found. The backend allocates all
/// the resources it needs to process that picture.
fn new_picture(
&mut self,
sequence: &SequenceHeaderObu,
picture: &FrameHeaderObu,
hdr: &FrameHeaderObu,
timestamp: u64,
reference_frames: &[Option<Self::Handle>; NUM_REF_FRAMES],
highest_spatial_layer: Option<u32>,
) -> StatelessBackendResult<Self::Picture>;

/// Called to set the global parameters of a picture.
fn begin_picture(
&mut self,
picture: &mut Self::Picture,
sequence: &SequenceHeaderObu,
hdr: &FrameHeaderObu,
reference_frames: &[Option<Self::Handle>; NUM_REF_FRAMES],
) -> StatelessBackendResult<()>;

/// Called to dispatch a decode operation to the backend.
#[allow(clippy::too_many_arguments)]
fn decode_tile_group(
Expand Down Expand Up @@ -176,14 +184,19 @@ where
handle: ref_frame.clone(),
});
} else if let Some(sequence) = &self.codec.sequence {
let backend_picture = self.backend.new_picture(
sequence,
let mut backend_picture = self.backend.new_picture(
&frame_header,
timestamp,
&self.codec.reference_frames,
self.codec.highest_spatial_layer,
)?;

self.backend.begin_picture(
&mut backend_picture,
sequence,
&frame_header,
&self.codec.reference_frames,
)?;

self.codec.current_pic = Some(CurrentPicState::RegularFrame {
header: frame_header.clone(),
backend_picture,
Expand Down
12 changes: 10 additions & 2 deletions src/decoder/stateless/av1/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,23 @@ impl StatelessAV1DecoderBackend for Backend {

fn new_picture(
&mut self,
_: &crate::codec::av1::parser::SequenceHeaderObu,
_: &crate::codec::av1::parser::FrameHeaderObu,
_: u64,
_: &[Option<Self::Handle>; crate::codec::av1::parser::NUM_REF_FRAMES],
_: Option<u32>,
) -> crate::decoder::stateless::StatelessBackendResult<Self::Picture> {
Ok(())
}

fn begin_picture(
&mut self,
_: &mut Self::Picture,
_: &crate::codec::av1::parser::SequenceHeaderObu,
_: &crate::codec::av1::parser::FrameHeaderObu,
_: &[Option<Self::Handle>; crate::codec::av1::parser::NUM_REF_FRAMES],
) -> crate::decoder::stateless::StatelessBackendResult<()> {
todo!()
}

fn decode_tile_group(
&mut self,
_: &mut Self::Picture,
Expand Down
32 changes: 20 additions & 12 deletions src/decoder/stateless/av1/vaapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use crate::decoder::stateless::av1::Av1;
use crate::decoder::stateless::av1::StatelessAV1DecoderBackend;
use crate::decoder::stateless::NewStatelessDecoderError;
use crate::decoder::stateless::StatelessBackendError;
use crate::decoder::stateless::StatelessBackendResult;
use crate::decoder::stateless::StatelessDecoder;
use crate::decoder::stateless::StatelessDecoderBackendPicture;
use crate::decoder::BlockingMode;
Expand Down Expand Up @@ -507,7 +508,7 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessAV1DecoderBackend for VaapiB
&mut self,
sequence: &Rc<SequenceHeaderObu>,
highest_spatial_layer: Option<u32>,
) -> crate::decoder::stateless::StatelessBackendResult<()> {
) -> StatelessBackendResult<()> {
let pool_creation_mode = match highest_spatial_layer {
Some(highest_layer) => {
/* The spec mandates a 2:1 or 1.5:1 ratio, let's go with 2:1 to
Expand All @@ -526,12 +527,10 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessAV1DecoderBackend for VaapiB

fn new_picture(
&mut self,
sequence: &SequenceHeaderObu,
hdr: &FrameHeaderObu,
timestamp: u64,
reference_frames: &[Option<Self::Handle>; NUM_REF_FRAMES],
highest_spatial_layer: Option<u32>,
) -> crate::decoder::stateless::StatelessBackendResult<Self::Picture> {
) -> StatelessBackendResult<Self::Picture> {
let pool = match highest_spatial_layer {
Some(_) => {
let layer = Resolution {
Expand All @@ -552,19 +551,31 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessAV1DecoderBackend for VaapiB
.ok_or(StatelessBackendError::OutOfResources)?;

let metadata = self.metadata_state.get_parsed()?;
let mut picture = VaPicture::new(timestamp, Rc::clone(&metadata.context), surface);
Ok(VaPicture::new(
timestamp,
Rc::clone(&metadata.context),
surface,
))
}

let surface_id = picture.surface().id();
fn begin_picture(
&mut self,
picture: &mut Self::Picture,
sequence: &SequenceHeaderObu,
hdr: &FrameHeaderObu,
reference_frames: &[Option<Self::Handle>; NUM_REF_FRAMES],
) -> StatelessBackendResult<()> {
let metadata = self.metadata_state.get_parsed()?;

let pic_param = build_pic_param(hdr, sequence, surface_id, reference_frames)
let pic_param = build_pic_param(hdr, sequence, picture.surface().id(), reference_frames)
.context("Failed to build picture parameter")?;
let pic_param = metadata
.context
.create_buffer(pic_param)
.context("Failed to create picture parameter buffer")?;
picture.add_buffer(pic_param);

Ok(picture)
Ok(())
}

fn decode_tile_group(
Expand Down Expand Up @@ -593,10 +604,7 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessAV1DecoderBackend for VaapiB
Ok(())
}

fn submit_picture(
&mut self,
picture: Self::Picture,
) -> crate::decoder::stateless::StatelessBackendResult<Self::Handle> {
fn submit_picture(&mut self, picture: Self::Picture) -> StatelessBackendResult<Self::Handle> {
self.process_picture::<Av1>(picture)
}
}
Expand Down

0 comments on commit 98eb82c

Please sign in to comment.