1use crate::{Mp4Parser, ParsedBox, Result, data, parser};
2
3#[derive(Debug, Clone)]
8pub struct TencBox {
9 pub default_kid: [u8; 16],
11 pub is_protected: bool,
13 pub per_sample_iv_size: u8,
15 pub crypt_byte_block: u8,
18 pub skip_byte_block: u8,
21 pub constant_iv: Option<[u8; 16]>,
23}
24
25impl TencBox {
26 pub fn from_init(data: &[u8]) -> Result<Option<Self>> {
31 let tenc_box = data!();
32 let tenc_box_c = tenc_box.clone();
33
34 Mp4Parser::new()
35 .base_box("moov", parser::children)
36 .base_box("trak", parser::children)
37 .base_box("mdia", parser::children)
38 .base_box("minf", parser::children)
39 .base_box("stbl", parser::children)
40 .full_box("stsd", parser::sample_description)
41 .base_box("encv", parser::visual_sample_entry)
42 .base_box("enca", parser::audio_sample_entry)
43 .base_box("sinf", parser::children)
44 .base_box("schi", parser::children)
45 .full_box("tenc", move |mut box_| {
46 *tenc_box_c.borrow_mut() = Some(Self::new(&mut box_)?);
47 Ok(())
48 })
49 .parse(data, true, false)?;
50
51 Ok(tenc_box.take())
52 }
53
54 pub fn new(box_: &mut ParsedBox) -> Result<Self> {
56 let reader = &mut box_.reader;
57 let version = box_.version.unwrap_or(0);
58
59 reader.skip(1)?;
61
62 let (crypt_byte_block, skip_byte_block) = if version == 0 {
65 reader.skip(1)?;
66 (0, 0)
67 } else {
68 let pattern = reader.read_u8()?;
69 ((pattern >> 4) & 0x0F, pattern & 0x0F)
70 };
71
72 let is_protected = reader.read_u8()? != 0;
73 let per_sample_iv_size = reader.read_u8()?;
74
75 let kid_bytes = reader.read_bytes_u8(16)?;
76 let mut default_kid = [0u8; 16];
77 default_kid.copy_from_slice(&kid_bytes);
78
79 let mut constant_iv = None;
81
82 if per_sample_iv_size == 0 {
83 let constant_iv_size = reader.read_u8()?;
84 if constant_iv_size > 0 && constant_iv_size <= 16 {
85 let bytes = reader.read_bytes_u8(constant_iv_size as usize)?;
86 let mut iv = [0u8; 16];
87 iv[..bytes.len()].copy_from_slice(&bytes);
88 constant_iv = Some(iv);
89 }
90 }
91
92 Ok(Self {
93 default_kid,
94 is_protected,
95 per_sample_iv_size,
96 crypt_byte_block,
97 skip_byte_block,
98 constant_iv,
99 })
100 }
101
102 pub fn default_kid_hex(&self) -> String {
104 hex::encode(self.default_kid)
105 }
106}