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

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