1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
6 (read; $dst:ident, $dpos:expr, $window:ident, $wpos:expr, $br:expr, $dst_size:expr) => {
7 validate!($dpos < $dst_size);
8 let b = $br.read_byte()?;
12 $wpos = ($wpos + 1) & 0xFFF;
14 (copy; $dst:ident, $dpos:expr, $window:ident, $wpos:expr, $off:expr, $dst_size:expr) => {
15 let b = $window[$off];
16 validate!($dpos < $dst_size);
20 $wpos = ($wpos + 1) & 0xFFF;
21 $off = ($off + 1) & 0xFFF;
24 fn lz_unpack(br: &mut ByteReader, dst: &mut [u8]) -> DecoderResult<()> {
25 let mut window: [u8; 0x1000] = [0x20; 0x1000];
27 let dst_size = br.read_u32le()? as usize;
28 validate!(dst_size <= dst.len());
31 if br.peek_u32le()? == 0x56781234 {
41 while br.left() > 0 && opos < dst_size {
42 let op = br.read_byte()?;
43 if (op == 0xFF) && (br.left() > 8) {
45 lz_op!(read; dst, opos, window, pos, br, dst_size);
49 if opos == dst_size { break; }
50 let is_literal = ((op >> i) & 1) != 0;
52 lz_op!(read; dst, opos, window, pos, br, dst_size);
54 let b0 = br.read_byte()? as usize;
55 let b1 = br.read_byte()? as usize;
56 let mut off = b0 | ((b1 & 0xF0) << 4);
57 let mut len = b1 & 0xF;
59 len = (br.read_byte()? as usize) + esc_len;
62 lz_op!(copy; dst, opos, window, pos, off, dst_size);
71 fn rle_unpack(br: &mut ByteReader, len: usize, dst: &mut [u8]) -> DecoderResult<()> {
72 let end = br.tell() + (len as u64);
75 dst[dpos] = br.read_byte()?;
78 while dpos < dst.len() && br.tell() < end {
79 let val = br.read_byte()?;
80 let len = ((val & 0x7F) as usize) * 2;
81 validate!(dpos + len <= dst.len());
82 if (val & 0x80) != 0 {
83 let dst = &mut dst[dpos..][..len];
86 let val = br.read_byte()?;
96 fn decode_frame_data(br: &mut ByteReader, dst: &mut [u8], mut dpos: usize, stride: usize, w: usize, h: usize, method: u8) -> DecoderResult<bool> {
102 let val = br.read_byte()?;
103 let len = ((val & 0x7F) as usize) + 1;
104 validate!(x + len <= w);
105 if (val & 0x80) != 0 {
106 let pix = &mut dst[dpos + x..][..len];
108 } // otherwise skip already existing data
117 let pix = &mut dst[dpos..][..w];
127 let val = br.read_byte()?;
128 let len = ((val & 0x7F) as usize) + 1;
129 validate!(x + len <= w);
130 if (val & 0x80) != 0 {
131 let pix = &mut dst[dpos + x..][..len];
132 if br.peek_byte()? == 0xFF {
134 rle_unpack(br, len, pix)?;
138 } // otherwise data is already there
145 _ => Err(DecoderError::InvalidData),
149 struct VMDVideoDecoder {
150 info: NACodecInfoRef,
158 impl VMDVideoDecoder {
161 info: NACodecInfoRef::default(),
166 hams: HAMShuffler::default(),
169 fn decode_frame(&mut self, br: &mut ByteReader, buf: &mut NAVideoBuffer<u8>) -> DecoderResult<bool> {
170 let paloff = buf.get_offset(1);
171 let stride = buf.get_stride(0);
172 let data = buf.get_data_mut().unwrap();
173 let dst = data.as_mut_slice();
175 let frame_x = br.read_u16le()? as usize;
176 let frame_y = br.read_u16le()? as usize;
177 let frame_l = br.read_u16le()? as usize;
178 let frame_d = br.read_u16le()? as usize;
180 let flags = br.read_byte()?;
181 let has_pal = (flags & 0x02) != 0;
182 validate!(frame_l >= frame_x && frame_d >= frame_y);
183 validate!(frame_l < self.width && frame_d < self.height);
187 for e in self.pal.iter_mut() {
188 let val = br.read_byte()?;
189 *e = (val << 2) | (val >> 4);
193 let dpal = &mut dst[paloff..][..768];
194 dpal.copy_from_slice(&self.pal[0..]);
196 if br.left() == 0 { return Ok(false); }
198 let w = frame_l + 1 - frame_x;
199 let h = frame_d + 1 - frame_y;
200 let dpos = frame_x + frame_y * stride;
202 let method = br.read_byte()?;
204 if (method & 0x80) != 0 {
205 validate!(!self.buf.is_empty());
206 lz_unpack(br, &mut self.buf)?;
207 let mut mr = MemoryReader::new_read(&self.buf);
208 let mut buf_br = ByteReader::new(&mut mr);
209 is_intra = decode_frame_data(&mut buf_br, dst, dpos, stride, w, h, method & 0x7F)?;
211 is_intra = decode_frame_data(br, dst, dpos, stride, w, h, method & 0x7F)?;
213 Ok(is_intra && frame_x == 0 && frame_y == 0 && w == self.width && h == self.height)
217 impl NADecoder for VMDVideoDecoder {
218 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
219 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
220 self.width = vinfo.get_width();
221 self.height = vinfo.get_height();
222 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, false, PAL8_FORMAT));
223 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
224 validate!(info.get_extradata().is_some());
226 if let Some(ref edata) = info.get_extradata() {
227 validate!(edata.len() == 0x330);
228 let unp_size = read_u32le(&edata[800..])? as usize;
229 validate!(unp_size < self.width * self.height * 3 + 64); // just for sanity
230 self.buf.resize(unp_size, 0);
232 let el = edata[28 + i];
233 self.pal[i] = (el << 2) | (el >> 4);
239 Err(DecoderError::InvalidData)
242 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
243 let src = pkt.get_buffer();
244 validate!(src.len() >= 10);
246 let mut mr = MemoryReader::new_read(&src);
247 let mut br = ByteReader::new(&mut mr);
250 let bufret = self.hams.clone_ref();
251 if let Some(bbuf) = bufret {
254 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?;
255 buf = bufinfo.get_vbuf().unwrap();
256 self.hams.add_frame(buf);
257 buf = self.hams.get_output_frame().unwrap();
260 let is_intra = self.decode_frame(&mut br, &mut buf)?;
262 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
263 frm.set_keyframe(is_intra);
264 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
267 fn flush(&mut self) {
273 pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
274 Box::new(VMDVideoDecoder::new())
277 struct VMDAudioDecoder {
285 const SOL_AUD_STEPS16: [i16; 128] = [
286 0x00, 0x08, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
287 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0,
288 0xF0, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160,
289 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 0x1D0, 0x1E0,
290 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
291 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270,
292 0x278, 0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0,
293 0x2B8, 0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0,
294 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330,
295 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
296 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0,
297 0x3B8, 0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0,
298 0x3F8, 0x400, 0x440, 0x480, 0x4C0, 0x500, 0x540, 0x580,
299 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 0x740, 0x780,
300 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
301 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
304 impl VMDAudioDecoder {
307 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
308 chmap: NAChannelMap::new(),
314 fn decode_16bit(&self, dst: &mut [i16], off1: usize, br: &mut ByteReader, nblocks: usize, mut mask: u32) -> DecoderResult<()> {
315 let channels = self.chmap.num_channels();
316 let mut off = [0, off1];
317 for _ in 0..nblocks {
319 for ch in 0..channels {
320 for i in 0..self.blk_align {
321 dst[off[ch] + i] = 0;
323 off[ch] += self.blk_align;
326 let mut pred: [i32; 2] = [0; 2];
327 for ch in 0..channels {
328 pred[ch] = i32::from(br.read_u16le()?);
329 dst[off[ch]] = pred[ch] as i16;
333 let flip_ch = if channels == 2 { 1 } else { 0 };
334 for _ in channels..self.blk_align*channels {
335 let b = br.read_byte()? as usize;
337 pred[ch] -= i32::from(SOL_AUD_STEPS16[b & 0x7F]);
339 pred[ch] += i32::from(SOL_AUD_STEPS16[b & 0x7F]);
341 //pred[ch] = pred[ch].max(-32768).min(32767);
342 dst[off[ch]] = pred[ch] as i16;
349 validate!(br.left() == 0);
354 impl NADecoder for VMDAudioDecoder {
355 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
356 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
358 if ainfo.get_format().get_bits() == 8 {
360 self.is16bit = false;
361 self.blk_size = ainfo.get_block_len();
362 self.blk_align = ainfo.get_block_len() / (ainfo.get_channels() as usize);
364 fmt = SND_S16P_FORMAT;
366 self.blk_size = (ainfo.get_block_len() + 1) * (ainfo.get_channels() as usize);
367 self.blk_align = ainfo.get_block_len();
369 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), fmt, ainfo.get_block_len());
370 self.chmap = NAChannelMap::from_str(if ainfo.get_channels() == 1 { "C" } else { "L,R" }).unwrap();
373 Err(DecoderError::InvalidData)
376 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
377 let info = pkt.get_stream().get_info();
378 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
379 let pktbuf = pkt.get_buffer();
380 validate!(pktbuf.len() >= 6);
381 let mut mr = MemoryReader::new_read(&pktbuf);
382 let mut br = ByteReader::new(&mut mr);
383 let blk_type = br.read_byte()?;
387 if blk_type == 2 { // initial
388 mask = br.read_u32le()?;
389 nblocks = (mask.count_ones() as usize) + (pktbuf.len() - 14) / self.blk_size;
390 } else if blk_type == 3 { // silence
397 let samples = nblocks * self.blk_align;
398 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
400 let mut adata = abuf.get_abuf_i16().unwrap();
401 let off1 = adata.get_offset(1);
402 let mut dst = adata.get_data_mut().unwrap();
403 self.decode_16bit(&mut dst, off1, &mut br, nblocks, mask)?;
405 let mut adata = abuf.get_abuf_u8().unwrap();
406 let dst = adata.get_data_mut().unwrap();
409 let channels = self.chmap.num_channels();
410 for _ in 0..nblocks {
412 for i in 0..self.blk_align * channels {
415 } else if channels == 1 {
416 for i in 0..self.blk_size {
417 dst[doff + i] = br.read_byte()?;
420 for i in 0..self.blk_size {
421 let val = br.read_byte()?;
423 dst[doff + i] = 127 - val;
429 doff += self.blk_align * channels;
434 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
435 frm.set_duration(Some(samples as u64));
436 frm.set_keyframe(true);
439 Err(DecoderError::InvalidData)
442 fn flush(&mut self) {
446 pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> {
447 Box::new(VMDAudioDecoder::new())
452 use nihav_core::codecs::RegisteredDecoders;
453 use nihav_core::demuxers::RegisteredDemuxers;
454 use nihav_core::test::dec_video::*;
455 use crate::game_register_all_codecs;
456 use crate::game_register_all_demuxers;
458 fn test_vmd_video() {
459 let mut dmx_reg = RegisteredDemuxers::new();
460 game_register_all_demuxers(&mut dmx_reg);
461 let mut dec_reg = RegisteredDecoders::new();
462 game_register_all_codecs(&mut dec_reg);
464 // let file = "assets/Game/1491.VMD";
465 let file = "assets/Game/128.vmd";
466 test_file_decoding("vmd", file, Some(10), true, false, None/*Some("vmd")*/, &dmx_reg, &dec_reg);
469 fn test_vmd_audio() {
470 let mut dmx_reg = RegisteredDemuxers::new();
471 game_register_all_demuxers(&mut dmx_reg);
472 let mut dec_reg = RegisteredDecoders::new();
473 game_register_all_codecs(&mut dec_reg);
475 // let file = "assets/Game/1491.VMD";
476 let file = "assets/Game/128.vmd";
477 // let file = "assets/Game/1000.VMD";
478 // let file = "assets/Game/235.VMD";
479 test_decode_audio("vmd", file, None, None/*Some("vmd")*/, &dmx_reg, &dec_reg);