]> git.nihav.org Git - nihav.git/blame - nihav-realmedia/src/codecs/rv60.rs
realmedia: remove unneeded mut
[nihav.git] / nihav-realmedia / src / codecs / rv60.rs
CommitLineData
5641dccf
KS
1use nihav_core::formats::YUV420_FORMAT;
2use nihav_core::frame::*;
01613464 3use nihav_core::codecs::{NADecoder, NADecoderSupport, MV, ZERO_MV, DecoderError, DecoderResult, IPBShuffler};
5641dccf
KS
4use nihav_core::io::byteio::{MemoryReader,ByteReader};
5use nihav_core::io::bitreader::{BitReader,BitReaderMode};
6use nihav_core::io::intcode::*;
52aad9fe
KS
7
8use super::rv60codes::*;
9use super::rv60dsp::*;
10
11struct UniqueList<A> {
12 list: [A; 4],
13 fill: usize,
14 max_size: usize,
15}
16
17impl<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;
61d3e294 24 for el in self.list.iter().take(self.fill) {
52aad9fe
KS
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
37const RV60_FRAME_TYPES: [FrameType; 4] = [ FrameType::I, FrameType::P, FrameType::B, FrameType::Other ];
38const MAX_IMODE: u8 = 34;
39
40#[derive(Clone,Copy,Debug)]
41struct 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
55const RV60_CUSTOM_MSG_LENS: [u32; 4] = [ 2, 4, 16, 32 ];
56impl 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();
147if ((br.left() >> 3) as usize) != sum {
148println!(" 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
214const 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];
221const 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)]
229enum CUType {
230 Intra,
231 InterMV,
232 Skip,
233 InterNoMV,
234}
235
236impl Default for CUType {
237 fn default() -> Self { CUType::Intra }
238}
239
240const RV60_CU_TYPES: [CUType; 4] = [ CUType::Intra, CUType::InterMV, CUType::Skip, CUType::InterNoMV ];
241
242#[derive(Clone,Copy,PartialEq,Debug)]
243enum PUType {
244 Full,
245 N2Hor,
246 N2Ver,
247 Quarters,
248 N4Hor,
249 N34Hor,
250 N4Ver,
251 N34Ver,
252}
253
254const 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
259impl PUType {
e07387c7
KS
260 fn get_num_mvs(self) -> usize {
261 match self {
52aad9fe
KS
262 PUType::Full => 1,
263 PUType::Quarters => 4,
264 _ => 2,
265 }
266 }
e07387c7 267 fn get_mv_size(self, part_no: usize, size: usize) -> (usize, usize) {
52aad9fe 268 let mv_size = size >> 2;
e07387c7 269 match self {
52aad9fe
KS
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 {
e07387c7 276 (mv_size, mv_size >> 2)
52aad9fe 277 } else {
e07387c7 278 (mv_size, (3 * mv_size) >> 2)
52aad9fe
KS
279 }
280 },
281 PUType::N34Hor => {
282 if part_no == 0 {
e07387c7 283 (mv_size, (3 * mv_size) >> 2)
52aad9fe 284 } else {
e07387c7 285 (mv_size, mv_size >> 2)
52aad9fe
KS
286 }
287 },
288 PUType::N4Ver => {
289 if part_no == 0 {
e07387c7 290 ( mv_size >> 2, mv_size)
52aad9fe 291 } else {
e07387c7 292 ((3 * mv_size) >> 2, mv_size)
52aad9fe
KS
293 }
294 },
295 PUType::N34Ver => {
296 if part_no == 0 {
e07387c7 297 ((3 * mv_size) >> 2, mv_size)
52aad9fe 298 } else {
e07387c7 299 ( mv_size >> 2, mv_size)
52aad9fe
KS
300 }
301 },
302 }
303 }
e07387c7
KS
304 fn has_hor_split(self) -> bool {
305 match self {
52aad9fe
KS
306 PUType::N2Hor | PUType::N4Hor | PUType::N34Hor | PUType::Quarters => true,
307 _ => false,
308 }
309 }
e07387c7
KS
310 fn has_ver_split(self) -> bool {
311 match self {
52aad9fe
KS
312 PUType::N2Ver | PUType::N4Ver | PUType::N34Ver | PUType::Quarters => true,
313 _ => false,
314 }
315 }
316}
317
318impl Default for PUType {
319 fn default() -> Self { PUType::Full }
320}
321
322#[derive(Clone,Copy,Debug)]
323enum IntraMode {
324 Index(u8),
325 Mode(u8),
326 DC64,
327 Plane64,
328}
329
330#[derive(Clone,Copy,PartialEq,Debug)]
331enum TransformType {
332 None,
333 T4X4,
334 T8X8,
335 T16X16,
336}
337
338impl Default for TransformType {
339 fn default() -> Self { TransformType::None }
340}
341
342#[derive(Clone,Copy,PartialEq,Debug)]
343enum MVRef {
344 None,
345 Ref0,
346 Ref1,
347 BRef,
348 Ref0AndBRef,
349 Skip0,
350 Skip1,
351 Skip2,
352 Skip3,
353}
354
355const SKIP_MV_REF: [MVRef; 4] = [ MVRef::Skip0, MVRef::Skip1, MVRef::Skip2, MVRef::Skip3 ];
356
357impl MVRef {
e07387c7
KS
358 fn get_skip_mv_num(self) -> usize {
359 match self {
52aad9fe
KS
360 MVRef::Skip1 => 1,
361 MVRef::Skip2 => 2,
362 MVRef::Skip3 => 3,
363 _ => 0,
364 }
365 }
e07387c7
KS
366 fn is_ref0(self) -> bool {
367 match self {
52aad9fe
KS
368 MVRef::Ref0 | MVRef::Ref0AndBRef => true,
369 _ => false,
370 }
371 }
e07387c7
KS
372 fn is_fwd(self) -> bool {
373 match self {
52aad9fe
KS
374 MVRef::Ref0 | MVRef::Ref1 | MVRef::Ref0AndBRef => true,
375 _ => false,
376 }
377 }
e07387c7
KS
378 fn is_bwd(self) -> bool {
379 match self {
52aad9fe
KS
380 MVRef::BRef | MVRef::Ref0AndBRef => true,
381 _ => false,
382 }
383 }
384}
385
386#[derive(Clone,Copy,PartialEq,Debug)]
387struct MVInfo {
388 f_mv: MV,
389 b_mv: MV,
390 mvref: MVRef,
391}
392
393impl 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
416impl 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)]
421struct CBHeader {
422 cu_type: CUType,
423 pu_type: PUType,
424 ttype: TransformType,
425 imode: [IntraMode; 4],
426 mv: [MVInfo; 4],
427}
428
429impl 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)]
547struct PUInfo {
548 cu_type: CUType,
549 ttype: TransformType,
550}
551
552impl PUInfo {
e07387c7 553 fn is_intra(self) -> bool { self.cu_type == CUType::Intra }
52aad9fe
KS
554}
555
556const RV60_CANDIDATE_INTRA_ANGLES: [u8; 6] = [ 0, 1, 10, 26, 18, 2 ];
557
558#[derive(Clone,Copy,Default)]
559struct BlockInfo {
560 mv: MVInfo,
561 imode: u8,
562}
563
564struct DeblockInfo {
565 left_str: Vec<u8>,
566 top_str: Vec<u8>,
567 stride: usize,
568}
569
570impl 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
610struct RealVideo60Decoder {
2422d969 611 info: NACodecInfoRef,
52aad9fe
KS
612 cbs: RV60Codebooks,
613 ipbs: IPBShuffler,
614 dsp: RV60DSP,
615 ipred: IntraPredContext,
616
3fc28ece 617 avg_buf: NAVideoBufferRef<u8>,
52aad9fe
KS
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
641impl RealVideo60Decoder {
642 fn new() -> Self {
643 let tmp_vinfo = NAVideoInfo::new(64, 64, false, YUV420_FORMAT);
b70cc006 644 let vt = alloc_video_buffer(tmp_vinfo, 4).unwrap();
52aad9fe
KS
645 let vb = vt.get_vbuf();
646 let avg_buf = vb.unwrap();
647 RealVideo60Decoder{
2422d969 648 info: NACodecInfoRef::default(),
52aad9fe
KS
649 cbs: RV60Codebooks::init(),
650 ipbs: IPBShuffler::new(),
651 ipred: IntraPredContext::new(),
652 dsp: RV60DSP::new(),
e07387c7 653 avg_buf,
52aad9fe
KS
654 y_coeffs: [0; 16 * 16],
655 u_coeffs: [0; 8 * 8],
656 v_coeffs: [0; 8 * 8],
657 qp: 0,
658 sel_qp: 0,
659 cu_splits: Vec::with_capacity(24),
660 coded_blk: [false; 64],
661 dblk: DeblockInfo::new(),
662 pu_info: Vec::new(),
663 pu_stride: 0,
664 pu_pos: 0,
665 blk_info: Vec::new(),
666 blk_stride: 0,
667 blk_pos: 0,
668 xpos: 0,
669 ypos: 0,
670 }
671 }
cd830591 672 fn decode_cu_line(&mut self, buf: &mut NASimpleVideoFrame<u8>, hdr: &FrameHeader, src: &[u8], cu_y: usize) -> DecoderResult<()> {
52aad9fe
KS
673 let mut br = BitReader::new(src, src.len(), BitReaderMode::BE);
674 let cu_w = hdr.get_width_cu();
675 let dqp = hdr.read_line_qp_offset(&mut br)?;
676 let qps = (hdr.qp as i8) + dqp;
677 validate!((qps >= 0) && (qps < 32));
678 let qp = qps as u8;
679 self.qp = qp;
680 self.sel_qp = match hdr.osvquant {
681 0 => qp,
682 1 => {
683 if qp <= 25 {
684 qp + 5
685 } else {
686 qp
687 }
688 },
689 _ => {
690 if qp <= 18 {
691 qp + 10
692 } else if qp <= 25 {
693 qp + 5
694 } else {
695 qp
696 }
697 },
698 };
699
700 for cu_x in 0..cu_w {
701 self.cu_splits.clear();
702 self.coded_blk = [false; 64];
703 self.decode_cb_tree(buf, hdr, &mut br, cu_x << 6, cu_y << 6, 6)?;
704 if hdr.deblock {
705 self.cu_splits.reverse();
706 self.deblock_cb_tree(buf, hdr, cu_x << 6, cu_y << 6, 6);
707 }
708 }
709if br.left() >= 8 {
710println!(" left {} bits", br.left());
711}
712 Ok(())
713 }
cd830591 714 fn decode_cb_tree(&mut self, buf: &mut NASimpleVideoFrame<u8>, hdr: &FrameHeader, br: &mut BitReader, xpos: usize, ypos: usize, log_size: u8) -> DecoderResult<()> {
52aad9fe
KS
715 if (xpos >= hdr.width) || (ypos >= hdr.height) { return Ok(()); }
716
717 let size = 1 << log_size;
718 let split = (xpos + size > hdr.width) || (ypos + size > hdr.height) || (size > 8 && br.read_bool()?);
719 self.cu_splits.push(split);
720 if split {
721 let hsize = size >> 1;
722 self.decode_cb_tree(buf, hdr, br, xpos, ypos, log_size - 1)?;
723 self.decode_cb_tree(buf, hdr, br, xpos + hsize, ypos, log_size - 1)?;
724 self.decode_cb_tree(buf, hdr, br, xpos, ypos + hsize, log_size - 1)?;
725 self.decode_cb_tree(buf, hdr, br, xpos + hsize, ypos + hsize, log_size - 1)?;
726 } else {
727 let cbh = CBHeader::read(br, hdr.ftype, hdr.two_f_refs, size)?;
728 self.pu_pos = (xpos >> 3) + (ypos >> 3) * self.pu_stride;
729 self.blk_pos = (xpos >> 2) + (ypos >> 2) * self.blk_stride;
730 self.xpos = xpos;
731 self.ypos = ypos;
732 self.reconstruct_info(hdr, &cbh, size)?;
733
734 let split_i4x4 = (cbh.cu_type == CUType::Intra) && (size == 8) && (cbh.pu_type == PUType::Quarters);
735 match cbh.cu_type {
736 CUType::Intra => {
737 let itype = self.blk_info[self.blk_pos].imode;
738 if !split_i4x4 {
cd830591 739 let dstride = buf.stride[0];
52aad9fe 740 let off = xpos + ypos * dstride;
cd830591 741 let dst = &mut buf.data;
52aad9fe
KS
742 self.populate_ipred(hdr, dst, 0, dstride, 0, 0, size, true);
743 self.ipred.pred_angle(dst, off, dstride, size, itype as usize, true);
744 }
745 for comp in 1..3 {
cd830591
KS
746 let dstride = buf.stride[comp];
747 let soff = buf.offset[comp];
52aad9fe 748 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
cd830591 749 let mut dst = &mut buf.data;
52aad9fe
KS
750 self.populate_ipred(hdr, dst, soff, dstride, 0, 0, size >> 1, false);
751 self.ipred.pred_angle(&mut dst, off, dstride, size >> 1, itype as usize, false);
752 }
753 },
754 _ => {
755 let mut mv_x = xpos >> 2;
756 let mut mv_y = ypos >> 2;
757 let mut mv_pos = mv_x + mv_y * self.blk_stride;
758 for part_no in 0..cbh.pu_type.get_num_mvs() {
759 let (mv_w, mv_h) = cbh.pu_type.get_mv_size(part_no, size);
760 let mv = self.blk_info[mv_pos].mv;
761 let bw = mv_w << 2;
762 let bh = mv_h << 2;
763 let bx = mv_x << 2;
764 let by = mv_y << 2;
765 match mv.mvref {
766 MVRef::Ref0 => {
767 if hdr.ftype != FrameType::B {
768 if let Some(ref prevbuf) = self.ipbs.get_lastref() {
769 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
770 }
771 } else {
772 if let Some(ref prevbuf) = self.ipbs.get_b_fwdref() {
773 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
774 }
775 }
776 },
777 MVRef::Ref1 => {
778 if let Some(ref prevbuf) = self.ipbs.get_nextref() {
779 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
780 }
781 },
782 MVRef::BRef => {
783 validate!(hdr.ftype == FrameType::B);
784 if let Some(ref prevbuf) = self.ipbs.get_b_bwdref() {
785 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.b_mv, false);
786 }
787 },
788 MVRef::Ref0AndBRef => {
789 validate!(hdr.ftype == FrameType::B);
790 if let (Some(ref prevbuf), Some(ref nextbuf)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) {
791 self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false);
cd830591
KS
792 {
793 let mut avg_buf = NASimpleVideoFrame::from_video_buf(&mut self.avg_buf).unwrap();
794 self.dsp.do_mc(&mut avg_buf, nextbuf, bx, by, bw, bh, mv.b_mv, true);
795 }
52aad9fe
KS
796 self.dsp.do_avg(buf, &self.avg_buf, bx, by, bw, bh);
797 }
798 },
799 _ => unreachable!(),
800 };
801 if cbh.pu_type == PUType::Quarters {
802 if part_no != 1 {
803 mv_pos += mv_w;
804 mv_x += mv_w;
805 } else {
806 mv_pos += mv_h * self.blk_stride - mv_w;
807 mv_x -= mv_w;
808 mv_y += mv_h;
809 }
810 } else if cbh.pu_type.has_hor_split() {
811 mv_pos += mv_h * self.blk_stride;
812 mv_y += mv_h;
813 } else if cbh.pu_type.has_ver_split() {
814 mv_pos += mv_w;
815 mv_x += mv_w;
816 }
817 }
818 },
819 };
820 if cbh.ttype != TransformType::None {
821 self.y_coeffs = [0; 16 * 16];
822 self.u_coeffs = [0; 8 * 8];
823 self.v_coeffs = [0; 8 * 8];
824 }
825 let is_intra = cbh.cu_type == CUType::Intra;
826 let cb_pos = ((xpos & 63) >> 3) + ((ypos & 63) >> 3) * 8;
827 match cbh.ttype {
828 TransformType::T4X4 => {
829 let subset = if is_intra { 0 } else { 2 };
830 if size == 16 {
831 let cbp16;
832 if br.read_bool()? {
833 cbp16 = rv6_decode_cbp16(br, &self.cbs, subset, self.sel_qp)?;
834 } else {
835 cbp16 = 0;
836 }
837 if cbp16 != 0 {
838 self.coded_blk[cb_pos + 0] = true;
839 self.coded_blk[cb_pos + 1] = true;
840 self.coded_blk[cb_pos + 8] = true;
841 self.coded_blk[cb_pos + 9] = true;
842 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)?;
843 for y in 0..4 {
844 for x in 0..4 {
845 let i = x + y * 4;
846 if ((cbp16 >> i) & 1) != 0 {
847 self.dsp.transform4x4(&mut self.y_coeffs[i * 16..][..16]);
cd830591 848 let dstride = buf.stride[0];
52aad9fe 849 let off = xpos + x * 4 + (ypos + y * 4) * dstride;
cd830591 850 let mut dst = &mut buf.data;
52aad9fe
KS
851 self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs[i*16..][..16], 4);
852 }
853 }
854 }
855 for y in 0..2 {
856 for x in 0..2 {
857 let i = x + y * 2;
858 let xoff = (xpos >> 1) + x * 4;
859 let yoff = (ypos >> 1) + y * 4;
860 if ((cbp16 >> (16 + i)) & 1) != 0 {
861 self.dsp.transform4x4(&mut self.u_coeffs[i * 16..][..16]);
cd830591
KS
862 let dstride = buf.stride[1];
863 let off = buf.offset[1] + xoff + yoff * dstride;
864 let mut dst = &mut buf.data;
52aad9fe
KS
865 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs[i * 16..][..16], 4);
866 }
867 if ((cbp16 >> (20 + i)) & 1) != 0 {
868 self.dsp.transform4x4(&mut self.v_coeffs[i * 16..][..16]);
cd830591
KS
869 let dstride = buf.stride[2];
870 let off = buf.offset[2] + xoff + yoff * dstride;
871 let mut dst = &mut buf.data;
52aad9fe
KS
872 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs[i * 16..][..16], 4);
873 }
874 }
875 }
876 }
877 } else {
878 let cbp8 = rv6_decode_cbp8(br, &self.cbs, subset, self.sel_qp)?;
879 if cbp8 != 0 {
880 self.coded_blk[cb_pos] = true;
881 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)?;
882 }
883 for i in 0..4 {
884 let xoff = (i & 1) * 4;
885 let yoff = (i & 2) * 2;
886 if split_i4x4 {
cd830591 887 let dstride = buf.stride[0];
52aad9fe 888 let off = xpos + xoff + (ypos + yoff) * dstride;
cd830591 889 let mut dst = &mut buf.data;
52aad9fe
KS
890 self.populate_ipred(hdr, dst, 0, dstride, xoff, yoff, 4, true);
891 let itype = self.blk_info[self.blk_pos + (i & 1) + (i >> 1) * self.blk_stride].imode;
892 self.ipred.pred_angle(&mut dst, off, dstride, 4, itype as usize, false);
893 }
894 if ((cbp8 >> i) & 1) != 0 {
895 let blk = &mut self.y_coeffs[i * 16..][..16];
896 self.dsp.transform4x4(blk);
cd830591
KS
897 let dstride = buf.stride[0];
898 let soff = buf.offset[0];
52aad9fe 899 let off = soff + xpos + xoff + (ypos + yoff) * dstride;
cd830591 900 let mut dst = &mut buf.data;
52aad9fe
KS
901 self.dsp.add_block(&mut dst, off, dstride, blk, 4);
902 }
903 }
904 if ((cbp8 >> 4) & 1) != 0 {
905 self.dsp.transform4x4(&mut self.u_coeffs);
cd830591
KS
906 let dstride = buf.stride[1];
907 let soff = buf.offset[1];
52aad9fe 908 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
cd830591 909 let mut dst = &mut buf.data;
52aad9fe
KS
910 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 4);
911 }
912 if ((cbp8 >> 5) & 1) != 0 {
913 self.dsp.transform4x4(&mut self.v_coeffs);
cd830591
KS
914 let dstride = buf.stride[2];
915 let soff = buf.offset[2];
52aad9fe 916 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
cd830591 917 let mut dst = &mut buf.data;
52aad9fe
KS
918 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 4);
919 }
920 }
921 },
922 TransformType::T8X8 => {
923 let subset = if is_intra { 1 } else { 3 };
924 let cbp8 = rv6_decode_cbp8(br, &self.cbs, subset, self.sel_qp)?;
925 if cbp8 != 0 {
926 self.coded_blk[cb_pos] = true;
927 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)?;
928 if (cbp8 & 0xF) != 0 {
929 self.dsp.transform8x8(&mut self.y_coeffs);
cd830591 930 let dstride = buf.stride[0];
52aad9fe 931 let off = xpos + ypos * dstride;
cd830591 932 let mut dst = &mut buf.data;
52aad9fe
KS
933 self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs, 8);
934 }
935 if ((cbp8 >> 4) & 1) != 0 {
936 self.dsp.transform4x4(&mut self.u_coeffs);
cd830591
KS
937 let dstride = buf.stride[1];
938 let soff = buf.offset[1];
52aad9fe 939 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
cd830591 940 let mut dst = &mut buf.data;
52aad9fe
KS
941 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 4);
942 }
943 if ((cbp8 >> 5) & 1) != 0 {
944 self.dsp.transform4x4(&mut self.v_coeffs);
cd830591
KS
945 let dstride = buf.stride[2];
946 let soff = buf.offset[2];
52aad9fe 947 let off = soff + (xpos >> 1) + (ypos >> 1) * dstride;
cd830591 948 let mut dst = &mut buf.data;
52aad9fe
KS
949 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 4);
950 }
951 }
952 },
953 TransformType::T16X16 => {
954 let subset = if is_intra { 1 } else { 3 };
955 let num_clusters = size >> 4;
956 let cl_cbp = br.read((num_clusters * num_clusters) as u8)?;
957 for y in 0..num_clusters {
958 for x in 0..num_clusters {
959 if ((cl_cbp >> (x + y * num_clusters)) & 1) == 0 { continue; }
960 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 0] = true;
961 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 1] = true;
962 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 8] = true;
963 self.coded_blk[cb_pos + x * 2 + y * 2 * 8 + 9] = true;
964 let super_cbp = rv6_decode_cbp16(br, &self.cbs, subset, self.sel_qp)?;
965 if super_cbp != 0 {
966 self.y_coeffs = [0; 16 * 16];
967 self.u_coeffs = [0; 8 * 8];
968 self.v_coeffs = [0; 8 * 8];
969 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)?;
970 if (super_cbp & 0xFFFF) != 0 {
971 self.dsp.transform16x16(&mut self.y_coeffs);
cd830591 972 let dstride = buf.stride[0];
52aad9fe 973 let off = xpos + x * 16 + (ypos + y * 16) * dstride;
cd830591 974 let mut dst = &mut buf.data;
52aad9fe
KS
975 self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs, 16);
976 }
977 if ((super_cbp >> 16) & 0xF) != 0 {
978 self.dsp.transform8x8(&mut self.u_coeffs);
cd830591
KS
979 let dstride = buf.stride[1];
980 let soff = buf.offset[1];
52aad9fe 981 let off = soff + (xpos >> 1) + x * 8 + ((ypos >> 1) + y * 8) * dstride;
cd830591 982 let mut dst = &mut buf.data;
52aad9fe
KS
983 self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 8);
984 }
985 if ((super_cbp >> 20) & 0xF) != 0 {
986 self.dsp.transform8x8(&mut self.v_coeffs);
cd830591
KS
987 let dstride = buf.stride[2];
988 let soff = buf.offset[2];
52aad9fe 989 let off = soff + (xpos >> 1) + x * 8 + ((ypos >> 1) + y * 8) * dstride;
cd830591 990 let mut dst = &mut buf.data;
52aad9fe
KS
991 self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 8);
992 }
993 }
994 }
995 }
996 },
997 _ => {},
998 };
999 }
1000 Ok(())
1001 }
1002 fn reconstruct_info(&mut self, hdr: &FrameHeader, cbh: &CBHeader, size: usize) -> DecoderResult<()>{
1003 let mut pui = PUInfo::default();
1004 let pu_size = size >> 3;
1005 pui.cu_type = cbh.cu_type;
1006 pui.ttype = cbh.ttype;
1007 if (cbh.cu_type == CUType::Intra) && (cbh.pu_type == PUType::Quarters) { // very special case
1008 self.pu_info[self.pu_pos] = pui;
1009 for y in 0..2 {
1010 for x in 0..2 {
1011 let imode = self.reconstruct_intra(hdr, cbh, 4, x + y * 2);
1012 validate!(imode <= MAX_IMODE);
1013 self.blk_info[self.blk_pos + x + y * self.blk_stride].imode = imode;
1014 self.blk_info[self.blk_pos + x + y * self.blk_stride].mv = MVInfo::default();
1015 }
1016 }
1017 return Ok(());
1018 }
1019 match cbh.cu_type {
1020 CUType::Intra => {
1021 self.pu_info[self.pu_pos] = pui;
1022 let imode = self.reconstruct_intra(hdr, cbh, size, 0);
1023 validate!(imode <= MAX_IMODE);
1024 for y in 0..(size >> 2) {
1025 for x in 0..(size >> 2) {
1026 self.blk_info[self.blk_pos + x + y * self.blk_stride].imode = imode;
1027 }
1028 }
1029 },
1030 CUType::InterMV => {
1031 let mut mv_x = self.xpos >> 2;
1032 let mut mv_y = self.ypos >> 2;
1033 let mut mv_pos = self.blk_pos;
1034 let pu_type = cbh.pu_type;
1035 for part_no in 0..pu_type.get_num_mvs() {
1036 let (mv_w, mv_h) = pu_type.get_mv_size(part_no, size);
1037 let mv = self.predict_mv(hdr, mv_x, mv_y, mv_w, &cbh.mv[part_no]);
1038 for y in 0..mv_h {
1039 for x in 0..mv_w {
1040 self.blk_info[mv_pos + x + y * self.blk_stride].mv = mv;
1041 }
1042 }
1043 if pu_type == PUType::Quarters {
1044 if part_no != 1 {
1045 mv_pos += mv_w;
1046 mv_x += mv_w;
1047 } else {
1048 mv_pos += mv_h * self.blk_stride - mv_w;
1049 mv_x -= mv_w;
1050 mv_y += mv_h;
1051 }
1052 } else if pu_type.has_hor_split() {
1053 mv_pos += mv_h * self.blk_stride;
1054 mv_y += mv_h;
1055 } else if pu_type.has_ver_split() {
1056 mv_pos += mv_w;
1057 mv_x += mv_w;
1058 }
1059 }
1060 },
1061 _ => {
1062 let skip_idx = cbh.mv[0].mvref.get_skip_mv_num();
1063 let mut skip_cand: UniqueList<MVInfo> = UniqueList::new(4);
1064 self.fill_skip_cand(hdr, &mut skip_cand, size);
1065 let mv = skip_cand.list[skip_idx];
1066
1067 let mv_size = size >> 2;
1068 for y in 0..mv_size {
1069 for x in 0..mv_size {
1070 self.blk_info[self.blk_pos + x + y * self.blk_stride].mv = mv;
1071 }
1072 }
1073 },
1074 };
1075 for y in 0..pu_size {
1076 for x in 0..pu_size {
1077 self.pu_info[self.pu_pos + x + y * self.pu_stride] = pui;
1078 }
1079 }
1080 Ok(())
1081 }
1082 fn reconstruct_intra(&self, hdr: &FrameHeader, cbh: &CBHeader, size: usize, sub: usize) -> u8 {
1083 match cbh.imode[0] {
1084 IntraMode::DC64 => { return 1; },
1085 IntraMode::Plane64 => { return 0; },
1086 _ => {},
1087 };
1088 // form list of predictors
1089 let blk_pos = self.blk_pos + (sub & 1) + (sub >> 1) * self.blk_stride;
1090 let mut ipm_cand: UniqueList<u8> = UniqueList::new(3);
1091 if hdr.has_top_block(self.xpos, self.ypos, (sub & 1) * 4, 0, size) {
1092 let pu = &self.pu_info[self.pu_pos - self.pu_stride];
1093 if pu.is_intra() {
1094 ipm_cand.add(self.blk_info[self.blk_pos + (sub & 1) - self.blk_stride].imode);
1095 }
1096 }
1097 if hdr.has_left_block(self.xpos, self.ypos, 0, (sub & 2) * 2, size) {
1098 let pu = &self.pu_info[self.pu_pos - 1];
1099 if pu.is_intra() {
1100 ipm_cand.add(self.blk_info[blk_pos - 1 - (sub & 1)].imode);
1101 }
1102 }
1103 let tl_x = if (sub & 2) == 0 { self.xpos + (sub & 1) * 4 } else { self.xpos };
1104 let tl_y = self.ypos + (sub & 2) * 4;
1105 if (tl_x > 0) && (tl_y > 0) {
1106 let pu = match sub {
1107 0 => &self.pu_info[self.pu_pos - self.pu_stride - 1],
1108 1 => &self.pu_info[self.pu_pos - self.pu_stride],
1109 2 => &self.pu_info[self.pu_pos - 1],
1110 _ => &self.pu_info[self.pu_pos - 1],
1111 };
1112 if pu.is_intra() {
1113 if sub != 3 {
1114 ipm_cand.add(self.blk_info[blk_pos - self.blk_stride - 1].imode);
1115 } else {
1116 ipm_cand.add(self.blk_info[blk_pos - self.blk_stride - 2].imode);
1117 }
1118 }
1119 }
61d3e294 1120 for el in RV60_CANDIDATE_INTRA_ANGLES.iter() {
52aad9fe
KS
1121 ipm_cand.add(*el);
1122 }
1123 // actually decode prediction mode
1124 match cbh.imode[sub] {
1125 IntraMode::Index(idx) => {
1126 ipm_cand.list[idx as usize]
1127 },
1128 IntraMode::Mode(mode) => {
1129 let mut imode = mode;
1130 let mut ipm_cs: [u8; 3] = [ipm_cand.list[0], ipm_cand.list[1], ipm_cand.list[2]];
1131 ipm_cs.sort();
61d3e294 1132 for ic in ipm_cs.iter() {
52aad9fe
KS
1133 if imode >= *ic {
1134 imode += 1;
1135 }
1136 }
1137 imode
1138 },
1139 _ => unreachable!(),
1140 }
1141 }
1142 fn populate_ipred(&mut self, hdr: &FrameHeader, src: &[u8], soff: usize, stride: usize, xoff: usize, yoff: usize, size: usize, is_luma: bool) {
1143 let src_off = if is_luma {
1144 soff + self.xpos + xoff + (self.ypos + yoff) * stride
1145 } else {
1146 soff + (self.xpos >> 1) + (self.ypos >> 1) * stride
1147 };
1148 self.ipred = IntraPredContext::new();
1149 if (self.ypos + yoff) > 0 {
1150 self.ipred.has_t = true;
1151 for x in 0..size {
1152 self.ipred.t[x + 1] = src[src_off - stride + x];
1153 }
1154 if (is_luma && hdr.has_top_right_block(self.xpos, self.ypos, xoff, yoff, size)) ||
1155 (!is_luma && hdr.has_top_right_block(self.xpos, self.ypos, 0, 0, size << 1)) {
1156 self.ipred.has_tr = true;
1157 for x in size..size*2 {
1158 self.ipred.t[x + 1] = src[src_off - stride + x];
1159 }
1160 } else {
1161 for i in 0..size {
1162 self.ipred.t[size + i + 1] = self.ipred.t[size];
1163 }
1164 }
1165 if (self.xpos + xoff) > 0 {
1166 self.ipred.t[0] = src[src_off - stride - 1];
1167 }
1168 }
1169 if (self.xpos + xoff) > 0 {
1170 self.ipred.has_l = true;
1171 for y in 0..size {
1172 self.ipred.l[y + 1] = src[src_off - 1 + y * stride];
1173 }
1174 if (is_luma && hdr.has_left_down_block(self.xpos, self.ypos, xoff, yoff, size)) ||
1175 (!is_luma && hdr.has_left_down_block(self.xpos, self.ypos, 0, 0, size << 1)) {
1176 self.ipred.has_ld = true;
1177 for y in size..size*2 {
1178 self.ipred.l[y + 1] = src[src_off - 1 + y * stride];
1179 }
1180 } else {
1181 for i in 0..size {
1182 self.ipred.l[size + i + 1] = self.ipred.l[size];
1183 }
1184 }
1185 if (self.ypos + yoff) > 0 {
1186 self.ipred.l[0] = src[src_off - stride - 1];
1187 }
1188 }
1189 }
1190 fn predict_mv(&self, hdr: &FrameHeader, mv_x: usize, mv_y: usize, mv_w: usize, mvi: &MVInfo) -> MVInfo {
1191 let mv_pos = mv_x + mv_y * self.blk_stride;
1192 let f_mv: MV;
1193 let b_mv: MV;
1194 if mvi.mvref.is_fwd() {
1195 let mut mv_cand: [MV; 3] = [ZERO_MV; 3];
1196 let mut mv_cand_size: usize = 0;
1197 if mv_x > 0 {
1198 let ref_mv = &self.blk_info[mv_pos - 1].mv;
1199 if ref_mv.matches_fwd(mvi.mvref) {
1200 mv_cand[mv_cand_size] = ref_mv.f_mv;
1201 mv_cand_size += 1;
1202 }
1203 }
1204 if mv_y > 0 {
1205 let ref_mv = &self.blk_info[mv_pos - self.blk_stride].mv;
1206 if ref_mv.matches_fwd(mvi.mvref) {
1207 mv_cand[mv_cand_size] = ref_mv.f_mv;
1208 mv_cand_size += 1;
1209 }
1210 }
1211 if hdr.has_top_block(mv_x << 2, mv_y << 2, mv_w << 2, 0, 4) {
1212 let ref_mv = &self.blk_info[mv_pos - self.blk_stride + mv_w].mv;
1213 if ref_mv.matches_fwd(mvi.mvref) {
1214 mv_cand[mv_cand_size] = ref_mv.f_mv;
1215 mv_cand_size += 1;
1216 }
1217 }
1218 f_mv = match mv_cand_size {
1219 1 | 2 => {
1220 let x = mv_cand[0].x + mv_cand[1].x + mv_cand[2].x;
1221 let y = mv_cand[0].y + mv_cand[1].y + mv_cand[2].y;
1222 if mv_cand_size == 1 {
1223 MV { x, y }
1224 } else {
1225 MV { x: x >> 1, y: y >> 1 }
1226 }
1227 },
1228 3 => MV::pred(mv_cand[0], mv_cand[1], mv_cand[2]),
1229 _ => ZERO_MV,
1230 };
1231 } else {
1232 f_mv = ZERO_MV;
1233 }
1234 if mvi.mvref.is_bwd() {
1235 let mut mv_cand: [MV; 3] = [ZERO_MV; 3];
1236 let mut mv_cand_size: usize = 0;
1237 if mv_x > 0 {
1238 let ref_mv = &self.blk_info[mv_pos - 1].mv;
1239 if ref_mv.matches_bwd(mvi.mvref) {
1240 mv_cand[mv_cand_size] = ref_mv.b_mv;
1241 mv_cand_size += 1;
1242 }
1243 }
1244 if mv_y > 0 {
1245 let ref_mv = &self.blk_info[mv_pos - self.blk_stride].mv;
1246 if ref_mv.matches_bwd(mvi.mvref) {
1247 mv_cand[mv_cand_size] = ref_mv.b_mv;
1248 mv_cand_size += 1;
1249 }
1250 }
1251 if hdr.has_top_block(mv_x << 2, mv_y << 2, mv_w << 2, 0, 4) {
1252 let ref_mv = &self.blk_info[mv_pos - self.blk_stride + mv_w].mv;
1253 if ref_mv.matches_bwd(mvi.mvref) {
1254 mv_cand[mv_cand_size] = ref_mv.b_mv;
1255 mv_cand_size += 1;
1256 }
1257 }
1258 b_mv = match mv_cand_size {
1259 1 | 2 => {
1260 let x = mv_cand[0].x + mv_cand[1].x + mv_cand[2].x;
1261 let y = mv_cand[0].y + mv_cand[1].y + mv_cand[2].y;
1262 if mv_cand_size == 1 {
1263 MV { x, y }
1264 } else {
1265 MV { x: x >> 1, y: y >> 1 }
1266 }
1267 },
1268 3 => MV::pred(mv_cand[0], mv_cand[1], mv_cand[2]),
1269 _ => ZERO_MV,
1270 };
1271 } else {
1272 b_mv = ZERO_MV;
1273 }
1274
1275 MVInfo { f_mv: mvi.f_mv + f_mv, b_mv: mvi.b_mv + b_mv, mvref: mvi.mvref }
1276 }
1277 fn fill_skip_cand(&mut self, hdr: &FrameHeader, skip_cand: &mut UniqueList<MVInfo>, size: usize) {
1278 let mv_size = size >> 2;
1279
1280 if self.xpos > 0 {
1281 let mv = &self.blk_info[self.blk_pos - 1].mv;
1282 if mv.is_some() {
1283 skip_cand.add(*mv);
1284 }
1285 }
1286 if self.ypos > 0 {
1287 let mv = &self.blk_info[self.blk_pos - self.blk_stride].mv;
1288 if mv.is_some() {
1289 skip_cand.add(*mv);
1290 }
1291 }
1292 if hdr.has_top_right_block(self.xpos, self.ypos, 0, 0, size) {
1293 let mv = &self.blk_info[self.blk_pos - self.blk_stride + mv_size].mv;
1294 if mv.is_some() {
1295 skip_cand.add(*mv);
1296 }
1297 }
1298 if hdr.has_left_down_block(self.xpos, self.ypos, 0, 0, size) {
1299 let mv = &self.blk_info[self.blk_pos + self.blk_stride * mv_size - 1].mv;
1300 if mv.is_some() {
1301 skip_cand.add(*mv);
1302 }
1303 }
1304 if hdr.has_left_block(self.xpos, self.ypos, 0, 0, size) {
1305 let mv = &self.blk_info[self.blk_pos + self.blk_stride * (mv_size - 1) - 1].mv;
1306 if mv.is_some() {
1307 skip_cand.add(*mv);
1308 }
1309 }
1310 if hdr.has_top_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 (self.xpos > 0) && (self.ypos > 0) {
1317 let mv = &self.blk_info[self.blk_pos - self.blk_stride - 1].mv;
1318 if mv.is_some() {
1319 skip_cand.add(*mv);
1320 }
1321 }
1322 for i in skip_cand.fill..4 {
1323 skip_cand.list[i] = MVInfo { f_mv: ZERO_MV, b_mv: ZERO_MV, mvref: MVRef::Ref0 };
1324 }
1325 }
cd830591 1326 fn deblock_cb_tree(&mut self, buf: &mut NASimpleVideoFrame<u8>, hdr: &FrameHeader, xpos: usize, ypos: usize, log_size: u8) {
52aad9fe
KS
1327 if (xpos >= hdr.width) || (ypos >= hdr.height) { return; }
1328 let split = (log_size > 3) && self.cu_splits.pop().unwrap();
1329 if split {
1330 let hsize = 1 << (log_size - 1);
1331 self.deblock_cb_tree(buf, hdr, xpos, ypos, log_size - 1);
1332 self.deblock_cb_tree(buf, hdr, xpos + hsize, ypos, log_size - 1);
1333 self.deblock_cb_tree(buf, hdr, xpos, ypos + hsize, log_size - 1);
1334 self.deblock_cb_tree(buf, hdr, xpos + hsize, ypos + hsize, log_size - 1);
1335 } else {
1336 let pu_pos = (xpos >> 3) + (ypos >> 3) * self.pu_stride;
1337 let cu_type = self.pu_info[pu_pos].cu_type;
1338 let tsize = if self.pu_info[pu_pos].ttype == TransformType::T16X16 { 4 } else { 3 };
1339 let ntiles = 1 << (log_size - tsize);
1340 let dparams = RV60DeblockParams {
1341 deblock_chroma: hdr.deblock_chroma,
1342 width: hdr.width,
1343 height: hdr.height,
1344 dblkstride: self.dblk.stride,
1345 };
1346 for ty in 0..ntiles {
1347 for tx in 0..ntiles {
1348 let x = xpos + (tx << tsize);
1349 let y = ypos + (ty << tsize);
1350 let cb_pos = ((x & 63) >> 3) + ((y & 63) >> 3) * 8;
1351 if cu_type == CUType::Intra {
1352 self.dblk.set_strength(x, y, 1 << tsize, self.qp, 2);
1353 } else if (cu_type != CUType::Skip) && self.coded_blk[cb_pos] {
1354 self.dblk.set_strength(x, y, 1 << tsize, self.qp, 1);
1355 } else {
1356 self.dblk.set_strength(x, y, 1 << tsize, self.qp, 0);
1357 self.derive_deblock_strength(x, y, 1 << (tsize - 2));
1358 }
1359 self.dsp.do_deblock(&dparams, buf, x, y, 1 << tsize,
1360 self.dblk.top_str.as_slice(),
1361 self.dblk.left_str.as_slice(),
1362 self.dblk.get_pos(x, y));
1363 }
1364 }
1365 }
1366 }
1367 fn derive_deblock_strength(&mut self, xpos: usize, ypos: usize, size4: usize) {
1368 let blk_pos = (xpos >> 2) + (ypos >> 2) * self.blk_stride;
1369 let mut dblk_pos = self.dblk.get_pos(xpos, ypos);
1370 if ypos > 0 {
1371 let top_blk_pos = blk_pos - self.blk_stride;
1372 for i in 0..size4 {
1373 if self.dblk.get_top_strength(dblk_pos + i) == 0 {
1374 if self.blk_info[blk_pos + i].mv.is_deblock_cand(&self.blk_info[top_blk_pos + i].mv) {
1375 self.dblk.set_top_strength(dblk_pos + i, 1);
1376 }
1377 }
1378 }
1379 }
1380 if xpos > 0 {
1381 for i in 0..size4 {
1382 if self.dblk.get_left_strength(dblk_pos) == 0 {
1383 if self.blk_info[blk_pos + i].mv.is_deblock_cand(&self.blk_info[blk_pos + i - 1].mv) {
1384 self.dblk.set_left_strength(dblk_pos, 1);
1385 }
1386 }
1387 dblk_pos += self.dblk.stride;
1388 }
1389 }
1390 }
1391}
1392
1393impl NADecoder for RealVideo60Decoder {
3c69ce1b
KS
1394 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
1395 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
52aad9fe
KS
1396 let fmt = YUV420_FORMAT;
1397 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
2422d969 1398 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
52aad9fe
KS
1399
1400 let edata = info.get_extradata().unwrap();
1401 let src: &[u8] = &edata;
1402
1403 if src.len() < 8 { return Err(DecoderError::InvalidData); }
1404 let mut mr = MemoryReader::new_read(src);
1405 let mut br = ByteReader::new(&mut mr);
1406 let _flags = br.read_u32be()?;
1407 let version = br.read_u32be()?;
1408 let _unk = br.read_u16be()?;
1409 validate!((version >> 28) == 4);
1410 // then width and height again as 16be
1411
1412 //self.bd.width = vinfo.get_width();
1413 //self.bd.height = vinfo.get_height();
1414 //self.frmmgr.clear();
3c69ce1b
KS
1415
1416 supp.pool_u8.set_dec_bufs(3);
1417 supp.pool_u8.prealloc_video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt), 6)?;
1418
52aad9fe
KS
1419 Ok(())
1420 } else {
1421println!("???");
1422 Err(DecoderError::InvalidData)
1423 }
1424 }
3c69ce1b 1425 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
52aad9fe
KS
1426 let src = pkt.get_buffer();
1427
1428 validate!(src.len() > 9);
1429 let hsize = (src[0] as usize) * 8 + 9;
1430 let mut br = BitReader::new(&src[hsize..], src.len() - hsize, BitReaderMode::BE);
1431 let hdr = FrameHeader::read(&mut br)?;
1432 let mut slices: Vec<usize> = Vec::new();
1433 hdr.parse_slice_sizes(&mut br, &mut slices)?;
1434
1435 let tmp_vinfo = NAVideoInfo::new(hdr.width, hdr.height, false, YUV420_FORMAT);
3c69ce1b
KS
1436 let ret = supp.pool_u8.get_free();
1437 if ret.is_none() {
1438 return Err(DecoderError::AllocError);
1439 }
1440 let mut buf = ret.unwrap();
1441 if buf.get_info() != tmp_vinfo {
1442 self.ipbs.clear();
1443 supp.pool_u8.reset();
1444 supp.pool_u8.prealloc_video(tmp_vinfo, 6)?;
1445 let ret = supp.pool_u8.get_free();
1446 if ret.is_none() {
1447 return Err(DecoderError::AllocError);
1448 }
1449 buf = ret.unwrap();
1450 }
52aad9fe
KS
1451
1452 let cu_w = hdr.get_width_cu();
1453 let cu_h = hdr.get_height_cu();
1454 self.pu_stride = cu_w << 3;
1455 self.pu_info.resize(self.pu_stride * (cu_h << 3), PUInfo::default());
1456 self.blk_stride = cu_w << 4;
1457 self.blk_info.truncate(0);
1458 self.blk_info.resize(self.blk_stride * (cu_h << 4), BlockInfo::default());
1459 if hdr.deblock {
1460 self.dblk.reinit(hdr.width, hdr.height);
1461 }
1462 let mut off = hsize + ((br.tell() >> 3) as usize);
cd830591 1463 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
52aad9fe 1464 for (cu_y, size) in slices.into_iter().enumerate() {
cd830591 1465 self.decode_cu_line(&mut dframe, &hdr, &src[off..][..size], cu_y)?;
52aad9fe
KS
1466 off += size;
1467 }
1468 if (hdr.ftype == FrameType::I) || (hdr.ftype == FrameType::P) {
3c69ce1b 1469 self.ipbs.add_frame(buf.clone());
52aad9fe
KS
1470 }
1471
3c69ce1b 1472 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
52aad9fe
KS
1473 frm.set_keyframe(hdr.ftype == FrameType::I);
1474 frm.set_pts(Some(hdr.ts as u64));
1475 frm.set_frame_type(hdr.ftype);
171860fc 1476 Ok(frm.into_ref())
52aad9fe
KS
1477 }
1478}
1479
6011e201 1480pub fn get_decoder() -> Box<dyn NADecoder> {
52aad9fe
KS
1481 Box::new(RealVideo60Decoder::new())
1482}
1483
1484#[cfg(test)]
1485mod test {
3167c45c
KS
1486 use nihav_core::codecs::RegisteredDecoders;
1487 use nihav_core::demuxers::RegisteredDemuxers;
1488 use nihav_core::test::dec_video::*;
1489 use crate::codecs::realmedia_register_all_codecs;
1490 use crate::demuxers::realmedia_register_all_demuxers;
52aad9fe
KS
1491 #[test]
1492 fn test_rv60() {
3167c45c
KS
1493 let mut dmx_reg = RegisteredDemuxers::new();
1494 realmedia_register_all_demuxers(&mut dmx_reg);
1495 let mut dec_reg = RegisteredDecoders::new();
1496 realmedia_register_all_codecs(&mut dec_reg);
1497
1498 test_file_decoding("realmedia", "assets/RV/RV60.rmhd", Some(4000), true, false, None/*Some("rv60")*/, &dmx_reg, &dec_reg);
1f7e9371 1499//panic!("end");
52aad9fe
KS
1500 }
1501}