]> git.nihav.org Git - nihav.git/blob - nihav-llaudio/src/codecs/ape.rs
add MPEG-4 ASP decoder
[nihav.git] / nihav-llaudio / src / codecs / ape.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_core::io::bitreader::*;
4
5 use super::apepred::*;
6 use super::apereader::*;
7
8 struct APEDecoder {
9 ainfo: NAAudioInfo,
10 chmap: NAChannelMap,
11 version: u16,
12 decode_mono: fn(&mut Coder, &mut [i32]) -> DecoderResult<()>,
13 decode_stereo: fn(&mut Coder, &mut [i32], &mut [i32]) -> DecoderResult<()>,
14 is_stereo: bool,
15 left: Vec<i32>,
16 right: Vec<i32>,
17 fmode: FilterMode,
18 data: Vec<u8>,
19 blocksperframe: usize,
20 }
21
22 impl APEDecoder {
23 fn new() -> Self {
24 Self {
25 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
26 chmap: NAChannelMap::new(),
27 version: 0,
28 decode_mono: decode_mono_dummy,
29 decode_stereo: decode_stereo_dummy,
30 is_stereo: false,
31 left: Vec::new(),
32 right: Vec::new(),
33 fmode: FilterMode::None,
34 data: Vec::new(),
35 blocksperframe: 0,
36 }
37 }
38 }
39
40 impl NADecoder for APEDecoder {
41 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
42 if let NACodecTypeInfo::Audio(_ainfo) = info.get_properties() {
43 if let Some(buf) = info.get_extradata() {
44 let mut mr = MemoryReader::new_read(&buf);
45 let mut br = ByteReader::new(&mut mr);
46 let version = br.read_u16le()?;
47 let compression = br.read_u16le()?;
48 let _flags = br.read_u16le()?;
49 let channels = br.read_byte()?;
50 let bits = br.read_byte()?;
51 let srate = br.read_u32le()?;
52 let blocksperframe = br.read_u32le()? as usize;
53
54 validate!(channels > 0);
55 validate!(bits > 0 && bits <= 32);
56 validate!((compression % 1000) == 0 && compression > 0 && compression <= 5000);
57 validate!(compression < 5000 || version >= 3930);
58 if bits != 16 {
59 return Err(DecoderError::NotImplemented);
60 }
61 if version > 3990 {
62 return Err(DecoderError::NotImplemented);
63 }
64
65 self.version = version;
66 self.blocksperframe = blocksperframe;
67 self.is_stereo = channels == 2;
68 self.left.resize(blocksperframe, 0);
69 if self.is_stereo {
70 self.right.resize(blocksperframe, 0);
71 }
72
73 self.decode_mono = if version >= 3990 {
74 decode_mono_3990
75 } else if version >= 3910 {
76 decode_mono_3910
77 } else if version >= 3900 {
78 decode_mono_3900
79 } else if version >= 3890 {
80 decode_mono_3890
81 } else if version >= 3860 {
82 decode_mono_3860
83 } else {
84 decode_mono_0000
85 };
86 self.decode_stereo = if version >= 3990 {
87 decode_stereo_3990
88 } else if version >= 3930 {
89 decode_stereo_3930
90 } else if version >= 3910 {
91 decode_stereo_3910
92 } else if version >= 3900 {
93 decode_stereo_3900
94 } else if version >= 3890 {
95 decode_stereo_3890
96 } else if version >= 3860 {
97 decode_stereo_3860
98 } else {
99 decode_stereo_0000
100 };
101 self.fmode = FilterMode::new(version, compression);
102
103 self.chmap = if channels == 1 {
104 NAChannelMap::from_str("C").unwrap()
105 } else if channels == 2 {
106 NAChannelMap::from_str("L,R").unwrap()
107 } else {
108 return Err(DecoderError::NotImplemented);
109 };
110 self.ainfo = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, 4602);
111 Ok(())
112 } else {
113 Err(DecoderError::InvalidData)
114 }
115 } else {
116 Err(DecoderError::InvalidData)
117 }
118 }
119 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
120 let info = pkt.get_stream().get_info();
121 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
122 let pktbuf = pkt.get_buffer();
123 validate!(pktbuf.len() > 9);
124
125 let nblocks = read_u32le(&pktbuf[0..])? as usize;
126 validate!(nblocks > 0);
127 let bits = u32::from(pktbuf[4]);
128 validate!(bits < 32);
129 self.data.clear();
130 self.data.reserve((pktbuf.len() & !3) + 2);
131 for word in pktbuf[8..].chunks_exact(4) {
132 self.data.push(word[3]);
133 self.data.push(word[2]);
134 self.data.push(word[1]);
135 self.data.push(word[0]);
136 }
137 if self.version < 3950 {
138 self.data.push(0);
139 self.data.push(0);
140 }
141
142 let (mut coder, ref_crc, fflags) = if self.version < 3900 {
143 let mut br = BitReader::new(&self.data, BitReaderMode::BE);
144 br.skip(bits)?;
145 let mut crc = br.read(32)?;
146 let fflags = if self.version >= 3830 && (crc & 0x80000000) != 0 {
147 crc ^= 0x80000000;
148 br.read(32)?
149 } else {
150 0
151 };
152 (Coder::Rice(RiceCoder::new(br)), crc, fflags)
153 } else {
154 let mut boff = (bits / 8) as usize;
155 let mut crc = read_u32be(&self.data[boff..])?;
156 boff += 4;
157 let fflags = if (crc & 0x80000000) != 0 {
158 crc ^= 0x80000000;
159 let flg = read_u32be(&self.data[boff..])?;
160 boff += 4;
161 flg
162 } else {
163 0
164 };
165 // it ignores first byte anyway
166 (Coder::Range(RangeCoder::new(&self.data[boff + 1..])), crc, fflags)
167 };
168 self.left.resize(nblocks, 0);
169 if self.is_stereo {
170 self.right.resize(nblocks, 0);
171 }
172 if (!self.is_stereo && (fflags & 1) == 0) || (self.is_stereo && (fflags & 3) != 3) {
173 if !self.is_stereo || (fflags & 4) != 0 {
174 (self.decode_mono)(&mut coder, &mut self.left)?;
175 self.fmode.filter_mono(&mut self.left);
176
177 if (fflags & 4) != 0 {
178 self.right.copy_from_slice(&self.left);
179 }
180 } else {
181 (self.decode_stereo)(&mut coder, &mut self.left, &mut self.right)?;
182 self.fmode.filter_stereo(&mut self.left, &mut self.right);
183 }
184 } else {
185 for l in self.left.iter_mut() { *l = 0; }
186 if self.is_stereo {
187 for r in self.right.iter_mut() { *r = 0; }
188 }
189 }
190
191 if self.version >= 0x3990 || nblocks == self.blocksperframe {
192 let mut crc = 0xFFFFFFFF;
193 if !self.is_stereo {
194 for el in self.left.iter() {
195 let byte1 = *el as u8;
196 let byte0 = (*el >> 8) as u8;
197 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte1) as usize];
198 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte0) as usize];
199 }
200 } else {
201 for (l, r) in self.left.iter().zip(self.right.iter()) {
202 let byte1 = *l as u8;
203 let byte0 = (*l >> 8) as u8;
204 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte1) as usize];
205 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte0) as usize];
206 let byte1 = *r as u8;
207 let byte0 = (*r >> 8) as u8;
208 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte1) as usize];
209 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte0) as usize];
210 }
211 }
212 crc = !crc;
213 if self.version >= 3830 {
214 crc >>= 1;
215 }
216 if crc != ref_crc {
217 return Err(DecoderError::ChecksumError);
218 }
219 }
220
221 let abuf = alloc_audio_buffer(self.ainfo, nblocks, self.chmap.clone())?;
222 let mut adata = abuf.get_abuf_i16().unwrap();
223 let off1 = adata.get_offset(1);
224 let dst = adata.get_data_mut().unwrap();
225 let (left, right) = dst.split_at_mut(off1);
226 for (dst, src) in left.iter_mut().zip(self.left.iter()) {
227 *dst = *src as i16;
228 }
229 if self.is_stereo {
230 for (dst, src) in right.iter_mut().zip(self.right.iter()) {
231 *dst = *src as i16;
232 }
233 }
234
235 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
236 frm.set_duration(Some(nblocks as u64));
237 Ok(frm.into_ref())
238 } else {
239 Err(DecoderError::InvalidData)
240 }
241 }
242 fn flush(&mut self) {
243 }
244 }
245
246 impl NAOptionHandler for APEDecoder {
247 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
248 fn set_options(&mut self, _options: &[NAOption]) { }
249 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
250 }
251
252 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
253 Box::new(APEDecoder::new())
254 }
255
256 #[cfg(test)]
257 mod test {
258 use nihav_core::codecs::RegisteredDecoders;
259 use nihav_core::demuxers::RegisteredDemuxers;
260 use nihav_codec_support::test::dec_video::*;
261 use crate::llaudio_register_all_decoders;
262 use crate::llaudio_register_all_demuxers;
263 // samples from Libav test suite
264 #[test]
265 fn test_ape_3990() {
266 let mut dmx_reg = RegisteredDemuxers::new();
267 llaudio_register_all_demuxers(&mut dmx_reg);
268 let mut dec_reg = RegisteredDecoders::new();
269 llaudio_register_all_decoders(&mut dec_reg);
270
271 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight.ape", Some(3), &dmx_reg, &dec_reg,
272 ExpectedTestResult::MD5([0x569e002b, 0xd93772a9, 0x1cfd81cd, 0xad81319a]));
273 }
274 #[test]
275 fn test_ape_3940() {
276 let mut dmx_reg = RegisteredDemuxers::new();
277 llaudio_register_all_demuxers(&mut dmx_reg);
278 let mut dec_reg = RegisteredDecoders::new();
279 llaudio_register_all_decoders(&mut dec_reg);
280
281 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac394b1-c4000.ape", Some(1), &dmx_reg, &dec_reg,
282 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
283 }
284 #[test]
285 fn test_ape_3920() {
286 let mut dmx_reg = RegisteredDemuxers::new();
287 llaudio_register_all_demuxers(&mut dmx_reg);
288 let mut dec_reg = RegisteredDecoders::new();
289 llaudio_register_all_decoders(&mut dec_reg);
290
291 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac392b2-c4000.ape", Some(1), &dmx_reg, &dec_reg,
292 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
293 }
294 #[test]
295 fn test_ape_3910() {
296 let mut dmx_reg = RegisteredDemuxers::new();
297 llaudio_register_all_demuxers(&mut dmx_reg);
298 let mut dec_reg = RegisteredDecoders::new();
299 llaudio_register_all_decoders(&mut dec_reg);
300
301 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac391b1-c4000.ape", Some(1), &dmx_reg, &dec_reg,
302 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
303 }
304 #[test]
305 fn test_ape_3890() {
306 let mut dmx_reg = RegisteredDemuxers::new();
307 llaudio_register_all_demuxers(&mut dmx_reg);
308 let mut dec_reg = RegisteredDecoders::new();
309 llaudio_register_all_decoders(&mut dec_reg);
310
311 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac389b1-c4000.ape", Some(1), &dmx_reg, &dec_reg,
312 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
313 }
314 #[test]
315 fn test_ape_3880() {
316 let mut dmx_reg = RegisteredDemuxers::new();
317 llaudio_register_all_demuxers(&mut dmx_reg);
318 let mut dec_reg = RegisteredDecoders::new();
319 llaudio_register_all_decoders(&mut dec_reg);
320
321 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac388-c4000.ape", Some(1), &dmx_reg, &dec_reg,
322 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
323 }
324 #[test]
325 fn test_ape_3800() {
326 let mut dmx_reg = RegisteredDemuxers::new();
327 llaudio_register_all_demuxers(&mut dmx_reg);
328 let mut dec_reg = RegisteredDecoders::new();
329 llaudio_register_all_decoders(&mut dec_reg);
330
331 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac380-c4000.ape", Some(1), &dmx_reg, &dec_reg,
332 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
333 }
334 }
335
336 const CRC32_TAB: [u32; 256] = [
337 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
338 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
339 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
340 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
341 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
342 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
343 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
344 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
345 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
346 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
347 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
348 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
349 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
350 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
351 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
352 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
353 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
354 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
355 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
356 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
357 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
358 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
359 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
360 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
361 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
362 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
363 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
364 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
365 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
366 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
367 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
368 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
369 ];