rename register_all_codecs to register_all_decoders
[nihav.git] / nihav-ms / src / codecs / msvideo1enc.rs
index 6ddae6485a4ffebafea4328936852994687272c0..b2233c230b7de7061dba27371da5c2fb12d72fee 100644 (file)
@@ -6,7 +6,7 @@ use nihav_codec_support::vq::*;
 struct Pixel16(u16);
 
 impl Pixel16 {
-    fn unpack(&self) -> (u8, u8, u8) {
+    fn unpack(self) -> (u8, u8, u8) {
         (((self.0 >> 10) & 0x1F) as u8, ((self.0 >> 5) & 0x1F) as u8, (self.0 & 0x1F) as u8)
     }
     fn pack(r: u8, g: u8, b: u8) -> Self {
@@ -256,6 +256,7 @@ struct MSVideo1Encoder {
     lastfrm:    Option<NAVideoBufferRef<u16>>,
     quality:    u8,
     frmcount:   u8,
+    key_int:    u8,
 }
 
 impl MSVideo1Encoder {
@@ -267,6 +268,7 @@ impl MSVideo1Encoder {
             lastfrm:    None,
             quality:    0,
             frmcount:   0,
+            key_int:    25,
         }
     }
     fn get_block(src: &[u16], sstride: usize, buf: &mut [Pixel16; 16]) {
@@ -407,10 +409,10 @@ impl NAEncoder for MSVideo1Encoder {
                 ofmt.format = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, true, RGB555_FORMAT));
                 Ok(ofmt)
             },
-            NACodecTypeInfo::Audio(_) => return Err(EncoderError::FormatError),
+            NACodecTypeInfo::Audio(_) => Err(EncoderError::FormatError),
             NACodecTypeInfo::Video(vinfo) => {
                 let outinfo = NAVideoInfo::new((vinfo.width + 3) & !3, (vinfo.height + 3) & !3, true, RGB555_FORMAT);
-                let mut ofmt = EncodeParameters::default();
+                let mut ofmt = *encinfo;
                 ofmt.format = NACodecTypeInfo::Video(outinfo);
                 Ok(ofmt)
             }
@@ -429,15 +431,17 @@ impl NAEncoder for MSVideo1Encoder {
                 }
 
                 let out_info = NAVideoInfo::new(vinfo.width, vinfo.height, true, RGB555_FORMAT);
-                let info = NACodecInfo::new("msvideo1", NACodecTypeInfo::Video(out_info.clone()), None);
-                let stream = NAStream::new(StreamType::Video, stream_id, info, encinfo.tb_num, encinfo.tb_den).into_ref();
-                if let Err(_) = self.pool.prealloc_video(out_info, 2) {
+                let info = NACodecInfo::new("msvideo1", NACodecTypeInfo::Video(out_info), None);
+                let mut stream = NAStream::new(StreamType::Video, stream_id, info, encinfo.tb_num, encinfo.tb_den);
+                stream.set_num(stream_id as usize);
+                let stream = stream.into_ref();
+                if self.pool.prealloc_video(out_info, 2).is_err() {
                     return Err(EncoderError::AllocError);
                 }
 
                 self.stream = Some(stream.clone());
                 self.quality = encinfo.quality;
-                
+
                 Ok(stream)
             },
         }
@@ -460,7 +464,7 @@ impl NAEncoder for MSVideo1Encoder {
             self.lastfrm = Some(cur_frm);
             self.pkt = Some(NAPacket::new(self.stream.clone().unwrap(), frm.ts, is_intra, dbuf));
             self.frmcount += 1;
-            if self.frmcount == 25 {
+            if self.frmcount == self.key_int {
                 self.frmcount = 0;
             }
             Ok(())
@@ -479,10 +483,36 @@ impl NAEncoder for MSVideo1Encoder {
     }
 }
 
+const ENCODER_OPTS: &[NAOptionDefinition] = &[
+    NAOptionDefinition {
+        name: KEYFRAME_OPTION, description: KEYFRAME_OPTION_DESC,
+        opt_type: NAOptionDefinitionType::Int(Some(0), Some(128)) },
+];
+
 impl NAOptionHandler for MSVideo1Encoder {
-    fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
-    fn set_options(&mut self, _options: &[NAOption]) { }
-    fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
+    fn get_supported_options(&self) -> &[NAOptionDefinition] { ENCODER_OPTS }
+    fn set_options(&mut self, options: &[NAOption]) {
+        for option in options.iter() {
+            for opt_def in ENCODER_OPTS.iter() {
+                if opt_def.check(option).is_ok() {
+                    match option.name {
+                        KEYFRAME_OPTION => {
+                            if let NAValue::Int(intval) = option.value {
+                                self.key_int = intval as u8;
+                            }
+                        },
+                        _ => {},
+                    };
+                }
+            }
+        }
+    }
+    fn query_option_value(&self, name: &str) -> Option<NAValue> {
+        match name {
+            KEYFRAME_OPTION => Some(NAValue::Int(i64::from(self.key_int))),
+            _ => None,
+        }
+    }
 }
 
 pub fn get_encoder() -> Box<dyn NAEncoder + Send> {
@@ -504,8 +534,8 @@ mod test {
         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);
-        ms_register_all_codecs(&mut dec_reg);
+        generic_register_all_decoders(&mut dec_reg);
+        ms_register_all_decoders(&mut dec_reg);
         let mut mux_reg = RegisteredMuxers::new();
         generic_register_all_muxers(&mut mux_reg);
         let mut enc_reg = RegisteredEncoders::new();
@@ -515,7 +545,7 @@ mod test {
                 demuxer:        "avi",
                 in_name:        "assets/Misc/TalkingHead_352x288.avi",
                 stream_type:    StreamType::Video,
-                limit:          Some(32),
+                limit:          Some(3),
                 dmx_reg, dec_reg,
             };
         let enc_config = EncoderTestParams {
@@ -529,6 +559,7 @@ mod test {
                 height:  0,
                 format:  RGB555_FORMAT,
                 flipped: true,
+                bits:    16,
             };
         let enc_params = EncodeParameters {
                 format:  NACodecTypeInfo::Video(dst_vinfo),
@@ -538,6 +569,8 @@ mod test {
                 tb_den:  0,
                 flags:   0,
             };
-        test_encoding_to_file(&dec_config, &enc_config, enc_params);
+        //test_encoding_to_file(&dec_config, &enc_config, enc_params);
+        test_encoding_md5(&dec_config, &enc_config, enc_params,
+                          &[0x8f0d3f66, 0xb91a6ee5, 0x59e4933e, 0x59c6fb0b]);
     }
 }