X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-ms%2Fsrc%2Fcodecs%2Fmsvideo1enc.rs;h=f457dfcf78ed6f81daf6f444d53bc38dd12486bf;hb=86b51082f5aa5b94e40aec40c6963ec34071f9b5;hp=3c89f7ae7e4721f694a72d342e55cf9b87ef8104;hpb=608a923fdacd068d33f904a5181691bbae221b94;p=nihav.git diff --git a/nihav-ms/src/codecs/msvideo1enc.rs b/nihav-ms/src/codecs/msvideo1enc.rs index 3c89f7a..f457dfc 100644 --- a/nihav-ms/src/codecs/msvideo1enc.rs +++ b/nihav-ms/src/codecs/msvideo1enc.rs @@ -201,9 +201,9 @@ macro_rules! quant_template { for clr in pix.iter() { if clr[best_axis] > avg[best_axis] { avg2.add(clr); - mask |= mask_bit; } else { avg1.add(clr); + mask |= mask_bit; } mask_bit <<= 1; } @@ -316,7 +316,7 @@ impl BlockState { self.clr2.swap(0, 1); } } else { - let (clrs, mask, dist) = quant2_16pix(&buf); + let (clrs, mask, dist) = quant2_16pix(buf); self.clr2 = clrs; self.clr2_flags = mask; self.clr2_dist = dist; @@ -338,8 +338,8 @@ impl BlockState { let src2 = [buf[off], buf[off + 1], buf[off + 4], buf[off + 5]]; let (clrs, mask, dist) = quant2_4pix(&src2); self.clr8[i] = clrs; - let lo_bits = (mask & 0x3) ^ 0x3; - let hi_bits = ((mask & 0xC) ^ 0xC) << 2; + let lo_bits = mask & 0x3; + let hi_bits = (mask & 0xC) << 2; self.clr8_flags |= (hi_bits | lo_bits) << ((i & 1) * 2 + (i & 2) * 4); self.clr8_dist += dist; } @@ -581,7 +581,7 @@ impl MSVideo1Encoder { let dst = cur_frm.get_data_mut().unwrap(); let mut skip_run = 0; let bpainter = BlockPainter15::new(); - for ((sstrip, rstrip), dstrip) in (&src[soff..]).chunks(sstride * 4).take(h / 4).zip((&rsrc[roff..]).chunks(rstride * 4)).zip((&mut dst[doff..]).chunks_mut(dstride * 4)) { + for ((sstrip, rstrip), dstrip) in src[soff..].chunks(sstride * 4).take(h / 4).zip(rsrc[roff..].chunks(rstride * 4)).zip(dst[doff..].chunks_mut(dstride * 4)) { for x in (0..w).step_by(4) { let mut buf = [UnpackedPixel::default(); 16]; let mut refbuf = [UnpackedPixel::default(); 16]; @@ -662,7 +662,7 @@ impl MSVideo1Encoder { let doff = cur_frm.get_offset(0); let dst = cur_frm.get_data_mut().unwrap(); let bpainter = BlockPainter15::new(); - for (sstrip, dstrip) in (&src[soff..]).chunks(sstride * 4).take(h / 4).zip((&mut dst[doff..]).chunks_mut(dstride * 4)) { + for (sstrip, dstrip) in src[soff..].chunks(sstride * 4).take(h / 4).zip(dst[doff..].chunks_mut(dstride * 4)) { for x in (0..w).step_by(4) { let mut buf = [UnpackedPixel::default(); 16]; Self::get_block(&sstrip[x..], sstride, &mut buf); @@ -701,7 +701,7 @@ impl MSVideo1Encoder { let dst = cur_frm.get_data_mut().unwrap(); let mut skip_run = 0; let bpainter = BlockPainterPal::new(ls); - for ((sstrip, rstrip), dstrip) in (&src[soff..]).chunks(sstride * 4).take(h / 4).zip((&rsrc[roff..]).chunks(rstride * 4)).zip((&mut dst[doff..]).chunks_mut(dstride * 4)) { + for ((sstrip, rstrip), dstrip) in src[soff..].chunks(sstride * 4).take(h / 4).zip(rsrc[roff..].chunks(rstride * 4)).zip(dst[doff..].chunks_mut(dstride * 4)) { for x in (0..w).step_by(4) { let mut buf = [UnpackedPixel::default(); 16]; let mut refbuf = [UnpackedPixel::default(); 16]; @@ -782,7 +782,7 @@ impl MSVideo1Encoder { let doff = cur_frm.get_offset(0); let dst = cur_frm.get_data_mut().unwrap(); let bpainter = BlockPainterPal::new(ls); - for (sstrip, dstrip) in (&src[soff..]).chunks(sstride * 4).take(h / 4).zip((&mut dst[doff..]).chunks_mut(dstride * 4)) { + for (sstrip, dstrip) in src[soff..].chunks(sstride * 4).take(h / 4).zip(dst[doff..].chunks_mut(dstride * 4)) { for x in (0..w).step_by(4) { let mut buf = [UnpackedPixel::default(); 16]; Self::get_block8(&sstrip[x..], sstride, &mut buf, pal); @@ -835,6 +835,7 @@ impl NAEncoder for MSVideo1Encoder { } } } + fn get_capabilities(&self) -> u64 { ENC_CAPS_SKIPFRAME } fn init(&mut self, stream_id: u32, encinfo: EncodeParameters) -> EncoderResult { match encinfo.format { NACodecTypeInfo::None => Err(EncoderError::FormatError), @@ -873,6 +874,31 @@ impl NAEncoder for MSVideo1Encoder { } fn encode(&mut self, frm: &NAFrame) -> EncoderResult<()> { let buf = frm.get_buffer(); + if frm.frame_type == FrameType::Skip { + if let Some(ref stream) = self.stream { + let mut dbuf = Vec::with_capacity(4); + let mut gw = GrowableMemoryWriter::new_write(&mut dbuf); + let mut bw = ByteWriter::new(&mut gw); + + let vinfo = stream.get_info().get_properties().get_video_info().unwrap(); + let mut nskips = ((vinfo.get_width() + 3) / 4) * ((vinfo.get_height() + 3) / 4); + while nskips >= 1023 { + Self::write_skips(&mut bw, 1023)?; + nskips -= 1023; + } + if nskips > 0 { + Self::write_skips(&mut bw, nskips)?; + } + self.pkt = Some(NAPacket::new(self.stream.clone().unwrap(), frm.ts, false, dbuf)); + self.frmcount += 1; + if self.frmcount == self.key_int { + self.frmcount = 0; + } + return Ok(()); + } else { + return Err(EncoderError::Bug); + } + } if let Some(ref vbuf) = buf.get_vbuf16() { if self.pal_mode { return Err(EncoderError::InvalidParameters); @@ -906,7 +932,7 @@ impl NAEncoder for MSVideo1Encoder { for (cur_pal, new_pal) in self.pal.iter_mut().zip(pal.chunks_exact(3)) { let (cur_clr, luma) = cur_pal.split_at_mut(3); let new_clr = [u16::from(new_pal[0]), u16::from(new_pal[1]), u16::from(new_pal[2])]; - if cur_clr != &new_clr { + if cur_clr != new_clr { pal_changed = true; cur_clr.copy_from_slice(&new_clr); luma[0] = rgb2y(cur_clr[0], cur_clr[1], cur_clr[2]); @@ -1050,7 +1076,7 @@ mod test { }; //test_encoding_to_file(&dec_config, &enc_config, enc_params, &[]); test_encoding_md5(&dec_config, &enc_config, enc_params, &[], - &[0x27a9db38, 0x74f1000a, 0x38818c05, 0x99d692ba]); + &[0x5afaf853, 0xd53ba9dd, 0x630f53e7, 0x41b33a36]); } #[test] @@ -1096,6 +1122,6 @@ mod test { }; //test_encoding_to_file(&dec_config, &enc_config, enc_params, &[]); test_encoding_md5(&dec_config, &enc_config, enc_params, &[], - &[0xe570a206, 0xc223063f, 0x44a0b70e, 0xa71fed1f]); + &[0xb3175a7b, 0x4a6cb45e, 0x526f3f5d, 0xaa1574cc]); } }