introduce option handling for decoders
[nihav.git] / nihav-realmedia / src / codecs / rv60.rs
1 use nihav_core::formats::YUV420_FORMAT;
2 use nihav_core::frame::*;
3 use nihav_core::codecs::{NADecoder, NADecoderSupport, DecoderError, DecoderResult};
4 use nihav_core::options::*;
5 use nihav_codec_support::codecs::{MV, ZERO_MV, IPBShuffler};
6 use nihav_core::io::byteio::{MemoryReader,ByteReader};
7 use nihav_core::io::bitreader::{BitReader,BitReaderMode};
8 use nihav_core::io::intcode::*;
9
10 use super::rv60codes::*;
11 use super::rv60dsp::*;
12
13 struct UniqueList<A> {
14 list: [A; 4],
15 fill: usize,
16 max_size: usize,
17 }
18
19 impl<A:Copy+Default+PartialEq> UniqueList<A> {
20 fn new(max_size: usize) -> Self {
21 Self { list: [A::default(); 4], fill: 0, max_size }
22 }
23 fn add(&mut self, cand: A) {
24 if self.fill == self.max_size { return; }
25 let mut unique = true;
26 for el in self.list.iter().take(self.fill) {
27 if *el == cand {
28 unique = false;
29 break;
30 }
31 }
32 if unique {
33 self.list[self.fill] = cand;
34 self.fill += 1;
35 }
36 }
37 }
38
39 const RV60_FRAME_TYPES: [FrameType; 4] = [ FrameType::I, FrameType::P, FrameType::B, FrameType::Other ];
40 const MAX_IMODE: u8 = 34;
41
42 #[derive(Clone,Copy,Debug)]
43 struct FrameHeader {
44 profile: u8,
45 ftype: FrameType,
46 qp: u8,
47 osvquant: u8,
48 ts: u32,
49 width: usize,
50 height: usize,
51 two_f_refs: bool,
52 qp_off_type: u8,
53 deblock: bool,
54 deblock_chroma: bool,
55 }
56
57 const RV60_CUSTOM_MSG_LENS: [u32; 4] = [ 2, 4, 16, 32 ];
58 impl FrameHeader {
59 fn read(br: &mut BitReader) -> DecoderResult<Self> {
60 let marker = br.read(2)?;
61 validate!(marker == 3);
62 let profile = br.read(2)? as u8;
63 validate!(profile == 0);
64 let _someval = br.read(4)?;
65 let ftypeid = br.read(2)? as usize;
66 let ftype = RV60_FRAME_TYPES[ftypeid];
67 let qp = br.read(6)? as u8;
68 let marker = br.read(1)?;
69 validate!(marker == 0);
70 let toolset = br.read(2)?;
71 validate!(toolset == 0);
72 let osvquant = br.read(2)? as u8;
73 let _some_flag = br.read_bool()?;
74 let _some_val = br.read(2)?;
75 let ts = br.read(24)?;
76 let width = ((br.read(11)? as usize) + 1) * 4;
77 let height = ((br.read(11)? as usize) + 0) * 4;
78 validate!(height > 0);
79 let _some_flag = br.read_bool()?;
80 let two_f_refs;
81 if ftype == FrameType::I {
82 //byte17 = 0
83 two_f_refs = false;
84 } else {
85 let flag = br.read_bool()?;
86 if flag { // untested
87 br.skip(1)?;
88 br.skip(1)?;
89 br.skip(1)?;
90 }
91 //byte17 = flag?
92 two_f_refs = br.read_bool()?;
93 }
94 // if byte17 { dw40 = 2; dw3C = 2; } else { dw40 = 1; dw3C = 1; }
95 let _some_val = br.read_code(UintCodeType::Unary012)?; // luma_qp_diff?
96 let chroma_qp_diff = br.read(1)?;
97 validate!(chroma_qp_diff == 0);
98 let qp_off_type = br.read_code(UintCodeType::Unary012)? as u8;
99 let deblock = br.read_bool()?;
100 let deblock_chroma = deblock && !br.read_bool()?;
101 if br.read_bool()? {
102 let custom_msg_hdr_len = br.read(2)? as usize;
103 if custom_msg_hdr_len != 0 {
104 for i in 0..custom_msg_hdr_len {
105 br.skip(RV60_CUSTOM_MSG_LENS[i] * 8)?;
106 }
107 }
108 }
109
110 Ok(FrameHeader {
111 profile, ftype, qp, osvquant, ts, width, height, two_f_refs, qp_off_type,
112 deblock, deblock_chroma,
113 })
114 }
115 fn parse_slice_sizes(&self, br: &mut BitReader, sizes: &mut Vec<usize>) -> DecoderResult<()> {
116 let nslices = self.get_height_cu();
117 let nbits = (br.read(5)? as u8) + 1;
118 validate!(nbits < 32);
119 let mut signs: Vec<bool> = Vec::with_capacity(nslices);
120 for _ in 0..nslices {
121 let sign = br.read_bool()?;
122 signs.push(sign);
123 }
124 validate!(signs[0]);
125 sizes.truncate(0);
126 let mut sum = 0;
127 let first_size = br.read(nbits)? as usize;
128 validate!(first_size > 0);
129 sum += first_size;
130 let mut lastsize = first_size;
131 sizes.push(first_size);
132 for i in 1..nslices {
133 let diff = br.read(nbits)? as isize;
134 let size;
135 if signs[i] {
136 let sum = (lastsize as isize).checked_add(diff);
137 validate!(sum.is_some());
138 size = sum.unwrap() as usize;
139 } else {
140 let sum = (lastsize as isize).checked_sub(diff);
141 validate!(sum.is_some());
142 size = sum.unwrap() as usize;
143 }
144 sizes.push(size);
145 sum += size;
146 lastsize = size;
147 }
148 br.align();
149 if ((br.left() >> 3) as usize) != sum {
150 println!(" left {} / {}", br.left() >> 3, sum);
151 }
152 validate!((br.left() >> 3) >= (sum as isize));
153 Ok(())
154 }
155 fn read_line_qp_offset(&self, br: &mut BitReader) -> DecoderResult<i8> {
156 match self.qp_off_type {
157 0 => Ok(0),
158 1 => {
159 let val = br.read_code(UintCodeType::Unary012)?;
160 if val != 2 {
161 Ok(val as i8)
162 } else {
163 Ok(-1)
164 }
165 },
166 _ => {
167 if br.read(1)? == 0 {
168 Ok(0)
169 } else {
170 let val = br.read(2)? as i8;
171 if (val & 2) == 0 {
172 Ok(val + 1)
173 } else {
174 Ok(-((val & 1) + 1))
175 }
176 }
177 },
178 }
179 }
180 fn get_width_cu(&self) -> usize {
181 (self.width + 63) >> 6
182 }
183 fn get_height_cu(&self) -> usize {
184 (self.height + 63) >> 6
185 }
186 fn has_top_block(&self, xpos: usize, ypos: usize, dx: usize, dy: usize, size: usize) -> bool {
187 if (ypos + dy) == 0 { return false; }
188 let xpos2 = xpos + dx;
189 if (xpos2 + size) > self.width { return false; }
190 true
191 }
192 fn has_top_right_block(&self, xpos: usize, ypos: usize, dx: usize, dy: usize, size: usize) -> bool {
193 if (ypos + dy) == 0 { return false; }
194 let xpos2 = xpos + dx;
195 if (xpos2 + size * 2) > self.width { return false; }
196 let cxpos = ((xpos + dx) & 63) >> RV60_BLOCK_LOG2[size];
197 let cypos = ((ypos + dy) & 63) >> RV60_BLOCK_LOG2[size];
198 ((cypos as u8) & RV60_AVAIL_MASK[cxpos]) == 0
199 }
200 fn has_left_block(&self, xpos: usize, ypos: usize, dx: usize, dy: usize, size: usize) -> bool {
201 if (xpos + dx) == 0 { return false; }
202 let ypos2 = ypos + dy;
203 if (ypos2 + size) > self.height { return false; }
204 true
205 }
206 fn has_left_down_block(&self, xpos: usize, ypos: usize, dx: usize, dy: usize, size: usize) -> bool {
207 if (xpos + dx) == 0 { return false; }
208 let ypos2 = ypos + dy;
209 if (ypos2 + size * 2) > self.height { return false; }
210 let cxpos = (!(xpos + dx) & 63) >> RV60_BLOCK_LOG2[size];
211 let cypos = (!(ypos + dy) & 63) >> RV60_BLOCK_LOG2[size];
212 ((cypos as u8) & RV60_AVAIL_MASK[cxpos]) >= 1
213 }
214 }
215
216 const RV60_BLOCK_LOG2: [u8; 65] = [
217 0,
218 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4,
219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6
222 ];
223 const RV60_AVAIL_MASK: [u8; 64] = [
224 0, 1, 0, 3, 0, 1, 0, 7, 0, 1, 0, 3, 0, 1, 0, 0,
225 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
226 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
228 ];
229
230 #[derive(Clone,Copy,PartialEq,Debug)]
231 enum CUType {
232 Intra,
233 InterMV,
234 Skip,
235 InterNoMV,
236 }
237
238 impl Default for CUType {
239 fn default() -> Self { CUType::Intra }
240 }
241
242 const RV60_CU_TYPES: [CUType; 4] = [ CUType::Intra, CUType::InterMV, CUType::Skip, CUType::InterNoMV ];
243
244 #[derive(Clone,Copy,PartialEq,Debug)]
245 enum PUType {
246 Full,
247 N2Hor,
248 N2Ver,
249 Quarters,
250 N4Hor,
251 N34Hor,
252 N4Ver,
253 N34Ver,
254 }
255
256 const RV60_PU_TYPES: [PUType; 8] = [
257 PUType::Full, PUType::N2Hor, PUType::N2Ver, PUType::Quarters,
258 PUType::N4Hor, PUType::N34Hor, PUType::N4Ver, PUType::N34Ver,
259 ];
260
261 impl PUType {
262 fn get_num_mvs(self) -> usize {
263 match self {
264 PUType::Full => 1,
265 PUType::Quarters => 4,
266 _ => 2,
267 }
268 }
269 fn get_mv_size(self, part_no: usize, size: usize) -> (usize, usize) {
270 let mv_size = size >> 2;
271 match self {
272 PUType::Full => (mv_size, mv_size),
273 PUType::N2Hor => (mv_size, mv_size >> 1),
274 PUType::N2Ver => (mv_size >> 1, mv_size),
275 PUType::Quarters => (mv_size >> 1, mv_size >> 1),
276 PUType::N4Hor => {
277 if part_no == 0 {
278 (mv_size, mv_size >> 2)
279 } else {
280 (mv_size, (3 * mv_size) >> 2)
281 }
282 },
283 PUType::N34Hor => {
284 if part_no == 0 {
285 (mv_size, (3 * mv_size) >> 2)
286 } else {
287 (mv_size, mv_size >> 2)
288 }
289 },
290 PUType::N4Ver => {
291 if part_no == 0 {
292 ( mv_size >> 2, mv_size)
293 } else {
294 ((3 * mv_size) >> 2, mv_size)
295 }
296 },
297 PUType::N34Ver => {
298 if part_no == 0 {
299 ((3 * mv_size) >> 2, mv_size)
300 } else {
301 ( mv_size >> 2, mv_size)
302 }
303 },
304 }
305 }
306 fn has_hor_split(self) -> bool {
307 match self {
308 PUType::N2Hor | PUType::N4Hor | PUType::N34Hor | PUType::Quarters => true,
309 _ => false,
310 }
311 }
312 fn has_ver_split(self) -> bool {
313 match self {
314 PUType::N2Ver | PUType::N4Ver | PUType::N34Ver | PUType::Quarters => true,
315 _ => false,
316 }
317 }
318 }
319
320 impl Default for PUType {
321 fn default() -> Self { PUType::Full }
322 }
323
324 #[derive(Clone,Copy,Debug)]
325 enum IntraMode {
326 Index(u8),
327 Mode(u8),
328 DC64,
329 Plane64,
330 }
331
332 #[derive(Clone,Copy,PartialEq,Debug)]
333 enum TransformType {
334 None,
335 T4X4,
336 T8X8,
337 T16X16,
338 }
339
340 impl Default for TransformType {
341 fn default() -> Self { TransformType::None }
342 }
343
344 #[derive(Clone,Copy,PartialEq,Debug)]
345 enum MVRef {
346 None,
347 Ref0,
348 Ref1,
349 BRef,
350 Ref0AndBRef,
351 Skip0,
352 Skip1,
353 Skip2,
354 Skip3,
355 }
356
357 const SKIP_MV_REF: [MVRef; 4] = [ MVRef::Skip0, MVRef::Skip1, MVRef::Skip2, MVRef::Skip3 ];
358
359 impl MVRef {
360 fn get_skip_mv_num(self) -> usize {
361 match self {
362 MVRef::Skip1 => 1,
363 MVRef::Skip2 => 2,
364 MVRef::Skip3 => 3,
365 _ => 0,
366 }
367 }
368 fn is_ref0(self) -> bool {
369 match self {
370 MVRef::Ref0 | MVRef::Ref0AndBRef => true,
371 _ => false,
372 }
373 }
374 fn is_fwd(self) -> bool {
375 match self {
376 MVRef::Ref0 | MVRef::Ref1 | MVRef::Ref0AndBRef => true,
377 _ => false,
378 }
379 }
380 fn is_bwd(self) -> bool {
381 match self {
382 MVRef::BRef | MVRef::Ref0AndBRef => true,
383 _ => false,
384 }
385 }
386 }
387
388 #[derive(Clone,Copy,PartialEq,Debug)]
389 struct MVInfo {
390 f_mv: MV,
391 b_mv: MV,
392 mvref: MVRef,
393 }
394
395 impl MVInfo {
396 fn is_some(&self) -> bool { self.mvref != MVRef::None }
397 fn matches_fwd(&self, mvref: MVRef) -> bool {
398 (self.mvref == mvref) || (self.mvref.is_ref0() && mvref.is_ref0())
399 }
400 fn matches_bwd(&self, mvref: MVRef) -> bool {
401 self.mvref.is_bwd() && mvref.is_bwd()
402 }
403 fn is_deblock_cand(&self, other: &MVInfo) -> bool {
404 if self.mvref != other.mvref { return true; }
405 let mut mvdiff = 0;
406 if self.mvref.is_fwd() {
407 let diff = self.f_mv - other.f_mv;
408 mvdiff += diff.x.abs() + diff.y.abs();
409 }
410 if self.mvref.is_bwd() {
411 let diff = self.b_mv - other.b_mv;
412 mvdiff += diff.x.abs() + diff.y.abs();
413 }
414 mvdiff > 4
415 }
416 }
417
418 impl Default for MVInfo {
419 fn default() -> Self { Self { f_mv: ZERO_MV, b_mv: ZERO_MV, mvref: MVRef::None } }
420 }
421
422 #[derive(Clone,Copy,Debug)]
423 struct CBHeader {
424 cu_type: CUType,
425 pu_type: PUType,
426 ttype: TransformType,
427 imode: [IntraMode; 4],
428 mv: [MVInfo; 4],
429 }
430
431 impl CBHeader {
432 fn read(br: &mut BitReader, ftype: FrameType, two_f_refs: bool, size: usize) -> DecoderResult<Self> {
433 let cu_type;
434 let pu_type;
435 let mut imode: [IntraMode; 4] = [IntraMode::Index(0); 4];
436 let mut mv: [MVInfo; 4] = [MVInfo::default(); 4];
437 if ftype == FrameType::I {
438 cu_type = CUType::Intra;
439 } else {
440 cu_type = RV60_CU_TYPES[br.read(2)? as usize];
441 }
442 match cu_type {
443 CUType::Intra => {
444 if (size == 8) && br.read_bool()? {
445 pu_type = PUType::Quarters;
446 } else {
447 pu_type = PUType::Full;
448 }
449 if pu_type == PUType::Quarters {
450 for i in 0..4 {
451 imode[i] = CBHeader::read_intra_mode(br)?;
452 }
453 } else if size <= 32 {
454 imode[0] = CBHeader::read_intra_mode(br)?;
455 } else {
456 if !br.read_bool()? {
457 imode[0] = IntraMode::DC64;
458 } else {
459 imode[0] = IntraMode::Plane64;
460 }
461 }
462 },
463 CUType::InterMV => {
464 let bits = if size == 8 { 2 } else { 3 };
465 pu_type = RV60_PU_TYPES[br.read(bits)? as usize];
466 CBHeader::read_mv_data(br, ftype, two_f_refs, size, pu_type, &mut mv)?;
467 },
468 _ => {
469 pu_type = PUType::Full;
470 let skip_mv_no = br.read_code(UintCodeType::LimitedUnary(3, 0))?;
471 mv[0].mvref = SKIP_MV_REF[skip_mv_no as usize];
472 },
473 };
474 let ttype;
475 if cu_type == CUType::Skip {
476 ttype = TransformType::None;
477 } else if size >= 32 {
478 ttype = TransformType::T16X16;
479 } else if size == 16 {
480 if (cu_type == CUType::Intra) || (pu_type == PUType::Full) {
481 ttype = TransformType::T16X16;
482 } else {
483 ttype = TransformType::T4X4;
484 }
485 } else {
486 if pu_type == PUType::Full {
487 ttype = TransformType::T8X8;
488 } else {
489 ttype = TransformType::T4X4;
490 }
491 }
492 Ok(Self {
493 cu_type, pu_type, ttype, imode, mv,
494 })
495 }
496 fn read_intra_mode(br: &mut BitReader) -> DecoderResult<IntraMode> {
497 if br.read_bool()? {
498 let idx = br.read_code(UintCodeType::Unary012)? as u8;
499 Ok(IntraMode::Index(idx))
500 } else {
501 let mode = br.read(5)? as u8;
502 Ok(IntraMode::Mode(mode))
503 }
504 }
505 fn read_mv_data(br: &mut BitReader, ftype: FrameType, two_f_refs: bool, size: usize, pu_type: PUType, mv: &mut [MVInfo; 4]) -> DecoderResult<()> {
506 let mv_count = pu_type.get_num_mvs();
507 for i in 0..mv_count {
508 mv[i] = CBHeader::read_mv_info(br, ftype, two_f_refs, size, pu_type)?;
509 }
510 Ok(())
511 }
512 fn read_mv_info(br: &mut BitReader, ftype: FrameType, two_f_refs: bool, size: usize, pu_type: PUType) -> DecoderResult<MVInfo> {
513 let mut f_mv = ZERO_MV;
514 let mut b_mv = ZERO_MV;
515 let mvref;
516 if ftype != FrameType::B {
517 if two_f_refs && br.read_bool()? {
518 mvref = MVRef::Ref1;
519 } else {
520 mvref = MVRef::Ref0;
521 }
522 f_mv = CBHeader::read_mv(br)?;
523 Ok(MVInfo { f_mv, b_mv: ZERO_MV, mvref })
524 } else {
525 if ((size <= 8) && ((size != 8) || (pu_type != PUType::Full))) || br.read_bool()? {
526 if !br.read_bool()? {
527 mvref = MVRef::Ref0;
528 f_mv = CBHeader::read_mv(br)?;
529 } else {
530 mvref = MVRef::BRef;
531 b_mv = CBHeader::read_mv(br)?;
532 }
533 } else {
534 mvref = MVRef::Ref0AndBRef;
535 f_mv = CBHeader::read_mv(br)?;
536 b_mv = CBHeader::read_mv(br)?;
537 }
538 Ok(MVInfo { f_mv, b_mv, mvref })
539 }
540 }
541 fn read_mv(br: &mut BitReader) -> DecoderResult<MV> {
542 let x = br.read_code_signed(IntCodeType::Gamma)? as i16;
543 let y = br.read_code_signed(IntCodeType::Gamma)? as i16;
544 Ok(MV { x, y })
545 }
546 }
547
548 #[derive(Clone,Copy,Default)]
549 struct PUInfo {
550 cu_type: CUType,
551 ttype: TransformType,
552 }
553
554 impl PUInfo {
555 fn is_intra(self) -> bool { self.cu_type == CUType::Intra }
556 }
557
558 const RV60_CANDIDATE_INTRA_ANGLES: [u8; 6] = [ 0, 1, 10, 26, 18, 2 ];
559
560 #[derive(Clone,Copy,Default)]
561 struct BlockInfo {
562 mv: MVInfo,
563 imode: u8,
564 }
565
566 struct DeblockInfo {
567 left_str: Vec<u8>,
568 top_str: Vec<u8>,
569 stride: usize,
570 }
571
572 impl DeblockInfo {
573 fn new() -> Self {
574 Self { left_str: Vec::new(), top_str: Vec::new(), stride: 0 }
575 }
576 fn reinit(&mut self, w: usize, h: usize) {
577 self.left_str.clear();
578 self.top_str.clear();
579 self.stride = w >> 2;
580 let size = self.stride * (h >> 2);
581 self.left_str.resize(size, 0);
582 self.top_str.resize(size, 0);
583 }
584 fn set_strength(&mut self, xpos: usize, ypos: usize, size: usize, q: u8, strength: u8) {
585 let pos = self.get_pos(xpos, ypos);
586 let dsize = size >> 2;
587 let dval = (q << 2) | strength;
588 for x in 0..dsize {
589 self.top_str[pos + x] = dval;
590 }
591 for y in 0..dsize {
592 self.left_str[pos + y * self.stride] = dval;
593 }
594 }
595 fn get_pos(&self, xpos: usize, ypos: usize) -> usize {
596 (xpos >> 2) + (ypos >> 2) * self.stride
597 }
598 fn get_top_strength(&self, pos: usize) -> u8 {
599 self.top_str[pos] & 3
600 }
601 fn get_left_strength(&self, pos: usize) -> u8 {
602 self.left_str[pos] & 3
603 }
604 fn set_top_strength(&mut self, pos: usize, str: u8) {
605 self.top_str[pos] |= str;
606 }
607 fn set_left_strength(&mut self, pos: usize, str: u8) {
608 self.left_str[pos] |= str;
609 }
610 }
611
612 struct RealVideo60Decoder {
613 info: NACodecInfoRef,
614 cbs: RV60Codebooks,
615 ipbs: IPBShuffler,
616 dsp: RV60DSP,
617 ipred: IntraPredContext,
618
619 avg_buf: NAVideoBufferRef<u8>,
620
621 y_coeffs: [i16; 16 * 16],
622 u_coeffs: [i16; 8 * 8],
623 v_coeffs: [i16; 8 * 8],
624 qp: u8,
625 sel_qp: u8,
626
627 cu_splits: Vec<bool>,
628 coded_blk: [bool; 64],
629 dblk: DeblockInfo,
630
631 pu_info: Vec<PUInfo>,
632 pu_stride: usize,
633 pu_pos: usize,
634
635 blk_info: Vec<BlockInfo>,
636 blk_stride: usize,
637 blk_pos: usize,
638
639 xpos: usize,
640 ypos: usize,
641
642 ts_scale: u64,
643 ref0_pts: u64,
644 ref1_pts: u64,
645 ref0_ts: u64,
646 ref1_ts: u64,
647 }
648
649 impl RealVideo60Decoder {
650 fn new() -> Self {
651 let tmp_vinfo = NAVideoInfo::new(64, 64, false, YUV420_FORMAT);
652 let vt = alloc_video_buffer(tmp_vinfo, 4).unwrap();
653 let vb = vt.get_vbuf();
654 let avg_buf = vb.unwrap();
655 RealVideo60Decoder{
656 info: NACodecInfoRef::default(),
657 cbs: RV60Codebooks::init(),
658 ipbs: IPBShuffler::new(),
659 ipred: IntraPredContext::new(),
660 dsp: RV60DSP::new(),
661 avg_buf,
662 y_coeffs: [0; 16 * 16],
663 u_coeffs: [0; 8 * 8],
664 v_coeffs: [0; 8 * 8],
665 qp: 0,
666 sel_qp: 0,
667 cu_splits: Vec::with_capacity(24),
668 coded_blk: [false; 64],
669 dblk: DeblockInfo::new(),
670 pu_info: Vec::new(),
671 pu_stride: 0,
672 pu_pos: 0,
673 blk_info: Vec::new(),
674 blk_stride: 0,
675 blk_pos: 0,
676 xpos: 0,
677 ypos: 0,
678
679 ts_scale: 1,
680 ref0_pts: 0,
681 ref1_pts: 0,
682 ref0_ts: 0,
683 ref1_ts: 0,
684 }
685 }
686 fn decode_cu_line(&mut self, buf: &mut NASimpleVideoFrame<u8>, hdr: &FrameHeader, src: &[u8], cu_y: usize) -> DecoderResult<()> {
687 let mut br = BitReader::new(src, BitReaderMode::BE);
688 let cu_w = hdr.get_width_cu();
689 let dqp = hdr.read_line_qp_offset(&mut br)?;
690 let qps = (hdr.qp as i8) + dqp;
691 validate!((qps >= 0) && (qps < 32));
692 let qp = qps as u8;
693 self.qp = qp;
694 self.sel_qp = match hdr.osvquant {
695 0 => qp,
696 1 => {
697 if qp <= 25 {
698 qp + 5
699 } else {
700 qp
701 }
702 },
703 _ => {
704 if qp <= 18 {
705 qp + 10
706 } else if qp <= 25 {
707 qp + 5
708 } else {
709 qp
710 }
711 },
712 };
713
714 for cu_x in 0..cu_w {
715 self.cu_splits.clear();
716 self.coded_blk = [false; 64];
717 self.decode_cb_tree(buf, hdr, &mut br, cu_x << 6, cu_y << 6, 6)?;
718 if hdr.deblock {
719 self.cu_splits.reverse();
720 self.deblock_cb_tree(buf, hdr, cu_x << 6, cu_y << 6, 6);
721 }
722 }
723 if br.left() >= 8 {
724 println!(" left {} bits", br.left());
725 }
726 Ok(())
727 }
728 fn decode_cb_tree(&mut self, buf: &mut NASimpleVideoFrame<u8>, hdr: &FrameHeader, br: &mut BitReader, xpos: usize, ypos: usize, log_size: u8) -> DecoderResult<()> {
729 if (xpos >= hdr.width) || (ypos >= hdr.height) { return Ok(()); }
730
731 let size = 1 << log_size;
732 let split = (xpos + size > hdr.width) || (ypos + size > hdr.height) || (size > 8 && br.read_bool()?);
733 self.cu_splits.push(split);
734 if split {
735 let hsize = size >> 1;
736 self.decode_cb_tree(buf, hdr, br, xpos, ypos, log_size - 1)?;
737 self.decode_cb_tree(buf, hdr, br, xpos + hsize, ypos, log_size - 1)?;
738 self.decode_cb_tree(buf, hdr, br, xpos, ypos + hsize, log_size - 1)?;
739 self.decode_cb_tree(buf, hdr, br, xpos + hsize, ypos + hsize, log_size - 1)?;
740 } else {
741 let cbh = CBHeader::read(br, hdr.ftype, hdr.two_f_refs, size)?;
742 self.pu_pos = (xpos >> 3) + (ypos >> 3) * self.pu_stride;
743 self.blk_pos = (xpos >> 2) + (ypos >> 2) * self.blk_stride;
744 self.xpos = xpos;
745 self.ypos = ypos;
746 self.reconstruct_info(hdr, &cbh, size)?;
747
748 let split_i4x4 = (cbh.cu_type == CUType::Intra) && (size == 8) && (cbh.pu_type == PUType::Quarters);
749 match cbh.cu_type {
750 CUType::Intra => {
751 let itype = self.blk_info[self.blk_pos].imode;
752 if !split_i4x4 {
753 let dstride = buf.stride[0];
754 let off = xpos + ypos * dstride;
755 let dst = &mut buf.data;
756 self.populate_ipred(hdr, dst, 0, dstride, 0, 0, size, true);
757 self.ipred.pred_angle(dst, off, dstride, size, itype as usize, true);
758 }
759 for comp in 1..3 {
760 let dstride = buf.stride[comp];
761 let soff = buf.offset[comp];
762 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
763 let mut dst = &mut buf.data;
764 self.populate_ipred(hdr, dst, soff, dstride, 0, 0, size >> 1, false);
765 self.ipred.pred_angle(&mut dst, off, dstride, size >> 1, itype as usize, false);
766 }
767 },
768 _ => {
769 let mut mv_x = xpos >> 2;
770 let mut mv_y = ypos >> 2;
771 let mut mv_pos = mv_x + mv_y * self.blk_stride;
772 for part_no in 0..cbh.pu_type.get_num_mvs() {
773 let (mv_w, mv_h) = cbh.pu_type.get_mv_size(part_no, size);
774 let mv = self.blk_info[mv_pos].mv;
775 let bw = mv_w << 2;
776 let bh = mv_h << 2;
777 let bx = mv_x << 2;
778 let by = mv_y << 2;
779 match mv.mvref {
780 MVRef::Ref0 => {
781 if hdr.ftype != FrameType::B {
782 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
783 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
784 }
785 } else {
786 if let Some(ref prevbuf) = self.ipbs.get_b_fwdref() {
787 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
788 }
789 }
790 },
791 MVRef::Ref1 => {
792 if let Some(ref prevbuf) = self.ipbs.get_nextref() {
793 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
794 }
795 },
796 MVRef::BRef => {
797 validate!(hdr.ftype == FrameType::B);
798 if let Some(ref prevbuf) = self.ipbs.get_b_bwdref() {
799 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.b_mv, false);
800 }
801 },
802 MVRef::Ref0AndBRef => {
803 validate!(hdr.ftype == FrameType::B);
804 if let (Some(ref prevbuf), Some(ref nextbuf)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) {
805 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
806 {
807 let mut avg_buf = NASimpleVideoFrame::from_video_buf(&mut self.avg_buf).unwrap();
808 self.dsp.do_mc(&mut avg_buf, nextbuf, bx, by, bw, bh, mv.b_mv, true);
809 }
810 self.dsp.do_avg(buf, &self.avg_buf, bx, by, bw, bh);
811 }
812 },
813 _ => unreachable!(),
814 };
815 if cbh.pu_type == PUType::Quarters {
816 if part_no != 1 {
817 mv_pos += mv_w;
818 mv_x += mv_w;
819 } else {
820 mv_pos += mv_h * self.blk_stride - mv_w;
821 mv_x -= mv_w;
822 mv_y += mv_h;
823 }
824 } else if cbh.pu_type.has_hor_split() {
825 mv_pos += mv_h * self.blk_stride;
826 mv_y += mv_h;
827 } else if cbh.pu_type.has_ver_split() {
828 mv_pos += mv_w;
829 mv_x += mv_w;
830 }
831 }
832 },
833 };
834 if cbh.ttype != TransformType::None {
835 self.y_coeffs = [0; 16 * 16];
836 self.u_coeffs = [0; 8 * 8];
837 self.v_coeffs = [0; 8 * 8];
838 }
839 let is_intra = cbh.cu_type == CUType::Intra;
840 let cb_pos = ((xpos & 63) >> 3) + ((ypos & 63) >> 3) * 8;
841 match cbh.ttype {
842 TransformType::T4X4 => {
843 let subset = if is_intra { 0 } else { 2 };
844 if size == 16 {
845 let cbp16;
846 if br.read_bool()? {
847 cbp16 = rv6_decode_cbp16(br, &self.cbs, subset, self.sel_qp)?;
848 } else {
849 cbp16 = 0;
850 }
851 if cbp16 != 0 {
852 self.coded_blk[cb_pos + 0] = true;
853 self.coded_blk[cb_pos + 1] = true;
854 self.coded_blk[cb_pos + 8] = true;
855 self.coded_blk[cb_pos + 9] = true;
856 rv6_decode_cu_4x4in16x16(br, &self.cbs, is_intra, self.qp, self.sel_qp, &mut self.y_coeffs, &mut self.u_coeffs, &mut self.v_coeffs, cbp16)?;
857 for y in 0..4 {
858 for x in 0..4 {
859 let i = x + y * 4;
860 if ((cbp16 >> i) & 1) != 0 {
861 self.dsp.transform4x4(&mut self.y_coeffs[i * 16..][..16]);
862 let dstride = buf.stride[0];
863 let off = xpos + x * 4 + (ypos + y * 4) * dstride;
864 let mut dst = &mut buf.data;
865 self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs[i*16..][..16], 4);
866 }
867 }
868 }
869 for y in 0..2 {
870 for x in 0..2 {
871 let i = x + y * 2;
872 let xoff = (xpos >> 1) + x * 4;
873 let yoff = (ypos >> 1) + y * 4;
874 if ((cbp16 >> (16 + i)) & 1) != 0 {
875 self.dsp.transform4x4(&mut self.u_coeffs[i * 16..][..16]);
876 let dstride = buf.stride[1];
877 let off = buf.offset[1] + xoff + yoff * dstride;
878 let mut dst = &mut buf.data;
879 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs[i * 16..][..16], 4);
880 }
881 if ((cbp16 >> (20 + i)) & 1) != 0 {
882 self.dsp.transform4x4(&mut self.v_coeffs[i * 16..][..16]);
883 let dstride = buf.stride[2];
884 let off = buf.offset[2] + xoff + yoff * dstride;
885 let mut dst = &mut buf.data;
886 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs[i * 16..][..16], 4);
887 }
888 }
889 }
890 }
891 } else {
892 let cbp8 = rv6_decode_cbp8(br, &self.cbs, subset, self.sel_qp)?;
893 if cbp8 != 0 {
894 self.coded_blk[cb_pos] = true;
895 rv6_decode_cu_8x8(br, &self.cbs, is_intra, self.qp, self.sel_qp, &mut self.y_coeffs, &mut self.u_coeffs, &mut self.v_coeffs, cbp8, true)?;
896 }
897 for i in 0..4 {
898 let xoff = (i & 1) * 4;
899 let yoff = (i & 2) * 2;
900 if split_i4x4 {
901 let dstride = buf.stride[0];
902 let off = xpos + xoff + (ypos + yoff) * dstride;
903 let mut dst = &mut buf.data;
904 self.populate_ipred(hdr, dst, 0, dstride, xoff, yoff, 4, true);
905 let itype = self.blk_info[self.blk_pos + (i & 1) + (i >> 1) * self.blk_stride].imode;
906 self.ipred.pred_angle(&mut dst, off, dstride, 4, itype as usize, false);
907 }
908 if ((cbp8 >> i) & 1) != 0 {
909 let blk = &mut self.y_coeffs[i * 16..][..16];
910 self.dsp.transform4x4(blk);
911 let dstride = buf.stride[0];
912 let soff = buf.offset[0];
913 let off = soff + xpos + xoff + (ypos + yoff) * dstride;
914 let mut dst = &mut buf.data;
915 self.dsp.add_block(&mut dst, off, dstride, blk, 4);
916 }
917 }
918 if ((cbp8 >> 4) & 1) != 0 {
919 self.dsp.transform4x4(&mut self.u_coeffs);
920 let dstride = buf.stride[1];
921 let soff = buf.offset[1];
922 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
923 let mut dst = &mut buf.data;
924 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 4);
925 }
926 if ((cbp8 >> 5) & 1) != 0 {
927 self.dsp.transform4x4(&mut self.v_coeffs);
928 let dstride = buf.stride[2];
929 let soff = buf.offset[2];
930 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
931 let mut dst = &mut buf.data;
932 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 4);
933 }
934 }
935 },
936 TransformType::T8X8 => {
937 let subset = if is_intra { 1 } else { 3 };
938 let cbp8 = rv6_decode_cbp8(br, &self.cbs, subset, self.sel_qp)?;
939 if cbp8 != 0 {
940 self.coded_blk[cb_pos] = true;
941 rv6_decode_cu_8x8(br, &self.cbs, is_intra, self.qp, self.sel_qp, &mut self.y_coeffs, &mut self.u_coeffs, &mut self.v_coeffs, cbp8, false)?;
942 if (cbp8 & 0xF) != 0 {
943 self.dsp.transform8x8(&mut self.y_coeffs);
944 let dstride = buf.stride[0];
945 let off = xpos + ypos * dstride;
946 let mut dst = &mut buf.data;
947 self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs, 8);
948 }
949 if ((cbp8 >> 4) & 1) != 0 {
950 self.dsp.transform4x4(&mut self.u_coeffs);
951 let dstride = buf.stride[1];
952 let soff = buf.offset[1];
953 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
954 let mut dst = &mut buf.data;
955 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 4);
956 }
957 if ((cbp8 >> 5) & 1) != 0 {
958 self.dsp.transform4x4(&mut self.v_coeffs);
959 let dstride = buf.stride[2];
960 let soff = buf.offset[2];
961 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
962 let mut dst = &mut buf.data;
963 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 4);
964 }
965 }
966 },
967 TransformType::T16X16 => {
968 let subset = if is_intra { 1 } else { 3 };
969 let num_clusters = size >> 4;
970 let cl_cbp = br.read((num_clusters * num_clusters) as u8)?;
971 for y in 0..num_clusters {
972 for x in 0..num_clusters {
973 if ((cl_cbp >> (x + y * num_clusters)) & 1) == 0 { continue; }
974 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 0] = true;
975 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 1] = true;
976 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 8] = true;
977 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 9] = true;
978 let super_cbp = rv6_decode_cbp16(br, &self.cbs, subset, self.sel_qp)?;
979 if super_cbp != 0 {
980 self.y_coeffs = [0; 16 * 16];
981 self.u_coeffs = [0; 8 * 8];
982 self.v_coeffs = [0; 8 * 8];
983 rv6_decode_cu_16x16(br, &self.cbs, is_intra, self.qp, self.sel_qp, &mut self.y_coeffs, &mut self.u_coeffs, &mut self.v_coeffs, super_cbp)?;
984 if (super_cbp & 0xFFFF) != 0 {
985 self.dsp.transform16x16(&mut self.y_coeffs);
986 let dstride = buf.stride[0];
987 let off = xpos + x * 16 + (ypos + y * 16) * dstride;
988 let mut dst = &mut buf.data;
989 self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs, 16);
990 }
991 if ((super_cbp >> 16) & 0xF) != 0 {
992 self.dsp.transform8x8(&mut self.u_coeffs);
993 let dstride = buf.stride[1];
994 let soff = buf.offset[1];
995 let off = soff + (xpos >> 1) + x * 8 + ((ypos >> 1) + y * 8) * dstride;
996 let mut dst = &mut buf.data;
997 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 8);
998 }
999 if ((super_cbp >> 20) & 0xF) != 0 {
1000 self.dsp.transform8x8(&mut self.v_coeffs);
1001 let dstride = buf.stride[2];
1002 let soff = buf.offset[2];
1003 let off = soff + (xpos >> 1) + x * 8 + ((ypos >> 1) + y * 8) * dstride;
1004 let mut dst = &mut buf.data;
1005 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 8);
1006 }
1007 }
1008 }
1009 }
1010 },
1011 _ => {},
1012 };
1013 }
1014 Ok(())
1015 }
1016 fn reconstruct_info(&mut self, hdr: &FrameHeader, cbh: &CBHeader, size: usize) -> DecoderResult<()>{
1017 let mut pui = PUInfo::default();
1018 let pu_size = size >> 3;
1019 pui.cu_type = cbh.cu_type;
1020 pui.ttype = cbh.ttype;
1021 if (cbh.cu_type == CUType::Intra) && (cbh.pu_type == PUType::Quarters) { // very special case
1022 self.pu_info[self.pu_pos] = pui;
1023 for y in 0..2 {
1024 for x in 0..2 {
1025 let imode = self.reconstruct_intra(hdr, cbh, 4, x + y * 2);
1026 validate!(imode <= MAX_IMODE);
1027 self.blk_info[self.blk_pos + x + y * self.blk_stride].imode = imode;
1028 self.blk_info[self.blk_pos + x + y * self.blk_stride].mv = MVInfo::default();
1029 }
1030 }
1031 return Ok(());
1032 }
1033 match cbh.cu_type {
1034 CUType::Intra => {
1035 self.pu_info[self.pu_pos] = pui;
1036 let imode = self.reconstruct_intra(hdr, cbh, size, 0);
1037 validate!(imode <= MAX_IMODE);
1038 for y in 0..(size >> 2) {
1039 for x in 0..(size >> 2) {
1040 self.blk_info[self.blk_pos + x + y * self.blk_stride].imode = imode;
1041 }
1042 }
1043 },
1044 CUType::InterMV => {
1045 let mut mv_x = self.xpos >> 2;
1046 let mut mv_y = self.ypos >> 2;
1047 let mut mv_pos = self.blk_pos;
1048 let pu_type = cbh.pu_type;
1049 for part_no in 0..pu_type.get_num_mvs() {
1050 let (mv_w, mv_h) = pu_type.get_mv_size(part_no, size);
1051 let mv = self.predict_mv(hdr, mv_x, mv_y, mv_w, &cbh.mv[part_no]);
1052 for y in 0..mv_h {
1053 for x in 0..mv_w {
1054 self.blk_info[mv_pos + x + y * self.blk_stride].mv = mv;
1055 }
1056 }
1057 if pu_type == PUType::Quarters {
1058 if part_no != 1 {
1059 mv_pos += mv_w;
1060 mv_x += mv_w;
1061 } else {
1062 mv_pos += mv_h * self.blk_stride - mv_w;
1063 mv_x -= mv_w;
1064 mv_y += mv_h;
1065 }
1066 } else if pu_type.has_hor_split() {
1067 mv_pos += mv_h * self.blk_stride;
1068 mv_y += mv_h;
1069 } else if pu_type.has_ver_split() {
1070 mv_pos += mv_w;
1071 mv_x += mv_w;
1072 }
1073 }
1074 },
1075 _ => {
1076 let skip_idx = cbh.mv[0].mvref.get_skip_mv_num();
1077 let mut skip_cand: UniqueList<MVInfo> = UniqueList::new(4);
1078 self.fill_skip_cand(hdr, &mut skip_cand, size);
1079 let mv = skip_cand.list[skip_idx];
1080
1081 let mv_size = size >> 2;
1082 for y in 0..mv_size {
1083 for x in 0..mv_size {
1084 self.blk_info[self.blk_pos + x + y * self.blk_stride].mv = mv;
1085 }
1086 }
1087 },
1088 };
1089 for y in 0..pu_size {
1090 for x in 0..pu_size {
1091 self.pu_info[self.pu_pos + x + y * self.pu_stride] = pui;
1092 }
1093 }
1094 Ok(())
1095 }
1096 fn reconstruct_intra(&self, hdr: &FrameHeader, cbh: &CBHeader, size: usize, sub: usize) -> u8 {
1097 match cbh.imode[0] {
1098 IntraMode::DC64 => { return 1; },
1099 IntraMode::Plane64 => { return 0; },
1100 _ => {},
1101 };
1102 // form list of predictors
1103 let blk_pos = self.blk_pos + (sub & 1) + (sub >> 1) * self.blk_stride;
1104 let mut ipm_cand: UniqueList<u8> = UniqueList::new(3);
1105 if hdr.has_top_block(self.xpos, self.ypos, (sub & 1) * 4, 0, size) {
1106 let pu = &self.pu_info[self.pu_pos - self.pu_stride];
1107 if pu.is_intra() {
1108 ipm_cand.add(self.blk_info[self.blk_pos + (sub & 1) - self.blk_stride].imode);
1109 }
1110 }
1111 if hdr.has_left_block(self.xpos, self.ypos, 0, (sub & 2) * 2, size) {
1112 let pu = &self.pu_info[self.pu_pos - 1];
1113 if pu.is_intra() {
1114 ipm_cand.add(self.blk_info[blk_pos - 1 - (sub & 1)].imode);
1115 }
1116 }
1117 let tl_x = if (sub & 2) == 0 { self.xpos + (sub & 1) * 4 } else { self.xpos };
1118 let tl_y = self.ypos + (sub & 2) * 4;
1119 if (tl_x > 0) && (tl_y > 0) {
1120 let pu = match sub {
1121 0 => &self.pu_info[self.pu_pos - self.pu_stride - 1],
1122 1 => &self.pu_info[self.pu_pos - self.pu_stride],
1123 2 => &self.pu_info[self.pu_pos - 1],
1124 _ => &self.pu_info[self.pu_pos - 1],
1125 };
1126 if pu.is_intra() {
1127 if sub != 3 {
1128 ipm_cand.add(self.blk_info[blk_pos - self.blk_stride - 1].imode);
1129 } else {
1130 ipm_cand.add(self.blk_info[blk_pos - self.blk_stride - 2].imode);
1131 }
1132 }
1133 }
1134 for el in RV60_CANDIDATE_INTRA_ANGLES.iter() {
1135 ipm_cand.add(*el);
1136 }
1137 // actually decode prediction mode
1138 match cbh.imode[sub] {
1139 IntraMode::Index(idx) => {
1140 ipm_cand.list[idx as usize]
1141 },
1142 IntraMode::Mode(mode) => {
1143 let mut imode = mode;
1144 let mut ipm_cs: [u8; 3] = [ipm_cand.list[0], ipm_cand.list[1], ipm_cand.list[2]];
1145 ipm_cs.sort();
1146 for ic in ipm_cs.iter() {
1147 if imode >= *ic {
1148 imode += 1;
1149 }
1150 }
1151 imode
1152 },
1153 _ => unreachable!(),
1154 }
1155 }
1156 fn populate_ipred(&mut self, hdr: &FrameHeader, src: &[u8], soff: usize, stride: usize, xoff: usize, yoff: usize, size: usize, is_luma: bool) {
1157 let src_off = if is_luma {
1158 soff + self.xpos + xoff + (self.ypos + yoff) * stride
1159 } else {
1160 soff + (self.xpos >> 1) + (self.ypos >> 1) * stride
1161 };
1162 self.ipred = IntraPredContext::new();
1163 if (self.ypos + yoff) > 0 {
1164 self.ipred.has_t = true;
1165 for x in 0..size {
1166 self.ipred.t[x + 1] = src[src_off - stride + x];
1167 }
1168 if (is_luma && hdr.has_top_right_block(self.xpos, self.ypos, xoff, yoff, size)) ||
1169 (!is_luma && hdr.has_top_right_block(self.xpos, self.ypos, 0, 0, size << 1)) {
1170 self.ipred.has_tr = true;
1171 for x in size..size*2 {
1172 self.ipred.t[x + 1] = src[src_off - stride + x];
1173 }
1174 } else {
1175 for i in 0..size {
1176 self.ipred.t[size + i + 1] = self.ipred.t[size];
1177 }
1178 }
1179 if (self.xpos + xoff) > 0 {
1180 self.ipred.t[0] = src[src_off - stride - 1];
1181 }
1182 }
1183 if (self.xpos + xoff) > 0 {
1184 self.ipred.has_l = true;
1185 for y in 0..size {
1186 self.ipred.l[y + 1] = src[src_off - 1 + y * stride];
1187 }
1188 if (is_luma && hdr.has_left_down_block(self.xpos, self.ypos, xoff, yoff, size)) ||
1189 (!is_luma && hdr.has_left_down_block(self.xpos, self.ypos, 0, 0, size << 1)) {
1190 self.ipred.has_ld = true;
1191 for y in size..size*2 {
1192 self.ipred.l[y + 1] = src[src_off - 1 + y * stride];
1193 }
1194 } else {
1195 for i in 0..size {
1196 self.ipred.l[size + i + 1] = self.ipred.l[size];
1197 }
1198 }
1199 if (self.ypos + yoff) > 0 {
1200 self.ipred.l[0] = src[src_off - stride - 1];
1201 }
1202 }
1203 }
1204 fn predict_mv(&self, hdr: &FrameHeader, mv_x: usize, mv_y: usize, mv_w: usize, mvi: &MVInfo) -> MVInfo {
1205 let mv_pos = mv_x + mv_y * self.blk_stride;
1206 let f_mv: MV;
1207 let b_mv: MV;
1208 if mvi.mvref.is_fwd() {
1209 let mut mv_cand: [MV; 3] = [ZERO_MV; 3];
1210 let mut mv_cand_size: usize = 0;
1211 if mv_x > 0 {
1212 let ref_mv = &self.blk_info[mv_pos - 1].mv;
1213 if ref_mv.matches_fwd(mvi.mvref) {
1214 mv_cand[mv_cand_size] = ref_mv.f_mv;
1215 mv_cand_size += 1;
1216 }
1217 }
1218 if mv_y > 0 {
1219 let ref_mv = &self.blk_info[mv_pos - self.blk_stride].mv;
1220 if ref_mv.matches_fwd(mvi.mvref) {
1221 mv_cand[mv_cand_size] = ref_mv.f_mv;
1222 mv_cand_size += 1;
1223 }
1224 }
1225 if hdr.has_top_block(mv_x << 2, mv_y << 2, mv_w << 2, 0, 4) {
1226 let ref_mv = &self.blk_info[mv_pos - self.blk_stride + mv_w].mv;
1227 if ref_mv.matches_fwd(mvi.mvref) {
1228 mv_cand[mv_cand_size] = ref_mv.f_mv;
1229 mv_cand_size += 1;
1230 }
1231 }
1232 f_mv = match mv_cand_size {
1233 1 | 2 => {
1234 let x = mv_cand[0].x + mv_cand[1].x + mv_cand[2].x;
1235 let y = mv_cand[0].y + mv_cand[1].y + mv_cand[2].y;
1236 if mv_cand_size == 1 {
1237 MV { x, y }
1238 } else {
1239 MV { x: x >> 1, y: y >> 1 }
1240 }
1241 },
1242 3 => MV::pred(mv_cand[0], mv_cand[1], mv_cand[2]),
1243 _ => ZERO_MV,
1244 };
1245 } else {
1246 f_mv = ZERO_MV;
1247 }
1248 if mvi.mvref.is_bwd() {
1249 let mut mv_cand: [MV; 3] = [ZERO_MV; 3];
1250 let mut mv_cand_size: usize = 0;
1251 if mv_x > 0 {
1252 let ref_mv = &self.blk_info[mv_pos - 1].mv;
1253 if ref_mv.matches_bwd(mvi.mvref) {
1254 mv_cand[mv_cand_size] = ref_mv.b_mv;
1255 mv_cand_size += 1;
1256 }
1257 }
1258 if mv_y > 0 {
1259 let ref_mv = &self.blk_info[mv_pos - self.blk_stride].mv;
1260 if ref_mv.matches_bwd(mvi.mvref) {
1261 mv_cand[mv_cand_size] = ref_mv.b_mv;
1262 mv_cand_size += 1;
1263 }
1264 }
1265 if hdr.has_top_block(mv_x << 2, mv_y << 2, mv_w << 2, 0, 4) {
1266 let ref_mv = &self.blk_info[mv_pos - self.blk_stride + mv_w].mv;
1267 if ref_mv.matches_bwd(mvi.mvref) {
1268 mv_cand[mv_cand_size] = ref_mv.b_mv;
1269 mv_cand_size += 1;
1270 }
1271 }
1272 b_mv = match mv_cand_size {
1273 1 | 2 => {
1274 let x = mv_cand[0].x + mv_cand[1].x + mv_cand[2].x;
1275 let y = mv_cand[0].y + mv_cand[1].y + mv_cand[2].y;
1276 if mv_cand_size == 1 {
1277 MV { x, y }
1278 } else {
1279 MV { x: x >> 1, y: y >> 1 }
1280 }
1281 },
1282 3 => MV::pred(mv_cand[0], mv_cand[1], mv_cand[2]),
1283 _ => ZERO_MV,
1284 };
1285 } else {
1286 b_mv = ZERO_MV;
1287 }
1288
1289 MVInfo { f_mv: mvi.f_mv + f_mv, b_mv: mvi.b_mv + b_mv, mvref: mvi.mvref }
1290 }
1291 fn fill_skip_cand(&mut self, hdr: &FrameHeader, skip_cand: &mut UniqueList<MVInfo>, size: usize) {
1292 let mv_size = size >> 2;
1293
1294 if self.xpos > 0 {
1295 let mv = &self.blk_info[self.blk_pos - 1].mv;
1296 if mv.is_some() {
1297 skip_cand.add(*mv);
1298 }
1299 }
1300 if self.ypos > 0 {
1301 let mv = &self.blk_info[self.blk_pos - self.blk_stride].mv;
1302 if mv.is_some() {
1303 skip_cand.add(*mv);
1304 }
1305 }
1306 if hdr.has_top_right_block(self.xpos, self.ypos, 0, 0, size) {
1307 let mv = &self.blk_info[self.blk_pos - self.blk_stride + mv_size].mv;
1308 if mv.is_some() {
1309 skip_cand.add(*mv);
1310 }
1311 }
1312 if hdr.has_left_down_block(self.xpos, self.ypos, 0, 0, size) {
1313 let mv = &self.blk_info[self.blk_pos + self.blk_stride * mv_size - 1].mv;
1314 if mv.is_some() {
1315 skip_cand.add(*mv);
1316 }
1317 }
1318 if hdr.has_left_block(self.xpos, self.ypos, 0, 0, size) {
1319 let mv = &self.blk_info[self.blk_pos + self.blk_stride * (mv_size - 1) - 1].mv;
1320 if mv.is_some() {
1321 skip_cand.add(*mv);
1322 }
1323 }
1324 if hdr.has_top_block(self.xpos, self.ypos, 0, 0, size) {
1325 let mv = &self.blk_info[self.blk_pos - self.blk_stride + mv_size - 1].mv;
1326 if mv.is_some() {
1327 skip_cand.add(*mv);
1328 }
1329 }
1330 if (self.xpos > 0) && (self.ypos > 0) {
1331 let mv = &self.blk_info[self.blk_pos - self.blk_stride - 1].mv;
1332 if mv.is_some() {
1333 skip_cand.add(*mv);
1334 }
1335 }
1336 for i in skip_cand.fill..4 {
1337 skip_cand.list[i] = MVInfo { f_mv: ZERO_MV, b_mv: ZERO_MV, mvref: MVRef::Ref0 };
1338 }
1339 }
1340 fn deblock_cb_tree(&mut self, buf: &mut NASimpleVideoFrame<u8>, hdr: &FrameHeader, xpos: usize, ypos: usize, log_size: u8) {
1341 if (xpos >= hdr.width) || (ypos >= hdr.height) { return; }
1342 let split = (log_size > 3) && self.cu_splits.pop().unwrap();
1343 if split {
1344 let hsize = 1 << (log_size - 1);
1345 self.deblock_cb_tree(buf, hdr, xpos, ypos, log_size - 1);
1346 self.deblock_cb_tree(buf, hdr, xpos + hsize, ypos, log_size - 1);
1347 self.deblock_cb_tree(buf, hdr, xpos, ypos + hsize, log_size - 1);
1348 self.deblock_cb_tree(buf, hdr, xpos + hsize, ypos + hsize, log_size - 1);
1349 } else {
1350 let pu_pos = (xpos >> 3) + (ypos >> 3) * self.pu_stride;
1351 let cu_type = self.pu_info[pu_pos].cu_type;
1352 let tsize = if self.pu_info[pu_pos].ttype == TransformType::T16X16 { 4 } else { 3 };
1353 let ntiles = 1 << (log_size - tsize);
1354 let dparams = RV60DeblockParams {
1355 deblock_chroma: hdr.deblock_chroma,
1356 width: hdr.width,
1357 height: hdr.height,
1358 dblkstride: self.dblk.stride,
1359 };
1360 for ty in 0..ntiles {
1361 for tx in 0..ntiles {
1362 let x = xpos + (tx << tsize);
1363 let y = ypos + (ty << tsize);
1364 let cb_pos = ((x & 63) >> 3) + ((y & 63) >> 3) * 8;
1365 if cu_type == CUType::Intra {
1366 self.dblk.set_strength(x, y, 1 << tsize, self.qp, 2);
1367 } else if (cu_type != CUType::Skip) && self.coded_blk[cb_pos] {
1368 self.dblk.set_strength(x, y, 1 << tsize, self.qp, 1);
1369 } else {
1370 self.dblk.set_strength(x, y, 1 << tsize, self.qp, 0);
1371 self.derive_deblock_strength(x, y, 1 << (tsize - 2));
1372 }
1373 self.dsp.do_deblock(&dparams, buf, x, y, 1 << tsize,
1374 self.dblk.top_str.as_slice(),
1375 self.dblk.left_str.as_slice(),
1376 self.dblk.get_pos(x, y));
1377 }
1378 }
1379 }
1380 }
1381 fn derive_deblock_strength(&mut self, xpos: usize, ypos: usize, size4: usize) {
1382 let blk_pos = (xpos >> 2) + (ypos >> 2) * self.blk_stride;
1383 let mut dblk_pos = self.dblk.get_pos(xpos, ypos);
1384 if ypos > 0 {
1385 let top_blk_pos = blk_pos - self.blk_stride;
1386 for i in 0..size4 {
1387 if self.dblk.get_top_strength(dblk_pos + i) == 0 {
1388 if self.blk_info[blk_pos + i].mv.is_deblock_cand(&self.blk_info[top_blk_pos + i].mv) {
1389 self.dblk.set_top_strength(dblk_pos + i, 1);
1390 }
1391 }
1392 }
1393 }
1394 if xpos > 0 {
1395 for i in 0..size4 {
1396 if self.dblk.get_left_strength(dblk_pos) == 0 {
1397 if self.blk_info[blk_pos + i].mv.is_deblock_cand(&self.blk_info[blk_pos + i - 1].mv) {
1398 self.dblk.set_left_strength(dblk_pos, 1);
1399 }
1400 }
1401 dblk_pos += self.dblk.stride;
1402 }
1403 }
1404 }
1405 }
1406
1407 impl NADecoder for RealVideo60Decoder {
1408 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
1409 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
1410 let fmt = YUV420_FORMAT;
1411 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
1412 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
1413
1414 let edata = info.get_extradata().unwrap();
1415 let src: &[u8] = &edata;
1416
1417 if src.len() < 8 { return Err(DecoderError::InvalidData); }
1418 let mut mr = MemoryReader::new_read(src);
1419 let mut br = ByteReader::new(&mut mr);
1420 let _flags = br.read_u32be()?;
1421 let version = br.read_u32be()?;
1422 let _unk = br.read_u16be()?;
1423 validate!((version >> 28) == 4);
1424 // then width and height again as 16be
1425
1426 //self.bd.width = vinfo.get_width();
1427 //self.bd.height = vinfo.get_height();
1428 //self.frmmgr.clear();
1429
1430 supp.pool_u8.set_dec_bufs(3);
1431 supp.pool_u8.prealloc_video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt), 6)?;
1432
1433 Ok(())
1434 } else {
1435 println!("???");
1436 Err(DecoderError::InvalidData)
1437 }
1438 }
1439 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1440 let src = pkt.get_buffer();
1441
1442 validate!(src.len() > 9);
1443 let hsize = (src[0] as usize) * 8 + 9;
1444 let mut br = BitReader::new(&src[hsize..], BitReaderMode::BE);
1445 let hdr = FrameHeader::read(&mut br)?;
1446 let mut slices: Vec<usize> = Vec::new();
1447 hdr.parse_slice_sizes(&mut br, &mut slices)?;
1448 match hdr.ftype {
1449 FrameType::P => {
1450 if self.ipbs.get_lastref().is_none() {
1451 return Err(DecoderError::MissingReference);
1452 }
1453 },
1454 FrameType::B => {
1455 if self.ipbs.get_lastref().is_none() {
1456 return Err(DecoderError::MissingReference);
1457 }
1458 if self.ipbs.get_nextref().is_none() {
1459 return Err(DecoderError::MissingReference);
1460 }
1461 },
1462 _ => {},
1463 };
1464
1465 let tmp_vinfo = NAVideoInfo::new(hdr.width, hdr.height, false, YUV420_FORMAT);
1466 let ret = supp.pool_u8.get_free();
1467 if ret.is_none() {
1468 return Err(DecoderError::AllocError);
1469 }
1470 let mut buf = ret.unwrap();
1471 if buf.get_info() != tmp_vinfo {
1472 self.ipbs.clear();
1473 supp.pool_u8.reset();
1474 supp.pool_u8.prealloc_video(tmp_vinfo, 6)?;
1475 let ret = supp.pool_u8.get_free();
1476 if ret.is_none() {
1477 return Err(DecoderError::AllocError);
1478 }
1479 buf = ret.unwrap();
1480 }
1481
1482 let cu_w = hdr.get_width_cu();
1483 let cu_h = hdr.get_height_cu();
1484 self.pu_stride = cu_w << 3;
1485 self.pu_info.resize(self.pu_stride * (cu_h << 3), PUInfo::default());
1486 self.blk_stride = cu_w << 4;
1487 self.blk_info.truncate(0);
1488 self.blk_info.resize(self.blk_stride * (cu_h << 4), BlockInfo::default());
1489 if hdr.deblock {
1490 self.dblk.reinit(hdr.width, hdr.height);
1491 }
1492 let mut off = hsize + ((br.tell() >> 3) as usize);
1493 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
1494 for (cu_y, size) in slices.into_iter().enumerate() {
1495 self.decode_cu_line(&mut dframe, &hdr, &src[off..][..size], cu_y)?;
1496 off += size;
1497 }
1498 if (hdr.ftype == FrameType::I) || (hdr.ftype == FrameType::P) {
1499 self.ipbs.add_frame(buf.clone());
1500 }
1501
1502 if hdr.ftype != FrameType::B {
1503 self.ref0_pts = self.ref1_pts;
1504 self.ref1_pts = pkt.get_pts().unwrap_or(0);
1505 self.ref0_ts = self.ref1_ts;
1506 self.ref1_ts = hdr.ts as u64;
1507 if (self.ref1_pts > self.ref0_pts) && (self.ref1_ts > self.ref0_ts) {
1508 self.ts_scale = (self.ref1_pts - self.ref0_pts) / (self.ref1_ts - self.ref0_ts);
1509 }
1510 }
1511 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
1512 frm.set_keyframe(hdr.ftype == FrameType::I);
1513 if hdr.ftype == FrameType::B {
1514 let pts = self.ref0_pts + ((hdr.ts as u64) - self.ref0_ts) * self.ts_scale;
1515 frm.set_pts(Some(pts));
1516 }
1517 frm.set_frame_type(hdr.ftype);
1518 Ok(frm.into_ref())
1519 }
1520 fn flush(&mut self) {
1521 self.ipbs.clear();
1522 }
1523 }
1524
1525 impl NAOptionHandler for RealVideo60Decoder {
1526 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1527 fn set_options(&mut self, _options: &[NAOption]) { }
1528 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1529 }
1530
1531 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
1532 Box::new(RealVideo60Decoder::new())
1533 }
1534
1535 #[cfg(test)]
1536 mod test {
1537 use nihav_core::codecs::RegisteredDecoders;
1538 use nihav_core::demuxers::RegisteredDemuxers;
1539 use nihav_codec_support::test::dec_video::*;
1540 use crate::realmedia_register_all_codecs;
1541 use crate::realmedia_register_all_demuxers;
1542 #[test]
1543 fn test_rv60() {
1544 let mut dmx_reg = RegisteredDemuxers::new();
1545 realmedia_register_all_demuxers(&mut dmx_reg);
1546 let mut dec_reg = RegisteredDecoders::new();
1547 realmedia_register_all_codecs(&mut dec_reg);
1548
1549 test_file_decoding("realmedia", "assets/RV/RV60.rmhd", Some(4000), true, false, None/*Some("rv60")*/, &dmx_reg, &dec_reg);
1550 //panic!("end");
1551 }
1552 }