| 1 | use nihav_core::codecs::*; |
| 2 | use nihav_core::io::bitreader::*; |
| 3 | use nihav_codec_support::dsp::qmf::QMF; |
| 4 | use std::str::FromStr; |
| 5 | use std::sync::Arc; |
| 6 | |
| 7 | const CODEC_SAMPLES: usize = 1152; |
| 8 | |
| 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 | } |
| 104 | #[allow(clippy::identity_op)] |
| 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); |
| 160 | self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo)); |
| 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 | 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 | |
| 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 | |
| 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 | |