1use std::io::{
2 Write, {self},
3};
4
5use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
6use bytes::{Buf, Bytes};
7use scuffle_bytes_util::{BitWriter, BytesCursorExt};
8
9#[derive(Debug, Clone, PartialEq)]
10pub struct AVCDecoderConfigurationRecord {
13 pub configuration_version: u8,
14 pub profile_indication: u8,
15 pub profile_compatibility: u8,
16 pub level_indication: u8,
17 pub length_size_minus_one: u8,
18 pub sps: Vec<Bytes>,
19 pub pps: Vec<Bytes>,
20 pub extended_config: Option<AvccExtendedConfig>,
21}
22
23#[derive(Debug, Clone, PartialEq)]
24pub struct AvccExtendedConfig {
27 pub chroma_format: u8,
28 pub bit_depth_luma_minus8: u8,
29 pub bit_depth_chroma_minus8: u8,
30 pub sequence_parameter_set_ext: Vec<Bytes>,
31}
32
33impl AVCDecoderConfigurationRecord {
34 pub fn demux(reader: &mut io::Cursor<Bytes>) -> io::Result<Self> {
35 let configuration_version = reader.read_u8()?;
36 let profile_indication = reader.read_u8()?;
37 let profile_compatibility = reader.read_u8()?;
38 let level_indication = reader.read_u8()?;
39 let length_size_minus_one = reader.read_u8()? & 0b00000011;
40 let num_of_sequence_parameter_sets = reader.read_u8()? & 0b00011111;
41
42 let mut sps = Vec::with_capacity(num_of_sequence_parameter_sets as usize);
43 for _ in 0..num_of_sequence_parameter_sets {
44 let sps_length = reader.read_u16::<BigEndian>()?;
45 let sps_data = reader.extract_bytes(sps_length as usize)?;
46 sps.push(sps_data);
47 }
48
49 let num_of_picture_parameter_sets = reader.read_u8()?;
50 let mut pps = Vec::with_capacity(num_of_picture_parameter_sets as usize);
51 for _ in 0..num_of_picture_parameter_sets {
52 let pps_length = reader.read_u16::<BigEndian>()?;
53 let pps_data = reader.extract_bytes(pps_length as usize)?;
54 pps.push(pps_data);
55 }
56
57 let extended_config = match profile_indication {
61 66 | 77 | 88 => None,
62 _ => {
63 if reader.has_remaining() {
64 let chroma_format = reader.read_u8()? & 0b00000011; let bit_depth_luma_minus8 = reader.read_u8()? & 0b00000111; let bit_depth_chroma_minus8 = reader.read_u8()? & 0b00000111; let number_of_sequence_parameter_set_ext = reader.read_u8()?; let mut sequence_parameter_set_ext = Vec::with_capacity(number_of_sequence_parameter_set_ext as usize);
70 for _ in 0..number_of_sequence_parameter_set_ext {
71 let sps_ext_length = reader.read_u16::<BigEndian>()?;
72 let sps_ext_data = reader.extract_bytes(sps_ext_length as usize)?;
73 sequence_parameter_set_ext.push(sps_ext_data);
74 }
75
76 Some(AvccExtendedConfig {
77 chroma_format,
78 bit_depth_luma_minus8,
79 bit_depth_chroma_minus8,
80 sequence_parameter_set_ext,
81 })
82 } else {
83 None
86 }
87 }
88 };
89
90 Ok(Self {
91 configuration_version,
92 profile_indication,
93 profile_compatibility,
94 level_indication,
95 length_size_minus_one,
96 sps,
97 pps,
98 extended_config,
99 })
100 }
101
102 pub fn size(&self) -> u64 {
103 1 + 1 + 1 + 1 + 1 + 1 + self.sps.iter().map(|sps| {
110 2 + sps.len() as u64
112 }).sum::<u64>() + 1 + self.pps.iter().map(|pps| {
115 2 + pps.len() as u64
117 }).sum::<u64>() + match &self.extended_config {
119 Some(config) => {
120 1 + 1 + 1 + 1 + config.sequence_parameter_set_ext.iter().map(|sps_ext| {
125 2 + sps_ext.len() as u64
127 }).sum::<u64>() }
129 None => 0,
130 }
131 }
132
133 pub fn mux<T: io::Write>(&self, writer: &mut T) -> io::Result<()> {
134 let mut bit_writer = BitWriter::new(writer);
135
136 bit_writer.write_u8(self.configuration_version)?;
137 bit_writer.write_u8(self.profile_indication)?;
138 bit_writer.write_u8(self.profile_compatibility)?;
139 bit_writer.write_u8(self.level_indication)?;
140 bit_writer.write_bits(0b111111, 6)?;
141 bit_writer.write_bits(self.length_size_minus_one as u64, 2)?;
142 bit_writer.write_bits(0b111, 3)?;
143
144 bit_writer.write_bits(self.sps.len() as u64, 5)?;
145 for sps in &self.sps {
146 bit_writer.write_u16::<BigEndian>(sps.len() as u16)?;
147 bit_writer.write_all(sps)?;
148 }
149
150 bit_writer.write_bits(self.pps.len() as u64, 8)?;
151 for pps in &self.pps {
152 bit_writer.write_u16::<BigEndian>(pps.len() as u16)?;
153 bit_writer.write_all(pps)?;
154 }
155
156 if let Some(config) = &self.extended_config {
157 bit_writer.write_bits(0b111111, 6)?;
158 bit_writer.write_bits(config.chroma_format as u64, 2)?;
159 bit_writer.write_bits(0b11111, 5)?;
160 bit_writer.write_bits(config.bit_depth_luma_minus8 as u64, 3)?;
161 bit_writer.write_bits(0b11111, 5)?;
162 bit_writer.write_bits(config.bit_depth_chroma_minus8 as u64, 3)?;
163
164 bit_writer.write_bits(config.sequence_parameter_set_ext.len() as u64, 8)?;
165 for sps_ext in &config.sequence_parameter_set_ext {
166 bit_writer.write_u16::<BigEndian>(sps_ext.len() as u16)?;
167 bit_writer.write_all(sps_ext)?;
168 }
169 }
170
171 bit_writer.finish()?;
172
173 Ok(())
174 }
175}