diff --git a/src/decoder/stateless/h264/vaapi.rs b/src/decoder/stateless/h264/vaapi.rs index b100907c..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,15 +457,19 @@ 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 for VaapiBackend { - type Picture = VaapiPicture; + type Picture = VaapiH264Picture>; } impl StatelessH264DecoderBackend for VaapiBackend { @@ -482,6 +488,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(); @@ -510,33 +517,44 @@ 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 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.process_picture::(picture) + self.process_picture::(picture.picture) } fn new_picture( @@ -551,11 +569,11 @@ 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), + slice_params: libva::SliceParameterBufferH264::new_array(), + slice_data: Vec::new(), + }) } fn new_field_picture( @@ -565,9 +583,13 @@ 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), + slice_params: libva::SliceParameterBufferH264::new_array(), + slice_data: Vec::new(), + }) } }