| 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; |
| 10 | const BYTEBUF_SIZE: usize = 1024; |
| 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 | |
| 275 | #[cfg(test)] |
| 276 | mod test { |
| 277 | use nihav_core::codecs::RegisteredDecoders; |
| 278 | use nihav_core::demuxers::RegisteredDemuxers; |
| 279 | use nihav_codec_support::test::dec_video::test_decode_audio; |
| 280 | use crate::mpeg_register_all_decoders; |
| 281 | use nihav_flash::flash_register_all_demuxers; |
| 282 | #[test] |
| 283 | fn test_mpeg1_layer3_mono() { |
| 284 | let mut dmx_reg = RegisteredDemuxers::new(); |
| 285 | flash_register_all_demuxers(&mut dmx_reg); |
| 286 | let mut dec_reg = RegisteredDecoders::new(); |
| 287 | mpeg_register_all_decoders(&mut dec_reg); |
| 288 | |
| 289 | let file = "assets/Flash/i_004.flv"; |
| 290 | test_decode_audio("flv", file, Some(6000), None/*Some("mp3_1")*/, &dmx_reg, &dec_reg); |
| 291 | } |
| 292 | #[test] |
| 293 | fn test_mpeg1_layer3_stereo() { |
| 294 | let mut dmx_reg = RegisteredDemuxers::new(); |
| 295 | flash_register_all_demuxers(&mut dmx_reg); |
| 296 | let mut dec_reg = RegisteredDecoders::new(); |
| 297 | mpeg_register_all_decoders(&mut dec_reg); |
| 298 | |
| 299 | let file = "assets/Flash/venture_030_ivcp_001_8bit.flv"; |
| 300 | test_decode_audio("flv", file, Some(7200), None/*Some("mp3_2")*/, &dmx_reg, &dec_reg); |
| 301 | } |
| 302 | #[test] |
| 303 | fn test_mpeg2_layer3() { |
| 304 | let mut dmx_reg = RegisteredDemuxers::new(); |
| 305 | flash_register_all_demuxers(&mut dmx_reg); |
| 306 | let mut dec_reg = RegisteredDecoders::new(); |
| 307 | mpeg_register_all_decoders(&mut dec_reg); |
| 308 | |
| 309 | let file = "assets/Flash/lection2-2.flv"; |
| 310 | test_decode_audio("flv", file, Some(6000), None/*Some("mp3_3")*/, &dmx_reg, &dec_reg); |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | const BITRATE: [[[u32; 15]; 3]; 2] = [ |
| 315 | [ |
| 316 | [ 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 ], |
| 317 | [ 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 ], |
| 318 | [ 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 ] |
| 319 | ], [ |
| 320 | [ 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 ], |
| 321 | [ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 ], |
| 322 | [ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 ] |
| 323 | ] |
| 324 | ]; |
| 325 | |
| 326 | const SAMPLING_RATE: [u32; 9] = [ 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000 ]; |