From 93839abd64a4c725e0194a790ffd743dd8c19916 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 14 Jun 2023 18:47:18 +0200 Subject: [PATCH] h264: make some structures shareable This is a preparation work for an upcoming multi-threaded decoding. --- nihav-itu/src/codecs/h264/decoder_st.rs | 14 ++++++++------ nihav-itu/src/codecs/h264/pic_ref.rs | 3 ++- nihav-itu/src/codecs/h264/sets.rs | 6 ++++-- nihav-itu/src/codecs/h264/slice.rs | 4 +++- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/nihav-itu/src/codecs/h264/decoder_st.rs b/nihav-itu/src/codecs/h264/decoder_st.rs index 3cffc6a..63815f8 100644 --- a/nihav-itu/src/codecs/h264/decoder_st.rs +++ b/nihav-itu/src/codecs/h264/decoder_st.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use nihav_core::codecs::*; use nihav_core::io::bitreader::*; @@ -9,9 +11,9 @@ struct H264Decoder { height: usize, num_mbs: usize, nal_len: u8, - sps: Vec, + sps: Vec>, cur_sps: usize, - pps: Vec, + pps: Vec>, cur_pps: usize, skip_mode: FrameSkipMode, @@ -104,7 +106,7 @@ impl H264Decoder { let mut br = BitReader::new(&src[..(full_size + 7)/8], BitReaderMode::BE); br.skip(8)?; - let slice_hdr = parse_slice_header(&mut br, &self.sps, &self.pps, is_idr, nal_ref_idc)?; + let slice_hdr = parse_slice_header(&mut br, self.sps.as_slice(), self.pps.as_slice(), is_idr, nal_ref_idc)?; validate!(br.tell() < full_size); let full_id; if slice_hdr.first_mb_in_slice == 0 { @@ -206,7 +208,7 @@ println!("PAFF?"); cur_mb: 0, is_ref: nal_ref_idc != 0, long_term: get_long_term_id(is_idr, &slice_hdr), - mv_info: FrameMV::new(sps.pic_width_in_mbs, sps.pic_height_in_mbs), + mv_info: NABufferRef::new(FrameMV::new(sps.pic_width_in_mbs, sps.pic_height_in_mbs)), }); } @@ -245,7 +247,7 @@ println!("PAFF?"); 6 => {}, //SEI 7 => { let sps = parse_sps(&src[1..])?; - self.sps.push(sps); + self.sps.push(Arc::new(sps)); }, 8 => { validate!(full_size >= 8 + 16); @@ -253,7 +255,7 @@ println!("PAFF?"); let mut found = false; for stored_pps in self.pps.iter_mut() { if stored_pps.pic_parameter_set_id == pps.pic_parameter_set_id { - *stored_pps = pps.clone(); + *stored_pps = Arc::clone(&pps); found = true; break; } diff --git a/nihav-itu/src/codecs/h264/pic_ref.rs b/nihav-itu/src/codecs/h264/pic_ref.rs index bf838be..fd2ae97 100644 --- a/nihav-itu/src/codecs/h264/pic_ref.rs +++ b/nihav-itu/src/codecs/h264/pic_ref.rs @@ -1,5 +1,6 @@ use nihav_core::codecs::DecoderResult; use nihav_core::frame::{FrameType, NAVideoBufferRef}; +use nihav_core::refs::*; use nihav_codec_support::codecs::MV; use super::sets::SeqParameterSet; use super::slice::*; @@ -15,7 +16,7 @@ pub struct PictureInfo { pub is_ref: bool, pub long_term: Option, - pub mv_info: FrameMV, //todo replace with refcounted index to a pool + pub mv_info: NABufferRef, } #[derive(Clone,Copy,Default, Debug)] diff --git a/nihav-itu/src/codecs/h264/sets.rs b/nihav-itu/src/codecs/h264/sets.rs index 61cf0a8..2d879bd 100644 --- a/nihav-itu/src/codecs/h264/sets.rs +++ b/nihav-itu/src/codecs/h264/sets.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use nihav_core::codecs::{DecoderResult, DecoderError}; use nihav_core::io::bitreader::*; @@ -303,7 +305,7 @@ pub struct PicParameterSet { pub second_chroma_qp_index_offset: i8, } -pub fn parse_pps(src: &[u8], sps_arr: &[SeqParameterSet], full_size: usize) -> DecoderResult { +pub fn parse_pps(src: &[u8], sps_arr: &[Arc], full_size: usize) -> DecoderResult> { let mut br = BitReader::new(src, BitReaderMode::BE); let mut pps: PicParameterSet = unsafe { std::mem::zeroed() }; @@ -417,5 +419,5 @@ println!("slice mode!"); pps.second_chroma_qp_index_offset = pps.chroma_qp_index_offset; } - Ok(pps) + Ok(Arc::new(pps)) } diff --git a/nihav-itu/src/codecs/h264/slice.rs b/nihav-itu/src/codecs/h264/slice.rs index e5a72ad..ad1d244 100644 --- a/nihav-itu/src/codecs/h264/slice.rs +++ b/nihav-itu/src/codecs/h264/slice.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use nihav_core::codecs::{DecoderResult, DecoderError}; use nihav_core::frame::FrameType; use nihav_core::io::bitreader::*; @@ -154,7 +156,7 @@ pub fn parse_slice_header_minimal(br: &mut BitReader) -> DecoderResult<(usize, S #[allow(clippy::cognitive_complexity)] #[allow(clippy::manual_range_contains)] -pub fn parse_slice_header(br: &mut BitReader, sps_arr: &[SeqParameterSet], pps_arr: &[PicParameterSet], is_idr: bool, nal_ref_idc: u8) -> DecoderResult { +pub fn parse_slice_header(br: &mut BitReader, sps_arr: &[Arc], pps_arr: &[Arc], is_idr: bool, nal_ref_idc: u8) -> DecoderResult { let mut hdr: SliceHeader = unsafe { std::mem::zeroed() }; hdr.first_mb_in_slice = br.read_ue()? as usize; -- 2.30.2