Skip to content

Commit faff96a

Browse files
authored
Fix vp9 support. (#22)
1 parent 3a72567 commit faff96a

File tree

7 files changed

+448
-110
lines changed

7 files changed

+448
-110
lines changed

src/any.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ any! {
147147
Esds,
148148
Tx3g,
149149
Vp09,
150+
VpcC,
150151
Av01,
151152
Av1c,
152153
Stts,

src/moov/trak/mdia/minf/stbl/stsd/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ mod mp4a;
55
mod tx3g;
66
mod visual;
77
mod vp09;
8-
mod vpcc;
98

109
pub use av01::*;
1110
pub use avc1::*;
@@ -14,7 +13,6 @@ pub use mp4a::*;
1413
pub use tx3g::*;
1514
pub use visual::*;
1615
pub use vp09::*;
17-
pub use vpcc::*;
1816

1917
use crate::*;
2018

src/moov/trak/mdia/minf/stbl/stsd/visual.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,34 @@ impl Encode for Visual {
5353
}
5454
impl Decode for Visual {
5555
fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
56-
u32::decode(buf)?; // reserved
57-
u16::decode(buf)?; // reserved
56+
/*
57+
class VisualSampleEntry(codingname) extends SampleEntry (codingname){
58+
unsigned int(16) pre_defined = 0;
59+
const unsigned int(16) reserved = 0;
60+
unsigned int(32)[3] pre_defined = 0;
61+
unsigned int(16) width;
62+
unsigned int(16) height;
63+
template unsigned int(32) horizresolution = 0x00480000; // 72 dpi
64+
template unsigned int(32) vertresolution = 0x00480000; // 72 dpi
65+
const unsigned int(32) reserved = 0;
66+
template unsigned int(16) frame_count = 1;
67+
string[32] compressorname;
68+
template unsigned int(16) depth = 0x0018;
69+
int(16) pre_defined = -1;
70+
// other boxes from derived specifications
71+
CleanApertureBox clap; // optional
72+
PixelAspectRatioBox pasp; // optional
73+
}
74+
75+
*/
76+
77+
// SampleEntry
78+
<[u8; 6]>::decode(buf)?;
5879
let data_reference_index = u16::decode(buf)?;
5980

60-
u32::decode(buf)?; // pre-defined, reserved
61-
u64::decode(buf)?; // pre-defined
62-
u32::decode(buf)?; // pre-defined
81+
// VisualSampleEntry
82+
// 16 bytes of garb at the front
83+
<[u8; 16]>::decode(buf)?;
6384
let width = u16::decode(buf)?;
6485
let height = u16::decode(buf)?;
6586
let horizresolution = FixedPoint::decode(buf)?;

src/moov/trak/mdia/minf/stbl/stsd/vp09.rs

Lines changed: 108 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,143 @@
11
use crate::*;
22

3+
// https://www.webmproject.org/vp9/mp4/
34
#[derive(Debug, Clone, PartialEq, Eq, Default)]
45
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
56
pub struct Vp09 {
67
pub visual: Visual,
7-
pub vpcc: Vpcc,
8+
pub vpcc: VpcC,
89
}
910

10-
impl AtomExt for Vp09 {
11-
type Ext = ();
11+
impl Atom for Vp09 {
12+
const KIND: FourCC = FourCC::new(b"vp09");
1213

13-
const KIND_EXT: FourCC = FourCC::new(b"vp09");
14-
15-
fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
14+
fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
1615
let visual = Visual::decode(buf)?;
17-
let vpcc = Vpcc::decode(buf)?;
1816

19-
Ok(Self { visual, vpcc })
17+
let mut vpcc = None;
18+
while let Some(atom) = Any::decode_maybe(buf)? {
19+
match atom {
20+
Any::VpcC(atom) => vpcc = atom.into(),
21+
_ => tracing::warn!("unknown atom: {:?}", atom),
22+
}
23+
}
24+
25+
Ok(Self {
26+
visual,
27+
vpcc: vpcc.ok_or(Error::MissingBox(VpcC::KIND))?,
28+
})
2029
}
2130

22-
fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
31+
fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
2332
self.visual.encode(buf)?;
2433
self.vpcc.encode(buf)?;
2534

2635
Ok(())
2736
}
2837
}
2938

39+
ext! {
40+
name: Vpcc,
41+
versions: [1],
42+
flags: {}
43+
}
44+
45+
#[derive(Debug, Clone, PartialEq, Eq, Default)]
46+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
47+
pub struct VpcC {
48+
pub profile: u8,
49+
pub level: u8,
50+
pub bit_depth: u8,
51+
pub chroma_subsampling: u8,
52+
pub video_full_range_flag: bool,
53+
pub color_primaries: u8,
54+
pub transfer_characteristics: u8,
55+
pub matrix_coefficients: u8,
56+
pub codec_initialization_data: Vec<u8>,
57+
}
58+
59+
impl AtomExt for VpcC {
60+
const KIND_EXT: FourCC = FourCC::new(b"vpcC");
61+
62+
type Ext = VpccExt;
63+
64+
fn decode_body_ext<B: Buf>(buf: &mut B, _ext: VpccExt) -> Result<Self> {
65+
let profile = u8::decode(buf)?;
66+
let level = u8::decode(buf)?;
67+
let (bit_depth, chroma_subsampling, video_full_range_flag) = {
68+
let b = u8::decode(buf)?;
69+
(b >> 4, (b >> 1) & 0x01, b & 0x01 == 1)
70+
};
71+
let color_primaries = u8::decode(buf)?;
72+
let transfer_characteristics = u8::decode(buf)?;
73+
let matrix_coefficients = u8::decode(buf)?;
74+
let _codec_initialization_data_size = u16::decode(buf)?;
75+
let codec_initialization_data = Vec::decode(buf)?; // assert same as data_size
76+
77+
Ok(Self {
78+
profile,
79+
level,
80+
bit_depth,
81+
chroma_subsampling,
82+
video_full_range_flag,
83+
color_primaries,
84+
transfer_characteristics,
85+
matrix_coefficients,
86+
codec_initialization_data,
87+
})
88+
}
89+
90+
fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<VpccExt> {
91+
self.profile.encode(buf)?;
92+
self.level.encode(buf)?;
93+
((self.bit_depth << 4)
94+
| (self.chroma_subsampling << 1)
95+
| (self.video_full_range_flag as u8))
96+
.encode(buf)?;
97+
self.color_primaries.encode(buf)?;
98+
self.transfer_characteristics.encode(buf)?;
99+
self.matrix_coefficients.encode(buf)?;
100+
(self.codec_initialization_data.len() as u16).encode(buf)?;
101+
self.codec_initialization_data.encode(buf)?;
102+
103+
Ok(VpccVersion::V1.into())
104+
}
105+
}
106+
30107
#[cfg(test)]
31108
mod tests {
32109
use super::*;
33110

34111
#[test]
35112
fn test_vpcc() {
113+
let expected = VpcC {
114+
profile: 0,
115+
level: 0x1F,
116+
bit_depth: 8,
117+
chroma_subsampling: 0,
118+
video_full_range_flag: false,
119+
color_primaries: 0,
120+
transfer_characteristics: 0,
121+
matrix_coefficients: 0,
122+
codec_initialization_data: vec![],
123+
};
124+
let mut buf = Vec::new();
125+
expected.encode(&mut buf).unwrap();
126+
127+
let mut buf = buf.as_ref();
128+
let decoded = VpcC::decode(&mut buf).unwrap();
129+
assert_eq!(decoded, expected);
130+
}
131+
132+
#[test]
133+
fn test_vp09() {
36134
let expected = Vp09 {
37135
visual: Visual {
38136
width: 1920,
39137
height: 1080,
40138
..Default::default()
41139
},
42-
vpcc: Vpcc::default(),
140+
vpcc: VpcC::default(),
43141
};
44142
let mut buf = Vec::new();
45143
expected.encode(&mut buf).unwrap();

src/moov/trak/mdia/minf/stbl/stsd/vpcc.rs

Lines changed: 0 additions & 93 deletions
This file was deleted.

src/test/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ mod avcc_ext;
33
mod bbb;
44
mod esds;
55
mod hevc;
6+
mod vp09;

0 commit comments

Comments
 (0)