]> git.nihav.org Git - nihav.git/blob - nihav-realmedia/src/codecs/rv60.rs
007450ae2d72ef965f5b2d88771ec5c6f2ff3833
[nihav.git] / nihav-realmedia / src / codecs / rv60.rs
1 use std::rc::Rc;
2 use std::cell::RefCell;
3 use nihav_core::formats::YUV420_FORMAT;
4 use nihav_core::frame::*;
5 use nihav_core::codecs::{NADecoder, MV, ZERO_MV, DecoderError, DecoderResult, 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.into_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: Rc<NACodecInfo>,
614 cbs: RV60Codebooks,
615 ipbs: IPBShuffler,
616 dsp: RV60DSP,
617 ipred: IntraPredContext,
618
619 avg_buf: NAVideoBuffer<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
643 impl RealVideo60Decoder {
644 fn new() -> Self {
645 let tmp_vinfo = NAVideoInfo::new(64, 64, false, YUV420_FORMAT);
646 let vt = alloc_video_buffer(tmp_vinfo, 4).unwrap();
647 let vb = vt.get_vbuf();
648 let avg_buf = vb.unwrap();
649 RealVideo60Decoder{
650 info: Rc::new(DUMMY_CODEC_INFO),
651 cbs: RV60Codebooks::init(),
652 ipbs: IPBShuffler::new(),
653 ipred: IntraPredContext::new(),
654 dsp: RV60DSP::new(),
655 avg_buf: avg_buf,
656 y_coeffs: [0; 16 * 16],
657 u_coeffs: [0; 8 * 8],
658 v_coeffs: [0; 8 * 8],
659 qp: 0,
660 sel_qp: 0,
661 cu_splits: Vec::with_capacity(24),
662 coded_blk: [false; 64],
663 dblk: DeblockInfo::new(),
664 pu_info: Vec::new(),
665 pu_stride: 0,
666 pu_pos: 0,
667 blk_info: Vec::new(),
668 blk_stride: 0,
669 blk_pos: 0,
670 xpos: 0,
671 ypos: 0,
672 }
673 }
674 fn decode_cu_line(&mut self, buf: &mut NAVideoBuffer<u8>, hdr: &FrameHeader, src: &[u8], cu_y: usize) -> DecoderResult<()> {
675 let mut br = BitReader::new(src, src.len(), BitReaderMode::BE);
676 let cu_w = hdr.get_width_cu();
677 let dqp = hdr.read_line_qp_offset(&mut br)?;
678 let qps = (hdr.qp as i8) + dqp;
679 validate!((qps >= 0) && (qps < 32));
680 let qp = qps as u8;
681 self.qp = qp;
682 self.sel_qp = match hdr.osvquant {
683 0 => qp,
684 1 => {
685 if qp <= 25 {
686 qp + 5
687 } else {
688 qp
689 }
690 },
691 _ => {
692 if qp <= 18 {
693 qp + 10
694 } else if qp <= 25 {
695 qp + 5
696 } else {
697 qp
698 }
699 },
700 };
701
702 for cu_x in 0..cu_w {
703 self.cu_splits.clear();
704 self.coded_blk = [false; 64];
705 self.decode_cb_tree(buf, hdr, &mut br, cu_x << 6, cu_y << 6, 6)?;
706 if hdr.deblock {
707 self.cu_splits.reverse();
708 self.deblock_cb_tree(buf, hdr, cu_x << 6, cu_y << 6, 6);
709 }
710 }
711 if br.left() >= 8 {
712 println!(" left {} bits", br.left());
713 }
714 Ok(())
715 }
716 fn decode_cb_tree(&mut self, buf: &mut NAVideoBuffer<u8>, hdr: &FrameHeader, br: &mut BitReader, xpos: usize, ypos: usize, log_size: u8) -> DecoderResult<()> {
717 if (xpos >= hdr.width) || (ypos >= hdr.height) { return Ok(()); }
718
719 let size = 1 << log_size;
720 let split = (xpos + size > hdr.width) || (ypos + size > hdr.height) || (size > 8 && br.read_bool()?);
721 self.cu_splits.push(split);
722 if split {
723 let hsize = size >> 1;
724 self.decode_cb_tree(buf, hdr, br, xpos, ypos, log_size - 1)?;
725 self.decode_cb_tree(buf, hdr, br, xpos + hsize, ypos, log_size - 1)?;
726 self.decode_cb_tree(buf, hdr, br, xpos, ypos + hsize, log_size - 1)?;
727 self.decode_cb_tree(buf, hdr, br, xpos + hsize, ypos + hsize, log_size - 1)?;
728 } else {
729 let cbh = CBHeader::read(br, hdr.ftype, hdr.two_f_refs, size)?;
730 self.pu_pos = (xpos >> 3) + (ypos >> 3) * self.pu_stride;
731 self.blk_pos = (xpos >> 2) + (ypos >> 2) * self.blk_stride;
732 self.xpos = xpos;
733 self.ypos = ypos;
734 self.reconstruct_info(hdr, &cbh, size)?;
735
736 let split_i4x4 = (cbh.cu_type == CUType::Intra) && (size == 8) && (cbh.pu_type == PUType::Quarters);
737 match cbh.cu_type {
738 CUType::Intra => {
739 let itype = self.blk_info[self.blk_pos].imode;
740 if !split_i4x4 {
741 let dstride = buf.get_stride(0);
742 let off = xpos + ypos * dstride;
743 let mut data = buf.get_data_mut().unwrap();
744 let dst = &mut data;
745 self.populate_ipred(hdr, dst, 0, dstride, 0, 0, size, true);
746 self.ipred.pred_angle(dst, off, dstride, size, itype as usize, true);
747 }
748 for comp in 1..3 {
749 let dstride = buf.get_stride(comp);
750 let soff = buf.get_offset(comp);
751 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
752 let mut data = buf.get_data_mut().unwrap();
753 let mut dst = &mut data;
754 self.populate_ipred(hdr, dst, soff, dstride, 0, 0, size >> 1, false);
755 self.ipred.pred_angle(&mut dst, off, dstride, size >> 1, itype as usize, false);
756 }
757 },
758 _ => {
759 let mut mv_x = xpos >> 2;
760 let mut mv_y = ypos >> 2;
761 let mut mv_pos = mv_x + mv_y * self.blk_stride;
762 for part_no in 0..cbh.pu_type.get_num_mvs() {
763 let (mv_w, mv_h) = cbh.pu_type.get_mv_size(part_no, size);
764 let mv = self.blk_info[mv_pos].mv;
765 let bw = mv_w << 2;
766 let bh = mv_h << 2;
767 let bx = mv_x << 2;
768 let by = mv_y << 2;
769 match mv.mvref {
770 MVRef::Ref0 => {
771 if hdr.ftype != FrameType::B {
772 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
773 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
774 }
775 } else {
776 if let Some(ref prevbuf) = self.ipbs.get_b_fwdref() {
777 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
778 }
779 }
780 },
781 MVRef::Ref1 => {
782 if let Some(ref prevbuf) = self.ipbs.get_nextref() {
783 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
784 }
785 },
786 MVRef::BRef => {
787 validate!(hdr.ftype == FrameType::B);
788 if let Some(ref prevbuf) = self.ipbs.get_b_bwdref() {
789 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.b_mv, false);
790 }
791 },
792 MVRef::Ref0AndBRef => {
793 validate!(hdr.ftype == FrameType::B);
794 if let (Some(ref prevbuf), Some(ref nextbuf)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) {
795 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
796 self.dsp.do_mc(&mut self.avg_buf, nextbuf, bx, by, bw, bh, mv.b_mv, true);
797 self.dsp.do_avg(buf, &self.avg_buf, bx, by, bw, bh);
798 }
799 },
800 _ => unreachable!(),
801 };
802 if cbh.pu_type == PUType::Quarters {
803 if part_no != 1 {
804 mv_pos += mv_w;
805 mv_x += mv_w;
806 } else {
807 mv_pos += mv_h * self.blk_stride - mv_w;
808 mv_x -= mv_w;
809 mv_y += mv_h;
810 }
811 } else if cbh.pu_type.has_hor_split() {
812 mv_pos += mv_h * self.blk_stride;
813 mv_y += mv_h;
814 } else if cbh.pu_type.has_ver_split() {
815 mv_pos += mv_w;
816 mv_x += mv_w;
817 }
818 }
819 },
820 };
821 if cbh.ttype != TransformType::None {
822 self.y_coeffs = [0; 16 * 16];
823 self.u_coeffs = [0; 8 * 8];
824 self.v_coeffs = [0; 8 * 8];
825 }
826 let is_intra = cbh.cu_type == CUType::Intra;
827 let cb_pos = ((xpos & 63) >> 3) + ((ypos & 63) >> 3) * 8;
828 match cbh.ttype {
829 TransformType::T4X4 => {
830 let subset = if is_intra { 0 } else { 2 };
831 if size == 16 {
832 let cbp16;
833 if br.read_bool()? {
834 cbp16 = rv6_decode_cbp16(br, &self.cbs, subset, self.sel_qp)?;
835 } else {
836 cbp16 = 0;
837 }
838 if cbp16 != 0 {
839 self.coded_blk[cb_pos + 0] = true;
840 self.coded_blk[cb_pos + 1] = true;
841 self.coded_blk[cb_pos + 8] = true;
842 self.coded_blk[cb_pos + 9] = true;
843 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)?;
844 for y in 0..4 {
845 for x in 0..4 {
846 let i = x + y * 4;
847 if ((cbp16 >> i) & 1) != 0 {
848 self.dsp.transform4x4(&mut self.y_coeffs[i * 16..][..16]);
849 let dstride = buf.get_stride(0);
850 let off = xpos + x * 4 + (ypos + y * 4) * dstride;
851 let mut data = buf.get_data_mut().unwrap();
852 let mut dst = &mut data;
853 self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs[i*16..][..16], 4);
854 }
855 }
856 }
857 for y in 0..2 {
858 for x in 0..2 {
859 let i = x + y * 2;
860 let xoff = (xpos >> 1) + x * 4;
861 let yoff = (ypos >> 1) + y * 4;
862 if ((cbp16 >> (16 + i)) & 1) != 0 {
863 self.dsp.transform4x4(&mut self.u_coeffs[i * 16..][..16]);
864 let dstride = buf.get_stride(1);
865 let off = buf.get_offset(1) + xoff + yoff * dstride;
866 let mut data = buf.get_data_mut().unwrap();
867 let mut dst = &mut data;
868 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs[i * 16..][..16], 4);
869 }
870 if ((cbp16 >> (20 + i)) & 1) != 0 {
871 self.dsp.transform4x4(&mut self.v_coeffs[i * 16..][..16]);
872 let dstride = buf.get_stride(2);
873 let off = buf.get_offset(2) + xoff + yoff * dstride;
874 let mut data = buf.get_data_mut().unwrap();
875 let mut dst = &mut data;
876 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs[i * 16..][..16], 4);
877 }
878 }
879 }
880 }
881 } else {
882 let cbp8 = rv6_decode_cbp8(br, &self.cbs, subset, self.sel_qp)?;
883 if cbp8 != 0 {
884 self.coded_blk[cb_pos] = true;
885 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)?;
886 }
887 for i in 0..4 {
888 let xoff = (i & 1) * 4;
889 let yoff = (i & 2) * 2;
890 if split_i4x4 {
891 let dstride = buf.get_stride(0);
892 let off = xpos + xoff + (ypos + yoff) * dstride;
893 let mut data = buf.get_data_mut().unwrap();
894 let mut dst = &mut data;
895 self.populate_ipred(hdr, dst, 0, dstride, xoff, yoff, 4, true);
896 let itype = self.blk_info[self.blk_pos + (i & 1) + (i >> 1) * self.blk_stride].imode;
897 self.ipred.pred_angle(&mut dst, off, dstride, 4, itype as usize, false);
898 }
899 if ((cbp8 >> i) & 1) != 0 {
900 let blk = &mut self.y_coeffs[i * 16..][..16];
901 self.dsp.transform4x4(blk);
902 let dstride = buf.get_stride(0);
903 let soff = buf.get_offset(0);
904 let off = soff + xpos + xoff + (ypos + yoff) * dstride;
905 let mut data = buf.get_data_mut().unwrap();
906 let mut dst = &mut data;
907 self.dsp.add_block(&mut dst, off, dstride, blk, 4);
908 }
909 }
910 if ((cbp8 >> 4) & 1) != 0 {
911 self.dsp.transform4x4(&mut self.u_coeffs);
912 let dstride = buf.get_stride(1);
913 let soff = buf.get_offset(1);
914 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
915 let mut data = buf.get_data_mut().unwrap();
916 let mut dst = &mut data;
917 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 4);
918 }
919 if ((cbp8 >> 5) & 1) != 0 {
920 self.dsp.transform4x4(&mut self.v_coeffs);
921 let dstride = buf.get_stride(2);
922 let soff = buf.get_offset(2);
923 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
924 let mut data = buf.get_data_mut().unwrap();
925 let mut dst = &mut data;
926 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 4);
927 }
928 }
929 },
930 TransformType::T8X8 => {
931 let subset = if is_intra { 1 } else { 3 };
932 let cbp8 = rv6_decode_cbp8(br, &self.cbs, subset, self.sel_qp)?;
933 if cbp8 != 0 {
934 self.coded_blk[cb_pos] = true;
935 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)?;
936 if (cbp8 & 0xF) != 0 {
937 self.dsp.transform8x8(&mut self.y_coeffs);
938 let dstride = buf.get_stride(0);
939 let off = xpos + ypos * dstride;
940 let mut data = buf.get_data_mut().unwrap();
941 let mut dst = &mut data;
942 self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs, 8);
943 }
944 if ((cbp8 >> 4) & 1) != 0 {
945 self.dsp.transform4x4(&mut self.u_coeffs);
946 let dstride = buf.get_stride(1);
947 let soff = buf.get_offset(1);
948 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
949 let mut data = buf.get_data_mut().unwrap();
950 let mut dst = &mut data;
951 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 4);
952 }
953 if ((cbp8 >> 5) & 1) != 0 {
954 self.dsp.transform4x4(&mut self.v_coeffs);
955 let dstride = buf.get_stride(2);
956 let soff = buf.get_offset(2);
957 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
958 let mut data = buf.get_data_mut().unwrap();
959 let mut dst = &mut data;
960 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 4);
961 }
962 }
963 },
964 TransformType::T16X16 => {
965 let subset = if is_intra { 1 } else { 3 };
966 let num_clusters = size >> 4;
967 let cl_cbp = br.read((num_clusters * num_clusters) as u8)?;
968 for y in 0..num_clusters {
969 for x in 0..num_clusters {
970 if ((cl_cbp >> (x + y * num_clusters)) & 1) == 0 { continue; }
971 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 0] = true;
972 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 1] = true;
973 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 8] = true;
974 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 9] = true;
975 let super_cbp = rv6_decode_cbp16(br, &self.cbs, subset, self.sel_qp)?;
976 if super_cbp != 0 {
977 self.y_coeffs = [0; 16 * 16];
978 self.u_coeffs = [0; 8 * 8];
979 self.v_coeffs = [0; 8 * 8];
980 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)?;
981 if (super_cbp & 0xFFFF) != 0 {
982 self.dsp.transform16x16(&mut self.y_coeffs);
983 let dstride = buf.get_stride(0);
984 let off = xpos + x * 16 + (ypos + y * 16) * dstride;
985 let mut data = buf.get_data_mut().unwrap();
986 let mut dst = &mut data;
987 self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs, 16);
988 }
989 if ((super_cbp >> 16) & 0xF) != 0 {
990 self.dsp.transform8x8(&mut self.u_coeffs);
991 let dstride = buf.get_stride(1);
992 let soff = buf.get_offset(1);
993 let off = soff + (xpos >> 1) + x * 8 + ((ypos >> 1) + y * 8) * dstride;
994 let mut data = buf.get_data_mut().unwrap();
995 let mut dst = &mut data;
996 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 8);
997 }
998 if ((super_cbp >> 20) & 0xF) != 0 {
999 self.dsp.transform8x8(&mut self.v_coeffs);
1000 let dstride = buf.get_stride(2);
1001 let soff = buf.get_offset(2);
1002 let off = soff + (xpos >> 1) + x * 8 + ((ypos >> 1) + y * 8) * dstride;
1003 let mut data = buf.get_data_mut().unwrap();
1004 let mut dst = &mut 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.into_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.into_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 NAVideoBuffer<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, info: Rc<NACodecInfo>) -> 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 = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
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 Ok(())
1430 } else {
1431 println!("???");
1432 Err(DecoderError::InvalidData)
1433 }
1434 }
1435 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1436 let src = pkt.get_buffer();
1437
1438 validate!(src.len() > 9);
1439 let hsize = (src[0] as usize) * 8 + 9;
1440 let mut br = BitReader::new(&src[hsize..], src.len() - hsize, BitReaderMode::BE);
1441 let hdr = FrameHeader::read(&mut br)?;
1442 let mut slices: Vec<usize> = Vec::new();
1443 hdr.parse_slice_sizes(&mut br, &mut slices)?;
1444
1445 let tmp_vinfo = NAVideoInfo::new(hdr.width, hdr.height, false, YUV420_FORMAT);
1446 let res = alloc_video_buffer(tmp_vinfo, 6);
1447 if !res.is_ok() { return Err(DecoderError::InvalidData); }
1448 let bufinfo = res.unwrap();
1449 let mut buf = bufinfo.get_vbuf().unwrap();
1450
1451 let cu_w = hdr.get_width_cu();
1452 let cu_h = hdr.get_height_cu();
1453 self.pu_stride = cu_w << 3;
1454 self.pu_info.resize(self.pu_stride * (cu_h << 3), PUInfo::default());
1455 self.blk_stride = cu_w << 4;
1456 self.blk_info.truncate(0);
1457 self.blk_info.resize(self.blk_stride * (cu_h << 4), BlockInfo::default());
1458 if hdr.deblock {
1459 self.dblk.reinit(hdr.width, hdr.height);
1460 }
1461 let mut off = hsize + ((br.tell() >> 3) as usize);
1462 for (cu_y, size) in slices.into_iter().enumerate() {
1463 self.decode_cu_line(&mut buf, &hdr, &src[off..][..size], cu_y)?;
1464 off += size;
1465 }
1466 if (hdr.ftype == FrameType::I) || (hdr.ftype == FrameType::P) {
1467 self.ipbs.add_frame(buf);
1468 }
1469
1470 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
1471 frm.set_keyframe(hdr.ftype == FrameType::I);
1472 frm.set_pts(Some(hdr.ts as u64));
1473 frm.set_frame_type(hdr.ftype);
1474 Ok(Rc::new(RefCell::new(frm)))
1475 }
1476 }
1477
1478 pub fn get_decoder() -> Box<NADecoder> {
1479 Box::new(RealVideo60Decoder::new())
1480 }
1481
1482 #[cfg(test)]
1483 mod test {
1484 use nihav_core::codecs::RegisteredDecoders;
1485 use nihav_core::demuxers::RegisteredDemuxers;
1486 use nihav_core::test::dec_video::*;
1487 use crate::codecs::realmedia_register_all_codecs;
1488 use crate::demuxers::realmedia_register_all_demuxers;
1489 #[test]
1490 fn test_rv60() {
1491 let mut dmx_reg = RegisteredDemuxers::new();
1492 realmedia_register_all_demuxers(&mut dmx_reg);
1493 let mut dec_reg = RegisteredDecoders::new();
1494 realmedia_register_all_codecs(&mut dec_reg);
1495
1496 test_file_decoding("realmedia", "assets/RV/RV60.rmhd", Some(4000), true, false, None/*Some("rv60")*/, &dmx_reg, &dec_reg);
1497 //panic!("end");
1498 }
1499 }