]>
Commit | Line | Data |
---|---|---|
16cca4d3 KS |
1 | use nihav_core::codecs::*; |
2 | use nihav_core::io::bitreader::*; | |
3 | use nihav_codec_support::dsp::qmf::QMF; | |
4 | ||
5 | mod mp3data; | |
6 | mod mp3code; | |
7 | use mp3code::*; | |
8 | ||
9 | const SAMPLES: usize = 1152; | |
d686ebc4 | 10 | const BYTEBUF_SIZE: usize = 2048; |
16cca4d3 KS |
11 | |
12 | #[allow(clippy::large_enum_variant)] | |
13 | enum LayerData { | |
14 | MP1, | |
15 | MP2, | |
16 | MP3(MP3Data), | |
17 | } | |
18 | ||
19 | impl LayerData { | |
20 | fn layer_id(&self) -> u8 { | |
21 | match *self { | |
22 | LayerData::MP1 => 0, | |
23 | LayerData::MP2 => 1, | |
24 | LayerData::MP3(_) => 2, | |
25 | } | |
26 | } | |
27 | fn reset(&mut self) { | |
28 | match self { | |
29 | LayerData::MP1 => {}, | |
30 | LayerData::MP2 => {}, | |
31 | LayerData::MP3(ref mut data) => data.reset(), | |
32 | }; | |
33 | } | |
34 | } | |
35 | ||
36 | struct MPADecoder { | |
37 | info: NACodecInfoRef, | |
38 | smap: NAChannelMap, | |
39 | mmap: NAChannelMap, | |
40 | qmf: [QMF; 2], | |
41 | srate: u32, | |
42 | channels: u8, | |
43 | sf_idx: usize, | |
44 | ||
45 | bytebuf: Vec<u8>, | |
46 | coeffs: [[f32; SAMPLES]; 2], | |
47 | out: [[[f32; 32]; 36]; 2], | |
48 | ctx: LayerData, | |
49 | } | |
50 | ||
51 | impl MPADecoder { | |
52 | fn new(layer: u8) -> Self { | |
53 | let ctx = match layer { | |
54 | 0 => LayerData::MP1, | |
55 | 1 => LayerData::MP2, | |
56 | 2 => LayerData::MP3(MP3Data::new()), | |
57 | _ => unreachable!(), | |
58 | }; | |
59 | Self { | |
60 | info: NACodecInfo::new_dummy(), | |
61 | smap: NAChannelMap::from_ms_mapping(3), | |
62 | mmap: NAChannelMap::from_ms_mapping(4), | |
63 | qmf: [QMF::new(), QMF::new()], | |
64 | srate: 0, | |
65 | channels: 0, | |
66 | sf_idx: 0, | |
67 | ctx, | |
68 | ||
69 | bytebuf: Vec::with_capacity(BYTEBUF_SIZE), | |
70 | coeffs: [[0.0; SAMPLES]; 2], | |
71 | out: [[[0.0; 32]; 36]; 2], | |
72 | } | |
73 | } | |
74 | fn read_mp3_side_data(&mut self, br: &mut BitReader, src: &[u8], mono: bool) -> DecoderResult<()> { | |
75 | if let LayerData::MP3(ref mut ctx) = self.ctx { | |
76 | let channels = if mono { 1 } else { 2 }; | |
77 | ctx.mpeg1 = self.sf_idx < 3; | |
78 | ctx.sf_idx = self.sf_idx; | |
79 | ctx.read_mp3_side_data(br, channels)?; | |
80 | let hdr_size = (br.tell() / 8) as usize; | |
81 | let add_len = src.len() - hdr_size; | |
82 | if self.bytebuf.len() + add_len > BYTEBUF_SIZE { | |
83 | self.bytebuf.drain(..self.bytebuf.len() + add_len - BYTEBUF_SIZE); | |
84 | } | |
85 | let underrun = self.bytebuf.len() < ctx.main_data_end; | |
86 | let del_len = if !underrun { self.bytebuf.len() - ctx.main_data_end } else { 0 }; | |
87 | self.bytebuf.extend_from_slice(&src[hdr_size..]); | |
88 | self.bytebuf.drain(..del_len); | |
89 | if underrun { | |
90 | return Err(DecoderError::MissingReference); | |
91 | } | |
92 | ||
93 | Ok(()) | |
94 | } else { | |
95 | Err(DecoderError::Bug) | |
96 | } | |
97 | } | |
98 | fn decode_layer3(&mut self, channels: usize, mode_ext: u8) -> DecoderResult<bool> { | |
99 | if let LayerData::MP3(ref mut ctx) = self.ctx { | |
100 | let mut br = BitReader::new(&self.bytebuf, BitReaderMode::BE); | |
101 | if ctx.mpeg1 { | |
102 | ctx.decode_mpeg1_layer3(&mut br, &mut self.coeffs, channels)?; | |
103 | } else { | |
104 | ctx.decode_mpeg2_layer3(&mut br, &mut self.coeffs, channels, mode_ext)?; | |
105 | } | |
106 | let used_data = (br.tell() + 7) / 8; | |
107 | self.bytebuf.drain(..used_data); | |
108 | ||
109 | Ok(true) | |
110 | } else { | |
111 | Err(DecoderError::Bug) | |
112 | } | |
113 | } | |
114 | fn synth_layer3(&mut self, mode: u8, mode_ext: u8) { | |
115 | if let LayerData::MP3(ref mut ctx) = self.ctx { | |
116 | ctx.synth(&mut self.coeffs, &mut self.out, mode, mode_ext); | |
117 | } | |
118 | } | |
119 | } | |
120 | ||
121 | fn apply_ms(ch0: &mut [f32], ch1: &mut [f32]) { | |
122 | for (l, r) in ch0.iter_mut().zip(ch1) { | |
123 | let ll = (*l + *r) * std::f32::consts::FRAC_1_SQRT_2; | |
124 | let rr = (*l - *r) * std::f32::consts::FRAC_1_SQRT_2; | |
125 | *l = ll; | |
126 | *r = rr; | |
127 | } | |
128 | } | |
129 | ||
130 | impl NADecoder for MPADecoder { | |
131 | fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { | |
132 | if let NACodecTypeInfo::Audio(_ainfo) = info.get_properties() { | |
133 | self.info = info.clone(); | |
134 | Ok(()) | |
135 | } else { | |
136 | Err(DecoderError::InvalidData) | |
137 | } | |
138 | } | |
139 | fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { | |
140 | let info = pkt.get_stream().get_info(); | |
141 | if let NACodecTypeInfo::Audio(_) = info.get_properties() { | |
142 | let src = pkt.get_buffer(); | |
143 | ||
144 | let mut br = BitReader::new(src.as_slice(), BitReaderMode::BE); | |
145 | ||
146 | let syncword = br.read(11)?; | |
147 | validate!(syncword == 0x7FF); | |
148 | let id = br.read(2)?; | |
149 | validate!(id != 1); | |
150 | let layer = (br.read(2)? ^ 3) as u8; | |
151 | validate!(layer != 3); | |
152 | let protection = br.read_bool()?; | |
153 | let bitrate_index = br.read(4)? as usize; | |
154 | validate!(bitrate_index < 15); | |
155 | if bitrate_index == 0 { | |
156 | //todo freeform eventually | |
157 | unimplemented!(); | |
158 | } | |
159 | let mut sf_idx = br.read(2)? as usize; | |
160 | validate!(sf_idx != 3); | |
161 | let padding = br.read_bool()?; | |
162 | let _private = br.read_bool()?; | |
163 | let mode = br.read(2)? as u8; | |
164 | let mode_extension = br.read(2)? as u8; | |
165 | let _copyright = br.read_bool()?; | |
166 | let _original = br.read_bool()?; | |
167 | let _emphasis = br.read(2)?; | |
168 | if !protection { | |
169 | let _crc_check = br.read(16)?; | |
170 | } | |
171 | validate!(layer == self.ctx.layer_id()); | |
172 | match id { | |
173 | 0 => sf_idx += 6, | |
174 | 2 => sf_idx += 3, | |
175 | _ => {}, | |
176 | }; | |
177 | let mpeg1 = id == 3; | |
178 | let srate = SAMPLING_RATE[sf_idx]; | |
179 | if self.srate == 0 { | |
180 | self.srate = srate; | |
181 | } | |
182 | validate!(srate == self.srate); | |
183 | let channels = if mode == 3 { 1 } else { 2 }; | |
184 | if self.channels == 0 { | |
185 | self.channels = channels; | |
186 | } | |
187 | if channels != self.channels { | |
188 | self.flush(); | |
189 | } | |
190 | let bitrate = BITRATE[if mpeg1 { 0 } else { 1 }][layer as usize][bitrate_index]; | |
191 | let frame_size = match layer { | |
192 | 0 => { | |
193 | ((SAMPLES / 3 / 8 * 1000 * (bitrate as usize) / (srate as usize)) & !3) + if padding { 4 } else { 0 } | |
194 | }, | |
195 | 2 if !mpeg1 => { | |
196 | SAMPLES / 2 / 8 * 1000 * (bitrate as usize) / (srate as usize) + if padding { 1 } else { 0 } | |
197 | }, | |
198 | _ => { | |
199 | SAMPLES / 8 * 1000 * (bitrate as usize) / (srate as usize) + if padding { 1 } else { 0 } | |
200 | }, | |
201 | }; | |
202 | validate!(src.len() >= frame_size); | |
203 | self.sf_idx = sf_idx; | |
204 | ||
205 | let nsamples = if mpeg1 { SAMPLES } else { SAMPLES / 2 }; | |
206 | ||
207 | let ainfo = NAAudioInfo::new(srate, channels, SND_F32P_FORMAT, nsamples); | |
208 | let chmap = if channels == 1 { self.mmap.clone() } else { self.smap.clone() }; | |
209 | ||
210 | let mut abuf = alloc_audio_buffer(ainfo, nsamples, chmap)?; | |
211 | let mut adata = abuf.get_abuf_f32().unwrap(); | |
212 | let off = if channels == 1 { adata.get_length() } else { adata.get_stride() }; | |
213 | let buf = adata.get_data_mut().unwrap(); | |
214 | let (ch0, ch1) = buf.split_at_mut(off); | |
215 | ||
216 | match layer { | |
217 | 0 => unimplemented!(), | |
218 | 1 => unimplemented!(), | |
219 | _ => { | |
220 | let ret = self.read_mp3_side_data(&mut br, &src[..frame_size], channels == 1); | |
221 | match ret { | |
222 | Err(DecoderError::MissingReference) => { | |
223 | abuf.truncate_audio(0); | |
224 | let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf); | |
225 | frm.set_duration(Some(0)); | |
226 | return Ok(frm.into_ref()); | |
227 | }, | |
228 | Err(err) => return Err(err), | |
229 | Ok(()) => {}, | |
230 | }; | |
231 | let has_data = self.decode_layer3(channels as usize, mode_extension)?; | |
232 | if !has_data { | |
233 | let frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None); | |
234 | return Ok(frm.into_ref()); | |
235 | } | |
236 | self.synth_layer3(mode, mode_extension); | |
237 | for (dst, src) in ch0.chunks_exact_mut(32).zip(self.out[0].iter_mut()) { | |
238 | self.qmf[0].synth(src, dst); | |
239 | } | |
240 | if channels == 2 { | |
241 | for (dst, src) in ch1.chunks_mut(32).zip(self.out[1].iter_mut()) { | |
242 | self.qmf[1].synth(src, dst); | |
243 | } | |
244 | } | |
245 | }, | |
246 | }; | |
247 | ||
248 | let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf); | |
249 | frm.set_duration(Some(nsamples as u64)); | |
250 | frm.set_keyframe(true); | |
251 | Ok(frm.into_ref()) | |
252 | } else { | |
253 | Err(DecoderError::Bug) | |
254 | } | |
255 | } | |
256 | fn flush(&mut self) { | |
257 | for qmf in self.qmf.iter_mut() { | |
258 | *qmf = QMF::new(); | |
259 | } | |
260 | self.bytebuf.clear(); | |
261 | self.ctx.reset(); | |
262 | } | |
263 | } | |
264 | ||
265 | impl NAOptionHandler for MPADecoder { | |
266 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
267 | fn set_options(&mut self, _options: &[NAOption]) { } | |
268 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
269 | } | |
270 | ||
271 | pub fn get_decoder_mp3() -> Box<dyn NADecoder + Send> { | |
272 | Box::new(MPADecoder::new(2)) | |
273 | } | |
274 | ||
f27c73df KS |
275 | #[derive(Clone,Copy,Debug)] |
276 | struct MPAHeader { | |
277 | layer: u8, | |
278 | srate: u32, | |
279 | channels: u8, | |
280 | frame_size: usize, | |
281 | nsamples: usize, | |
282 | } | |
283 | ||
284 | impl PartialEq for MPAHeader { | |
285 | fn eq(&self, other: &Self) -> bool { | |
286 | self.layer == other.layer && | |
287 | self.srate == other.srate && | |
288 | self.channels == other.channels | |
289 | } | |
290 | } | |
291 | ||
292 | #[derive(Default)] | |
293 | struct MPAPacketiser { | |
294 | buf: Vec<u8>, | |
295 | hdr: Option<MPAHeader>, | |
296 | } | |
297 | ||
298 | impl MPAPacketiser { | |
299 | fn new() -> Self { Self::default() } | |
300 | fn parse_header(&self, off: usize) -> DecoderResult<MPAHeader> { | |
301 | if self.buf.len() < off + 4 { return Err(DecoderError::ShortData); } | |
302 | ||
303 | let mut br = BitReader::new(&self.buf[off..], BitReaderMode::BE); | |
304 | ||
305 | let syncword = br.read(11)?; | |
306 | validate!(syncword == 0x7FF); | |
307 | let id = br.read(2)?; | |
308 | validate!(id != 1); | |
309 | let layer = (br.read(2)? ^ 3) as u8; | |
310 | validate!(layer != 3); | |
311 | let _protection = br.read_bool()?; | |
312 | let bitrate_index = br.read(4)? as usize; | |
313 | validate!(bitrate_index < 15); | |
314 | if bitrate_index == 0 { | |
315 | //todo freeform eventually | |
316 | unimplemented!(); | |
317 | } | |
318 | let mut sf_idx = br.read(2)? as usize; | |
319 | validate!(sf_idx != 3); | |
320 | let padding = br.read_bool()?; | |
321 | let _private = br.read_bool()?; | |
322 | let mode = br.read(2)? as u8; | |
323 | ||
324 | match id { | |
325 | 0 => sf_idx += 6, | |
326 | 2 => sf_idx += 3, | |
327 | _ => {}, | |
328 | }; | |
329 | let mpeg1 = id == 3; | |
330 | let srate = SAMPLING_RATE[sf_idx]; | |
331 | let channels = if mode == 3 { 1 } else { 2 }; | |
332 | let bitrate = BITRATE[if mpeg1 { 0 } else { 1 }][layer as usize][bitrate_index]; | |
333 | let frame_size = match layer { | |
334 | 0 => { | |
335 | ((SAMPLES / 3 / 8 * 1000 * (bitrate as usize) / (srate as usize)) & !3) + if padding { 4 } else { 0 } | |
336 | }, | |
337 | 2 if !mpeg1 => { | |
338 | SAMPLES / 2 / 8 * 1000 * (bitrate as usize) / (srate as usize) + if padding { 1 } else { 0 } | |
339 | }, | |
340 | _ => { | |
341 | SAMPLES / 8 * 1000 * (bitrate as usize) / (srate as usize) + if padding { 1 } else { 0 } | |
342 | }, | |
343 | }; | |
344 | let nsamples = if mpeg1 { SAMPLES } else { SAMPLES / 2 }; | |
345 | ||
346 | Ok(MPAHeader{ layer, srate, channels, frame_size, nsamples }) | |
347 | } | |
348 | } | |
349 | ||
350 | impl NAPacketiser for MPAPacketiser { | |
351 | fn add_data(&mut self, src: &[u8]) -> bool { | |
352 | self.buf.extend_from_slice(src); | |
353 | self.buf.len() < 4096 | |
354 | } | |
355 | fn parse_stream(&mut self, id: u32) -> DecoderResult<NAStreamRef> { | |
356 | if self.hdr.is_none() { | |
357 | if self.buf.len() < 4 { | |
358 | return Err(DecoderError::ShortData); | |
359 | } | |
360 | let hdr = self.parse_header(0)?; | |
361 | self.hdr = Some(hdr); | |
362 | } | |
363 | let hdr = self.hdr.unwrap(); | |
364 | let ainfo = NAAudioInfo::new(hdr.srate, hdr.channels, SND_F32P_FORMAT, hdr.nsamples); | |
365 | let info = NACodecInfo::new("mp3", NACodecTypeInfo::Audio(ainfo), None); | |
366 | Ok(NAStream::new(StreamType::Audio, id, info, hdr.nsamples as u32, hdr.srate, 0).into_ref()) | |
367 | } | |
368 | fn skip_junk(&mut self) -> DecoderResult<usize> { | |
369 | if self.buf.len() <= 2 { | |
370 | return Ok(0); | |
371 | } | |
372 | let mut off = 0; | |
373 | let mut hdr = u16::from(self.buf[0]) * 256 + u16::from(self.buf[1]); | |
374 | let mut iter = self.buf[2..].iter(); | |
375 | loop { | |
376 | if (hdr & 0xFFE0) != 0xFFE0 { | |
377 | let ret = self.parse_header(off); | |
378 | match ret { | |
379 | Ok(hdr) => { | |
380 | if self.hdr.is_none() { | |
381 | self.hdr = Some(hdr); | |
382 | } | |
383 | if self.hdr.unwrap() != hdr { // header is valid but mismatches | |
384 | self.buf.drain(..off + 1); | |
385 | return Err(DecoderError::InvalidData); | |
386 | } | |
387 | break; | |
388 | }, | |
389 | Err(err) => { | |
390 | self.buf.drain(..off + 1); | |
391 | return Err(err); | |
392 | }, | |
393 | }; | |
394 | } | |
395 | off += 1; | |
396 | if let Some(&b) = iter.next() { | |
397 | hdr = (hdr << 8) | u16::from(b); | |
398 | } else { | |
399 | break; | |
400 | } | |
401 | } | |
402 | self.buf.drain(..off); | |
403 | Ok(off) | |
404 | } | |
405 | fn get_packet(&mut self, stream: NAStreamRef) -> DecoderResult<Option<NAPacket>> { | |
406 | if self.buf.len() < 4 { | |
407 | return Err(DecoderError::ShortData); | |
408 | } | |
409 | let hdr = self.parse_header(0)?; | |
410 | if self.hdr.is_none() { | |
411 | self.hdr = Some(hdr); | |
412 | } | |
413 | if self.hdr.unwrap() != hdr { | |
414 | return Err(DecoderError::InvalidData); | |
415 | } | |
416 | if hdr.frame_size <= self.buf.len() { | |
417 | let mut data = Vec::with_capacity(hdr.frame_size); | |
418 | data.extend_from_slice(&self.buf[..hdr.frame_size]); | |
419 | self.buf.drain(..hdr.frame_size); | |
420 | let ts = NATimeInfo::new(None, None, Some(1), hdr.nsamples as u32, hdr.srate); | |
421 | Ok(Some(NAPacket::new(stream, ts, true, data))) | |
422 | } else { | |
423 | Ok(None) | |
424 | } | |
425 | } | |
426 | fn reset(&mut self) { | |
427 | self.buf.clear(); | |
428 | } | |
429 | } | |
430 | ||
431 | pub fn get_packetiser() -> Box<dyn NAPacketiser + Send> { | |
432 | Box::new(MPAPacketiser::new()) | |
433 | } | |
434 | ||
16cca4d3 KS |
435 | #[cfg(test)] |
436 | mod test { | |
437 | use nihav_core::codecs::RegisteredDecoders; | |
438 | use nihav_core::demuxers::RegisteredDemuxers; | |
439 | use nihav_codec_support::test::dec_video::test_decode_audio; | |
440 | use crate::mpeg_register_all_decoders; | |
441 | use nihav_flash::flash_register_all_demuxers; | |
f27c73df KS |
442 | use std::io::Read; |
443 | use nihav_core::codecs::NAPacketiser; | |
444 | ||
16cca4d3 KS |
445 | #[test] |
446 | fn test_mpeg1_layer3_mono() { | |
447 | let mut dmx_reg = RegisteredDemuxers::new(); | |
448 | flash_register_all_demuxers(&mut dmx_reg); | |
449 | let mut dec_reg = RegisteredDecoders::new(); | |
450 | mpeg_register_all_decoders(&mut dec_reg); | |
451 | ||
452 | let file = "assets/Flash/i_004.flv"; | |
453 | test_decode_audio("flv", file, Some(6000), None/*Some("mp3_1")*/, &dmx_reg, &dec_reg); | |
454 | } | |
455 | #[test] | |
456 | fn test_mpeg1_layer3_stereo() { | |
457 | let mut dmx_reg = RegisteredDemuxers::new(); | |
458 | flash_register_all_demuxers(&mut dmx_reg); | |
459 | let mut dec_reg = RegisteredDecoders::new(); | |
460 | mpeg_register_all_decoders(&mut dec_reg); | |
461 | ||
462 | let file = "assets/Flash/venture_030_ivcp_001_8bit.flv"; | |
463 | test_decode_audio("flv", file, Some(7200), None/*Some("mp3_2")*/, &dmx_reg, &dec_reg); | |
464 | } | |
465 | #[test] | |
466 | fn test_mpeg2_layer3() { | |
467 | let mut dmx_reg = RegisteredDemuxers::new(); | |
468 | flash_register_all_demuxers(&mut dmx_reg); | |
469 | let mut dec_reg = RegisteredDecoders::new(); | |
470 | mpeg_register_all_decoders(&mut dec_reg); | |
471 | ||
472 | let file = "assets/Flash/lection2-2.flv"; | |
473 | test_decode_audio("flv", file, Some(6000), None/*Some("mp3_3")*/, &dmx_reg, &dec_reg); | |
474 | } | |
f27c73df KS |
475 | #[test] |
476 | fn test_mpa_packetiser() { | |
477 | let mut buf = [0; 16384]; | |
478 | let mut file = std::fs::File::open("assets/MPEG/1.mp3").unwrap(); | |
479 | ||
480 | let mut pkts = super::MPAPacketiser::new(); | |
481 | file.read_exact(&mut buf).unwrap(); | |
482 | pkts.add_data(&buf); | |
483 | let stream = pkts.parse_stream(0).unwrap(); | |
484 | let mut frame_sizes = Vec::with_capacity(15); | |
485 | while let Some(pkt) = pkts.get_packet(stream.clone()).unwrap() { | |
486 | let frame_size = pkt.get_buffer().len(); | |
487 | println!("pkt size {}", frame_size); | |
488 | frame_sizes.push(frame_size); | |
489 | } | |
490 | assert_eq!(&frame_sizes, &[1044, 1044, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1044, 1045, 1045, 1045]); | |
491 | } | |
16cca4d3 KS |
492 | } |
493 | ||
494 | const BITRATE: [[[u32; 15]; 3]; 2] = [ | |
495 | [ | |
496 | [ 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 ], | |
497 | [ 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 ], | |
498 | [ 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 ] | |
499 | ], [ | |
500 | [ 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 ], | |
501 | [ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 ], | |
502 | [ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 ] | |
503 | ] | |
504 | ]; | |
505 | ||
506 | const SAMPLING_RATE: [u32; 9] = [ 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000 ]; |