]>
Commit | Line | Data |
---|---|---|
40494a85 KS |
1 | use nihav_core::codecs::*; |
2 | use nihav_core::io::byteio::*; | |
3 | use nihav_core::io::bitreader::*; | |
4 | use nihav_core::io::intcode::*; | |
5 | use std::str::FromStr; | |
6 | ||
7 | struct ALACDecoder { | |
8 | ainfo: NAAudioInfo, | |
9 | chmap: NAChannelMap, | |
10 | bits: u8, | |
11 | frame_len: usize, | |
12 | samples_l: Vec<i32>, | |
13 | samples_r: Vec<i32>, | |
14 | cur_len: usize, | |
15 | ||
16 | pb: u8, | |
17 | kb: u8, | |
18 | mb: u8, | |
19 | } | |
20 | ||
21 | #[derive(Default,Clone,Copy)] | |
22 | struct PredInfo { | |
23 | mode: u8, | |
24 | shift: u8, | |
25 | factor: u8, | |
26 | order: usize, | |
27 | filt: [i32; 32], | |
28 | } | |
29 | ||
30 | fn read_code(br: &mut BitReader, k: u8, bits: u8) -> DecoderResult<u32> { | |
31 | let pfx = br.read_code(UintCodeType::LimitedUnary(9, 0))?; | |
32 | if pfx < 9 { | |
33 | if k > 1 { | |
34 | let tail = br.read(k - 1)?; | |
35 | if tail != 0 { | |
36 | Ok((pfx << k) - pfx + tail * 2 + br.read(1)? - 1) | |
37 | } else { | |
38 | Ok((pfx << k) - pfx) | |
39 | } | |
40 | } else { | |
41 | Ok(pfx) | |
42 | } | |
43 | } else { | |
44 | Ok(br.read(bits)?) | |
45 | } | |
46 | } | |
47 | ||
48 | fn clip_sample(val: i32, bits: u8) -> i32 { | |
49 | val << (32 - bits) >> (32 - bits) | |
50 | } | |
51 | ||
52 | impl PredInfo { | |
53 | fn read_header(&mut self, br: &mut BitReader, pb: u8) -> DecoderResult<()> { | |
54 | self.mode = br.read(4)? as u8; | |
55 | if self.mode != 0 && self.mode != 15 { | |
56 | return Err(DecoderError::NotImplemented); | |
57 | } | |
58 | self.shift = br.read(4)? as u8; | |
59 | self.factor = (br.read(3)? as u8) * pb / 4; | |
60 | self.order = br.read(5)? as usize; | |
61 | for coef in self.filt.iter_mut().take(self.order).rev() { | |
62 | *coef = br.read_s(16)?; | |
63 | } | |
64 | Ok(()) | |
65 | } | |
66 | fn read_data(&mut self, br: &mut BitReader, dst: &mut [i32], kb: u8, mb: u8, bits: u8) -> DecoderResult<()> { | |
67 | let mut history = u32::from(mb); | |
68 | let mut add = 0; | |
69 | let dst_len = dst.len(); | |
70 | let mut zero_run = 0; | |
71 | for (i, samp) in dst.iter_mut().enumerate() { | |
72 | if zero_run > 0 { | |
73 | *samp = 0; | |
74 | zero_run -= 1; | |
75 | continue; | |
76 | } | |
77 | let k = ((31 - ((history >> 9) + 3).leading_zeros()) as u8).min(kb); | |
78 | ||
79 | let val = read_code(br, k, bits)? + add; | |
80 | add = 0; | |
81 | *samp = if (val & 1) == 0 { val as i32 >> 1 } else { -(val as i32 >> 1) - 1 }; | |
82 | ||
83 | if val > 0xFFFF { | |
84 | history = 0xFFFF; | |
85 | } else { | |
86 | history -= (history * u32::from(self.factor)) >> 9; | |
87 | history += val * u32::from(self.factor) | |
88 | } | |
89 | ||
90 | if history < 128 && (i + 1 < dst_len) { | |
91 | let k = (((history as u8).leading_zeros() as u8) + (((history + 16) >> 6) as u8)).min(kb); | |
92 | zero_run = read_code(br, k, 16)?; | |
93 | if zero_run < 0x10000 { | |
94 | add = 1; | |
95 | } | |
96 | history = 0; | |
97 | } | |
98 | } | |
99 | Ok(()) | |
100 | } | |
101 | fn lpc_pred(&mut self, samps: &mut [i32], bits: u8) { | |
102 | if self.mode == 15 || self.order == 31 { | |
103 | for i in 1..samps.len() { | |
104 | samps[i] = clip_sample(samps[i].wrapping_add(samps[i - 1]), bits); | |
105 | } | |
106 | } | |
107 | if self.order == 0 { | |
108 | return; | |
109 | } | |
110 | for i in 0..self.order { | |
111 | samps[i + 1] = clip_sample(samps[i + 1].wrapping_add(samps[i]), bits); | |
112 | } | |
113 | for i in self.order+1..samps.len() { | |
114 | let mut diff = samps[i]; | |
115 | ||
116 | let el0 = samps[i - self.order - 1]; | |
117 | let mut sum = 0i32; | |
118 | for j in 0..self.order { | |
119 | sum = sum.wrapping_add((samps[i - self.order + j] - el0).wrapping_mul(self.filt[j])); | |
120 | } | |
121 | sum = (sum + ((1 << self.shift) >> 1)) >> self.shift; | |
122 | samps[i] = clip_sample(samps[i].wrapping_add(el0).wrapping_add(sum), bits); | |
123 | ||
124 | if diff != 0 { | |
125 | let sign = if diff > 0 { 1 } else { -1 }; | |
126 | for j in 0..self.order { | |
127 | if diff * sign <= 0 { | |
128 | break; | |
129 | } | |
130 | let cur_diff = el0 - samps[i - self.order + j]; | |
131 | let dsign = if cur_diff > 0 { 1 } else if cur_diff < 0 { -1 } else { 0 } * sign; | |
132 | self.filt[j] -= dsign; | |
133 | diff -= ((cur_diff * dsign) >> self.shift) * ((j + 1) as i32); | |
134 | } | |
135 | } | |
136 | } | |
137 | } | |
138 | } | |
139 | ||
140 | impl ALACDecoder { | |
141 | fn new() -> Self { | |
142 | Self { | |
143 | ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 1), | |
144 | chmap: NAChannelMap::new(), | |
145 | bits: 0, | |
146 | frame_len: 0, | |
147 | samples_l: Vec::new(), | |
148 | samples_r: Vec::new(), | |
149 | cur_len: 0, | |
150 | ||
151 | pb: 0, | |
152 | mb: 0, | |
153 | kb: 0, | |
154 | } | |
155 | } | |
156 | #[allow(clippy::collapsible_if)] | |
157 | fn decode_elem(&mut self, br: &mut BitReader, stereo: bool) -> DecoderResult<()> { | |
158 | let _element_instance = br.read(4)?; | |
159 | br.skip(12)?; | |
160 | let partial = br.read_bool()?; | |
161 | let shift = (br.read(2)? * 8) as u8; | |
162 | let escape = br.read_bool()?; | |
163 | self.cur_len = if partial { | |
164 | br.read(32)? as usize | |
165 | } else { self.frame_len }; | |
166 | ||
167 | if !escape { | |
168 | validate!(shift <= self.bits); | |
169 | let sbits = self.bits - shift + if stereo { 1 } else { 0 }; | |
170 | let channels = if stereo { 2 } else { 1 }; | |
171 | ||
172 | let mix_bits = br.read(8)?; | |
173 | let mix_res = br.read_s(8)?; | |
174 | let mut pinfo = [PredInfo::default(); 2]; | |
175 | for info in pinfo.iter_mut().take(channels) { | |
176 | info.read_header(br, self.pb)?; | |
177 | } | |
178 | let ebits_pos = br.tell() as u32; | |
179 | br.skip((shift as u32) * (self.cur_len as u32) * (channels as u32))?; | |
180 | pinfo[0].read_data(br, &mut self.samples_l[..self.cur_len], self.kb, self.mb, sbits)?; | |
181 | pinfo[0].lpc_pred(&mut self.samples_l[..self.cur_len], sbits); | |
182 | if stereo { | |
183 | pinfo[1].read_data(br, &mut self.samples_r[..self.cur_len], self.kb, self.mb, sbits)?; | |
184 | pinfo[1].lpc_pred(&mut self.samples_r[..self.cur_len], sbits); | |
185 | } | |
186 | if stereo && mix_res != 0 { | |
187 | let weight = mix_res; | |
188 | for (l, r) in self.samples_l[..self.cur_len].iter_mut().zip(self.samples_r[..self.cur_len].iter_mut()) { | |
189 | let mut a = *l; | |
190 | let b = *r; | |
191 | a -= (b * weight) >> mix_bits; | |
192 | *l = a + b; | |
193 | *r = a; | |
194 | } | |
195 | } | |
196 | if shift > 0 { | |
197 | let end_pos = br.tell() as u32; | |
198 | br.seek(ebits_pos)?; | |
199 | for i in 0..self.cur_len { | |
200 | self.samples_l[i] = (self.samples_l[i] << shift) | (br.read(shift)? as i32); | |
201 | if stereo { | |
202 | self.samples_r[i] = (self.samples_r[i] << shift) | (br.read(shift)? as i32); | |
203 | } | |
204 | } | |
205 | br.seek(end_pos)?; | |
206 | } | |
207 | } else { | |
208 | if !stereo { | |
209 | for dst in self.samples_l.iter_mut().take(self.cur_len) { | |
210 | *dst = br.read_s(self.bits)? << shift; | |
211 | } | |
212 | } else { | |
213 | for (l, r) in self.samples_l.iter_mut().zip(self.samples_r.iter_mut()).take(self.cur_len) { | |
214 | *l = br.read_s(self.bits)? << shift; | |
215 | *r = br.read_s(self.bits)? << shift; | |
216 | } | |
217 | } | |
218 | } | |
219 | ||
220 | ||
221 | Ok(()) | |
222 | } | |
223 | fn output_i16(&self, dst: &mut [i16], stride: usize, shift: u8, stereo: bool) { | |
224 | if !stereo { | |
225 | for (dst, &src) in dst[..self.frame_len].iter_mut().zip(self.samples_l.iter()) { | |
226 | *dst = (src << shift) as i16; | |
227 | } | |
228 | } else { | |
229 | let (l, r) = dst.split_at_mut(stride); | |
230 | for i in 0..self.frame_len { | |
231 | l[i] = (self.samples_l[i] << shift) as i16; | |
232 | r[i] = (self.samples_r[i] << shift) as i16; | |
233 | } | |
234 | } | |
235 | } | |
236 | fn output_i32(&self, dst: &mut [i32], stride: usize, shift: u8, stereo: bool) { | |
237 | if !stereo { | |
238 | for (dst, &src) in dst[..self.frame_len].iter_mut().zip(self.samples_l.iter()) { | |
239 | *dst = src << shift; | |
240 | } | |
241 | } else { | |
242 | let (l, r) = dst.split_at_mut(stride); | |
243 | for i in 0..self.frame_len { | |
244 | l[i] = self.samples_l[i] << shift; | |
245 | r[i] = self.samples_r[i] << shift; | |
246 | } | |
247 | } | |
248 | } | |
249 | } | |
250 | ||
251 | fn skip_dse(br: &mut BitReader) -> DecoderResult<()> { | |
252 | br.skip(4)?; | |
253 | let align = br.read_bool()?; | |
254 | let mut count = br.read(8)?; | |
255 | if count == 255 { | |
256 | count += br.read(8)?; | |
257 | } | |
258 | if align { | |
259 | br.align(); | |
260 | } | |
261 | br.skip(count * 8)?; | |
262 | Ok(()) | |
263 | } | |
264 | ||
265 | fn skip_fil(br: &mut BitReader) -> DecoderResult<()> { | |
266 | let mut count = br.read(4)?; | |
267 | if count == 15 { | |
268 | count = 14 + br.read(8)?; | |
269 | } | |
270 | br.skip(count * 8)?; | |
271 | Ok(()) | |
272 | } | |
273 | ||
274 | impl NADecoder for ALACDecoder { | |
275 | fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { | |
276 | if let (NACodecTypeInfo::Audio(_), Some(edata)) = (info.get_properties(), info.get_extradata()) { | |
277 | validate!(edata.len() >= 12 + 24); | |
278 | ||
279 | let mut mr = MemoryReader::new_read(&edata); | |
280 | let mut br = ByteReader::new(&mut mr); | |
281 | let len = br.read_u32be()? as usize; | |
282 | validate!(len == 12 + 24); | |
283 | let fcc = br.read_tag()?; | |
284 | validate!(&fcc == b"alac"); | |
285 | let _flags = br.read_u32be()?; | |
286 | ||
287 | // config | |
288 | let frame_len = br.read_u32be()? as usize; | |
289 | let version = br.read_byte()?; | |
290 | validate!(version == 0); | |
291 | let bits = br.read_byte()?; | |
292 | validate!(bits >= 8 && bits <= 32); | |
293 | self.pb = br.read_byte()?; | |
294 | validate!(self.pb == 40); | |
295 | self.mb = br.read_byte()?; | |
296 | validate!(self.mb == 10); | |
297 | self.kb = br.read_byte()?; | |
298 | validate!(self.kb == 14); | |
299 | let channels = br.read_byte()?; | |
300 | validate!(channels > 0); | |
301 | let max_run = br.read_u16be()?; | |
302 | validate!(max_run == 255); | |
303 | let _max_frame_bytes = br.read_u32be()? as usize; | |
304 | let _avg_bitrate = br.read_u32be()? as usize; | |
305 | let sample_rate = br.read_u32be()?; | |
306 | ||
307 | let mut chmap = match channels { | |
308 | 1 => "C", | |
309 | 2 => "L,R", | |
310 | 3 => "C,L,R", | |
311 | 4 => "C,L,R,Cs", | |
312 | 5 => "C,L,R,Ls,Rs", | |
313 | 6 => "C,L,R,Ls,Rs,LFE", | |
314 | 7 => "C,L,R,Ls,Rs,Cs,LFE", | |
315 | 8 => "C,Lc,Rc,L,R,Ls,Rs,LFE", | |
316 | _ => return Err(DecoderError::NotImplemented), | |
317 | }; | |
318 | if len + 24 <= edata.len() { | |
319 | let len2 = br.read_u32be()? as usize; | |
320 | let id = br.read_tag()?; | |
321 | let _flags = br.read_u32be()?; | |
322 | if (len2 == 24) && (&id == b"chan") { | |
323 | let layout = br.read_u32be()?; | |
324 | let _rsvd1 = br.read_u32be()?; // 0 | |
325 | let _rsvd2 = br.read_u32be()?; // 0 | |
326 | if (layout as u8) == channels { | |
327 | chmap = match layout { | |
328 | 0x640001 => "C", | |
329 | 0x640002 => "L,R", | |
330 | 0x710003 => "C,L,R", | |
331 | 0x740004 => "C,L,R,Cs", | |
332 | 0x780005 => "C,L,R,Ls,Rs", | |
333 | 0x7C0006 => "C,L,R,Ls,Rs,LFE", | |
334 | 0x8E0007 => "C,L,R,Ls,Rs,Cs,LFE", | |
335 | 0x7F0008 => "C,Lc,Rc,L,R,Ls,Rs,LFE", | |
336 | _ => return Err(DecoderError::NotImplemented), | |
337 | }; | |
338 | } | |
339 | } | |
340 | } | |
341 | ||
342 | self.ainfo = NAAudioInfo::new(sample_rate, channels, if bits <= 16 { SND_S16P_FORMAT } else { SND_S32P_FORMAT }, frame_len); | |
343 | self.chmap = NAChannelMap::from_str(chmap).unwrap(); | |
344 | self.bits = bits; | |
345 | self.frame_len = frame_len; | |
346 | self.samples_l = vec![0; frame_len]; | |
347 | self.samples_r = vec![0; frame_len]; | |
348 | ||
349 | Ok(()) | |
350 | } else { | |
351 | Err(DecoderError::InvalidData) | |
352 | } | |
353 | } | |
354 | fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { | |
355 | let info = pkt.get_stream().get_info(); | |
356 | if let NACodecTypeInfo::Audio(_) = info.get_properties() { | |
357 | let src = pkt.get_buffer(); | |
358 | let channels = self.chmap.num_channels(); | |
2d1e0773 | 359 | let mut abuf = alloc_audio_buffer(self.ainfo, self.frame_len, self.chmap.clone())?; |
40494a85 KS |
360 | |
361 | let mut br = BitReader::new(&src, BitReaderMode::BE); | |
362 | ||
363 | let mut channels_left = channels; | |
364 | if let Some(mut adata) = abuf.get_abuf_i16() { | |
365 | let shift = 16 - self.bits; | |
366 | let stride = adata.get_stride(); | |
367 | let dst = adata.get_data_mut().unwrap(); | |
368 | let mut off = 0; | |
369 | ||
370 | while br.left() >= 3 { | |
371 | let tag = br.read(3)?; | |
372 | match tag { | |
373 | 0 | 3 => { | |
374 | validate!(channels_left >= 1); | |
375 | self.decode_elem(&mut br, false)?; | |
376 | self.output_i16(&mut dst[off..], stride, shift, false); | |
377 | off += stride; | |
378 | channels_left -= 1; | |
379 | }, | |
380 | 1 => { | |
381 | validate!(channels_left >= 2); | |
382 | self.decode_elem(&mut br, true)?; | |
383 | self.output_i16(&mut dst[off..], stride, shift, true); | |
384 | off += stride * 2; | |
385 | channels_left -= 2; | |
386 | }, | |
387 | 4 => skip_dse(&mut br)?, | |
388 | 6 => skip_fil(&mut br)?, | |
389 | 7 => break, | |
390 | _ => return Err(DecoderError::InvalidData), | |
391 | }; | |
392 | } | |
40494a85 KS |
393 | } else if let Some(mut adata) = abuf.get_abuf_i32() { |
394 | let shift = 32 - self.bits; | |
395 | let stride = adata.get_stride(); | |
396 | let dst = adata.get_data_mut().unwrap(); | |
397 | let mut off = 0; | |
398 | ||
399 | while br.left() >= 3 { | |
400 | let tag = br.read(3)?; | |
401 | match tag { | |
402 | 0 | 3 => { | |
403 | validate!(channels_left >= 1); | |
404 | self.decode_elem(&mut br, false)?; | |
405 | self.output_i32(&mut dst[off..], stride, shift, false); | |
406 | off += stride; | |
407 | channels_left -= 1; | |
408 | }, | |
409 | 1 => { | |
410 | validate!(channels_left >= 2); | |
411 | self.decode_elem(&mut br, true)?; | |
412 | self.output_i32(&mut dst[off..], stride, shift, true); | |
413 | off += stride * 2; | |
414 | channels_left -= 2; | |
415 | }, | |
416 | 4 => skip_dse(&mut br)?, | |
417 | 6 => skip_fil(&mut br)?, | |
418 | 7 => break, | |
419 | _ => return Err(DecoderError::InvalidData), | |
420 | }; | |
421 | } | |
40494a85 KS |
422 | } else { |
423 | return Err(DecoderError::Bug); | |
424 | } | |
2d1e0773 | 425 | abuf.truncate_audio(self.cur_len); |
40494a85 KS |
426 | |
427 | let mut frm = NAFrame::new_from_pkt(pkt, info.replace_info(NACodecTypeInfo::Audio(self.ainfo)), abuf); | |
428 | frm.set_duration(Some(self.cur_len as u64)); | |
429 | frm.set_keyframe(true); | |
430 | Ok(frm.into_ref()) | |
431 | } else { | |
432 | Err(DecoderError::InvalidData) | |
433 | } | |
434 | } | |
435 | fn flush(&mut self) { | |
436 | } | |
437 | } | |
438 | ||
439 | impl NAOptionHandler for ALACDecoder { | |
440 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
441 | fn set_options(&mut self, _options: &[NAOption]) { } | |
442 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
443 | } | |
444 | ||
445 | pub fn get_decoder() -> Box<dyn NADecoder + Send> { | |
446 | Box::new(ALACDecoder::new()) | |
447 | } | |
448 | ||
449 | #[cfg(test)] | |
450 | mod test { | |
451 | use nihav_core::codecs::RegisteredDecoders; | |
452 | use nihav_core::demuxers::RegisteredDemuxers; | |
453 | use nihav_codec_support::test::dec_video::*; | |
454 | use crate::qt_register_all_decoders; | |
455 | use nihav_commonfmt::generic_register_all_demuxers; | |
456 | #[test] | |
457 | fn test_alac_16bit() { | |
458 | let mut dmx_reg = RegisteredDemuxers::new(); | |
459 | generic_register_all_demuxers(&mut dmx_reg); | |
460 | let mut dec_reg = RegisteredDecoders::new(); | |
461 | qt_register_all_decoders(&mut dec_reg); | |
462 | ||
463 | test_decoding("mov", "alac", "assets/LLaudio/alac/luckynight.m4a", Some(48000 * 16), &dmx_reg, &dec_reg, | |
464 | ExpectedTestResult::MD5([0x8b6562ac, 0x95981733, 0x47e14709, 0x45d4f05a])); | |
465 | } | |
466 | #[test] | |
467 | fn test_alac_6ch() { | |
468 | let mut dmx_reg = RegisteredDemuxers::new(); | |
469 | generic_register_all_demuxers(&mut dmx_reg); | |
470 | let mut dec_reg = RegisteredDecoders::new(); | |
471 | qt_register_all_decoders(&mut dec_reg); | |
472 | ||
473 | test_decoding("mov", "alac", "assets/LLaudio/alac/ALAC_6ch.mov", None, &dmx_reg, &dec_reg, | |
474 | ExpectedTestResult::MD5([0x0356ff3d, 0x1ddd3684, 0xb4da8b00, 0x8e8671a7])); | |
475 | } | |
476 | #[test] | |
477 | fn test_alac_24bit() { | |
478 | let mut dmx_reg = RegisteredDemuxers::new(); | |
479 | generic_register_all_demuxers(&mut dmx_reg); | |
480 | let mut dec_reg = RegisteredDecoders::new(); | |
481 | qt_register_all_decoders(&mut dec_reg); | |
482 | ||
483 | test_decoding("mov", "alac", "assets/LLaudio/alac/ALAC_24bits2.mov", None, &dmx_reg, &dec_reg, | |
484 | ExpectedTestResult::MD5([0x15d58ed9, 0x9ee74f5e, 0x0fb82c0b, 0x27da35f9])); | |
485 | } | |
486 | } |