]> git.nihav.org Git - nihav.git/blob - gremlinvideo.rs
65d5ed121bd02bba750db1a1fd0d1513c16a0dc5
[nihav.git] / gremlinvideo.rs
1 use std::rc::Rc;
2 use std::cell::RefCell;
3 use nihav_core::frame::*;
4 use nihav_core::formats;
5 use nihav_core::formats::{NAChannelType, NAChannelMap};
6 use nihav_core::codecs::*;
7 use nihav_core::io::byteio::*;
8
9 struct GremlinVideoDecoder {
10 info: Rc<NACodecInfo>,
11 pal: [u8; 768],
12 frame: Vec<u8>,
13 scale_v: bool,
14 scale_h: 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 |= (br.read_u16le()? as u32) << self.fill;
56 self.fill += 16;
57 }
58 Ok(res)
59 }
60 }
61
62 impl GremlinVideoDecoder {
63 fn new() -> Self {
64 let dummy_info = Rc::new(DUMMY_CODEC_INFO);
65 GremlinVideoDecoder {
66 info: dummy_info, pal: [0; 768], frame: Vec::new(),
67 scale_v: false, scale_h: 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 rescale(&mut self, w: usize, h: usize, scale_v: bool, scale_h: bool) {
88 if (self.scale_v == scale_v) && (self.scale_h == scale_h) { return; }
89
90 if self.scale_h && self.scale_v {
91 for j in 0..h {
92 let y = h - j - 1;
93 for i in 0..w {
94 let x = w - i - 1;
95 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x/2 + (y/2) * (w/2)];
96 }
97 }
98 } else if self.scale_h {
99 for j in 0..h {
100 let y = h - j - 1;
101 for x in 0..w {
102 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x + (y/2) * w];
103 }
104 }
105 } else if self.scale_v {
106 for j in 0..h {
107 let y = h - j - 1;
108 for i in 0..w {
109 let x = w - i - 1;
110 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x/2 + y * (w/2)];
111 }
112 }
113 }
114
115 if scale_h && scale_v {
116 for y in 0..h/2 {
117 for x in 0..w/2 {
118 self.frame[PREAMBLE_SIZE + x + y * (w/2)] = self.frame[PREAMBLE_SIZE + x*2 + y*2 * w];
119 }
120 }
121 } else if scale_h {
122 for y in 0..h/2 {
123 for x in 0..w {
124 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x + y*2 * w];
125 }
126 }
127 } else if scale_v {
128 for y in 0..h {
129 for x in 0..w/2 {
130 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x*2 + y * w];
131 }
132 }
133 }
134
135 self.scale_v = scale_v;
136 self.scale_h = scale_h;
137 }
138
139 fn output_frame(&mut self, bufinfo: &mut NABufferType, w: usize, h: usize) {
140 let bufo = bufinfo.get_vbuf();
141 let mut buf = bufo.unwrap();
142 let paloff = buf.get_offset(1);
143 let stride = buf.get_stride(0);
144 let mut data = buf.get_data_mut();
145 let dst = data.as_mut_slice();
146 let mut sidx = PREAMBLE_SIZE;
147 let mut didx = 0;
148
149 for i in 0..768 { dst[paloff + i] = self.pal[i]; }
150 if !self.scale_v && !self.scale_h {
151 for _ in 0..h {
152 for x in 0..w { dst[didx + x] = self.frame[sidx + x]; }
153 sidx += w;
154 didx += stride;
155 }
156 } else {
157 for y in 0..h {
158 if !self.scale_v {
159 for x in 0..w { dst[didx + x] = self.frame[sidx + x]; }
160 } else {
161 for x in 0..w { dst[didx + x] = self.frame[sidx + x/2]; }
162 }
163 if !self.scale_h || ((y & 1) == 1) {
164 sidx += if !self.scale_v { w } else { w/2 };
165 }
166 didx += stride;
167 }
168 }
169 }
170
171 fn decode_method2(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
172 let mut bits = Bits8::new();
173
174 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
175 self.info.get_properties().get_video_info().unwrap().get_height();
176 let mut idx = PREAMBLE_SIZE;
177 if self.frame[8] != 0 {
178 for c in 0..256 {
179 for i in 0..16 { self.frame[c * 16 + i] = c as u8; }
180 }
181 }
182 while size > 0 {
183 let tag = bits.read_2bits(br)?;
184 if tag == 0 {
185 self.frame[idx] = br.read_byte()?;
186 size -= 1;
187 idx += 1;
188 } else if tag == 1 {
189 let b = br.read_byte()?;
190 let len = ((b & 0xF) as usize) + 3;
191 let bot = (b >> 4) as isize;
192 let off = ((br.read_byte()? as isize) << 4) + bot - 4096;
193 validate!(len <= size);
194 size -= len;
195 self.lz_copy(idx, off, len)?;
196 idx += len;
197 } else if tag == 2 {
198 let len = (br.read_byte()? as usize) + 2;
199 validate!(len <= size);
200 size -= len;
201 idx += len;
202 } else {
203 break;
204 }
205 }
206 Ok(())
207 }
208
209 fn decode_method5(&mut self, br: &mut ByteReader, skip: usize) -> DecoderResult<()> {
210 let mut bits = Bits8::new();
211
212 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
213 self.info.get_properties().get_video_info().unwrap().get_height();
214 let mut idx = PREAMBLE_SIZE;
215 validate!(size >= skip);
216 size -= skip;
217 idx += skip;
218 while size > 0 {
219 let tag = bits.read_2bits(br)?;
220 if tag == 0 {
221 self.frame[idx] = br.read_byte()?;
222 size -= 1;
223 idx += 1;
224 } else if tag == 1 {
225 let b = br.read_byte()?;
226 let len = ((b & 0xF) as usize) + 3;
227 let bot = (b >> 4) as isize;
228 let off = ((br.read_byte()? as isize) << 4) + bot - 4096;
229 validate!(len <= size);
230 size -= len;
231 self.lz_copy(idx, off, len)?;
232 idx += len;
233 } else if tag == 2 {
234 let b = br.read_byte()?;
235 if b == 0 { break; }
236 let len: usize = (if b != 0xFF { b as usize } else { br.read_u16le()? as usize }) + 1;
237 validate!(len <= size);
238 size -= len;
239 idx += len;
240 } else {
241 let b = br.read_byte()?;
242 let len = ((b & 0x3) as usize) + 2;
243 let off = -((b >> 2) as isize) - 1;
244 validate!(len <= size);
245 size -= len;
246 self.lz_copy(idx, off, len)?;
247 idx += len;
248 }
249 }
250 Ok(())
251 }
252
253 fn decode_method68(&mut self, br: &mut ByteReader,
254 skip: usize, use8: bool) -> DecoderResult<()> {
255 let mut bits = Bits32::new();
256
257 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
258 self.info.get_properties().get_video_info().unwrap().get_height();
259 let mut idx = PREAMBLE_SIZE;
260 validate!(size >= skip);
261 size -= skip;
262 idx += skip;
263 bits.fill(br)?;
264 while size > 0 {
265 let tag = bits.read_bits(br, 2)?;
266 if tag == 0 { //draw
267 let b = bits.read_bits(br, 1)?;
268 if b == 0 {
269 self.frame[idx] = br.read_byte()?;
270 size -= 1;
271 idx += 1;
272 } else {
273 let mut len: usize = 2;
274 let mut lbits = 0;
275 loop {
276 lbits += 1;
277 let val = bits.read_bits(br, lbits)?;
278 len += val as usize;
279 if val != ((1 << lbits) - 1) { break; }
280 validate!(lbits < 16);
281 }
282 validate!(len <= size);
283 for i in 0..len { self.frame[idx + i] = br.read_byte()?; }
284 size -= len;
285 idx += len;
286 }
287 } else if tag == 1 { //skip
288 let b = bits.read_bits(br, 1)?;
289 let len: usize;
290 if b == 0 {
291 len = (bits.read_bits(br, 4)? as usize) + 2;
292 } else {
293 let bb = br.read_byte()?;
294 if (bb & 0x80) == 0 {
295 len = (bb as usize) + 18;
296 } else {
297 let top = ((bb & 0x7F) as usize) << 8;
298 len = top + (br.read_byte()? as usize) + 146;
299 }
300 }
301 validate!(len <= size);
302 size -= len;
303 idx += len;
304 } else if tag == 2 {
305 let subtag = bits.read_bits(br, 2)? as usize;
306 if subtag != 3 {
307 let top = (bits.read_bits(br, 4)? as usize) << 8;
308 let offs = top + (br.read_byte()? as usize);
309 if (subtag != 0) || (offs <= 0xF80) {
310 let len = (subtag as usize) + 3;
311 self.lz_copy(idx, (offs as isize) - 4096, len)?;
312 idx += len;
313 } else {
314 if offs == 0xFFF { return Ok(()); }
315 let real_off = ((offs >> 4) & 0x7) + 1;
316 let len = ((offs & 0xF) + 2) * 2;
317 validate!(len <= size);
318 size -= len;
319 let c1 = self.frame[idx - real_off];
320 let c2 = self.frame[idx - real_off + 1];
321 for i in 0..len/2 {
322 self.frame[idx + i*2 + 0] = c1;
323 self.frame[idx + i*2 + 1] = c2;
324 }
325 idx += len;
326 }
327 } else {
328 let b = br.read_byte()?;
329 let off = ((b & 0x7F) as usize) + 1;
330 let len = if (b & 0x80) == 0 { 2 } else { 3 };
331 validate!(len <= size);
332 size -= len;
333 self.lz_copy(idx, -(off as isize), len)?;
334 idx += len;
335 }
336 } else {
337 let len: usize;
338 let off: isize;
339 if use8 {
340 let b = br.read_byte()?;
341 if (b & 0xC0) == 0xC0 {
342 len = ((b & 0x3F) as usize) + 8;
343 let q = bits.read_bits(br, 4)? as isize;
344 off = (q << 8) + (br.read_byte()? as isize) + 1;
345 } else {
346 let ofs1: isize;
347 if (b & 0x80) == 0 {
348 len = ((b >> 4) as usize) + 6;
349 ofs1 = (b & 0xF) as isize;
350 } else {
351 len = ((b & 0x3F) as usize) + 14;
352 ofs1 = bits.read_bits(br, 4)? as isize;
353 }
354 off = (ofs1 << 8) + (br.read_byte()? as isize) - 4096;
355 }
356 } else {
357 let b = br.read_byte()?;
358 if (b >> 4) == 0xF {
359 len = (br.read_byte()? as usize) + 21;
360 } else {
361 len = ((b >> 4) as usize) + 6;
362 }
363 let ofs1 = (b & 0xF) as isize;
364 off = (ofs1 << 8) + (br.read_byte()? as isize) - 4096;
365 }
366 validate!(len <= size);
367 size -= len;
368 self.lz_copy(idx, off, len)?;
369 idx += len;
370 }
371 }
372 Ok(())
373 }
374 }
375
376 impl NADecoder for GremlinVideoDecoder {
377 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
378 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
379 let w = vinfo.get_width();
380 let h = vinfo.get_height();
381 if !vinfo.get_format().is_paletted() { return Err(DecoderError::NotImplemented); }
382 let fmt = formats::PAL8_FORMAT;
383 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, fmt));
384 self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
385
386 self.frame.resize(PREAMBLE_SIZE + w * h, 0);
387 for i in 0..2 {
388 for j in 0..256 {
389 for k in 0..8 {
390 self.frame[i * 2048 + j * 8 + k] = j as u8;
391 }
392 }
393 }
394 let edata = info.get_extradata().unwrap();
395 validate!(edata.len() == 768);
396 for c in 0..256 {
397 for i in 0..3 {
398 let cc = edata[c * 3 + i];
399 self.pal[c * 3 + (2 - i)] = (cc << 2) | (cc >> 4);
400 }
401 }
402 Ok(())
403 } else {
404 Err(DecoderError::InvalidData)
405 }
406 }
407 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
408 let src = pkt.get_buffer();
409 let mut mr = MemoryReader::new_read(&src);
410 let mut br = ByteReader::new(&mut mr);
411 let flags = br.read_u32le()?;
412 let w = self.info.get_properties().get_video_info().unwrap().get_width();
413 let h = self.info.get_properties().get_video_info().unwrap().get_height();
414
415 let cmethod = flags & 0xF;
416 let is_intra = (flags & 0x40) != 0;
417 let scale_v = (flags & 0x10) != 0;
418 let scale_h = (flags & 0x20) != 0;
419
420 self.rescale(w, h, scale_v, scale_h);
421
422 if (cmethod == 0) || (cmethod == 1) {
423 for c in 0..256 {
424 for i in 0..3 {
425 let b = br.read_byte()?;
426 self.pal[c * 3 + (2 - i)] = (b << 2) | (b >> 4);
427 }
428 }
429 if cmethod == 1 {
430 for i in PREAMBLE_SIZE..self.frame.len() { self.frame[i] = 0x00; }
431 }
432 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
433 frm.set_keyframe(false);
434 frm.set_frame_type(FrameType::Skip);
435 return Ok(Rc::new(RefCell::new(frm)))
436 } else if cmethod == 3 {
437 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
438 frm.set_keyframe(false);
439 frm.set_frame_type(FrameType::Skip);
440 return Ok(Rc::new(RefCell::new(frm)))
441 } else if cmethod == 2 {
442 self.decode_method2(&mut br)?;
443 } else if cmethod == 5 {
444 self.decode_method5(&mut br, (flags >> 8) as usize)?;
445 } else if cmethod == 6 {
446 self.decode_method68(&mut br, (flags >> 8) as usize, false)?;
447 } else if cmethod == 8 {
448 self.decode_method68(&mut br, (flags >> 8) as usize, true)?;
449 } else {
450 return Err(DecoderError::NotImplemented);
451 }
452
453 let bufret = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 0);
454 if let Err(_) = bufret { return Err(DecoderError::InvalidData); }
455 let mut bufinfo = bufret.unwrap();
456
457 self.output_frame(&mut bufinfo, w, h);
458
459 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
460 frm.set_keyframe(is_intra);
461 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
462 Ok(Rc::new(RefCell::new(frm)))
463 }
464 }
465
466 pub fn get_decoder_video() -> Box<NADecoder> {
467 Box::new(GremlinVideoDecoder::new())
468 }
469
470 struct GremlinAudioDecoder {
471 ainfo: NAAudioInfo,
472 chmap: NAChannelMap,
473 delta_tab: [i16; 256],
474 state0: i16,
475 state1: i16,
476 }
477
478 impl GremlinAudioDecoder {
479 fn new() -> Self {
480 let mut delta_tab: [i16; 256] = [0; 256];
481 let mut delta = 0;
482 let mut code = 64;
483 let mut step = 45;
484 for i in 0..127 {
485 delta += code >> 5;
486 code += step;
487 step += 2;
488 delta_tab[i * 2 + 1] = delta;
489 delta_tab[i * 2 + 2] = -delta;
490 }
491 delta_tab[255] = 32767;//delta + (code >> 5);
492 GremlinAudioDecoder {
493 ainfo: NAAudioInfo::new(0, 1, formats::SND_S16_FORMAT, 0),
494 chmap: NAChannelMap::new(),
495 delta_tab,
496 state0: 0,
497 state1: 0,
498 }
499 }
500 }
501
502 const CHMAP_MONO: [NAChannelType; 1] = [NAChannelType::C];
503 const CHMAP_STEREO: [NAChannelType; 2] = [NAChannelType::L, NAChannelType::R];
504
505 fn get_default_chmap(nch: u8) -> NAChannelMap {
506 let mut chmap = NAChannelMap::new();
507 match nch {
508 1 => chmap.add_channels(&CHMAP_MONO),
509 2 => chmap.add_channels(&CHMAP_STEREO),
510 _ => (),
511 }
512 chmap
513 }
514
515 impl NADecoder for GremlinAudioDecoder {
516 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
517 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
518 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), formats::SND_S16P_FORMAT, ainfo.get_block_len());
519 self.chmap = get_default_chmap(ainfo.get_channels());
520 if self.chmap.num_channels() == 0 { return Err(DecoderError::InvalidData); }
521 Ok(())
522 } else {
523 Err(DecoderError::InvalidData)
524 }
525 }
526 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
527 let info = pkt.get_stream().get_info();
528 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
529 let pktbuf = pkt.get_buffer();
530 let samples = pktbuf.len() / self.chmap.num_channels();
531 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
532 let mut adata = abuf.get_abuf_i16().unwrap();
533 let off1 = adata.get_offset(1);
534 let mut buf = adata.get_data_mut();
535 if self.chmap.num_channels() == 2 {
536 for (i, e) in pktbuf.chunks(2).enumerate() {
537 self.state0 = self.state0.wrapping_add(self.delta_tab[e[0] as usize]);
538 buf[i] = self.state0;
539 self.state1 = self.state1.wrapping_add(self.delta_tab[e[1] as usize]);
540 buf[off1 + i] = self.state1;
541 }
542 } else {
543 for (i, e) in pktbuf.iter().enumerate() {
544 self.state0 += self.delta_tab[*e as usize];
545 buf[i] = self.state0;
546 }
547 }
548 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
549 frm.set_duration(Some(samples as u64));
550 frm.set_keyframe(false);
551 Ok(Rc::new(RefCell::new(frm)))
552 } else {
553 Err(DecoderError::InvalidData)
554 }
555 }
556 }
557
558 pub fn get_decoder_audio() -> Box<NADecoder> {
559 Box::new(GremlinAudioDecoder::new())
560 }
561
562 #[cfg(test)]
563 mod test {
564 use nihav_core::codecs::RegisteredDecoders;
565 use nihav_core::demuxers::RegisteredDemuxers;
566 use nihav_core::test::dec_video::test_file_decoding;
567 use crate::codecs::game_register_all_codecs;
568 use crate::demuxers::game_register_all_demuxers;
569 #[test]
570 fn test_gdv() {
571 let mut dmx_reg = RegisteredDemuxers::new();
572 game_register_all_demuxers(&mut dmx_reg);
573 let mut dec_reg = RegisteredDecoders::new();
574 game_register_all_codecs(&mut dec_reg);
575
576 test_file_decoding("gdv", "assets/Game/intro1.gdv", Some(10), true, false, None, &dmx_reg, &dec_reg);
577 }
578 }