bbf48460061c519d85906af5f0ca57a2e9f7a60d
[nihav.git] / nihav-rad / src / codecs / smacker.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_core::io::bitreader::*;
4 use nihav_core::io::codebook::*;
5 use std::str::FromStr;
6
7 const PAL_SIZE: usize = 768;
8 const SMK_FLAG_INTERLACED: u32 = 0x02;
9 const SMK_FLAG_SCALED: u32 = 0x04;
10
11 struct SmackerTree8 {
12 cb: Option<Codebook<u8>>,
13 defsym: u8,
14 }
15
16 fn get_tree8(br: &mut BitReader, bits: &mut [u8; 256], codes: &mut [u32; 256], syms: &mut [u8; 256], count: &mut usize, len: u8, prefix: u32) -> DecoderResult<()> {
17 if !br.read_bool()? {
18 bits[*count] = len;
19 codes[*count] = prefix;
20 syms[*count] = br.read(8)? as u8;
21 *count += 1;
22 } else {
23 validate!((*count <= 256 - 2) && (len <= 31));
24 get_tree8(br, bits, codes, syms, count, len + 1, prefix)?;
25 get_tree8(br, bits, codes, syms, count, len + 1, prefix | (1 << len))?;
26 }
27 Ok(())
28 }
29
30 pub struct FullTableCodebookDescReader<'a> {
31 bits: &'a [u8],
32 codes: &'a [u32],
33 syms: &'a [u8],
34 }
35
36 impl<'a> FullTableCodebookDescReader<'a> {
37 pub fn new(codes: &'a [u32], bits: &'a [u8], syms: &'a [u8]) -> Self {
38 Self { bits, codes, syms }
39 }
40 }
41 impl<'a> CodebookDescReader<u8> for FullTableCodebookDescReader<'a>
42 {
43 fn bits(&mut self, idx: usize) -> u8 { self.bits[idx] }
44 fn code(&mut self, idx: usize) -> u32 { self.codes[idx] }
45 fn sym (&mut self, idx: usize) -> u8 { self.syms[idx] }
46 fn len(&mut self) -> usize { self.bits.len() }
47 }
48
49 impl SmackerTree8 {
50 fn new() -> Self {
51 Self {
52 cb: None,
53 defsym: 0,
54 }
55 }
56 fn decode(&mut self, br: &mut BitReader) -> DecoderResult<()> {
57 if !br.read_bool()? { return Ok(()); }
58
59 let mut bits: [u8; 256] = [0; 256];
60 let mut codes: [u32; 256] = [0; 256];
61 let mut syms: [u8; 256] = [0; 256];
62 let mut count = 0;
63
64 get_tree8(br, &mut bits, &mut codes, &mut syms, &mut count, 0, 0)?;
65 validate!(!br.read_bool()?);
66
67 if count > 1 {
68 let mut cr = FullTableCodebookDescReader::new(&codes[0..count], &bits[0..count], &syms[0..count]);
69 let cb = Codebook::new(&mut cr, CodebookMode::LSB)?;
70 self.cb = Some(cb);
71 } else {
72 self.defsym = syms[0];
73 }
74
75 Ok(())
76 }
77 }
78
79 struct SmackerTree16 {
80 tree: Vec<u32>,
81 last: [usize; 3],
82 }
83
84 struct SmackerTree16Builder {
85 tree_lo: SmackerTree8,
86 tree_hi: SmackerTree8,
87 nsyms: usize,
88 esc: [u32; 3],
89 }
90
91 const SMK_BIGTREE_NODE: u32 = 0x80000000;
92 const SMK_LAST_UNINIT: usize = 0xFFFFFFFF;
93
94 impl SmackerTree16Builder {
95 fn get_tree16(&mut self, br: &mut BitReader, tree: &mut SmackerTree16, depth: usize) -> DecoderResult<u32> {
96 validate!(tree.tree.len() < self.nsyms);
97 if !br.read_bool()? {
98 let lo = br.read_tree8(&self.tree_lo)?;
99 let hi = br.read_tree8(&self.tree_hi)?;
100 let mut sym = (((hi as u16) << 8) | (lo as u16)) as u32;
101 if sym == self.esc[0] {
102 tree.last[0] = tree.tree.len();
103 sym = 0;
104 } else if sym == self.esc[1] {
105 tree.last[1] = tree.tree.len();
106 sym = 0;
107 } else if sym == self.esc[2] {
108 tree.last[2] = tree.tree.len();
109 sym = 0;
110 }
111 tree.tree.push(sym);
112 Ok(1)
113 } else {
114 let cur_idx = tree.tree.len();
115 tree.tree.push(0);
116 let lcount = self.get_tree16(br, tree, depth + 1)?;
117 let rcount = self.get_tree16(br, tree, depth + 1)?;
118 tree.tree[cur_idx] = SMK_BIGTREE_NODE | lcount;
119 Ok(lcount + rcount + 1)
120 }
121 }
122 }
123
124 impl SmackerTree16 {
125 fn new() -> Self {
126 Self {
127 tree: Vec::new(),
128 last: [SMK_LAST_UNINIT; 3],
129 }
130 }
131 fn decode(&mut self, br: &mut BitReader, size: u32) -> DecoderResult<()> {
132 if !br.read_bool()? { return Ok(()); }
133
134 let mut tree_lo = SmackerTree8::new();
135 tree_lo.decode(br)?;
136 let mut tree_hi = SmackerTree8::new();
137 tree_hi.decode(br)?;
138
139 let mut esc: [u32; 3] = [0; 3];
140 for i in 0..esc.len() {
141 esc[i] = br.read(16)? as u32;
142 }
143
144 let nsyms = (((size + 3) >> 2) + 4) as usize;
145 self.tree = Vec::with_capacity(nsyms);
146
147 let mut tb = SmackerTree16Builder { tree_lo, tree_hi, nsyms, esc };
148
149 tb.get_tree16(br, self, 0)?;
150 validate!(!br.read_bool()?);
151
152 for i in 0..self.last.len() {
153 if self.last[i] == SMK_LAST_UNINIT {
154 self.last[i] = self.tree.len();
155 self.tree.push(0);
156 }
157 }
158 validate!(self.tree.len() <= nsyms);
159 Ok(())
160 }
161 fn reset(&mut self) {
162 for i in 0..self.last.len() {
163 if self.last[i] != SMK_LAST_UNINIT {
164 self.tree[self.last[i]] = 0;
165 }
166 }
167 }
168 }
169
170 trait ReadTree {
171 fn read_tree8(&mut self, tree: &SmackerTree8) -> DecoderResult<u8>;
172 fn read_bigtree(&mut self, tree: &mut SmackerTree16) -> DecoderResult<u16>;
173 }
174
175 impl<'a> ReadTree for BitReader<'a> {
176 fn read_tree8(&mut self, tree: &SmackerTree8) -> DecoderResult<u8> {
177 if let Some(ref cb) = tree.cb {
178 Ok(self.read_cb(cb)?)
179 } else {
180 Ok(tree.defsym)
181 }
182 }
183 fn read_bigtree(&mut self, tree: &mut SmackerTree16) -> DecoderResult<u16> {
184 let mut pos = 0;
185 while (tree.tree[pos] & SMK_BIGTREE_NODE) != 0 {
186 if self.read_bool()? {
187 pos += (tree.tree[pos] & !SMK_BIGTREE_NODE) as usize;
188 }
189 pos += 1;
190 }
191 let val = tree.tree[pos];
192 if val != tree.tree[tree.last[0]] {
193 tree.tree[tree.last[2]] = tree.tree[tree.last[1]];
194 tree.tree[tree.last[1]] = tree.tree[tree.last[0]];
195 tree.tree[tree.last[0]] = val;
196 }
197 Ok(val as u16)
198 }
199 }
200
201 const SMK_BLOCK_RUNS: [usize; 64] = [
202 1, 2, 3, 4, 5, 6, 7, 8,
203 9, 10, 11, 12, 13, 14, 15, 16,
204 17, 18, 19, 20, 21, 22, 23, 24,
205 25, 26, 27, 28, 29, 30, 31, 32,
206 33, 34, 35, 36, 37, 38, 39, 40,
207 41, 42, 43, 44, 45, 46, 47, 48,
208 49, 50, 51, 52, 53, 54, 55, 56,
209 57, 58, 59, 128, 256, 512, 1024, 2048
210 ];
211
212 struct SmackerVideoDecoder {
213 info: Rc<NACodecInfo>,
214 mmap_tree: SmackerTree16,
215 mclr_tree: SmackerTree16,
216 full_tree: SmackerTree16,
217 type_tree: SmackerTree16,
218 w: usize,
219 h: usize,
220 bw: usize,
221 bh: usize,
222 is_ver4: bool,
223 flags: u32,
224 frame: Vec<u8>,
225 stride: usize,
226 }
227
228 impl SmackerVideoDecoder {
229 fn new() -> Self {
230 let dummy_info = Rc::new(DUMMY_CODEC_INFO);
231 Self {
232 info: dummy_info,
233 mmap_tree: SmackerTree16::new(),
234 mclr_tree: SmackerTree16::new(),
235 full_tree: SmackerTree16::new(),
236 type_tree: SmackerTree16::new(),
237 w: 0,
238 h: 0,
239 bw: 0,
240 bh: 0,
241 is_ver4: false,
242 flags: 0,
243 frame: Vec::new(),
244 stride: 0,
245 }
246 }
247 fn block_pos(&self, blk_no: usize) -> usize {
248 let bx = blk_no % self.bw;
249 let by = blk_no / self.bw;
250 bx * 4 + by * 4 * self.stride
251 }
252 fn decode_frame(&mut self, br: &mut BitReader) -> DecoderResult<bool> {
253 let mut is_intra = true;
254 let blocks = self.bw * self.bh;
255
256 self.mmap_tree.reset();
257 self.mclr_tree.reset();
258 self.full_tree.reset();
259 self.type_tree.reset();
260
261 let mut block = 0;
262 while block < blocks {
263 let btype = br.read_bigtree(&mut self.type_tree)?;
264 let run = SMK_BLOCK_RUNS[((btype as usize) >> 2) & 0x3F];
265 validate!(run <= blocks - block);
266 match btype & 3 {
267 0 => { // two-colour pattern
268 for i in 0..run {
269 let clr = br.read_bigtree(&mut self.mclr_tree)?;
270 let mut map = br.read_bigtree(&mut self.mmap_tree)?;
271 let hi = (clr >> 8) as u8;
272 let lo = (clr & 0xFF) as u8;
273 let mut doff = self.block_pos(block + i);
274 for _ in 0..4 {
275 self.frame[doff + 0] = if (map & 1) != 0 { hi } else { lo };
276 self.frame[doff + 1] = if (map & 2) != 0 { hi } else { lo };
277 self.frame[doff + 2] = if (map & 4) != 0 { hi } else { lo };
278 self.frame[doff + 3] = if (map & 8) != 0 { hi } else { lo };
279 map >>= 4;
280 doff += self.stride;
281 }
282 }
283 },
284 1 => { // full
285 let mode;
286 if !self.is_ver4 || !br.read_bool()? {
287 mode = 0;
288 } else {
289 mode = 1 + br.read(1)?;
290 }
291 for i in 0..run {
292 let mut doff = self.block_pos(block + i);
293 match mode {
294 0 => {
295 for _ in 0..4 {
296 let clr0 = br.read_bigtree(&mut self.full_tree)?;
297 let clr1 = br.read_bigtree(&mut self.full_tree)?;
298 self.frame[doff + 0] = (clr1 & 0xFF) as u8;
299 self.frame[doff + 1] = (clr1 >> 8) as u8;
300 self.frame[doff + 2] = (clr0 & 0xFF) as u8;
301 self.frame[doff + 3] = (clr0 >> 8) as u8;
302 doff += self.stride;
303 }
304 },
305 1 => {
306 for _ in 0..2 {
307 let clr = br.read_bigtree(&mut self.full_tree)?;
308 self.frame[doff + 0] = (clr & 0xFF) as u8;
309 self.frame[doff + 1] = (clr & 0xFF) as u8;
310 self.frame[doff + 2] = (clr >> 8) as u8;
311 self.frame[doff + 3] = (clr >> 8) as u8;
312 doff += self.stride;
313 self.frame[doff + 0] = (clr & 0xFF) as u8;
314 self.frame[doff + 1] = (clr & 0xFF) as u8;
315 self.frame[doff + 2] = (clr >> 8) as u8;
316 self.frame[doff + 3] = (clr >> 8) as u8;
317 doff += self.stride;
318 }
319 },
320 2 => {
321 for _ in 0..2 {
322 let clr0 = br.read_bigtree(&mut self.full_tree)?;
323 let clr1 = br.read_bigtree(&mut self.full_tree)?;
324 self.frame[doff + 0] = (clr1 & 0xFF) as u8;
325 self.frame[doff + 1] = (clr1 >> 8) as u8;
326 self.frame[doff + 2] = (clr0 & 0xFF) as u8;
327 self.frame[doff + 3] = (clr0 >> 8) as u8;
328 doff += self.stride;
329 self.frame[doff + 0] = (clr1 & 0xFF) as u8;
330 self.frame[doff + 1] = (clr1 >> 8) as u8;
331 self.frame[doff + 2] = (clr0 & 0xFF) as u8;
332 self.frame[doff + 3] = (clr0 >> 8) as u8;
333 doff += self.stride;
334 }
335 },
336 _ => unreachable!(),
337 };
338 }
339 },
340 2 => { // skip
341 is_intra = false;
342 },
343 3 => { // fill
344 let clr = (btype >> 8) as u8;
345 for i in 0..run {
346 let mut doff = self.block_pos(block + i);
347 for _ in 0..4 {
348 self.frame[doff + 0] = clr;
349 self.frame[doff + 1] = clr;
350 self.frame[doff + 2] = clr;
351 self.frame[doff + 3] = clr;
352 doff += self.stride;
353 }
354 }
355 },
356 _ => unreachable!(),
357 };
358 block += run;
359 }
360 Ok(is_intra)
361 }
362 fn output_frame(&self, buf: &mut NAVideoBuffer<u8>) {
363 let stride = buf.get_stride(0);
364 let data = buf.get_data_mut().unwrap();
365 let dst = data.as_mut_slice();
366 let is_scaled = (self.flags & SMK_FLAG_SCALED) != 0;
367 let is_interlaced = (self.flags & SMK_FLAG_INTERLACED) != 0;
368 let mut didx = 0;
369 let mut sidx = 0;
370 for _ in 0..self.h {
371 for x in 0..self.w { dst[didx + x] = self.frame[sidx + x]; }
372 sidx += self.stride;
373 didx += stride;
374 if is_scaled {
375 for x in 0..self.w { dst[didx + x] = dst[didx - stride + x]; }
376 didx += stride;
377 }
378 if is_interlaced {
379 for x in 0..self.w { dst[didx + x] = 0; }
380 didx += stride;
381 if is_scaled {
382 for x in 0..self.w { dst[didx + x] = 0; }
383 didx += stride;
384 }
385 }
386 }
387 }
388 }
389
390 impl NADecoder for SmackerVideoDecoder {
391 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
392 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
393 let w = vinfo.get_width();
394 let h = vinfo.get_height();
395 let fmt = PAL8_FORMAT;
396
397 self.w = w;
398 self.h = h;
399 self.bw = w >> 2;
400 self.bh = h >> 2;
401 let edata = info.get_extradata().unwrap();
402 validate!(edata.len() > 24);
403
404 self.stride = w;
405 self.frame.resize(w * h, 0);
406
407 let mut mr = MemoryReader::new_read(&edata);
408 let mut br = ByteReader::new(&mut mr);
409 let magic = br.read_u32be()?;
410 self.flags = br.read_u32le()?;
411 let mmap_size = br.read_u32le()?;
412 let mclr_size = br.read_u32le()?;
413 let full_size = br.read_u32le()?;
414 let type_size = br.read_u32le()?;
415
416 self.is_ver4 = (magic & 0xFF) == 0x34;
417 let mut br = BitReader::new(&edata[24..], edata.len() - 24, BitReaderMode::LE);
418 self.mmap_tree.decode(&mut br, mmap_size)?;
419 self.mclr_tree.decode(&mut br, mclr_size)?;
420 self.full_tree.decode(&mut br, full_size)?;
421 self.type_tree.decode(&mut br, type_size)?;
422
423 let mut out_h = h;
424 if (self.flags & SMK_FLAG_INTERLACED) != 0 {
425 out_h <<= 1;
426 }
427 if (self.flags & SMK_FLAG_SCALED) != 0 {
428 out_h <<= 1;
429 }
430 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, out_h, false, fmt));
431 self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
432
433
434 Ok(())
435 } else {
436 Err(DecoderError::InvalidData)
437 }
438 }
439 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
440 let src = pkt.get_buffer();
441 validate!(src.len() >= PAL_SIZE);
442
443 let is_intra;
444 let ftype;
445 let bufinfo;
446 if src.len() > PAL_SIZE {
447 let mut br = BitReader::new(&src[PAL_SIZE..], src.len() - PAL_SIZE, BitReaderMode::LE);
448
449 let bufret = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 2);
450 if let Err(_) = bufret { return Err(DecoderError::InvalidData); }
451 bufinfo = bufret.unwrap();
452 let mut buf = bufinfo.get_vbuf().unwrap();
453 is_intra = self.decode_frame(&mut br)?;
454 self.output_frame(&mut buf);
455 let paloff = buf.get_offset(1);
456 let data = buf.get_data_mut().unwrap();
457 let dst = data.as_mut_slice();
458 let palout = &mut dst[paloff..][..PAL_SIZE];
459 palout.copy_from_slice(&src[0..PAL_SIZE]);
460 ftype = if is_intra { FrameType::I } else { FrameType::P };
461 } else {
462 bufinfo = NABufferType::None;
463 ftype = FrameType::Skip;
464 is_intra = false;
465 }
466
467 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
468 frm.set_keyframe(is_intra);
469 frm.set_frame_type(ftype);
470 Ok(Rc::new(RefCell::new(frm)))
471 }
472 }
473
474 pub fn get_decoder_video() -> Box<NADecoder> {
475 Box::new(SmackerVideoDecoder::new())
476 }
477
478 struct SmackerAudioDecoder {
479 ainfo: NAAudioInfo,
480 chmap: NAChannelMap,
481 chans: usize,
482 bits: u8,
483 }
484
485 impl SmackerAudioDecoder {
486 fn new() -> Self {
487 Self {
488 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
489 chmap: NAChannelMap::new(),
490 chans: 0,
491 bits: 0,
492 }
493 }
494 }
495
496 impl NADecoder for SmackerAudioDecoder {
497 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
498 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
499 self.bits = ainfo.get_format().get_bits();
500 let fmt = if self.bits == 8 { SND_U8_FORMAT } else { SND_S16P_FORMAT };
501 self.chans = ainfo.get_channels() as usize;
502 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), ainfo.get_channels(), fmt, 0);
503 self.chmap = NAChannelMap::from_str(if ainfo.get_channels() == 2 {"L,R"} else {"C"}).unwrap();
504 Ok(())
505 } else {
506 Err(DecoderError::InvalidData)
507 }
508 }
509 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
510 let info = pkt.get_stream().get_info();
511 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
512 let src = pkt.get_buffer();
513 validate!(src.len() > 4);
514 let mut br = BitReader::new(&src, src.len(), BitReaderMode::LE);
515 let unp_size = br.read(32)? as usize;
516 if !br.read_bool()? {
517 let mut frm = NAFrame::new_from_pkt(pkt, info.clone(), NABufferType::None);
518 frm.set_frame_type(FrameType::Skip);
519 return Ok(Rc::new(RefCell::new(frm)));
520 }
521 let stereo = br.read_bool()?;
522 let bits16 = br.read_bool()?;
523 validate!(!(stereo ^ (self.chans == 2)));
524 validate!(!(bits16 ^ (self.bits == 16)));
525
526 let abuf;
527 let samples;
528 let nch = if stereo { 2 } else { 1 };
529 if bits16 {
530 samples = unp_size / 2 / nch;
531 let mask = if stereo { 1 } else { 0 };
532 let mut trees: [SmackerTree8; 4] = [SmackerTree8::new(), SmackerTree8::new(), SmackerTree8::new(), SmackerTree8::new()];
533 for i in 0..nch*2 {
534 trees[i].decode(&mut br)?;
535 }
536 let mut pred: [i16; 2] = [0; 2];
537 for i in 0..nch {
538 let hi = br.read(8)?;
539 let lo = br.read(8)?;
540 pred[nch - i - 1] = (lo | (hi << 8)) as i16;
541 }
542
543 abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
544 let mut adata = abuf.get_abuf_i16().unwrap();
545 let offs: [usize; 2] = [0, adata.get_offset(1)];
546 let dst = adata.get_data_mut().unwrap();
547 for ch in 0..nch {
548 dst[offs[ch]] = pred[ch];
549 }
550 for i in nch..(unp_size >> 1) {
551 let idx = i & mask;
552 let lo = br.read_tree8(&trees[idx * 2 + 0])? as u16;
553 let hi = br.read_tree8(&trees[idx * 2 + 1])? as u16;
554 let diff = (lo | (hi << 8)) as i16;
555 pred[idx] = pred[idx].wrapping_add(diff);
556 dst[offs[idx] + (i >> 1)] = pred[idx];
557 }
558 } else {
559 samples = unp_size / nch;
560 abuf = alloc_audio_buffer(self.ainfo, samples, self.chmap.clone())?;
561 let mut adata = abuf.get_abuf_u8().unwrap();
562 let dst = adata.get_data_mut().unwrap();
563 if stereo {
564 let mut trees: [SmackerTree8; 2] = [SmackerTree8::new(), SmackerTree8::new()];
565 trees[0].decode(&mut br)?;
566 trees[1].decode(&mut br)?;
567 let pred0 = br.read(8)? as u8;
568 let pred1 = br.read(8)? as u8;
569 let mut pred: [u8; 2] = [ pred1, pred0 ];
570 for ch in 0..2 { dst[ch] = pred[ch]; }
571 for i in 2..unp_size {
572 let diff = br.read_tree8(&trees[i & 1])? as u8;
573 pred[i & 1] = pred[i & 1].wrapping_add(diff);
574 dst[i] = pred[i & 1];
575 }
576 } else {
577 let mut tree = SmackerTree8::new();
578 tree.decode(&mut br)?;
579 let mut pred = br.read(8)? as u8;
580 dst[0] = pred;
581 for i in 1..unp_size {
582 let diff = br.read_tree8(&tree)? as u8;
583 pred = pred.wrapping_add(diff);
584 dst[i] = pred;
585 }
586 }
587 }
588 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
589 frm.set_duration(Some(samples as u64));
590 frm.set_keyframe(false);
591 Ok(Rc::new(RefCell::new(frm)))
592 } else {
593 Err(DecoderError::InvalidData)
594 }
595 }
596 }
597
598 pub fn get_decoder_audio() -> Box<NADecoder> {
599 Box::new(SmackerAudioDecoder::new())
600 }
601
602 #[cfg(test)]
603 mod test {
604 use nihav_core::codecs::RegisteredDecoders;
605 use nihav_core::demuxers::RegisteredDemuxers;
606 use nihav_core::test::dec_video::*;
607 use crate::codecs::rad_register_all_codecs;
608 use crate::demuxers::rad_register_all_demuxers;
609 #[test]
610 fn test_smkvid() {
611 let mut dmx_reg = RegisteredDemuxers::new();
612 rad_register_all_demuxers(&mut dmx_reg);
613 let mut dec_reg = RegisteredDecoders::new();
614 rad_register_all_codecs(&mut dec_reg);
615
616 //let file = "assets/RAD/20130507_audio-distortion.smk";
617 //let file = "assets/RAD/ajfstr1.smk";
618 //let file = "assets/RAD/credits.smk";
619 let file = "assets/RAD/wetlogo.smk";
620 test_file_decoding("smacker", file, Some(1000), true, false, None, &dmx_reg, &dec_reg);
621 }
622 #[test]
623 fn test_smkaud() {
624 let mut dmx_reg = RegisteredDemuxers::new();
625 rad_register_all_demuxers(&mut dmx_reg);
626 let mut dec_reg = RegisteredDecoders::new();
627 rad_register_all_codecs(&mut dec_reg);
628
629 //let file = "assets/RAD/20130507_audio-distortion.smk";
630 let file = "assets/RAD/wetlogo.smk";
631 test_decode_audio("smacker", file, None, "smk", &dmx_reg, &dec_reg);
632 }
633 }