Skip to main content

mp4_atom/moov/trak/mdia/minf/stbl/stsd/
av01.rs

1use crate::coding::{Decode, Encode};
2use crate::{
3    skip_trailing_padding, Any, Atom, Buf, BufMut, Ccst, DecodeMaybe, Error, FourCC, Result,
4};
5
6use super::{Btrt, Colr, Pasp, Spatial, Taic, Visual};
7
8#[derive(Debug, Clone, PartialEq, Eq, Default)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct Av01 {
11    pub visual: Visual,
12    pub av1c: Av1c,
13    pub btrt: Option<Btrt>,
14    pub ccst: Option<Ccst>,
15    pub colr: Option<Colr>,
16    pub pasp: Option<Pasp>,
17    pub taic: Option<Taic>,
18    pub spatial: Option<Box<Spatial>>,
19}
20
21impl Atom for Av01 {
22    const KIND: FourCC = FourCC::new(b"av01");
23
24    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
25        let visual = Visual::decode(buf)?;
26
27        let mut av1c = None;
28        let mut btrt = None;
29        let mut ccst = None;
30        let mut colr = None;
31        let mut pasp = None;
32        let mut taic = None;
33        let mut spatial = None;
34        while let Some(atom) = Any::decode_maybe(buf)? {
35            match atom {
36                Any::Av1c(atom) => av1c = atom.into(),
37                Any::Btrt(atom) => btrt = atom.into(),
38                Any::Ccst(atom) => ccst = atom.into(),
39                Any::Colr(atom) => colr = atom.into(),
40                Any::Pasp(atom) => pasp = atom.into(),
41                Any::Taic(atom) => taic = atom.into(),
42                atom => Spatial::decode_child::<Self>(&mut spatial, atom)?,
43            }
44        }
45        skip_trailing_padding(buf);
46
47        Ok(Av01 {
48            visual,
49            av1c: av1c.ok_or(Error::MissingBox(Av1c::KIND))?,
50            btrt,
51            ccst,
52            colr,
53            pasp,
54            taic,
55            spatial,
56        })
57    }
58
59    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
60        self.visual.encode(buf)?;
61        self.av1c.encode(buf)?;
62        self.btrt.encode(buf)?;
63        self.ccst.encode(buf)?;
64        self.colr.encode(buf)?;
65        if let Some(spatial) = &self.spatial {
66            spatial.encode(buf)?;
67        }
68        self.pasp.encode(buf)?;
69        self.taic.encode(buf)?;
70
71        Ok(())
72    }
73}
74
75// https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-section
76#[derive(Debug, Clone, PartialEq, Eq, Default)]
77#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
78pub struct Av1c {
79    pub seq_profile: u8,
80    pub seq_level_idx_0: u8,
81    pub seq_tier_0: bool,
82    pub high_bitdepth: bool,
83    pub twelve_bit: bool,
84    pub monochrome: bool,
85    pub chroma_subsampling_x: bool,
86    pub chroma_subsampling_y: bool,
87    pub chroma_sample_position: u8, // 0..3
88    pub initial_presentation_delay: Option<u8>,
89    pub config_obus: Vec<u8>,
90}
91
92impl Atom for Av1c {
93    const KIND: FourCC = FourCC::new(b"av1C");
94
95    fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
96        let version = u8::decode(buf)?;
97        if version != 0b1000_0001 {
98            return Err(Error::UnknownVersion(version));
99        }
100
101        let v = u8::decode(buf)?;
102        let seq_profile = v >> 5;
103        let seq_level_idx_0 = v & 0b11111;
104
105        let v = u8::decode(buf)?;
106        let seq_tier_0 = (v >> 7) == 1;
107        let high_bitdepth = ((v >> 6) & 0b1) == 1;
108        let twelve_bit = ((v >> 5) & 0b1) == 1;
109        let monochrome = ((v >> 4) & 0b1) == 1;
110        let chroma_subsampling_x = ((v >> 3) & 0b1) == 1;
111        let chroma_subsampling_y = ((v >> 2) & 0b1) == 1;
112        let chroma_sample_position = v & 0b11;
113
114        let v = u8::decode(buf)?;
115        let reserved = v >> 5;
116        if reserved != 0 {
117            return Err(Error::Reserved);
118        }
119
120        let initial_presentation_delay_present = (v >> 4) & 0b1;
121        let initial_presentation_delay_minus_one = v & 0b1111;
122
123        let initial_presentation_delay = if initial_presentation_delay_present == 1 {
124            Some(initial_presentation_delay_minus_one + 1)
125        } else {
126            if initial_presentation_delay_minus_one != 0 {
127                return Err(Error::Reserved);
128            }
129
130            None
131        };
132
133        let config_obus = Vec::decode(buf)?;
134
135        Ok(Self {
136            seq_profile,
137            seq_level_idx_0,
138            seq_tier_0,
139            high_bitdepth,
140            twelve_bit,
141            monochrome,
142            chroma_subsampling_x,
143            chroma_subsampling_y,
144            chroma_sample_position,
145            initial_presentation_delay,
146            config_obus,
147        })
148    }
149
150    fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
151        0b1000_0001_u8.encode(buf)?;
152        ((self.seq_profile << 5) | self.seq_level_idx_0).encode(buf)?;
153
154        (((self.seq_tier_0 as u8) << 7)
155            | ((self.high_bitdepth as u8) << 6)
156            | ((self.twelve_bit as u8) << 5)
157            | ((self.monochrome as u8) << 4)
158            | ((self.chroma_subsampling_x as u8) << 3)
159            | ((self.chroma_subsampling_y as u8) << 2)
160            | self.chroma_sample_position)
161            .encode(buf)?;
162
163        if let Some(initial_presentation_delay) = self.initial_presentation_delay {
164            ((initial_presentation_delay - 1) | 0b0001_0000).encode(buf)?;
165        } else {
166            0b0000_0000_u8.encode(buf)?;
167        }
168
169        self.config_obus.encode(buf)?;
170
171        Ok(())
172    }
173}