]>
Commit | Line | Data |
---|---|---|
3e52414f KS |
1 | use nihav_core::codecs::*; |
2 | use nihav_core::io::bitreader::*; | |
12cf91ea | 3 | use nihav_codec_support::dsp::qmf::QMF; |
3e52414f KS |
4 | use std::str::FromStr; |
5 | use std::sync::Arc; | |
6 | ||
7 | const CODEC_SAMPLES: usize = 1152; | |
8 | ||
3e52414f KS |
9 | struct LHDecoder { |
10 | ainfo: NAAudioInfo, | |
11 | info: Arc<NACodecInfo>, | |
12 | chmap: NAChannelMap, | |
13 | ||
14 | bitalloc: [[u8; 32]; 3], | |
15 | scf_select: [u8; 32], | |
16 | scales: [[u8; 32]; 3], | |
17 | samples: [[f32; 32]; 36], | |
18 | ||
19 | bitpos: u32, | |
20 | ||
21 | qmf: QMF, | |
22 | } | |
23 | ||
24 | impl LHDecoder { | |
25 | fn new() -> Self { | |
26 | Self { | |
27 | ainfo: NAAudioInfo::new(22050, 1, SND_F32P_FORMAT, CODEC_SAMPLES), | |
28 | info: NACodecInfo::new_dummy(), | |
29 | chmap: NAChannelMap::new(), | |
30 | ||
31 | bitalloc: [[0; 32]; 3], | |
32 | scf_select: [0; 32], | |
33 | scales: [[0; 32]; 3], | |
34 | samples: [[0.0; 32]; 36], | |
35 | ||
36 | bitpos: 0, | |
37 | ||
38 | qmf: QMF::new(), | |
39 | } | |
40 | } | |
41 | fn unpack_bitalloc(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
42 | for i in 0..3 { | |
43 | for sb in 0..32 { | |
44 | self.bitalloc[i][sb] = br.read(BITALLOC_INFO[sb])? as u8; | |
45 | } | |
46 | } | |
47 | Ok(()) | |
48 | } | |
49 | fn unpack_scales(&mut self, br: &mut BitReader) -> DecoderResult<()> { | |
50 | for sb in 0..32 { | |
51 | if (self.bitalloc[0][sb] | self.bitalloc[1][sb] | self.bitalloc[2][sb]) != 0 { | |
52 | self.scf_select[sb] = br.read(2)? as u8; | |
53 | } else { | |
54 | self.scf_select[sb] = 0; | |
55 | } | |
56 | } | |
57 | ||
58 | self.scales = [[0; 32]; 3]; | |
59 | for sb in 0..32 { | |
60 | let ba0 = self.bitalloc[0][sb]; | |
61 | let ba1 = self.bitalloc[1][sb]; | |
62 | let ba2 = self.bitalloc[2][sb]; | |
63 | if (ba0 | ba1 | ba2) == 0 { | |
64 | continue; | |
65 | } | |
66 | match self.scf_select[sb] { | |
67 | 0 => { | |
68 | for j in 0..3 { | |
69 | if self.bitalloc[j][sb] != 0 { | |
70 | self.scales[j][sb] = br.read(6)? as u8; | |
71 | } | |
72 | } | |
73 | }, | |
74 | 1 => { | |
75 | if (ba0 | ba1) != 0 { | |
76 | let scale = br.read(6)? as u8; | |
77 | self.scales[0][sb] = scale; | |
78 | self.scales[1][sb] = scale; | |
79 | } | |
80 | if ba2 != 0 { | |
81 | self.scales[2][sb] = br.read(6)? as u8; | |
82 | } | |
83 | }, | |
84 | 2 => { | |
85 | let scale = br.read(6)? as u8; | |
86 | self.scales[0][sb] = scale; | |
87 | self.scales[1][sb] = scale; | |
88 | self.scales[2][sb] = scale; | |
89 | }, | |
90 | _ => { | |
91 | if ba0 != 0 { | |
92 | self.scales[0][sb] = br.read(6)? as u8; | |
93 | } | |
94 | if (ba1 | ba2) != 0 { | |
95 | let scale = br.read(6)? as u8; | |
96 | self.scales[1][sb] = scale; | |
97 | self.scales[2][sb] = scale; | |
98 | } | |
99 | }, | |
100 | }; | |
101 | } | |
102 | Ok(()) | |
103 | } | |
7450554d | 104 | #[allow(clippy::identity_op)] |
3e52414f KS |
105 | fn unpack_samples(&mut self, br: &mut BitReader) -> DecoderResult<()> { |
106 | for grp in 0..3 { | |
107 | for gr in 0..4 { | |
108 | for sb in 0..32 { | |
109 | let set = (grp * 4 + gr) * 3; | |
110 | if self.bitalloc[grp][sb] == 0 { | |
111 | self.samples[set + 0][sb] = 0.0; | |
112 | self.samples[set + 1][sb] = 0.0; | |
113 | self.samples[set + 2][sb] = 0.0; | |
114 | continue; | |
115 | } | |
116 | let idx = sb * 4 + (self.bitalloc[grp][sb] as usize); | |
117 | let bits = GROUP_BITS[idx]; | |
118 | let sf = SCALEFACTORS[self.scales[grp][sb] as usize]; | |
119 | if GROUP_INFO[idx] == 1 { | |
120 | let radix = (1 << bits) - 1; | |
121 | let val0 = br.read(bits)? as usize; | |
122 | let val1 = br.read(bits)? as usize; | |
123 | let val2 = br.read(bits)? as usize; | |
124 | self.samples[set + 0][sb] = Self::dequant(val0, idx, radix) * sf; | |
125 | self.samples[set + 1][sb] = Self::dequant(val1, idx, radix) * sf; | |
126 | self.samples[set + 2][sb] = Self::dequant(val2, idx, radix) * sf; | |
127 | } else { | |
128 | let radix = GROUP_RADIX[idx] as usize; | |
129 | let val = br.read(bits)? as usize; | |
130 | let val0 = val % radix; | |
131 | let val1 = (val / radix) % radix; | |
132 | let val2 = val / radix / radix; | |
133 | self.samples[set + 0][sb] = Self::dequant(val0, idx, radix) * sf; | |
134 | self.samples[set + 1][sb] = Self::dequant(val1, idx, radix) * sf; | |
135 | self.samples[set + 2][sb] = Self::dequant(val2, idx, radix) * sf; | |
136 | } | |
137 | } | |
138 | } | |
139 | } | |
140 | Ok(()) | |
141 | } | |
142 | fn dequant(val: usize, idx: usize, radix: usize) -> f32 { | |
143 | let qval = match radix { | |
144 | 3 => QUANTS3[val], | |
145 | 5 => QUANTS5[val], | |
146 | 7 => QUANTS7[val], | |
147 | 15 => QUANTS15[val], | |
148 | 63 => QUANTS63[val], | |
149 | _ => unreachable!(), | |
150 | }; | |
151 | let bias_idx = QUANT_BIAS_MAP[idx] as usize; | |
152 | (qval + QUANT_BIAS[bias_idx]) / QUANT_RANGE[bias_idx] | |
153 | } | |
154 | } | |
155 | ||
156 | impl NADecoder for LHDecoder { | |
157 | fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { | |
158 | if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() { | |
159 | self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), 1, SND_F32P_FORMAT, CODEC_SAMPLES); | |
7450554d | 160 | self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo)); |
3e52414f KS |
161 | self.chmap = NAChannelMap::from_str("C").unwrap(); |
162 | Ok(()) | |
163 | } else { | |
164 | Err(DecoderError::InvalidData) | |
165 | } | |
166 | } | |
167 | fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { | |
168 | let info = pkt.get_stream().get_info(); | |
169 | if let NACodecTypeInfo::Audio(_) = info.get_properties() { | |
170 | let pktbuf = pkt.get_buffer(); | |
171 | ||
172 | let mut daudio = Vec::with_capacity(CODEC_SAMPLES); | |
173 | ||
174 | let mut br = BitReader::new(pktbuf.as_slice(), BitReaderMode::BE); | |
175 | br.skip(self.bitpos)?; | |
176 | ||
177 | while br.left() >= 8 { | |
178 | self.unpack_bitalloc(&mut br)?; | |
179 | self.unpack_scales(&mut br)?; | |
180 | self.unpack_samples(&mut br)?; | |
181 | ||
182 | let mut samp_buf = [0.0f32; 32]; | |
183 | for set in 0..36 { | |
184 | self.qmf.synth(&self.samples[set], &mut samp_buf); | |
185 | daudio.extend_from_slice(&samp_buf); | |
186 | } | |
187 | } | |
188 | ||
189 | self.bitpos = (br.tell() as u32) & 7; | |
190 | ||
191 | let abuf = alloc_audio_buffer(self.ainfo, daudio.len(), self.chmap.clone())?; | |
192 | let mut adata = abuf.get_abuf_f32().unwrap(); | |
193 | let buf = adata.get_data_mut().unwrap(); | |
194 | (&mut buf[..daudio.len()]).copy_from_slice(daudio.as_slice()); | |
195 | ||
196 | let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf); | |
197 | frm.set_duration(Some(CODEC_SAMPLES as u64)); | |
198 | frm.set_keyframe(true); | |
199 | Ok(frm.into_ref()) | |
200 | } else { | |
201 | Err(DecoderError::Bug) | |
202 | } | |
203 | } | |
204 | fn flush(&mut self) { | |
205 | self.qmf = QMF::new(); | |
206 | self.bitpos = 0; | |
207 | } | |
208 | } | |
209 | ||
7d57ae2f KS |
210 | impl NAOptionHandler for LHDecoder { |
211 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
212 | fn set_options(&mut self, _options: &[NAOption]) { } | |
213 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
214 | } | |
215 | ||
3e52414f KS |
216 | pub fn get_decoder() -> Box<dyn NADecoder + Send> { |
217 | Box::new(LHDecoder::new()) | |
218 | } | |
219 | ||
220 | const BITALLOC_INFO: [u8; 32] = [ | |
221 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, | |
222 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 | |
223 | ]; | |
224 | ||
225 | const GROUP_BITS: [u8; 128] = [ | |
226 | 0, 3, 4, 6, 0, 3, 4, 6, 0, 3, 4, 6, 0, 3, 4, 6, | |
227 | 0, 3, 4, 6, 0, 3, 4, 6, 0, 5, 7, 4, 0, 5, 7, 4, | |
228 | 0, 5, 7, 4, 0, 5, 7, 4, 0, 5, 7, 4, 0, 5, 7, 4, | |
229 | 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, | |
230 | 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, | |
231 | 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, | |
232 | 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, | |
233 | 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0 | |
234 | ]; | |
235 | const GROUP_INFO: [u8; 128] = [ | |
236 | 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, | |
237 | 0, 1, 1, 1, 0, 1, 1, 1, 0, 3, 3, 1, 0, 3, 3, 1, | |
238 | 0, 3, 3, 1, 0, 3, 3, 1, 0, 3, 3, 1, 0, 3, 3, 1, | |
239 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, | |
240 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, | |
241 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, | |
242 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, | |
243 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0 | |
244 | ]; | |
245 | const GROUP_RADIX: [u8; 128] = [ | |
246 | 0, 7, 15, 63, 0, 7, 15, 63, 0, 7, 15, 63, 0, 7, 15, 63, | |
247 | 0, 7, 15, 63, 0, 7, 15, 63, 0, 3, 5, 15, 0, 3, 5, 15, | |
248 | 0, 3, 5, 15, 0, 3, 5, 15, 0, 3, 5, 15, 0, 3, 5, 15, | |
249 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, | |
250 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, | |
251 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, | |
252 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, | |
253 | 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0 | |
254 | ]; | |
255 | ||
256 | const QUANT_BIAS_MAP: [u8; 128] = [ | |
257 | 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6, | |
258 | 0, 2, 4, 6, 0, 2, 4, 6, 0, 0, 1, 4, 0, 0, 1, 4, | |
259 | 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 1, 4, 0, 0, 1, 4, | |
260 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
261 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
262 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
263 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
264 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | |
265 | ]; | |
266 | const QUANT_BIAS: [f32; 17] = [ | |
267 | 0.5, 0.5, 0.25, 0.5, 0.125, 0.0625, 0.03125, 0.015625, | |
268 | 0.0078125, 0.00390625, 0.001953125, 0.0009765625, 0.00048828125, | |
269 | 0.00024414062, 0.00012207031, 0.000061035164, 0.000030517582 | |
270 | ]; | |
271 | const QUANT_RANGE: [f32; 17] = [ | |
272 | 0.75, 0.625, 0.875, 0.5625, 0.9375, 0.96875, 0.984375, | |
273 | 0.9921875, 0.99609375, 0.99804688, 0.99902344, 0.99951172, | |
274 | 0.99975586, 0.99987793, 0.99993896, 0.99996948, 0.99998474 | |
275 | ]; | |
276 | const SCALEFACTORS: [f32; 64] = [ | |
277 | 2.0, 1.587401, 1.2599211, 1.0, 0.79370052, 0.62996054, | |
278 | 0.5, 0.39685026, 0.31498027, 0.25, 0.19842513, 0.15749013, | |
279 | 0.125, 0.099212565, 0.078745067, 0.0625, 0.049606282, 0.039372534, | |
280 | 0.03125, 0.024803141, 0.019686267, 0.015625, 0.012401571, 0.0098431334, | |
281 | 0.0078125, 0.0062007853, 0.0049215667, 0.00390625, 0.0031003926, 0.0024607833, | |
282 | 0.001953125, 0.0015501963, 0.0012303917, 0.0009765625, 0.00077509816, 0.00061519584, | |
283 | 0.00048828125, 0.00038754908, 0.00030759792, 0.00024414062, 0.00019377454, 0.00015379896, | |
284 | 0.00012207031, 0.00009688727, 0.00007689948, 0.000061035156, | |
285 | 0.000048443635, 0.00003844974, 0.000030517578, 0.000024221818, | |
286 | 0.00001922487, 0.000015258789, 0.000012110909, 0.000009612435, | |
287 | 0.0000076293945, 0.0000060554544, 0.0000048062175, 0.0000038146973, | |
288 | 0.0000030277272, 0.0000024031087, 0.0000019073486, 0.0000015138636, | |
289 | 0.0000012015544, 9.9999997e-21 | |
290 | ]; | |
291 | ||
292 | const QUANTS3: [f32; 4] = [ -1.0, -0.5, 0.0, 0.5 ]; | |
293 | const QUANTS5: [f32; 6] = [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25 ]; | |
294 | const QUANTS7: [f32; 8] = [ -1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75 ]; | |
295 | const QUANTS15: [f32; 16] = [ | |
296 | -1.0, -0.875, -0.75, -0.625, -0.5, -0.375, -0.25, -0.125, | |
297 | 0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875 ]; | |
298 | const QUANTS63: [f32; 64] = [ | |
299 | -1.0, -0.96875, -0.9375, -0.90625, -0.875, -0.84375, -0.8125, -0.78125, | |
300 | -0.75, -0.71875, -0.6875, -0.65625, -0.625, -0.59375, -0.5625, -0.53125, | |
301 | -0.5, -0.46875, -0.4375, -0.40625, -0.375, -0.34375, -0.3125, -0.28125, | |
302 | -0.25, -0.21875, -0.1875, -0.15625, -0.125, -0.09375, -0.0625, -0.03125, | |
303 | 0.0, 0.03125, 0.0625, 0.09375, 0.125, 0.15625, 0.1875, 0.21875, | |
304 | 0.25, 0.28125, 0.3125, 0.34375, 0.375, 0.40625, 0.4375, 0.46875, | |
305 | 0.5, 0.53125, 0.5625, 0.59375, 0.625, 0.65625, 0.6875, 0.71875, | |
306 | 0.75, 0.78125, 0.8125, 0.84375, 0.875, 0.90625, 0.9375, 0.96875 ]; | |
307 |