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 _ => return 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.len() > 0);
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 bufret = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 4);
255 if let Err(_) = bufret { return Err(DecoderError::InvalidData); }
256 let bufinfo = bufret.unwrap();
257 buf = bufinfo.get_vbuf().unwrap();
258 self.hams.add_frame(buf);
259 buf = self.hams.get_output_frame().unwrap();
262 let is_intra = self.decode_frame(&mut br, &mut buf)?;
264 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
265 frm.set_keyframe(is_intra);
266 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
272 pub fn get_decoder_video() -> Box<NADecoder> {
273 Box::new(VMDVideoDecoder::new())
276 struct VMDAudioDecoder {
284 const SOL_AUD_STEPS16: [i16; 128] = [
285 0x00, 0x08, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
286 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0,
287 0xF0, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160,
288 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 0x1D0, 0x1E0,
289 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
290 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270,
291 0x278, 0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0,
292 0x2B8, 0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0,
293 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330,
294 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
295 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0,
296 0x3B8, 0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0,
297 0x3F8, 0x400, 0x440, 0x480, 0x4C0, 0x500, 0x540, 0x580,
298 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 0x740, 0x780,
299 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
300 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
303 impl VMDAudioDecoder {
306 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
307 chmap: NAChannelMap::new(),
313 fn decode_16bit(&self, dst: &mut [i16], off1: usize, br: &mut ByteReader, nblocks: usize, mut mask: u32) -> DecoderResult<()> {
314 let channels = self.chmap.num_channels();
315 let mut off = [0, off1];
316 for _ in 0..nblocks {
318 for ch in 0..channels {
319 for i in 0..self.blk_align {
320 dst[off[ch] + i] = 0;
322 off[ch] += self.blk_align;
325 let mut pred: [i32; 2] = [0; 2];
326 for ch in 0..channels {
327 pred[ch] = br.read_u16le()? as i32;
328 dst[off[ch]] = pred[ch] as i16;
332 let flip_ch = if channels == 2 { 1 } else { 0 };
333 for _ in channels..self.blk_align*channels {
334 let b = br.read_byte()? as usize;
336 pred[ch] -= SOL_AUD_STEPS16[b & 0x7F] as i32;
338 pred[ch] += SOL_AUD_STEPS16[b & 0x7F] as i32;
340 //pred[ch] = pred[ch].max(-32768).min(32767);
341 dst[off[ch]] = pred[ch] as i16;
348 validate!(br.left() == 0);
353 impl NADecoder for VMDAudioDecoder {
354 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
355 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
357 if ainfo.get_format().get_bits() == 8 {
359 self.is16bit = false;
360 self.blk_size = ainfo.get_block_len();
361 self.blk_align = ainfo.get_block_len() / (ainfo.get_channels() as usize);
363 fmt = SND_S16P_FORMAT;
365 self.blk_size = (ainfo.get_block_len() + 1) * (ainfo.get_channels() as usize);
366 self.blk_align = ainfo.get_block_len();
368 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), fmt, ainfo.get_block_len());
369 self.chmap = NAChannelMap::from_str(if ainfo.get_channels() == 1 { "C" } else { "L,R" }).unwrap();
372 Err(DecoderError::InvalidData)
375 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
376 let info = pkt.get_stream().get_info();
377 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
378 let pktbuf = pkt.get_buffer();
379 validate!(pktbuf.len() >= 6);
380 let mut mr = MemoryReader::new_read(&pktbuf);
381 let mut br = ByteReader::new(&mut mr);
382 let blk_type = br.read_byte()?;
386 if blk_type == 2 { // initial
387 mask = br.read_u32le()?;
388 nblocks = (mask.count_ones() as usize) + (pktbuf.len() - 14) / self.blk_size;
389 } else if blk_type == 3 { // silence
396 let samples = nblocks * self.blk_align;
397 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
399 let mut adata = abuf.get_abuf_i16().unwrap();
400 let off1 = adata.get_offset(1);
401 let mut dst = adata.get_data_mut().unwrap();
402 self.decode_16bit(&mut dst, off1, &mut br, nblocks, mask)?;
404 let mut adata = abuf.get_abuf_u8().unwrap();
405 let dst = adata.get_data_mut().unwrap();
408 let channels = self.chmap.num_channels();
409 for _ in 0..nblocks {
411 for i in 0..self.blk_align * channels {
414 } else if channels == 1 {
415 for i in 0..self.blk_size {
416 dst[doff + i] = br.read_byte()?;
419 for i in 0..self.blk_size {
420 let val = br.read_byte()?;
422 dst[doff + i] = 127 - val;
428 doff += self.blk_align * channels;
433 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
434 frm.set_duration(Some(samples as u64));
435 frm.set_keyframe(true);
438 Err(DecoderError::InvalidData)
443 pub fn get_decoder_audio() -> Box<NADecoder> {
444 Box::new(VMDAudioDecoder::new())
449 use nihav_core::codecs::RegisteredDecoders;
450 use nihav_core::demuxers::RegisteredDemuxers;
451 use nihav_core::test::dec_video::*;
452 use crate::codecs::game_register_all_codecs;
453 use crate::demuxers::game_register_all_demuxers;
455 fn test_vmd_video() {
456 let mut dmx_reg = RegisteredDemuxers::new();
457 game_register_all_demuxers(&mut dmx_reg);
458 let mut dec_reg = RegisteredDecoders::new();
459 game_register_all_codecs(&mut dec_reg);
461 // let file = "assets/Game/1491.VMD";
462 let file = "assets/Game/128.vmd";
463 test_file_decoding("vmd", file, Some(10), true, false, None/*Some("vmd")*/, &dmx_reg, &dec_reg);
466 fn test_vmd_audio() {
467 let mut dmx_reg = RegisteredDemuxers::new();
468 game_register_all_demuxers(&mut dmx_reg);
469 let mut dec_reg = RegisteredDecoders::new();
470 game_register_all_codecs(&mut dec_reg);
472 // let file = "assets/Game/1491.VMD";
473 let file = "assets/Game/128.vmd";
474 // let file = "assets/Game/1000.VMD";
475 // let file = "assets/Game/235.VMD";
476 test_decode_audio("vmd", file, None, "vmd", &dmx_reg, &dec_reg);