vsd_mp4/boxes/senc.rs
1use crate::{ParsedBox, Result};
2
3/// A subsample encryption entry, dividing a sample into clear (unencrypted) and encrypted bytes.
4#[derive(Debug, Clone)]
5pub struct SencSubsample {
6 /// Number of clear (unencrypted) bytes in this subsample.
7 pub bytes_of_clear_data: u16,
8 /// Number of encrypted bytes in this subsample.
9 pub bytes_of_encrypted_data: u32,
10}
11
12/// Encryption parameters for a single media sample.
13#[derive(Debug, Clone)]
14pub struct SencSample {
15 /// The initialization vector (IV) for this sample. Shorter IVs (e.g. 8 bytes) are zero-padded to 16 bytes.
16 pub iv: [u8; 16],
17 /// The list of subsample encryption entries if subsample-level encryption is active.
18 pub subsamples: Vec<SencSubsample>,
19}
20
21/// Sample Encryption Box (senc) - contains initialization vectors and subsample maps for all samples in a movie fragment.
22#[derive(Debug, Clone)]
23pub struct SencBox {
24 /// The flags from the box header (typically indicating whether subsamples are present).
25 pub flags: u32,
26 /// Per-sample encryption parameters.
27 pub samples: Vec<SencSample>,
28}
29
30impl SencBox {
31 /// Parses a `senc` box from a `ParsedBox`.
32 ///
33 /// # Arguments
34 /// * `box_` - The parsed box to read from.
35 /// * `iv_size` - The IV size in bytes (from `tenc` default or per-sample IV size).
36 /// * `constant_iv` - An optional constant IV to use if `iv_size` is zero.
37 pub fn new(box_: &mut ParsedBox, iv_size: u8, constant_iv: Option<&[u8; 16]>) -> Result<Self> {
38 let reader = &mut box_.reader;
39 let flags = box_.flags.unwrap_or(0);
40
41 let sample_count = reader.read_u32()?;
42 let has_subsamples = flags & 0x02 != 0;
43
44 let mut samples = Vec::with_capacity(sample_count as usize);
45
46 for _ in 0..sample_count {
47 let iv = if iv_size > 0 && iv_size <= 16 {
48 let bytes = reader.read_bytes_u8(iv_size as usize)?;
49 let mut iv = [0u8; 16];
50 iv[..bytes.len()].copy_from_slice(&bytes);
51 iv
52 } else if let Some(civ) = constant_iv {
53 *civ
54 } else {
55 [0u8; 16]
56 };
57
58 let subsamples = if has_subsamples {
59 let subsample_count = reader.read_u16()?;
60 let mut subs = Vec::with_capacity(subsample_count as usize);
61 for _ in 0..subsample_count {
62 let bytes_of_clear_data = reader.read_u16()?;
63 let bytes_of_encrypted_data = reader.read_u32()?;
64 subs.push(SencSubsample {
65 bytes_of_clear_data,
66 bytes_of_encrypted_data,
67 });
68 }
69 subs
70 } else {
71 Vec::new()
72 };
73
74 samples.push(SencSample { iv, subsamples });
75 }
76
77 Ok(Self { flags, samples })
78 }
79}