introduce a way for encoder to manifest its capabilities
[nihav.git] / nihav-indeo / src / codecs / indeo3enc / mod.rs
index 8ff2aec1bca39ed3a6dfc98d071aa84eadcca4f6..eefa3d7b94bcb95fb6aae470bb3eb79e6886b651 100644 (file)
@@ -148,7 +148,7 @@ impl Indeo3Encoder {
             }
 
             let mut iw = Indeo3Writer::new(dbuf);
-            self.cframe.plane[planeno].encode_tree(&mut iw, &tree, &mut self.cenc, is_intra, ref_plane);
+            self.cframe.plane[planeno].encode_tree(&mut iw, &tree, &mut self.cenc, ref_plane);
             drop(iw);
             while (dbuf.len() & 3) != 0 {
                 dbuf.push(0);
@@ -162,7 +162,7 @@ impl Indeo3Encoder {
         for plane in self.cframe.plane.iter() {
             checksum ^= plane.checksum();
         }
-        write_u16le(&mut dbuf[26..], checksum)?;
+        write_u16le(&mut dbuf[26..], checksum * 2)?;
 
         let size = (dbuf.len() - OS_HEADER_SIZE) as u32;
         write_u32le(&mut dbuf[8..], self.frameno ^ HDR_FIELD_2 ^ FRMH_TAG ^ size)?;
@@ -199,6 +199,7 @@ impl NAEncoder for Indeo3Encoder {
             }
         }
     }
+    fn get_capabilities(&self) -> u64 { ENC_CAPS_SKIPFRAME }
     fn init(&mut self, stream_id: u32, encinfo: EncodeParameters) -> EncoderResult<NAStreamRef> {
         match encinfo.format {
             NACodecTypeInfo::None => Err(EncoderError::FormatError),
@@ -273,6 +274,7 @@ impl NAEncoder for Indeo3Encoder {
 
             let fsize = dbuf.len() as u32;
             self.rc.advance(fsize);
+            self.frameno += 1;
 
             self.pkt = Some(NAPacket::new(self.stream.clone().unwrap(), frm.ts, false, dbuf));
             return Ok(());
@@ -339,20 +341,23 @@ impl NAEncoder for Indeo3Encoder {
             // prepare plane data structure
             for &planeno in PLANE_ORDER.iter() {
                 let ref_plane = &self.pframe.plane[planeno];
-                let tree = self.cframe.plane[planeno].find_cells(is_intra, ref_plane, &self.mv_est);
+                let mut tree = self.cframe.plane[planeno].find_cells(is_intra, ref_plane, &self.mv_est);
                 if self.debug_tree {
                     println!(" tree for plane {}:", planeno);
                     tree.print();
                 }
-                trees.push(tree);
                 let mvs = &mut self.cframe.plane[planeno].mvs;
-                compact_mvs(mvs);
+                if mvs.len() > 256 {
+                    compact_mvs(mvs);
+                    self.cframe.plane[planeno].prune_extra_mvs(&mut tree);
+                }
+                trees.push(tree);
             }
 
             self.encode_planes(&mut dbuf, &trees, is_intra)?;
 
             let cur_quant = self.cenc.quant.unwrap_or(42);
-            if !is_intra && cur_quant < 8 {
+            if self.try_again && !is_intra && cur_quant < 8 {
                 let expected_size = self.rc.get_expected_size();
                 if expected_size > 0 {
                     let cur_size = dbuf.len() as u32;
@@ -587,7 +592,7 @@ mod test {
         let enc_options = &[
                 NAOption { name: super::TRY_AGAIN_OPTION, value: NAValue::Bool(true) },
             ];
-        encode_test("indeo3.avi", enc_options, Some(4), &[0x4cc927d3, 0x9872f824, 0x92dee9cb, 0xaf912ecc]);
+        encode_test("indeo3.avi", enc_options, Some(4), &[0x17d742bc, 0x6f4c1200, 0x79422bac, 0xc46b5dd0]);
     }
     /*#[test]
     fn test_indeo3_roundtrip() {
@@ -626,6 +631,7 @@ mod test {
         }
         let info = NACodecInfo::new("indeo3", NACodecTypeInfo::Video(dst_vinfo), None).into_ref();
         let frm = NAFrame::new(NATimeInfo::new(Some(0), None, None, 1, 12), FrameType::I, true, info.clone(), buffer);
+        //ienc.set_options(&[NAOption{ name: super::DEBUG_FRAME_OPTION, value: NAValue::Bool(true) }]);
         ienc.encode(&frm).unwrap();
         let pkt = ienc.get_packet().unwrap().unwrap();
         println!(" pkt size {}", pkt.get_buffer().len());
@@ -636,6 +642,7 @@ mod test {
         let mut dec = (decfunc)();
         let mut dsupp = Box::new(NADecoderSupport::new());
         dec.init(&mut dsupp, info).unwrap();
+        dec.set_options(&[NAOption{ name: "checksum", value: NAValue::Bool(true) }]);
         let dst = dec.decode(&mut dsupp, &pkt).unwrap();
         if let NABufferType::Video(ref vbuf) = dst.get_buffer() {
             for plane in 0..3 {