rename register_all_codecs to register_all_decoders
[nihav.git] / nihav-commonfmt / src / codecs / clearvideo.rs
index 790ea3e00b369d91a2e5b4fc3a1b6faccc983ba6..8b22dad4c194b33bfc8c72d572b622ab61178c1e 100644 (file)
@@ -3,6 +3,7 @@ use nihav_core::io::bitreader::*;
 use nihav_core::io::codebook::*;
 use nihav_core::formats;
 use nihav_core::codecs::*;
+use nihav_codec_support::codecs::{HAMShuffler, MV, ZERO_MV, ZIGZAG};
 
 struct CLVDCCodeReader { }
 struct CLVACCodeReader { }
@@ -372,7 +373,7 @@ struct ClearVideoDecoder {
     info:    NACodecInfoRef,
     dc_cb:   Codebook<i8>,
     ac_cb:   Codebook<u16>,
-    frmmgr:  HAMShuffler,
+    frmmgr:  HAMShuffler<u8>,
     is_rm:   bool,
     ylev:    [LevelCodes; 4],
     ulev:    [LevelCodes; 3],
@@ -622,8 +623,8 @@ impl ClearVideoDecoder {
 }
 
 impl NADecoder for ClearVideoDecoder {
+    #[allow(clippy::or_fun_call)]
     fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
-        if info.get_extradata().is_none() { return Err(DecoderError::InvalidData); }
         if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
             let w = vinfo.get_width();
             let h = vinfo.get_height();
@@ -632,9 +633,11 @@ impl NADecoder for ClearVideoDecoder {
             let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
             self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
             self.frmmgr.clear();
-            let edata = info.get_extradata().unwrap();
+            let edata = info.get_extradata().unwrap_or(std::sync::Arc::new(vec![]));
 //todo detect simply by extradata contents?
-            if !self.is_rm {
+            if edata.len() == 0 || edata.len() < 0x60 { // no or short extradata probably comes from MOV
+                self.tsize = 4;
+            } else if !self.is_rm {
                 let mut mr = MemoryReader::new_read(edata.as_slice());
                 let mut br = ByteReader::new(&mut mr);
                 br.read_skip(0x5E).unwrap();
@@ -671,7 +674,7 @@ impl NADecoder for ClearVideoDecoder {
         }
 
         let is_intra = (src[off] & 2) == 2;
-        let mut br = BitReader::new(&src[(off + 1)..], src.len() - (off + 1), BitReaderMode::BE);
+        let mut br = BitReader::new(&src[(off + 1)..], BitReaderMode::BE);
 
         let vinfo = self.info.get_properties().get_video_info().unwrap();
         let bufinfo = alloc_video_buffer(vinfo, self.tsize)?;
@@ -683,7 +686,9 @@ impl NADecoder for ClearVideoDecoder {
             self.decode_frame_intra(&mut br, &mut buf, vinfo.get_width(), vinfo.get_height())?;
             extend_edges(&mut buf, 1 << self.tsize);
         } else {
-            let mut prev = self.frmmgr.clone_ref().unwrap();
+            let pref = self.frmmgr.clone_ref();
+            if pref.is_none() { return Err(DecoderError::MissingReference); }
+            let mut prev = pref.unwrap();
             extend_edges(&mut prev, 1 << self.tsize);
             self.decode_frame_inter(&mut br, &mut buf, &mut prev, vinfo.get_width(), vinfo.get_height())?;
             extend_edges(&mut buf, 1 << self.tsize);
@@ -703,11 +708,17 @@ impl NADecoder for ClearVideoDecoder {
     }
 }
 
-pub fn get_decoder() -> Box<dyn NADecoder> {
+impl NAOptionHandler for ClearVideoDecoder {
+    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() -> Box<dyn NADecoder + Send> {
     Box::new(ClearVideoDecoder::new(false))
 }
 
-pub fn get_decoder_rm() -> Box<dyn NADecoder> {
+pub fn get_decoder_rm() -> Box<dyn NADecoder + Send> {
     Box::new(ClearVideoDecoder::new(true))
 }
 
@@ -715,18 +726,28 @@ pub fn get_decoder_rm() -> Box<dyn NADecoder> {
 mod test {
     use nihav_core::codecs::RegisteredDecoders;
     use nihav_core::demuxers::RegisteredDemuxers;
-    use nihav_core::test::dec_video::test_file_decoding;
-    use crate::codecs::generic_register_all_codecs;
-    use crate::demuxers::generic_register_all_demuxers;
+    use nihav_codec_support::test::dec_video::*;
+    use crate::generic_register_all_decoders;
+    use crate::generic_register_all_demuxers;
     #[test]
     fn test_clv() {
         let mut dmx_reg = RegisteredDemuxers::new();
         generic_register_all_demuxers(&mut dmx_reg);
         let mut dec_reg = RegisteredDecoders::new();
-        generic_register_all_codecs(&mut dec_reg);
-        test_file_decoding("avi", "assets/Misc/TalkingHead_352x288.avi", Some(10), true, false, None/*Some("clv")*/, &dmx_reg, &dec_reg);
-//         test_file_decoding("avi", "assets/Misc/basketball.avi", None/*Some(10)*/, true, false, Some("clv1"));
-//panic!("debug");
+        generic_register_all_decoders(&mut dec_reg);
+        test_decoding("avi", "clearvideo", "assets/Misc/TalkingHead_352x288.avi", Some(10), &dmx_reg,
+                     &dec_reg, ExpectedTestResult::MD5Frames(vec![
+                            [0xb432376c, 0xf1dce57b, 0x8e79c7ee, 0xdd51850d],
+                            [0x76eb9726, 0x7ca1aabd, 0xf3f0740c, 0xf804dd0e],
+                            [0xc639b32c, 0x1f53f1f4, 0x50c34651, 0xc49cd2ac],
+                            [0x55408f2a, 0x37b01de0, 0xcc6aeadd, 0x09768735],
+                            [0xea219c51, 0xed72710c, 0x6c4b2bb0, 0xbfab0cb7],
+                            [0xfbf56708, 0x7f6597c7, 0x08ce894d, 0x9c4c7f60],
+                            [0x3dbf8b57, 0x9e1513ef, 0x209309a6, 0x56f0aca7],
+                            [0xc5fb6cb7, 0x1b9b092f, 0xe11127be, 0xe4fe8f45],
+                            [0x81a4a122, 0xb2b84bcf, 0xa478bd80, 0x12c78fb6],
+                            [0xb5b43c22, 0xd9c457fa, 0xcc5390d8, 0x1201ef22],
+                            [0x27a206e9, 0x88085556, 0x1114fb62, 0x77f1ebed]]));
     }
 }