mp4_atom/moov/trak/mdia/minf/stbl/stsd/
opus.rs1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub struct Opus {
6 pub audio: Audio,
7 pub dops: Dops,
8 pub btrt: Option<Btrt>,
9}
10
11impl Atom for Opus {
12 const KIND: FourCC = FourCC::new(b"Opus");
13
14 fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
15 let audio = Audio::decode(buf)?;
16
17 let mut dops = None;
18 let mut btrt = None;
19
20 while let Some(atom) = Any::decode_maybe(buf)? {
22 match atom {
23 Any::Dops(atom) => dops = atom.into(),
24 Any::Btrt(atom) => btrt = atom.into(),
25 unknown => Self::decode_unknown(&unknown)?,
26 }
27 }
28 skip_trailing_padding(buf);
29
30 Ok(Self {
31 audio,
32 dops: dops.ok_or(Error::MissingBox(Dops::KIND))?,
33 btrt,
34 })
35 }
36
37 fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
38 self.audio.encode(buf)?;
39 self.dops.encode(buf)?;
40 self.btrt.encode(buf)?;
41 Ok(())
42 }
43}
44
45#[derive(Debug, Clone, PartialEq, Eq)]
67#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
68pub struct Dops {
69 pub output_channel_count: u8,
70 pub pre_skip: u16,
71 pub input_sample_rate: u32,
72 pub output_gain: i16,
73}
74
75impl Atom for Dops {
76 const KIND: FourCC = FourCC::new(b"dOps");
77
78 fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
79 let version = u8::decode(buf)?;
80 if version != 0 {
81 return Err(Error::UnknownVersion(version));
82 }
83
84 let output_channel_count = u8::decode(buf)?;
85 let pre_skip = u16::decode(buf)?;
86 let input_sample_rate = u32::decode(buf)?;
87 let output_gain = i16::decode(buf)?;
88
89 let channel_mapping_family = u8::decode(buf)?;
90 if channel_mapping_family != 0 {
91 return Err(Error::Unsupported("OPUS channel mapping"));
92 }
93
94 Ok(Self {
95 output_channel_count,
96 pre_skip,
97 input_sample_rate,
98 output_gain,
99 })
100 }
101
102 fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
103 (0u8).encode(buf)?;
104 self.output_channel_count.encode(buf)?;
105 self.pre_skip.encode(buf)?;
106 self.input_sample_rate.encode(buf)?;
107 self.output_gain.encode(buf)?;
108 (0u8).encode(buf)?;
109
110 Ok(())
111 }
112}