1 use nihav_core::frame::{FrameType, NAVideoBuffer};
2 use nihav_core::codecs::MV;
3 use nihav_core::codecs::blockdsp::edge_emu;
4 use super::rv3040::{RV34DSP, RV34MBInfo};
6 fn clip8(a: i16) -> u8 {
8 else if a > 255 { 255 }
13 ($s: ident, $o: expr) => ( $s[$o] as i16 )
17 (01; $s: ident, $o: expr, $step: expr) => (
18 clip8((( el!($s, $o - 2 * $step)
19 -5 * el!($s, $o - 1 * $step)
20 +52 * el!($s, $o - 0 * $step)
21 +20 * el!($s, $o + 1 * $step)
22 -5 * el!($s, $o + 2 * $step)
23 + el!($s, $o + 3 * $step) + 32) >> 6) as i16)
25 (02; $s: ident, $o: expr, $step: expr) => (
26 clip8((( el!($s, $o - 2 * $step)
27 -5 * el!($s, $o - 1 * $step)
28 +20 * el!($s, $o - 0 * $step)
29 +20 * el!($s, $o + 1 * $step)
30 -5 * el!($s, $o + 2 * $step)
31 + el!($s, $o + 3 * $step) + 16) >> 5) as i16)
33 (03; $s: ident, $o: expr, $step: expr) => (
34 clip8((( el!($s, $o - 2 * $step)
35 -5 * el!($s, $o - 1 * $step)
36 +20 * el!($s, $o - 0 * $step)
37 +52 * el!($s, $o + 1 * $step)
38 -5 * el!($s, $o + 2 * $step)
39 + el!($s, $o + 3 * $step) + 32) >> 6) as i16)
43 macro_rules! mc_func {
44 (copy; $name: ident, $size: expr) => (
45 fn $name (dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
47 let d = &mut dst[didx..][..$size];
48 let s = &src[sidx..][..$size];
49 for x in 0..$size { d[x] = s[x]; }
55 (mc01; $name: ident, $size: expr, $ver: expr) => (
56 fn $name (dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
57 let step = if $ver { sstride } else { 1 };
60 dst[didx + x] = filter!(01; src, sidx + x, step);
67 (mc02; $name: ident, $size: expr, $ver: expr) => (
68 fn $name (dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
69 let step = if $ver { sstride } else { 1 };
72 dst[didx + x] = filter!(02; src, sidx + x, step);
79 (mc03; $name: ident, $size: expr, $ver: expr) => (
80 fn $name (dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
81 let step = if $ver { sstride } else { 1 };
84 dst[didx + x] = filter!(03; src, sidx + x, step);
91 (cm01; $name: ident, $size: expr, $ofilt: ident) => (
92 fn $name (dst: &mut [u8], didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
93 let mut buf: [u8; ($size + 5) * $size] = [0; ($size + 5) * $size];
98 for x in 0..$size { buf[bidx + x] = filter!(01; src, sidx + x, 1); }
102 $ofilt(dst, didx, dstride, &buf, 2*bstride, $size);
105 (cm02; $name: ident, $size: expr, $ofilt: ident) => (
106 fn $name (dst: &mut [u8], didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
107 let mut buf: [u8; ($size + 5) * $size] = [0; ($size + 5) * $size];
111 for _ in 0..$size+5 {
112 for x in 0..$size { buf[bidx + x] = filter!(02; src, sidx + x, 1); }
116 $ofilt(dst, didx, dstride, &buf, 2*bstride, $size);
119 (cm03; $name: ident, $size: expr, $ofilt: ident) => (
120 fn $name (dst: &mut [u8], didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
121 let mut buf: [u8; ($size + 5) * $size] = [0; ($size + 5) * $size];
125 for _ in 0..$size+5 {
126 for x in 0..$size { buf[bidx + x] = filter!(03; src, sidx + x, 1); }
130 $ofilt(dst, didx, dstride, &buf, 2*bstride, $size);
134 mc_func!(copy; copy_16, 16);
135 mc_func!(copy; copy_8, 8);
136 mc_func!(mc01; luma_mc_10_16, 16, false);
137 mc_func!(mc01; luma_mc_10_8, 8, false);
138 mc_func!(mc02; luma_mc_20_16, 16, false);
139 mc_func!(mc02; luma_mc_20_8, 8, false);
140 mc_func!(mc03; luma_mc_30_16, 16, false);
141 mc_func!(mc03; luma_mc_30_8, 8, false);
142 mc_func!(mc01; luma_mc_01_16, 16, true);
143 mc_func!(mc01; luma_mc_01_8, 8, true);
144 mc_func!(mc02; luma_mc_02_16, 16, true);
145 mc_func!(mc02; luma_mc_02_8, 8, true);
146 mc_func!(mc03; luma_mc_03_16, 16, true);
147 mc_func!(mc03; luma_mc_03_8, 8, true);
148 mc_func!(cm01; luma_mc_11_16, 16, luma_mc_01_16);
149 mc_func!(cm01; luma_mc_11_8, 8, luma_mc_01_8);
150 mc_func!(cm01; luma_mc_12_16, 16, luma_mc_02_16);
151 mc_func!(cm01; luma_mc_12_8, 8, luma_mc_02_8);
152 mc_func!(cm01; luma_mc_13_16, 16, luma_mc_03_16);
153 mc_func!(cm01; luma_mc_13_8, 8, luma_mc_03_8);
154 mc_func!(cm02; luma_mc_21_16, 16, luma_mc_01_16);
155 mc_func!(cm02; luma_mc_21_8, 8, luma_mc_01_8);
156 mc_func!(cm02; luma_mc_22_16, 16, luma_mc_02_16);
157 mc_func!(cm02; luma_mc_22_8, 8, luma_mc_02_8);
158 mc_func!(cm02; luma_mc_23_16, 16, luma_mc_03_16);
159 mc_func!(cm02; luma_mc_23_8, 8, luma_mc_03_8);
160 mc_func!(cm03; luma_mc_31_16, 16, luma_mc_01_16);
161 mc_func!(cm03; luma_mc_31_8, 8, luma_mc_01_8);
162 mc_func!(cm03; luma_mc_32_16, 16, luma_mc_02_16);
163 mc_func!(cm03; luma_mc_32_8, 8, luma_mc_02_8);
164 mc_func!(cm03; luma_mc_33_16, 16, luma_mc_03_16);
165 mc_func!(cm03; luma_mc_33_8, 8, luma_mc_03_8);
167 const RV40_CHROMA_BIAS: [[u16; 4]; 4] = [
174 fn rv40_chroma_mc(dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize, size: usize, x: usize, y: usize) {
175 if (x == 0) && (y == 0) {
177 for x in 0..size { dst[didx + x] = src[sidx + x]; }
183 let bias = RV40_CHROMA_BIAS[y >> 1][x >> 1];
184 if (x > 0) && (y > 0) {
185 let a = ((4 - x) * (4 - y)) as u16;
186 let b = (( x) * (4 - y)) as u16;
187 let c = ((4 - x) * ( y)) as u16;
188 let d = (( x) * ( y)) as u16;
191 dst[didx + x] = ((a * (src[sidx + x] as u16)
192 + b * (src[sidx + x + 1] as u16)
193 + c * (src[sidx + x + sstride] as u16)
194 + d * (src[sidx + x + 1 + sstride] as u16) + bias) >> 4) as u8;
200 let a = ((4 - x) * (4 - y)) as u16;
201 let e = (( x) * (4 - y) + (4 - x) * ( y)) as u16;
202 let step = if y > 0 { sstride } else { 1 };
205 dst[didx + x] = ((a * (src[sidx + x] as u16)
206 + e * (src[sidx + x + step] as u16) + bias) >> 4) as u8;
215 luma_mc: [[fn (&mut [u8], usize, usize, &[u8], usize, usize); 16]; 2],
219 pub fn new() -> Self {
222 [ copy_16, luma_mc_10_16, luma_mc_20_16, luma_mc_30_16,
223 luma_mc_01_16, luma_mc_11_16, luma_mc_21_16, luma_mc_31_16,
224 luma_mc_02_16, luma_mc_12_16, luma_mc_22_16, luma_mc_32_16,
225 luma_mc_03_16, luma_mc_13_16, luma_mc_23_16, luma_mc_33_16 ],
226 [ copy_8, luma_mc_10_8, luma_mc_20_8, luma_mc_30_8,
227 luma_mc_01_8, luma_mc_11_8, luma_mc_21_8, luma_mc_31_8,
228 luma_mc_02_8, luma_mc_12_8, luma_mc_22_8, luma_mc_32_8,
229 luma_mc_03_8, luma_mc_13_8, luma_mc_23_8, luma_mc_33_8 ] ],
235 ($src: ident, $o: expr) => ($src[$o] as i16);
238 fn clip_symm(a: i16, lim: i16) -> i16 {
248 fn rv40_weak_loop_filter4(pix: &mut [u8], mut off: usize, step: usize, stride: usize,
249 filter_p1: bool, filter_q1: bool, alpha: i16, beta: i16,
250 lim_p0q0: i16, lim_p1: i16, lim_q1: i16) {
252 let p0 = el!(pix, off - step);
253 let q0 = el!(pix, off);
261 let u = (alpha * t.wrapping_abs()) >> 7;
262 if u > (if filter_p1 && filter_q1 { 2 } else { 3 }) {
267 let p2 = el!(pix, off - 3*step);
268 let p1 = el!(pix, off - 2*step);
269 let q1 = el!(pix, off + step);
270 let q2 = el!(pix, off + 2*step);
273 if filter_p1 && filter_q1 {
274 str = (t << 2) + (p1 - q1);
279 let diff = clip_symm((str + 4) >> 3, lim_p0q0);
280 pix[off - step] = clip8(p0 + diff);
281 pix[off ] = clip8(q0 - diff);
283 if filter_p1 && ((p1 - p0).wrapping_abs() <= beta) {
284 let p1_diff = ((p1 - p0) + (p1 - p2) - diff) >> 1;
285 pix[off - 2*step] = clip8(p1 - clip_symm(p1_diff, lim_p1));
288 if filter_q1 && ((q1 - q0).wrapping_abs() <= beta) {
289 let q1_diff = ((q1 - q0) + (q1 - q2) + diff) >> 1;
290 pix[off + step] = clip8(q1 - clip_symm(q1_diff, lim_q1));
297 fn rv40_weak_loop_filter4_h(pix: &mut [u8], off: usize, stride: usize,
298 filter_p1: bool, filter_q1: bool, alpha: i16, beta: i16,
299 lim_p0q0: i16, lim_p1: i16, lim_q1: i16) {
300 rv40_weak_loop_filter4(pix, off, stride, 1, filter_p1, filter_q1, alpha, beta, lim_p0q0, lim_p1, lim_q1);
302 fn rv40_weak_loop_filter4_v(pix: &mut [u8], off: usize, stride: usize,
303 filter_p1: bool, filter_q1: bool, alpha: i16, beta: i16,
304 lim_p0q0: i16, lim_p1: i16, lim_q1: i16) {
305 let src = &mut pix[off - 3..][..stride * 3 + 3 + 3];
306 for ch in src.chunks_mut(stride).take(4) {
307 assert!(ch.len() >= 3 + 3);
308 let p0 = el!(ch, 3 - 1);
316 let u = (alpha * t.wrapping_abs()) >> 7;
317 if u > (if filter_p1 && filter_q1 { 2 } else { 3 }) {
321 let p2 = el!(ch, 3 - 3);
322 let p1 = el!(ch, 3 - 2);
323 let q1 = el!(ch, 3 + 1);
324 let q2 = el!(ch, 3 + 2);
327 if filter_p1 && filter_q1 {
328 str = (t << 2) + (p1 - q1);
333 let diff = clip_symm((str + 4) >> 3, lim_p0q0);
334 ch[3 - 1] = clip8(p0 + diff);
335 ch[3 ] = clip8(q0 - diff);
337 if filter_p1 && ((p1 - p0).wrapping_abs() <= beta) {
338 let p1_diff = ((p1 - p0) + (p1 - p2) - diff) >> 1;
339 ch[3 - 2] = clip8(p1 - clip_symm(p1_diff, lim_p1));
342 if filter_q1 && ((q1 - q0).wrapping_abs() <= beta) {
343 let q1_diff = ((q1 - q0) + (q1 - q2) + diff) >> 1;
344 ch[3 + 1] = clip8(q1 - clip_symm(q1_diff, lim_q1));
350 const RV40_DITHER_L: [i16; 16] = [
351 0x40, 0x50, 0x20, 0x60, 0x30, 0x50, 0x40, 0x30,
352 0x50, 0x40, 0x50, 0x30, 0x60, 0x20, 0x50, 0x40
354 const RV40_DITHER_R: [i16; 16] = [
355 0x40, 0x30, 0x60, 0x20, 0x50, 0x30, 0x30, 0x40,
356 0x40, 0x40, 0x50, 0x30, 0x20, 0x60, 0x30, 0x40
359 fn sfilter(a: i16, b: i16, c: i16, d: i16, e: i16, dither: i16, clip: bool, lims: i16) -> i16 {
360 let val = (25 * (a + e) + 26 * (b + c + d) + dither) >> 7;
364 } else if val > c + lims {
374 fn rv40_strong_loop_filter4(pix: &mut [u8], mut off: usize, step: usize, stride: usize,
375 alpha: i16, lims: i16, dmode: usize, chroma: bool) {
377 let p0 = el!(pix, off - step);
378 let q0 = el!(pix, off);
386 let fmode = (alpha * t.wrapping_abs()) >> 7;
392 let p3 = el!(pix, off - 4*step);
393 let p2 = el!(pix, off - 3*step);
394 let p1 = el!(pix, off - 2*step);
395 let q1 = el!(pix, off + step);
396 let q2 = el!(pix, off + 2*step);
397 let q3 = el!(pix, off + 3*step);
399 let np0 = sfilter(p2, p1, p0, q0, q1, RV40_DITHER_L[dmode + i], fmode != 0, lims);
400 let nq0 = sfilter( p1, p0, q0, q1, q0, RV40_DITHER_R[dmode + i], fmode != 0, lims);
402 let np1 = sfilter(p3, p2, p1, np0, q0, RV40_DITHER_L[dmode + i], fmode != 0, lims);
403 let nq1 = sfilter( p0, nq0, q1, q2, q3, RV40_DITHER_R[dmode + i], fmode != 0, lims);
405 pix[off - 2*step] = np1 as u8;
406 pix[off - step] = np0 as u8;
407 pix[off] = nq0 as u8;
408 pix[off + step] = nq1 as u8;
411 let np2 = sfilter(np0, np1, p2, p3, np1, 64, false, 0);
412 let nq2 = sfilter(nq0, nq1, q2, q3, q2, 64, false, 0);
413 pix[off - 3*step] = np2 as u8;
414 pix[off + 2*step] = nq2 as u8;
421 fn rv40_loop_strength(pix: &[u8], off: usize, step: usize, stride: usize,
422 beta: i16, beta2: i16, edge: bool) -> (bool, bool, bool) {
423 let mut sum_p1p0 = 0;
424 let mut sum_q1q0 = 0;
428 sum_p1p0 += el!(pix, off1 - 2 * step) - el!(pix, off1 - step);
429 sum_q1q0 += el!(pix, off1 + step) - el!(pix, off1);
433 let filter_p1 = sum_p1p0.wrapping_abs() < beta * 4;
434 let filter_q1 = sum_q1q0.wrapping_abs() < beta * 4;
436 if (!filter_p1 || !filter_q1) || !edge {
437 return (false, filter_p1, filter_q1);
440 let mut sum_p1p2 = 0;
441 let mut sum_q1q2 = 0;
445 sum_p1p2 += el!(pix, off1 - 2 * step) - el!(pix, off1 - 3 * step);
446 sum_q1q2 += el!(pix, off1 + step) - el!(pix, off1 + 2 * step);
450 let strong = (sum_p1p2.wrapping_abs() < beta2) && (sum_q1q2.wrapping_abs() < beta2);
452 (strong, filter_p1, filter_q1)
455 fn rv40_loop_strength_h(pix: &[u8], off: usize, stride: usize,
456 beta: i16, beta2: i16, edge: bool) -> (bool, bool, bool) {
457 rv40_loop_strength(pix, off, stride, 1, beta, beta2, edge)
460 fn rv40_loop_strength_v(pix: &[u8], off: usize, stride: usize,
461 beta: i16, beta2: i16, edge: bool) -> (bool, bool, bool) {
462 let src = &pix[off - 3..][..stride * 3 + 3 + 3];
463 let mut sum_p1p0 = 0;
464 let mut sum_q1q0 = 0;
466 for ch in src.chunks(stride).take(4) {
467 assert!(ch.len() >= 3 + 3);
468 sum_p1p0 += el!(ch, 3 - 2) - el!(ch, 3 - 1);
469 sum_q1q0 += el!(ch, 3 + 1) - el!(ch, 3);
472 let filter_p1 = sum_p1p0.wrapping_abs() < beta * 4;
473 let filter_q1 = sum_q1q0.wrapping_abs() < beta * 4;
475 if (!filter_p1 || !filter_q1) || !edge {
476 return (false, filter_p1, filter_q1);
479 let mut sum_p1p2 = 0;
480 let mut sum_q1q2 = 0;
482 for ch in src.chunks(stride).take(4) {
483 assert!(ch.len() >= 3 + 3);
484 sum_p1p2 += el!(ch, 3 - 2) - el!(ch, 3 - 3);
485 sum_q1q2 += el!(ch, 3 + 1) - el!(ch, 3 + 2);
488 let strong = (sum_p1p2.wrapping_abs() < beta2) && (sum_q1q2.wrapping_abs() < beta2);
490 (strong, filter_p1, filter_q1)
493 fn rv40_loop_filter4_h(pix: &mut [u8], off: usize, stride: usize,
494 dmode: usize, lim_p1: i16, lim_q1: i16, alpha: i16, beta: i16, beta2: i16,
495 chroma: bool, edge: bool) {
496 let (strong, filter_p1, filter_q1) = rv40_loop_strength_h(pix, off, stride, beta, beta2, edge);
497 let lims = (filter_p1 as i16) + (filter_q1 as i16) + ((lim_p1 + lim_q1) >> 1) + 1;
500 rv40_strong_loop_filter4(pix, off, stride, 1, alpha, lims, dmode, chroma);
501 } else if filter_p1 && filter_q1 {
502 rv40_weak_loop_filter4_h(pix, off, stride, true, true, alpha, beta,
503 lims, lim_p1, lim_q1);
504 } else if filter_p1 || filter_q1 {
505 rv40_weak_loop_filter4_h(pix, off, stride, filter_p1, filter_q1, alpha, beta,
506 lims >> 1, lim_p1 >> 1, lim_q1 >> 1);
510 fn rv40_loop_filter4_v(pix: &mut [u8], off: usize, stride: usize,
511 dmode: usize, lim_p1: i16, lim_q1: i16, alpha: i16, beta: i16, beta2: i16,
512 chroma: bool, edge: bool) {
513 let (strong, filter_p1, filter_q1) = rv40_loop_strength_v(pix, off, stride, beta, beta2, edge);
514 let lims = (filter_p1 as i16) + (filter_q1 as i16) + ((lim_p1 + lim_q1) >> 1) + 1;
517 rv40_strong_loop_filter4(pix, off, 1, stride, alpha, lims, dmode, chroma);
518 } else if filter_p1 && filter_q1 {
519 rv40_weak_loop_filter4_v(pix, off, stride, true, true, alpha, beta,
520 lims, lim_p1, lim_q1);
521 } else if filter_p1 || filter_q1 {
522 rv40_weak_loop_filter4_v(pix, off, stride, filter_p1, filter_q1, alpha, beta,
523 lims >> 1, lim_p1 >> 1, lim_q1 >> 1);
527 const RV40_ALPHA_TAB: [i16; 32] = [
528 128, 128, 128, 128, 128, 128, 128, 128,
529 128, 128, 122, 96, 75, 59, 47, 37,
530 29, 23, 18, 15, 13, 11, 10, 9,
531 8, 7, 6, 5, 4, 3, 2, 1
534 const RV40_BETA_TAB: [i16; 32] = [
535 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 4, 4, 6, 6,
536 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14, 15, 16, 17
539 const RV40_FILTER_CLIP_TBL: [[i16; 32]; 3] = [
541 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
542 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
544 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
545 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5
547 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
548 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 7, 8, 9
552 macro_rules! test_bit {
553 ($pat: expr, $x: expr) => ( (($pat >> $x) & 1) != 0 )
556 fn check_pos(x: usize, y: usize, size: usize, w: usize, h: usize, dx: i16, dy: i16, e0: isize, e1: isize, e2: isize, e3: isize) -> bool {
557 let xn = (x as isize) + (dx as isize);
558 let yn = (y as isize) + (dy as isize);
560 (xn - e0 >= 0) && (xn + (size as isize) + e1 <= (w as isize)) && (yn - e2 >= 0) && (yn + (size as isize) + e3 <= (h as isize))
563 const RV40_EDGE1: [isize; 4] = [ 0, 2, 2, 2 ];
564 const RV40_EDGE2: [isize; 4] = [ 0, 3, 3, 3 ];
566 impl RV34DSP for RV40DSP {
567 fn loop_filter(&self, frame: &mut NAVideoBuffer<u8>, _ftype: FrameType, mbinfo: &[RV34MBInfo], mb_w: usize, row: usize) {
568 // todo proper B-frame filtering?
569 let mut offs: [usize; 3] = [0; 3];
570 let mut stride: [usize; 3] = [0; 3];
571 let (w, h) = frame.get_dimensions(0);
572 let small_frame = w * h <= 176*144;
575 stride[comp] = frame.get_stride(comp);
576 let start = if comp == 0 { row * 16 } else { row * 8 };
577 offs[comp] = frame.get_offset(comp) + start * stride[comp];
580 let data = frame.get_data_mut().unwrap();
581 let dst: &mut [u8] = data.as_mut_slice();
583 let mut mb_pos: usize = row * mb_w;
584 let mut left_q: usize = 0;
585 for mb_x in 0..mb_w {
586 let q = mbinfo[mb_pos].q as usize;
587 let alpha = RV40_ALPHA_TAB[q];
588 let beta = RV40_BETA_TAB[q];
589 let beta_y = if small_frame { beta * 4 } else { beta * 3 };
590 let beta_c = beta * 3;
592 let cur_dbk = mbinfo[mb_pos].deblock;
593 let cur_cbp = mbinfo[mb_pos].cbp_c;
595 let is_strong = mbinfo[mb_pos].mbtype.is_intra_or_16();
596 let top_is_strong = is_strong || (row > 0 && mbinfo[mb_pos - mb_w].mbtype.is_intra_or_16());
597 let left_is_strong = is_strong || (mb_x > 0 && mbinfo[mb_pos - 1].mbtype.is_intra_or_16());
600 let yoff = offs[0] + mb_x * 16 + y * 4 * stride[0];
602 let bpos = x + y * 4;
603 let filter_hor_down = (y != 3) && !is_strong;
604 let filter_ver = (x > 0) || (mb_x > 0);
605 let filter_hor_up = (row > 0) && (x == 0) && top_is_strong;
606 let ver_strong = (x == 0) && (mb_x > 0) && left_is_strong;
608 let cur_strength: usize;
611 } else if test_bit!(cur_dbk, bpos) {
617 let left_strength: usize;
621 } else if test_bit!(cur_dbk, bpos - 1) {
629 } else if test_bit!(mbinfo[mb_pos - 1].deblock, bpos + 3) {
638 let bot_strength: usize;
642 } else if test_bit!(cur_dbk, bpos + 4) {
651 let top_strength: usize;
655 } else if test_bit!(cur_dbk, bpos - 4) {
663 } else if test_bit!(mbinfo[mb_pos - mb_w].deblock, bpos + 12) {
672 let l_q = if x > 0 { q } else { left_q };
673 let top_q = if row > 0 { mbinfo[mb_pos - mb_w].q as usize } else { 0 };
675 let lim_cur = RV40_FILTER_CLIP_TBL [cur_strength][q];
676 let lim_top = RV40_FILTER_CLIP_TBL [top_strength][top_q];
677 let lim_left = RV40_FILTER_CLIP_TBL[left_strength][l_q];
678 let lim_bottom = RV40_FILTER_CLIP_TBL [bot_strength][q];
680 let dmode = if y > 0 { x + y * 4 } else { x * 4 };
683 rv40_loop_filter4_h(dst, yoff + 4 * stride[0] + x * 4, stride[0],
684 dmode, lim_cur, lim_bottom, alpha, beta, beta_y, false, false);
686 if filter_ver && !ver_strong {
687 rv40_loop_filter4_v(dst, yoff + x * 4, stride[0],
688 dmode, lim_left, lim_cur, alpha, beta, beta_y, false, false);
691 rv40_loop_filter4_h(dst, yoff + x * 4, stride[0],
692 dmode, lim_top, lim_cur, alpha, beta, beta_y, false, true);
694 if filter_ver && ver_strong {
695 rv40_loop_filter4_v(dst, yoff + x * 4, stride[0],
696 dmode, lim_left, lim_cur, alpha, beta, beta_y, false, true);
703 let coff = offs[comp] + mb_x * 8 + y * 4 * stride[comp];
705 let bpos = x + y * 2 + (comp - 1) * 4;
707 let filter_hor_down = (y != 1) && !is_strong;
708 let filter_ver = (x > 0) || (mb_x > 0);
709 let filter_hor_up = (row > 0) && (x == 0) && top_is_strong;
710 let ver_strong = (x == 0) && (mb_x > 0) && left_is_strong;
712 let cur_strength: usize;
715 } else if test_bit!(cur_cbp, bpos) {
721 let left_strength: usize;
725 } else if test_bit!(cur_cbp, bpos - 1) {
733 } else if test_bit!(mbinfo[mb_pos - 1].cbp_c, bpos + 1) {
742 let bot_strength: usize;
746 } else if test_bit!(cur_cbp, bpos + 2) {
755 let top_strength: usize;
759 } else if test_bit!(cur_cbp, bpos - 2) {
767 } else if test_bit!(mbinfo[mb_pos - mb_w].cbp_c, bpos + 2) {
776 let l_q = if x > 0 { q } else { left_q };
777 let top_q = if row > 0 { mbinfo[mb_pos - mb_w].q as usize } else { 0 };
779 let lim_cur = RV40_FILTER_CLIP_TBL [cur_strength][q];
780 let lim_top = RV40_FILTER_CLIP_TBL [top_strength][top_q];
781 let lim_left = RV40_FILTER_CLIP_TBL[left_strength][l_q];
782 let lim_bottom = RV40_FILTER_CLIP_TBL [bot_strength][q];
785 rv40_loop_filter4_h(dst, coff + 4 * stride[comp] + x * 4, stride[comp],
786 x * 8, lim_cur, lim_bottom, alpha, beta, beta_c, true, false);
788 if filter_ver && !ver_strong {
789 rv40_loop_filter4_v(dst, coff + x * 4, stride[comp],
790 y * 8, lim_left, lim_cur, alpha, beta, beta_c, true, false);
793 rv40_loop_filter4_h(dst, coff + x * 4, stride[comp],
794 x * 8, lim_top, lim_cur, alpha, beta, beta_c, true, true);
796 if filter_ver && ver_strong {
797 rv40_loop_filter4_v(dst, coff + x * 4, stride[comp],
798 y * 8, lim_left, lim_cur, alpha, beta, beta_c, true, true);
809 fn do_luma_mc(&self, frame: &mut NAVideoBuffer<u8>, prev_frame: &NAVideoBuffer<u8>, x: usize, y: usize, mv: MV, use16: bool, avg: bool) {
810 let size: usize = if use16 { 16 } else { 8 };
811 let dstride = frame.get_stride(0);
812 let doffset = frame.get_offset(0) + (if !avg { x + y * dstride } else { 0 });
813 let data = frame.get_data_mut().unwrap();
814 let dst: &mut [u8] = data.as_mut_slice();
816 let (w_, h_) = prev_frame.get_dimensions(0);
817 let w = (w_ + 15) & !15;
818 let h = (h_ + 15) & !15;
821 let cx = (mv.x & 3) as usize;
823 let cy = (mv.y & 3) as usize;
824 let mode = cx + cy * 4;
826 if check_pos(x, y, size, w, h, dx, dy, RV40_EDGE1[cx], RV40_EDGE2[cx], RV40_EDGE1[cy], RV40_EDGE2[cy]) {
827 let sstride = prev_frame.get_stride(0);
828 let mut soffset = prev_frame.get_offset(0) + x + y * sstride;
829 let data = prev_frame.get_data();
830 let src: &[u8] = data.as_slice();
831 soffset = ((soffset as isize) + (dx as isize) + (dy as isize) * (sstride as isize)) as usize;
832 self.luma_mc[if use16 { 0 } else { 1 }][mode](dst, doffset, dstride, src, soffset, sstride);
834 let mut ebuf: [u8; 32*22] = [0; 32*22];
835 edge_emu(prev_frame, (x as isize) + (dx as isize) - 2, (y as isize) + (dy as isize) - 2, 16+5, 16+5, &mut ebuf, 32, 0);
836 self.luma_mc[if use16 { 0 } else { 1 }][mode](dst, doffset, dstride, &ebuf, 32*2 + 2, 32);
839 fn do_chroma_mc(&self, frame: &mut NAVideoBuffer<u8>, prev_frame: &NAVideoBuffer<u8>, x: usize, y: usize, comp: usize, mv: MV, use8: bool, avg: bool) {
840 let size: usize = if use8 { 8 } else { 4 };
841 let dstride = frame.get_stride(comp);
842 let doffset = frame.get_offset(comp) + (if !avg { x + y * dstride } else { 0 });
843 let data = frame.get_data_mut().unwrap();
844 let dst: &mut [u8] = data.as_mut_slice();
846 let (w_, h_) = prev_frame.get_dimensions(comp);
847 let w = (w_ + 7) & !7;
848 let h = (h_ + 7) & !7;
853 let mut cx = (mvx & 3) as usize;
855 let mut cy = (mvy & 3) as usize;
857 if (cx == 3) && (cy == 3) {
862 if check_pos(x, y, size, w, h, dx, dy, 0, 1, 0, 1) {
863 let sstride = prev_frame.get_stride(comp);
864 let mut soffset = prev_frame.get_offset(comp) + x + y * sstride;
865 let data = prev_frame.get_data();
866 let src: &[u8] = data.as_slice();
867 soffset = ((soffset as isize) + (dx as isize) + (dy as isize) * (sstride as isize)) as usize;
868 rv40_chroma_mc(dst, doffset, dstride, src, soffset, sstride, size, cx, cy);
870 let mut ebuf: [u8; 16*10] = [0; 16*10];
871 edge_emu(prev_frame, (x as isize) + (dx as isize), (y as isize) + (dy as isize), 8+1, 8+1, &mut ebuf, 16, comp);
872 rv40_chroma_mc(dst, doffset, dstride, &ebuf, 0, 16, size, cx, cy);