mp4_atom/moov/trak/mdia/minf/stbl/stsd/vp9/
vpcc.rs1use crate::*;
2
3ext! {
4 name: Vpcc,
5 versions: [1],
6 flags: {}
7}
8
9#[derive(Debug, Clone, PartialEq, Eq, Default)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct VpcC {
12 pub profile: u8,
13 pub level: u8,
14 pub bit_depth: u8,
15 pub chroma_subsampling: u8,
16 pub video_full_range_flag: bool,
17 pub color_primaries: u8,
18 pub transfer_characteristics: u8,
19 pub matrix_coefficients: u8,
20 pub codec_initialization_data: Vec<u8>,
21}
22
23impl AtomExt for VpcC {
24 const KIND_EXT: FourCC = FourCC::new(b"vpcC");
25
26 type Ext = VpccExt;
27
28 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: VpccExt) -> Result<Self> {
29 let profile = u8::decode(buf)?;
30 let level = u8::decode(buf)?;
31 let (bit_depth, chroma_subsampling, video_full_range_flag) = {
32 let b = u8::decode(buf)?;
33 (b >> 4, (b >> 1) & 0x01, b & 0x01 == 1)
34 };
35 let color_primaries = u8::decode(buf)?;
36 let transfer_characteristics = u8::decode(buf)?;
37 let matrix_coefficients = u8::decode(buf)?;
38 let _codec_initialization_data_size = u16::decode(buf)?;
39 let codec_initialization_data = Vec::decode(buf)?; Ok(Self {
42 profile,
43 level,
44 bit_depth,
45 chroma_subsampling,
46 video_full_range_flag,
47 color_primaries,
48 transfer_characteristics,
49 matrix_coefficients,
50 codec_initialization_data,
51 })
52 }
53
54 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<VpccExt> {
55 self.profile.encode(buf)?;
56 self.level.encode(buf)?;
57 ((self.bit_depth << 4)
58 | (self.chroma_subsampling << 1)
59 | (self.video_full_range_flag as u8))
60 .encode(buf)?;
61 self.color_primaries.encode(buf)?;
62 self.transfer_characteristics.encode(buf)?;
63 self.matrix_coefficients.encode(buf)?;
64 (self.codec_initialization_data.len() as u16).encode(buf)?;
65 self.codec_initialization_data.encode(buf)?;
66
67 Ok(VpccVersion::V1.into())
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_vpcc() {
77 let expected = VpcC {
78 profile: 0,
79 level: 0x1F,
80 bit_depth: 8,
81 chroma_subsampling: 0,
82 video_full_range_flag: false,
83 color_primaries: 0,
84 transfer_characteristics: 0,
85 matrix_coefficients: 0,
86 codec_initialization_data: vec![],
87 };
88 let mut buf = Vec::new();
89 expected.encode(&mut buf).unwrap();
90
91 let mut buf = buf.as_ref();
92 let decoded = VpcC::decode(&mut buf).unwrap();
93 assert_eq!(decoded, expected);
94 }
95}