1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_codec_support::codecs::HAMShuffler;
7 (read; $dst:ident, $dpos:expr, $window:ident, $wpos:expr, $br:expr, $dst_size:expr) => {
8 validate!($dpos < $dst_size);
9 let b = $br.read_byte()?;
13 $wpos = ($wpos + 1) & 0xFFF;
15 (copy; $dst:ident, $dpos:expr, $window:ident, $wpos:expr, $off:expr, $dst_size:expr) => {
16 let b = $window[$off];
17 validate!($dpos < $dst_size);
21 $wpos = ($wpos + 1) & 0xFFF;
22 $off = ($off + 1) & 0xFFF;
25 fn lz_unpack(br: &mut ByteReader, dst: &mut [u8]) -> DecoderResult<()> {
26 let mut window: [u8; 0x1000] = [0x20; 0x1000];
28 let dst_size = br.read_u32le()? as usize;
29 validate!(dst_size <= dst.len());
32 if br.peek_u32le()? == 0x56781234 {
42 while br.left() > 0 && opos < dst_size {
43 let op = br.read_byte()?;
44 if (op == 0xFF) && (br.left() > 8) {
46 lz_op!(read; dst, opos, window, pos, br, dst_size);
50 if opos == dst_size { break; }
51 let is_literal = ((op >> i) & 1) != 0;
53 lz_op!(read; dst, opos, window, pos, br, dst_size);
55 let b0 = br.read_byte()? as usize;
56 let b1 = br.read_byte()? as usize;
57 let mut off = b0 | ((b1 & 0xF0) << 4);
58 let mut len = b1 & 0xF;
60 len = (br.read_byte()? as usize) + esc_len;
63 lz_op!(copy; dst, opos, window, pos, off, dst_size);
72 fn rle_unpack(br: &mut ByteReader, len: usize, dst: &mut [u8]) -> DecoderResult<()> {
73 let end = br.tell() + (len as u64);
76 dst[dpos] = br.read_byte()?;
79 while dpos < dst.len() && br.tell() < end {
80 let val = br.read_byte()?;
81 let len = ((val & 0x7F) as usize) * 2;
82 validate!(dpos + len <= dst.len());
83 if (val & 0x80) != 0 {
84 let dst = &mut dst[dpos..][..len];
87 let val = br.read_byte()?;
97 fn decode_frame_data(br: &mut ByteReader, dst: &mut [u8], mut dpos: usize, stride: usize, w: usize, h: usize, method: u8) -> DecoderResult<bool> {
103 let val = br.read_byte()?;
104 let len = ((val & 0x7F) as usize) + 1;
105 validate!(x + len <= w);
106 if (val & 0x80) != 0 {
107 let pix = &mut dst[dpos + x..][..len];
109 } // otherwise skip already existing data
118 let pix = &mut dst[dpos..][..w];
128 let val = br.read_byte()?;
129 let len = ((val & 0x7F) as usize) + 1;
130 validate!(x + len <= w);
131 if (val & 0x80) != 0 {
132 let pix = &mut dst[dpos + x..][..len];
133 if br.peek_byte()? == 0xFF {
135 rle_unpack(br, len, pix)?;
139 } // otherwise data is already there
146 _ => Err(DecoderError::InvalidData),
150 struct VMDVideoDecoder {
151 info: NACodecInfoRef,
159 impl VMDVideoDecoder {
162 info: NACodecInfoRef::default(),
167 hams: HAMShuffler::default(),
170 fn decode_frame(&mut self, br: &mut ByteReader, buf: &mut NAVideoBuffer<u8>) -> DecoderResult<bool> {
171 let paloff = buf.get_offset(1);
172 let stride = buf.get_stride(0);
173 let data = buf.get_data_mut().unwrap();
174 let dst = data.as_mut_slice();
176 let frame_x = br.read_u16le()? as usize;
177 let frame_y = br.read_u16le()? as usize;
178 let frame_l = br.read_u16le()? as usize;
179 let frame_d = br.read_u16le()? as usize;
181 let flags = br.read_byte()?;
182 let has_pal = (flags & 0x02) != 0;
183 validate!(frame_l >= frame_x && frame_d >= frame_y);
184 validate!(frame_l < self.width && frame_d < self.height);
188 for e in self.pal.iter_mut() {
189 let val = br.read_byte()?;
190 *e = (val << 2) | (val >> 4);
194 let dpal = &mut dst[paloff..][..768];
195 dpal.copy_from_slice(&self.pal[0..]);
197 if br.left() == 0 { return Ok(false); }
199 let w = frame_l + 1 - frame_x;
200 let h = frame_d + 1 - frame_y;
201 let dpos = frame_x + frame_y * stride;
203 let method = br.read_byte()?;
205 if (method & 0x80) != 0 {
206 validate!(!self.buf.is_empty());
207 lz_unpack(br, &mut self.buf)?;
208 let mut mr = MemoryReader::new_read(&self.buf);
209 let mut buf_br = ByteReader::new(&mut mr);
210 is_intra = decode_frame_data(&mut buf_br, dst, dpos, stride, w, h, method & 0x7F)?;
212 is_intra = decode_frame_data(br, dst, dpos, stride, w, h, method & 0x7F)?;
214 Ok(is_intra && frame_x == 0 && frame_y == 0 && w == self.width && h == self.height)
218 impl NADecoder for VMDVideoDecoder {
219 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
220 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
221 self.width = vinfo.get_width();
222 self.height = vinfo.get_height();
223 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, false, PAL8_FORMAT));
224 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
225 validate!(info.get_extradata().is_some());
227 if let Some(ref edata) = info.get_extradata() {
228 validate!(edata.len() == 0x330);
229 let unp_size = read_u32le(&edata[800..])? as usize;
230 validate!(unp_size < self.width * self.height * 3 + 64); // just for sanity
231 self.buf.resize(unp_size, 0);
233 let el = edata[28 + i];
234 self.pal[i] = (el << 2) | (el >> 4);
240 Err(DecoderError::InvalidData)
243 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
244 let src = pkt.get_buffer();
245 validate!(src.len() >= 10);
247 let mut mr = MemoryReader::new_read(&src);
248 let mut br = ByteReader::new(&mut mr);
251 let bufret = self.hams.clone_ref();
252 if let Some(bbuf) = bufret {
255 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?;
256 buf = bufinfo.get_vbuf().unwrap();
257 self.hams.add_frame(buf);
258 buf = self.hams.get_output_frame().unwrap();
261 let is_intra = self.decode_frame(&mut br, &mut buf)?;
263 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
264 frm.set_keyframe(is_intra);
265 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
268 fn flush(&mut self) {
274 pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
275 Box::new(VMDVideoDecoder::new())
278 struct VMDAudioDecoder {
286 const SOL_AUD_STEPS16: [i16; 128] = [
287 0x00, 0x08, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
288 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0,
289 0xF0, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160,
290 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 0x1D0, 0x1E0,
291 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
292 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270,
293 0x278, 0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0,
294 0x2B8, 0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0,
295 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330,
296 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
297 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0,
298 0x3B8, 0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0,
299 0x3F8, 0x400, 0x440, 0x480, 0x4C0, 0x500, 0x540, 0x580,
300 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 0x740, 0x780,
301 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
302 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
305 impl VMDAudioDecoder {
308 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
309 chmap: NAChannelMap::new(),
315 fn decode_16bit(&self, dst: &mut [i16], off1: usize, br: &mut ByteReader, nblocks: usize, mut mask: u32) -> DecoderResult<()> {
316 let channels = self.chmap.num_channels();
317 let mut off = [0, off1];
318 for _ in 0..nblocks {
320 for ch in 0..channels {
321 for i in 0..self.blk_align {
322 dst[off[ch] + i] = 0;
324 off[ch] += self.blk_align;
327 let mut pred: [i32; 2] = [0; 2];
328 for ch in 0..channels {
329 pred[ch] = i32::from(br.read_u16le()?);
330 dst[off[ch]] = pred[ch] as i16;
334 let flip_ch = if channels == 2 { 1 } else { 0 };
335 for _ in channels..self.blk_align*channels {
336 let b = br.read_byte()? as usize;
338 pred[ch] -= i32::from(SOL_AUD_STEPS16[b & 0x7F]);
340 pred[ch] += i32::from(SOL_AUD_STEPS16[b & 0x7F]);
342 //pred[ch] = pred[ch].max(-32768).min(32767);
343 dst[off[ch]] = pred[ch] as i16;
350 validate!(br.left() == 0);
355 impl NADecoder for VMDAudioDecoder {
356 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
357 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
359 if ainfo.get_format().get_bits() == 8 {
361 self.is16bit = false;
362 self.blk_size = ainfo.get_block_len();
363 self.blk_align = ainfo.get_block_len() / (ainfo.get_channels() as usize);
365 fmt = SND_S16P_FORMAT;
367 self.blk_size = (ainfo.get_block_len() + 1) * (ainfo.get_channels() as usize);
368 self.blk_align = ainfo.get_block_len();
370 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), fmt, ainfo.get_block_len());
371 self.chmap = NAChannelMap::from_str(if ainfo.get_channels() == 1 { "C" } else { "L,R" }).unwrap();
374 Err(DecoderError::InvalidData)
377 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
378 let info = pkt.get_stream().get_info();
379 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
380 let pktbuf = pkt.get_buffer();
381 validate!(pktbuf.len() >= 6);
382 let mut mr = MemoryReader::new_read(&pktbuf);
383 let mut br = ByteReader::new(&mut mr);
384 let blk_type = br.read_byte()?;
388 if blk_type == 2 { // initial
389 mask = br.read_u32le()?;
390 nblocks = (mask.count_ones() as usize) + (pktbuf.len() - 14) / self.blk_size;
391 } else if blk_type == 3 { // silence
398 let samples = nblocks * self.blk_align;
399 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
401 let mut adata = abuf.get_abuf_i16().unwrap();
402 let off1 = adata.get_offset(1);
403 let mut dst = adata.get_data_mut().unwrap();
404 self.decode_16bit(&mut dst, off1, &mut br, nblocks, mask)?;
406 let mut adata = abuf.get_abuf_u8().unwrap();
407 let dst = adata.get_data_mut().unwrap();
410 let channels = self.chmap.num_channels();
411 for _ in 0..nblocks {
413 for i in 0..self.blk_align * channels {
416 } else if channels == 1 {
417 for i in 0..self.blk_size {
418 dst[doff + i] = br.read_byte()?;
421 for i in 0..self.blk_size {
422 let val = br.read_byte()?;
424 dst[doff + i] = 127 - val;
430 doff += self.blk_align * channels;
435 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
436 frm.set_duration(Some(samples as u64));
437 frm.set_keyframe(true);
440 Err(DecoderError::InvalidData)
443 fn flush(&mut self) {
447 pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> {
448 Box::new(VMDAudioDecoder::new())
453 use nihav_core::codecs::RegisteredDecoders;
454 use nihav_core::demuxers::RegisteredDemuxers;
455 use nihav_codec_support::test::dec_video::*;
456 use crate::game_register_all_codecs;
457 use crate::game_register_all_demuxers;
459 fn test_vmd_video() {
460 let mut dmx_reg = RegisteredDemuxers::new();
461 game_register_all_demuxers(&mut dmx_reg);
462 let mut dec_reg = RegisteredDecoders::new();
463 game_register_all_codecs(&mut dec_reg);
465 // let file = "assets/Game/1491.VMD";
466 let file = "assets/Game/128.vmd";
467 test_file_decoding("vmd", file, Some(10), true, false, None/*Some("vmd")*/, &dmx_reg, &dec_reg);
470 fn test_vmd_audio() {
471 let mut dmx_reg = RegisteredDemuxers::new();
472 game_register_all_demuxers(&mut dmx_reg);
473 let mut dec_reg = RegisteredDecoders::new();
474 game_register_all_codecs(&mut dec_reg);
476 // let file = "assets/Game/1491.VMD";
477 let file = "assets/Game/128.vmd";
478 // let file = "assets/Game/1000.VMD";
479 // let file = "assets/Game/235.VMD";
480 test_decode_audio("vmd", file, None, None/*Some("vmd")*/, &dmx_reg, &dec_reg);