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.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.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) = match val {
320 0..=2 => (0, val as i16),
322 _ => ((val & 3) as usize, (((val + 9) >> 2) - (val & 3)) as i16)
325 validate!(idx < blk.len());
326 blk[idx] = if sign { -level } else { level };
329 if idx == blk.len() {
330 let val = br.read_code(UintCodeType::Gamma)?;
336 fn read_mv(br: &mut BitReader) -> DecoderResult<MV> {
337 let y = br.read_code_signed(IntCodeType::Gamma)? as i16;
338 let x = br.read_code_signed(IntCodeType::Gamma)? as i16;
342 fn div6(val: i16) -> i16 {
343 (((((i32::from(val) + (6 << 16)) as u32) / 6) as i32) - (1 << 16)) as i16
346 fn scale_mv(mv: MV, trb: u8, trd: u8) -> (MV, MV) {
347 let trb = i32::from(trb);
348 let trd = i32::from(trd);
349 let fx = (i32::from(mv.x * 2) * trb / trd + 1) >> 1;
350 let fy = (i32::from(mv.y * 2) * trb / trd + 1) >> 1;
351 let bx = (i32::from(mv.x * 2) * (trb - trd) / trd + 1) >> 1;
352 let by = (i32::from(mv.y * 2) * (trb - trd) / trd + 1) >> 1;
353 (MV { x: fx as i16, y: fy as i16 }, MV { x: bx as i16, y: by as i16 })
356 fn add_mv(pred_mv: MV, dmv: MV, mc_mode: MCMode) -> (MV, usize, &'static [BlkInterpFunc]) {
359 let x = div6(pred_mv.x + 3);
360 let y = div6(pred_mv.y + 3);
361 let mut mv = MV{ x, y } + dmv;
364 (mv, 0, HALFPEL_INTERP_FUNCS)
367 let x = div6(pred_mv.x * 2 + 2);
368 let y = div6(pred_mv.y * 2 + 2);
369 let mut mv = MV{ x, y } + dmv;
370 let mode = ((mv.x & 1) + (mv.y & 1) * 2) as usize;
373 (mv, mode, HALFPEL_INTERP_FUNCS)
375 MCMode::Thirdpel => {
376 let x = (pred_mv.x + 1) >> 1;
377 let y = (pred_mv.y + 1) >> 1;
378 let mut mv = MV{ x, y } + dmv;
379 let mut mx = mv.x % 3;
380 if mx < 0 { mx += 3; }
381 let mut my = mv.y % 3;
382 if my < 0 { my += 3; }
383 let mode = (mx + my * 3) as usize;
386 (mv, mode, THIRDPEL_INTERP_FUNCS)
391 fn copy_block(dst: &mut NASimpleVideoFrame<u8>, src: NAVideoBufferRef<u8>, ebuf: &mut [u8; 32 * 18], comp: usize,
392 dx: usize, dy: usize, mv_x: i16, mv_y: i16, bw: usize, bh: usize,
393 preborder: usize, postborder: usize,
394 mode: usize, interp: &[BlkInterpFunc])
396 let pre = if mode != 0 { preborder as isize } else { 0 };
397 let post = if mode != 0 { postborder as isize } else { 0 };
398 let (w, h) = src.get_dimensions(comp);
399 let sx = (dx as isize) + (mv_x as isize);
400 let sy = (dy as isize) + (mv_y as isize);
402 if (sx - pre < 0) || (sx + (bw as isize) + post > (w as isize)) ||
403 (sy - pre < 0) || (sy + (bh as isize) + post > (h as isize)) {
404 let ebuf_stride: usize = 32;
406 let dstride = dst.stride[comp];
407 let doff = dst.offset[comp];
408 let edge = (pre + post) as usize;
409 edge_emu(&src, sx - pre, sy - pre, bw + edge, bh + edge,
410 ebuf, ebuf_stride, comp, 4);
411 (interp[mode])(&mut dst.data[doff + dx + dy * dstride..], dstride,
412 ebuf, ebuf_stride, bw, bh);
414 let sstride = src.get_stride(comp);
415 let soff = src.get_offset(comp);
416 let sdta = src.get_data();
417 let sbuf: &[u8] = sdta.as_slice();
418 let dstride = dst.stride[comp];
419 let doff = dst.offset[comp];
420 let saddr = soff + ((sx - pre) as usize) + ((sy - pre) as usize) * sstride;
421 (interp[mode])(&mut dst.data[doff + dx + dy * dstride..], dstride,
422 &sbuf[saddr..], sstride, bw, bh);
426 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]) {
429 let cmx = (mx + if mx < 0 { 1 } else { 0 }) >> 1;
430 let cmy = (my + if my < 0 { 1 } else { 0 }) >> 1;
431 let post = if mode != 0 { 1 } else { 0 };
433 copy_block(dframe, src.clone(), ebuf, 0, xoff, yoff, mx, my, bw * 4, bh * 4, 0, post, mode, ifuncs);
434 copy_block(dframe, src.clone(), ebuf, 1, xoff / 2, yoff / 2, cmx, cmy, bw * 2, bh * 2, 0, post, mode, ifuncs);
435 copy_block(dframe, src, ebuf, 2, xoff / 2, yoff / 2, cmx, cmy, bw * 2, bh * 2, 0, post, mode, ifuncs);
440 let tmp_vinfo = NAVideoInfo::new(16, 16, false, YUV420_FORMAT);
441 let vt = alloc_video_buffer(tmp_vinfo, 4).unwrap();
442 let vb = vt.get_vbuf();
443 let avg_buf = vb.unwrap();
446 info: NACodecInfoRef::default(),
449 ipbs: IPBShuffler::new(),
451 imode: IntraModeState::new(0),
453 ref_mvi: MVInfo::new(),
457 coeffs: [[0; 16]; 25],
459 dc_only: [false; 24],
465 slice_buf: Vec::new(),
476 fn parse_sequence_header(&mut self, src: &[u8]) -> DecoderResult<()> {
477 let mut br = BitReader::new(src, BitReaderMode::BE);
478 let fcode = br.read(3)? as usize;
479 let (w, h) = if fcode < FRAME_SIZES.len() {
482 let w = br.read(12)? as usize;
483 let h = br.read(12)? as usize;
484 validate!(w >= 16 && h >= 16);
489 self.use_hpel = br.read_bool()?;
490 self.use_tpel = br.read_bool()?;
495 self.no_bframes = br.read_bool()?;
497 while br.read_bool()? {
500 self.protected = br.read_bool()?;
501 //println!(" seq: {}x{} hpel {} tpel {} nob {}", w, h, self.use_hpel, self.use_tpel, self.no_bframes);
507 fn prepare_slice_buffer(&mut self, src: &[u8]) -> DecoderResult<usize> {
508 let llen = ((src[0] >> 5) & 3) as usize;
509 validate!(llen != 0);
510 validate!(src.len() > llen);
511 let length = match llen {
512 1 => src[1] as usize,
513 2 => (src[1] as usize) * 256 + (src[2] as usize),
514 3 => ((src[1] as usize) << 16) + ((src[2] as usize) << 8) + (src[3] as usize),
517 let slice_len = length + llen + 1;
518 validate!(src.len() >= slice_len);
519 self.slice_buf.clear();
521 self.slice_buf.extend_from_slice(&src[slice_len - llen + 1..][..llen - 1]);
523 self.slice_buf.extend_from_slice(&src[llen + 1..][..slice_len - llen - 1]);
527 fn parse_slice_header(&self, br: &mut BitReader, slice_mode: u8) -> DecoderResult<SVQ3Header> {
528 let ftype_id = br.read_code(UintCodeType::Gamma)? as usize;
529 validate!(ftype_id < FRAME_TYPES.len());
530 let ftype = FRAME_TYPES[ftype_id];
532 validate!(ftype != FrameType::B);
538 let mbs = self.mb_w * self.mb_h;
539 let mb_bits = if mbs < 64 { 6 } else { 32 - (mbs - 1).leading_zeros() } as u8;
540 let _offset = br.read(mb_bits)?;
541 //println!("slice offset {}", _offset);
543 let ts = br.read(8)? as u8;
544 let quant = br.read(5)? as u8;
545 let dquant = br.read_bool()?;
552 while br.read_bool()? {
556 Ok(SVQ3Header { ftype, ts, quant, dquant })
558 fn decode_intra_block(&mut self, br: &mut BitReader, mb_type: usize, sstate: &mut SState, hdr: &SVQ3Header) -> DecoderResult<()> {
559 const INTRA_CBP: [u8; 48] = [
560 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
561 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
562 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41
564 let is_4x4 = mb_type == 8 || mb_type == 33;
567 let angle = SVQ3_INTRA_ANGLE[(mb_type - 9) & 3];
568 cbp = SVQ3_INTRA_CBP[(mb_type - 9) / 4];
569 self.imode.i16_pred = angle;
570 self.imode.fill_block(2);
571 } else if mb_type == 8 {
573 let idx = br.read_code(UintCodeType::Gamma)? as usize;
574 validate!(idx < SVQ3_INTRA4_PAIRS.len());
575 let mut iidx = self.imode.cache.xpos;
576 if (i & 1) != 0 { iidx += self.imode.cache.stride; }
577 if (i & 2) != 0 { iidx += 2; }
578 if (i & 4) != 0 { iidx += self.imode.cache.stride * 2; }
580 let t0 = self.imode.cache.data[iidx - self.imode.cache.stride];
581 let t1 = self.imode.cache.data[iidx + 1 - self.imode.cache.stride];
582 let l0 = self.imode.cache.data[iidx - 1];
584 let p = SVQ3_INTRA4_PAIRS[idx];
585 self.imode.cache.data[iidx] = SVQ3_INTRA4_CTX_PRED[(t0 + 1) as usize][(l0 + 1) as usize][p[0] as usize];
586 let l1 = self.imode.cache.data[iidx];
587 self.imode.cache.data[iidx + 1] = SVQ3_INTRA4_CTX_PRED[(t1 + 1) as usize][(l1 + 1) as usize][p[1] as usize];
588 validate!(self.imode.cache.data[iidx] != -1);
589 validate!(self.imode.cache.data[iidx + 1] != -1);
591 let idx = br.read_code(UintCodeType::Gamma)? as usize;
592 validate!(idx < INTRA_CBP.len());
593 cbp = INTRA_CBP[idx];
594 self.imode.i16_pred = 0;
596 self.imode.fill_block(2);
600 if !is_4x4 || (hdr.dquant && hdr.ftype != FrameType::I && cbp != 0) {
601 let dq = br.read_code_signed(IntCodeType::Gamma)?;
602 let new_q = i32::from(sstate.q) + dq;
603 validate!((0..32).contains(&new_q));
604 sstate.q = new_q as u8;
607 decode_block(br, &mut self.coeffs[24], 0, false)?;
608 idct_dc_coeffs(&mut self.coeffs[24], sstate.q);
610 let start = if is_4x4 { 0 } else { 1 };
611 let alt = sstate.q < 24 && is_4x4;
613 if ((cbp >> sb) & 1) == 0 { continue; }
615 let blk_idx = if is_4x4 {
616 (sb & 1) * 2 + (sb >> 1) * 8 + (b & 1) + (b >> 1) * 4
620 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], start, alt)?;
621 if is_4x4 && self.coded[blk_idx] {
622 idct_dc_coeffs(&mut self.coeffs[blk_idx], sstate.q);
627 for blk_idx in 0..16 {
628 self.coeffs[blk_idx][0] = self.coeffs[24][blk_idx];
629 self.dc_only[blk_idx] = self.coeffs[blk_idx][0] != 0;
630 idct(&mut self.coeffs[blk_idx], sstate.q, false);
633 if (cbp & 0x30) != 0 {
634 let mut u_dc = decode_chroma_dc(br)?;
635 let mut v_dc = decode_chroma_dc(br)?;
636 chroma_transform(&mut u_dc);
637 chroma_transform(&mut v_dc);
639 let cdcs = [u_dc, v_dc];
640 if (cbp & 0x20) != 0 {
643 let blk_idx = 16 + comp * 4 + i;
644 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 1, false)?;
648 for (comp, cdcs) in cdcs.iter().enumerate() {
649 for (i, &c_dc) in cdcs.iter().enumerate() {
650 let blk_idx = 16 + comp * 4 + i;
651 self.coeffs[blk_idx][0] = c_dc;
652 self.dc_only[blk_idx] = c_dc != 0;
653 idct(&mut self.coeffs[blk_idx], SVQ3_CHROMA_QUANT[sstate.q as usize], true);
660 #[allow(clippy::identity_op)]
661 fn do_mc_p(&mut self, br: &mut BitReader, mb_type: usize, sstate: &mut SState, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
663 self.mvi.fill(self.mb_x, self.mb_y, true, ZERO_MV);
664 if let Some(ref_frm) = self.ipbs.get_lastref() {
665 mc_part(dframe, ref_frm, &mut self.ebuf, self.mb_x * 16, self.mb_y * 16, 4, 4, ZERO_MV, 0, HALFPEL_INTERP_FUNCS);
669 let mc_mode = if self.use_tpel && br.read_bool()? != self.use_hpel {
671 } else if self.use_hpel && br.read_bool()? != self.use_tpel {
676 let (bw, bh) = SVQ3_PART_SIZES[mb_type];
677 let bw = (bw >> 2) as usize;
678 let bh = (bh >> 2) as usize;
680 let mut avail = [false; 6 * 5];
681 avail[0] = sstate.has_tl;
688 avail[5] = sstate.has_tr;
696 let dir = true; //forward
697 for y in (0..16).step_by(bh * 4) {
698 for x in (0..16).step_by(bw * 4) {
701 let xpos = self.mb_x * 16 + x;
702 let ypos = self.mb_y * 16 + y;
704 let avail_idx = mv_x + 1 + (mv_y + 1) * 6;
705 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]);
706 pred_mv.x = pred_mv.x.max(-6 * (xpos as i16)).min(6 * ((((self.width + 15) & !15) - xpos - bw * 4) as i16));
707 pred_mv.y = pred_mv.y.max(-6 * (ypos as i16)).min(6 * ((((self.height + 15) & !15) - ypos - bh * 4) as i16));
711 avail[avail_idx + i + j * 6] = true;
715 let dmv = read_mv(br)?;
716 let (mv, mode, ifuncs) = add_mv(pred_mv, dmv, mc_mode);
717 self.mvi.fill_part(self.mb_x * 4 + mv_x, self.mb_y * 4 + mv_y, dir, bw, bh, mv);
718 if let Some(ref_frm) = self.ipbs.get_lastref() {
719 mc_part(dframe, ref_frm, &mut self.ebuf, xpos, ypos, bw, bh, mv, mode, ifuncs);
725 fn do_mc_direct(&mut self, sstate: &mut SState, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
726 let mut ref_mbt = self.mbtypes[self.mb_x + self.mb_y * self.mb_w];
730 let (bw, bh) = SVQ3_PART_SIZES[ref_mbt as usize];
731 let bw = (bw >> 2) as usize;
732 let bh = (bh >> 2) as usize;
733 let mut aframe = NASimpleVideoFrame::from_video_buf(&mut self.avg_buf).unwrap();
734 if let (Some(fwd_ref), Some(bwd_ref)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) {
735 for y in (0..16).step_by(bh * 4) {
736 for x in (0..16).step_by(bw * 4) {
737 let mv = self.ref_mvi.get_mv(self.mb_x * 4 + x / 4, self.mb_y * 4 + y / 4, true);
738 let (fwd_pred, bwd_pred) = scale_mv(mv, sstate.trb, sstate.trd);
739 let (fmv, fmode, _) = add_mv(fwd_pred, ZERO_MV, MCMode::Halfpel);
740 let (bmv, bmode, _) = add_mv(bwd_pred, ZERO_MV, MCMode::Halfpel);
741 self.mvi.fill_part(self.mb_x * 4 + x / 4, self.mb_y * 4 + y / 4, true, bw, bh, fmv);
742 self.mvi.fill_part(self.mb_x * 4 + x / 4, self.mb_y * 4 + y / 4, false, bw, bh, bmv);
744 let xoff = self.mb_x * 16 + x;
745 let yoff = self.mb_y * 16 + y;
746 mc_part(dframe, fwd_ref.clone(), &mut self.ebuf, xoff, yoff, bw, bh, fmv, fmode, HALFPEL_INTERP_FUNCS);
748 let amv = MV { x: bmv.x + (xoff as i16) * 6, y: bmv.y + (yoff as i16) * 6 };
749 mc_part(&mut aframe, bwd_ref.clone(), &mut self.ebuf, 0, 0, bw, bh, amv, bmode, HALFPEL_INTERP_FUNCS);
751 let dstride = dframe.stride[0];
752 let dst = &mut dframe.data[dframe.offset[0] + xoff + yoff * dstride..];
753 let src = &aframe.data;
754 let sstride = aframe.stride[0];
755 avg(dst, dstride, src, sstride, bw * 4, bh * 4);
757 let dstride = dframe.stride[1];
758 let dst = &mut dframe.data[dframe.offset[1] + xoff / 2 + yoff / 2 * dstride..];
759 let sstride = aframe.stride[1];
760 avg(dst, dstride, &src[aframe.offset[1]..], sstride, bw * 2, bh * 2);
762 let dstride = dframe.stride[2];
763 let dst = &mut dframe.data[dframe.offset[2] + xoff / 2 + yoff / 2 * dstride..];
764 let sstride = aframe.stride[2];
765 avg(dst, dstride, &src[aframe.offset[2]..], sstride, bw * 2, bh * 2);
771 fn do_mc_b(&mut self, br: &mut BitReader, mb_type: usize, sstate: &mut SState, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
772 let mc_mode = if self.use_tpel && br.read_bool()? != self.use_hpel {
774 } else if self.use_hpel && br.read_bool()? != self.use_tpel {
779 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);
780 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);
781 let (fdmv, bdmv) = match mb_type {
783 let dmv = read_mv(br)?;
787 let dmv = read_mv(br)?;
791 let fdmv = read_mv(br)?;
792 let bdmv = read_mv(br)?;
797 let (fmv, fmode, ifuncs) = add_mv(fwd_pred, fdmv, mc_mode);
798 let (bmv, bmode, _) = add_mv(bwd_pred, bdmv, mc_mode);
799 let has_fwd = mb_type != 2;
800 let has_bwd = mb_type != 1;
802 self.mvi.fill(self.mb_x, self.mb_y, true, fmv);
805 self.mvi.fill(self.mb_x, self.mb_y, false, bmv);
807 let refframe = if has_fwd { self.ipbs.get_b_fwdref() } else { self.ipbs.get_b_bwdref() };
808 if let Some(ref_buf) = refframe {
809 let (mv, mode) = if has_fwd { (fmv, fmode) } else { (bmv, bmode) };
810 mc_part(dframe, ref_buf, &mut self.ebuf, self.mb_x * 16, self.mb_y * 16, 4, 4, mv, mode, ifuncs);
812 if let (Some(bwd_ref), true, true) = (self.ipbs.get_b_bwdref(), has_fwd, has_bwd) {
813 let mut aframe = NASimpleVideoFrame::from_video_buf(&mut self.avg_buf).unwrap();
814 let amv = MV { x: bmv.x + (self.mb_x as i16) * 16 * 6, y: bmv.y + (self.mb_y as i16) * 16 * 6 };
815 mc_part(&mut aframe, bwd_ref, &mut self.ebuf, 0, 0, 4, 4, amv, bmode, ifuncs);
817 let dstride = dframe.stride[0];
818 let dst = &mut dframe.data[dframe.offset[0] + self.mb_x * 16 + self.mb_y * 16 * dstride..];
819 let src = self.avg_buf.get_data();
820 let sstride = self.avg_buf.get_stride(0);
821 avg(dst, dstride, src, sstride, 16, 16);
823 let dstride = dframe.stride[1];
824 let dst = &mut dframe.data[dframe.offset[1] + self.mb_x * 8 + self.mb_y * 8 * dstride..];
825 let sstride = self.avg_buf.get_stride(1);
826 avg(dst, dstride, &src[self.avg_buf.get_offset(1)..], sstride, 8, 8);
828 let dstride = dframe.stride[2];
829 let dst = &mut dframe.data[dframe.offset[2] + self.mb_x * 8 + self.mb_y * 8 * dstride..];
830 let sstride = self.avg_buf.get_stride(2);
831 avg(dst, dstride, &src[self.avg_buf.get_offset(2)..], sstride, 8, 8);
835 fn decode_inter_block(&mut self, br: &mut BitReader, mb_type: usize, sstate: &mut SState, hdr: &SVQ3Header, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
836 const INTER_CBP: [u8; 48] = [
837 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
838 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
839 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
841 if hdr.ftype == FrameType::P {
842 self.do_mc_p(br, mb_type, sstate, dframe)?;
846 } else if mb_type != 0 {
847 self.do_mc_b(br, mb_type, sstate, dframe)?;
849 self.do_mc_direct(sstate, dframe)?;
852 let idx = br.read_code(UintCodeType::Gamma)? as usize;
853 validate!(idx < INTER_CBP.len());
854 let cbp = INTER_CBP[idx];
856 if hdr.dquant && cbp != 0 {
857 let dq = br.read_code_signed(IntCodeType::Gamma)?;
858 let new_q = i32::from(sstate.q) + dq;
859 validate!((0..32).contains(&new_q));
860 sstate.q = new_q as u8;
863 if ((cbp >> sb) & 1) == 0 { continue; }
865 let blk_idx = (sb & 1) * 2 + (sb >> 1) * 8 + (b & 1) + (b >> 1) * 4;
866 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 0, false)?;
867 if self.coded[blk_idx] {
868 idct_dc_coeffs(&mut self.coeffs[blk_idx], sstate.q);
872 if (cbp & 0x30) != 0 {
873 let mut u_dc = decode_chroma_dc(br)?;
874 let mut v_dc = decode_chroma_dc(br)?;
875 chroma_transform(&mut u_dc);
876 chroma_transform(&mut v_dc);
878 let cdcs = [u_dc, v_dc];
879 if (cbp & 0x20) != 0 {
882 let blk_idx = 16 + comp * 4 + i;
883 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 1, false)?;
887 for (comp, cdcs) in cdcs.iter().enumerate() {
888 for (i, &c_dc) in cdcs.iter().enumerate() {
889 let blk_idx = 16 + comp * 4 + i;
890 self.coeffs[blk_idx][0] = c_dc;
891 self.dc_only[blk_idx] = c_dc != 0;
892 idct(&mut self.coeffs[blk_idx], SVQ3_CHROMA_QUANT[sstate.q as usize], true);
899 fn put_intra4x4(&self, dframe: &mut NASimpleVideoFrame<u8>, sstate: &SState) {
900 let dst = &mut dframe.data[0..];
901 let stride = dframe.stride[0];
902 let mut doff = dframe.offset[0] + self.mb_x * 16 + self.mb_y * 16 * stride;
905 let im = self.imode.get_pred4_type(x, y, sstate.has_top, sstate.has_left);
906 let noright = (self.mb_x == self.mb_w - 1) && (x == 3);
907 let has_top = sstate.has_top || (y > 0);
908 let topright: [u8; 4] = if (noright && sstate.has_top && y == 0) || (x == 3 && y > 0) {
909 let i = doff + x * 4 - stride;
910 [dst[i + 3], dst[i + 3], dst[i + 3], dst[i + 3]]
912 let i = doff + x * 4 - stride;
913 [dst[i + 4], dst[i + 5], dst[i + 6], dst[i + 7]]
917 IPRED_FUNCS4X4[im as usize](dst, doff + x * 4, stride, &topright);
918 let blk_idx = x + y * 4;
919 if self.dc_only[blk_idx] || self.coded[blk_idx] {
920 add_coeffs(dst, doff + x * 4, stride, &self.coeffs[blk_idx]);
925 let im8 = self.imode.get_pred8_type(sstate.has_top, sstate.has_left);
927 let stride = dframe.stride[comp];
928 let mut doff = dframe.offset[comp] + self.mb_x * 8 + self.mb_y * 8 * stride;
929 IPRED_FUNCS8X8[im8 as usize](dst, doff, stride);
932 let blk_idx = 16 + (comp - 1) * 4 + x + y * 2;
933 if self.dc_only[blk_idx] || self.coded[blk_idx] {
934 add_coeffs(dst, doff + x * 4, stride, &self.coeffs[blk_idx]);
941 fn put_residue(&self, dframe: &mut NASimpleVideoFrame<u8>) {
942 let dst = &mut dframe.data[0..];
943 let stride = dframe.stride[0];
944 let mut doff = dframe.offset[0] + self.mb_x * 16 + self.mb_y * 16 * stride;
947 let blk_idx = x + y * 4;
948 if self.dc_only[blk_idx] || self.coded[blk_idx] {
949 add_coeffs(dst, doff + x * 4, stride, &self.coeffs[blk_idx]);
955 let stride = dframe.stride[comp];
956 let mut doff = dframe.offset[comp] + self.mb_x * 8 + self.mb_y * 8 * stride;
959 let blk_idx = 16 + (comp - 1) * 4 + x + y * 2;
960 if self.dc_only[blk_idx] || self.coded[blk_idx] {
961 add_coeffs(dst, doff + x * 4, stride, &self.coeffs[blk_idx]);
968 #[allow(clippy::field_reassign_with_default)]
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;
990 if br.left() < 8 && (br.tell() & 7) == 0 && br.peek(8) == 0 {
993 let mut mb_type = br.read_code(UintCodeType::Gamma)? as usize;
994 if hdr.ftype == FrameType::I {
997 if hdr.ftype == FrameType::B && mb_type >= 4 {
1000 validate!(mb_type <= 33);
1001 self.imode.set_mb_x(self.mb_x);
1002 self.coeffs = [[0; 16]; 25];
1003 self.coded = [false; 24];
1004 self.dc_only = [false; 24];
1005 if hdr.ftype != FrameType::B {
1006 self.mbtypes[mb_idx] = mb_type as u8;
1009 validate!(hdr.ftype != FrameType::I);
1010 self.imode.fill_block(2);
1011 self.decode_inter_block(br, mb_type, &mut sstate, hdr, dframe)?;
1012 self.put_residue(dframe);
1014 self.decode_intra_block(br, mb_type, &mut sstate, hdr)?;
1015 let is_4x4 = mb_type == 8 || mb_type == 33;
1017 self.put_intra4x4(dframe, &sstate);
1019 let im16 = self.imode.get_pred16_type(sstate.has_top, sstate.has_left);
1020 let stride = dframe.stride[0];
1021 let doff = dframe.offset[0] + self.mb_x * 16 + self.mb_y * 16 * stride;
1022 IPRED_FUNCS16X16[im16 as usize](dframe.data, doff, stride);
1023 let im8 = self.imode.get_pred8_type(sstate.has_top, sstate.has_left);
1025 let stride = dframe.stride[comp];
1026 let doff = dframe.offset[comp] + self.mb_x * 8 + self.mb_y * 8 * stride;
1027 IPRED_FUNCS8X8[im8 as usize](dframe.data, doff, stride);
1029 self.put_residue(dframe);
1031 self.mvi.fill(self.mb_x, self.mb_y, true, ZERO_MV);
1032 self.mvi.fill(self.mb_x, self.mb_y, false, ZERO_MV);
1034 sstate.has_left = true;
1036 if self.mb_x == self.mb_w {
1039 sstate.has_left = false;
1040 self.imode.update();
1048 const FRAME_SIZES: [(usize, usize); 7] = [
1049 (160, 120), (128, 96), (176, 144), (352, 288),
1050 (704, 576), (240, 180), (320, 240)
1052 const FRAME_TYPES: [FrameType; 3] = [ FrameType::P, FrameType::B, FrameType::I ];
1054 impl NADecoder for SVQ3Decoder {
1055 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
1056 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
1057 self.width = vinfo.get_width();
1058 self.height = vinfo.get_height();
1059 if let Some(ref edata) = info.get_extradata() {
1060 let mut start = edata.len();
1061 for i in 0..edata.len() - 9 {
1062 if &edata[i..][..4] == b"SEQH" {
1063 let size = read_u32be(&edata[i + 4..])? as usize;
1064 validate!(i + 8 + size <= edata.len());
1069 if start < edata.len() {
1070 self.parse_sequence_header(&edata[start..])?;
1072 return Err(DecoderError::InvalidData);
1075 return Err(DecoderError::InvalidData);
1077 let myinfo = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
1078 self.info = NACodecInfo::new_ref(info.get_name(), NACodecTypeInfo::Video(myinfo), info.get_extradata()).into_ref();
1079 supp.pool_u8.set_dec_bufs(3);
1080 supp.pool_u8.prealloc_video(myinfo, 4)?;
1082 self.mb_w = (self.width + 15) >> 4;
1083 self.mb_h = (self.height + 15) >> 4;
1084 self.imode = IntraModeState::new(self.mb_w);
1088 Err(DecoderError::InvalidData)
1091 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1092 let src = pkt.get_buffer();
1093 validate!(src.len() > 0);
1096 validate!(src[0] == 0xFF);
1097 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
1098 frm.set_keyframe(false);
1099 frm.set_frame_type(FrameType::Skip);
1100 return Ok(frm.into_ref());
1103 let slice_mode = src[0] & 0x9F;
1104 validate!(slice_mode == 1 || slice_mode == 2);
1105 let mut slice_len = self.prepare_slice_buffer(src.as_slice())?;
1107 let mut br = BitReader::new(&self.slice_buf, BitReaderMode::BE);
1108 let frame_hdr = self.parse_slice_header(&mut br, slice_mode)?;
1110 let ret = supp.pool_u8.get_free();
1112 return Err(DecoderError::AllocError);
1115 let mut buf = ret.unwrap();
1116 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
1118 match frame_hdr.ftype {
1122 if self.ipbs.get_lastref().is_none() {
1123 return Err(DecoderError::MissingReference);
1127 if self.ipbs.get_b_fwdref().is_none() || self.ipbs.get_b_bwdref().is_none() {
1128 return Err(DecoderError::MissingReference);
1132 _ => unreachable!(),
1138 self.mvi.resize(self.mb_w, self.mb_h);
1139 if frame_hdr.ftype != FrameType::B {
1140 self.mbtypes.resize(self.mb_w * self.mb_h, 0);
1143 let mut slice_prepared = true;
1145 while off < src.len() {
1146 if src[off] == 0xFF { break; }
1148 let slice_mode = src[off] & 0x9F;
1149 validate!(slice_mode == 1 || slice_mode == 2);
1150 if !slice_prepared {
1151 slice_len = self.prepare_slice_buffer(&src[off..])?;
1153 let mut sbuf = Vec::new();
1154 std::mem::swap(&mut sbuf, &mut self.slice_buf);
1155 let mut br = BitReader::new(sbuf.as_slice(), BitReaderMode::BE);
1156 let ret = self.parse_slice_header(&mut br, slice_mode);
1157 if let Err(err) = ret {
1158 std::mem::swap(&mut sbuf, &mut self.slice_buf);
1161 let hdr = ret.unwrap();
1162 if hdr.ftype != frame_hdr.ftype || hdr.ts != frame_hdr.ts {
1163 std::mem::swap(&mut sbuf, &mut self.slice_buf);
1164 return Err(DecoderError::InvalidData);
1166 let ret = self.decode_slice(&mut br, &hdr, &mut dframe);
1167 std::mem::swap(&mut sbuf, &mut self.slice_buf);
1169 slice_prepared = false;
1173 validate!(self.mb_x == 0 && self.mb_y == self.mb_h);
1175 if frame_hdr.ftype != FrameType::B {
1176 self.ipbs.add_frame(buf.clone());
1177 std::mem::swap(&mut self.mvi, &mut self.ref_mvi);
1178 self.ts_fwd = self.ts_bwd;
1179 self.ts_bwd = frame_hdr.ts;
1181 self.pts_base = pkt.get_pts().unwrap_or(0);
1182 self.ts_base = frame_hdr.ts;
1185 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
1186 frm.set_keyframe(frame_hdr.ftype == FrameType::I);
1187 frm.set_frame_type(frame_hdr.ftype);
1188 if !self.no_bframes && frm.get_pts().is_some() {
1189 let pts = self.pts_base - u64::from(self.ts_base.wrapping_sub(frame_hdr.ts));
1190 frm.set_pts(Some(pts));
1194 fn flush(&mut self) {
1201 impl NAOptionHandler for SVQ3Decoder {
1202 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1203 fn set_options(&mut self, _options: &[NAOption]) { }
1204 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1207 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
1208 Box::new(SVQ3Decoder::new())
1213 use nihav_core::codecs::RegisteredDecoders;
1214 use nihav_core::demuxers::RegisteredDemuxers;
1215 use nihav_codec_support::test::dec_video::*;
1216 use crate::qt_register_all_decoders;
1217 use nihav_commonfmt::generic_register_all_demuxers;
1220 let mut dmx_reg = RegisteredDemuxers::new();
1221 generic_register_all_demuxers(&mut dmx_reg);
1222 let mut dec_reg = RegisteredDecoders::new();
1223 qt_register_all_decoders(&mut dec_reg);
1225 //let file = "assets/QT/cristinreel.mov";
1226 //let file = "assets/QT/broken_sword_Large.mov";
1227 //test_file_decoding("mov", file, Some(264), true, false, Some("svq3"), &dmx_reg, &dec_reg);
1229 // sample: https://samples.mplayerhq.hu/V-codecs/SVQ3/broken_sword_Large.mov
1230 test_decoding("mov", "sorenson-video3", "assets/QT/broken_sword_Large.mov", Some(40), &dmx_reg, &dec_reg,
1231 ExpectedTestResult::MD5Frames(vec![
1232 [0x16924d18, 0xccc5a0b4, 0xc2bb9412, 0x93d41f10],
1233 [0x84cccf62, 0x0762a61c, 0xe0b1d369, 0x211f066e],
1234 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1235 [0x8f9e157e, 0xb61f5864, 0x49cc29a7, 0xa2b648a4],
1236 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1237 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1238 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
1239 [0xb7a27005, 0xd22f8f4d, 0x8414d8e2, 0x84be8fda],
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 [0xad96c999, 0x89bfe564, 0x476f918a, 0xf89bb023],
1259 [0x1f40cce7, 0xcccc68b3, 0x2a0b28b1, 0x3210675c],
1260 [0x3165e832, 0xcb7dad5b, 0x295983fa, 0x270acdcd],
1261 [0x54b88d2a, 0x97c5ad60, 0x9cca1823, 0x458566e6],
1262 [0xbdd02a56, 0x7ee24530, 0x32262d19, 0x2f3c8237],
1263 [0x4e898806, 0x85fb7504, 0x19da4747, 0x00c55a0e],
1264 [0x5899e1f5, 0x667fbc86, 0xcbeeff49, 0x6ac996b9],
1265 [0x1b640dd6, 0xa999c0f6, 0x57cb9bed, 0xf0265669],
1266 [0x3cee4540, 0x35ce897b, 0x9db825aa, 0xd6204c2c],
1267 [0x459bfa2f, 0x451555e6, 0x08681f32, 0xf56cdc05],
1268 [0x78018c23, 0x333f1892, 0xabab4889, 0x3e3cf020],
1269 [0x2a24d296, 0xc572a5fe, 0x0af6a85a, 0x5721bfc4],
1270 [0xdf354969, 0xfbf01155, 0xa1e6d53a, 0x49334823],
1271 [0x5e493eb2, 0xc92258b8, 0xcec5e684, 0x92bd0f3c],
1272 [0x5bf8ea79, 0xb363c077, 0x05c461a3, 0xa065da2c]]));
1276 const SVQ3_INTRA_ANGLE: [i8; 4] = [ 0, 2, 1, 3 ];
1277 const SVQ3_INTRA_CBP: [u8; 6] = [ 0x00, 0x10, 0x20, 0x0F, 0x1F, 0x2F ];
1279 const SVQ3_INTRA4_PAIRS: [[u8; 2]; 25] = [
1282 [ 0, 2 ], [ 1, 1 ], [ 2, 0 ],
1283 [ 3, 0 ], [ 2, 1 ], [ 1, 2 ], [ 0, 3 ],
1284 [ 0, 4 ], [ 1, 3 ], [ 2, 2 ], [ 3, 1 ], [ 4, 0 ],
1285 [ 4, 1 ], [ 3, 2 ], [ 2, 3 ], [ 1, 4 ],
1286 [ 2, 4 ], [ 3, 3 ], [ 4, 2 ],
1291 const SVQ3_INTRA4_CTX_PRED: [[[i8; 5]; 6]; 6] = [
1293 [ 2, -1, -1, -1, -1 ], [ 2, 1, -1, -1, -1 ], [ 1, 2, -1, -1, -1 ],
1294 [ 2, 1, -1, -1, -1 ], [ 1, 2, -1, -1, -1 ], [ 1, 2, -1, -1, -1 ]
1296 [ 0, 2, -1, -1, -1 ], [ 0, 2, 1, 4, 3 ], [ 0, 1, 2, 4, 3 ],
1297 [ 0, 2, 1, 4, 3 ], [ 2, 0, 1, 3, 4 ], [ 0, 4, 2, 1, 3 ]
1299 [ 2, 0, -1, -1, -1 ], [ 2, 1, 0, 4, 3 ], [ 1, 2, 4, 0, 3 ],
1300 [ 2, 1, 0, 4, 3 ], [ 2, 1, 4, 3, 0 ], [ 1, 2, 4, 0, 3 ]
1302 [ 2, 0, -1, -1, -1 ], [ 2, 0, 1, 4, 3 ], [ 1, 2, 0, 4, 3 ],
1303 [ 2, 1, 0, 4, 3 ], [ 2, 1, 3, 4, 0 ], [ 2, 4, 1, 0, 3 ]
1305 [ 0, 2, -1, -1, -1 ], [ 0, 2, 1, 3, 4 ], [ 1, 2, 3, 0, 4 ],
1306 [ 2, 0, 1, 3, 4 ], [ 2, 1, 3, 0, 4 ], [ 2, 0, 4, 3, 1 ]
1308 [ 0, 2, -1, -1, -1 ], [ 0, 2, 4, 1, 3 ], [ 1, 4, 2, 0, 3 ],
1309 [ 4, 2, 0, 1, 3 ], [ 2, 0, 1, 4, 3 ], [ 4, 2, 1, 0, 3 ]
1313 const SVQ3_PART_SIZES: [(u8, u8); 8] = [
1314 (16, 16), (16, 16), (8, 16), (16, 8), (8, 8), (4, 8), (8, 4), (4, 4)
1317 const SVQ3_CHROMA_QUANT: [u8; 32] = [
1318 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1319 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25