fix some clippy warnings
[nihav.git] / nihav-commonfmt / src / codecs / zmbvenc.rs
CommitLineData
f1787005
KS
1use nihav_core::codecs::*;
2use nihav_core::compr::deflate::{Deflate, DeflateMode, DeflateWriter};
3use nihav_core::io::byteio::*;
4
5const RGB555_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
6 comp_info: [
7 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 10, comp_offs: 0, next_elem: 2 }),
8 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 5, comp_offs: 0, next_elem: 2 }),
9 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 0, comp_offs: 0, next_elem: 2 }),
10 None, None],
11 elem_size: 2, be: false, alpha: false, palette: false };
12const RGB24_0_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
13 comp_info: [
14 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 2, next_elem: 4 }),
15 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 1, next_elem: 4 }),
16 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 0, next_elem: 4 }),
17 None, None],
18 elem_size: 4, be: false, alpha: false, palette: false };
19
20struct ZMBVEncoder {
21 stream: Option<NAStreamRef>,
22 frm1: Vec<u8>,
23 frm2: Vec<u8>,
24 tmp_buf: Vec<u8>,
25 zbuf: Vec<u8>,
26 pal: [u8; 768],
27 pkt: Option<NAPacket>,
28 frmcount: u8,
29 key_int: u8,
30 tile_w: usize,
31 tile_h: usize,
32 cmode: DeflateMode,
33 compr: Deflate,
34 bpp: u8,
35 width: usize,
36 height: usize,
37 range: usize,
95b8d59d 38 sent_pal: bool,
f1787005
KS
39}
40
41fn buf_type_to_bpp(buf: &NABufferType) -> u8 {
42 match buf {
43 NABufferType::Video(ref vbuf) => {
44 let vinfo = vbuf.get_info();
45 if vinfo.get_format().is_paletted() {
46 8
47 } else {
48 vinfo.get_format().get_total_depth()
49 }
50 },
51 NABufferType::VideoPacked(ref vbuf) => {
52 let vinfo = vbuf.get_info();
53 vinfo.get_format().elem_size * 8
54 },
55 NABufferType::Video16(ref vbuf) => {
56 let vinfo = vbuf.get_info();
57 vinfo.get_format().get_total_depth()
58 },
59 _ => 0,
60 }
61}
62
63fn copy_frame(buf: NABufferType, dst: &mut [u8], bpp: u8) -> EncoderResult<()> {
64 match buf {
65 NABufferType::Video(ref vbuf) => {
66 if bpp != 8 {
67 return Err(EncoderError::FormatError);
68 }
69 let off = vbuf.get_offset(0);
70 let stride = vbuf.get_stride(0);
71 let data = vbuf.get_data();
72 let w = vbuf.get_info().get_width();
73 let h = vbuf.get_info().get_height();
74
75 for (dline, sline) in dst.chunks_mut(w).zip(data[off..].chunks(stride)).take(h) {
76 dline[..w].copy_from_slice(&sline[..w]);
77 }
78 },
79 NABufferType::Video16(ref vbuf) => {
80 let off = vbuf.get_offset(0);
81 let stride = vbuf.get_stride(0);
82 let data = vbuf.get_data();
83 let w = vbuf.get_info().get_width();
84 let h = vbuf.get_info().get_height();
85
86 for (dline, sline) in dst.chunks_mut(w * 2).zip(data[off..].chunks(stride)).take(h) {
87 for (dst, &src) in dline[..w * 2].chunks_exact_mut(2).zip(sline.iter()) {
88 dst[0] = src as u8;
89 dst[1] = (src >> 8) as u8;
90 }
91 }
92 },
93 NABufferType::VideoPacked(ref vbuf) => {
94 let off = vbuf.get_offset(0);
95 let stride = vbuf.get_stride(0);
96 let data = vbuf.get_data();
97 let w = vbuf.get_info().get_width();
98 let h = vbuf.get_info().get_height();
99 let w = w * (((bpp as usize) + 7) / 8);
100
101 for (dline, sline) in dst.chunks_mut(w).zip(data[off..].chunks(stride)).take(h) {
102 dline[..w].copy_from_slice(&sline[..w]);
103 }
104 },
105 _ => return Err(EncoderError::FormatError),
106 };
107 Ok(())
108}
109
110fn to_signed(val: usize) -> isize {
111 if (val & 1) == 0 {
112 (val >> 1) as isize
113 } else {
114 -((val >> 1) as isize) - 1
115 }
116}
117
118impl ZMBVEncoder {
119 fn new() -> Self {
120 Self {
121 stream: None,
122 pkt: None,
123 frm1: Vec::new(),
124 frm2: Vec::new(),
125 pal: [0; 768],
126 tmp_buf: Vec::new(),
127 zbuf: Vec::new(),
128 frmcount: 0,
129 key_int: 25,
130 tile_w: 16,
131 tile_h: 16,
132 cmode: DeflateMode::default(),
133 compr: Deflate::new(DeflateMode::default()),
134 bpp: 0,
135 width: 0,
136 height: 0,
137 range: 128,
95b8d59d 138 sent_pal: false,
f1787005
KS
139 }
140 }
141 fn encode_intra(&mut self, bw: &mut ByteWriter, buf: NABufferType) -> EncoderResult<()> {
142 let bpp = buf_type_to_bpp(&buf);
143
144 if let NABufferType::None = buf {
145 if self.bpp == 0 {
146 return Err(EncoderError::FormatError);
147 }
148 self.frm1.copy_from_slice(&self.frm2);
149 } else {
150 if bpp == 0 {
151 return Err(EncoderError::FormatError);
152 }
153 self.bpp = bpp;
154
155 if let (NABufferType::Video(ref vbuf), true) = (&buf, bpp == 8) {
156 let off = vbuf.get_offset(1);
157 let data = vbuf.get_data();
158 self.pal.copy_from_slice(&data[off..][..768]);
159 }
160
161 copy_frame(buf, &mut self.frm1, self.bpp)?;
162 }
163
164 bw.write_byte(1)?; // intra flag
165 bw.write_byte(0)?; // high version
166 bw.write_byte(1)?; // low version
167 bw.write_byte(if self.cmode == DeflateMode::NoCompr { 0 } else { 1 })?;
168 let fmt = match self.bpp {
169 8 => 4,
170 15 => 5,
171 16 => 6,
172 24 => 7,
173 32 => 8,
174 _ => unreachable!(),
175 };
176 bw.write_byte(fmt)?;
177 bw.write_byte(self.tile_w as u8)?;
178 bw.write_byte(self.tile_h as u8)?;
179
180 let bm = ((bpp as usize) + 7) / 8;
181 if self.cmode == DeflateMode::NoCompr {
182 if bpp == 8 {
183 bw.write_buf(&self.pal)?;
184 }
185 bw.write_buf(&self.frm1[..self.width * self.height * bm])?;
186 } else {
37952415 187 self.tmp_buf.clear();
f1787005
KS
188 if bpp == 8 {
189 self.tmp_buf.extend_from_slice(&self.pal);
190 }
191 self.tmp_buf.extend_from_slice(&self.frm1[..self.width * self.height * bm]);
192 self.compr = Deflate::new(self.cmode);
193
194 let mut db = Vec::new();
195 std::mem::swap(&mut db, &mut self.zbuf);
37952415 196 db.clear();
f1787005
KS
197 let mut wr = DeflateWriter::new(db);
198 self.compr.write_zlib_header(&mut wr);
199 self.compr.compress(&self.tmp_buf, &mut wr);
200 self.compr.compress_flush(&mut wr);
201 let mut db = wr.end();
202 std::mem::swap(&mut db, &mut self.zbuf);
203
204 bw.write_buf(&self.zbuf)?;
205 }
206
207 Ok(())
208 }
209 fn encode_inter(&mut self, bw: &mut ByteWriter, buf: NABufferType) -> EncoderResult<()> {
210 if let NABufferType::None = buf {
211 self.frm1.copy_from_slice(&self.frm2);
212
213 bw.write_byte(0)?;
37952415 214 self.tmp_buf.clear();
f1787005
KS
215 let tile_w = (self.width + self.tile_w - 1) / self.tile_w;
216 let tile_h = (self.height + self.tile_h - 1) / self.tile_h;
217 let mv_size = (tile_w * tile_h * 2 + 3) & !3;
218 for _ in 0..mv_size {
219 self.tmp_buf.push(0);
220 }
221 if self.cmode == DeflateMode::NoCompr {
222 bw.write_buf(&self.tmp_buf)?;
223 } else {
224 let mut db = Vec::new();
225
226 std::mem::swap(&mut db, &mut self.zbuf);
37952415 227 db.clear();
f1787005
KS
228 let mut wr = DeflateWriter::new(db);
229 self.compr.compress(&self.tmp_buf, &mut wr);
230 self.compr.compress_flush(&mut wr);
231 let mut db = wr.end();
232 std::mem::swap(&mut db, &mut self.zbuf);
233
234 bw.write_buf(&self.zbuf)?;
235 }
236 return Ok(());
237 }
238 let bpp = buf_type_to_bpp(&buf);
239 if bpp == 0 || bpp != self.bpp {
240 return Err(EncoderError::FormatError);
241 }
242
37952415 243 self.tmp_buf.clear();
f1787005
KS
244 if let (NABufferType::Video(ref vbuf), true) = (&buf, bpp == 8) {
245 let mut npal = [0; 768];
246 let off = vbuf.get_offset(1);
247 let data = vbuf.get_data();
248 npal.copy_from_slice(&data[off..][..768]);
249 let mut cmp = true;
250 for (&a, &b) in self.pal.iter().zip(npal.iter()) {
251 if a != b {
252 cmp = false;
253 break;
254 }
255 }
256 if !cmp {
257 for (&a, &b) in self.pal.iter().zip(npal.iter()) {
258 self.tmp_buf.push(a ^ b);
259 }
260 self.pal = npal;
261
262 bw.write_byte(2)?;
95b8d59d
KS
263
264 self.sent_pal = false;
f1787005
KS
265 } else {
266 bw.write_byte(0)?;
267 }
268 } else {
269 bw.write_byte(0)?;
270 }
271 copy_frame(buf, &mut self.frm1, self.bpp)?;
272
273 let tile_w = (self.width + self.tile_w - 1) / self.tile_w;
274 let tile_h = (self.height + self.tile_h - 1) / self.tile_h;
275 let mut mv_start = self.tmp_buf.len();
276 let mv_size = (tile_w * tile_h * 2 + 3) & !3;
277 for _ in 0..mv_size {
278 self.tmp_buf.push(0);
279 }
280
281 let bpp = ((self.bpp as usize) + 7) / 8;
282 let stride = self.width * bpp;
283 let mut off = 0;
284 for y in (0..self.height).step_by(self.tile_h) {
285 let cur_h = (self.height - y).min(self.tile_h);
286 for x in (0..self.width).step_by(self.tile_w) {
287 let cur_w = (self.width - x).min(self.tile_w);
288
289 let mut best_dist = std::u32::MAX;
290 let mut best_x = x;
291 let mut best_y = y;
292
293 'search: for yoff in 0..self.range {
294 let ypos = (y as isize) + to_signed(yoff);
295 if ypos < 0 {
296 continue;
297 }
298 let ypos = ypos as usize;
299 if ypos + cur_h > self.height {
300 break;
301 }
302 for xoff in 0..self.range {
303 let xpos = (x as isize) + to_signed(xoff);
304 if xpos < 0 {
305 continue;
306 }
307 let xpos = xpos as usize;
308 if xpos + cur_w > self.width {
309 break;
310 }
311
312 let mut diff = 0;
313 let roff = xpos * bpp + ypos * stride;
314 for (line0, line1) in self.frm1[off..].chunks(stride).take(cur_h).zip(self.frm2[roff..].chunks(stride)) {
315 for (&a, &b) in line0[..cur_w * bpp].iter().zip(line1[..cur_w * bpp].iter()) {
316 diff += u32::from(a ^ b);
317 }
318 }
319
320 if best_dist > diff {
321 best_dist = diff;
322 best_x = xpos;
323 best_y = ypos;
324 if diff == 0 {
325 break 'search;
326 }
327 }
328 }
329 }
330
331 let has_delta = best_dist != 0;
332 self.tmp_buf[mv_start] = (best_x.wrapping_sub(x) << 1) as u8;
333 if has_delta {
334 self.tmp_buf[mv_start] |= 1;
335 }
336 self.tmp_buf[mv_start + 1] = (best_y.wrapping_sub(y) << 1) as u8;
337 mv_start += 2;
338 if has_delta {
339 let rpos = best_x * bpp + best_y * stride;
340 for (line0, line1) in self.frm1[off..].chunks(stride).take(cur_h).zip(self.frm2[rpos..].chunks(stride)) {
341 for (&a, &b) in line0[..cur_w * bpp].iter().zip(line1[..cur_w * bpp].iter()) {
342 self.tmp_buf.push(a ^ b);
343 }
344 }
345 }
346
347 off += self.tile_w * bpp;
348 }
349 off -= tile_w * self.tile_w * bpp;
350 off += stride * self.tile_h;
351 }
352
353 if self.cmode == DeflateMode::NoCompr {
354 bw.write_buf(&self.tmp_buf)?;
355 } else {
356 let mut db = Vec::new();
357
358 std::mem::swap(&mut db, &mut self.zbuf);
37952415 359 db.clear();
f1787005
KS
360 let mut wr = DeflateWriter::new(db);
361 self.compr.compress(&self.tmp_buf, &mut wr);
362 self.compr.compress_flush(&mut wr);
363 let mut db = wr.end();
364 std::mem::swap(&mut db, &mut self.zbuf);
365
366 bw.write_buf(&self.zbuf)?;
367 }
5181ac4d 368
f1787005
KS
369 Ok(())
370 }
371}
372
373impl NAEncoder for ZMBVEncoder {
374 fn negotiate_format(&self, encinfo: &EncodeParameters) -> EncoderResult<EncodeParameters> {
375 match encinfo.format {
376 NACodecTypeInfo::None => {
6f263099
KS
377 Ok(EncodeParameters {
378 format: NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, true, YUV420_FORMAT)),
379 ..Default::default()
380 })
f1787005
KS
381 },
382 NACodecTypeInfo::Audio(_) => Err(EncoderError::FormatError),
383 NACodecTypeInfo::Video(vinfo) => {
384 let depth = vinfo.format.get_total_depth();
385 let pix_fmt = if vinfo.format.is_paletted() {
386 PAL8_FORMAT
387 } else if !vinfo.format.model.is_rgb() || depth > 16 {
388 RGB24_0_FORMAT
389 } else if depth < 16 {
390 RGB555_FORMAT
391 } else {
392 RGB565_FORMAT
393 };
394 let outinfo = NAVideoInfo::new(vinfo.width, vinfo.height, false, pix_fmt);
395 let mut ofmt = *encinfo;
396 ofmt.format = NACodecTypeInfo::Video(outinfo);
397 Ok(ofmt)
398 }
399 }
400 }
401 fn init(&mut self, stream_id: u32, encinfo: EncodeParameters) -> EncoderResult<NAStreamRef> {
402 match encinfo.format {
403 NACodecTypeInfo::None => Err(EncoderError::FormatError),
404 NACodecTypeInfo::Audio(_) => Err(EncoderError::FormatError),
405 NACodecTypeInfo::Video(vinfo) => {
406 self.width = vinfo.width;
407 self.height = vinfo.height;
5181ac4d 408
f1787005
KS
409 let out_info = NAVideoInfo::new(vinfo.width, vinfo.height, false, vinfo.format);
410 let info = NACodecInfo::new("zmbv", NACodecTypeInfo::Video(out_info), None);
411 let mut stream = NAStream::new(StreamType::Video, stream_id, info, encinfo.tb_num, encinfo.tb_den, 0);
412 stream.set_num(stream_id as usize);
413 let stream = stream.into_ref();
414
415 self.stream = Some(stream.clone());
416
417 self.frm1 = vec![0; vinfo.width * vinfo.height * 4];
418 self.frm2 = vec![0; vinfo.width * vinfo.height * 4];
419
420 Ok(stream)
421 },
422 }
423 }
424 fn encode(&mut self, frm: &NAFrame) -> EncoderResult<()> {
425 let buf = frm.get_buffer();
426 let mut dbuf = Vec::with_capacity(4);
427 let mut gw = GrowableMemoryWriter::new_write(&mut dbuf);
428 let mut bw = ByteWriter::new(&mut gw);
429 let is_intra = if self.frmcount == 0 {
430 self.encode_intra(&mut bw, buf)?;
431 true
432 } else {
433 self.encode_inter(&mut bw, buf)?;
434 false
435 };
436 self.pkt = Some(NAPacket::new(self.stream.clone().unwrap(), frm.ts, is_intra, dbuf));
95b8d59d
KS
437 if self.bpp == 8 && !self.sent_pal {
438 if let NABufferType::Video(ref buf) = frm.get_buffer() {
439 let paloff = buf.get_offset(1);
440 let data = buf.get_data();
441 let mut pal = [0; 1024];
442 let srcpal = &data[paloff..][..768];
443 for (dclr, sclr) in pal.chunks_exact_mut(4).zip(srcpal.chunks_exact(3)) {
444 dclr[..3].copy_from_slice(sclr);
445 }
446 if let Some(ref mut pkt) = &mut self.pkt {
447 pkt.side_data.push(NASideData::Palette(true, Arc::new(pal)));
448 }
449 }
450 self.sent_pal = true;
451 }
f1787005
KS
452 self.frmcount += 1;
453 if self.frmcount == self.key_int {
454 self.frmcount = 0;
455 }
456 std::mem::swap(&mut self.frm1, &mut self.frm2);
457 Ok(())
458 }
459 fn get_packet(&mut self) -> EncoderResult<Option<NAPacket>> {
460 let mut npkt = None;
461 std::mem::swap(&mut self.pkt, &mut npkt);
462 Ok(npkt)
463 }
464 fn flush(&mut self) -> EncoderResult<()> {
465 self.frmcount = 0;
466 Ok(())
467 }
468}
469
470const ENCODER_OPTS: &[NAOptionDefinition] = &[
471 NAOptionDefinition {
472 name: KEYFRAME_OPTION, description: KEYFRAME_OPTION_DESC,
473 opt_type: NAOptionDefinitionType::Int(Some(0), Some(128)) },
474 NAOptionDefinition {
475 name: "range", description: "Block search range (0-128)",
476 opt_type: NAOptionDefinitionType::Int(Some(0), Some(128)) },
477 NAOptionDefinition {
478 name: "tile_width", description: "Block width (1-255)",
479 opt_type: NAOptionDefinitionType::Int(Some(1), Some(255)) },
480 NAOptionDefinition {
481 name: "tile_height", description: "Block width (1-255)",
482 opt_type: NAOptionDefinitionType::Int(Some(1), Some(255)) },
483 NAOptionDefinition {
484 name: "compr_level", description: "Compression level",
485 opt_type: DEFLATE_OPTION_VALUES },
486];
487
488impl NAOptionHandler for ZMBVEncoder {
489 fn get_supported_options(&self) -> &[NAOptionDefinition] { ENCODER_OPTS }
490 fn set_options(&mut self, options: &[NAOption]) {
491 for option in options.iter() {
492 for opt_def in ENCODER_OPTS.iter() {
493 if opt_def.check(option).is_ok() {
494 match option.name {
495 "compr_level" => {
496 if let NAValue::String(ref s) = option.value {
497 if let Ok(val) = s.parse::<DeflateMode>() {
498 self.cmode = val;
499 }
500 }
501 },
502 KEYFRAME_OPTION => {
503 if let NAValue::Int(intval) = option.value {
504 self.key_int = intval as u8;
505 }
506 },
507 "range" => {
508 if let NAValue::Int(intval) = option.value {
509 self.range = intval as usize;
510 }
511 },
512 "tile_width" => {
513 if let NAValue::Int(intval) = option.value {
514 self.tile_w = intval as usize;
515 }
516 },
517 "tile_height" => {
518 if let NAValue::Int(intval) = option.value {
519 self.tile_h = intval as usize;
520 }
521 },
522 _ => {},
523 };
524 }
525 }
526 }
527 }
528 fn query_option_value(&self, name: &str) -> Option<NAValue> {
529 match name {
530 "compr_level" => Some(NAValue::String(self.cmode.to_string())),
531 KEYFRAME_OPTION => Some(NAValue::Int(i64::from(self.key_int))),
532 "range" => Some(NAValue::Int(self.range as i64)),
533 "tile_width" => Some(NAValue::Int(self.tile_w as i64)),
534 "tile_height" => Some(NAValue::Int(self.tile_h as i64)),
535 _ => None,
536 }
537 }
538}
539
540pub fn get_encoder() -> Box<dyn NAEncoder + Send> {
541 Box::new(ZMBVEncoder::new())
542}
543
544#[cfg(test)]
545mod test {
546 use nihav_core::codecs::*;
547 use nihav_core::demuxers::*;
548 use nihav_core::muxers::*;
549 use crate::*;
550 use nihav_codec_support::test::enc_video::*;
551 use super::{RGB555_FORMAT, RGB24_0_FORMAT};
552
886cde48 553 // samples are from https://samples.mplayerhq.hu/V-codecs/ZMBV/
f1787005
KS
554 #[test]
555 fn test_zmbv_encoder_8bit() {
556 let mut dmx_reg = RegisteredDemuxers::new();
557 generic_register_all_demuxers(&mut dmx_reg);
558 let mut dec_reg = RegisteredDecoders::new();
559 generic_register_all_decoders(&mut dec_reg);
560 let mut mux_reg = RegisteredMuxers::new();
561 generic_register_all_muxers(&mut mux_reg);
562 let mut enc_reg = RegisteredEncoders::new();
563 generic_register_all_encoders(&mut enc_reg);
564
565 let dec_config = DecoderTestParams {
566 demuxer: "avi",
567 in_name: "assets/Misc/td3_000.avi",
568 stream_type: StreamType::Video,
569 limit: Some(20),
570 dmx_reg, dec_reg,
571 };
572 let enc_config = EncoderTestParams {
573 muxer: "avi",
574 enc_name: "zmbv",
575 out_name: "zmbv8.avi",
576 mux_reg, enc_reg,
577 };
578 let dst_vinfo = NAVideoInfo {
579 width: 0,
580 height: 0,
581 format: PAL8_FORMAT,
582 flipped: false,
583 bits: 8,
584 };
585 let enc_params = EncodeParameters {
586 format: NACodecTypeInfo::Video(dst_vinfo),
587 quality: 0,
588 bitrate: 0,
589 tb_num: 0,
590 tb_den: 0,
591 flags: 0,
592 };
f714b4e5
KS
593 let enc_options = &[
594 NAOption { name: "range", value: NAValue::Int(16) },
595 ];
b09ecc09
KS
596 //test_encoding_to_file(&dec_config, &enc_config, enc_params, enc_options);
597 test_encoding_md5(&dec_config, &enc_config, enc_params, enc_options,
78556b82 598 &[0x08615111, 0x6f644a35, 0xa4e28f32, 0x35d2e66c]);
f1787005
KS
599 }
600
601 #[test]
602 fn test_zmbv_encoder_15bit() {
603 let mut dmx_reg = RegisteredDemuxers::new();
604 generic_register_all_demuxers(&mut dmx_reg);
605 let mut dec_reg = RegisteredDecoders::new();
606 generic_register_all_decoders(&mut dec_reg);
607 let mut mux_reg = RegisteredMuxers::new();
608 generic_register_all_muxers(&mut mux_reg);
609 let mut enc_reg = RegisteredEncoders::new();
610 generic_register_all_encoders(&mut enc_reg);
611
612 let dec_config = DecoderTestParams {
613 demuxer: "avi",
614 in_name: "assets/Misc/zmbv_15bit.avi",
615 stream_type: StreamType::Video,
616 limit: Some(4),
617 dmx_reg, dec_reg,
618 };
619 let enc_config = EncoderTestParams {
620 muxer: "avi",
621 enc_name: "zmbv",
622 out_name: "zmbv15.avi",
623 mux_reg, enc_reg,
624 };
625 let dst_vinfo = NAVideoInfo {
626 width: 0,
627 height: 0,
628 format: RGB555_FORMAT,
629 flipped: false,
630 bits: 8,
631 };
632 let enc_params = EncodeParameters {
633 format: NACodecTypeInfo::Video(dst_vinfo),
634 quality: 0,
635 bitrate: 0,
636 tb_num: 0,
637 tb_den: 0,
638 flags: 0,
639 };
f714b4e5
KS
640 let enc_options = &[
641 NAOption { name: "range", value: NAValue::Int(16) },
642 ];
b09ecc09
KS
643 //test_encoding_to_file(&dec_config, &enc_config, enc_params, enc_options);
644 test_encoding_md5(&dec_config, &enc_config, enc_params, enc_options,
f714b4e5 645 &[0x1cff4116, 0x5926d91b, 0x60aac53f, 0x8a22bc7b]);
f1787005
KS
646 }
647
648 #[test]
649 fn test_zmbv_encoder_16bit() {
650 let mut dmx_reg = RegisteredDemuxers::new();
651 generic_register_all_demuxers(&mut dmx_reg);
652 let mut dec_reg = RegisteredDecoders::new();
653 generic_register_all_decoders(&mut dec_reg);
654 let mut mux_reg = RegisteredMuxers::new();
655 generic_register_all_muxers(&mut mux_reg);
656 let mut enc_reg = RegisteredEncoders::new();
657 generic_register_all_encoders(&mut enc_reg);
658
659 let dec_config = DecoderTestParams {
660 demuxer: "avi",
661 in_name: "assets/Misc/zmbv_16bit.avi",
662 stream_type: StreamType::Video,
663 limit: Some(4),
664 dmx_reg, dec_reg,
665 };
666 let enc_config = EncoderTestParams {
667 muxer: "avi",
668 enc_name: "zmbv",
669 out_name: "zmbv16.avi",
670 mux_reg, enc_reg,
671 };
672 let dst_vinfo = NAVideoInfo {
673 width: 0,
674 height: 0,
675 format: RGB565_FORMAT,
676 flipped: false,
677 bits: 8,
678 };
679 let enc_params = EncodeParameters {
680 format: NACodecTypeInfo::Video(dst_vinfo),
681 quality: 0,
682 bitrate: 0,
683 tb_num: 0,
684 tb_den: 0,
685 flags: 0,
686 };
f714b4e5
KS
687 let enc_options = &[
688 NAOption { name: "range", value: NAValue::Int(16) },
689 ];
b09ecc09
KS
690 //test_encoding_to_file(&dec_config, &enc_config, enc_params, enc_options);
691 test_encoding_md5(&dec_config, &enc_config, enc_params, enc_options,
f714b4e5 692 &[0xb48aa633, 0x673539fe, 0xa312d45a, 0x76eee134]);
f1787005
KS
693 }
694
695 #[test]
696 fn test_zmbv_encoder_32bit() {
697 let mut dmx_reg = RegisteredDemuxers::new();
698 generic_register_all_demuxers(&mut dmx_reg);
699 let mut dec_reg = RegisteredDecoders::new();
700 generic_register_all_decoders(&mut dec_reg);
701 let mut mux_reg = RegisteredMuxers::new();
702 generic_register_all_muxers(&mut mux_reg);
703 let mut enc_reg = RegisteredEncoders::new();
704 generic_register_all_encoders(&mut enc_reg);
705
706 let dec_config = DecoderTestParams {
707 demuxer: "avi",
708 in_name: "assets/Misc/zmbv_32bit.avi",
709 stream_type: StreamType::Video,
710 limit: Some(4),
711 dmx_reg, dec_reg,
712 };
713 let enc_config = EncoderTestParams {
714 muxer: "avi",
715 enc_name: "zmbv",
716 out_name: "zmbv32.avi",
717 mux_reg, enc_reg,
718 };
719 let dst_vinfo = NAVideoInfo {
720 width: 0,
721 height: 0,
722 format: RGB24_0_FORMAT,
723 flipped: false,
724 bits: 8,
725 };
726 let enc_params = EncodeParameters {
727 format: NACodecTypeInfo::Video(dst_vinfo),
728 quality: 0,
729 bitrate: 0,
730 tb_num: 0,
731 tb_den: 0,
732 flags: 0,
733 };
f714b4e5
KS
734 let enc_options = &[
735 NAOption { name: "range", value: NAValue::Int(16) },
736 ];
b09ecc09
KS
737 //test_encoding_to_file(&dec_config, &enc_config, enc_params, enc_options);
738 test_encoding_md5(&dec_config, &enc_config, enc_params, enc_options,
f714b4e5 739 &[0x0836152c, 0xfcd7e1fc, 0xf1e2f619, 0x874d3dbc]);
f1787005
KS
740 }
741}