use std::io::Read;
use media_codec_bitstream::{BigEndian, BitReader};
use media_core::{invalid_data_error, Result};
use smallvec::SmallVec;
use crate::constants::{MAX_CPB_COUNT, MAX_SUB_LAYERS, MAX_VPS_COUNT, MAX_VPS_LAYERS};
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct ProfileTierLevel {
pub general_profile_space: u8,
pub general_tier_flag: bool,
pub general_profile_idc: u8,
pub general_profile_compatibility_flags: u32,
pub general_progressive_source_flag: bool,
pub general_interlaced_source_flag: bool,
pub general_non_packed_constraint_flag: bool,
pub general_frame_only_constraint_flag: bool,
pub general_constraint_indicator_flags: u64,
pub general_level_idc: u8,
pub sub_layer_profile_present_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub sub_layer_level_present_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub sub_layer_profile_space: SmallVec<[u8; MAX_SUB_LAYERS]>,
pub sub_layer_tier_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub sub_layer_profile_idc: SmallVec<[u8; MAX_SUB_LAYERS]>,
pub sub_layer_profile_compatibility_flags: SmallVec<[u32; MAX_SUB_LAYERS]>,
pub sub_layer_progressive_source_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub sub_layer_interlaced_source_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub sub_layer_non_packed_constraint_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub sub_layer_frame_only_constraint_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub sub_layer_constraint_indicator_flags: SmallVec<[u64; MAX_SUB_LAYERS]>,
pub sub_layer_level_idc: SmallVec<[u8; MAX_SUB_LAYERS]>,
}
impl ProfileTierLevel {
pub fn parse<R: Read>(reader: &mut BitReader<R, BigEndian>, profile_present_flag: bool, max_num_sub_layers: u8) -> Result<Self> {
let mut ptl = Self::default();
if profile_present_flag {
ptl.general_profile_space = reader.read::<2, u8>()?;
ptl.general_tier_flag = reader.read_bit()?;
ptl.general_profile_idc = reader.read::<5, u8>()?;
ptl.general_profile_compatibility_flags = reader.read::<32, u32>()?;
ptl.general_progressive_source_flag = reader.read_bit()?;
ptl.general_interlaced_source_flag = reader.read_bit()?;
ptl.general_non_packed_constraint_flag = reader.read_bit()?;
ptl.general_frame_only_constraint_flag = reader.read_bit()?;
let high = reader.read::<32, u64>()?;
let low = reader.read::<12, u64>()?;
ptl.general_constraint_indicator_flags = (high << 12) | low;
}
ptl.general_level_idc = reader.read::<8, u8>()?;
let sub_layer_count = (max_num_sub_layers - 1) as usize;
ptl.sub_layer_profile_present_flag.reserve(sub_layer_count);
ptl.sub_layer_level_present_flag.reserve(sub_layer_count);
for _ in 0..sub_layer_count {
ptl.sub_layer_profile_present_flag.push(reader.read_bit()?);
ptl.sub_layer_level_present_flag.push(reader.read_bit()?);
}
if max_num_sub_layers > 1 {
for _ in sub_layer_count..8 {
let _ = reader.read::<2, u8>()?; }
}
ptl.sub_layer_profile_space = smallvec::smallvec![0; sub_layer_count];
ptl.sub_layer_tier_flag = smallvec::smallvec![false; sub_layer_count];
ptl.sub_layer_profile_idc = smallvec::smallvec![0; sub_layer_count];
ptl.sub_layer_profile_compatibility_flags = smallvec::smallvec![0; sub_layer_count];
ptl.sub_layer_progressive_source_flag = smallvec::smallvec![false; sub_layer_count];
ptl.sub_layer_interlaced_source_flag = smallvec::smallvec![false; sub_layer_count];
ptl.sub_layer_non_packed_constraint_flag = smallvec::smallvec![false; sub_layer_count];
ptl.sub_layer_frame_only_constraint_flag = smallvec::smallvec![false; sub_layer_count];
ptl.sub_layer_constraint_indicator_flags = smallvec::smallvec![0; sub_layer_count];
ptl.sub_layer_level_idc = smallvec::smallvec![0; sub_layer_count];
for i in 0..sub_layer_count {
if ptl.sub_layer_profile_present_flag[i] {
ptl.sub_layer_profile_space[i] = reader.read::<2, u8>()?;
ptl.sub_layer_tier_flag[i] = reader.read_bit()?;
ptl.sub_layer_profile_idc[i] = reader.read::<5, u8>()?;
ptl.sub_layer_profile_compatibility_flags[i] = reader.read::<32, u32>()?;
ptl.sub_layer_progressive_source_flag[i] = reader.read_bit()?;
ptl.sub_layer_interlaced_source_flag[i] = reader.read_bit()?;
ptl.sub_layer_non_packed_constraint_flag[i] = reader.read_bit()?;
ptl.sub_layer_frame_only_constraint_flag[i] = reader.read_bit()?;
let high = reader.read::<32, u64>()?;
let low = reader.read::<12, u64>()?;
ptl.sub_layer_constraint_indicator_flags[i] = (high << 12) | low;
}
if ptl.sub_layer_level_present_flag[i] {
ptl.sub_layer_level_idc[i] = reader.read::<8, u8>()?;
}
}
Ok(ptl)
}
#[inline]
pub fn is_profile_compatible(&self, profile_idc: u8) -> bool {
if profile_idc < 32 {
(self.general_profile_compatibility_flags >> (31 - profile_idc)) & 1 != 0
} else {
false
}
}
#[inline]
pub fn is_main_profile(&self) -> bool {
self.general_profile_idc == 1 || self.is_profile_compatible(1)
}
#[inline]
pub fn is_main_10_profile(&self) -> bool {
self.general_profile_idc == 2 || self.is_profile_compatible(2)
}
#[inline]
pub fn is_main_still_picture_profile(&self) -> bool {
self.general_profile_idc == 3 || self.is_profile_compatible(3)
}
#[inline]
pub fn is_range_extensions_profile(&self) -> bool {
self.general_profile_idc == 4 || self.is_profile_compatible(4)
}
#[inline]
pub fn level(&self) -> f32 {
self.general_level_idc as f32 / 30.0
}
#[inline]
pub fn is_high_tier(&self) -> bool {
self.general_tier_flag
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct SubLayerHrdParameters {
pub bit_rate_value: SmallVec<[u32; MAX_CPB_COUNT]>,
pub cpb_size_value: SmallVec<[u32; MAX_CPB_COUNT]>,
pub cpb_size_du_value: SmallVec<[u32; MAX_CPB_COUNT]>,
pub bit_rate_du_value: SmallVec<[u32; MAX_CPB_COUNT]>,
pub cbr_flag: SmallVec<[bool; MAX_CPB_COUNT]>,
}
impl SubLayerHrdParameters {
pub fn parse<R: Read>(reader: &mut BitReader<R, BigEndian>, cpb_cnt: usize, sub_pic_hrd_params_present_flag: bool) -> Result<Self> {
let mut params = Self::default();
params.bit_rate_value.reserve(cpb_cnt);
params.cpb_size_value.reserve(cpb_cnt);
params.cpb_size_du_value.reserve(cpb_cnt);
params.bit_rate_du_value.reserve(cpb_cnt);
params.cbr_flag.reserve(cpb_cnt);
for _ in 0..cpb_cnt {
params.bit_rate_value.push(reader.read_ue()? + 1);
params.cpb_size_value.push(reader.read_ue()? + 1);
if sub_pic_hrd_params_present_flag {
params.cpb_size_du_value.push(reader.read_ue()? + 1);
params.bit_rate_du_value.push(reader.read_ue()? + 1);
}
params.cbr_flag.push(reader.read_bit()?);
}
Ok(params)
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct HrdParameters {
pub nal_hrd_parameters_present_flag: bool,
pub vcl_hrd_parameters_present_flag: bool,
pub sub_pic_hrd_params_present_flag: bool,
pub tick_divisor: u8,
pub du_cpb_removal_delay_increment_length: u8,
pub sub_pic_cpb_params_in_pic_timing_sei_flag: bool,
pub dpb_output_delay_du_length: u8,
pub bit_rate_scale: u8,
pub cpb_size_scale: u8,
pub cpb_size_du_scale: u8,
pub initial_cpb_removal_delay_length: u8,
pub au_cpb_removal_delay_length: u8,
pub dpb_output_delay_length: u8,
pub fixed_pic_rate_general_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub fixed_pic_rate_within_cvs_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub elemental_duration_in_tc: SmallVec<[u32; MAX_SUB_LAYERS]>,
pub low_delay_hrd_flag: SmallVec<[bool; MAX_SUB_LAYERS]>,
pub cpb_cnt: SmallVec<[u32; MAX_SUB_LAYERS]>,
pub nal_sub_layer_hrd_parameters: SmallVec<[SubLayerHrdParameters; MAX_SUB_LAYERS]>,
pub vcl_sub_layer_hrd_parameters: SmallVec<[SubLayerHrdParameters; MAX_SUB_LAYERS]>,
}
impl HrdParameters {
pub fn parse<R: Read>(reader: &mut BitReader<R, BigEndian>, common_inf_present_flag: bool, max_num_sub_layers: u8) -> Result<Self> {
let mut hrd = Self::default();
if common_inf_present_flag {
hrd.nal_hrd_parameters_present_flag = reader.read_bit()?;
hrd.vcl_hrd_parameters_present_flag = reader.read_bit()?;
if hrd.nal_hrd_parameters_present_flag || hrd.vcl_hrd_parameters_present_flag {
hrd.sub_pic_hrd_params_present_flag = reader.read_bit()?;
if hrd.sub_pic_hrd_params_present_flag {
hrd.tick_divisor = reader.read::<8, u8>()? + 2;
hrd.du_cpb_removal_delay_increment_length = reader.read::<5, u8>()? + 1;
hrd.sub_pic_cpb_params_in_pic_timing_sei_flag = reader.read_bit()?;
hrd.dpb_output_delay_du_length = reader.read::<5, u8>()? + 1;
}
hrd.bit_rate_scale = reader.read::<4, u8>()?;
hrd.cpb_size_scale = reader.read::<4, u8>()?;
if hrd.sub_pic_hrd_params_present_flag {
hrd.cpb_size_du_scale = reader.read::<4, u8>()?;
}
hrd.initial_cpb_removal_delay_length = reader.read::<5, u8>()? + 1;
hrd.au_cpb_removal_delay_length = reader.read::<5, u8>()? + 1;
hrd.dpb_output_delay_length = reader.read::<5, u8>()? + 1;
}
}
let num_sub_layers = max_num_sub_layers as usize;
hrd.fixed_pic_rate_general_flag = smallvec::smallvec![false; num_sub_layers];
hrd.fixed_pic_rate_within_cvs_flag = smallvec::smallvec![false; num_sub_layers];
hrd.elemental_duration_in_tc = smallvec::smallvec![0; num_sub_layers];
hrd.low_delay_hrd_flag = smallvec::smallvec![false; num_sub_layers];
hrd.cpb_cnt = smallvec::smallvec![0; num_sub_layers];
hrd.nal_sub_layer_hrd_parameters.reserve(num_sub_layers);
hrd.vcl_sub_layer_hrd_parameters.reserve(num_sub_layers);
for i in 0..num_sub_layers {
hrd.fixed_pic_rate_general_flag[i] = reader.read_bit()?;
if !hrd.fixed_pic_rate_general_flag[i] {
hrd.fixed_pic_rate_within_cvs_flag[i] = reader.read_bit()?;
} else {
hrd.fixed_pic_rate_within_cvs_flag[i] = true;
}
if hrd.fixed_pic_rate_within_cvs_flag[i] {
hrd.elemental_duration_in_tc[i] = reader.read_ue()? + 1;
} else {
hrd.low_delay_hrd_flag[i] = reader.read_bit()?;
}
if !hrd.low_delay_hrd_flag[i] {
hrd.cpb_cnt[i] = reader.read_ue()? + 1;
}
let cpb_cnt = hrd.cpb_cnt[i] as usize;
if hrd.nal_hrd_parameters_present_flag {
hrd.nal_sub_layer_hrd_parameters.push(SubLayerHrdParameters::parse(reader, cpb_cnt, hrd.sub_pic_hrd_params_present_flag)?);
}
if hrd.vcl_hrd_parameters_present_flag {
hrd.vcl_sub_layer_hrd_parameters.push(SubLayerHrdParameters::parse(reader, cpb_cnt, hrd.sub_pic_hrd_params_present_flag)?);
}
}
Ok(hrd)
}
#[inline]
pub fn initial_cpb_removal_delay_length(&self) -> u8 {
self.initial_cpb_removal_delay_length
}
#[inline]
pub fn au_cpb_removal_delay_length(&self) -> u8 {
self.au_cpb_removal_delay_length
}
#[inline]
pub fn dpb_output_delay_length(&self) -> u8 {
self.dpb_output_delay_length
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Vps {
pub video_parameter_set_id: u8,
pub vps_base_layer_internal_flag: bool,
pub vps_base_layer_available_flag: bool,
pub vps_max_layers: u8,
pub vps_max_sub_layers: u8,
pub vps_temporal_id_nesting_flag: bool,
pub profile_tier_level: ProfileTierLevel,
pub vps_sub_layer_ordering_info_present_flag: bool,
pub vps_max_dec_pic_buffering: SmallVec<[u32; MAX_SUB_LAYERS]>,
pub vps_max_num_reorder_pics: SmallVec<[u32; MAX_SUB_LAYERS]>,
pub vps_max_latency_increase_plus1: SmallVec<[u32; MAX_SUB_LAYERS]>,
pub vps_max_layer_id: u8,
pub vps_num_layer_sets: u32,
pub layer_id_included_flag: Vec<Vec<bool>>,
pub vps_timing_info_present_flag: bool,
pub vps_num_units_in_tick: u32,
pub vps_time_scale: u32,
pub vps_poc_proportional_to_timing_flag: bool,
pub vps_num_ticks_poc_diff_one: u32,
pub vps_num_hrd_parameters: u32,
pub hrd_layer_set_idx: Vec<u32>,
pub cprms_present_flag: Vec<bool>,
pub hrd_parameters: Vec<HrdParameters>,
pub vps_extension_flag: bool,
}
impl Vps {
pub fn parse(data: &[u8]) -> Result<Self> {
let mut reader = BitReader::new(data);
Self::parse_from_bit_reader(&mut reader)
}
pub fn parse_from_bit_reader<R: Read>(reader: &mut BitReader<R, BigEndian>) -> Result<Self> {
let vps_video_parameter_set_id = reader.read::<4, u8>()?;
if vps_video_parameter_set_id as usize >= MAX_VPS_COUNT {
return Err(invalid_data_error!("vps_video_parameter_set_id", vps_video_parameter_set_id));
}
let vps_base_layer_internal_flag = reader.read_bit()?;
let vps_base_layer_available_flag = reader.read_bit()?;
let vps_max_layers = reader.read::<6, u8>()? + 1;
if vps_max_layers as usize > MAX_VPS_LAYERS {
return Err(invalid_data_error!("vps_max_layers", vps_max_layers));
}
let vps_max_sub_layers = reader.read::<3, u8>()? + 1;
if vps_max_sub_layers as usize > MAX_SUB_LAYERS {
return Err(invalid_data_error!("vps_max_sub_layers", vps_max_sub_layers));
}
let vps_temporal_id_nesting_flag = reader.read_bit()?;
let reserved = reader.read::<16, u16>()?;
if reserved != 0xFFFF {
return Err(invalid_data_error!("reserved", reserved));
}
let profile_tier_level = ProfileTierLevel::parse(reader, true, vps_max_sub_layers)?;
let vps_sub_layer_ordering_info_present_flag = reader.read_bit()?;
let num_sub_layers = vps_max_sub_layers as usize;
let start_idx = if vps_sub_layer_ordering_info_present_flag {
0
} else {
num_sub_layers - 1
};
let mut vps_max_dec_pic_buffering = smallvec::smallvec![0u32; num_sub_layers];
let mut vps_max_num_reorder_pics = smallvec::smallvec![0u32; num_sub_layers];
let mut vps_max_latency_increase_plus1 = smallvec::smallvec![0u32; num_sub_layers];
for i in start_idx..num_sub_layers {
vps_max_dec_pic_buffering[i] = reader.read_ue()? + 1;
vps_max_num_reorder_pics[i] = reader.read_ue()?;
vps_max_latency_increase_plus1[i] = reader.read_ue()?;
}
if !vps_sub_layer_ordering_info_present_flag {
for i in 0..start_idx {
vps_max_dec_pic_buffering[i] = vps_max_dec_pic_buffering[start_idx];
vps_max_num_reorder_pics[i] = vps_max_num_reorder_pics[start_idx];
vps_max_latency_increase_plus1[i] = vps_max_latency_increase_plus1[start_idx];
}
}
let vps_max_layer_id = reader.read::<6, u8>()?;
let vps_num_layer_sets = reader.read_ue()? + 1;
let mut layer_id_included_flag = Vec::with_capacity(vps_num_layer_sets as usize);
layer_id_included_flag.push(vec![true]);
for _ in 1..vps_num_layer_sets {
let mut layer_flags = Vec::with_capacity((vps_max_layer_id + 1) as usize);
for _ in 0..=vps_max_layer_id {
layer_flags.push(reader.read_bit()?);
}
layer_id_included_flag.push(layer_flags);
}
let vps_timing_info_present_flag = reader.read_bit()?;
let mut vps_num_units_in_tick = 0;
let mut vps_time_scale = 0;
let mut vps_poc_proportional_to_timing_flag = false;
let mut vps_num_ticks_poc_diff_one = 0;
let mut vps_num_hrd_parameters = 0;
let mut hrd_layer_set_idx = Vec::new();
let mut cprms_present_flag = Vec::new();
let mut hrd_parameters = Vec::new();
if vps_timing_info_present_flag {
vps_num_units_in_tick = reader.read::<32, u32>()?;
vps_time_scale = reader.read::<32, u32>()?;
vps_poc_proportional_to_timing_flag = reader.read_bit()?;
if vps_poc_proportional_to_timing_flag {
vps_num_ticks_poc_diff_one = reader.read_ue()? + 1;
}
vps_num_hrd_parameters = reader.read_ue()?;
for i in 0..vps_num_hrd_parameters as usize {
hrd_layer_set_idx.push(reader.read_ue()?);
let cprms_flag = if i > 0 {
reader.read_bit()?
} else {
true
};
cprms_present_flag.push(cprms_flag);
hrd_parameters.push(HrdParameters::parse(reader, cprms_flag, vps_max_sub_layers)?);
}
}
let vps_extension_flag = reader.read_bit()?;
Ok(Self {
video_parameter_set_id: vps_video_parameter_set_id,
vps_base_layer_internal_flag,
vps_base_layer_available_flag,
vps_max_layers,
vps_max_sub_layers,
vps_temporal_id_nesting_flag,
profile_tier_level,
vps_sub_layer_ordering_info_present_flag,
vps_max_dec_pic_buffering,
vps_max_num_reorder_pics,
vps_max_latency_increase_plus1,
vps_max_layer_id,
vps_num_layer_sets,
layer_id_included_flag,
vps_timing_info_present_flag,
vps_num_units_in_tick,
vps_time_scale,
vps_poc_proportional_to_timing_flag,
vps_num_ticks_poc_diff_one,
vps_num_hrd_parameters,
hrd_layer_set_idx,
cprms_present_flag,
hrd_parameters,
vps_extension_flag,
})
}
#[inline]
pub fn max_layers(&self) -> u8 {
self.vps_max_layers
}
#[inline]
pub fn max_sub_layers(&self) -> u8 {
self.vps_max_sub_layers
}
#[inline]
pub fn max_dec_pic_buffering(&self, sub_layer: usize) -> Option<u32> {
self.vps_max_dec_pic_buffering.get(sub_layer).copied()
}
#[inline]
pub fn max_num_reorder_pics(&self, sub_layer: usize) -> Option<u32> {
self.vps_max_num_reorder_pics.get(sub_layer).copied()
}
pub fn frame_rate(&self) -> Option<(u32, u32)> {
if self.vps_timing_info_present_flag && self.vps_num_units_in_tick > 0 {
Some((self.vps_time_scale, self.vps_num_units_in_tick))
} else {
None
}
}
pub fn frame_rate_fps(&self) -> Option<f64> {
self.frame_rate().map(|(num, den)| num as f64 / den as f64)
}
#[inline]
pub fn num_layer_sets(&self) -> u32 {
self.vps_num_layer_sets
}
}