use crate::{Mp4Parser, ParsedBox, Result, data, parser};
#[derive(Debug, Clone)]
pub struct TencBox {
pub default_kid: [u8; 16],
pub is_protected: bool,
pub per_sample_iv_size: u8,
pub crypt_byte_block: u8,
pub skip_byte_block: u8,
pub constant_iv: Option<[u8; 16]>,
}
impl TencBox {
pub fn from_init(data: &[u8]) -> Result<Option<Self>> {
let tenc_box = data!();
let tenc_box_c = tenc_box.clone();
Mp4Parser::new()
.base_box("moov", parser::children)
.base_box("trak", parser::children)
.base_box("mdia", parser::children)
.base_box("minf", parser::children)
.base_box("stbl", parser::children)
.full_box("stsd", parser::sample_description)
.base_box("encv", parser::visual_sample_entry)
.base_box("enca", parser::audio_sample_entry)
.base_box("sinf", parser::children)
.base_box("schi", parser::children)
.full_box("tenc", move |mut box_| {
*tenc_box_c.borrow_mut() = Some(Self::new(&mut box_)?);
Ok(())
})
.parse(data, true, false)?;
Ok(tenc_box.take())
}
pub fn new(box_: &mut ParsedBox) -> Result<Self> {
let reader = &mut box_.reader;
let version = box_.version.unwrap_or(0);
reader.skip(1)?;
let (crypt_byte_block, skip_byte_block) = if version == 0 {
reader.skip(1)?;
(0, 0)
} else {
let pattern = reader.read_u8()?;
((pattern >> 4) & 0x0F, pattern & 0x0F)
};
let is_protected = reader.read_u8()? != 0;
let per_sample_iv_size = reader.read_u8()?;
let kid_bytes = reader.read_bytes_u8(16)?;
let mut default_kid = [0u8; 16];
default_kid.copy_from_slice(&kid_bytes);
let mut constant_iv = None;
if per_sample_iv_size == 0 {
let constant_iv_size = reader.read_u8()?;
if constant_iv_size > 0 && constant_iv_size <= 16 {
let bytes = reader.read_bytes_u8(constant_iv_size as usize)?;
let mut iv = [0u8; 16];
iv[..bytes.len()].copy_from_slice(&bytes);
constant_iv = Some(iv);
}
}
Ok(Self {
default_kid,
is_protected,
per_sample_iv_size,
crypt_byte_block,
skip_byte_block,
constant_iv,
})
}
pub fn default_kid_hex(&self) -> String {
hex::encode(self.default_kid)
}
}