Skip to content
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

rbsp module changes #81

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
lfs: true

- name: Install toolchain
uses: dtolnay/rust-toolchain@1.76.0
uses: dtolnay/rust-toolchain@1.79.0

- uses: bencherdev/bencher@main
- uses: cargo-bins/cargo-binstall@main
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

* BREAKING CHANGE: The `ParamSetId` type has been removed and replaced with separate `PicParamSetId` and
`SeqParamSetId` types, since the allowed range of values needs to be different in these two usages.
* BREAKING CHANGE: The `rbsp::ByteReader::new` constructor has been removed in favor of more explicit
`ByteReader::skipping_h264_header`, alongside the new `ByteReader::without_skip` and `ByteReader::skipping_bytes`
that are suitable for other situations or parsing H.265 streams with two-byte NAL headers.
* BREAKING CHANGE: the `rbsp::BitReaderError::ReadError` has been removed; methods consistently return
the variant `rbsp::BitReaderError::ReadErrorFor` which additionally supplies the field name.
* BREAKING CHANGE: some methods in `rbsp::BitRead` have been renamed to match the `bitstream-io` conventions.

## 0.7.0 - 2023-05-30

Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "h264-reader"
version = "0.7.1-dev"
version = "0.8.0-dev"
authors = ["David Holroyd <[email protected]>"]
license = "MIT/Apache-2.0"
description = "Reader for H264 bitstream syntax"
Expand All @@ -21,7 +21,7 @@ log = "0.4"
hex-literal = "0.4.1"
criterion = "0.5"
test-case = "3.0.0"
iai-callgrind = "0.11.0"
iai-callgrind = "0.12.3"

[[bench]]
name = "bench"
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

use std::fmt::Debug;

pub use bitstream_io;

pub mod annexb;
pub mod avcc;
pub mod nal;
Expand Down
8 changes: 4 additions & 4 deletions src/nal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ impl fmt::Debug for NalHeader {
///
/// // Reading RBSP as a bit sequence:
/// let mut r = nal.rbsp_bits();
/// assert_eq!(r.read_u8(4, "first nibble").unwrap(), 0x1);
/// assert_eq!(r.read_u8(4, "second nibble").unwrap(), 0x2);
/// assert_eq!(r.read_u32(23, "23 bits at a time").unwrap(), 0x1a_00_00);
/// assert_eq!(r.read::<u8>(4, "first nibble").unwrap(), 0x1);
/// assert_eq!(r.read::<u8>(4, "second nibble").unwrap(), 0x2);
/// assert_eq!(r.read::<u32>(23, "23 bits at a time").unwrap(), 0x1a_00_00);
/// assert!(r.has_more_rbsp_data("more left").unwrap());
/// ```
pub trait Nal {
Expand All @@ -217,7 +217,7 @@ pub trait Nal {
/// emulation-prevention-three-bytes).
#[inline]
fn rbsp_bytes(&self) -> rbsp::ByteReader<Self::BufRead> {
rbsp::ByteReader::new(self.reader())
rbsp::ByteReader::skipping_h264_header(self.reader())
}

/// Reads bits within the RBSP form.
Expand Down
4 changes: 2 additions & 2 deletions src/nal/pps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ impl SliceGroup {
let size = (1f64 + f64::from(num_slice_groups_minus1)).log2().ceil() as u32;
let mut run_length_minus1 = Vec::with_capacity(num_slice_groups_minus1 as usize + 1);
for _ in 0..pic_size_in_map_units_minus1 + 1 {
run_length_minus1.push(r.read_u32(size, "slice_group_id")?);
run_length_minus1.push(r.read(size, "slice_group_id")?);
}
Ok(run_length_minus1)
}
Expand Down Expand Up @@ -271,7 +271,7 @@ impl PicParameterSet {
"num_ref_idx_l1_default_active_minus1",
)?,
weighted_pred_flag: r.read_bool("weighted_pred_flag")?,
weighted_bipred_idc: r.read_u8(2, "weighted_bipred_idc")?,
weighted_bipred_idc: r.read(2, "weighted_bipred_idc")?,
pic_init_qp_minus26: r.read_se("pic_init_qp_minus26")?,
pic_init_qs_minus26: r.read_se("pic_init_qs_minus26")?,
chroma_qp_index_offset: r.read_se("chroma_qp_index_offset")?,
Expand Down
5 changes: 2 additions & 3 deletions src/nal/sei/buffering_period.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ fn read_cpb_removal_delay_list<R: BitRead>(
let mut res = vec![];
for _ in 0..count {
res.push(InitialCpbRemoval {
initial_cpb_removal_delay: r.read_u32(length, "initial_cpb_removal_delay")?,
initial_cpb_removal_delay_offset: r
.read_u32(length, "initial_cpb_removal_delay_offset")?,
initial_cpb_removal_delay: r.read(length, "initial_cpb_removal_delay")?,
initial_cpb_removal_delay_offset: r.read(length, "initial_cpb_removal_delay_offset")?,
});
}
Ok(res)
Expand Down
26 changes: 13 additions & 13 deletions src/nal/sei/pic_timing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,25 +171,25 @@ impl ClockTimestamp {
r: &mut R,
sps: &sps::SeqParameterSet,
) -> Result<ClockTimestamp, PicTimingError> {
let ct_type = CtType::from_id(r.read_u8(2, "ct_type")?);
let ct_type = CtType::from_id(r.read(2, "ct_type")?);
let nuit_field_based_flag = r.read_bool("nuit_field_based_flag")?;
let counting_type = CountingType::from_id(r.read_u8(5, "counting_type")?);
let counting_type = CountingType::from_id(r.read(5, "counting_type")?);
let full_timestamp_flag = r.read_bool("full_timestamp_flag")?;
let discontinuity_flag = r.read_bool("discontinuity_flag")?;
let cnt_dropped_flag = r.read_bool("cnt_dropped_flag")?;
let n_frames = r.read_u8(8, "n_frames")?;
let n_frames = r.read(8, "n_frames")?;
let smh = if full_timestamp_flag {
SecMinHour::SMH(
r.read_u8(6, "seconds_value")?,
r.read_u8(6, "minutes_value")?,
r.read_u8(5, "hours_value")?,
r.read(6, "seconds_value")?,
r.read(6, "minutes_value")?,
r.read(5, "hours_value")?,
)
} else if r.read_bool("seconds_flag")? {
let seconds = r.read_u8(6, "seconds_value")?;
let seconds = r.read(6, "seconds_value")?;
if r.read_bool("minutes_flag")? {
let minutes = r.read_u8(6, "minutes_value")?;
let minutes = r.read(6, "minutes_value")?;
if r.read_bool("hours_flag")? {
let hours = r.read_u8(5, "hours_value")?;
let hours = r.read(5, "hours_value")?;
SecMinHour::SMH(seconds, minutes, hours)
} else {
SecMinHour::SM(seconds, minutes)
Expand All @@ -214,7 +214,7 @@ impl ClockTimestamp {
let time_offset = if time_offset_length == 0 {
None
} else {
Some(r.read_i32(u32::from(time_offset_length), "time_offset_length")?)
Some(r.read(u32::from(time_offset_length), "time_offset_length")?)
};
Ok(ClockTimestamp {
ct_type,
Expand Down Expand Up @@ -269,11 +269,11 @@ impl PicTiming {
.or_else(|| vui_params.nal_hrd_parameters.as_ref())
{
Some(Delays {
cpb_removal_delay: r.read_u32(
cpb_removal_delay: r.read(
u32::from(hrd.cpb_removal_delay_length_minus1) + 1,
"cpb_removal_delay",
)?,
dpb_output_delay: r.read_u32(
dpb_output_delay: r.read(
u32::from(hrd.dpb_output_delay_length_minus1) + 1,
"dpb_output_delay",
)?,
Expand All @@ -292,7 +292,7 @@ impl PicTiming {
) -> Result<Option<PicStruct>, PicTimingError> {
Ok(if let Some(ref vui_params) = sps.vui_parameters {
if vui_params.pic_struct_present_flag {
let pic_struct = PicStructType::from_id(r.read_u8(4, "pic_struct")?)?;
let pic_struct = PicStructType::from_id(r.read(4, "pic_struct")?)?;
let clock_timestamps = Self::read_clock_timestamps(r, &pic_struct, sps)?;

Some(PicStruct {
Expand Down
6 changes: 3 additions & 3 deletions src/nal/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,11 +453,11 @@ impl SliceHeader {
SliceHeaderError::UndefinedSeqParamSetId(pps.seq_parameter_set_id),
)?;
let colour_plane = if sps.chroma_info.separate_colour_plane_flag {
Some(ColourPlane::from_id(r.read_u8(2, "colour_plane_id")?)?)
Some(ColourPlane::from_id(r.read(2, "colour_plane_id")?)?)
} else {
None
};
let frame_num = r.read_u16(u32::from(sps.log2_max_frame_num()), "frame_num")?;
let frame_num = r.read(u32::from(sps.log2_max_frame_num()), "frame_num")?;
let field_pic = if let sps::FrameMbsFlags::Fields { .. } = sps.frame_mbs_flags {
if r.read_bool("field_pic_flag")? {
if r.read_bool("bottom_field_flag")? {
Expand All @@ -481,7 +481,7 @@ impl SliceHeader {
sps::PicOrderCntType::TypeZero {
log2_max_pic_order_cnt_lsb_minus4,
} => {
let pic_order_cnt_lsb = r.read_u32(
let pic_order_cnt_lsb = r.read(
u32::from(log2_max_pic_order_cnt_lsb_minus4) + 4,
"pic_order_cnt_lsb",
)?;
Expand Down
39 changes: 19 additions & 20 deletions src/nal/sps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ impl AspectRatioInfo {
fn read<R: BitRead>(r: &mut R) -> Result<Option<AspectRatioInfo>, BitReaderError> {
let aspect_ratio_info_present_flag = r.read_bool("aspect_ratio_info_present_flag")?;
Ok(if aspect_ratio_info_present_flag {
let aspect_ratio_idc = r.read_u8(8, "aspect_ratio_idc")?;
let aspect_ratio_idc = r.read(8, "aspect_ratio_idc")?;
Some(match aspect_ratio_idc {
0 => AspectRatioInfo::Unspecified,
1 => AspectRatioInfo::Ratio1_1,
Expand All @@ -564,10 +564,9 @@ impl AspectRatioInfo {
14 => AspectRatioInfo::Ratio4_3,
15 => AspectRatioInfo::Ratio3_2,
16 => AspectRatioInfo::Ratio2_1,
255 => AspectRatioInfo::Extended(
r.read_u16(16, "sar_width")?,
r.read_u16(16, "sar_height")?,
),
255 => {
AspectRatioInfo::Extended(r.read(16, "sar_width")?, r.read(16, "sar_height")?)
}
_ => AspectRatioInfo::Reserved(aspect_ratio_idc),
})
} else {
Expand Down Expand Up @@ -670,9 +669,9 @@ impl ColourDescription {
let colour_description_present_flag = r.read_bool("colour_description_present_flag")?;
Ok(if colour_description_present_flag {
Some(ColourDescription {
colour_primaries: r.read_u8(8, "colour_primaries")?,
transfer_characteristics: r.read_u8(8, "transfer_characteristics")?,
matrix_coefficients: r.read_u8(8, "matrix_coefficients")?,
colour_primaries: r.read(8, "colour_primaries")?,
transfer_characteristics: r.read(8, "transfer_characteristics")?,
matrix_coefficients: r.read(8, "matrix_coefficients")?,
})
} else {
None
Expand All @@ -691,7 +690,7 @@ impl VideoSignalType {
let video_signal_type_present_flag = r.read_bool("video_signal_type_present_flag")?;
Ok(if video_signal_type_present_flag {
Some(VideoSignalType {
video_format: VideoFormat::from(r.read_u8(3, "video_format")?),
video_format: VideoFormat::from(r.read(3, "video_format")?),
video_full_range_flag: r.read_bool("video_full_range_flag")?,
colour_description: ColourDescription::read(r)?,
})
Expand Down Expand Up @@ -732,8 +731,8 @@ impl TimingInfo {
let timing_info_present_flag = r.read_bool("timing_info_present_flag")?;
Ok(if timing_info_present_flag {
Some(TimingInfo {
num_units_in_tick: r.read_u32(32, "num_units_in_tick")?,
time_scale: r.read_u32(32, "time_scale")?,
num_units_in_tick: r.read(32, "num_units_in_tick")?,
time_scale: r.read(32, "time_scale")?,
fixed_frame_rate_flag: r.read_bool("fixed_frame_rate_flag")?,
})
} else {
Expand Down Expand Up @@ -782,14 +781,14 @@ impl HrdParameters {
}
let cpb_cnt = cpb_cnt_minus1 + 1;
Some(HrdParameters {
bit_rate_scale: r.read_u8(4, "bit_rate_scale")?,
cpb_size_scale: r.read_u8(4, "cpb_size_scale")?,
bit_rate_scale: r.read(4, "bit_rate_scale")?,
cpb_size_scale: r.read(4, "cpb_size_scale")?,
cpb_specs: Self::read_cpb_specs(r, cpb_cnt)?,
initial_cpb_removal_delay_length_minus1: r
.read_u8(5, "initial_cpb_removal_delay_length_minus1")?,
cpb_removal_delay_length_minus1: r.read_u8(5, "cpb_removal_delay_length_minus1")?,
dpb_output_delay_length_minus1: r.read_u8(5, "dpb_output_delay_length_minus1")?,
time_offset_length: r.read_u8(5, "time_offset_length")?,
.read(5, "initial_cpb_removal_delay_length_minus1")?,
cpb_removal_delay_length_minus1: r.read(5, "cpb_removal_delay_length_minus1")?,
dpb_output_delay_length_minus1: r.read(5, "dpb_output_delay_length_minus1")?,
time_offset_length: r.read(5, "time_offset_length")?,
})
} else {
None
Expand Down Expand Up @@ -894,11 +893,11 @@ pub struct SeqParameterSet {
}
impl SeqParameterSet {
pub fn from_bits<R: BitRead>(mut r: R) -> Result<SeqParameterSet, SpsError> {
let profile_idc = r.read_u8(8, "profile_idc")?.into();
let profile_idc = r.read::<u8>(8, "profile_idc")?.into();
let sps = SeqParameterSet {
profile_idc,
constraint_flags: r.read_u8(8, "constraint_flags")?.into(),
level_idc: r.read_u8(8, "level_idc")?,
constraint_flags: r.read::<u8>(8, "constraint_flags")?.into(),
level_idc: r.read(8, "level_idc")?,
seq_parameter_set_id: SeqParamSetId::from_u32(r.read_ue("seq_parameter_set_id")?)
.map_err(SpsError::BadSeqParamSetId)?,
chroma_info: ChromaInfo::read(&mut r, profile_idc)?,
Expand Down
Loading