]>
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; | |
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 ]; |