annotate the sources for test samples
[nihav.git] / nihav-qt / src / codecs / svq3.rs
CommitLineData
4c1582cf
KS
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;
37952415 143 self.mv_f.clear();
4c1582cf 144 self.mv_f.resize(size, ZERO_MV);
37952415 145 self.mv_b.clear();
4c1582cf 146 self.mv_b.resize(size, ZERO_MV);
37952415 147 self.has_f.clear();
4c1582cf 148 self.has_f.resize(size >> 4, false);
37952415 149 self.has_b.clear();
4c1582cf
KS
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 as usize).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 as usize).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) = if val < 3 {
320 (0, val as i16)
321 } else if val == 3 {
322 (1, 1)
323 } else {
324 ((val & 3) as usize, (((val + 9) >> 2) - (val & 3)) as i16)
325 };
326 idx += run;
327 validate!(idx < blk.len());
328 blk[idx] = if sign { -level } else { level };
329 idx += 1;
330 }
331 if idx == blk.len() {
332 let val = br.read_code(UintCodeType::Gamma)?;
333 validate!(val == 0);
334 }
335 Ok(blk)
336}
337
338fn 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;
341 Ok(MV{ x, y })
342}
343
344fn div6(val: i16) -> i16 {
345 (((((i32::from(val) + (6 << 16)) as u32) / 6) as i32) - (1 << 16)) as i16
346}
347
348fn 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 })
356}
357
358fn add_mv(pred_mv: MV, dmv: MV, mc_mode: MCMode) -> (MV, usize, &'static [BlkInterpFunc]) {
359 match mc_mode {
360 MCMode::Pixel => {
361 let x = div6(pred_mv.x + 3);
362 let y = div6(pred_mv.y + 3);
363 let mut mv = MV{ x, y } + dmv;
364 mv.x *= 6;
365 mv.y *= 6;
366 (mv, 0, HALFPEL_INTERP_FUNCS)
367 },
368 MCMode::Halfpel => {
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;
373 mv.x *= 3;
374 mv.y *= 3;
375 (mv, mode, HALFPEL_INTERP_FUNCS)
376 },
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;
386 mv.x <<= 1;
387 mv.y <<= 1;
388 (mv, mode, THIRDPEL_INTERP_FUNCS)
389 },
390 }
391}
392
393fn 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])
397{
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);
403
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;
407
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);
415 } else {
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);
425 }
426}
427
428fn 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 mx = div6(mv.x);
430 let my = div6(mv.y);
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 };
434
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);
b7c882c1 437 copy_block(dframe, src, ebuf, 2, xoff / 2, yoff / 2, cmx, cmy, bw * 2, bh * 2, 0, post, mode, ifuncs);
4c1582cf
KS
438}
439
440impl SVQ3Decoder {
441 fn new() -> Self {
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();
446
447 Self {
448 info: NACodecInfoRef::default(),
449 width: 0,
450 height: 0,
451 ipbs: IPBShuffler::new(),
452 avg_buf,
453 imode: IntraModeState::new(0),
454 mvi: MVInfo::new(),
455 ref_mvi: MVInfo::new(),
456 mbtypes: Vec::new(),
457 ebuf: [0; 32 * 18],
458
459 coeffs: [[0; 16]; 25],
460 coded: [false; 24],
461 dc_only: [false; 24],
462
463 use_hpel: false,
464 use_tpel: false,
465 no_bframes: false,
466 protected: false,
467 slice_buf: Vec::new(),
468 mb_x: 0,
469 mb_y: 0,
470 mb_w: 0,
471 mb_h: 0,
472 ts_fwd: 0,
473 ts_bwd: 0,
474 pts_base: 0,
475 ts_base: 0,
476 }
477 }
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() {
482 FRAME_SIZES[fcode]
483 } else {
484 let w = br.read(12)? as usize;
485 let h = br.read(12)? as usize;
486 validate!(w >= 16 && h >= 16);
487 (w, h)
488 };
489 self.width = w;
490 self.height = h;
491 self.use_hpel = br.read_bool()?;
492 self.use_tpel = br.read_bool()?;
493 br.skip(1)?;
494 br.skip(1)?;
495 br.skip(1)?;
496 br.skip(1)?;
497 self.no_bframes = br.read_bool()?;
498 br.skip(1)?;
499 while br.read_bool()? {
500 br.skip(8)?;
501 }
502 self.protected = br.read_bool()?;
503//println!(" seq: {}x{} hpel {} tpel {} nob {}", w, h, self.use_hpel, self.use_tpel, self.no_bframes);
504 if self.protected {
505unimplemented!();
506 }
507 Ok(())
508 }
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),
517 _ => unreachable!(),
518 };
519 let slice_len = length + llen + 1;
520 validate!(src.len() >= slice_len);
37952415 521 self.slice_buf.clear();
4c1582cf
KS
522 if llen > 1 {
523 self.slice_buf.extend_from_slice(&src[slice_len - llen + 1..][..llen - 1]);
524 }
525 self.slice_buf.extend_from_slice(&src[llen + 1..][..slice_len - llen - 1]);
526 // todo unscramble
527 Ok(slice_len)
528 }
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];
533 if self.no_bframes {
534 validate!(ftype != FrameType::B);
535 }
536
537 if slice_mode == 1 {
538 br.skip(1)?;
539 } else {
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)?;
543println!("slice offset {}", _offset);
544 }
545 let ts = br.read(8)? as u8;
546 let quant = br.read(5)? as u8;
547 let dquant = br.read_bool()?;
548 br.skip(1)?;
549 if self.protected {
550 br.skip(1)?;
551 }
552 br.skip(1)?;
553 br.skip(2)?;
554 while br.read_bool()? {
555 br.skip(8)?;
556 }
557
558 Ok(SVQ3Header { ftype, ts, quant, dquant })
559 }
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
565 ];
566 let is_4x4 = mb_type == 8 || mb_type == 33;
567 let cbp;
568 if !is_4x4 {
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 {
574 for i in 0..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; }
581
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];
585
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);
592 }
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;
597 } else {
598 self.imode.fill_block(2);
599 cbp = 0;
600 }
601
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!(new_q >= 0 && new_q < 32);
606 sstate.q = new_q as u8;
607 }
608 if !is_4x4 {
609 decode_block(br, &mut self.coeffs[24], 0, false)?;
610 idct_dc_coeffs(&mut self.coeffs[24], sstate.q);
611 }
612 let start = if is_4x4 { 0 } else { 1 };
613 let alt = sstate.q < 24 && is_4x4;
614 for sb in 0..4 {
615 if ((cbp >> sb) & 1) == 0 { continue; }
616 for b in 0..4 {
617 let blk_idx = if is_4x4 {
618 (sb & 1) * 2 + (sb >> 1) * 8 + (b & 1) + (b >> 1) * 4
619 } else {
620 sb * 4 + b
621 };
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);
625 }
626 }
627 }
628 if !is_4x4 {
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);
633 }
634 }
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);
640
641 let cdcs = [u_dc, v_dc];
642 if (cbp & 0x20) != 0 {
643 for comp in 0..2 {
644 for i in 0..4 {
645 let blk_idx = 16 + comp * 4 + i;
646 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 1, false)?;
647 }
648 }
649 }
650 for comp in 0..2 {
651 for i in 0..4 {
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);
656 }
657 }
658 }
237cc1f9 659
4c1582cf
KS
660 Ok(())
661 }
662 fn do_mc_p(&mut self, br: &mut BitReader, mb_type: usize, sstate: &mut SState, dframe: &mut NASimpleVideoFrame<u8>) -> DecoderResult<()> {
663 if mb_type == 0 {
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);
667 }
668 return Ok(());
669 }
670 let mc_mode = if self.use_tpel && br.read_bool()? != self.use_hpel {
671 MCMode::Thirdpel
672 } else if self.use_hpel && br.read_bool()? != self.use_tpel {
673 MCMode::Halfpel
674 } else {
675 MCMode::Pixel
676 };
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;
680
681 let mut avail = [false; 6 * 5];
682 avail[0] = sstate.has_tl;
683 if sstate.has_top {
684 avail[1] = true;
685 avail[2] = true;
686 avail[3] = true;
687 avail[4] = true;
688 }
689 avail[5] = sstate.has_tr;
690 if sstate.has_left {
691 avail[6 * 1] = true;
692 avail[6 * 2] = true;
693 avail[6 * 3] = true;
694 avail[6 * 4] = true;
695 }
696
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) {
700 let mv_x = x >> 2;
701 let mv_y = y >> 2;
702 let xpos = self.mb_x * 16 + x;
703 let ypos = self.mb_y * 16 + y;
704
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));
709
710 for j in 0..bh {
711 for i in 0..bw {
712 avail[avail_idx + i + j * 6] = true;
713 }
714 }
715
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);
721 }
722 }
723 }
724 Ok(())
725 }
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];
728 if ref_mbt >= 8 {
729 ref_mbt = 0;
730 }
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);
744
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);
748
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);
751
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);
757
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);
762
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);
767 }
768 }
769 }
770 Ok(())
771 }
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 {
774 MCMode::Thirdpel
775 } else if self.use_hpel && br.read_bool()? != self.use_tpel {
776 MCMode::Halfpel
777 } else {
778 MCMode::Pixel
779 };
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 {
783 1 => {
784 let dmv = read_mv(br)?;
785 (dmv, ZERO_MV)
786 },
787 2 => {
788 let dmv = read_mv(br)?;
789 (ZERO_MV, dmv)
790 },
791 3 => {
792 let fdmv = read_mv(br)?;
793 let bdmv = read_mv(br)?;
794 (fdmv, bdmv)
795 },
796 _ => unreachable!(),
797 };
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;
802 if has_fwd {
803 self.mvi.fill(self.mb_x, self.mb_y, true, fmv);
804 }
805 if has_bwd {
806 self.mvi.fill(self.mb_x, self.mb_y, false, bmv);
807 }
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);
812 }
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 };
b7c882c1 816 mc_part(&mut aframe, bwd_ref, &mut self.ebuf, 0, 0, 4, 4, amv, bmode, ifuncs);
4c1582cf
KS
817
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);
823
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);
828
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);
833 }
834 Ok(())
835 }
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
841 ];
842 if hdr.ftype == FrameType::P {
843 self.do_mc_p(br, mb_type, sstate, dframe)?;
844 if mb_type == 0 {
845 return Ok(());
846 }
847 } else if mb_type != 0 {
848 self.do_mc_b(br, mb_type, sstate, dframe)?;
849 } else {
850 self.do_mc_direct(sstate, dframe)?;
851 }
852
853 let idx = br.read_code(UintCodeType::Gamma)? as usize;
854 validate!(idx < INTER_CBP.len());
855 let cbp = INTER_CBP[idx];
856
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!(new_q >= 0 && new_q < 32);
861 sstate.q = new_q as u8;
862 }
863 for sb in 0..4 {
864 if ((cbp >> sb) & 1) == 0 { continue; }
865 for b in 0..4 {
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);
870 }
871 }
872 }
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);
878
879 let cdcs = [u_dc, v_dc];
880 if (cbp & 0x20) != 0 {
881 for comp in 0..2 {
882 for i in 0..4 {
883 let blk_idx = 16 + comp * 4 + i;
884 self.coded[blk_idx] = decode_block(br, &mut self.coeffs[blk_idx], 1, false)?;
885 }
886 }
887 }
888 for comp in 0..2 {
889 for i in 0..4 {
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);
894 }
895 }
896 }
897
898 Ok(())
899 }
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;
904 for y in 0..4 {
905 for x in 0..4 {
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]]
912 } else if has_top {
913 let i = doff + x * 4 - stride;
914 [dst[i + 4], dst[i + 5], dst[i + 6], dst[i + 7]]
915 } else {
916 [0; 4]
917 };
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]);
922 }
923 }
924 doff += stride * 4;
925 }
926 let im8 = self.imode.get_pred8_type(sstate.has_top, sstate.has_left);
927 for comp in 1..3 {
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);
931 for y in 0..2 {
932 for x in 0..2 {
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]);
936 }
937 }
938 doff += stride * 4;
939 }
940 }
941 }
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;
946 for y in 0..4 {
947 for x in 0..4 {
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]);
951 }
952 }
953 doff += stride * 4;
954 }
955 for comp in 1..3 {
956 let stride = dframe.stride[comp];
957 let mut doff = dframe.offset[comp] + self.mb_x * 8 + self.mb_y * 8 * stride;
958 for y in 0..2 {
959 for x in 0..2 {
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]);
963 }
964 }
965 doff += stride * 4;
966 }
967 }
968 }
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 {
991 if (br.tell() & 7) == 0 && br.peek(8) == 0 {
992 return Ok(());
993 }
994 }
995 let mut mb_type = br.read_code(UintCodeType::Gamma)? as usize;
996 if hdr.ftype == FrameType::I {
997 mb_type += 8;
998 }
999 if hdr.ftype == FrameType::B && mb_type >= 4 {
1000 mb_type += 4;
1001 }
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;
1009 }
1010 if mb_type < 8 {
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);
1015 } else {
1016 self.decode_intra_block(br, mb_type, &mut sstate, hdr)?;
1017 let is_4x4 = mb_type == 8 || mb_type == 33;
1018 if is_4x4 {
1019 self.put_intra4x4(dframe, &sstate);
1020 } else {
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);
1026 for comp in 1..3 {
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);
1030 }
1031 self.put_residue(dframe);
1032 }
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);
1035 }
1036 sstate.has_left = true;
1037 self.mb_x += 1;
1038 if self.mb_x == self.mb_w {
1039 self.mb_x = 0;
1040 self.mb_y += 1;
1041 sstate.has_left = false;
1042 self.imode.update();
1043 }
1044 mb_idx += 1;
1045 }
1046 Ok(())
1047 }
1048}
1049
1050const FRAME_SIZES: [(usize, usize); 7] = [
1051 (160, 120), (128, 96), (176, 144), (352, 288),
1052 (704, 576), (240, 180), (320, 240)
1053];
1054const FRAME_TYPES: [FrameType; 3] = [ FrameType::P, FrameType::B, FrameType::I ];
1055
1056impl 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());
1067 start = i + 8;
1068 break;
1069 }
1070 }
1071 if start < edata.len() {
1072 self.parse_sequence_header(&edata[start..])?;
1073 } else {
1074 return Err(DecoderError::InvalidData);
1075 }
1076 } else {
1077 return Err(DecoderError::InvalidData);
1078 }
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)?;
1083
1084 self.mb_w = (self.width + 15) >> 4;
1085 self.mb_h = (self.height + 15) >> 4;
1086 self.imode = IntraModeState::new(self.mb_w);
1087
1088 Ok(())
1089 } else {
1090 Err(DecoderError::InvalidData)
1091 }
1092 }
1093 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1094 let src = pkt.get_buffer();
1095 validate!(src.len() > 0);
1096
1097 if src.len() == 1 {
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());
1103 }
1104
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())?;
1108
1109 let mut br = BitReader::new(&self.slice_buf, BitReaderMode::BE);
1110 let frame_hdr = self.parse_slice_header(&mut br, slice_mode)?;
1111
1112 let ret = supp.pool_u8.get_free();
1113 if ret.is_none() {
1114 return Err(DecoderError::AllocError);
1115 }
1116
1117 let mut buf = ret.unwrap();
1118 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
1119
1120 match frame_hdr.ftype {
1121 FrameType::I => {
1122 },
1123 FrameType::P => {
1124 if self.ipbs.get_lastref().is_none() {
1125 return Err(DecoderError::MissingReference);
1126 }
1127 },
1128 FrameType::B => {
1129 if self.ipbs.get_b_fwdref().is_none() || self.ipbs.get_b_bwdref().is_none() {
1130 return Err(DecoderError::MissingReference);
1131 }
1132 },
1133
1134 _ => unreachable!(),
1135 }
1136
1137 self.mb_x = 0;
1138 self.mb_y = 0;
1139
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);
1143 }
1144
1145 let mut slice_prepared = true;
1146 let mut off = 0;
1147 while off < src.len() {
1148 if src[off] == 0xFF { break; }
1149
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..])?;
1154 }
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);
1161 return Err(err);
1162 }
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);
1167 }
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 {
1171 return Err(err);
1172 }
1173 slice_prepared = false;
1174 off += slice_len;
1175 }
1176
1177 validate!(self.mb_x == 0 && self.mb_y == self.mb_h);
1178
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;
1184
1185 self.pts_base = pkt.get_pts().unwrap_or(0);
1186 self.ts_base = frame_hdr.ts;
1187 }
1188
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));
1195 }
1196 Ok(frm.into_ref())
1197 }
1198 fn flush(&mut self) {
1199 self.ipbs.clear();
1200 self.ts_fwd = 0;
1201 self.ts_bwd = 0;
1202 }
1203}
1204
1205impl 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 }
1209}
1210
1211pub fn get_decoder() -> Box<dyn NADecoder + Send> {
1212 Box::new(SVQ3Decoder::new())
1213}
1214
1215#[cfg(test)]
1216mod test {
1217 use nihav_core::codecs::RegisteredDecoders;
1218 use nihav_core::demuxers::RegisteredDemuxers;
1219 use nihav_codec_support::test::dec_video::*;
78fb6560 1220 use crate::qt_register_all_decoders;
4c1582cf
KS
1221 use nihav_commonfmt::generic_register_all_demuxers;
1222 #[test]
1223 fn test_svq3() {
1224 let mut dmx_reg = RegisteredDemuxers::new();
1225 generic_register_all_demuxers(&mut dmx_reg);
1226 let mut dec_reg = RegisteredDecoders::new();
78fb6560 1227 qt_register_all_decoders(&mut dec_reg);
4c1582cf
KS
1228
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);
1232//panic!("end");
886cde48 1233 // sample: https://samples.mplayerhq.hu/V-codecs/SVQ3/broken_sword_Large.mov
4c1582cf
KS
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]]));
1277 }
1278}
1279
1280const SVQ3_INTRA_ANGLE: [i8; 4] = [ 0, 2, 1, 3 ];
1281const SVQ3_INTRA_CBP: [u8; 6] = [ 0x00, 0x10, 0x20, 0x0F, 0x1F, 0x2F ];
1282
1283const SVQ3_INTRA4_PAIRS: [[u8; 2]; 25] = [
1284 [ 0, 0 ],
1285 [ 1, 0 ], [ 0, 1 ],
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 ],
1291 [ 4, 3 ], [ 3, 4 ],
1292 [ 4, 4 ]
1293];
1294
1295const SVQ3_INTRA4_CTX_PRED: [[[i8; 5]; 6]; 6] = [
1296 [
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 ]
1299 ], [
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 ]
1302 ], [
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 ]
1305 ], [
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 ]
1308 ], [
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 ]
1311 ], [
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 ]
1314 ]
1315];
1316
1317const SVQ3_PART_SIZES: [(u8, u8); 8] = [
1318 (16, 16), (16, 16), (8, 16), (16, 8), (8, 8), (4, 8), (8, 4), (4, 4)
1319];
1320
1321const 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
1324];