mp4_atom/moov/trak/mdia/minf/stbl/stsd/
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_size: u16,
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
40 Ok(Self {
41 profile,
42 level,
43 bit_depth,
44 chroma_subsampling,
45 video_full_range_flag,
46 color_primaries,
47 transfer_characteristics,
48 matrix_coefficients,
49 codec_initialization_data_size,
50 })
51 }
52
53 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<VpccExt> {
54 self.profile.encode(buf)?;
55 self.level.encode(buf)?;
56 ((self.bit_depth << 4)
57 | (self.chroma_subsampling << 1)
58 | (self.video_full_range_flag as u8))
59 .encode(buf)?;
60 self.color_primaries.encode(buf)?;
61 self.transfer_characteristics.encode(buf)?;
62 self.matrix_coefficients.encode(buf)?;
63 self.codec_initialization_data_size.encode(buf)?;
64
65 Ok(VpccVersion::V1.into())
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn test_vpcc() {
75 let expected = Vpcc {
76 profile: 0,
77 level: 0x1F,
78 bit_depth: 8,
79 chroma_subsampling: 0,
80 video_full_range_flag: false,
81 color_primaries: 0,
82 transfer_characteristics: 0,
83 matrix_coefficients: 0,
84 codec_initialization_data_size: 0,
85 };
86 let mut buf = Vec::new();
87 expected.encode(&mut buf).unwrap();
88
89 let mut buf = buf.as_ref();
90 let decoded = Vpcc::decode(&mut buf).unwrap();
91 assert_eq!(decoded, expected);
92 }
93}