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 });
270 pub fn get_decoder_video() -> Box<dyn NADecoder> {
271 Box::new(VMDVideoDecoder::new())
274 struct VMDAudioDecoder {
282 const SOL_AUD_STEPS16: [i16; 128] = [
283 0x00, 0x08, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60,
284 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0,
285 0xF0, 0x100, 0x110, 0x120, 0x130, 0x140, 0x150, 0x160,
286 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 0x1D0, 0x1E0,
287 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
288 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270,
289 0x278, 0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0,
290 0x2B8, 0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0,
291 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330,
292 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
293 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0,
294 0x3B8, 0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0,
295 0x3F8, 0x400, 0x440, 0x480, 0x4C0, 0x500, 0x540, 0x580,
296 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 0x740, 0x780,
297 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
298 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
301 impl VMDAudioDecoder {
304 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
305 chmap: NAChannelMap::new(),
311 fn decode_16bit(&self, dst: &mut [i16], off1: usize, br: &mut ByteReader, nblocks: usize, mut mask: u32) -> DecoderResult<()> {
312 let channels = self.chmap.num_channels();
313 let mut off = [0, off1];
314 for _ in 0..nblocks {
316 for ch in 0..channels {
317 for i in 0..self.blk_align {
318 dst[off[ch] + i] = 0;
320 off[ch] += self.blk_align;
323 let mut pred: [i32; 2] = [0; 2];
324 for ch in 0..channels {
325 pred[ch] = i32::from(br.read_u16le()?);
326 dst[off[ch]] = pred[ch] as i16;
330 let flip_ch = if channels == 2 { 1 } else { 0 };
331 for _ in channels..self.blk_align*channels {
332 let b = br.read_byte()? as usize;
334 pred[ch] -= i32::from(SOL_AUD_STEPS16[b & 0x7F]);
336 pred[ch] += i32::from(SOL_AUD_STEPS16[b & 0x7F]);
338 //pred[ch] = pred[ch].max(-32768).min(32767);
339 dst[off[ch]] = pred[ch] as i16;
346 validate!(br.left() == 0);
351 impl NADecoder for VMDAudioDecoder {
352 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
353 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
355 if ainfo.get_format().get_bits() == 8 {
357 self.is16bit = false;
358 self.blk_size = ainfo.get_block_len();
359 self.blk_align = ainfo.get_block_len() / (ainfo.get_channels() as usize);
361 fmt = SND_S16P_FORMAT;
363 self.blk_size = (ainfo.get_block_len() + 1) * (ainfo.get_channels() as usize);
364 self.blk_align = ainfo.get_block_len();
366 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), fmt, ainfo.get_block_len());
367 self.chmap = NAChannelMap::from_str(if ainfo.get_channels() == 1 { "C" } else { "L,R" }).unwrap();
370 Err(DecoderError::InvalidData)
373 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
374 let info = pkt.get_stream().get_info();
375 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
376 let pktbuf = pkt.get_buffer();
377 validate!(pktbuf.len() >= 6);
378 let mut mr = MemoryReader::new_read(&pktbuf);
379 let mut br = ByteReader::new(&mut mr);
380 let blk_type = br.read_byte()?;
384 if blk_type == 2 { // initial
385 mask = br.read_u32le()?;
386 nblocks = (mask.count_ones() as usize) + (pktbuf.len() - 14) / self.blk_size;
387 } else if blk_type == 3 { // silence
394 let samples = nblocks * self.blk_align;
395 let abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
397 let mut adata = abuf.get_abuf_i16().unwrap();
398 let off1 = adata.get_offset(1);
399 let mut dst = adata.get_data_mut().unwrap();
400 self.decode_16bit(&mut dst, off1, &mut br, nblocks, mask)?;
402 let mut adata = abuf.get_abuf_u8().unwrap();
403 let dst = adata.get_data_mut().unwrap();
406 let channels = self.chmap.num_channels();
407 for _ in 0..nblocks {
409 for i in 0..self.blk_align * channels {
412 } else if channels == 1 {
413 for i in 0..self.blk_size {
414 dst[doff + i] = br.read_byte()?;
417 for i in 0..self.blk_size {
418 let val = br.read_byte()?;
420 dst[doff + i] = 127 - val;
426 doff += self.blk_align * channels;
431 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
432 frm.set_duration(Some(samples as u64));
433 frm.set_keyframe(true);
436 Err(DecoderError::InvalidData)
441 pub fn get_decoder_audio() -> Box<dyn NADecoder> {
442 Box::new(VMDAudioDecoder::new())
447 use nihav_core::codecs::RegisteredDecoders;
448 use nihav_core::demuxers::RegisteredDemuxers;
449 use nihav_core::test::dec_video::*;
450 use crate::codecs::game_register_all_codecs;
451 use crate::demuxers::game_register_all_demuxers;
453 fn test_vmd_video() {
454 let mut dmx_reg = RegisteredDemuxers::new();
455 game_register_all_demuxers(&mut dmx_reg);
456 let mut dec_reg = RegisteredDecoders::new();
457 game_register_all_codecs(&mut dec_reg);
459 // let file = "assets/Game/1491.VMD";
460 let file = "assets/Game/128.vmd";
461 test_file_decoding("vmd", file, Some(10), true, false, None/*Some("vmd")*/, &dmx_reg, &dec_reg);
464 fn test_vmd_audio() {
465 let mut dmx_reg = RegisteredDemuxers::new();
466 game_register_all_demuxers(&mut dmx_reg);
467 let mut dec_reg = RegisteredDecoders::new();
468 game_register_all_codecs(&mut dec_reg);
470 // let file = "assets/Game/1491.VMD";
471 let file = "assets/Game/128.vmd";
472 // let file = "assets/Game/1000.VMD";
473 // let file = "assets/Game/235.VMD";
474 test_decode_audio("vmd", file, None, "vmd", &dmx_reg, &dec_reg);