X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-ms%2Fsrc%2Fcodecs%2Fmsvideo1enc.rs;h=b2233c230b7de7061dba27371da5c2fb12d72fee;hp=6ddae6485a4ffebafea4328936852994687272c0;hb=78fb6560c73965d834b215fb0b49505ae5443288;hpb=20766f15236404c4eb336229d4a9d202d107bb99 diff --git a/nihav-ms/src/codecs/msvideo1enc.rs b/nihav-ms/src/codecs/msvideo1enc.rs index 6ddae64..b2233c2 100644 --- a/nihav-ms/src/codecs/msvideo1enc.rs +++ b/nihav-ms/src/codecs/msvideo1enc.rs @@ -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>, 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 { 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 { + match name { + KEYFRAME_OPTION => Some(NAValue::Int(i64::from(self.key_int))), + _ => None, + } + } } pub fn get_encoder() -> Box { @@ -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]); } }