Skip to content

Commit d6dca09

Browse files
SingingTreekinetiknz
authored andcommitted
Parse tenc members related to pattern encryption.
Parse the tenc members for: - crypt_byte_block: number of encrypted bytes in the pattern if pattern encryption is used - skip_byte_block: number of clear bytes in the pattern if pattern encryption is used - constant_iv: the iv that is used for a track by certain pattern based encryption schemes, such as cbcs Update the data structures used to contain new data. Note, the is_encrypted member of the tenc structure has been changed from a u32 to a u8 to reflect changes in the spec. This changes our interface.
1 parent 20ffd30 commit d6dca09

File tree

2 files changed

+75
-4
lines changed

2 files changed

+75
-4
lines changed

mp4parse/src/lib.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,9 +426,14 @@ pub struct ProtectionSystemSpecificHeaderBox {
426426

427427
#[derive(Debug, Default, Clone)]
428428
pub struct TrackEncryptionBox {
429-
pub is_encrypted: u32,
429+
pub is_encrypted: u8,
430430
pub iv_size: u8,
431431
pub kid: Vec<u8>,
432+
// Members for pattern encryption schemes
433+
pub crypt_byte_block_count: Option<u8>,
434+
pub skip_byte_block_count: Option<u8>,
435+
pub constant_iv: Option<Vec<u8>>,
436+
// End pattern encryption scheme members
432437
}
433438

434439
#[derive(Debug, Default, Clone)]
@@ -2154,16 +2159,42 @@ fn read_schi<T: Read>(src: &mut BMFFBox<T>) -> Result<Option<TrackEncryptionBox>
21542159
}
21552160

21562161
fn read_tenc<T: Read>(src: &mut BMFFBox<T>) -> Result<TrackEncryptionBox> {
2157-
let (_, _) = read_fullbox_extra(src)?;
2162+
let (version, _) = read_fullbox_extra(src)?;
21582163

2159-
let default_is_encrypted = be_u24(src)?;
2164+
// reserved byte
2165+
skip(src, 1)?;
2166+
// the next byte is used to signal the default pattern in version >= 1
2167+
let (default_crypt_byte_block, default_skip_byte_block) = match version {
2168+
0 => {
2169+
skip(src, 1)?;
2170+
(None, None)
2171+
},
2172+
_ => {
2173+
let pattern_byte = src.read_u8()?;
2174+
let crypt_bytes = pattern_byte >> 4;
2175+
let skip_bytes = pattern_byte & 0x0f;
2176+
(Some(crypt_bytes), Some(skip_bytes))
2177+
}
2178+
};
2179+
let default_is_encrypted = src.read_u8()?;
21602180
let default_iv_size = src.read_u8()?;
21612181
let default_kid = read_buf(src, 16)?;
2182+
// If default_is_encrypted == 1 && default_iv_size == 0 we expect a default_constant_iv
2183+
let default_constant_iv = match (default_is_encrypted, default_iv_size) {
2184+
(1, 0) => {
2185+
let default_constant_iv_size = src.read_u8()?;
2186+
Some(read_buf(src, default_constant_iv_size as usize)?)
2187+
},
2188+
_ => None,
2189+
};
21622190

21632191
Ok(TrackEncryptionBox {
21642192
is_encrypted: default_is_encrypted,
21652193
iv_size: default_iv_size,
21662194
kid: default_kid,
2195+
crypt_byte_block_count: default_crypt_byte_block,
2196+
skip_byte_block_count: default_skip_byte_block,
2197+
constant_iv: default_constant_iv
21672198
})
21682199
}
21692200

mp4parse_capi/src/lib.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,15 @@ pub struct Mp4parsePsshInfo {
168168
#[repr(C)]
169169
#[derive(Default, Debug)]
170170
pub struct Mp4parseSinfInfo {
171-
pub is_encrypted: u32,
171+
pub is_encrypted: u8,
172172
pub iv_size: u8,
173173
pub kid: Mp4parseByteData,
174+
// Members for pattern encryption schemes, may be 0 (u8) or empty
175+
// (Mp4parseByteData) if pattern encryption is not in use
176+
pub crypt_byte_block: u8,
177+
pub skip_byte_block: u8,
178+
pub constant_iv: Mp4parseByteData,
179+
// End pattern encryption scheme members
174180
}
175181

176182
#[repr(C)]
@@ -617,6 +623,23 @@ pub unsafe extern fn mp4parse_get_track_audio_info(parser: *mut Mp4parseParser,
617623
sample_info.protected_data.is_encrypted = tenc.is_encrypted;
618624
sample_info.protected_data.iv_size = tenc.iv_size;
619625
sample_info.protected_data.kid.set_data(&(tenc.kid));
626+
sample_info.protected_data.crypt_byte_block = match tenc.crypt_byte_block_count {
627+
Some(n) => n,
628+
None => 0,
629+
};
630+
sample_info.protected_data.skip_byte_block = match tenc.skip_byte_block_count {
631+
Some(n) => n,
632+
None => 0,
633+
};
634+
match tenc.constant_iv {
635+
Some(ref iv_vec) => {
636+
if iv_vec.len() > std::u32::MAX as usize {
637+
return Mp4parseStatus::Invalid;
638+
}
639+
sample_info.protected_data.constant_iv.set_data(iv_vec);
640+
},
641+
None => {}, // Don't need to do anything, defaults are correct
642+
};
620643
}
621644
}
622645
audio_sample_infos.push(sample_info);
@@ -721,6 +744,23 @@ pub unsafe extern fn mp4parse_get_track_video_info(parser: *mut Mp4parseParser,
721744
sample_info.protected_data.is_encrypted = tenc.is_encrypted;
722745
sample_info.protected_data.iv_size = tenc.iv_size;
723746
sample_info.protected_data.kid.set_data(&(tenc.kid));
747+
sample_info.protected_data.crypt_byte_block = match tenc.crypt_byte_block_count {
748+
Some(n) => n,
749+
None => 0,
750+
};
751+
sample_info.protected_data.skip_byte_block = match tenc.skip_byte_block_count {
752+
Some(n) => n,
753+
None => 0,
754+
};
755+
match tenc.constant_iv {
756+
Some(ref iv_vec) => {
757+
if iv_vec.len() > std::u32::MAX as usize {
758+
return Mp4parseStatus::Invalid;
759+
}
760+
sample_info.protected_data.constant_iv.set_data(iv_vec);
761+
},
762+
None => {}, // Don't need to do anything, defaults are correct
763+
};
724764
}
725765
}
726766
video_sample_infos.push(sample_info);

0 commit comments

Comments
 (0)