Skip to content
Merged
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
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hevc_parser"
version = "0.6.8"
version = "0.6.9"
authors = ["quietvoid"]
edition = "2024"
rust-version = "1.85.0"
Expand All @@ -10,12 +10,12 @@ repository = "https://github.com/quietvoid/hevc_parser"

[dependencies]
nom = "8.0.0"
bitvec_helpers = { version = "3.1.6", default-features = false, features = ["bitstream-io"] }
anyhow = "1.0.96"
bitvec_helpers = { version = "4.0.0", default-features = false, features = ["bitstream-io"] }
anyhow = "1.0.98"
regex = { version = "1.11.1", optional = true }

# Matroska support
matroska-demuxer = { version = "0.6.0", optional = true }
matroska-demuxer = { version = "0.7.0", optional = true }

[features]
hevc_io = ["dep:regex", "dep:matroska-demuxer"]
34 changes: 17 additions & 17 deletions src/hevc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,36 @@ pub struct HEVCDecoderConfigurationRecord {
impl HEVCDecoderConfigurationRecord {
pub fn parse(bs: &mut BsIoSliceReader) -> Result<Self> {
let mut config = HEVCDecoderConfigurationRecord {
configuration_version: bs.get_n(8)?,
general_profile_space: bs.get_n(2)?,
general_tier_flag: bs.get()?,
general_profile_idc: bs.get_n(5)?,
general_profile_compatibility_flags: bs.get_n(32)?,
general_constraint_indicator_flags: bs.get_n(48)?,
general_level_idc: bs.get_n(8)?,
configuration_version: bs.read::<8, u8>()?,
general_profile_space: bs.read::<2, u8>()?,
general_tier_flag: bs.read_bit()?,
general_profile_idc: bs.read::<5, u8>()?,
general_profile_compatibility_flags: bs.read::<32, u32>()?,
general_constraint_indicator_flags: bs.read::<48, u64>()?,
general_level_idc: bs.read::<8, u8>()?,
..Default::default()
};

bs.skip_n(4)?; // reserved 4bits
config.min_spatial_segmentation_idc = bs.get_n(12)?;
config.min_spatial_segmentation_idc = bs.read::<12, u16>()?;

bs.skip_n(6)?; // reserved 6 bits
config.parallelism_type = bs.get_n(2)?;
config.parallelism_type = bs.read::<2, u8>()?;

bs.skip_n(6)?; // reserved 6 bits
config.chroma_format_idc = bs.get_n(2)?;
config.chroma_format_idc = bs.read::<2, u8>()?;

bs.skip_n(5)?; // reserved 5 bits
config.bit_depth_luma_minus8 = bs.get_n(3)?;
config.bit_depth_luma_minus8 = bs.read::<3, u8>()?;

bs.skip_n(5)?; // reserved 5 bits
config.bit_depth_chroma_minus8 = bs.get_n(3)?;
config.bit_depth_chroma_minus8 = bs.read::<3, u8>()?;

config.avg_frame_rate = bs.get_n(16)?;
config.constant_frame_rate = bs.get_n(2)?;
config.num_temporal_layers = bs.get_n(3)?;
config.temporal_id_nested = bs.get()?;
config.length_size_minus_one = bs.get_n(2)?;
config.avg_frame_rate = bs.read::<16, u16>()?;
config.constant_frame_rate = bs.read::<2, u8>()?;
config.num_temporal_layers = bs.read::<3, u8>()?;
config.temporal_id_nested = bs.read_bit()?;
config.length_size_minus_one = bs.read::<2, u8>()?;

Ok(config)
}
Expand Down
24 changes: 12 additions & 12 deletions src/hevc/hrd_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ impl HrdParameters {
let mut subpic_params_present = false;

if common_inf_present {
nal_params_present = bs.get()?;
vcl_params_present = bs.get()?;
nal_params_present = bs.read_bit()?;
vcl_params_present = bs.read_bit()?;

if nal_params_present || vcl_params_present {
subpic_params_present = bs.get()?;
subpic_params_present = bs.read_bit()?;

if subpic_params_present {
bs.skip_n(8)?; // tick_divisor_minus2
Expand All @@ -46,20 +46,20 @@ impl HrdParameters {
for _ in 0..vps_max_sub_layers {
let mut low_delay = false;
let mut nb_cpb = 1;
let mut fixed_rate = bs.get()?;
let mut fixed_rate = bs.read_bit()?;

if !fixed_rate {
fixed_rate = bs.get()?;
fixed_rate = bs.read_bit()?;
}

if fixed_rate {
bs.get_ue()?;
bs.read_ue()?;
} else {
low_delay = bs.get()?;
low_delay = bs.read_bit()?;
}

if !low_delay {
nb_cpb = bs.get_ue()? + 1;
nb_cpb = bs.read_ue()? + 1;
}

if nal_params_present {
Expand All @@ -78,12 +78,12 @@ impl HrdParameters {
impl SubLayerHrdParameter {
pub fn parse(bs: &mut BsIoVecReader, nb_cpb: u64, subpic_params_present: bool) -> Result<()> {
for _ in 0..nb_cpb {
bs.get_ue()?; // bit_rate_value_minus1
bs.get_ue()?; // cpb_size_value_minus1
bs.read_ue()?; // bit_rate_value_minus1
bs.read_ue()?; // cpb_size_value_minus1

if subpic_params_present {
bs.get_ue()?; // cpb_size_du_value_minus1
bs.get_ue()?; // bit_rate_du_value_minus1
bs.read_ue()?; // cpb_size_du_value_minus1
bs.read_ue()?; // bit_rate_du_value_minus1
}

bs.skip_n(1)?; // cbr_flag
Expand Down
78 changes: 39 additions & 39 deletions src/hevc/pps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,82 +54,82 @@ pub struct PPSNAL {
impl PPSNAL {
pub fn parse(bs: &mut BsIoVecReader) -> Result<PPSNAL> {
let mut pps = PPSNAL {
pps_id: bs.get_ue()?,
sps_id: bs.get_ue()?,
pps_id: bs.read_ue()?,
sps_id: bs.read_ue()?,
..Default::default()
};

pps.dependent_slice_segments_enabled_flag = bs.get()?;
pps.output_flag_present_flag = bs.get()?;
pps.num_extra_slice_header_bits = bs.get_n(3)?;
pps.sign_data_hiding_flag = bs.get()?;
pps.cabac_init_present_flag = bs.get()?;
pps.num_ref_idx_l0_default_active = bs.get_ue()? + 1;
pps.num_ref_idx_l1_default_active = bs.get_ue()? + 1;
pps.pic_init_qp_minus26 = bs.get_se()?;
pps.constrained_intra_pred_flag = bs.get()?;
pps.transform_skip_enabled_flag = bs.get()?;
pps.cu_qp_delta_enabled_flag = bs.get()?;
pps.dependent_slice_segments_enabled_flag = bs.read_bit()?;
pps.output_flag_present_flag = bs.read_bit()?;
pps.num_extra_slice_header_bits = bs.read::<3, u8>()?;
pps.sign_data_hiding_flag = bs.read_bit()?;
pps.cabac_init_present_flag = bs.read_bit()?;
pps.num_ref_idx_l0_default_active = bs.read_ue()? + 1;
pps.num_ref_idx_l1_default_active = bs.read_ue()? + 1;
pps.pic_init_qp_minus26 = bs.read_se()?;
pps.constrained_intra_pred_flag = bs.read_bit()?;
pps.transform_skip_enabled_flag = bs.read_bit()?;
pps.cu_qp_delta_enabled_flag = bs.read_bit()?;

pps.diff_cu_qp_delta_depth = if pps.cu_qp_delta_enabled_flag {
bs.get_ue()?
bs.read_ue()?
} else {
0
};

pps.cb_qp_offset = bs.get_se()?;
pps.cr_qp_offset = bs.get_se()?;
pps.cb_qp_offset = bs.read_se()?;
pps.cr_qp_offset = bs.read_se()?;

pps.pic_slice_level_chroma_qp_offsets_present_flag = bs.get()?;
pps.weighted_pred_flag = bs.get()?;
pps.weighted_bipred_flag = bs.get()?;
pps.pic_slice_level_chroma_qp_offsets_present_flag = bs.read_bit()?;
pps.weighted_pred_flag = bs.read_bit()?;
pps.weighted_bipred_flag = bs.read_bit()?;

pps.transquant_bypass_enable_flag = bs.get()?;
pps.tiles_enabled_flag = bs.get()?;
pps.entropy_coding_sync_enabled_flag = bs.get()?;
pps.transquant_bypass_enable_flag = bs.read_bit()?;
pps.tiles_enabled_flag = bs.read_bit()?;
pps.entropy_coding_sync_enabled_flag = bs.read_bit()?;

if pps.tiles_enabled_flag {
pps.num_tile_columns = bs.get_ue()? + 1;
pps.num_tile_rows = bs.get_ue()? + 1;
pps.num_tile_columns = bs.read_ue()? + 1;
pps.num_tile_rows = bs.read_ue()? + 1;

pps.uniform_spacing_flag = bs.get()?;
pps.uniform_spacing_flag = bs.read_bit()?;

if !pps.uniform_spacing_flag {
for _ in 0..pps.num_tile_columns - 1 {
pps.column_widths.push(bs.get_ue()? + 1);
pps.column_widths.push(bs.read_ue()? + 1);
}

for _ in 0..pps.num_tile_rows - 1 {
pps.row_heights.push(bs.get_ue()? + 1);
pps.row_heights.push(bs.read_ue()? + 1);
}
}

pps.loop_filter_across_tiles_enabled_flag = bs.get()?;
pps.loop_filter_across_tiles_enabled_flag = bs.read_bit()?;
}

pps.seq_loop_filter_across_slices_enabled_flag = bs.get()?;
pps.deblocking_filter_control_present_flag = bs.get()?;
pps.seq_loop_filter_across_slices_enabled_flag = bs.read_bit()?;
pps.deblocking_filter_control_present_flag = bs.read_bit()?;

if pps.deblocking_filter_control_present_flag {
pps.deblocking_filter_override_enabled_flag = bs.get()?;
pps.disable_dbf = bs.get()?;
pps.deblocking_filter_override_enabled_flag = bs.read_bit()?;
pps.disable_dbf = bs.read_bit()?;

if !pps.disable_dbf {
pps.beta_offset = 2 * bs.get_se()?;
pps.tc_offset = 2 * bs.get_se()?;
pps.beta_offset = 2 * bs.read_se()?;
pps.tc_offset = 2 * bs.read_se()?;
}
}

pps.scaling_list_data_present_flag = bs.get()?;
pps.scaling_list_data_present_flag = bs.read_bit()?;
if pps.scaling_list_data_present_flag {
pps.scaling_list_data = ScalingListData::parse(bs)?;
}

pps.lists_modification_present_flag = bs.get()?;
pps.log2_parallel_merge_level = bs.get_ue()? + 2;
pps.lists_modification_present_flag = bs.read_bit()?;
pps.log2_parallel_merge_level = bs.read_ue()? + 2;

pps.slice_header_extension_present_flag = bs.get()?;
pps.pps_extension_present_flag = bs.get()?;
pps.slice_header_extension_present_flag = bs.read_bit()?;
pps.pps_extension_present_flag = bs.read_bit()?;

Ok(pps)
}
Expand Down
43 changes: 23 additions & 20 deletions src/hevc/profile_tier_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,26 @@ pub struct ProfileTierLevel {

impl ProfileTierLevel {
pub fn parse(&mut self, bs: &mut BsIoVecReader, max_sub_layers: u8) -> Result<()> {
self.general_profile_space = bs.get_n(2)?;
self.general_tier_flag = bs.get()?;
self.general_profile_idc = bs.get_n(5)?;
self.general_profile_space = bs.read::<2, u8>()?;
self.general_tier_flag = bs.read_bit()?;
self.general_profile_idc = bs.read::<5, u8>()?;

for _ in 0..32 {
self.general_profile_compatibility_flag.push(bs.get()?);
self.general_profile_compatibility_flag.push(bs.read_bit()?);
}

self.general_progressive_source_flag = bs.get()?;
self.general_interlaced_source_flag = bs.get()?;
self.general_non_packed_constraint_flag = bs.get()?;
self.general_frame_only_constraint_flag = bs.get()?;
self.general_progressive_source_flag = bs.read_bit()?;
self.general_interlaced_source_flag = bs.read_bit()?;
self.general_non_packed_constraint_flag = bs.read_bit()?;
self.general_frame_only_constraint_flag = bs.read_bit()?;
bs.skip_n(32)?;
bs.skip_n(12)?;
self.general_level_idc = bs.get_n(8)?;
self.general_level_idc = bs.read::<8, u8>()?;

let max_sub_layers_minus1 = max_sub_layers - 1;
for _ in 0..max_sub_layers_minus1 {
self.sub_layer_profile_present_flag.push(bs.get()?);
self.sub_layer_level_present_flag.push(bs.get()?);
self.sub_layer_profile_present_flag.push(bs.read_bit()?);
self.sub_layer_level_present_flag.push(bs.read_bit()?);
}

if max_sub_layers_minus1 > 0 {
Expand All @@ -58,25 +58,28 @@ impl ProfileTierLevel {

for i in 0..max_sub_layers_minus1 as usize {
if self.sub_layer_profile_present_flag[i] {
self.sub_layer_profile_space.push(bs.get_n(2)?);
self.sub_layer_tier_flag.push(bs.get()?);
self.sub_layer_profile_idc.push(bs.get_n(5)?);
self.sub_layer_profile_space.push(bs.read::<2, u8>()?);
self.sub_layer_tier_flag.push(bs.read_bit()?);
self.sub_layer_profile_idc.push(bs.read::<5, u8>()?);

for _ in 0..32 {
self.sub_layer_profile_compatibility_flag.push(bs.get()?);
self.sub_layer_profile_compatibility_flag
.push(bs.read_bit()?);
}

self.sub_layer_progressive_source_flag.push(bs.get()?);
self.sub_layer_interlaced_source_flag.push(bs.get()?);
self.sub_layer_non_packed_constraint_flag.push(bs.get()?);
self.sub_layer_frame_only_constraint_flag.push(bs.get()?);
self.sub_layer_progressive_source_flag.push(bs.read_bit()?);
self.sub_layer_interlaced_source_flag.push(bs.read_bit()?);
self.sub_layer_non_packed_constraint_flag
.push(bs.read_bit()?);
self.sub_layer_frame_only_constraint_flag
.push(bs.read_bit()?);

bs.skip_n(32)?;
bs.skip_n(12)?;
}

if self.sub_layer_level_present_flag[i] {
self.sub_layer_level_idc.push(bs.get_n(8)?);
self.sub_layer_level_idc.push(bs.read::<8, u8>()?);
} else {
self.sub_layer_level_idc.push(1);
}
Expand Down
8 changes: 4 additions & 4 deletions src/hevc/scaling_list_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,22 @@ impl ScalingListData {
}

for matrix_id in 0..matrix_size {
scl.scaling_list_pred_mode_flag[size_id][matrix_id] = bs.get()?;
scl.scaling_list_pred_mode_flag[size_id][matrix_id] = bs.read_bit()?;

if !scl.scaling_list_pred_mode_flag[size_id][matrix_id] {
scl.scaling_list_pred_matrix_id_delta[size_id][matrix_id] = bs.get_ue()?;
scl.scaling_list_pred_matrix_id_delta[size_id][matrix_id] = bs.read_ue()?;
} else {
let _next_coef = 8;
let coef_num = min(64, 1 << (4 + (size_id << 1)));

if size_id > 1 {
scl.scaling_list_dc_coef_minus8[size_id - 2][matrix_id] = bs.get_se()?;
scl.scaling_list_dc_coef_minus8[size_id - 2][matrix_id] = bs.read_se()?;
}

scl.scaling_list_delta_coef[size_id][matrix_id].resize(coef_num, 0);

for i in 0..coef_num {
scl.scaling_list_delta_coef[size_id][matrix_id][i] = bs.get_se()?;
scl.scaling_list_delta_coef[size_id][matrix_id][i] = bs.read_se()?;
}
}
}
Expand Down
Loading