From 212e96d9a582658ecb260ca62fadaa20f76da357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Grzesik?= Date: Tue, 5 Mar 2024 15:41:19 +0100 Subject: [PATCH 1/2] decoder: h264: vaapi: Use codec specific picture This changes is necessary for the next change, that will require picture to contain copies of slices. --- src/decoder/stateless/h264/vaapi.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/decoder/stateless/h264/vaapi.rs b/src/decoder/stateless/h264/vaapi.rs index b100907c..d1ba289a 100644 --- a/src/decoder/stateless/h264/vaapi.rs +++ b/src/decoder/stateless/h264/vaapi.rs @@ -460,10 +460,14 @@ fn build_slice_param( ))) } +pub struct VaapiH264Picture { + picture: Picture, +} + impl StatelessDecoderBackendPicture for VaapiBackend { - type Picture = VaapiPicture; + type Picture = VaapiH264Picture>; } impl StatelessH264DecoderBackend for VaapiBackend { @@ -482,6 +486,7 @@ impl 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(); @@ -512,6 +517,7 @@ impl StatelessH264DecoderBackend for Vaapi ) -> StatelessBackendResult<()> { let metadata = self.metadata_state.get_parsed()?; let context = &metadata.context; + let picture = &mut picture.picture; let slice_param = context .create_buffer(build_slice_param( @@ -536,7 +542,7 @@ impl StatelessH264DecoderBackend for Vaapi } fn submit_picture(&mut self, picture: Self::Picture) -> StatelessBackendResult { - self.process_picture::(picture) + self.process_picture::(picture.picture) } fn new_picture( @@ -551,11 +557,9 @@ impl 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), + }) } fn new_field_picture( @@ -565,9 +569,11 @@ impl StatelessH264DecoderBackend for Vaapi first_field: &Self::Handle, ) -> StatelessBackendResult { // 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), + }) } } From 52e4af7ce1e53eb046ef7732dc2c776f6af2832d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Grzesik?= Date: Tue, 5 Mar 2024 16:28:39 +0100 Subject: [PATCH 2/2] decoder: h264: vaapi: Use slice arrays instead multiple buffers With this commit the #44 is fixed. It is achieved by submitting multiple slices of one picture using a single slice data buffer and all slice parameters using a single buffer with multiple elements. --- src/decoder/stateless/h264/vaapi.rs | 60 ++++++++++++++++++----------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/src/decoder/stateless/h264/vaapi.rs b/src/decoder/stateless/h264/vaapi.rs index d1ba289a..f959e9ce 100644 --- a/src/decoder/stateless/h264/vaapi.rs +++ b/src/decoder/stateless/h264/vaapi.rs @@ -347,13 +347,15 @@ fn fill_ref_pic_list( } fn build_slice_param( + params: &mut libva::SliceParameterBufferH264, + offset: u32, hdr: &SliceHeader, slice_size: usize, ref_list_0: &[&DpbEntry>], ref_list_1: &[&DpbEntry>], sps: &Sps, pps: &Pps, -) -> anyhow::Result { +) -> 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; @@ -422,9 +424,9 @@ fn build_slice_param( } } - 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, @@ -455,13 +457,13 @@ fn build_slice_param( chroma_offset_l1, ); - Ok(BufferType::SliceParameter(SliceParameter::H264( - slice_param, - ))) + Ok(()) } pub struct VaapiH264Picture { picture: Picture, + slice_params: libva::SliceParameterBufferH264, + slice_data: Vec, } impl StatelessDecoderBackendPicture @@ -515,33 +517,43 @@ impl StatelessH264DecoderBackend for Vaapi ref_pic_list0: &[&DpbEntry], ref_pic_list1: &[&DpbEntry], ) -> 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 { let metadata = self.metadata_state.get_parsed()?; let context = &metadata.context; - let picture = &mut picture.picture; 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); - - Ok(()) - } + picture.picture.add_buffer(slice_data); - fn submit_picture(&mut self, picture: Self::Picture) -> StatelessBackendResult { self.process_picture::(picture.picture) } @@ -559,6 +571,8 @@ impl StatelessH264DecoderBackend for Vaapi Ok(VaapiH264Picture { picture: VaPicture::new(timestamp, Rc::clone(&metadata.context), surface), + slice_params: libva::SliceParameterBufferH264::new_array(), + slice_data: Vec::new(), }) } @@ -573,6 +587,8 @@ impl StatelessH264DecoderBackend for Vaapi picture: first_field .borrow() .new_picture_from_same_surface(timestamp), + slice_params: libva::SliceParameterBufferH264::new_array(), + slice_data: Vec::new(), }) } }