in mp4parse/src/lib.rs [4884:4931]
fn read_av1c<T: Read>(src: &mut BMFFBox<T>) -> Result<AV1ConfigBox> {
// We want to store the raw config as well as a structured (parsed) config, so create a copy of
// the raw config so we have it later, and then parse the structured data from that.
let raw_config = src.read_into_try_vec()?;
let mut raw_config_slice = raw_config.as_slice();
let marker_byte = raw_config_slice.read_u8()?;
if marker_byte & 0x80 != 0x80 {
return Err(Error::Unsupported("missing av1C marker bit"));
}
if marker_byte & 0x7f != 0x01 {
return Err(Error::Unsupported("missing av1C marker bit"));
}
let profile_byte = raw_config_slice.read_u8()?;
let profile = (profile_byte & 0xe0) >> 5;
let level = profile_byte & 0x1f;
let flags_byte = raw_config_slice.read_u8()?;
let tier = (flags_byte & 0x80) >> 7;
let bit_depth = match flags_byte & 0x60 {
0x60 => 12,
0x40 => 10,
_ => 8,
};
let monochrome = flags_byte & 0x10 == 0x10;
let chroma_subsampling_x = (flags_byte & 0x08) >> 3;
let chroma_subsampling_y = (flags_byte & 0x04) >> 2;
let chroma_sample_position = flags_byte & 0x03;
let delay_byte = raw_config_slice.read_u8()?;
let initial_presentation_delay_present = (delay_byte & 0x10) == 0x10;
let initial_presentation_delay_minus_one = if initial_presentation_delay_present {
delay_byte & 0x0f
} else {
0
};
Ok(AV1ConfigBox {
profile,
level,
tier,
bit_depth,
monochrome,
chroma_subsampling_x,
chroma_subsampling_y,
chroma_sample_position,
initial_presentation_delay_present,
initial_presentation_delay_minus_one,
raw_config,
})
}