]> git.nihav.org Git - nihav.git/blob - nihav-game/src/codecs/gremlinvideo.rs
nihav_registry: fix clippy warnings and tests in detect module
[nihav.git] / nihav-game / src / codecs / gremlinvideo.rs
1 use nihav_core::frame::*;
2 use nihav_core::formats;
3 use nihav_core::formats::{NAChannelType, NAChannelMap};
4 use nihav_core::codecs::*;
5 use nihav_core::io::byteio::*;
6
7 struct GremlinVideoDecoder {
8 info: NACodecInfoRef,
9 pal: [u8; 768],
10 frame: Vec<u8>,
11 frame16: Vec<u16>,
12 scale_v: bool,
13 scale_h: bool,
14 is_16bit: bool,
15 }
16
17 struct Bits8 {
18 queue: u8,
19 fill: u8,
20 }
21
22 struct Bits32 {
23 queue: u32,
24 fill: u8,
25 }
26
27 const PREAMBLE_SIZE: usize = 4096;
28
29 impl Bits8 {
30 fn new() -> Self { Bits8 { queue: 0, fill: 0 } }
31 fn read_2bits(&mut self, br: &mut ByteReader) -> ByteIOResult<u8> {
32 if self.fill == 0 {
33 self.queue = br.read_byte()?;
34 self.fill += 8;
35 }
36 let res = self.queue >> 6;
37 self.queue <<= 2;
38 self.fill -= 2;
39 Ok(res)
40 }
41 }
42
43 impl Bits32 {
44 fn new() -> Self { Bits32 { queue: 0, fill: 0 } }
45 fn fill(&mut self, br: &mut ByteReader) -> ByteIOResult<()> {
46 self.queue = br.read_u32le()?;
47 self.fill = 32;
48 Ok(())
49 }
50 fn read_bits(&mut self, br: &mut ByteReader, nbits: u8) -> ByteIOResult<u32> {
51 let res = self.queue & ((1 << nbits) - 1);
52 self.queue >>= nbits;
53 self.fill -= nbits;
54 if self.fill <= 16 {
55 self.queue |= u32::from(br.read_u16le()?) << self.fill;
56 self.fill += 16;
57 }
58 Ok(res)
59 }
60 }
61
62 impl GremlinVideoDecoder {
63 fn new() -> Self {
64 GremlinVideoDecoder {
65 info: NACodecInfoRef::default(), pal: [0; 768],
66 frame: Vec::new(), frame16: Vec::new(),
67 scale_v: false, scale_h: false, is_16bit: false,
68 }
69 }
70
71 fn lz_copy(&mut self, idx: usize, offset: isize, len: usize) -> DecoderResult<()> {
72 if idx + len > self.frame.len() { return Err(DecoderError::InvalidData); }
73 if offset == -1 {
74 let c = self.frame[idx - 1];
75 for i in 0..len { self.frame[idx + i] = c; }
76 } else if offset < 0 {
77 let start = idx - (-offset as usize);
78 for i in 0..len { self.frame[idx + i] = self.frame[start + i]; }
79 } else {
80 if idx + (offset as usize) + len > self.frame.len() { return Err(DecoderError::InvalidData); }
81 let start = idx + (offset as usize);
82 for i in 0..len { self.frame[idx + i] = self.frame[start + i]; }
83 }
84 Ok(())
85 }
86
87 fn lz_copy16(&mut self, idx: usize, offset: isize, len: usize) -> DecoderResult<()> {
88 if idx + len > self.frame16.len() { return Err(DecoderError::InvalidData); }
89 if offset == -1 {
90 let c = self.frame16[idx - 1];
91 for i in 0..len { self.frame16[idx + i] = c; }
92 } else if offset < 0 {
93 let start = idx - (-offset as usize);
94 for i in 0..len { self.frame16[idx + i] = self.frame16[start + i]; }
95 } else {
96 if idx + (offset as usize) + len > self.frame16.len() { return Err(DecoderError::InvalidData); }
97 let start = idx + (offset as usize);
98 for i in 0..len { self.frame16[idx + i] = self.frame16[start + i]; }
99 }
100 Ok(())
101 }
102
103 fn rescale(&mut self, w: usize, h: usize, scale_v: bool, scale_h: bool) {
104 if (self.scale_v == scale_v) && (self.scale_h == scale_h) { return; }
105
106 if self.scale_h && self.scale_v {
107 for j in 0..h {
108 let y = h - j - 1;
109 for i in 0..w {
110 let x = w - i - 1;
111 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x/2 + (y/2) * (w/2)];
112 }
113 }
114 } else if self.scale_h {
115 for j in 0..h {
116 let y = h - j - 1;
117 for x in 0..w {
118 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x + (y/2) * w];
119 }
120 }
121 } else if self.scale_v {
122 for j in 0..h {
123 let y = h - j - 1;
124 for i in 0..w {
125 let x = w - i - 1;
126 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x/2 + y * (w/2)];
127 }
128 }
129 }
130
131 if scale_h && scale_v {
132 for y in 0..h/2 {
133 for x in 0..w/2 {
134 self.frame[PREAMBLE_SIZE + x + y * (w/2)] = self.frame[PREAMBLE_SIZE + x*2 + y*2 * w];
135 }
136 }
137 } else if scale_h {
138 for y in 0..h/2 {
139 for x in 0..w {
140 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x + y*2 * w];
141 }
142 }
143 } else if scale_v {
144 for y in 0..h {
145 for x in 0..w/2 {
146 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x*2 + y * w];
147 }
148 }
149 }
150
151 self.scale_v = scale_v;
152 self.scale_h = scale_h;
153 }
154
155 fn rescale16(&mut self, w: usize, h: usize, scale_v: bool, scale_h: bool) {
156 if (self.scale_v == scale_v) && (self.scale_h == scale_h) { return; }
157
158 if self.scale_h && self.scale_v {
159 for j in 0..h {
160 let y = h - j - 1;
161 for i in 0..w {
162 let x = w - i - 1;
163 self.frame16[PREAMBLE_SIZE + x + y * w] = self.frame16[PREAMBLE_SIZE + x/2 + (y/2) * (w/2)];
164 }
165 }
166 } else if self.scale_h {
167 for j in 0..h {
168 let y = h - j - 1;
169 for x in 0..w {
170 self.frame16[PREAMBLE_SIZE + x + y * w] = self.frame16[PREAMBLE_SIZE + x + (y/2) * w];
171 }
172 }
173 } else if self.scale_v {
174 for j in 0..h {
175 let y = h - j - 1;
176 for i in 0..w {
177 let x = w - i - 1;
178 self.frame16[PREAMBLE_SIZE + x + y * w] = self.frame16[PREAMBLE_SIZE + x/2 + y * (w/2)];
179 }
180 }
181 }
182
183 if scale_h && scale_v {
184 for y in 0..h/2 {
185 for x in 0..w/2 {
186 self.frame16[PREAMBLE_SIZE + x + y * (w/2)] = self.frame16[PREAMBLE_SIZE + x*2 + y*2 * w];
187 }
188 }
189 } else if scale_h {
190 for y in 0..h/2 {
191 for x in 0..w {
192 self.frame16[PREAMBLE_SIZE + x + y * w] = self.frame16[PREAMBLE_SIZE + x + y*2 * w];
193 }
194 }
195 } else if scale_v {
196 for y in 0..h {
197 for x in 0..w/2 {
198 self.frame16[PREAMBLE_SIZE + x + y * w] = self.frame16[PREAMBLE_SIZE + x*2 + y * w];
199 }
200 }
201 }
202
203 self.scale_v = scale_v;
204 self.scale_h = scale_h;
205 }
206
207 fn output_frame(&mut self, bufinfo: &mut NABufferType, w: usize, h: usize) {
208 let bufo = bufinfo.get_vbuf();
209 let mut buf = bufo.unwrap();
210 let paloff = buf.get_offset(1);
211 let stride = buf.get_stride(0);
212 let data = buf.get_data_mut().unwrap();
213 let dst = data.as_mut_slice();
214 let mut sidx = PREAMBLE_SIZE;
215 let mut didx = 0;
216
217 dst[paloff..][..768].copy_from_slice(&self.pal);
218 if !self.scale_v && !self.scale_h {
219 for _ in 0..h {
220 dst[didx..][..w].copy_from_slice(&self.frame[sidx..][..w]);
221 sidx += w;
222 didx += stride;
223 }
224 } else {
225 for y in 0..h {
226 if !self.scale_v {
227 dst[didx..][..w].copy_from_slice(&self.frame[sidx..][..w]);
228 } else {
229 for x in 0..w { dst[didx + x] = self.frame[sidx + x/2]; }
230 }
231 if !self.scale_h || ((y & 1) == 1) {
232 sidx += if !self.scale_v { w } else { w/2 };
233 }
234 didx += stride;
235 }
236 }
237 }
238
239 fn output_frame16(&mut self, bufinfo: &mut NABufferType, w: usize, h: usize) {
240 let bufo = bufinfo.get_vbuf16();
241 let mut buf = bufo.unwrap();
242 let stride = buf.get_stride(0);
243 let data = buf.get_data_mut().unwrap();
244 let dst = data.as_mut_slice();
245
246 if !self.scale_v && !self.scale_h {
247 for (dline, sline) in dst.chunks_mut(stride).zip(self.frame16[PREAMBLE_SIZE..].chunks(w)).take(h) {
248 dline[..w].copy_from_slice(sline);
249 }
250 } else if !self.scale_h {
251 for (dline, sline) in dst.chunks_mut(stride).zip(self.frame16[PREAMBLE_SIZE..].chunks(w / 2)).take(h) {
252 for (dst, &src) in dline.chunks_mut(2).zip(sline.iter()) {
253 dst[0] = src;
254 dst[1] = src;
255 }
256 }
257 } else if !self.scale_v {
258 for (dline, sline) in dst.chunks_mut(stride * 2).zip(self.frame16[PREAMBLE_SIZE..].chunks(w)).take(h) {
259 dline[..w].copy_from_slice(sline);
260 dline[stride..][..w].copy_from_slice(sline);
261 }
262 } else {
263 for (dline, sline) in dst.chunks_mut(stride).zip(self.frame16[PREAMBLE_SIZE..].chunks(w / 2)).take(h) {
264 for x in 0..w/2 {
265 dline[x * 2] = sline[x];
266 dline[x * 2 + 1] = sline[x];
267 dline[x * 2 + stride] = sline[x];
268 dline[x * 2 + 1 + stride] = sline[x];
269 }
270 }
271 }
272 }
273
274 fn decode_method2(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
275 let mut bits = Bits8::new();
276
277 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
278 self.info.get_properties().get_video_info().unwrap().get_height();
279 let mut idx = PREAMBLE_SIZE;
280 if self.frame[8] != 0 {
281 for c in 0..256 {
282 for i in 0..16 { self.frame[c * 16 + i] = c as u8; }
283 }
284 }
285 while size > 0 {
286 let tag = bits.read_2bits(br)?;
287 if tag == 0 {
288 self.frame[idx] = br.read_byte()?;
289 size -= 1;
290 idx += 1;
291 } else if tag == 1 {
292 let b = br.read_byte()?;
293 let len = ((b & 0xF) as usize) + 3;
294 let bot = (b >> 4) as isize;
295 let off = ((br.read_byte()? as isize) << 4) + bot - 4096;
296 validate!(len <= size);
297 size -= len;
298 self.lz_copy(idx, off, len)?;
299 idx += len;
300 } else if tag == 2 {
301 let len = (br.read_byte()? as usize) + 2;
302 validate!(len <= size);
303 size -= len;
304 idx += len;
305 } else {
306 break;
307 }
308 }
309 Ok(())
310 }
311
312 fn decode_method2_16bit(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
313 let mut bits = Bits8::new();
314
315 if self.frame16[8] != 64 {
316 for (i, dst) in self.frame16[..PREAMBLE_SIZE].chunks_mut(4).enumerate() {
317 let val = (i as u16) << 5;
318 for el in dst.iter_mut() {
319 *el = val;
320 }
321 }
322 }
323
324 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
325 self.info.get_properties().get_video_info().unwrap().get_height();
326 let mut idx = PREAMBLE_SIZE;
327 while size > 0 {
328 let tag = bits.read_2bits(br)?;
329 if tag == 0 {
330 self.frame16[idx] = br.read_u16le()?;
331 size -= 1;
332 idx += 1;
333 } else if tag == 1 {
334 let b = br.read_byte()?;
335 let len = ((b & 0xF) as usize) + 3;
336 let bot = (b >> 4) as isize;
337 let off = ((br.read_byte()? as isize) << 4) + bot - 4096;
338 validate!(len <= size);
339 size -= len;
340 self.lz_copy16(idx, off, len)?;
341 idx += len;
342 } else if tag == 2 {
343 let len = (br.read_byte()? as usize) + 2;
344 validate!(len <= size);
345 size -= len;
346 idx += len;
347 } else {
348 break;
349 }
350 }
351 Ok(())
352 }
353
354 fn decode_method5(&mut self, br: &mut ByteReader, skip: usize) -> DecoderResult<()> {
355 let mut bits = Bits8::new();
356
357 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
358 self.info.get_properties().get_video_info().unwrap().get_height();
359 let mut idx = PREAMBLE_SIZE;
360 validate!(size >= skip);
361 size -= skip;
362 idx += skip;
363 while size > 0 {
364 let tag = bits.read_2bits(br)?;
365 if tag == 0 {
366 self.frame[idx] = br.read_byte()?;
367 size -= 1;
368 idx += 1;
369 } else if tag == 1 {
370 let b = br.read_byte()?;
371 let len = ((b & 0xF) as usize) + 3;
372 let bot = (b >> 4) as isize;
373 let off = ((br.read_byte()? as isize) << 4) + bot - 4096;
374 validate!(len <= size);
375 size -= len;
376 self.lz_copy(idx, off, len)?;
377 idx += len;
378 } else if tag == 2 {
379 let b = br.read_byte()?;
380 if b == 0 { break; }
381 let len: usize = (if b != 0xFF { b as usize } else { br.read_u16le()? as usize }) + 1;
382 validate!(len <= size);
383 size -= len;
384 idx += len;
385 } else {
386 let b = br.read_byte()?;
387 let len = ((b & 0x3) as usize) + 2;
388 let off = -((b >> 2) as isize) - 1;
389 validate!(len <= size);
390 size -= len;
391 self.lz_copy(idx, off, len)?;
392 idx += len;
393 }
394 }
395 Ok(())
396 }
397
398 #[allow(clippy::identity_op)]
399 fn decode_method68(&mut self, br: &mut ByteReader,
400 skip: usize, use8: bool) -> DecoderResult<()> {
401 let mut bits = Bits32::new();
402
403 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
404 self.info.get_properties().get_video_info().unwrap().get_height();
405 let mut idx = PREAMBLE_SIZE;
406 validate!(size >= skip);
407 size -= skip;
408 idx += skip;
409 bits.fill(br)?;
410 while size > 0 {
411 let tag = bits.read_bits(br, 2)?;
412 if tag == 0 { //draw
413 let b = bits.read_bits(br, 1)?;
414 if b == 0 {
415 self.frame[idx] = br.read_byte()?;
416 size -= 1;
417 idx += 1;
418 } else {
419 let mut len: usize = 2;
420 let mut lbits = 0;
421 loop {
422 lbits += 1;
423 let val = bits.read_bits(br, lbits)?;
424 len += val as usize;
425 if val != ((1 << lbits) - 1) { break; }
426 validate!(lbits < 16);
427 }
428 validate!(len <= size);
429 for i in 0..len { self.frame[idx + i] = br.read_byte()?; }
430 size -= len;
431 idx += len;
432 }
433 } else if tag == 1 { //skip
434 let b = bits.read_bits(br, 1)?;
435 let len: usize;
436 if b == 0 {
437 len = (bits.read_bits(br, 4)? as usize) + 2;
438 } else {
439 let bb = br.read_byte()?;
440 if (bb & 0x80) == 0 {
441 len = (bb as usize) + 18;
442 } else {
443 let top = ((bb & 0x7F) as usize) << 8;
444 len = top + (br.read_byte()? as usize) + 146;
445 }
446 }
447 validate!(len <= size);
448 size -= len;
449 idx += len;
450 } else if tag == 2 {
451 let subtag = bits.read_bits(br, 2)? as usize;
452 if subtag != 3 {
453 let top = (bits.read_bits(br, 4)? as usize) << 8;
454 let offs = top + (br.read_byte()? as usize);
455 if (subtag != 0) || (offs <= 0xF80) {
456 let len = (subtag as usize) + 3;
457 self.lz_copy(idx, (offs as isize) - 4096, len)?;
458 idx += len;
459 } else {
460 if offs == 0xFFF { return Ok(()); }
461 let real_off = ((offs >> 4) & 0x7) + 1;
462 let len = ((offs & 0xF) + 2) * 2;
463 validate!(len <= size);
464 size -= len;
465 let c1 = self.frame[idx - real_off];
466 let c2 = self.frame[idx - real_off + 1];
467 for i in 0..len/2 {
468 self.frame[idx + i*2 + 0] = c1;
469 self.frame[idx + i*2 + 1] = c2;
470 }
471 idx += len;
472 }
473 } else {
474 let b = br.read_byte()?;
475 let off = ((b & 0x7F) as usize) + 1;
476 let len = if (b & 0x80) == 0 { 2 } else { 3 };
477 validate!(len <= size);
478 size -= len;
479 self.lz_copy(idx, -(off as isize), len)?;
480 idx += len;
481 }
482 } else {
483 let len: usize;
484 let off: isize;
485 if use8 {
486 let b = br.read_byte()?;
487 if (b & 0xC0) == 0xC0 {
488 len = ((b & 0x3F) as usize) + 8;
489 let q = bits.read_bits(br, 4)? as isize;
490 off = (q << 8) + (br.read_byte()? as isize) + 1;
491 } else {
492 let ofs1: isize;
493 if (b & 0x80) == 0 {
494 len = ((b >> 4) as usize) + 6;
495 ofs1 = (b & 0xF) as isize;
496 } else {
497 len = ((b & 0x3F) as usize) + 14;
498 ofs1 = bits.read_bits(br, 4)? as isize;
499 }
500 off = (ofs1 << 8) + (br.read_byte()? as isize) - 4096;
501 }
502 } else {
503 let b = br.read_byte()?;
504 if (b >> 4) == 0xF {
505 len = (br.read_byte()? as usize) + 21;
506 } else {
507 len = ((b >> 4) as usize) + 6;
508 }
509 let ofs1 = (b & 0xF) as isize;
510 off = (ofs1 << 8) + (br.read_byte()? as isize) - 4096;
511 }
512 validate!(len <= size);
513 size -= len;
514 self.lz_copy(idx, off, len)?;
515 idx += len;
516 }
517 }
518 Ok(())
519 }
520 }
521
522 const RGB555_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
523 comp_info: [
524 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 10, comp_offs: 0, next_elem: 2 }),
525 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 5, comp_offs: 1, next_elem: 2 }),
526 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 0, comp_offs: 2, next_elem: 2 }),
527 None, None],
528 elem_size: 2, be: false, alpha: false, palette: false };
529
530 impl NADecoder for GremlinVideoDecoder {
531 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
532 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
533 let w = vinfo.get_width();
534 let h = vinfo.get_height();
535 self.is_16bit = !vinfo.get_format().is_paletted();
536 let fmt = if !self.is_16bit { PAL8_FORMAT } else { RGB555_FORMAT };
537 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, fmt));
538 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
539
540 if !self.is_16bit {
541 self.frame.resize(PREAMBLE_SIZE + w * h, 0);
542 for i in 0..2 {
543 for j in 0..256 {
544 for k in 0..8 {
545 self.frame[i * 2048 + j * 8 + k] = j as u8;
546 }
547 }
548 }
549 let edata = info.get_extradata().unwrap();
550 validate!(edata.len() == 768);
551 for c in 0..256 {
552 for i in 0..3 {
553 let cc = edata[c * 3 + i];
554 self.pal[c * 3 + i] = (cc << 2) | (cc >> 4);
555 }
556 }
557 } else {
558 self.frame16.resize(PREAMBLE_SIZE + w * h, 0);
559 }
560 Ok(())
561 } else {
562 Err(DecoderError::InvalidData)
563 }
564 }
565 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
566 let src = pkt.get_buffer();
567 let mut mr = MemoryReader::new_read(&src);
568 let mut br = ByteReader::new(&mut mr);
569 let flags = br.read_u32le()?;
570 let w = self.info.get_properties().get_video_info().unwrap().get_width();
571 let h = self.info.get_properties().get_video_info().unwrap().get_height();
572
573 let cmethod = flags & 0xF;
574 let is_intra = (flags & 0x40) != 0;
575 let scale_v = (flags & 0x10) != 0;
576 let scale_h = (flags & 0x20) != 0;
577
578 if !self.is_16bit {
579 self.rescale(w, h, scale_v, scale_h);
580 } else {
581 self.rescale16(w, h, scale_v, scale_h);
582 }
583
584 if self.is_16bit && (cmethod != 2) && (cmethod != 3) {
585 return Err(DecoderError::NotImplemented);
586 }
587 if (cmethod == 0) || (cmethod == 1) {
588 validate!(!self.is_16bit);
589 for c in 0..256 {
590 for i in 0..3 {
591 let b = br.read_byte()?;
592 self.pal[c * 3 + i] = (b << 2) | (b >> 4);
593 }
594 }
595 if cmethod == 1 {
596 for i in PREAMBLE_SIZE..self.frame.len() { self.frame[i] = 0x00; }
597 }
598 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
599 frm.set_keyframe(false);
600 frm.set_frame_type(FrameType::Skip);
601 return Ok(frm.into_ref())
602 } else if cmethod == 3 {
603 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
604 frm.set_keyframe(false);
605 frm.set_frame_type(FrameType::Skip);
606 return Ok(frm.into_ref())
607 } else if cmethod == 2 {
608 if !self.is_16bit {
609 self.decode_method2(&mut br)?;
610 } else {
611 self.decode_method2_16bit(&mut br)?;
612 }
613 } else if cmethod == 5 {
614 self.decode_method5(&mut br, (flags >> 8) as usize)?;
615 } else if cmethod == 6 {
616 self.decode_method68(&mut br, (flags >> 8) as usize, false)?;
617 } else if cmethod == 8 {
618 self.decode_method68(&mut br, (flags >> 8) as usize, true)?;
619 } else {
620 return Err(DecoderError::NotImplemented);
621 }
622
623 let mut bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 0)?;
624
625 if !self.is_16bit {
626 self.output_frame(&mut bufinfo, w, h);
627 } else {
628 self.output_frame16(&mut bufinfo, w, h);
629 }
630
631 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
632 frm.set_keyframe(is_intra);
633 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
634 Ok(frm.into_ref())
635 }
636 fn flush(&mut self) {
637 }
638 }
639
640 impl NAOptionHandler for GremlinVideoDecoder {
641 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
642 fn set_options(&mut self, _options: &[NAOption]) { }
643 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
644 }
645
646 pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
647 Box::new(GremlinVideoDecoder::new())
648 }
649
650 struct GremlinAudioDecoder {
651 ainfo: NAAudioInfo,
652 chmap: NAChannelMap,
653 delta_tab: [i16; 256],
654 state0: i16,
655 state1: i16,
656 }
657
658 impl GremlinAudioDecoder {
659 fn new() -> Self {
660 let mut delta_tab: [i16; 256] = [0; 256];
661 let mut delta = 0;
662 let mut code = 64;
663 let mut step = 45;
664 for i in 0..127 {
665 delta += code >> 5;
666 code += step;
667 step += 2;
668 delta_tab[i * 2 + 1] = delta;
669 delta_tab[i * 2 + 2] = -delta;
670 }
671 delta_tab[255] = 32767;//delta + (code >> 5);
672 GremlinAudioDecoder {
673 ainfo: NAAudioInfo::new(0, 1, formats::SND_S16_FORMAT, 0),
674 chmap: NAChannelMap::new(),
675 delta_tab,
676 state0: 0,
677 state1: 0,
678 }
679 }
680 }
681
682 const CHMAP_MONO: [NAChannelType; 1] = [NAChannelType::C];
683 const CHMAP_STEREO: [NAChannelType; 2] = [NAChannelType::L, NAChannelType::R];
684
685 fn get_default_chmap(nch: u8) -> NAChannelMap {
686 let mut chmap = NAChannelMap::new();
687 match nch {
688 1 => chmap.add_channels(&CHMAP_MONO),
689 2 => chmap.add_channels(&CHMAP_STEREO),
690 _ => (),
691 }
692 chmap
693 }
694
695 impl NADecoder for GremlinAudioDecoder {
696 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
697 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
698 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), formats::SND_S16P_FORMAT, ainfo.get_block_len());
699 self.chmap = get_default_chmap(ainfo.get_channels());
700 if self.chmap.num_channels() == 0 { return Err(DecoderError::InvalidData); }
701 Ok(())
702 } else {
703 Err(DecoderError::InvalidData)
704 }
705 }
706 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
707 let info = pkt.get_stream().get_info();
708 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
709 let pktbuf = pkt.get_buffer();
710 let samples = pktbuf.len() / self.chmap.num_channels();
711 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
712 let mut adata = abuf.get_abuf_i16().unwrap();
713 let off1 = adata.get_offset(1);
714 let buf = adata.get_data_mut().unwrap();
715 if self.chmap.num_channels() == 2 {
716 for (i, e) in pktbuf.chunks(2).enumerate() {
717 self.state0 = self.state0.wrapping_add(self.delta_tab[e[0] as usize]);
718 buf[i] = self.state0;
719 self.state1 = self.state1.wrapping_add(self.delta_tab[e[1] as usize]);
720 buf[off1 + i] = self.state1;
721 }
722 } else {
723 for (i, e) in pktbuf.iter().enumerate() {
724 self.state0 += self.delta_tab[*e as usize];
725 buf[i] = self.state0;
726 }
727 }
728 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
729 frm.set_duration(Some(samples as u64));
730 frm.set_keyframe(false);
731 Ok(frm.into_ref())
732 } else {
733 Err(DecoderError::InvalidData)
734 }
735 }
736 fn flush(&mut self) {
737 }
738 }
739
740 impl NAOptionHandler for GremlinAudioDecoder {
741 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
742 fn set_options(&mut self, _options: &[NAOption]) { }
743 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
744 }
745
746 pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> {
747 Box::new(GremlinAudioDecoder::new())
748 }
749
750 #[cfg(test)]
751 mod test {
752 use nihav_core::codecs::RegisteredDecoders;
753 use nihav_core::demuxers::RegisteredDemuxers;
754 use nihav_codec_support::test::dec_video::*;
755 use crate::game_register_all_decoders;
756 use crate::game_register_all_demuxers;
757
758 #[test]
759 fn test_gdv_video() {
760 let mut dmx_reg = RegisteredDemuxers::new();
761 game_register_all_demuxers(&mut dmx_reg);
762 let mut dec_reg = RegisteredDecoders::new();
763 game_register_all_decoders(&mut dec_reg);
764
765 test_decoding("gdv", "gdv-video", "assets/Game/intro1.gdv", Some(10), &dmx_reg, &dec_reg,
766 ExpectedTestResult::MD5([0x7ea302bf, 0xc3e210cf, 0x6e341376, 0x9e976056]));
767 }
768 #[test]
769 fn test_gdv_video16() {
770 let mut dmx_reg = RegisteredDemuxers::new();
771 game_register_all_demuxers(&mut dmx_reg);
772 let mut dec_reg = RegisteredDecoders::new();
773 game_register_all_decoders(&mut dec_reg);
774
775 test_decoding("gdv", "gdv-video", "assets/Game/SHELI_S.GDV", Some(10), &dmx_reg, &dec_reg,
776 ExpectedTestResult::MD5([0x9acfdefd, 0x12687f8c, 0x9ef1cd56, 0x019240bb]));
777 }
778 #[test]
779 fn test_gdv_audio() {
780 let mut dmx_reg = RegisteredDemuxers::new();
781 game_register_all_demuxers(&mut dmx_reg);
782 let mut dec_reg = RegisteredDecoders::new();
783 game_register_all_decoders(&mut dec_reg);
784
785 test_decoding("gdv", "gdv-audio", "assets/Game/intro1.gdv", None, &dmx_reg, &dec_reg,
786 ExpectedTestResult::MD5([0xd41d8cd9, 0x8f00b204, 0xe9800998, 0xecf8427e]));
787 }
788 }