]> git.nihav.org Git - nihav.git/blame_incremental - nihav-qt/src/codecs/svq3.rs
avimux: do not record palette change chunks in OpenDML index
[nihav.git] / nihav-qt / src / codecs / svq3.rs
... / ...
CommitLineData
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
3use nihav_core::io::bitreader::*;
4use nihav_core::io::intcode::*;
5use nihav_codec_support::codecs::*;
6use nihav_codec_support::codecs::blockdsp::*;
7use nihav_codec_support::data::GenericCache;
8
9use super::svq3dsp::*;
10
11struct SVQ3Header {
12 ftype: FrameType,
13 ts: u8,
14 quant: u8,
15 dquant: bool,
16}
17
18#[derive(Clone,Copy,Debug,PartialEq)]
19enum MCMode {
20 Pixel,
21 Halfpel,
22 Thirdpel
23}
24
25#[derive(Default)]
26struct SState {
27 q: u8,
28 has_left: bool,
29 has_top: bool,
30 has_tl: bool,
31 has_tr: bool,
32 trb: u8,
33 trd: u8,
34}
35
36struct IntraModeState {
37 cache: GenericCache<i8>,
38 i16_pred: i8,
39}
40
41impl IntraModeState {
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 }
45 }
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
50 }
51 fn set_mb_x(&mut self, mb_x: usize) {
52 self.cache.xpos = self.get_pos(mb_x);
53 }
54 fn fill_block(&mut self, val: i8) {
55 let mut pos = self.cache.xpos;
56 for _ in 0..4 {
57 for j in 0..4 {
58 self.cache.data[pos + j] = val;
59 }
60 pos += self.cache.stride;
61 }
62 }
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];
66 if !has_top {
67 im = match im {
68 PredType8x8::Plane | PredType8x8::Ver => PredType8x8::Hor,
69 PredType8x8::DC => PredType8x8::LeftDC,
70 _ => im,
71 };
72 } else if !has_left {
73 im = match im {
74 PredType8x8::Plane | PredType8x8::Hor => PredType8x8::Ver,
75 PredType8x8::DC => PredType8x8::TopDC,
76 _ => im,
77 };
78 }
79 im
80 }
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;
84 if !has_top {
85 im = match im {
86 PredType8x8::Plane | PredType8x8::Ver => PredType8x8::Hor,
87 PredType8x8::DC => PredType8x8::LeftDC,
88 _ => im,
89 };
90 } else if !has_left {
91 im = match im {
92 PredType8x8::Plane | PredType8x8::Hor => PredType8x8::Ver,
93 PredType8x8::DC => PredType8x8::TopDC,
94 _ => im,
95 };
96 }
97 im
98 }
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; }
103
104 let mut im = INTRA_PRED4[self.cache.data[self.cache.xpos + x + y * self.cache.stride] as usize];
105
106 if no_up {
107 im = match im {
108 PredType4x4::Ver => PredType4x4::Hor,
109 PredType4x4::DC => PredType4x4::LeftDC,
110 _ => im,
111 };
112 } else if no_left {
113 im = match im {
114 PredType4x4::Hor => PredType4x4::Ver,
115 PredType4x4::DC => PredType4x4::TopDC,
116 _ => im,
117 };
118 }
119 im
120 }
121}
122
123struct MVInfo {
124 mv_b: Vec<MV>,
125 mv_f: Vec<MV>,
126 w: usize,
127 h: usize,
128 has_b: Vec<bool>,
129 has_f: Vec<bool>,
130}
131
132impl MVInfo {
133 fn new() -> Self {
134 Self { mv_b: Vec::new(), mv_f: Vec::new(), w: 0, h: 0, has_b: Vec::new(), has_f: Vec::new() }
135 }
136 fn resize(&mut self, mb_w: usize, mb_h: usize) {
137 self.w = mb_w * 4;
138 self.h = mb_h * 4;
139 self.reset();
140 }
141 fn reset(&mut self) {
142 let size = self.w * self.h;
143 self.mv_f.clear();
144 self.mv_f.resize(size, ZERO_MV);
145 self.mv_b.clear();
146 self.mv_b.resize(size, ZERO_MV);
147 self.has_f.clear();
148 self.has_f.resize(size >> 4, false);
149 self.has_b.clear();
150 self.has_b.resize(size >> 4, false);
151 }
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) {
156 row[0] = mv;
157 row[1] = mv;
158 row[2] = mv;
159 row[3] = mv;
160 }
161 }
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) {
167 *el = mv;
168 }
169 }
170 }
171 fn get_mv_by_idx(&self, idx: usize, fwd: bool) -> MV {
172 if fwd { self.mv_f[idx] } else { self.mv_b[idx] }
173 }
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 };
178 let tr_mv;
179 if has_tr {
180 tr_mv = self.get_mv_by_idx(idx - self.w + bw, fwd);
181 } else if has_tl {
182 tr_mv = self.get_mv_by_idx(idx - self.w - 1, fwd);
183 } else {
184 tr_mv = left_mv;
185 }
186 MV::pred(left_mv, top_mv, tr_mv)
187 }
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)
190 }
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] }
195 }
196}
197
198struct SVQ3Decoder {
199 info: NACodecInfoRef,
200 width: usize,
201 height: usize,
202 ipbs: IPBShuffler,
203 avg_buf: NAVideoBufferRef<u8>,
204 imode: IntraModeState,
205 mvi: MVInfo,
206 ref_mvi: MVInfo,
207 mbtypes: Vec<u8>,
208 ebuf: [u8; 32 * 18],
209
210 coeffs: [[i16; 16]; 25],
211 coded: [bool; 24],
212 dc_only: [bool; 24],
213
214 use_hpel: bool,
215 use_tpel: bool,
216 no_bframes: bool,
217 protected: bool,
218 slice_buf: Vec<u8>,
219 mb_x: usize,
220 mb_y: usize,
221 mb_w: usize,
222 mb_h: usize,
223 ts_fwd: u8,
224 ts_bwd: u8,
225 pts_base: u64,
226 ts_base: u8,
227}
228
229const ZIGZAG4: &[usize; 16] = &[
230 0, 1, 4, 8,
231 5, 2, 3, 6,
232 9, 12, 13, 10,
233 7, 11, 14, 15
234];
235const ALT_SCAN: &[usize; 16] = &[
236 0, 1, 2, 6,
237 10, 3, 7, 11,
238 4, 8, 5, 9,
239 12, 13, 14, 15
240];
241
242const 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 )
245];
246const 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 )
249];
250const RUN_ADD: [i16; 16] = [ 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ];
251const RUN_ADD_ALT: [i16; 8] = [ 8, 2, 0, 0, 0, -1, -1, -1 ];
252
253fn decode_alt_slice(br: &mut BitReader, blk: &mut [i16; 16], mut idx: usize, end: usize) -> DecoderResult<bool> {
254 let mut coded = false;
255 while idx < end {
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]
262 } else {
263 let run = (val & 0x7) as usize;
264 (run, ((val >> 3) as i16) + RUN_ADD_ALT[run.min(RUN_ADD_ALT.len() - 1)])
265 };
266 idx += run;
267 validate!(idx < end);
268 blk[ALT_SCAN[idx]] = if sign { -level } else { level };
269 coded = true;
270 idx += 1;
271 }
272 if idx == end {
273 let val = br.read_code(UintCodeType::Gamma)?;
274 validate!(val == 0);
275 }
276 Ok(coded)
277}
278
279fn decode_block(br: &mut BitReader, blk: &mut [i16; 16], start: usize, alt: bool) -> DecoderResult<bool> {
280 let mut coded = false;
281 if !alt {
282 let mut idx = start;
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]
290 } else {
291 let run = (val & 0xF) as usize;
292 (run, ((val >> 4) as i16) + RUN_ADD[run.min(RUN_ADD.len() - 1)])
293 };
294 idx += run;
295 validate!(idx < blk.len());
296 blk[ZIGZAG4[idx]] = if sign { -level } else { level };
297 coded = true;
298 idx += 1;
299 }
300 if idx == blk.len() {
301 let val = br.read_code(UintCodeType::Gamma)?;
302 validate!(val == 0);
303 }
304 } else {
305 coded = decode_alt_slice(br, blk, start, 8)?;
306 coded |= decode_alt_slice(br, blk, 8, 16)?;
307 }
308 Ok(coded)
309}
310
311fn decode_chroma_dc(br: &mut BitReader) -> DecoderResult<[i16; 4]> {
312 let mut idx = 0;
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),
321 3 => (1, 1),
322 _ => ((val & 3) as usize, (((val + 9) >> 2) - (val & 3)) as i16)
323 };
324 idx += run;
325 validate!(idx < blk.len());
326 blk[idx] = if sign { -level } else { level };
327 idx += 1;
328 }
329 if idx == blk.len() {
330 let val = br.read_code(UintCodeType::Gamma)?;
331 validate!(val == 0);
332 }
333 Ok(blk)
334}
335
336fn 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;
339 Ok(MV{ x, y })
340}
341
342fn div6(val: i16) -> i16 {
343 (((((i32::from(val) + (6 << 16)) as u32) / 6) as i32) - (1 << 16)) as i16
344}
345
346fn 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 })
354}
355
356fn add_mv(pred_mv: MV, dmv: MV, mc_mode: MCMode) -> (MV, usize, &'static [BlkInterpFunc]) {
357 match mc_mode {
358 MCMode::Pixel => {
359 let x = div6(pred_mv.x + 3);
360 let y = div6(pred_mv.y + 3);
361 let mut mv = MV{ x, y } + dmv;
362 mv.x *= 6;
363 mv.y *= 6;
364 (mv, 0, HALFPEL_INTERP_FUNCS)
365 },
366 MCMode::Halfpel => {
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;
371 mv.x *= 3;
372 mv.y *= 3;
373 (mv, mode, HALFPEL_INTERP_FUNCS)
374 },
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;
384 mv.x <<= 1;
385 mv.y <<= 1;
386 (mv, mode, THIRDPEL_INTERP_FUNCS)
387 },
388 }
389}
390
391fn 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])
395{
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);
401
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;
405
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);
413 } else {
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);
423 }
424}
425
426fn 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]) {
427 let mx = div6(mv.x);
428 let my = div6(mv.y);
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 };
432
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);
436}
437
438impl SVQ3Decoder {
439 fn new() -> Self {
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();
444
445 Self {
446 info: NACodecInfoRef::default(),
447 width: 0,
448 height: 0,
449 ipbs: IPBShuffler::new(),
450 avg_buf,
451 imode: IntraModeState::new(0),
452 mvi: MVInfo::new(),
453 ref_mvi: MVInfo::new(),
454 mbtypes: Vec::new(),
455 ebuf: [0; 32 * 18],
456
457 coeffs: [[0; 16]; 25],
458 coded: [false; 24],
459 dc_only: [false; 24],
460
461 use_hpel: false,
462 use_tpel: false,
463 no_bframes: false,
464 protected: false,
465 slice_buf: Vec::new(),
466 mb_x: 0,
467 mb_y: 0,
468 mb_w: 0,
469 mb_h: 0,
470 ts_fwd: 0,
471 ts_bwd: 0,
472 pts_base: 0,
473 ts_base: 0,
474 }
475 }
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() {
480 FRAME_SIZES[fcode]
481 } else {
482 let w = br.read(12)? as usize;
483 let h = br.read(12)? as usize;
484 validate!(w >= 16 && h >= 16);
485 (w, h)
486 };
487 self.width = w;
488 self.height = h;
489 self.use_hpel = br.read_bool()?;
490 self.use_tpel = br.read_bool()?;
491 br.skip(1)?;
492 br.skip(1)?;
493 br.skip(1)?;
494 br.skip(1)?;
495 self.no_bframes = br.read_bool()?;
496 br.skip(1)?;
497 while br.read_bool()? {
498 br.skip(8)?;
499 }
500 self.protected = br.read_bool()?;
501//println!(" seq: {}x{} hpel {} tpel {} nob {}", w, h, self.use_hpel, self.use_tpel, self.no_bframes);
502 if self.protected {
503unimplemented!();
504 }
505 Ok(())
506 }
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),
515 _ => unreachable!(),
516 };
517 let slice_len = length + llen + 1;
518 validate!(src.len() >= slice_len);
519 self.slice_buf.clear();
520 if llen > 1 {
521 self.slice_buf.extend_from_slice(&src[slice_len - llen + 1..][..llen - 1]);
522 }
523 self.slice_buf.extend_from_slice(&src[llen + 1..][..slice_len - llen - 1]);
524 // todo unscramble
525 Ok(slice_len)
526 }
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];
531 if self.no_bframes {
532 validate!(ftype != FrameType::B);
533 }
534
535 if slice_mode == 1 {
536 br.skip(1)?;
537 } else {
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);
542 }
543 let ts = br.read(8)? as u8;
544 let quant = br.read(5)? as u8;
545 let dquant = br.read_bool()?;
546 br.skip(1)?;
547 if self.protected {
548 br.skip(1)?;
549 }
550 br.skip(1)?;
551 br.skip(2)?;
552 while br.read_bool()? {
553 br.skip(8)?;
554 }
555
556 Ok(SVQ3Header { ftype, ts, quant, dquant })
557 }
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
563 ];
564 let is_4x4 = mb_type == 8 || mb_type == 33;
565 let cbp;
566 if !is_4x4 {
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 {
572 for i in 0..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; }
579
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];
583
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);
590 }
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;
595 } else {
596 self.imode.fill_block(2);
597 cbp = 0;
598 }
599
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;
605 }
606 if !is_4x4 {
607 decode_block(br, &mut self.coeffs[24], 0, false)?;
608 idct_dc_coeffs(&mut self.coeffs[24], sstate.q);
609 }
610 let start = if is_4x4 { 0 } else { 1 };
611 let alt = sstate.q < 24 && is_4x4;
612 for sb in 0..4 {
613 if ((cbp >> sb) & 1) == 0 { continue; }
614 for b in 0..4 {
615 let blk_idx = if is_4x4 {
616 (sb & 1) * 2 + (sb >> 1) * 8 + (b & 1) + (b >> 1) * 4
617 } else {
618 sb * 4 + b
619 };
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);
623 }
624 }
625 }
626 if !is_4x4 {
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);
631 }
632 }
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);
638
639 let cdcs = [u_dc, v_dc];
640 if (cbp & 0x20) != 0 {
641 for comp in 0..2 {
642 for i in 0..4 {
643 let blk_idx = 16 + comp * 4 + i;
644 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 1, false)?;
645 }
646 }
647 }
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);
654 }
655 }
656 }
657
658 Ok(())
659 }
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<()> {
662 if mb_type == 0 {
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);
666 }
667 return Ok(());
668 }
669 let mc_mode = if self.use_tpel && br.read_bool()? != self.use_hpel {
670 MCMode::Thirdpel
671 } else if self.use_hpel && br.read_bool()? != self.use_tpel {
672 MCMode::Halfpel
673 } else {
674 MCMode::Pixel
675 };
676 let (bw, bh) = SVQ3_PART_SIZES[mb_type];
677 let bw = (bw >> 2) as usize;
678 let bh = (bh >> 2) as usize;
679
680 let mut avail = [false; 6 * 5];
681 avail[0] = sstate.has_tl;
682 if sstate.has_top {
683 avail[1] = true;
684 avail[2] = true;
685 avail[3] = true;
686 avail[4] = true;
687 }
688 avail[5] = sstate.has_tr;
689 if sstate.has_left {
690 avail[6 * 1] = true;
691 avail[6 * 2] = true;
692 avail[6 * 3] = true;
693 avail[6 * 4] = true;
694 }
695
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) {
699 let mv_x = x >> 2;
700 let mv_y = y >> 2;
701 let xpos = self.mb_x * 16 + x;
702 let ypos = self.mb_y * 16 + y;
703
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));
708
709 for j in 0..bh {
710 for i in 0..bw {
711 avail[avail_idx + i + j * 6] = true;
712 }
713 }
714
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);
720 }
721 }
722 }
723 Ok(())
724 }
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];
727 if ref_mbt >= 8 {
728 ref_mbt = 0;
729 }
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);
743
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);
747
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);
750
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);
756
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);
761
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);
766 }
767 }
768 }
769 Ok(())
770 }
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 {
773 MCMode::Thirdpel
774 } else if self.use_hpel && br.read_bool()? != self.use_tpel {
775 MCMode::Halfpel
776 } else {
777 MCMode::Pixel
778 };
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 {
782 1 => {
783 let dmv = read_mv(br)?;
784 (dmv, ZERO_MV)
785 },
786 2 => {
787 let dmv = read_mv(br)?;
788 (ZERO_MV, dmv)
789 },
790 3 => {
791 let fdmv = read_mv(br)?;
792 let bdmv = read_mv(br)?;
793 (fdmv, bdmv)
794 },
795 _ => unreachable!(),
796 };
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;
801 if has_fwd {
802 self.mvi.fill(self.mb_x, self.mb_y, true, fmv);
803 }
804 if has_bwd {
805 self.mvi.fill(self.mb_x, self.mb_y, false, bmv);
806 }
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);
811 }
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);
816
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);
822
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);
827
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);
832 }
833 Ok(())
834 }
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
840 ];
841 if hdr.ftype == FrameType::P {
842 self.do_mc_p(br, mb_type, sstate, dframe)?;
843 if mb_type == 0 {
844 return Ok(());
845 }
846 } else if mb_type != 0 {
847 self.do_mc_b(br, mb_type, sstate, dframe)?;
848 } else {
849 self.do_mc_direct(sstate, dframe)?;
850 }
851
852 let idx = br.read_code(UintCodeType::Gamma)? as usize;
853 validate!(idx < INTER_CBP.len());
854 let cbp = INTER_CBP[idx];
855
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;
861 }
862 for sb in 0..4 {
863 if ((cbp >> sb) & 1) == 0 { continue; }
864 for b in 0..4 {
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);
869 }
870 }
871 }
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);
877
878 let cdcs = [u_dc, v_dc];
879 if (cbp & 0x20) != 0 {
880 for comp in 0..2 {
881 for i in 0..4 {
882 let blk_idx = 16 + comp * 4 + i;
883 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 1, false)?;
884 }
885 }
886 }
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);
893 }
894 }
895 }
896
897 Ok(())
898 }
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;
903 for y in 0..4 {
904 for x in 0..4 {
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]]
911 } else if has_top {
912 let i = doff + x * 4 - stride;
913 [dst[i + 4], dst[i + 5], dst[i + 6], dst[i + 7]]
914 } else {
915 [0; 4]
916 };
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]);
921 }
922 }
923 doff += stride * 4;
924 }
925 let im8 = self.imode.get_pred8_type(sstate.has_top, sstate.has_left);
926 for comp in 1..3 {
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);
930 for y in 0..2 {
931 for x in 0..2 {
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]);
935 }
936 }
937 doff += stride * 4;
938 }
939 }
940 }
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;
945 for y in 0..4 {
946 for x in 0..4 {
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]);
950 }
951 }
952 doff += stride * 4;
953 }
954 for comp in 1..3 {
955 let stride = dframe.stride[comp];
956 let mut doff = dframe.offset[comp] + self.mb_x * 8 + self.mb_y * 8 * stride;
957 for y in 0..2 {
958 for x in 0..2 {
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]);
962 }
963 }
964 doff += stride * 4;
965 }
966 }
967 }
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);
977 }
978 let start_idx = mb_idx;
979 self.imode.reset();
980 while mb_idx < mbs {
981 sstate.has_top = mb_idx - start_idx >= self.mb_w;
982 if sstate.has_top {
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;
985 } else {
986 sstate.has_tl = false;
987 sstate.has_tr = false;
988 }
989
990 if br.left() < 8 && (br.tell() & 7) == 0 && br.peek(8) == 0 {
991 return Ok(());
992 }
993 let mut mb_type = br.read_code(UintCodeType::Gamma)? as usize;
994 if hdr.ftype == FrameType::I {
995 mb_type += 8;
996 }
997 if hdr.ftype == FrameType::B && mb_type >= 4 {
998 mb_type += 4;
999 }
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;
1007 }
1008 if mb_type < 8 {
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);
1013 } else {
1014 self.decode_intra_block(br, mb_type, &mut sstate, hdr)?;
1015 let is_4x4 = mb_type == 8 || mb_type == 33;
1016 if is_4x4 {
1017 self.put_intra4x4(dframe, &sstate);
1018 } else {
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);
1024 for comp in 1..3 {
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);
1028 }
1029 self.put_residue(dframe);
1030 }
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);
1033 }
1034 sstate.has_left = true;
1035 self.mb_x += 1;
1036 if self.mb_x == self.mb_w {
1037 self.mb_x = 0;
1038 self.mb_y += 1;
1039 sstate.has_left = false;
1040 self.imode.update();
1041 }
1042 mb_idx += 1;
1043 }
1044 Ok(())
1045 }
1046}
1047
1048const FRAME_SIZES: [(usize, usize); 7] = [
1049 (160, 120), (128, 96), (176, 144), (352, 288),
1050 (704, 576), (240, 180), (320, 240)
1051];
1052const FRAME_TYPES: [FrameType; 3] = [ FrameType::P, FrameType::B, FrameType::I ];
1053
1054impl 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());
1065 start = i + 8;
1066 break;
1067 }
1068 }
1069 if start < edata.len() {
1070 self.parse_sequence_header(&edata[start..])?;
1071 } else {
1072 return Err(DecoderError::InvalidData);
1073 }
1074 } else {
1075 return Err(DecoderError::InvalidData);
1076 }
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)?;
1081
1082 self.mb_w = (self.width + 15) >> 4;
1083 self.mb_h = (self.height + 15) >> 4;
1084 self.imode = IntraModeState::new(self.mb_w);
1085
1086 Ok(())
1087 } else {
1088 Err(DecoderError::InvalidData)
1089 }
1090 }
1091 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1092 let src = pkt.get_buffer();
1093 validate!(src.len() > 0);
1094
1095 if src.len() == 1 {
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());
1101 }
1102
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())?;
1106
1107 let mut br = BitReader::new(&self.slice_buf, BitReaderMode::BE);
1108 let frame_hdr = self.parse_slice_header(&mut br, slice_mode)?;
1109
1110 let ret = supp.pool_u8.get_free();
1111 if ret.is_none() {
1112 return Err(DecoderError::AllocError);
1113 }
1114
1115 let mut buf = ret.unwrap();
1116 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
1117
1118 match frame_hdr.ftype {
1119 FrameType::I => {
1120 },
1121 FrameType::P => {
1122 if self.ipbs.get_lastref().is_none() {
1123 return Err(DecoderError::MissingReference);
1124 }
1125 },
1126 FrameType::B => {
1127 if self.ipbs.get_b_fwdref().is_none() || self.ipbs.get_b_bwdref().is_none() {
1128 return Err(DecoderError::MissingReference);
1129 }
1130 },
1131
1132 _ => unreachable!(),
1133 }
1134
1135 self.mb_x = 0;
1136 self.mb_y = 0;
1137
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);
1141 }
1142
1143 let mut slice_prepared = true;
1144 let mut off = 0;
1145 while off < src.len() {
1146 if src[off] == 0xFF { break; }
1147
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..])?;
1152 }
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);
1159 return Err(err);
1160 }
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);
1165 }
1166 let ret = self.decode_slice(&mut br, &hdr, &mut dframe);
1167 std::mem::swap(&mut sbuf, &mut self.slice_buf);
1168 ret?;
1169 slice_prepared = false;
1170 off += slice_len;
1171 }
1172
1173 validate!(self.mb_x == 0 && self.mb_y == self.mb_h);
1174
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;
1180
1181 self.pts_base = pkt.get_pts().unwrap_or(0);
1182 self.ts_base = frame_hdr.ts;
1183 }
1184
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));
1191 }
1192 Ok(frm.into_ref())
1193 }
1194 fn flush(&mut self) {
1195 self.ipbs.clear();
1196 self.ts_fwd = 0;
1197 self.ts_bwd = 0;
1198 }
1199}
1200
1201impl 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 }
1205}
1206
1207pub fn get_decoder() -> Box<dyn NADecoder + Send> {
1208 Box::new(SVQ3Decoder::new())
1209}
1210
1211#[cfg(test)]
1212mod test {
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;
1218 #[test]
1219 fn test_svq3() {
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);
1224
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);
1228//panic!("end");
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]]));
1273 }
1274}
1275
1276const SVQ3_INTRA_ANGLE: [i8; 4] = [ 0, 2, 1, 3 ];
1277const SVQ3_INTRA_CBP: [u8; 6] = [ 0x00, 0x10, 0x20, 0x0F, 0x1F, 0x2F ];
1278
1279const SVQ3_INTRA4_PAIRS: [[u8; 2]; 25] = [
1280 [ 0, 0 ],
1281 [ 1, 0 ], [ 0, 1 ],
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 ],
1287 [ 4, 3 ], [ 3, 4 ],
1288 [ 4, 4 ]
1289];
1290
1291const SVQ3_INTRA4_CTX_PRED: [[[i8; 5]; 6]; 6] = [
1292 [
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 ]
1295 ], [
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 ]
1298 ], [
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 ]
1301 ], [
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 ]
1304 ], [
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 ]
1307 ], [
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 ]
1310 ]
1311];
1312
1313const SVQ3_PART_SIZES: [(u8, u8); 8] = [
1314 (16, 16), (16, 16), (8, 16), (16, 8), (8, 8), (4, 8), (8, 4), (4, 4)
1315];
1316
1317const 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
1320];