X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-commonfmt%2Fsrc%2Fcodecs%2Fcinepakenc.rs;h=ddf2584321afa3881787c4680bc4f559de7fc07f;hp=d40f504dbc828d81aba036177c220e53bbb28cfe;hb=379524159c95f1c3639976ccf35f9d47cd9732ac;hpb=a178c22cac8a9eea22eba4d2e3ebc34294054c6c diff --git a/nihav-commonfmt/src/codecs/cinepakenc.rs b/nihav-commonfmt/src/codecs/cinepakenc.rs index d40f504..ddf2584 100644 --- a/nihav-commonfmt/src/codecs/cinepakenc.rs +++ b/nihav-commonfmt/src/codecs/cinepakenc.rs @@ -169,7 +169,7 @@ impl MaskWriter { } } fn reset(&mut self) { - self.masks.truncate(0); + self.masks.clear(); self.mask = 0; self.pos = 0; } @@ -211,19 +211,41 @@ impl MaskWriter { } } +#[derive(Clone,Copy,PartialEq)] +enum QuantMode { + ELBG, + Hybrid, + MedianCut, +} + +impl std::string::ToString for QuantMode { + fn to_string(&self) -> String { + match *self { + QuantMode::ELBG => "elbg".to_string(), + QuantMode::Hybrid => "hybrid".to_string(), + QuantMode::MedianCut => "mediancut".to_string(), + } + } +} + struct CinepakEncoder { stream: Option, lastfrm: Option>, pkt: Option, frmcount: u8, + key_int: u8, + qmode: QuantMode, quality: u8, nstrips: usize, + cur_strip: usize, v1_entries: Vec, v4_entries: Vec, - v1_cb: [YUVCode; 256], - v4_cb: [YUVCode; 256], - v1_cur_cb: [YUVCode; 256], - v4_cur_cb: [YUVCode; 256], + v1_cb: Vec<[YUVCode; 256]>, + v4_cb: Vec<[YUVCode; 256]>, + v1_cur_cb: Vec<[YUVCode; 256]>, + v4_cur_cb: Vec<[YUVCode; 256]>, + v1_len: usize, + v4_len: usize, v1_idx: Vec, v4_idx: Vec, grayscale: bool, @@ -251,14 +273,19 @@ impl CinepakEncoder { pkt: None, lastfrm: None, frmcount: 0, + qmode: QuantMode::MedianCut, + key_int: 25, quality: 0, nstrips: 2, + cur_strip: 0, v1_entries: Vec::new(), v4_entries: Vec::new(), - v1_cb: [YUVCode::default(); 256], - v4_cb: [YUVCode::default(); 256], - v1_cur_cb: [YUVCode::default(); 256], - v4_cur_cb: [YUVCode::default(); 256], + v1_cb: Vec::with_capacity(2), + v4_cb: Vec::with_capacity(2), + v1_cur_cb: Vec::with_capacity(2), + v4_cur_cb: Vec::with_capacity(2), + v1_len: 0, + v4_len: 0, grayscale: false, rng: RNG::new(), v1_idx: Vec::new(), @@ -276,8 +303,8 @@ impl CinepakEncoder { let mut voff = in_frm.get_offset(2) + start / 2 * vstride; let (width, _) = in_frm.get_dimensions(0); let data = in_frm.get_data(); - self.v1_entries.truncate(0); - self.v4_entries.truncate(0); + self.v1_entries.clear(); + self.v4_entries.clear(); for _ in (start..end).step_by(4) { for x in (0..width).step_by(4) { let mut yblk = [0; 16]; @@ -318,7 +345,7 @@ impl CinepakEncoder { voff += vstride * 2; } } - fn find_nearest(codebook: &[YUVCode; 256], code: YUVCode) -> (u8, u32) { + fn find_nearest(codebook: &[YUVCode], code: YUVCode) -> (u8, u32) { let mut min_dist = std::u32::MAX; let mut idx = 0; for (i, cw) in codebook.iter().enumerate() { @@ -411,7 +438,7 @@ impl CinepakEncoder { for _ in (start..end).step_by(4) { for x in (0..width).step_by(4) { if cur_bit == 0 { - if !intra || self.v1_idx.len() > 0 { + if !intra || !self.v1_idx.is_empty() { cur_mask = *miter.next().unwrap(); } else { cur_mask = 0xFFFFFFFF; @@ -431,7 +458,7 @@ impl CinepakEncoder { } if (cur_mask & cur_bit) == 0 { let idx = *v1_iter.next().unwrap() as usize; - let cb = &self.v1_cur_cb[idx]; + let cb = &self.v1_cur_cb[self.cur_strip][idx]; let mut coff = yoff + x; data[coff] = cb.y[0]; data[coff + 1] = cb.y[0]; @@ -459,13 +486,13 @@ impl CinepakEncoder { } } else { let idx0 = *v4_iter.next().unwrap() as usize; - let cb0 = &self.v4_cur_cb[idx0]; + let cb0 = &self.v4_cur_cb[self.cur_strip][idx0]; let idx1 = *v4_iter.next().unwrap() as usize; - let cb1 = &self.v4_cur_cb[idx1]; + let cb1 = &self.v4_cur_cb[self.cur_strip][idx1]; let idx2 = *v4_iter.next().unwrap() as usize; - let cb2 = &self.v4_cur_cb[idx2]; + let cb2 = &self.v4_cur_cb[self.cur_strip][idx2]; let idx3 = *v4_iter.next().unwrap() as usize; - let cb3 = &self.v4_cur_cb[idx3]; + let cb3 = &self.v4_cur_cb[self.cur_strip][idx3]; let mut coff = yoff + x; data[coff] = cb0.y[0]; data[coff + 1] = cb0.y[1]; @@ -503,7 +530,7 @@ impl CinepakEncoder { } } fn calc_skip_dist(&mut self, in_frm: &NAVideoBuffer, start: usize, end: usize) { - self.skip_dist.truncate(0); + self.skip_dist.clear(); if let Some(ref ref_frm) = self.lastfrm { let rystride = ref_frm.get_stride(0); let mut ryoff = ref_frm.get_offset(0) + start * rystride; @@ -574,6 +601,39 @@ impl CinepakEncoder { unreachable!(); } } + fn quant_vectors(&mut self) { + match self.qmode { + QuantMode::ELBG => { + let mut elbg_v1: ELBG = ELBG::new(&self.v1_cb[self.cur_strip]); + let mut elbg_v4: ELBG = ELBG::new(&self.v4_cb[self.cur_strip]); + + for entry in self.v1_cb[self.cur_strip].iter_mut().skip(self.v1_len) { + self.rng.fill_entry(entry); + } + for entry in self.v4_cb[self.cur_strip].iter_mut().skip(self.v4_len) { + self.rng.fill_entry(entry); + } + + self.v1_len = elbg_v1.quantise(&self.v1_entries, &mut self.v1_cur_cb[self.cur_strip]); + self.v4_len = elbg_v4.quantise(&self.v4_entries, &mut self.v4_cur_cb[self.cur_strip]); + }, + QuantMode::Hybrid => { + quantise_median_cut::(&self.v1_entries, &mut self.v1_cur_cb[self.cur_strip]); + quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb[self.cur_strip]); + let mut elbg_v1: ELBG = ELBG::new(&self.v1_cur_cb[self.cur_strip]); + let mut elbg_v4: ELBG = ELBG::new(&self.v4_cur_cb[self.cur_strip]); + self.v1_len = elbg_v1.quantise(&self.v1_entries, &mut self.v1_cur_cb[self.cur_strip]); + self.v4_len = elbg_v4.quantise(&self.v4_entries, &mut self.v4_cur_cb[self.cur_strip]); + }, + QuantMode::MedianCut => { + self.v1_len = quantise_median_cut::(&self.v1_entries, &mut self.v1_cur_cb[self.cur_strip]); + self.v4_len = quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb[self.cur_strip]); + }, + }; + + for e in self.v1_cur_cb[self.cur_strip].iter_mut().skip(self.v1_len) { *e = YUVCode::default(); } + for e in self.v4_cur_cb[self.cur_strip].iter_mut().skip(self.v4_len) { *e = YUVCode::default(); } + } fn encode_intra(&mut self, bw: &mut ByteWriter, in_frm: &NAVideoBuffer) -> EncoderResult { let (width, height) = in_frm.get_dimensions(0); let mut strip_h = (height / self.nstrips + 3) & !3; @@ -591,47 +651,47 @@ impl CinepakEncoder { bw.write_u16be(height as u16)?; bw.write_u16be(self.nstrips as u16)?; - for entry in self.v1_cb.iter_mut() { + self.cur_strip = 0; + for entry in self.v1_cb[self.cur_strip].iter_mut() { self.rng.fill_entry(entry); } - for entry in self.v4_cb.iter_mut() { + for entry in self.v4_cb[self.cur_strip].iter_mut() { self.rng.fill_entry(entry); } while start_line < height { self.read_strip(in_frm, start_line, end_line); -// let mut elbg_v1: ELBG = ELBG::new(&self.v1_cb); -// let mut elbg_v4: ELBG = ELBG::new(&self.v4_cb); -// elbg_v1.quantise(&self.v1_entries, &mut self.v1_cur_cb); -// elbg_v4.quantise(&self.v4_entries, &mut self.v4_cur_cb); -quantise_median_cut::(&self.v1_entries, &mut self.v1_cur_cb); -quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb); + if self.cur_strip > 0 { + self.v1_cb[self.cur_strip] = self.v1_cb[self.cur_strip - 1]; + self.v4_cb[self.cur_strip] = self.v4_cb[self.cur_strip - 1]; + } + self.quant_vectors(); if self.grayscale { - for cw in self.v1_cur_cb.iter_mut() { + for cw in self.v1_cur_cb[self.cur_strip].iter_mut() { cw.u = 128; cw.v = 128; } - for cw in self.v4_cur_cb.iter_mut() { + for cw in self.v4_cur_cb[self.cur_strip].iter_mut() { cw.u = 128; cw.v = 128; } } - self.v1_idx.truncate(0); - self.v4_idx.truncate(0); + self.v1_idx.clear(); + self.v4_idx.clear(); self.masks.reset(); for (v1_entry, v4_entries) in self.v1_entries.iter().zip(self.v4_entries.chunks(4)) { - let (v1_idx, v1_dist) = Self::find_nearest(&self.v1_cur_cb, *v1_entry); + let (v1_idx, v1_dist) = Self::find_nearest(&self.v1_cur_cb[self.cur_strip][..self.v1_len], *v1_entry); if v1_dist == 0 { self.masks.put_v1(); self.v1_idx.push(v1_idx); continue; } - let (v40_idx, v40_dist) = Self::find_nearest(&self.v4_cur_cb, v4_entries[0]); - let (v41_idx, v41_dist) = Self::find_nearest(&self.v4_cur_cb, v4_entries[1]); - let (v42_idx, v42_dist) = Self::find_nearest(&self.v4_cur_cb, v4_entries[2]); - let (v43_idx, v43_dist) = Self::find_nearest(&self.v4_cur_cb, v4_entries[3]); + let (v40_idx, v40_dist) = Self::find_nearest(&self.v4_cur_cb[self.cur_strip][..self.v4_len], v4_entries[0]); + let (v41_idx, v41_dist) = Self::find_nearest(&self.v4_cur_cb[self.cur_strip][..self.v4_len], v4_entries[1]); + let (v42_idx, v42_dist) = Self::find_nearest(&self.v4_cur_cb[self.cur_strip][..self.v4_len], v4_entries[2]); + let (v43_idx, v43_dist) = Self::find_nearest(&self.v4_cur_cb[self.cur_strip][..self.v4_len], v4_entries[3]); if v40_dist + v41_dist + v42_dist + v43_dist > v1_dist { self.masks.put_v4(); self.v4_idx.push(v40_idx); @@ -648,8 +708,8 @@ quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb let mut is_intra_strip = start_line == 0; let (upd_v1, upd_v4) = if !is_intra_strip { let cb_size = if self.grayscale { 4 } else { 6 }; - (Self::can_update_cb(&self.v1_cur_cb, &self.v1_cb, cb_size), - Self::can_update_cb(&self.v4_cur_cb, &self.v4_cb, cb_size)) + (Self::can_update_cb(&self.v1_cur_cb[self.cur_strip], &self.v1_cb[self.cur_strip], cb_size), + Self::can_update_cb(&self.v4_cur_cb[self.cur_strip], &self.v4_cb[self.cur_strip], cb_size)) } else { (false, false) }; @@ -664,15 +724,15 @@ quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb bw.write_u16be((end_line - start_line) as u16)?; bw.write_u16be(width as u16)?; - Self::write_cb(bw, 0x20, &self.v4_cur_cb, &self.v4_cb, self.grayscale, upd_v4)?; - Self::write_cb(bw, 0x22, &self.v1_cur_cb, &self.v1_cb, self.grayscale, upd_v1)?; + Self::write_cb(bw, 0x20, &self.v4_cur_cb[self.cur_strip], &self.v4_cb[self.cur_strip], self.grayscale, upd_v4)?; + Self::write_cb(bw, 0x22, &self.v1_cur_cb[self.cur_strip], &self.v1_cb[self.cur_strip], self.grayscale, upd_v1)?; self.render_stripe(true, start_line, end_line); - if self.v1_idx.len() == 0 { + if self.v4_idx.is_empty() { bw.write_byte(0x32)?; - bw.write_u24be((self.v4_idx.len() + 4) as u32)?; - bw.write_buf(self.v4_idx.as_slice())?; + bw.write_u24be((self.v1_idx.len() + 4) as u32)?; + bw.write_buf(self.v1_idx.as_slice())?; } else { bw.write_byte(0x30)?; bw.write_u24be(0)?; @@ -706,10 +766,12 @@ quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb patch_size(bw, strip_data_pos)?; - self.v1_cb.copy_from_slice(&self.v1_cur_cb); - self.v4_cb.copy_from_slice(&self.v4_cur_cb); + self.v1_cb[self.cur_strip].copy_from_slice(&self.v1_cur_cb[self.cur_strip]); + self.v4_cb[self.cur_strip].copy_from_slice(&self.v4_cur_cb[self.cur_strip]); start_line = end_line; end_line = (end_line + strip_h).min(height); + + self.cur_strip += 1; } patch_size(bw, frame_data_pos)?; Ok(true) @@ -731,29 +793,25 @@ quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb bw.write_u16be(height as u16)?; bw.write_u16be(self.nstrips as u16)?; + self.cur_strip = 0; while start_line < height { self.read_strip(in_frm, start_line, end_line); self.calc_skip_dist(in_frm, start_line, end_line); -// let mut elbg_v1: ELBG = ELBG::new(&self.v1_cb); -// let mut elbg_v4: ELBG = ELBG::new(&self.v4_cb); -// elbg_v1.quantise(&self.v1_entries, &mut self.v1_cur_cb); -// elbg_v4.quantise(&self.v4_entries, &mut self.v4_cur_cb); -quantise_median_cut::(&self.v1_entries, &mut self.v1_cur_cb); -quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb); + self.quant_vectors(); if self.grayscale { - for cw in self.v1_cur_cb.iter_mut() { + for cw in self.v1_cur_cb[self.cur_strip].iter_mut() { cw.u = 128; cw.v = 128; } - for cw in self.v4_cur_cb.iter_mut() { + for cw in self.v4_cur_cb[self.cur_strip].iter_mut() { cw.u = 128; cw.v = 128; } } - self.v1_idx.truncate(0); - self.v4_idx.truncate(0); + self.v1_idx.clear(); + self.v4_idx.clear(); self.masks.reset(); let mut skip_iter = self.skip_dist.iter(); @@ -763,7 +821,7 @@ quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb self.masks.put_inter(true); continue; } - let (v1_idx, v1_dist) = Self::find_nearest(&self.v1_cur_cb, *v1_entry); + let (v1_idx, v1_dist) = Self::find_nearest(&self.v1_cur_cb[self.cur_strip][..self.v1_len], *v1_entry); if skip_dist < v1_dist { self.masks.put_inter(true); continue; @@ -775,10 +833,10 @@ quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb self.v1_idx.push(v1_idx); continue; } - let (v40_idx, v40_dist) = Self::find_nearest(&self.v4_cur_cb, v4_entries[0]); - let (v41_idx, v41_dist) = Self::find_nearest(&self.v4_cur_cb, v4_entries[1]); - let (v42_idx, v42_dist) = Self::find_nearest(&self.v4_cur_cb, v4_entries[2]); - let (v43_idx, v43_dist) = Self::find_nearest(&self.v4_cur_cb, v4_entries[3]); + let (v40_idx, v40_dist) = Self::find_nearest(&self.v4_cur_cb[self.cur_strip][..self.v4_len], v4_entries[0]); + let (v41_idx, v41_dist) = Self::find_nearest(&self.v4_cur_cb[self.cur_strip][..self.v4_len], v4_entries[1]); + let (v42_idx, v42_dist) = Self::find_nearest(&self.v4_cur_cb[self.cur_strip][..self.v4_len], v4_entries[2]); + let (v43_idx, v43_dist) = Self::find_nearest(&self.v4_cur_cb[self.cur_strip][..self.v4_len], v4_entries[3]); if v40_dist + v41_dist + v42_dist + v43_dist > v1_dist { self.masks.put_v4(); self.v4_idx.push(v40_idx); @@ -794,8 +852,8 @@ quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb let (upd_v1, upd_v4) = { let cb_size = if self.grayscale { 4 } else { 6 }; - (Self::can_update_cb(&self.v1_cur_cb, &self.v1_cb, cb_size), - Self::can_update_cb(&self.v4_cur_cb, &self.v4_cb, cb_size)) + (Self::can_update_cb(&self.v1_cur_cb[self.cur_strip], &self.v1_cb[self.cur_strip], cb_size), + Self::can_update_cb(&self.v4_cur_cb[self.cur_strip], &self.v4_cb[self.cur_strip], cb_size)) }; bw.write_byte(0x11)?; bw.write_u24be(0)?; // strip size @@ -805,8 +863,8 @@ quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb bw.write_u16be((end_line - start_line) as u16)?; bw.write_u16be(width as u16)?; - Self::write_cb(bw, 0x20, &self.v4_cur_cb, &self.v4_cb, self.grayscale, upd_v4)?; - Self::write_cb(bw, 0x22, &self.v1_cur_cb, &self.v1_cb, self.grayscale, upd_v1)?; + Self::write_cb(bw, 0x20, &self.v4_cur_cb[self.cur_strip], &self.v4_cb[self.cur_strip], self.grayscale, upd_v4)?; + Self::write_cb(bw, 0x22, &self.v1_cur_cb[self.cur_strip], &self.v1_cb[self.cur_strip], self.grayscale, upd_v1)?; self.render_stripe(false, start_line, end_line); @@ -851,10 +909,12 @@ quantise_median_cut::(&self.v4_entries, &mut self.v4_cur_cb patch_size(bw, strip_data_pos)?; - self.v1_cb.copy_from_slice(&self.v1_cur_cb); - self.v4_cb.copy_from_slice(&self.v4_cur_cb); + self.v1_cb[self.cur_strip].copy_from_slice(&self.v1_cur_cb[self.cur_strip]); + self.v4_cb[self.cur_strip].copy_from_slice(&self.v4_cur_cb[self.cur_strip]); start_line = end_line; end_line = (end_line + strip_h).min(height); + + self.cur_strip += 1; } patch_size(bw, frame_data_pos)?; Ok(true) @@ -869,11 +929,11 @@ impl NAEncoder for CinepakEncoder { ofmt.format = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, true, YUV420_FORMAT)); Ok(ofmt) }, - NACodecTypeInfo::Audio(_) => return Err(EncoderError::FormatError), + NACodecTypeInfo::Audio(_) => Err(EncoderError::FormatError), NACodecTypeInfo::Video(vinfo) => { let pix_fmt = if vinfo.format == GRAY_FORMAT { GRAY_FORMAT } else { YUV420_FORMAT }; - let outinfo = NAVideoInfo::new((vinfo.width + 3) & !3, (vinfo.height + 3) & !3, true, pix_fmt); - let mut ofmt = EncodeParameters::default(); + let outinfo = NAVideoInfo::new((vinfo.width + 3) & !3, (vinfo.height + 3) & !3, false, pix_fmt); + let mut ofmt = *encinfo; ofmt.format = NACodecTypeInfo::Video(outinfo); Ok(ofmt) } @@ -895,8 +955,10 @@ impl NAEncoder for CinepakEncoder { } let out_info = NAVideoInfo::new(vinfo.width, vinfo.height, false, vinfo.format); - let info = NACodecInfo::new("cinepak", NACodecTypeInfo::Video(out_info.clone()), None); - let stream = NAStream::new(StreamType::Video, stream_id, info, encinfo.tb_num, encinfo.tb_den).into_ref(); + let info = NACodecInfo::new("cinepak", NACodecTypeInfo::Video(out_info), None); + let mut stream = NAStream::new(StreamType::Video, stream_id, info, encinfo.tb_num, encinfo.tb_den, 0); + stream.set_num(stream_id as usize); + let stream = stream.into_ref(); self.stream = Some(stream.clone()); self.quality = encinfo.quality; @@ -910,7 +972,7 @@ impl NAEncoder for CinepakEncoder { let buf = alloc_video_buffer(out_info, 2)?; self.lastfrm = Some(buf.get_vbuf().unwrap()); - + Ok(stream) }, } @@ -918,6 +980,19 @@ impl NAEncoder for CinepakEncoder { fn encode(&mut self, frm: &NAFrame) -> EncoderResult<()> { let buf = frm.get_buffer(); if let Some(ref vbuf) = buf.get_vbuf() { + let cur_strips = self.v1_cb.len(); + if cur_strips != self.nstrips { + self.frmcount = 0; + } + if cur_strips < self.nstrips { + for _ in cur_strips..self.nstrips { + self.v1_cb.push([YUVCode::default(); 256]); + self.v4_cb.push([YUVCode::default(); 256]); + self.v1_cur_cb.push([YUVCode::default(); 256]); + self.v4_cur_cb.push([YUVCode::default(); 256]); + } + } + let mut dbuf = Vec::with_capacity(4); let mut gw = GrowableMemoryWriter::new_write(&mut dbuf); let mut bw = ByteWriter::new(&mut gw); @@ -928,7 +1003,7 @@ impl NAEncoder for CinepakEncoder { }; 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(()) @@ -947,10 +1022,59 @@ impl NAEncoder for CinepakEncoder { } } +const ENCODER_OPTS: &[NAOptionDefinition] = &[ + NAOptionDefinition { + name: KEYFRAME_OPTION, description: KEYFRAME_OPTION_DESC, + opt_type: NAOptionDefinitionType::Int(Some(0), Some(128)) }, + NAOptionDefinition { + name: "nstrips", description: "Number of strips per frame (0 - automatic)", + opt_type: NAOptionDefinitionType::Int(Some(0), Some(16)) }, + NAOptionDefinition { + name: "quant_mode", description: "Quantisation mode", + opt_type: NAOptionDefinitionType::String(Some(&["elbg", "hybrid", "mediancut"])) }, +]; + impl NAOptionHandler for CinepakEncoder { - 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; + } + }, + "nstrips" => { + if let NAValue::Int(intval) = option.value { + self.nstrips = intval as usize; + } + }, + "quant_mode" => { + if let NAValue::String(ref str) = option.value { + match str.as_str() { + "elbg" => self.qmode = QuantMode::ELBG, + "hybrid" => self.qmode = QuantMode::Hybrid, + "mediancut" => self.qmode = QuantMode::MedianCut, + _ => {}, + }; + } + }, + _ => {}, + }; + } + } + } + } + fn query_option_value(&self, name: &str) -> Option { + match name { + KEYFRAME_OPTION => Some(NAValue::Int(i64::from(self.key_int))), + "nstrips" => Some(NAValue::Int(self.nstrips as i64)), + "quant_mode" => Some(NAValue::String(self.qmode.to_string())), + _ => None, + } + } } pub fn get_encoder() -> Box { @@ -970,7 +1094,7 @@ 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); + generic_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(); @@ -994,6 +1118,7 @@ mod test { height: 0, format: YUV420_FORMAT, flipped: true, + bits: 12, }; let enc_params = EncodeParameters { format: NACodecTypeInfo::Video(dst_vinfo), @@ -1003,6 +1128,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, &[], + &[0xd73cb3c7, 0x30d59f90, 0x1d6e0e28, 0x5b72cc0c]); } }