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 if (frame_x == 0xFFFF) && (frame_y == 0xFFFF) && (frame_l == 0xFFFF) && (frame_d == 0xFFFF) {
186 validate!(frame_l >= frame_x && frame_d >= frame_y);
187 validate!(frame_l < self.width && frame_d < self.height);
191 for e in self.pal.iter_mut() {
192 let val = br.read_byte()?;
193 *e = (val << 2) | (val >> 4);
197 let dpal = &mut dst[paloff..][..768];
198 dpal.copy_from_slice(&self.pal[0..]);
200 if br.left() == 0 { return Ok(false); }
202 let w = frame_l + 1 - frame_x;
203 let h = frame_d + 1 - frame_y;
204 let dpos = frame_x + frame_y * stride;
206 let method = br.read_byte()?;
208 if (method & 0x80) != 0 {
209 validate!(!self.buf.is_empty());
210 lz_unpack(br, &mut self.buf)?;
211 let mut mr = MemoryReader::new_read(&self.buf);
212 let mut buf_br = ByteReader::new(&mut mr);
213 is_intra = decode_frame_data(&mut buf_br, dst, dpos, stride, w, h, method & 0x7F)?;
215 is_intra = decode_frame_data(br, dst, dpos, stride, w, h, method & 0x7F)?;
217 Ok(is_intra && frame_x == 0 && frame_y == 0 && w == self.width && h == self.height)
221 impl NADecoder for VMDVideoDecoder {
222 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
223 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
224 self.width = vinfo.get_width();
225 self.height = vinfo.get_height();
226 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, false, PAL8_FORMAT));
227 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
228 validate!(info.get_extradata().is_some());
230 if let Some(ref edata) = info.get_extradata() {
231 validate!(edata.len() == 0x330);
232 let unp_size = read_u32le(&edata[800..])? as usize;
233 validate!(unp_size < self.width * self.height * 3 + 64); // just for sanity
234 self.buf.resize(unp_size, 0);
236 let el = edata[28 + i];
237 self.pal[i] = (el << 2) | (el >> 4);
243 Err(DecoderError::InvalidData)
246 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
247 let src = pkt.get_buffer();
248 validate!(src.len() >= 10);
250 let mut mr = MemoryReader::new_read(&src);
251 let mut br = ByteReader::new(&mut mr);
254 let bufret = self.hams.clone_ref();
255 if let Some(bbuf) = bufret {
258 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4)?;
259 buf = bufinfo.get_vbuf().unwrap();
260 self.hams.add_frame(buf);
261 buf = self.hams.get_output_frame().unwrap();
264 let is_intra = self.decode_frame(&mut br, &mut buf)?;
266 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
267 frm.set_keyframe(is_intra);
268 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
271 fn flush(&mut self) {
277 pub fn get_decoder_video() -> Box<dyn NADecoder + Send> {
278 Box::new(VMDVideoDecoder::new())
281 struct VMDAudioDecoder {
289 const SOL_AUD_STEPS16: [i16; 128] = [
290 0x00, 0x08, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
291 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0,
292 0xF0, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160,
293 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 0x1D0, 0x1E0,
294 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
295 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270,
296 0x278, 0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0,
297 0x2B8, 0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0,
298 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330,
299 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
300 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0,
301 0x3B8, 0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0,
302 0x3F8, 0x400, 0x440, 0x480, 0x4C0, 0x500, 0x540, 0x580,
303 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 0x740, 0x780,
304 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
305 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
308 impl VMDAudioDecoder {
311 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
312 chmap: NAChannelMap::new(),
318 fn decode_16bit(&self, dst: &mut [i16], off1: usize, br: &mut ByteReader, nblocks: usize, mut mask: u32) -> DecoderResult<()> {
319 let channels = self.chmap.num_channels();
320 let mut off = [0, off1];
321 for _ in 0..nblocks {
323 for ch in 0..channels {
324 for i in 0..self.blk_align {
325 dst[off[ch] + i] = 0;
327 off[ch] += self.blk_align;
330 let mut pred: [i32; 2] = [0; 2];
331 for ch in 0..channels {
332 pred[ch] = i32::from(br.read_u16le()?);
333 dst[off[ch]] = pred[ch] as i16;
337 let flip_ch = if channels == 2 { 1 } else { 0 };
338 for _ in channels..self.blk_align*channels {
339 let b = br.read_byte()? as usize;
341 pred[ch] -= i32::from(SOL_AUD_STEPS16[b & 0x7F]);
343 pred[ch] += i32::from(SOL_AUD_STEPS16[b & 0x7F]);
345 //pred[ch] = pred[ch].max(-32768).min(32767);
346 dst[off[ch]] = pred[ch] as i16;
353 validate!(br.left() == 0);
358 impl NADecoder for VMDAudioDecoder {
359 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
360 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
362 if ainfo.get_format().get_bits() == 8 {
364 self.is16bit = false;
365 self.blk_size = ainfo.get_block_len();
366 self.blk_align = ainfo.get_block_len() / (ainfo.get_channels() as usize);
368 fmt = SND_S16P_FORMAT;
370 self.blk_size = (ainfo.get_block_len() + 1) * (ainfo.get_channels() as usize);
371 self.blk_align = ainfo.get_block_len();
373 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), fmt, ainfo.get_block_len());
374 self.chmap = NAChannelMap::from_str(if ainfo.get_channels() == 1 { "C" } else { "L,R" }).unwrap();
377 Err(DecoderError::InvalidData)
380 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
381 let info = pkt.get_stream().get_info();
382 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
383 let pktbuf = pkt.get_buffer();
384 validate!(pktbuf.len() >= 6);
385 let mut mr = MemoryReader::new_read(&pktbuf);
386 let mut br = ByteReader::new(&mut mr);
387 let blk_type = br.read_byte()?;
391 if blk_type == 2 { // initial
392 mask = br.read_u32le()?;
393 nblocks = (mask.count_ones() as usize) + (pktbuf.len() - 14) / self.blk_size;
394 } else if blk_type == 3 { // silence
401 let samples = nblocks * self.blk_align;
402 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
404 let mut adata = abuf.get_abuf_i16().unwrap();
405 let off1 = adata.get_offset(1);
406 let mut dst = adata.get_data_mut().unwrap();
407 self.decode_16bit(&mut dst, off1, &mut br, nblocks, mask)?;
409 let mut adata = abuf.get_abuf_u8().unwrap();
410 let dst = adata.get_data_mut().unwrap();
413 let channels = self.chmap.num_channels();
414 for _ in 0..nblocks {
416 for i in 0..self.blk_align * channels {
419 } else if channels == 1 {
420 for i in 0..self.blk_size {
421 dst[doff + i] = br.read_byte()?;
424 for i in 0..self.blk_size {
425 let val = br.read_byte()?;
427 dst[doff + i] = 127 - val;
433 doff += self.blk_align * channels;
438 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
439 frm.set_duration(Some(samples as u64));
440 frm.set_keyframe(true);
443 Err(DecoderError::InvalidData)
446 fn flush(&mut self) {
450 pub fn get_decoder_audio() -> Box<dyn NADecoder + Send> {
451 Box::new(VMDAudioDecoder::new())
456 use nihav_core::codecs::RegisteredDecoders;
457 use nihav_core::demuxers::RegisteredDemuxers;
458 use nihav_codec_support::test::dec_video::*;
459 use crate::game_register_all_codecs;
460 use crate::game_register_all_demuxers;
462 fn test_vmd_video() {
463 let mut dmx_reg = RegisteredDemuxers::new();
464 game_register_all_demuxers(&mut dmx_reg);
465 let mut dec_reg = RegisteredDecoders::new();
466 game_register_all_codecs(&mut dec_reg);
468 // let file = "assets/Game/1491.VMD";
469 let file = "assets/Game/128.vmd";
470 test_file_decoding("vmd", file, Some(10), true, false, None/*Some("vmd")*/, &dmx_reg, &dec_reg);
473 fn test_vmd_audio() {
474 let mut dmx_reg = RegisteredDemuxers::new();
475 game_register_all_demuxers(&mut dmx_reg);
476 let mut dec_reg = RegisteredDecoders::new();
477 game_register_all_codecs(&mut dec_reg);
479 // let file = "assets/Game/1491.VMD";
480 let file = "assets/Game/128.vmd";
481 // let file = "assets/Game/1000.VMD";
482 // let file = "assets/Game/235.VMD";
483 test_decode_audio("vmd", file, None, None/*Some("vmd")*/, &dmx_reg, &dec_reg);