Skip to content

decoder: h264: Use Cow instead of slice #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 53 additions & 31 deletions src/decoder/stateless/h264/vaapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,15 @@ fn fill_ref_pic_list<M: SurfaceMemoryDescriptor>(
}

fn build_slice_param<M: SurfaceMemoryDescriptor>(
params: &mut libva::SliceParameterBufferH264,
offset: u32,
hdr: &SliceHeader,
slice_size: usize,
ref_list_0: &[&DpbEntry<VADecodedHandle<M>>],
ref_list_1: &[&DpbEntry<VADecodedHandle<M>>],
sps: &Sps,
pps: &Pps,
) -> anyhow::Result<BufferType> {
) -> anyhow::Result<()> {
let ref_list_0 = fill_ref_pic_list(ref_list_0);
let ref_list_1 = fill_ref_pic_list(ref_list_1);
let pwt = &hdr.pred_weight_table;
Expand Down Expand Up @@ -422,9 +424,9 @@ fn build_slice_param<M: SurfaceMemoryDescriptor>(
}
}

let slice_param = libva::SliceParameterBufferH264::new(
params.add_slice_parameter(
slice_size as u32,
0,
offset,
libva::constants::VA_SLICE_DATA_FLAG_ALL,
hdr.header_bit_size as u16,
hdr.first_mb_in_slice as u16,
Expand Down Expand Up @@ -455,15 +457,19 @@ fn build_slice_param<M: SurfaceMemoryDescriptor>(
chroma_offset_l1,
);

Ok(BufferType::SliceParameter(SliceParameter::H264(
slice_param,
)))
Ok(())
}

pub struct VaapiH264Picture<Picture> {
picture: Picture,
slice_params: libva::SliceParameterBufferH264,
slice_data: Vec<u8>,
}

impl<M: SurfaceMemoryDescriptor + 'static> StatelessDecoderBackendPicture<H264>
for VaapiBackend<M>
{
type Picture = VaapiPicture<M>;
type Picture = VaapiH264Picture<VaapiPicture<M>>;
}

impl<M: SurfaceMemoryDescriptor + 'static> StatelessH264DecoderBackend for VaapiBackend<M> {
Expand All @@ -482,6 +488,7 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessH264DecoderBackend for Vaapi
) -> StatelessBackendResult<()> {
let metadata = self.metadata_state.get_parsed()?;
let context = &metadata.context;
let picture = &mut picture.picture;

let surface_id = picture.surface().id();

Expand Down Expand Up @@ -510,33 +517,44 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessH264DecoderBackend for Vaapi
ref_pic_list0: &[&DpbEntry<Self::Handle>],
ref_pic_list1: &[&DpbEntry<Self::Handle>],
) -> StatelessBackendResult<()> {
build_slice_param(
&mut picture.slice_params,
picture.slice_data.len() as u32,
&slice.header,
slice.nalu.size,
ref_pic_list0,
ref_pic_list1,
sps,
pps,
)?;

picture.slice_data.extend(slice.nalu.as_ref());

Ok(())
}

fn submit_picture(
&mut self,
mut picture: Self::Picture,
) -> StatelessBackendResult<Self::Handle> {
let metadata = self.metadata_state.get_parsed()?;
let context = &metadata.context;

let slice_param = context
.create_buffer(build_slice_param(
&slice.header,
slice.nalu.size,
ref_pic_list0,
ref_pic_list1,
sps,
pps,
)?)
.create_buffer(BufferType::SliceParameter(SliceParameter::H264(
picture.slice_params,
)))
.context("while creating slice params buffer")?;

picture.add_buffer(slice_param);
picture.picture.add_buffer(slice_param);

let slice_data = context
.create_buffer(BufferType::SliceData(Vec::from(slice.nalu.as_ref())))
.create_buffer(BufferType::SliceData(picture.slice_data))
.context("while creating slice data buffer")?;

picture.add_buffer(slice_data);
picture.picture.add_buffer(slice_data);

Ok(())
}

fn submit_picture(&mut self, picture: Self::Picture) -> StatelessBackendResult<Self::Handle> {
self.process_picture::<H264>(picture)
self.process_picture::<H264>(picture.picture)
}

fn new_picture(
Expand All @@ -551,11 +569,11 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessH264DecoderBackend for Vaapi

let metadata = self.metadata_state.get_parsed()?;

Ok(VaPicture::new(
timestamp,
Rc::clone(&metadata.context),
surface,
))
Ok(VaapiH264Picture {
picture: VaPicture::new(timestamp, Rc::clone(&metadata.context), surface),
slice_params: libva::SliceParameterBufferH264::new_array(),
slice_data: Vec::new(),
})
}

fn new_field_picture(
Expand All @@ -565,9 +583,13 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessH264DecoderBackend for Vaapi
first_field: &Self::Handle,
) -> StatelessBackendResult<Self::Picture> {
// Decode to the same surface as the first field picture.
Ok(first_field
.borrow()
.new_picture_from_same_surface(timestamp))
Ok(VaapiH264Picture {
picture: first_field
.borrow()
.new_picture_from_same_surface(timestamp),
slice_params: libva::SliceParameterBufferH264::new_array(),
slice_data: Vec::new(),
})
}
}

Expand Down
Loading