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