Skip to content

Commit 59c24d9

Browse files
committed
Add support for adrm boxes
1 parent 55875d7 commit 59c24d9

File tree

3 files changed

+133
-6
lines changed

3 files changed

+133
-6
lines changed

src/mp4box/adrm.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
2+
3+
use serde::Serialize;
4+
use std::io::{Read, Seek, Write};
5+
6+
use crate::mp4box::*;
7+
8+
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
9+
pub struct AdrmBox {
10+
#[serde(serialize_with = "<[_]>::serialize")]
11+
pub drm_blob: [u8; 48],
12+
pub file_checksum: [u8; 20],
13+
#[serde(serialize_with = "<[_]>::serialize")]
14+
pub unknown0: [u8; 60],
15+
}
16+
17+
impl Mp4Box for AdrmBox {
18+
fn box_type(&self) -> BoxType {
19+
BoxType::AdrmBox
20+
}
21+
22+
fn box_size(&self) -> u64 {
23+
156
24+
}
25+
26+
fn to_json(&self) -> Result<String> {
27+
Ok(serde_json::to_string(&self).unwrap())
28+
}
29+
30+
fn summary(&self) -> Result<String> {
31+
let mut s = String::with_capacity(49);
32+
s.push_str("checksum=");
33+
for b in self.file_checksum.iter() {
34+
s.push_str(&format!("{:02x}", b));
35+
}
36+
Ok(s)
37+
}
38+
}
39+
40+
impl<R: Read + Seek> ReadBox<&mut R> for AdrmBox {
41+
fn read_box(reader: &mut R, size: u64) -> Result<Self> {
42+
let start = box_start(reader)?;
43+
44+
let mut result = AdrmBox {
45+
drm_blob: [0u8; 48],
46+
file_checksum: [0u8; 20],
47+
unknown0: [0u8; 60],
48+
};
49+
50+
reader.read_u32::<BigEndian>()?; // 56
51+
reader.read_u32::<BigEndian>()?; // 1
52+
reader.read_exact(&mut result.drm_blob)?;
53+
reader.read_u32::<BigEndian>()?; // 0
54+
reader.read_u32::<BigEndian>()?; // 1
55+
reader.read_u32::<BigEndian>()?; // 0
56+
reader.read_exact(&mut result.file_checksum)?;
57+
reader.read_exact(&mut result.unknown0)?;
58+
59+
assert_eq!(reader.stream_position()?, start + size);
60+
61+
Ok(result)
62+
}
63+
}
64+
65+
impl<W: Write> WriteBox<&mut W> for AdrmBox {
66+
fn write_box(&self, writer: &mut W) -> Result<u64> {
67+
let size = self.box_size();
68+
BoxHeader::new(self.box_type(), size).write(writer)?;
69+
70+
writer.write_u32::<BigEndian>(56)?;
71+
writer.write_u32::<BigEndian>(1)?;
72+
writer.write_all(&self.drm_blob)?;
73+
writer.write_u32::<BigEndian>(0)?;
74+
writer.write_u32::<BigEndian>(1)?;
75+
writer.write_u32::<BigEndian>(0)?;
76+
writer.write_all(&self.file_checksum)?;
77+
writer.write_all(&self.unknown0)?;
78+
79+
Ok(size)
80+
}
81+
}
82+
83+
#[cfg(test)]
84+
mod tests {
85+
use super::*;
86+
use crate::mp4box::BoxHeader;
87+
use std::io::Cursor;
88+
89+
#[test]
90+
fn test_adrm() {
91+
let src_box = AdrmBox {
92+
drm_blob: [29u8; 48],
93+
file_checksum: [244u8; 20],
94+
unknown0: [113u8; 60],
95+
};
96+
97+
let mut buf = Vec::new();
98+
src_box.write_box(&mut buf).unwrap();
99+
assert_eq!(buf.len(), src_box.box_size() as usize);
100+
101+
let mut reader = Cursor::new(&buf);
102+
let header = BoxHeader::read(&mut reader).unwrap();
103+
assert_eq!(header.name, BoxType::AdrmBox);
104+
assert_eq!(src_box.box_size(), header.size);
105+
106+
let dst_box = AdrmBox::read_box(&mut reader, header.size).unwrap();
107+
assert_eq!(src_box, dst_box);
108+
}
109+
}

src/mp4box/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ use std::io::{Read, Seek, SeekFrom, Write};
6262

6363
use crate::*;
6464

65+
pub(crate) mod adrm;
6566
pub(crate) mod avc1;
6667
pub(crate) mod co64;
6768
pub(crate) mod ctts;
@@ -198,6 +199,7 @@ boxtype! {
198199
DayBox => 0xa9646179,
199200
CovrBox => 0x636f7672,
200201
DescBox => 0x64657363,
202+
AdrmBox => 0x6164726d,
201203
WideBox => 0x77696465
202204
}
203205

src/mp4box/mp4a.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
22
use serde::Serialize;
33
use std::io::{Read, Seek, Write};
44

5-
use crate::mp4box::*;
5+
use crate::{adrm::AdrmBox, mp4box::*};
66

77
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
88
pub struct Mp4aBox {
@@ -12,6 +12,7 @@ pub struct Mp4aBox {
1212

1313
#[serde(with = "value_u32")]
1414
pub samplerate: FixedPointU16,
15+
pub adrm: Option<AdrmBox>,
1516
pub esds: Option<EsdsBox>,
1617
}
1718

@@ -22,6 +23,7 @@ impl Default for Mp4aBox {
2223
channelcount: 2,
2324
samplesize: 16,
2425
samplerate: FixedPointU16::new(48000),
26+
adrm: None,
2527
esds: Some(EsdsBox::default()),
2628
}
2729
}
@@ -34,6 +36,7 @@ impl Mp4aBox {
3436
channelcount: config.chan_conf as u16,
3537
samplesize: 16,
3638
samplerate: FixedPointU16::new(config.freq_index.freq() as u16),
39+
adrm: None,
3740
esds: Some(EsdsBox::new(config)),
3841
}
3942
}
@@ -89,9 +92,10 @@ impl<R: Read + Seek> ReadBox<&mut R> for Mp4aBox {
8992
reader.read_u32::<BigEndian>()?; // pre-defined, reserved
9093
let samplerate = FixedPointU16::new_raw(reader.read_u32::<BigEndian>()?);
9194

95+
let mut adrm = None;
9296
let mut esds = None;
93-
let current = reader.stream_position()?;
94-
if current < start + size {
97+
let mut current = reader.stream_position()?;
98+
while current < start + size {
9599
let header = BoxHeader::read(reader)?;
96100
let BoxHeader { name, size: s } = header;
97101
if s > size {
@@ -100,17 +104,27 @@ impl<R: Read + Seek> ReadBox<&mut R> for Mp4aBox {
100104
));
101105
}
102106

103-
if name == BoxType::EsdsBox {
104-
esds = Some(EsdsBox::read_box(reader, s)?);
107+
match name {
108+
BoxType::AdrmBox => {
109+
adrm = Some(AdrmBox::read_box(reader, s)?);
110+
}
111+
BoxType::EsdsBox => {
112+
esds = Some(EsdsBox::read_box(reader, s)?);
113+
}
114+
_ => {
115+
skip_box(reader, s)?;
116+
}
105117
}
106-
skip_bytes_to(reader, start + size)?;
118+
119+
current = reader.stream_position()?;
107120
}
108121

109122
Ok(Mp4aBox {
110123
data_reference_index,
111124
channelcount,
112125
samplesize,
113126
samplerate,
127+
adrm,
114128
esds,
115129
})
116130
}
@@ -605,6 +619,7 @@ mod tests {
605619
channelcount: 2,
606620
samplesize: 16,
607621
samplerate: FixedPointU16::new(48000),
622+
adrm: None,
608623
esds: Some(EsdsBox {
609624
version: 0,
610625
flags: 0,
@@ -647,6 +662,7 @@ mod tests {
647662
channelcount: 2,
648663
samplesize: 16,
649664
samplerate: FixedPointU16::new(48000),
665+
adrm: None,
650666
esds: None,
651667
};
652668
let mut buf = Vec::new();

0 commit comments

Comments
 (0)