1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_core::io::bitreader::*;
4 use nihav_core::io::intcode::*;
5 use nihav_codec_support::codecs::*;
6 use nihav_codec_support::codecs::blockdsp::*;
7 use nihav_codec_support::data::GenericCache;
18 #[derive(Clone,Copy,Debug,PartialEq)]
36 struct IntraModeState {
37 cache: GenericCache<i8>,
42 fn new(mb_w: usize) -> Self {
43 let stride = 1 + mb_w * 4 + 1;
44 IntraModeState { cache: GenericCache::new(4, stride, -1), i16_pred: 0 }
46 fn reset(&mut self) { self.cache.reset(); }
47 fn update(&mut self) { self.cache.update_row(); }
48 fn get_pos(&self, xpos: usize) -> usize {
49 self.cache.stride + 1 + xpos * 4
51 fn set_mb_x(&mut self, mb_x: usize) {
52 self.cache.xpos = self.get_pos(mb_x);
54 fn fill_block(&mut self, val: i8) {
55 let mut pos = self.cache.xpos;
58 self.cache.data[pos + j] = val;
60 pos += self.cache.stride;
63 fn get_pred16_type(&self, has_top: bool, has_left: bool) -> PredType8x8 {
64 if !has_top && !has_left { return PredType8x8::DC128; }
65 let mut im = INTRA_PRED16[self.i16_pred as usize];
68 PredType8x8::Plane | PredType8x8::Ver => PredType8x8::Hor,
69 PredType8x8::DC => PredType8x8::LeftDC,
74 PredType8x8::Plane | PredType8x8::Hor => PredType8x8::Ver,
75 PredType8x8::DC => PredType8x8::TopDC,
81 fn get_pred8_type(&self, has_top: bool, has_left: bool) -> PredType8x8 {
82 if !has_top && !has_left { return PredType8x8::DC128; }
83 let mut im = PredType8x8::DC;
86 PredType8x8::Plane | PredType8x8::Ver => PredType8x8::Hor,
87 PredType8x8::DC => PredType8x8::LeftDC,
92 PredType8x8::Plane | PredType8x8::Hor => PredType8x8::Ver,
93 PredType8x8::DC => PredType8x8::TopDC,
99 fn get_pred4_type(&self, x: usize, y: usize, has_top: bool, has_left: bool) -> PredType4x4 {
100 let no_up = !has_top && (y == 0);
101 let no_left = !has_left && (x == 0);
102 if no_up && no_left { return PredType4x4::DC128; }
104 let mut im = INTRA_PRED4[self.cache.data[self.cache.xpos + x + y * self.cache.stride] as usize];
108 PredType4x4::Ver => PredType4x4::Hor,
109 PredType4x4::DC => PredType4x4::LeftDC,
114 PredType4x4::Hor => PredType4x4::Ver,
115 PredType4x4::DC => PredType4x4::TopDC,
134 Self { mv_b: Vec::new(), mv_f: Vec::new(), w: 0, h: 0, has_b: Vec::new(), has_f: Vec::new() }
136 fn resize(&mut self, mb_w: usize, mb_h: usize) {
141 fn reset(&mut self) {
142 let size = self.w * self.h;
144 self.mv_f.resize(size, ZERO_MV);
146 self.mv_b.resize(size, ZERO_MV);
148 self.has_f.resize(size >> 4, false);
150 self.has_b.resize(size >> 4, false);
152 fn fill(&mut self, mb_x: usize, mb_y: usize, fwd: bool, mv: MV) {
153 let idx = mb_x * 4 + mb_y * 4 * self.w;
154 let dst = if fwd { &mut self.mv_f[idx..] } else { &mut self.mv_b[idx..] };
155 for row in dst.chunks_mut(self.w).take(4) {
162 fn fill_part(&mut self, x: usize, y: usize, fwd: bool, bw: usize, bh: usize, mv: MV) {
163 let idx = x + y * self.w;
164 let dst = if fwd { &mut self.mv_f[idx..] } else { &mut self.mv_b[idx..] };
165 for row in dst.chunks_mut(self.w).take(bh) {
166 for el in row.iter_mut().take(bw) {
171 fn get_mv_by_idx(&self, idx: usize, fwd: bool) -> MV {
172 if fwd { self.mv_f[idx] } else { self.mv_b[idx] }
174 fn pred_mv(&self, idx: usize, bw: usize, fwd: bool, has_top: bool, has_left: bool, has_tr: bool, has_tl: bool) -> MV {
175 if !has_top && !has_left { return ZERO_MV; }
176 let left_mv = if has_left { self.get_mv_by_idx(idx - 1, fwd) } else { ZERO_MV };
177 let top_mv = if has_top { self.get_mv_by_idx(idx - self.w, fwd) } else { left_mv };
180 tr_mv = self.get_mv_by_idx(idx - self.w + bw, fwd);
182 tr_mv = self.get_mv_by_idx(idx - self.w - 1, fwd);
186 MV::pred(left_mv, top_mv, tr_mv)
188 fn pred_mv_part(&self, x: usize, y: usize, bw: usize, fwd: bool, has_top: bool, has_left: bool, has_tr: bool, has_tl: bool) -> MV {
189 self.pred_mv(x + y * self.w, bw, fwd, has_top, has_left, has_tr, has_tl)
191 fn get_mv(&self, x: usize, y: usize, fwd: bool) -> MV {
192 let idx = x + y * self.w;
193 if fwd { self.mv_f[idx] }
194 else { self.mv_b[idx] }
199 info: NACodecInfoRef,
203 avg_buf: NAVideoBufferRef<u8>,
204 imode: IntraModeState,
210 coeffs: [[i16; 16]; 25],
229 const ZIGZAG4: &[usize; 16] = &[
235 const ALT_SCAN: &[usize; 16] = &[
242 const SVQ3_RUNLEVEL: [(usize, i16); 16] = [
243 ( 0, 0 ), ( 0, 1 ), ( 1, 1 ), ( 2, 1 ), ( 0, 2 ), ( 3, 1 ), ( 4, 1 ), ( 5, 1 ),
244 ( 0, 3 ), ( 1, 2 ), ( 2, 2 ), ( 6, 1 ), ( 7, 1 ), ( 8, 1 ), ( 9, 1 ), ( 0, 4 )
246 const SVQ3_RUNLEVEL_ALT: [(usize, i16); 16] = [
247 ( 0, 0 ), ( 0, 1 ), ( 1, 1 ), ( 0, 2 ), ( 2, 1 ), ( 0, 3 ), ( 0, 4 ), ( 0, 5 ),
248 ( 3, 1 ), ( 4, 1 ), ( 1, 2 ), ( 1, 3 ), ( 0, 6 ), ( 0, 7 ), ( 0, 8 ), ( 0, 9 )
250 const RUN_ADD: [i16; 16] = [ 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ];
251 const RUN_ADD_ALT: [i16; 8] = [ 8, 2, 0, 0, 0, -1, -1, -1 ];
253 fn decode_alt_slice(br: &mut BitReader, blk: &mut [i16; 16], mut idx: usize, end: usize) -> DecoderResult<bool> {
254 let mut coded = false;
256 let val = br.read_code(UintCodeType::Gamma)?;
257 if val == 0 { break; }
258 let sign = (val & 1) == 0;
259 let val = (val + 1) >> 1;
260 let (run, level) = if (val as usize) < SVQ3_RUNLEVEL.len() {
261 SVQ3_RUNLEVEL_ALT[val as usize]
263 let run = (val & 0x7) as usize;
264 (run, ((val >> 3) as i16) + RUN_ADD_ALT[(run as usize).min(RUN_ADD_ALT.len() - 1)])
267 validate!(idx < end);
268 blk[ALT_SCAN[idx]] = if sign { -level } else { level };
273 let val = br.read_code(UintCodeType::Gamma)?;
279 fn decode_block(br: &mut BitReader, blk: &mut [i16; 16], start: usize, alt: bool) -> DecoderResult<bool> {
280 let mut coded = false;
283 while idx < blk.len() {
284 let val = br.read_code(UintCodeType::Gamma)?;
285 if val == 0 { break; }
286 let sign = (val & 1) == 0;
287 let val = (val + 1) >> 1;
288 let (run, level) = if (val as usize) < SVQ3_RUNLEVEL.len() {
289 SVQ3_RUNLEVEL[val as usize]
291 let run = (val & 0xF) as usize;
292 (run, ((val >> 4) as i16) + RUN_ADD[(run as usize).min(RUN_ADD.len() - 1)])
295 validate!(idx < blk.len());
296 blk[ZIGZAG4[idx]] = if sign { -level } else { level };
300 if idx == blk.len() {
301 let val = br.read_code(UintCodeType::Gamma)?;
305 coded = decode_alt_slice(br, blk, start, 8)?;
306 coded |= decode_alt_slice(br, blk, 8, 16)?;
311 fn decode_chroma_dc(br: &mut BitReader) -> DecoderResult<[i16; 4]> {
313 let mut blk = [0i16; 4];
314 while idx < blk.len() {
315 let val = br.read_code(UintCodeType::Gamma)?;
316 if val == 0 { break; }
317 let sign = (val & 1) == 0;
318 let val = (val + 1) >> 1;
319 let (run, level) = if val < 3 {
324 ((val & 3) as usize, (((val + 9) >> 2) - (val & 3)) as i16)
327 validate!(idx < blk.len());
328 blk[idx] = if sign { -level } else { level };
331 if idx == blk.len() {
332 let val = br.read_code(UintCodeType::Gamma)?;
338 fn read_mv(br: &mut BitReader) -> DecoderResult<MV> {
339 let y = br.read_code_signed(IntCodeType::Gamma)? as i16;
340 let x = br.read_code_signed(IntCodeType::Gamma)? as i16;
344 fn div6(val: i16) -> i16 {
345 (((((i32::from(val) + (6 << 16)) as u32) / 6) as i32) - (1 << 16)) as i16
348 fn scale_mv(mv: MV, trb: u8, trd: u8) -> (MV, MV) {
349 let trb = i32::from(trb);
350 let trd = i32::from(trd);
351 let fx = (i32::from(mv.x * 2) * trb / trd + 1) >> 1;
352 let fy = (i32::from(mv.y * 2) * trb / trd + 1) >> 1;
353 let bx = (i32::from(mv.x * 2) * (trb - trd) / trd + 1) >> 1;
354 let by = (i32::from(mv.y * 2) * (trb - trd) / trd + 1) >> 1;
355 (MV { x: fx as i16, y: fy as i16 }, MV { x: bx as i16, y: by as i16 })
358 fn add_mv(pred_mv: MV, dmv: MV, mc_mode: MCMode) -> (MV, usize, &'static [BlkInterpFunc]) {
361 let x = div6(pred_mv.x + 3);
362 let y = div6(pred_mv.y + 3);
363 let mut mv = MV{ x, y } + dmv;
366 (mv, 0, HALFPEL_INTERP_FUNCS)
369 let x = div6(pred_mv.x * 2 + 2);
370 let y = div6(pred_mv.y * 2 + 2);
371 let mut mv = MV{ x, y } + dmv;
372 let mode = ((mv.x & 1) + (mv.y & 1) * 2) as usize;
375 (mv, mode, HALFPEL_INTERP_FUNCS)
377 MCMode::Thirdpel => {
378 let x = (pred_mv.x + 1) >> 1;
379 let y = (pred_mv.y + 1) >> 1;
380 let mut mv = MV{ x, y } + dmv;
381 let mut mx = mv.x % 3;
382 if mx < 0 { mx += 3; }
383 let mut my = mv.y % 3;
384 if my < 0 { my += 3; }
385 let mode = (mx + my * 3) as usize;
388 (mv, mode, THIRDPEL_INTERP_FUNCS)
393 fn copy_block(dst: &mut NASimpleVideoFrame<u8>, src: NAVideoBufferRef<u8>, ebuf: &mut [u8; 32 * 18], comp: usize,
394 dx: usize, dy: usize, mv_x: i16, mv_y: i16, bw: usize, bh: usize,
395 preborder: usize, postborder: usize,
396 mode: usize, interp: &[BlkInterpFunc])
398 let pre = if mode != 0 { preborder as isize } else { 0 };
399 let post = if mode != 0 { postborder as isize } else { 0 };
400 let (w, h) = src.get_dimensions(comp);
401 let sx = (dx as isize) + (mv_x as isize);
402 let sy = (dy as isize) + (mv_y as isize);
404 if (sx - pre < 0) || (sx + (bw as isize) + post > (w as isize)) ||
405 (sy - pre < 0) || (sy + (bh as isize) + post > (h as isize)) {
406 let ebuf_stride: usize = 32;
408 let dstride = dst.stride[comp];
409 let doff = dst.offset[comp];
410 let edge = (pre + post) as usize;
411 edge_emu(&src, sx - pre, sy - pre, bw + edge, bh + edge,
412 ebuf, ebuf_stride, comp, 4);
413 (interp[mode])(&mut dst.data[doff + dx + dy * dstride..], dstride,
414 ebuf, ebuf_stride, bw, bh);
416 let sstride = src.get_stride(comp);
417 let soff = src.get_offset(comp);
418 let sdta = src.get_data();
419 let sbuf: &[u8] = sdta.as_slice();
420 let dstride = dst.stride[comp];
421 let doff = dst.offset[comp];
422 let saddr = soff + ((sx - pre) as usize) + ((sy - pre) as usize) * sstride;
423 (interp[mode])(&mut dst.data[doff + dx + dy * dstride..], dstride,
424 &sbuf[saddr..], sstride, bw, bh);
428 fn mc_part(dframe: &mut NASimpleVideoFrame<u8>, src: NAVideoBufferRef<u8>, ebuf: &mut [u8; 32 * 18], xoff: usize, yoff: usize, bw: usize, bh: usize, mv: MV, mode: usize, ifuncs: &[BlkInterpFunc]) {
431 let cmx = (mx + if mx < 0 { 1 } else { 0 }) >> 1;
432 let cmy = (my + if my < 0 { 1 } else { 0 }) >> 1;
433 let post = if mode != 0 { 1 } else { 0 };
435 copy_block(dframe, src.clone(), ebuf, 0, xoff, yoff, mx, my, bw * 4, bh * 4, 0, post, mode, ifuncs);
436 copy_block(dframe, src.clone(), ebuf, 1, xoff / 2, yoff / 2, cmx, cmy, bw * 2, bh * 2, 0, post, mode, ifuncs);
437 copy_block(dframe, src, ebuf, 2, xoff / 2, yoff / 2, cmx, cmy, bw * 2, bh * 2, 0, post, mode, ifuncs);
442 let tmp_vinfo = NAVideoInfo::new(16, 16, false, YUV420_FORMAT);
443 let vt = alloc_video_buffer(tmp_vinfo, 4).unwrap();
444 let vb = vt.get_vbuf();
445 let avg_buf = vb.unwrap();
448 info: NACodecInfoRef::default(),
451 ipbs: IPBShuffler::new(),
453 imode: IntraModeState::new(0),
455 ref_mvi: MVInfo::new(),
459 coeffs: [[0; 16]; 25],
461 dc_only: [false; 24],
467 slice_buf: Vec::new(),
478 fn parse_sequence_header(&mut self, src: &[u8]) -> DecoderResult<()> {
479 let mut br = BitReader::new(src, BitReaderMode::BE);
480 let fcode = br.read(3)? as usize;
481 let (w, h) = if fcode < FRAME_SIZES.len() {
484 let w = br.read(12)? as usize;
485 let h = br.read(12)? as usize;
486 validate!(w >= 16 && h >= 16);
491 self.use_hpel = br.read_bool()?;
492 self.use_tpel = br.read_bool()?;
497 self.no_bframes = br.read_bool()?;
499 while br.read_bool()? {
502 self.protected = br.read_bool()?;
503 //println!(" seq: {}x{} hpel {} tpel {} nob {}", w, h, self.use_hpel, self.use_tpel, self.no_bframes);
509 fn prepare_slice_buffer(&mut self, src: &[u8]) -> DecoderResult<usize> {
510 let llen = ((src[0] >> 5) & 3) as usize;
511 validate!(llen != 0);
512 validate!(src.len() > llen);
513 let length = match llen {
514 1 => src[1] as usize,
515 2 => (src[1] as usize) * 256 + (src[2] as usize),
516 3 => ((src[1] as usize) << 16) + ((src[2] as usize) << 8) + (src[3] as usize),
519 let slice_len = length + llen + 1;
520 validate!(src.len() >= slice_len);
521 self.slice_buf.clear();
523 self.slice_buf.extend_from_slice(&src[slice_len - llen + 1..][..llen - 1]);
525 self.slice_buf.extend_from_slice(&src[llen + 1..][..slice_len - llen - 1]);
529 fn parse_slice_header(&self, br: &mut BitReader, slice_mode: u8) -> DecoderResult<SVQ3Header> {
530 let ftype_id = br.read_code(UintCodeType::Gamma)? as usize;
531 validate!(ftype_id < FRAME_TYPES.len());
532 let ftype = FRAME_TYPES[ftype_id];
534 validate!(ftype != FrameType::B);
540 let mbs = self.mb_w * self.mb_h;
541 let mb_bits = if mbs < 64 { 6 } else { 32 - (mbs - 1).leading_zeros() } as u8;
542 let _offset = br.read(mb_bits)?;
543 //println!("slice offset {}", _offset);
545 let ts = br.read(8)? as u8;
546 let quant = br.read(5)? as u8;
547 let dquant = br.read_bool()?;
554 while br.read_bool()? {
558 Ok(SVQ3Header { ftype, ts, quant, dquant })
560 fn decode_intra_block(&mut self, br: &mut BitReader, mb_type: usize, sstate: &mut SState, hdr: &SVQ3Header) -> DecoderResult<()> {
561 const INTRA_CBP: [u8; 48] = [
562 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
563 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
564 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41
566 let is_4x4 = mb_type == 8 || mb_type == 33;
569 let angle = SVQ3_INTRA_ANGLE[(mb_type - 9) & 3];
570 cbp = SVQ3_INTRA_CBP[(mb_type - 9) / 4];
571 self.imode.i16_pred = angle;
572 self.imode.fill_block(2);
573 } else if mb_type == 8 {
575 let idx = br.read_code(UintCodeType::Gamma)? as usize;
576 validate!(idx < SVQ3_INTRA4_PAIRS.len());
577 let mut iidx = self.imode.cache.xpos;
578 if (i & 1) != 0 { iidx += self.imode.cache.stride; }
579 if (i & 2) != 0 { iidx += 2; }
580 if (i & 4) != 0 { iidx += self.imode.cache.stride * 2; }
582 let t0 = self.imode.cache.data[iidx - self.imode.cache.stride];
583 let t1 = self.imode.cache.data[iidx + 1 - self.imode.cache.stride];
584 let l0 = self.imode.cache.data[iidx - 1];
586 let p = SVQ3_INTRA4_PAIRS[idx];
587 self.imode.cache.data[iidx] = SVQ3_INTRA4_CTX_PRED[(t0 + 1) as usize][(l0 + 1) as usize][p[0] as usize];
588 let l1 = self.imode.cache.data[iidx];
589 self.imode.cache.data[iidx + 1] = SVQ3_INTRA4_CTX_PRED[(t1 + 1) as usize][(l1 + 1) as usize][p[1] as usize];
590 validate!(self.imode.cache.data[iidx] != -1);
591 validate!(self.imode.cache.data[iidx + 1] != -1);
593 let idx = br.read_code(UintCodeType::Gamma)? as usize;
594 validate!(idx < INTRA_CBP.len());
595 cbp = INTRA_CBP[idx];
596 self.imode.i16_pred = 0;
598 self.imode.fill_block(2);
602 if !is_4x4 || (hdr.dquant && hdr.ftype != FrameType::I && cbp != 0) {
603 let dq = br.read_code_signed(IntCodeType::Gamma)?;
604 let new_q = i32::from(sstate.q) + dq;
605 validate!((0..32).contains(&new_q));
606 sstate.q = new_q as u8;
609 decode_block(br, &mut self.coeffs[24], 0, false)?;
610 idct_dc_coeffs(&mut self.coeffs[24], sstate.q);
612 let start = if is_4x4 { 0 } else { 1 };
613 let alt = sstate.q < 24 && is_4x4;
615 if ((cbp >> sb) & 1) == 0 { continue; }
617 let blk_idx = if is_4x4 {
618 (sb & 1) * 2 + (sb >> 1) * 8 + (b & 1) + (b >> 1) * 4
622 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], start, alt)?;
623 if is_4x4 && self.coded[blk_idx] {
624 idct_dc_coeffs(&mut self.coeffs[blk_idx], sstate.q);
629 for blk_idx in 0..16 {
630 self.coeffs[blk_idx][0] = self.coeffs[24][blk_idx];
631 self.dc_only[blk_idx] = self.coeffs[blk_idx][0] != 0;
632 idct(&mut self.coeffs[blk_idx], sstate.q, false);
635 if (cbp & 0x30) != 0 {
636 let mut u_dc = decode_chroma_dc(br)?;
637 let mut v_dc = decode_chroma_dc(br)?;
638 chroma_transform(&mut u_dc);
639 chroma_transform(&mut v_dc);
641 let cdcs = [u_dc, v_dc];
642 if (cbp & 0x20) != 0 {
645 let blk_idx = 16 + comp * 4 + i;
646 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 1, false)?;
652 let blk_idx = 16 + comp * 4 + i;
653 self.coeffs[blk_idx][0] = cdcs[comp][i];
654 self.dc_only[blk_idx] = cdcs[comp][i] != 0;
655 idct(&mut self.coeffs[blk_idx], SVQ3_CHROMA_QUANT[sstate.q as usize], true);
662 fn do_mc_p(&mut self, br: &mut BitReader, mb_type: usize, sstate: &mut SState, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
664 self.mvi.fill(self.mb_x, self.mb_y, true, ZERO_MV);
665 if let Some(ref_frm) = self.ipbs.get_lastref() {
666 mc_part(dframe, ref_frm, &mut self.ebuf, self.mb_x * 16, self.mb_y * 16, 4, 4, ZERO_MV, 0, HALFPEL_INTERP_FUNCS);
670 let mc_mode = if self.use_tpel && br.read_bool()? != self.use_hpel {
672 } else if self.use_hpel && br.read_bool()? != self.use_tpel {
677 let (bw, bh) = SVQ3_PART_SIZES[mb_type as usize];
678 let bw = (bw >> 2) as usize;
679 let bh = (bh >> 2) as usize;
681 let mut avail = [false; 6 * 5];
682 avail[0] = sstate.has_tl;
689 avail[5] = sstate.has_tr;
697 let dir = true; //forward
698 for y in (0..16).step_by(bh * 4) {
699 for x in (0..16).step_by(bw * 4) {
702 let xpos = self.mb_x * 16 + x;
703 let ypos = self.mb_y * 16 + y;
705 let avail_idx = mv_x + 1 + (mv_y + 1) * 6;
706 let mut pred_mv = self.mvi.pred_mv_part(self.mb_x * 4 + mv_x, self.mb_y * 4 + mv_y, bw, dir, avail[avail_idx - 6], avail[avail_idx - 1], avail[avail_idx - 6 + bw], avail[avail_idx - 6 - 1]);
707 pred_mv.x = pred_mv.x.max(-6 * (xpos as i16)).min(6 * ((((self.width + 15) & !15) - xpos - bw * 4) as i16));
708 pred_mv.y = pred_mv.y.max(-6 * (ypos as i16)).min(6 * ((((self.height + 15) & !15) - ypos - bh * 4) as i16));
712 avail[avail_idx + i + j * 6] = true;
716 let dmv = read_mv(br)?;
717 let (mv, mode, ifuncs) = add_mv(pred_mv, dmv, mc_mode);
718 self.mvi.fill_part(self.mb_x * 4 + mv_x, self.mb_y * 4 + mv_y, dir, bw, bh, mv);
719 if let Some(ref_frm) = self.ipbs.get_lastref() {
720 mc_part(dframe, ref_frm, &mut self.ebuf, xpos, ypos, bw, bh, mv, mode, ifuncs);
726 fn do_mc_direct(&mut self, sstate: &mut SState, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
727 let mut ref_mbt = self.mbtypes[self.mb_x + self.mb_y * self.mb_w];
731 let (bw, bh) = SVQ3_PART_SIZES[ref_mbt as usize];
732 let bw = (bw >> 2) as usize;
733 let bh = (bh >> 2) as usize;
734 let mut aframe = NASimpleVideoFrame::from_video_buf(&mut self.avg_buf).unwrap();
735 if let (Some(fwd_ref), Some(bwd_ref)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) {
736 for y in (0..16).step_by(bh * 4) {
737 for x in (0..16).step_by(bw * 4) {
738 let mv = self.ref_mvi.get_mv(self.mb_x * 4 + x / 4, self.mb_y * 4 + y / 4, true);
739 let (fwd_pred, bwd_pred) = scale_mv(mv, sstate.trb, sstate.trd);
740 let (fmv, fmode, _) = add_mv(fwd_pred, ZERO_MV, MCMode::Halfpel);
741 let (bmv, bmode, _) = add_mv(bwd_pred, ZERO_MV, MCMode::Halfpel);
742 self.mvi.fill_part(self.mb_x * 4 + x / 4, self.mb_y * 4 + y / 4, true, bw, bh, fmv);
743 self.mvi.fill_part(self.mb_x * 4 + x / 4, self.mb_y * 4 + y / 4, false, bw, bh, bmv);
745 let xoff = self.mb_x * 16 + x;
746 let yoff = self.mb_y * 16 + y;
747 mc_part(dframe, fwd_ref.clone(), &mut self.ebuf, xoff, yoff, bw, bh, fmv, fmode, HALFPEL_INTERP_FUNCS);
749 let amv = MV { x: bmv.x + (xoff as i16) * 6, y: bmv.y + (yoff as i16) * 6 };
750 mc_part(&mut aframe, bwd_ref.clone(), &mut self.ebuf, 0, 0, bw, bh, amv, bmode, HALFPEL_INTERP_FUNCS);
752 let dstride = dframe.stride[0];
753 let dst = &mut dframe.data[dframe.offset[0] + xoff + yoff * dstride..];
754 let src = &aframe.data;
755 let sstride = aframe.stride[0];
756 avg(dst, dstride, src, sstride, bw * 4, bh * 4);
758 let dstride = dframe.stride[1];
759 let dst = &mut dframe.data[dframe.offset[1] + xoff / 2 + yoff / 2 * dstride..];
760 let sstride = aframe.stride[1];
761 avg(dst, dstride, &src[aframe.offset[1]..], sstride, bw * 2, bh * 2);
763 let dstride = dframe.stride[2];
764 let dst = &mut dframe.data[dframe.offset[2] + xoff / 2 + yoff / 2 * dstride..];
765 let sstride = aframe.stride[2];
766 avg(dst, dstride, &src[aframe.offset[2]..], sstride, bw * 2, bh * 2);
772 fn do_mc_b(&mut self, br: &mut BitReader, mb_type: usize, sstate: &mut SState, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
773 let mc_mode = if self.use_tpel && br.read_bool()? != self.use_hpel {
775 } else if self.use_hpel && br.read_bool()? != self.use_tpel {
780 let fwd_pred = self.mvi.pred_mv_part(self.mb_x * 4, self.mb_y * 4, 4, true, sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl);
781 let bwd_pred = self.mvi.pred_mv_part(self.mb_x * 4, self.mb_y * 4, 4, false, sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl);
782 let (fdmv, bdmv) = match mb_type {
784 let dmv = read_mv(br)?;
788 let dmv = read_mv(br)?;
792 let fdmv = read_mv(br)?;
793 let bdmv = read_mv(br)?;
798 let (fmv, fmode, ifuncs) = add_mv(fwd_pred, fdmv, mc_mode);
799 let (bmv, bmode, _) = add_mv(bwd_pred, bdmv, mc_mode);
800 let has_fwd = mb_type != 2;
801 let has_bwd = mb_type != 1;
803 self.mvi.fill(self.mb_x, self.mb_y, true, fmv);
806 self.mvi.fill(self.mb_x, self.mb_y, false, bmv);
808 let refframe = if has_fwd { self.ipbs.get_b_fwdref() } else { self.ipbs.get_b_bwdref() };
809 if let Some(ref_buf) = refframe {
810 let (mv, mode) = if has_fwd { (fmv, fmode) } else { (bmv, bmode) };
811 mc_part(dframe, ref_buf, &mut self.ebuf, self.mb_x * 16, self.mb_y * 16, 4, 4, mv, mode, ifuncs);
813 if let (Some(bwd_ref), true, true) = (self.ipbs.get_b_bwdref(), has_fwd, has_bwd) {
814 let mut aframe = NASimpleVideoFrame::from_video_buf(&mut self.avg_buf).unwrap();
815 let amv = MV { x: bmv.x + (self.mb_x as i16) * 16 * 6, y: bmv.y + (self.mb_y as i16) * 16 * 6 };
816 mc_part(&mut aframe, bwd_ref, &mut self.ebuf, 0, 0, 4, 4, amv, bmode, ifuncs);
818 let dstride = dframe.stride[0];
819 let dst = &mut dframe.data[dframe.offset[0] + self.mb_x * 16 + self.mb_y * 16 * dstride..];
820 let src = self.avg_buf.get_data();
821 let sstride = self.avg_buf.get_stride(0);
822 avg(dst, dstride, src, sstride, 16, 16);
824 let dstride = dframe.stride[1];
825 let dst = &mut dframe.data[dframe.offset[1] + self.mb_x * 8 + self.mb_y * 8 * dstride..];
826 let sstride = self.avg_buf.get_stride(1);
827 avg(dst, dstride, &src[self.avg_buf.get_offset(1)..], sstride, 8, 8);
829 let dstride = dframe.stride[2];
830 let dst = &mut dframe.data[dframe.offset[2] + self.mb_x * 8 + self.mb_y * 8 * dstride..];
831 let sstride = self.avg_buf.get_stride(2);
832 avg(dst, dstride, &src[self.avg_buf.get_offset(2)..], sstride, 8, 8);
836 fn decode_inter_block(&mut self, br: &mut BitReader, mb_type: usize, sstate: &mut SState, hdr: &SVQ3Header, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
837 const INTER_CBP: [u8; 48] = [
838 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
839 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
840 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
842 if hdr.ftype == FrameType::P {
843 self.do_mc_p(br, mb_type, sstate, dframe)?;
847 } else if mb_type != 0 {
848 self.do_mc_b(br, mb_type, sstate, dframe)?;
850 self.do_mc_direct(sstate, dframe)?;
853 let idx = br.read_code(UintCodeType::Gamma)? as usize;
854 validate!(idx < INTER_CBP.len());
855 let cbp = INTER_CBP[idx];
857 if hdr.dquant && cbp != 0 {
858 let dq = br.read_code_signed(IntCodeType::Gamma)?;
859 let new_q = i32::from(sstate.q) + dq;
860 validate!((0..32).contains(&new_q));
861 sstate.q = new_q as u8;
864 if ((cbp >> sb) & 1) == 0 { continue; }
866 let blk_idx = (sb & 1) * 2 + (sb >> 1) * 8 + (b & 1) + (b >> 1) * 4;
867 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 0, false)?;
868 if self.coded[blk_idx] {
869 idct_dc_coeffs(&mut self.coeffs[blk_idx], sstate.q);
873 if (cbp & 0x30) != 0 {
874 let mut u_dc = decode_chroma_dc(br)?;
875 let mut v_dc = decode_chroma_dc(br)?;
876 chroma_transform(&mut u_dc);
877 chroma_transform(&mut v_dc);
879 let cdcs = [u_dc, v_dc];
880 if (cbp & 0x20) != 0 {
883 let blk_idx = 16 + comp * 4 + i;
884 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 1, false)?;
890 let blk_idx = 16 + comp * 4 + i;
891 self.coeffs[blk_idx][0] = cdcs[comp][i];
892 self.dc_only[blk_idx] = cdcs[comp][i] != 0;
893 idct(&mut self.coeffs[blk_idx], SVQ3_CHROMA_QUANT[sstate.q as usize], true);
900 fn put_intra4x4(&self, dframe: &mut NASimpleVideoFrame<u8>, sstate: &SState) {
901 let dst = &mut dframe.data[0..];
902 let stride = dframe.stride[0];
903 let mut doff = dframe.offset[0] + self.mb_x * 16 + self.mb_y * 16 * stride;
906 let im = self.imode.get_pred4_type(x, y, sstate.has_top, sstate.has_left);
907 let noright = (self.mb_x == self.mb_w - 1) && (x == 3);
908 let has_top = sstate.has_top || (y > 0);
909 let topright: [u8; 4] = if (noright && sstate.has_top && y == 0) || (x == 3 && y > 0) {
910 let i = doff + x * 4 - stride;
911 [dst[i + 3], dst[i + 3], dst[i + 3], dst[i + 3]]
913 let i = doff + x * 4 - stride;
914 [dst[i + 4], dst[i + 5], dst[i + 6], dst[i + 7]]
918 IPRED_FUNCS4X4[im as usize](dst, doff + x * 4, stride, &topright);
919 let blk_idx = x + y * 4;
920 if self.dc_only[blk_idx] || self.coded[blk_idx] {
921 add_coeffs(dst, doff + x * 4, stride, &self.coeffs[blk_idx]);
926 let im8 = self.imode.get_pred8_type(sstate.has_top, sstate.has_left);
928 let stride = dframe.stride[comp];
929 let mut doff = dframe.offset[comp] + self.mb_x * 8 + self.mb_y * 8 * stride;
930 IPRED_FUNCS8X8[im8 as usize](dst, doff, stride);
933 let blk_idx = 16 + (comp - 1) * 4 + x + y * 2;
934 if self.dc_only[blk_idx] || self.coded[blk_idx] {
935 add_coeffs(dst, doff + x * 4, stride, &self.coeffs[blk_idx]);
942 fn put_residue(&self, dframe: &mut NASimpleVideoFrame<u8>) {
943 let dst = &mut dframe.data[0..];
944 let stride = dframe.stride[0];
945 let mut doff = dframe.offset[0] + self.mb_x * 16 + self.mb_y * 16 * stride;
948 let blk_idx = x + y * 4;
949 if self.dc_only[blk_idx] || self.coded[blk_idx] {
950 add_coeffs(dst, doff + x * 4, stride, &self.coeffs[blk_idx]);
956 let stride = dframe.stride[comp];
957 let mut doff = dframe.offset[comp] + self.mb_x * 8 + self.mb_y * 8 * stride;
960 let blk_idx = 16 + (comp - 1) * 4 + x + y * 2;
961 if self.dc_only[blk_idx] || self.coded[blk_idx] {
962 add_coeffs(dst, doff + x * 4, stride, &self.coeffs[blk_idx]);
969 fn decode_slice(&mut self, br: &mut BitReader, hdr: &SVQ3Header, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
970 let mut mb_idx = self.mb_x + self.mb_y * self.mb_w;
971 let mbs = self.mb_w * self.mb_h;
972 let mut sstate = SState::default();
973 sstate.q = hdr.quant;
974 if hdr.ftype == FrameType::B {
975 sstate.trd = self.ts_bwd.wrapping_sub(self.ts_fwd).max(1);
976 sstate.trb = hdr.ts.wrapping_sub(self.ts_fwd).max(1);
978 let start_idx = mb_idx;
981 sstate.has_top = mb_idx - start_idx >= self.mb_w;
983 sstate.has_tl = sstate.has_left && mb_idx - start_idx + 1 > self.mb_w;
984 sstate.has_tr = self.mb_x + 1 < self.mb_w && mb_idx - start_idx >= self.mb_w - 1;
986 sstate.has_tl = false;
987 sstate.has_tr = false;
991 if (br.tell() & 7) == 0 && br.peek(8) == 0 {
995 let mut mb_type = br.read_code(UintCodeType::Gamma)? as usize;
996 if hdr.ftype == FrameType::I {
999 if hdr.ftype == FrameType::B && mb_type >= 4 {
1002 validate!(mb_type <= 33);
1003 self.imode.set_mb_x(self.mb_x);
1004 self.coeffs = [[0; 16]; 25];
1005 self.coded = [false; 24];
1006 self.dc_only = [false; 24];
1007 if hdr.ftype != FrameType::B {
1008 self.mbtypes[mb_idx] = mb_type as u8;
1011 validate!(hdr.ftype != FrameType::I);
1012 self.imode.fill_block(2);
1013 self.decode_inter_block(br, mb_type, &mut sstate, hdr, dframe)?;
1014 self.put_residue(dframe);
1016 self.decode_intra_block(br, mb_type, &mut sstate, hdr)?;
1017 let is_4x4 = mb_type == 8 || mb_type == 33;
1019 self.put_intra4x4(dframe, &sstate);
1021 let im16 = self.imode.get_pred16_type(sstate.has_top, sstate.has_left);
1022 let stride = dframe.stride[0];
1023 let doff = dframe.offset[0] + self.mb_x * 16 + self.mb_y * 16 * stride;
1024 IPRED_FUNCS16X16[im16 as usize](dframe.data, doff, stride);
1025 let im8 = self.imode.get_pred8_type(sstate.has_top, sstate.has_left);
1027 let stride = dframe.stride[comp];
1028 let doff = dframe.offset[comp] + self.mb_x * 8 + self.mb_y * 8 * stride;
1029 IPRED_FUNCS8X8[im8 as usize](dframe.data, doff, stride);
1031 self.put_residue(dframe);
1033 self.mvi.fill(self.mb_x, self.mb_y, true, ZERO_MV);
1034 self.mvi.fill(self.mb_x, self.mb_y, false, ZERO_MV);
1036 sstate.has_left = true;
1038 if self.mb_x == self.mb_w {
1041 sstate.has_left = false;
1042 self.imode.update();
1050 const FRAME_SIZES: [(usize, usize); 7] = [
1051 (160, 120), (128, 96), (176, 144), (352, 288),
1052 (704, 576), (240, 180), (320, 240)
1054 const FRAME_TYPES: [FrameType; 3] = [ FrameType::P, FrameType::B, FrameType::I ];
1056 impl NADecoder for SVQ3Decoder {
1057 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
1058 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
1059 self.width = vinfo.get_width();
1060 self.height = vinfo.get_height();
1061 if let Some(ref edata) = info.get_extradata() {
1062 let mut start = edata.len();
1063 for i in 0..edata.len() - 9 {
1064 if &edata[i..][..4] == b"SEQH" {
1065 let size = read_u32be(&edata[i + 4..])? as usize;
1066 validate!(i + 8 + size <= edata.len());
1071 if start < edata.len() {
1072 self.parse_sequence_header(&edata[start..])?;
1074 return Err(DecoderError::InvalidData);
1077 return Err(DecoderError::InvalidData);
1079 let myinfo = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
1080 self.info = NACodecInfo::new_ref(info.get_name(), NACodecTypeInfo::Video(myinfo), info.get_extradata()).into_ref();
1081 supp.pool_u8.set_dec_bufs(3);
1082 supp.pool_u8.prealloc_video(myinfo, 4)?;
1084 self.mb_w = (self.width + 15) >> 4;
1085 self.mb_h = (self.height + 15) >> 4;
1086 self.imode = IntraModeState::new(self.mb_w);
1090 Err(DecoderError::InvalidData)
1093 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1094 let src = pkt.get_buffer();
1095 validate!(src.len() > 0);
1098 validate!(src[0] == 0xFF);
1099 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
1100 frm.set_keyframe(false);
1101 frm.set_frame_type(FrameType::Skip);
1102 return Ok(frm.into_ref());
1105 let slice_mode = src[0] & 0x9F;
1106 validate!(slice_mode == 1 || slice_mode == 2);
1107 let mut slice_len = self.prepare_slice_buffer(src.as_slice())?;
1109 let mut br = BitReader::new(&self.slice_buf, BitReaderMode::BE);
1110 let frame_hdr = self.parse_slice_header(&mut br, slice_mode)?;
1112 let ret = supp.pool_u8.get_free();
1114 return Err(DecoderError::AllocError);
1117 let mut buf = ret.unwrap();
1118 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
1120 match frame_hdr.ftype {
1124 if self.ipbs.get_lastref().is_none() {
1125 return Err(DecoderError::MissingReference);
1129 if self.ipbs.get_b_fwdref().is_none() || self.ipbs.get_b_bwdref().is_none() {
1130 return Err(DecoderError::MissingReference);
1134 _ => unreachable!(),
1140 self.mvi.resize(self.mb_w, self.mb_h);
1141 if frame_hdr.ftype != FrameType::B {
1142 self.mbtypes.resize(self.mb_w * self.mb_h, 0);
1145 let mut slice_prepared = true;
1147 while off < src.len() {
1148 if src[off] == 0xFF { break; }
1150 let slice_mode = src[off] & 0x9F;
1151 validate!(slice_mode == 1 || slice_mode == 2);
1152 if !slice_prepared {
1153 slice_len = self.prepare_slice_buffer(&src[off..])?;
1155 let mut sbuf = Vec::new();
1156 std::mem::swap(&mut sbuf, &mut self.slice_buf);
1157 let mut br = BitReader::new(sbuf.as_slice(), BitReaderMode::BE);
1158 let ret = self.parse_slice_header(&mut br, slice_mode);
1159 if let Err(err) = ret {
1160 std::mem::swap(&mut sbuf, &mut self.slice_buf);
1163 let hdr = ret.unwrap();
1164 if hdr.ftype != frame_hdr.ftype || hdr.ts != frame_hdr.ts {
1165 std::mem::swap(&mut sbuf, &mut self.slice_buf);
1166 return Err(DecoderError::InvalidData);
1168 let ret = self.decode_slice(&mut br, &hdr, &mut dframe);
1169 std::mem::swap(&mut sbuf, &mut self.slice_buf);
1170 if let Err(err) = ret {
1173 slice_prepared = false;
1177 validate!(self.mb_x == 0 && self.mb_y == self.mb_h);
1179 if frame_hdr.ftype != FrameType::B {
1180 self.ipbs.add_frame(buf.clone());
1181 std::mem::swap(&mut self.mvi, &mut self.ref_mvi);
1182 self.ts_fwd = self.ts_bwd;
1183 self.ts_bwd = frame_hdr.ts;
1185 self.pts_base = pkt.get_pts().unwrap_or(0);
1186 self.ts_base = frame_hdr.ts;
1189 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
1190 frm.set_keyframe(frame_hdr.ftype == FrameType::I);
1191 frm.set_frame_type(frame_hdr.ftype);
1192 if !self.no_bframes && frm.get_pts().is_some() {
1193 let pts = self.pts_base - u64::from(self.ts_base.wrapping_sub(frame_hdr.ts));
1194 frm.set_pts(Some(pts));
1198 fn flush(&mut self) {
1205 impl NAOptionHandler for SVQ3Decoder {
1206 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1207 fn set_options(&mut self, _options: &[NAOption]) { }
1208 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1211 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
1212 Box::new(SVQ3Decoder::new())
1217 use nihav_core::codecs::RegisteredDecoders;
1218 use nihav_core::demuxers::RegisteredDemuxers;
1219 use nihav_codec_support::test::dec_video::*;
1220 use crate::qt_register_all_decoders;
1221 use nihav_commonfmt::generic_register_all_demuxers;
1224 let mut dmx_reg = RegisteredDemuxers::new();
1225 generic_register_all_demuxers(&mut dmx_reg);
1226 let mut dec_reg = RegisteredDecoders::new();
1227 qt_register_all_decoders(&mut dec_reg);
1229 //let file = "assets/QT/cristinreel.mov";
1230 //let file = "assets/QT/broken_sword_Large.mov";
1231 //test_file_decoding("mov", file, Some(264), true, false, Some("svq3"), &dmx_reg, &dec_reg);
1233 // sample: https://samples.mplayerhq.hu/V-codecs/SVQ3/broken_sword_Large.mov
1234 test_decoding("mov", "sorenson-video3", "assets/QT/broken_sword_Large.mov", Some(40), &dmx_reg, &dec_reg,
1235 ExpectedTestResult::MD5Frames(vec![
1236 [0x16924d18, 0xccc5a0b4, 0xc2bb9412, 0x93d41f10],
1237 [0x84cccf62, 0x0762a61c, 0xe0b1d369, 0x211f066e],
1238 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1239 [0x8f9e157e, 0xb61f5864, 0x49cc29a7, 0xa2b648a4],
1240 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1241 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1242 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1243 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1244 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1245 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1246 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1247 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1248 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1249 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1250 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1251 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1252 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1253 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1254 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1255 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1256 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1257 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1258 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1259 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1260 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1261 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1262 [0xad96c999, 0x89bfe564, 0x476f918a, 0xf89bb023],
1263 [0x1f40cce7, 0xcccc68b3, 0x2a0b28b1, 0x3210675c],
1264 [0x3165e832, 0xcb7dad5b, 0x295983fa, 0x270acdcd],
1265 [0x54b88d2a, 0x97c5ad60, 0x9cca1823, 0x458566e6],
1266 [0xbdd02a56, 0x7ee24530, 0x32262d19, 0x2f3c8237],
1267 [0x4e898806, 0x85fb7504, 0x19da4747, 0x00c55a0e],
1268 [0x5899e1f5, 0x667fbc86, 0xcbeeff49, 0x6ac996b9],
1269 [0x1b640dd6, 0xa999c0f6, 0x57cb9bed, 0xf0265669],
1270 [0x3cee4540, 0x35ce897b, 0x9db825aa, 0xd6204c2c],
1271 [0x459bfa2f, 0x451555e6, 0x08681f32, 0xf56cdc05],
1272 [0x78018c23, 0x333f1892, 0xabab4889, 0x3e3cf020],
1273 [0x2a24d296, 0xc572a5fe, 0x0af6a85a, 0x5721bfc4],
1274 [0xdf354969, 0xfbf01155, 0xa1e6d53a, 0x49334823],
1275 [0x5e493eb2, 0xc92258b8, 0xcec5e684, 0x92bd0f3c],
1276 [0x5bf8ea79, 0xb363c077, 0x05c461a3, 0xa065da2c]]));
1280 const SVQ3_INTRA_ANGLE: [i8; 4] = [ 0, 2, 1, 3 ];
1281 const SVQ3_INTRA_CBP: [u8; 6] = [ 0x00, 0x10, 0x20, 0x0F, 0x1F, 0x2F ];
1283 const SVQ3_INTRA4_PAIRS: [[u8; 2]; 25] = [
1286 [ 0, 2 ], [ 1, 1 ], [ 2, 0 ],
1287 [ 3, 0 ], [ 2, 1 ], [ 1, 2 ], [ 0, 3 ],
1288 [ 0, 4 ], [ 1, 3 ], [ 2, 2 ], [ 3, 1 ], [ 4, 0 ],
1289 [ 4, 1 ], [ 3, 2 ], [ 2, 3 ], [ 1, 4 ],
1290 [ 2, 4 ], [ 3, 3 ], [ 4, 2 ],
1295 const SVQ3_INTRA4_CTX_PRED: [[[i8; 5]; 6]; 6] = [
1297 [ 2, -1, -1, -1, -1 ], [ 2, 1, -1, -1, -1 ], [ 1, 2, -1, -1, -1 ],
1298 [ 2, 1, -1, -1, -1 ], [ 1, 2, -1, -1, -1 ], [ 1, 2, -1, -1, -1 ]
1300 [ 0, 2, -1, -1, -1 ], [ 0, 2, 1, 4, 3 ], [ 0, 1, 2, 4, 3 ],
1301 [ 0, 2, 1, 4, 3 ], [ 2, 0, 1, 3, 4 ], [ 0, 4, 2, 1, 3 ]
1303 [ 2, 0, -1, -1, -1 ], [ 2, 1, 0, 4, 3 ], [ 1, 2, 4, 0, 3 ],
1304 [ 2, 1, 0, 4, 3 ], [ 2, 1, 4, 3, 0 ], [ 1, 2, 4, 0, 3 ]
1306 [ 2, 0, -1, -1, -1 ], [ 2, 0, 1, 4, 3 ], [ 1, 2, 0, 4, 3 ],
1307 [ 2, 1, 0, 4, 3 ], [ 2, 1, 3, 4, 0 ], [ 2, 4, 1, 0, 3 ]
1309 [ 0, 2, -1, -1, -1 ], [ 0, 2, 1, 3, 4 ], [ 1, 2, 3, 0, 4 ],
1310 [ 2, 0, 1, 3, 4 ], [ 2, 1, 3, 0, 4 ], [ 2, 0, 4, 3, 1 ]
1312 [ 0, 2, -1, -1, -1 ], [ 0, 2, 4, 1, 3 ], [ 1, 4, 2, 0, 3 ],
1313 [ 4, 2, 0, 1, 3 ], [ 2, 0, 1, 4, 3 ], [ 4, 2, 1, 0, 3 ]
1317 const SVQ3_PART_SIZES: [(u8, u8); 8] = [
1318 (16, 16), (16, 16), (8, 16), (16, 8), (8, 8), (4, 8), (8, 4), (4, 4)
1321 const SVQ3_CHROMA_QUANT: [u8; 32] = [
1322 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1323 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25