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