rename register_all_codecs to register_all_decoders
[nihav.git] / nihav-indeo / src / codecs / imc.rs
index 53ea68600133443ab7a078231ae3d9b0c101fbb7..ea84d0ab01977f91285045264d60488f5df197d7 100644 (file)
@@ -1,16 +1,14 @@
 use std::mem;
 use std::ptr;
 use std::f32::consts;
-use std::rc::Rc;
-use std::cell::RefCell;
 
 use nihav_core::formats::*;
 use nihav_core::frame::*;
 use nihav_core::codecs::*;
 use nihav_core::io::bitreader::*;
 use nihav_core::io::codebook::*;
-use nihav_core::dsp::fft::*;
-use nihav_core::dsp::window::*;
+use nihav_codec_support::dsp::fft::*;
+use nihav_codec_support::dsp::window::*;
 
 const BANDS:      usize =  32;
 const COEFFS:     usize = 256;
@@ -105,6 +103,7 @@ impl BitAlloc {
             self.skip_flag[i]       = false;
         }
     }
+    #[allow(clippy::cyclomatic_complexity)]
     fn calculate_bit_allocation(&mut self, ch_data: &mut IMCChannel, bits: usize, fixed_head: bool, adj_idx: usize) -> DecoderResult<()> {
 
         let mut peak = 0.0;
@@ -188,7 +187,7 @@ impl BitAlloc {
             let mut tmp: [f32; BANDS] = [BITALLOC_LIMIT; BANDS];
             for band in 0..BANDS {
                 if self.band_bits[band] != 6 {
-                    tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.bit_est[band] - 0.415;
+                    tmp[band] = f32::from(self.band_bits[band]) * -2.0 + ch_data.bit_est[band] - 0.415;
                 }
             }
             let mut peak = 0.0;
@@ -222,7 +221,7 @@ impl BitAlloc {
             let mut tmp: [f32; BANDS] = [BITALLOC_TOP_LIMIT; BANDS];
             for band in start..BANDS {
                 if self.band_bits[band] != 0 {
-                    tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.bit_est[band] - 0.415 + 2.0;
+                    tmp[band] = f32::from(self.band_bits[band]) * -2.0 + ch_data.bit_est[band] - 0.415 + 2.0;
                 }
             }
             while free_bits < cur_bits {
@@ -258,7 +257,7 @@ impl BitAlloc {
         let mut tmp: [f32; BANDS] = [BITALLOC_LIMIT; BANDS];
         for band in 0..BANDS {
             if self.band_bits[band] != 6 {
-                tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.bit_est[band] - 0.415;
+                tmp[band] = f32::from(self.band_bits[band]) * -2.0 + ch_data.bit_est[band] - 0.415;
             }
         }
         let mut used_bits: i32 = 0;
@@ -314,7 +313,7 @@ impl LUTs {
             sqrt_tab[i] = (i as f32).sqrt();
         }
 
-        LUTs { exp_lev: exp_lev, exp_10: exp_10, sqrt_tab: sqrt_tab }
+        LUTs { exp_lev, exp_10, sqrt_tab }
     }
 }
 
@@ -323,7 +322,7 @@ struct IMCDecoder {
 
     chmap:  NAChannelMap,
     ainfo:  NAAudioInfo,
-    info:   Rc<NACodecInfo>,
+    info:   NACodecInfoRef,
 
     codes:  [[Codebook<u8>; 4]; 4],
     ch_data: [IMCChannel; 2],
@@ -370,21 +369,21 @@ impl IMCDecoder {
             }
         }
         IMCDecoder {
-            is_imc:     is_imc,
+            is_imc,
             chmap:      NAChannelMap::new(),
             ainfo:      NAAudioInfo::new(0, 0, SND_F32P_FORMAT, 0),
             info:       NACodecInfo::new_dummy(),
 
-            codes:      codes,
+            codes,
             ch_data:    [IMCChannel::new(), IMCChannel::new()],
             ba:         BitAlloc::new(),
             imdct:      IMDCTContext::new(),
             luts:       LUTs::new(),
 
-            cycle1:     cycle1,
-            cycle2:     cycle2,
-            weights1:   weights1,
-            weights2:   weights2,
+            cycle1,
+            cycle2,
+            weights1,
+            weights2,
         }
     }
 
@@ -440,7 +439,7 @@ impl IMCDecoder {
         let maxc_pos = br.read(5)? as usize;
         let max_coef = br.read(7)? as u8;
 
-        let (c1, c2) = calc_maxcoef(max_coef as f32);
+        let (c1, c2) = calc_maxcoef(f32::from(max_coef));
         for i in 0..BANDS {
             if i != maxc_pos {
                 let level = br.read(4)?;
@@ -468,7 +467,7 @@ impl IMCDecoder {
             ch_data.mask_wght[band] = 0.0;
             let val;
             if self.ba.band_width[band] > 0 {
-                val = (ch_data.new_floor[band] as f64).powi(2);
+                val = f64::from(ch_data.new_floor[band]).powi(2);
                 ch_data.log_floor2[band] = 2.0 * ch_data.log_floor[band];
             } else {
                 val = 0.0;
@@ -529,7 +528,7 @@ impl IMCDecoder {
         }
         if reset {
             let ch_data = &mut self.ch_data[ch];
-            let (mut c1, mut c2) = calc_maxcoef(level[0] as f32);
+            let (mut c1, mut c2) = calc_maxcoef(f32::from(level[0]));
             ch_data.new_floor[0] = c1;
             ch_data.log_floor[0] = c2;
             for i in 1..BANDS {
@@ -546,7 +545,7 @@ impl IMCDecoder {
                         lval = level[i] - 16;
                     }
                     c1 *= self.luts.exp_10[(lval + 16) as usize];
-                    c2 += 0.83048 * (lval as f32);
+                    c2 += 0.83048 * f32::from(lval);
                     ch_data.new_floor[i] = c1;
                     ch_data.log_floor[i] = c2;
                 }
@@ -557,7 +556,7 @@ impl IMCDecoder {
                 if level[i] < 16 {
                     let lval = level[i] - 7;
                     ch_data.new_floor[i]  = self.luts.exp_10[(lval + 16) as usize] * ch_data.old_floor[i];
-                    ch_data.log_floor[i] += (lval as f32) * 0.83048;
+                    ch_data.log_floor[i] += f32::from(lval) * 0.83048;
                 } else {
                     ch_data.new_floor[i] = ch_data.old_floor[i];
                 }
@@ -668,11 +667,11 @@ impl IMCDecoder {
             if !self.ba.band_present[band] { continue; }
             for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
                 if self.ba.skip_flag[i] {
-                    bits_freed += self.ba.cw_len[i] as i32;
+                    bits_freed += i32::from(self.ba.cw_len[i]);
                     self.ba.cw_len[i] = 0;
                 }
             }
-            bits_freed -= self.ba.skip_flag_bits[band] as i32;
+            bits_freed -= i32::from(self.ba.skip_flag_bits[band]);
         }
 
         if bits_freed < 0 { return Err(DecoderError::Bug); }
@@ -730,7 +729,7 @@ impl IMCDecoder {
     }
 
     fn decode_block(&mut self, data: &[u8], ch: usize, dst: &mut [f32]) -> DecoderResult<()> {
-        let mut br = BitReader::new(&data[BLOCK_SIZE*ch..], BLOCK_SIZE, BitReaderMode::LE16MSB);
+        let mut br = BitReader::new(&data[BLOCK_SIZE*ch..][..BLOCK_SIZE], BitReaderMode::LE16MSB);
         let hdr = br.read(9)?;
         validate!((hdr & 0x18) == 0);
 
@@ -833,12 +832,12 @@ impl IMDCTContext {
             posttwiddle[i] = FFTComplex::exp(consts::PI / 256.0 * n).scale(1.0/32768.0);
         }
         IMDCTContext {
-            pretwiddle1: pretwiddle1,
-            pretwiddle2: pretwiddle2,
-            posttwiddle: posttwiddle,
+            pretwiddle1,
+            pretwiddle2,
+            posttwiddle,
             tmp:         [FFTC_ZERO; COEFFS/2],
-            fft:         FFTBuilder::new_fft(FFTMode::SplitRadix, COEFFS/2),
-            window:      window,
+            fft:         FFTBuilder::new_fft(COEFFS/2, false),
+            window,
         }
     }
     fn imdct(&mut self, coeffs: &[f32; COEFFS], dst: &mut [f32], last_im: &mut [f32; COEFFS/2]) {
@@ -850,7 +849,7 @@ impl IMDCTContext {
             self.tmp[i].re = -(c2 * in1 + c1 * in2);
             self.tmp[i].im =   c1 * in1 - c2 * in2;
         }
-        self.fft.do_fft_inplace(&mut self.tmp, false);
+        self.fft.do_ifft_inplace(&mut self.tmp);
         for i in 0..COEFFS/2 {
             let tmp = !(self.tmp[i] * self.posttwiddle[i]);
             let c1 = self.window[i * 2];
@@ -867,7 +866,7 @@ const CHMAP_MONO: [NAChannelType; 1] = [NAChannelType::C];
 const CHMAP_STEREO: [NAChannelType; 2] = [NAChannelType::L, NAChannelType::R];
 
 impl NADecoder for IMCDecoder {
-    fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
+    fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
         if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
             self.chmap = NAChannelMap::new();
             match ainfo.get_channels() {
@@ -878,7 +877,7 @@ impl NADecoder for IMCDecoder {
             self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(),
                                           ainfo.get_channels(),
                                           SND_F32P_FORMAT, 0);
-            self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo.clone()));
+            self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo));
 
             if !self.is_imc {
                 self.generate_iac_tables(ainfo.get_sample_rate() as f32);
@@ -888,7 +887,7 @@ impl NADecoder for IMCDecoder {
             Err(DecoderError::InvalidData)
         }
     }
-    fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
+    fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
         let info = pkt.get_stream().get_info();
         validate!(info.get_properties().is_audio());
         let pktbuf = pkt.get_buffer();
@@ -898,7 +897,7 @@ impl NADecoder for IMCDecoder {
 
         let abuf = alloc_audio_buffer(self.ainfo, duration, self.chmap.clone())?;
         let mut adata = abuf.get_abuf_f32().unwrap();
-        let mut dst = adata.get_data_mut();
+        let dst = adata.get_data_mut().unwrap();
 
         let mut start: usize = 0;
         let channels = self.ainfo.get_channels() as usize;
@@ -922,27 +921,35 @@ impl NADecoder for IMCDecoder {
 
         let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
         frm.set_keyframe(true);
-        Ok(Rc::new(RefCell::new(frm)))
+        Ok(frm.into_ref())
     }
+    fn flush(&mut self) {
+    }
+}
+
+impl NAOptionHandler for IMCDecoder {
+    fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
+    fn set_options(&mut self, _options: &[NAOption]) { }
+    fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
 }
 
-pub fn get_decoder_imc() -> Box<NADecoder> {
+pub fn get_decoder_imc() -> Box<dyn NADecoder + Send> {
     Box::new(IMCDecoder::new(true))
 }
 
-pub fn get_decoder_iac() -> Box<NADecoder> {
+pub fn get_decoder_iac() -> Box<dyn NADecoder + Send> {
     Box::new(IMCDecoder::new(false))
 }
 
 struct IMCCodeReader { sel1: usize, sel2: usize }
 
 impl IMCCodeReader {
-    fn new(sel1: usize, sel2: usize) -> Self { IMCCodeReader { sel1: sel1, sel2: sel2 } }
+    fn new(sel1: usize, sel2: usize) -> Self { IMCCodeReader { sel1, sel2 } }
 }
 
 impl CodebookDescReader<u8> for IMCCodeReader {
     fn bits(&mut self, idx: usize) -> u8  { IMC_CODE_LENGTHS[self.sel1][self.sel2][idx] }
-    fn code(&mut self, idx: usize) -> u32 { IMC_CODE_CODES[self.sel1][self.sel2][idx] as u32 }
+    fn code(&mut self, idx: usize) -> u32 { u32::from(IMC_CODE_CODES[self.sel1][self.sel2][idx]) }
     fn sym (&mut self, idx: usize) -> u8 { idx as u8 }
     fn len(&mut self) -> usize { IMC_CODE_LENGTHS[0][0].len() }
 }
@@ -1111,22 +1118,22 @@ const IMC_CB_SELECTOR: [[usize; BANDS]; 4] = [
 mod test {
     use nihav_core::codecs::RegisteredDecoders;
     use nihav_core::demuxers::RegisteredDemuxers;
-    use nihav_core::test::dec_video::*;
-    use crate::codecs::indeo_register_all_codecs;
-    use nihav_commonfmt::demuxers::generic_register_all_demuxers;
+    use nihav_codec_support::test::dec_video::*;
+    use crate::indeo_register_all_decoders;
+    use nihav_commonfmt::generic_register_all_demuxers;
     #[test]
     fn test_imc() {
         let mut dmx_reg = RegisteredDemuxers::new();
         generic_register_all_demuxers(&mut dmx_reg);
         let mut dec_reg = RegisteredDecoders::new();
-        indeo_register_all_codecs(&mut dec_reg);
+        indeo_register_all_decoders(&mut dec_reg);
 
 //        let file = "assets/Indeo/neal73_saber.avi";
 //        let file = "assets/Indeo/IMC/hvalen.avi";
         let file = "assets/Indeo/IMC/8khz.avi";
 //        let file = "assets/Indeo/STsKlassFist-1a.avi";
 //        let file = "assets/Indeo/IMC/Angel Bday.avi";
-        test_decode_audio("avi", file, None, "imc", &dmx_reg, &dec_reg);
+        test_decode_audio("avi", file, None, None/*Some("imc")*/, &dmx_reg, &dec_reg);
         //test_file_decoding("avi", file, None, false, true, None);
     }
 }