scuffle_h264/sps/
sample_aspect_ratio.rs1use std::io;
2
3use byteorder::ReadBytesExt;
4use scuffle_bytes_util::{BitReader, BitWriter};
5
6use crate::AspectRatioIdc;
7
8#[derive(Debug, Clone, PartialEq)]
13pub struct SarDimensions {
14 pub aspect_ratio_idc: AspectRatioIdc,
22
23 pub sar_width: u16,
32
33 pub sar_height: u16,
42}
43
44impl SarDimensions {
45 pub fn parse<T: io::Read>(reader: &mut BitReader<T>) -> io::Result<Self> {
48 let mut sar_width = 0; let mut sar_height = 0; let aspect_ratio_idc = reader.read_u8()?;
52 if aspect_ratio_idc == 255 {
53 sar_width = reader.read_bits(16)? as u16;
54 sar_height = reader.read_bits(16)? as u16;
55 }
56
57 Ok(SarDimensions {
58 aspect_ratio_idc: AspectRatioIdc(aspect_ratio_idc),
59 sar_width,
60 sar_height,
61 })
62 }
63
64 pub fn build<T: io::Write>(&self, writer: &mut BitWriter<T>) -> io::Result<()> {
67 writer.write_bits(self.aspect_ratio_idc.0 as u64, 8)?;
68
69 if self.aspect_ratio_idc == AspectRatioIdc(255) {
70 writer.write_bits(self.sar_width as u64, 16)?;
71 writer.write_bits(self.sar_height as u64, 16)?;
72 }
73 Ok(())
74 }
75
76 pub fn bitsize(&self) -> u64 {
78 8 + ((self.aspect_ratio_idc == AspectRatioIdc(255)) as u64) * 32
80 }
81
82 pub fn bytesize(&self) -> u64 {
86 self.bitsize().div_ceil(8)
87 }
88}
89
90#[cfg(test)]
91#[cfg_attr(all(test, coverage_nightly), coverage(off))]
92mod tests {
93 use scuffle_bytes_util::{BitReader, BitWriter};
94
95 use crate::sps::SarDimensions;
96
97 #[test]
98 fn test_build_size_sar_idc_not_255() {
99 let mut data = Vec::new();
101 let mut writer = BitWriter::new(&mut data);
102
103 writer.write_bits(1, 8).unwrap();
104 writer.finish().unwrap();
105
106 let mut reader = BitReader::new_from_slice(&mut data);
108 let sample_aspect_ratio = SarDimensions::parse(&mut reader).unwrap();
109
110 let mut buf = Vec::new();
112 let mut writer2 = BitWriter::new(&mut buf);
113
114 sample_aspect_ratio.build(&mut writer2).unwrap();
116 writer2.finish().unwrap();
117
118 assert_eq!(buf, data);
119
120 let mut reader2 = BitReader::new_from_slice(buf);
123 let rebuilt_sample_aspect_ratio = SarDimensions::parse(&mut reader2).unwrap();
124
125 assert_eq!(rebuilt_sample_aspect_ratio.bitsize(), sample_aspect_ratio.bitsize());
127 assert_eq!(rebuilt_sample_aspect_ratio.bytesize(), sample_aspect_ratio.bytesize());
128 }
129
130 #[test]
131 fn test_build_size_sar_idc_255() {
132 let mut data = Vec::new();
134 let mut writer = BitWriter::new(&mut data);
135
136 writer.write_bits(255, 8).unwrap();
137 writer.write_bits(11, 16).unwrap();
138 writer.write_bits(32, 16).unwrap();
139 writer.finish().unwrap();
140
141 let mut reader = BitReader::new_from_slice(&mut data);
143 let sample_aspect_ratio = SarDimensions::parse(&mut reader).unwrap();
144
145 let mut buf = Vec::new();
147 let mut writer2 = BitWriter::new(&mut buf);
148
149 sample_aspect_ratio.build(&mut writer2).unwrap();
151 writer2.finish().unwrap();
152
153 assert_eq!(buf, data);
154
155 let mut reader2 = BitReader::new_from_slice(buf);
158 let rebuilt_sample_aspect_ratio = SarDimensions::parse(&mut reader2).unwrap();
159
160 assert_eq!(rebuilt_sample_aspect_ratio.bitsize(), sample_aspect_ratio.bitsize());
162 assert_eq!(rebuilt_sample_aspect_ratio.bytesize(), sample_aspect_ratio.bytesize());
163 }
164}