diff --git a/Cargo.toml b/Cargo.toml index f5764b7..99f1e8f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/dholroyd/h264-reader" edition = "2018" [dependencies] -bitreader = "0.3.1" +bitstream-io = "1.0" memchr = "2.1.1" rfc6381-codec = "0.1" diff --git a/src/nal/sps.rs b/src/nal/sps.rs index 82349b4..7cab8ff 100644 --- a/src/nal/sps.rs +++ b/src/nal/sps.rs @@ -9,7 +9,7 @@ use crate::nal::pps::ParamSetId; use crate::nal::pps::ParamSetIdError; use std::fmt::Debug; -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub enum SpsError { /// Signals that bit_depth_luma_minus8 was greater than the max value, 6 BitDepthOutOfRange(u32), @@ -301,7 +301,7 @@ impl ScalingList { } } -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub enum ScalingMatrixError { ReaderError(RbspBitReaderError), /// The `delta_scale` field must be between -128 and 127 inclusive. @@ -393,7 +393,7 @@ impl ChromaInfo { } } -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub enum PicOrderCntError { InvalidPicOrderCountType(u32), ReaderError(RbspBitReaderError), @@ -990,7 +990,7 @@ mod test { assert!(!format!("{:?}", sps).is_empty()); assert_eq!(100, sps.profile_idc.0); assert_eq!(0, sps.constraint_flags.reserved_zero_two_bits()); - assert_eq!(Ok((64, 64)), sps.pixel_dimensions()); + assert_eq!((64, 64), sps.pixel_dimensions().unwrap()); assert!(!sps.rfc6381().to_string().is_empty()) } diff --git a/src/rbsp.rs b/src/rbsp.rs index e6b8c9e..30f87d6 100644 --- a/src/rbsp.rs +++ b/src/rbsp.rs @@ -21,8 +21,8 @@ //! yield byte sequences where the encoding is removed (i.e. the decoder will replace instances of //! the sequence `0x00 0x00 0x03` with `0x00 0x00`). +use bitstream_io::read::BitRead; use std::borrow::Cow; -use bitreader; use crate::nal::{NalHandler, NalHeader}; use crate::Context; @@ -233,30 +233,30 @@ pub fn decode_nal<'a>(nal_unit: &'a [u8]) -> Cow<'a, [u8]> { decoder.into_handler().data } -impl From for RbspBitReaderError { - fn from(e: bitreader::BitReaderError) -> Self { +impl From for RbspBitReaderError { + fn from(e: std::io::Error) -> Self { RbspBitReaderError::ReaderError(e) } } -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub enum RbspBitReaderError { - ReaderError(bitreader::BitReaderError), - ReaderErrorFor(&'static str, bitreader::BitReaderError), + ReaderError(std::io::Error), + ReaderErrorFor(&'static str, std::io::Error), /// An Exp-Golomb-coded syntax elements value has more than 32 bits. ExpGolombTooLarge(&'static str), } -pub struct RbspBitReader<'a> { +pub struct RbspBitReader<'buf> { total_size: usize, - reader: bitreader::BitReader<'a>, + reader: bitstream_io::read::BitReader, bitstream_io::BigEndian>, } -impl<'a> RbspBitReader<'a> { - pub fn new(buf: &'a[u8]) -> RbspBitReader<'a> { +impl<'buf> RbspBitReader<'buf> { + pub fn new(buf: &'buf [u8]) -> Self { RbspBitReader { total_size: buf.len() * 8, - reader: bitreader::BitReader::new(buf), + reader: bitstream_io::read::BitReader::new(std::io::Cursor::new(buf)), } } @@ -275,31 +275,33 @@ impl<'a> RbspBitReader<'a> { } pub fn read_bool(&mut self) -> Result { - self.reader.read_bool().map_err( |e| RbspBitReaderError::ReaderError(e) ) + self.reader.read_bit().map_err( |e| RbspBitReaderError::ReaderError(e) ) } pub fn read_bool_named(&mut self, name: &'static str) -> Result { - self.reader.read_bool().map_err( |e| RbspBitReaderError::ReaderErrorFor(name, e) ) + self.reader.read_bit().map_err( |e| RbspBitReaderError::ReaderErrorFor(name, e) ) } - pub fn read_u8(&mut self, bit_count: u8) -> Result { - self.reader.read_u8(bit_count).map_err( |e| RbspBitReaderError::ReaderError(e) ) + pub fn read_u8(&mut self, bit_count: u32) -> Result { + self.reader.read(u32::from(bit_count)).map_err( |e| RbspBitReaderError::ReaderError(e) ) } pub fn read_u16(&mut self, bit_count: u8) -> Result { - self.reader.read_u16(bit_count).map_err( |e| RbspBitReaderError::ReaderError(e) ) + self.reader.read(u32::from(bit_count)).map_err( |e| RbspBitReaderError::ReaderError(e) ) } pub fn read_u32(&mut self, bit_count: u8) -> Result { - self.reader.read_u32(bit_count).map_err( |e| RbspBitReaderError::ReaderError(e) ) + self.reader.read(u32::from(bit_count)).map_err( |e| RbspBitReaderError::ReaderError(e) ) } pub fn read_i32(&mut self, bit_count: u8) -> Result { - self.reader.read_i32(bit_count).map_err( |e| RbspBitReaderError::ReaderError(e) ) + self.reader.read(u32::from(bit_count)).map_err( |e| RbspBitReaderError::ReaderError(e) ) } - pub fn has_more_rbsp_data(&self) -> bool { - self.reader.position() < self.total_size as u64 + pub fn has_more_rbsp_data(&mut self) -> bool { + // BitReader returns its reader iff at an aligned position. + let total_size = self.total_size; + self.reader.reader().map(|r| r.position() < total_size as u64).unwrap_or(true) } fn golomb_to_signed(val: u32) -> i32 { @@ -307,9 +309,9 @@ impl<'a> RbspBitReader<'a> { ((val >> 1) as i32 + (val & 0x1) as i32) * sign } } -fn count_zero_bits(r: &mut bitreader::BitReader<'_>, name: &'static str) -> Result { +fn count_zero_bits(r: &mut R, name: &'static str) -> Result { let mut count = 0; - while !r.read_bool()? { + while !r.read_bit()? { count += 1; if count > 31 { return Err(RbspBitReaderError::ExpGolombTooLarge(name));