1 use nihav_core::frame::NAVideoBuffer;
2 use super::{BlockDSP, CBPInfo, MV};
3 use super::super::blockdsp;
4 //use super::h263data::*;
6 /*const W1: i32 = 22725;
10 const W5: i32 = 12873;
14 const ROW_SHIFT: u8 = 11;
15 const COL_SHIFT: u8 = 20;
17 fn idct_row(row: &mut [i16]) {
18 let in0 = row[0] as i32;
19 let in1 = row[1] as i32;
20 let in2 = row[2] as i32;
21 let in3 = row[3] as i32;
22 let in4 = row[4] as i32;
23 let in5 = row[5] as i32;
24 let in6 = row[6] as i32;
25 let in7 = row[7] as i32;
27 let mut a0 = in0 * W1 + (1 << (ROW_SHIFT - 1));
37 let mut b0 = W1 * in1 + W3 * in3;
38 let mut b1 = W3 * in1 - W7 * in3;
39 let mut b2 = W5 * in1 - W1 * in3;
40 let mut b3 = W7 * in1 - W5 * in3;
42 a0 += W4 * in4 + W6 * in6;
43 a1 -= W4 * in4 + W2 * in6;
44 a2 -= W4 * in4 - W2 * in6;
45 a3 += W4 * in4 - W6 * in6;
47 b0 += W5 * in5 + W7 * in7;
48 b1 -= W1 * in5 + W5 * in7;
49 b2 += W7 * in5 + W3 * in7;
50 b3 += W3 * in5 - W1 * in7;
52 row[0] = ((a0 + b0) >> ROW_SHIFT) as i16;
53 row[7] = ((a0 - b0) >> ROW_SHIFT) as i16;
54 row[1] = ((a1 + b1) >> ROW_SHIFT) as i16;
55 row[6] = ((a1 - b1) >> ROW_SHIFT) as i16;
56 row[2] = ((a2 + b2) >> ROW_SHIFT) as i16;
57 row[5] = ((a2 - b2) >> ROW_SHIFT) as i16;
58 row[3] = ((a3 + b3) >> ROW_SHIFT) as i16;
59 row[4] = ((a3 - b3) >> ROW_SHIFT) as i16;
62 fn idct_col(blk: &mut [i16; 64], off: usize) {
63 let in0 = blk[off + 0*8] as i32;
64 let in1 = blk[off + 1*8] as i32;
65 let in2 = blk[off + 2*8] as i32;
66 let in3 = blk[off + 3*8] as i32;
67 let in4 = blk[off + 4*8] as i32;
68 let in5 = blk[off + 5*8] as i32;
69 let in6 = blk[off + 6*8] as i32;
70 let in7 = blk[off + 7*8] as i32;
72 let mut a0 = in0 * W1 + (1 << (COL_SHIFT - 1));
82 let mut b0 = W1 * in1 + W3 * in3;
83 let mut b1 = W3 * in1 - W7 * in3;
84 let mut b2 = W5 * in1 - W1 * in3;
85 let mut b3 = W7 * in1 - W5 * in3;
87 a0 += W4 * in4 + W6 * in6;
88 a1 -= W4 * in4 + W2 * in6;
89 a2 -= W4 * in4 - W2 * in6;
90 a3 += W4 * in4 - W6 * in6;
92 b0 += W5 * in5 + W7 * in7;
93 b1 -= W1 * in5 + W5 * in7;
94 b2 += W7 * in5 + W3 * in7;
95 b3 += W3 * in5 - W1 * in7;
97 blk[off + 0*8] = ((a0 + b0) >> COL_SHIFT) as i16;
98 blk[off + 7*8] = ((a0 - b0) >> COL_SHIFT) as i16;
99 blk[off + 1*8] = ((a1 + b1) >> COL_SHIFT) as i16;
100 blk[off + 6*8] = ((a1 - b1) >> COL_SHIFT) as i16;
101 blk[off + 2*8] = ((a2 + b2) >> COL_SHIFT) as i16;
102 blk[off + 5*8] = ((a2 - b2) >> COL_SHIFT) as i16;
103 blk[off + 3*8] = ((a3 + b3) >> COL_SHIFT) as i16;
104 blk[off + 4*8] = ((a3 - b3) >> COL_SHIFT) as i16;
108 pub fn h263_idct(blk: &mut [i16; 64]) {
109 for i in 0..8 { idct_row(&mut blk[i*8..(i+1)*8]); }
110 for i in 0..8 { idct_col(blk, i); }
113 const W1: i32 = 2841;
114 const W2: i32 = 2676;
115 const W3: i32 = 2408;
116 const W5: i32 = 1609;
117 const W6: i32 = 1108;
121 const ROW_SHIFT: u8 = 8;
122 const COL_SHIFT: u8 = 14;
124 #[allow(clippy::erasing_op)]
125 fn idct_row(row: &mut [i16]) {
126 let in0 = ((i32::from(row[0])) << 11) + (1 << (ROW_SHIFT - 1));
127 let in1 = (i32::from(row[4])) << 11;
128 let in2 = i32::from(row[6]);
129 let in3 = i32::from(row[2]);
130 let in4 = i32::from(row[1]);
131 let in5 = i32::from(row[7]);
132 let in6 = i32::from(row[5]);
133 let in7 = i32::from(row[3]);
135 let tmp = W7 * (in4 + in5);
136 let a4 = tmp + (W1 - W7) * in4;
137 let a5 = tmp - (W1 + W7) * in5;
139 let tmp = W3 * (in6 + in7);
140 let a6 = tmp - (W3 - W5) * in6;
141 let a7 = tmp - (W3 + W5) * in7;
146 let t1 = W6 * (in2 + in3);
147 let a2 = t1 - (W2 + W6) * in2;
148 let a3 = t1 + (W2 - W6) * in3;
158 let b2 = (W8 * (b4 + t2) + 128) >> 8;
159 let b4 = (W8 * (b4 - t2) + 128) >> 8;
161 row[0] = ((b7 + b1) >> ROW_SHIFT) as i16;
162 row[7] = ((b7 - b1) >> ROW_SHIFT) as i16;
163 row[1] = ((b3 + b2) >> ROW_SHIFT) as i16;
164 row[6] = ((b3 - b2) >> ROW_SHIFT) as i16;
165 row[2] = ((b0 + b4) >> ROW_SHIFT) as i16;
166 row[5] = ((b0 - b4) >> ROW_SHIFT) as i16;
167 row[3] = ((b5 + b6) >> ROW_SHIFT) as i16;
168 row[4] = ((b5 - b6) >> ROW_SHIFT) as i16;
171 #[allow(clippy::erasing_op)]
172 fn idct_col(blk: &mut [i16; 64], off: usize) {
173 let in0 = ((i32::from(blk[off + 0*8])) << 8) + (1 << (COL_SHIFT - 1));
174 let in1 = (i32::from(blk[off + 4*8])) << 8;
175 let in2 = i32::from(blk[off + 6*8]);
176 let in3 = i32::from(blk[off + 2*8]);
177 let in4 = i32::from(blk[off + 1*8]);
178 let in5 = i32::from(blk[off + 7*8]);
179 let in6 = i32::from(blk[off + 5*8]);
180 let in7 = i32::from(blk[off + 3*8]);
182 let tmp = W7 * (in4 + in5);
183 let a4 = (tmp + (W1 - W7) * in4) >> 3;
184 let a5 = (tmp - (W1 + W7) * in5) >> 3;
186 let tmp = W3 * (in6 + in7);
187 let a6 = (tmp - (W3 - W5) * in6) >> 3;
188 let a7 = (tmp - (W3 + W5) * in7) >> 3;
193 let t1 = W6 * (in2 + in3);
194 let a2 = (t1 - (W2 + W6) * in2) >> 3;
195 let a3 = (t1 + (W2 - W6) * in3) >> 3;
205 let b2 = (W8 * (b4 + t2) + 128) >> 8;
206 let b4 = (W8 * (b4 - t2) + 128) >> 8;
208 blk[off + 0*8] = ((b7 + b1) >> COL_SHIFT) as i16;
209 blk[off + 7*8] = ((b7 - b1) >> COL_SHIFT) as i16;
210 blk[off + 1*8] = ((b3 + b2) >> COL_SHIFT) as i16;
211 blk[off + 6*8] = ((b3 - b2) >> COL_SHIFT) as i16;
212 blk[off + 2*8] = ((b0 + b4) >> COL_SHIFT) as i16;
213 blk[off + 5*8] = ((b0 - b4) >> COL_SHIFT) as i16;
214 blk[off + 3*8] = ((b5 + b6) >> COL_SHIFT) as i16;
215 blk[off + 4*8] = ((b5 - b6) >> COL_SHIFT) as i16;
219 pub fn h263_idct(blk: &mut [i16; 64]) {
220 for i in 0..8 { idct_row(&mut blk[i*8..(i+1)*8]); }
221 for i in 0..8 { idct_col(blk, i); }
224 fn h263_interp00(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize)
229 for x in 0..bw { dst[didx + x] = src[sidx + x]; }
235 fn h263_interp01(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize)
240 for x in 0..bw { dst[didx + x] = (((src[sidx + x] as u16) + (src[sidx + x + 1] as u16) + 1) >> 1) as u8; }
246 fn h263_interp10(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize)
251 for x in 0..bw { dst[didx + x] = (((src[sidx + x] as u16) + (src[sidx + x + sstride] as u16) + 1) >> 1) as u8; }
257 fn h263_interp11(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize)
263 dst[didx + x] = (((src[sidx + x] as u16) +
264 (src[sidx + x + 1] as u16) +
265 (src[sidx + x + sstride] as u16) +
266 (src[sidx + x + sstride + 1] as u16) + 2) >> 2) as u8;
273 pub const H263_INTERP_FUNCS: &[blockdsp::BlkInterpFunc] = &[
274 h263_interp00, h263_interp01, h263_interp10, h263_interp11 ];
276 fn h263_interp00_avg(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize)
282 let a = dst[didx + x] as u16;
283 let b = src[sidx + x] as u16;
284 dst[didx + x] = ((a + b + 1) >> 1) as u8;
291 fn h263_interp01_avg(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize)
297 let a = dst[didx + x] as u16;
298 let b = ((src[sidx + x] as u16) + (src[sidx + x + 1] as u16) + 1) >> 1;
299 dst[didx + x] = ((a + b + 1) >> 1) as u8;
306 fn h263_interp10_avg(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize)
312 let a = dst[didx + x] as u16;
313 let b = ((src[sidx + x] as u16) + (src[sidx + x + sstride] as u16) + 1) >> 1;
314 dst[didx + x] = ((a + b + 1) >> 1) as u8;
321 fn h263_interp11_avg(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize)
327 let a = dst[didx + x] as u16;
328 let b = ((src[sidx + x] as u16) +
329 (src[sidx + x + 1] as u16) +
330 (src[sidx + x + sstride] as u16) +
331 (src[sidx + x + sstride + 1] as u16) + 2) >> 2;
332 dst[didx + x] = ((a + b + 1) >> 1) as u8;
339 pub const H263_INTERP_AVG_FUNCS: &[blockdsp::BlkInterpFunc] = &[
340 h263_interp00_avg, h263_interp01_avg, h263_interp10_avg, h263_interp11_avg ];
342 pub struct H263BlockDSP { }
345 pub fn new() -> Self {
350 #[allow(clippy::erasing_op)]
351 fn deblock_hor(buf: &mut NAVideoBuffer<u8>, comp: usize, q: u8, off: usize) {
352 let stride = buf.get_stride(comp);
353 let dptr = buf.get_data_mut().unwrap();
354 let buf = dptr.as_mut_slice();
356 let a = buf[off - 2 * stride + x] as i16;
357 let b = buf[off - 1 * stride + x] as i16;
358 let c = buf[off + 0 * stride + x] as i16;
359 let d = buf[off + 1 * stride + x] as i16;
360 let diff = ((a - d) * 3 + (c - b) * 8) >> 4;
361 if (diff != 0) && (diff >= -32) && (diff < 32) {
362 let d0 = diff.abs() * 2 - (q as i16);
363 let d1 = if d0 < 0 { 0 } else { d0 };
364 let d2 = diff.abs() - d1;
365 let d3 = if d2 < 0 { 0 } else { d2 };
367 let delta = if diff < 0 { -d3 } else { d3 };
370 if b1 < 0 { buf[off - 1 * stride + x] = 0; }
371 else if b1 > 255 { buf[off - 1 * stride + x] = 0xFF; }
372 else { buf[off - 1 * stride + x] = b1 as u8; }
374 if c1 < 0 { buf[off + x] = 0; }
375 else if c1 > 255 { buf[off + x] = 0xFF; }
376 else { buf[off + x] = c1 as u8; }
381 fn deblock_ver(buf: &mut NAVideoBuffer<u8>, comp: usize, q: u8, off: usize) {
382 let stride = buf.get_stride(comp);
383 let dptr = buf.get_data_mut().unwrap();
384 let buf = dptr.as_mut_slice();
386 let a = buf[off - 2 + y * stride] as i16;
387 let b = buf[off - 1 + y * stride] as i16;
388 let c = buf[off + 0 + y * stride] as i16;
389 let d = buf[off + 1 + y * stride] as i16;
390 let diff = ((a - d) * 3 + (c - b) * 8) >> 4;
391 if (diff != 0) && (diff >= -32) && (diff < 32) {
392 let d0 = diff.abs() * 2 - (q as i16);
393 let d1 = if d0 < 0 { 0 } else { d0 };
394 let d2 = diff.abs() - d1;
395 let d3 = if d2 < 0 { 0 } else { d2 };
397 let delta = if diff < 0 { -d3 } else { d3 };
400 if b1 < 0 { buf[off - 1 + y * stride] = 0; }
401 else if b1 > 255 { buf[off - 1 + y * stride] = 0xFF; }
402 else { buf[off - 1 + y * stride] = b1 as u8; }
404 if c1 < 0 { buf[off + y * stride] = 0; }
405 else if c1 > 255 { buf[off + y * stride] = 0xFF; }
406 else { buf[off + y * stride] = c1 as u8; }
411 pub fn h263_filter_row(buf: &mut NAVideoBuffer<u8>, mb_y: usize, mb_w: usize, cbpi: &CBPInfo) {
412 let stride = buf.get_stride(0);
413 let mut off = buf.get_offset(0) + mb_y * 16 * stride;
414 for mb_x in 0..mb_w {
416 let coded0 = cbpi.is_coded(mb_x, 0);
417 let coded1 = cbpi.is_coded(mb_x, 1);
418 let q = cbpi.get_q(mb_w + mb_x);
420 if coded0 && cbpi.is_coded_top(mb_x, 0) { deblock_hor(buf, 0, q, coff); }
421 if coded1 && cbpi.is_coded_top(mb_x, 1) { deblock_hor(buf, 0, q, coff + 8); }
423 let coff = off + 8 * stride;
424 if cbpi.is_coded(mb_x, 2) && coded0 { deblock_hor(buf, 0, q, coff); }
425 if cbpi.is_coded(mb_x, 3) && coded1 { deblock_hor(buf, 0, q, coff + 8); }
428 let mut leftt = false;
429 let mut leftc = false;
430 let mut off = buf.get_offset(0) + mb_y * 16 * stride;
431 for mb_x in 0..mb_w {
432 let ctop0 = cbpi.is_coded_top(mb_x, 0);
433 let ctop1 = cbpi.is_coded_top(mb_x, 0);
434 let ccur0 = cbpi.is_coded(mb_x, 0);
435 let ccur1 = cbpi.is_coded(mb_x, 1);
436 let q = cbpi.get_q(mb_w + mb_x);
438 let coff = off - 8 * stride;
439 let qtop = cbpi.get_q(mb_x);
440 if leftt && ctop0 { deblock_ver(buf, 0, qtop, coff); }
441 if ctop0 && ctop1 { deblock_ver(buf, 0, qtop, coff + 8); }
443 if leftc && ccur0 { deblock_ver(buf, 0, q, off); }
444 if ccur0 && ccur1 { deblock_ver(buf, 0, q, off + 8); }
449 let strideu = buf.get_stride(1);
450 let stridev = buf.get_stride(2);
451 let offu = buf.get_offset(1) + mb_y * 8 * strideu;
452 let offv = buf.get_offset(2) + mb_y * 8 * stridev;
454 for mb_x in 0..mb_w {
455 let ctu = cbpi.is_coded_top(mb_x, 4);
456 let ccu = cbpi.is_coded(mb_x, 4);
457 let ctv = cbpi.is_coded_top(mb_x, 5);
458 let ccv = cbpi.is_coded(mb_x, 5);
459 let q = cbpi.get_q(mb_w + mb_x);
460 if ctu && ccu { deblock_hor(buf, 1, q, offu + mb_x * 8); }
461 if ctv && ccv { deblock_hor(buf, 2, q, offv + mb_x * 8); }
463 let mut leftu = false;
464 let mut leftv = false;
465 let offu = buf.get_offset(1) + (mb_y - 1) * 8 * strideu;
466 let offv = buf.get_offset(2) + (mb_y - 1) * 8 * stridev;
467 for mb_x in 0..mb_w {
468 let ctu = cbpi.is_coded_top(mb_x, 4);
469 let ctv = cbpi.is_coded_top(mb_x, 5);
470 let qt = cbpi.get_q(mb_x);
471 if leftu && ctu { deblock_ver(buf, 1, qt, offu + mb_x * 8); }
472 if leftv && ctv { deblock_ver(buf, 2, qt, offv + mb_x * 8); }
479 impl BlockDSP for H263BlockDSP {
480 fn idct(&self, blk: &mut [i16; 64]) {
483 fn copy_blocks(&self, dst: &mut NAVideoBuffer<u8>, src: &NAVideoBuffer<u8>, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV) {
484 let srcx = ((mv.x >> 1) as isize) + (xpos as isize);
485 let srcy = ((mv.y >> 1) as isize) + (ypos as isize);
486 let mode = ((mv.x & 1) + (mv.y & 1) * 2) as usize;
488 blockdsp::copy_blocks(dst, src, xpos, ypos, srcx, srcy, w, h, 0, 1, mode, H263_INTERP_FUNCS);
490 fn avg_blocks(&self, dst: &mut NAVideoBuffer<u8>, src: &NAVideoBuffer<u8>, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV) {
491 let srcx = ((mv.x >> 1) as isize) + (xpos as isize);
492 let srcy = ((mv.y >> 1) as isize) + (ypos as isize);
493 let mode = ((mv.x & 1) + (mv.y & 1) * 2) as usize;
495 blockdsp::copy_blocks(dst, src, xpos, ypos, srcx, srcy, w, h, 0, 1, mode, H263_INTERP_AVG_FUNCS);
497 fn filter_row(&self, buf: &mut NAVideoBuffer<u8>, mb_y: usize, mb_w: usize, cbpi: &CBPInfo) {
498 h263_filter_row(buf, mb_y, mb_w, cbpi)