add bytes_left() to NAPacketiser so its internal buffer size can be monitored
[nihav.git] / nihav-mpeg / src / codecs / mpegaudio / mod.rs
CommitLineData
16cca4d3
KS
1use nihav_core::codecs::*;
2use nihav_core::io::bitreader::*;
3use nihav_codec_support::dsp::qmf::QMF;
4
5mod mp3data;
6mod mp3code;
7use mp3code::*;
8
9const SAMPLES: usize = 1152;
d686ebc4 10const BYTEBUF_SIZE: usize = 2048;
16cca4d3
KS
11
12#[allow(clippy::large_enum_variant)]
13enum LayerData {
14 MP1,
15 MP2,
16 MP3(MP3Data),
17}
18
19impl 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
36struct 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
51impl 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
121fn 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
130impl 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
265impl 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
271pub fn get_decoder_mp3() -> Box<dyn NADecoder + Send> {
272 Box::new(MPADecoder::new(2))
273}
274
f27c73df
KS
275#[derive(Clone,Copy,Debug)]
276struct MPAHeader {
277 layer: u8,
278 srate: u32,
279 channels: u8,
280 frame_size: usize,
281 nsamples: usize,
282}
283
284impl 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)]
293struct MPAPacketiser {
294 buf: Vec<u8>,
295 hdr: Option<MPAHeader>,
296}
297
298impl 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
350impl 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 }
7f754c49 429 fn bytes_left(&self) -> usize { self.buf.len() }
f27c73df
KS
430}
431
432pub fn get_packetiser() -> Box<dyn NAPacketiser + Send> {
433 Box::new(MPAPacketiser::new())
434}
435
16cca4d3
KS
436#[cfg(test)]
437mod test {
438 use nihav_core::codecs::RegisteredDecoders;
439 use nihav_core::demuxers::RegisteredDemuxers;
440 use nihav_codec_support::test::dec_video::test_decode_audio;
441 use crate::mpeg_register_all_decoders;
442 use nihav_flash::flash_register_all_demuxers;
f27c73df
KS
443 use std::io::Read;
444 use nihav_core::codecs::NAPacketiser;
445
16cca4d3
KS
446 #[test]
447 fn test_mpeg1_layer3_mono() {
448 let mut dmx_reg = RegisteredDemuxers::new();
449 flash_register_all_demuxers(&mut dmx_reg);
450 let mut dec_reg = RegisteredDecoders::new();
451 mpeg_register_all_decoders(&mut dec_reg);
452
453 let file = "assets/Flash/i_004.flv";
454 test_decode_audio("flv", file, Some(6000), None/*Some("mp3_1")*/, &dmx_reg, &dec_reg);
455 }
456 #[test]
457 fn test_mpeg1_layer3_stereo() {
458 let mut dmx_reg = RegisteredDemuxers::new();
459 flash_register_all_demuxers(&mut dmx_reg);
460 let mut dec_reg = RegisteredDecoders::new();
461 mpeg_register_all_decoders(&mut dec_reg);
462
463 let file = "assets/Flash/venture_030_ivcp_001_8bit.flv";
464 test_decode_audio("flv", file, Some(7200), None/*Some("mp3_2")*/, &dmx_reg, &dec_reg);
465 }
466 #[test]
467 fn test_mpeg2_layer3() {
468 let mut dmx_reg = RegisteredDemuxers::new();
469 flash_register_all_demuxers(&mut dmx_reg);
470 let mut dec_reg = RegisteredDecoders::new();
471 mpeg_register_all_decoders(&mut dec_reg);
472
473 let file = "assets/Flash/lection2-2.flv";
474 test_decode_audio("flv", file, Some(6000), None/*Some("mp3_3")*/, &dmx_reg, &dec_reg);
475 }
f27c73df
KS
476 #[test]
477 fn test_mpa_packetiser() {
478 let mut buf = [0; 16384];
479 let mut file = std::fs::File::open("assets/MPEG/1.mp3").unwrap();
480
481 let mut pkts = super::MPAPacketiser::new();
482 file.read_exact(&mut buf).unwrap();
483 pkts.add_data(&buf);
484 let stream = pkts.parse_stream(0).unwrap();
485 let mut frame_sizes = Vec::with_capacity(15);
486 while let Some(pkt) = pkts.get_packet(stream.clone()).unwrap() {
487 let frame_size = pkt.get_buffer().len();
488 println!("pkt size {}", frame_size);
489 frame_sizes.push(frame_size);
490 }
491 assert_eq!(&frame_sizes, &[1044, 1044, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1044, 1045, 1045, 1045]);
492 }
16cca4d3
KS
493}
494
495const BITRATE: [[[u32; 15]; 3]; 2] = [
496 [
497 [ 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 ],
498 [ 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 ],
499 [ 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 ]
500 ], [
501 [ 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 ],
502 [ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 ],
503 [ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 ]
504 ]
505];
506
507const SAMPLING_RATE: [u32; 9] = [ 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000 ];