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