]> git.nihav.org Git - nihav.git/blobdiff - src/codecs/real/rv30dsp.rs
split NihAV into subcrates
[nihav.git] / src / codecs / real / rv30dsp.rs
diff --git a/src/codecs/real/rv30dsp.rs b/src/codecs/real/rv30dsp.rs
deleted file mode 100644 (file)
index b1365db..0000000
+++ /dev/null
@@ -1,435 +0,0 @@
-use crate::frame::{FrameType, NAVideoBuffer};
-use crate::codecs::MV;
-use crate::codecs::blockdsp::edge_emu;
-use super::rv3040::{RV34DSP, RV34MBInfo};
-
-fn clip8(a: i16) -> u8 {
-    if a < 0 { 0 }
-    else if a > 255 { 255 }
-    else { a as u8 }
-}
-
-fn rv3_filter_h(dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize, bsize: usize, c1: i16, c2: i16) {
-    for _ in 0..bsize {
-        for x in 0..bsize {
-            dst[didx + x] = clip8((-((src[sidx + x - 1] as i16) + (src[sidx + x + 2] as i16)) + (src[sidx + x + 0] as i16) * c1 + (src[sidx + x + 1] as i16) * c2 + 8) >> 4);
-        }
-        sidx += sstride;
-        didx += dstride;
-    }
-}
-
-fn rv3_filter_v(dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize, bsize: usize, c1: i16, c2: i16) {
-    for _ in 0..bsize {
-        for x in 0..bsize {
-            dst[didx + x] = clip8((-((src[sidx + x - 1 * sstride] as i16) + (src[sidx + x + 2 * sstride] as i16)) + (src[sidx + x + 0 * sstride] as i16) * c1 + (src[sidx + x + 1 * sstride] as i16) * c2 + 8) >> 4);
-        }
-        sidx += sstride;
-        didx += dstride;
-    }
-}
-
-macro_rules! mc_matrix {
-    ($s: ident, $o: expr, $c1: expr) => (
-            ($c1 * 6) * ($s[$o] as i32) + ($c1 * 9) * ($s[$o + 1] as i32) + ($c1) * ($s[$o + 2] as i32)
-        );
-    ($s: ident, $o: expr, $c1: expr, $d1: expr, $d2: expr) => (
-            (-$c1) * ($s[$o - 1] as i32) + ($c1 * $d1) * ($s[$o] as i32) + ($c1 * $d2) * ($s[$o + 1] as i32) + (-$c1) * ($s[$o + 2] as i32)
-        );
-    ($s: ident, $o: expr, $ss: expr, $c1: expr, $c2: expr, $d1: expr, $d2: expr) => (
-        ((mc_matrix!($s, $o -     $ss,  -1, $d1, $d2) +
-          mc_matrix!($s, $o          , $c1, $d1, $d2) +
-          mc_matrix!($s, $o +     $ss, $c2, $d1, $d2) +
-          mc_matrix!($s, $o + 2 * $ss,  -1, $d1, $d2) + 128) >> 8) as i16
-        );
-    (m22; $s: ident, $o: expr, $ss: expr) => (
-        ((mc_matrix!($s, $o + 0 * $ss, 6) +
-          mc_matrix!($s, $o + 1 * $ss, 9) +
-          mc_matrix!($s, $o + 2 * $ss, 1) + 128) >> 8) as i16
-        );
-}
-
-macro_rules! mc_func {
-    (copy; $name: ident, $size: expr) => (
-        fn $name (dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
-            for _ in 0..$size {
-                let d = &mut dst[didx..][..$size];
-                let s = &src[sidx..][..$size];
-                for x in 0..$size { d[x] = s[x]; }
-                didx += dstride;
-                sidx += sstride;
-            }
-        }
-        );
-    (hor; $name: ident, $c1: expr, $c2: expr, $size: expr) => (
-        fn $name (dst: &mut [u8], didx: usize, dstride: usize, src: &[u8], sidx: usize, sstride: usize) {
-            rv3_filter_h(dst, didx, dstride, src, sidx, sstride, $size, $c1, $c2);
-        }
-        );
-    (ver; $name: ident, $c1: expr, $c2: expr, $size: expr) => (
-        fn $name (dst: &mut [u8], didx: usize, dstride: usize, src: &[u8], sidx: usize, sstride: usize) {
-            rv3_filter_v(dst, didx, dstride, src, sidx, sstride, $size, $c1, $c2);
-        }
-        );
-    (m11; $name: ident, $size: expr) => (
-        fn $name (dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
-            for _ in 0..$size {
-                for x in 0..$size {
-                    dst[didx + x] = clip8(mc_matrix!(src, sidx + x, sstride, 12, 6, 12, 6));
-                }
-                didx += dstride;
-                sidx += sstride;
-            }
-        }
-        );
-    (m12; $name: ident, $size: expr) => (
-        fn $name (dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
-            for _ in 0..$size {
-                for x in 0..$size {
-                    dst[didx + x] = clip8(mc_matrix!(src, sidx + x, sstride, 6, 12, 12, 6));
-                }
-                didx += dstride;
-                sidx += sstride;
-            }
-        }
-        );
-    (m21; $name: ident, $size: expr) => (
-        fn $name (dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
-            for _ in 0..$size {
-                for x in 0..$size {
-                    dst[didx + x] = clip8(mc_matrix!(src, sidx + x, sstride, 12, 6, 6, 12));
-                }
-                didx += dstride;
-                sidx += sstride;
-            }
-        }
-        );
-    (m22; $name: ident, $size: expr) => (
-        fn $name (dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize) {
-            for _ in 0..$size {
-                for x in 0..$size {
-                    dst[didx + x] = clip8(mc_matrix!(m22; src, sidx + x, sstride));
-                }
-                didx += dstride;
-                sidx += sstride;
-            }
-        }
-        );
-}
-mc_func!(copy; copy_16, 16);
-mc_func!(copy; copy_8,   8);
-mc_func!(hor;  luma_mc_10_16, 12, 6, 16);
-mc_func!(hor;  luma_mc_20_16, 6, 12, 16);
-mc_func!(hor;  luma_mc_10_8,  12, 6,  8);
-mc_func!(hor;  luma_mc_20_8,  6, 12,  8);
-mc_func!(ver;  luma_mc_01_16, 12, 6, 16);
-mc_func!(ver;  luma_mc_02_16, 6, 12, 16);
-mc_func!(ver;  luma_mc_01_8,  12, 6,  8);
-mc_func!(ver;  luma_mc_02_8,  6, 12,  8);
-mc_func!(m11;  luma_mc_11_16,        16);
-mc_func!(m11;  luma_mc_11_8,          8);
-mc_func!(m21;  luma_mc_21_16,        16);
-mc_func!(m21;  luma_mc_21_8,          8);
-mc_func!(m12;  luma_mc_12_16,        16);
-mc_func!(m12;  luma_mc_12_8,          8);
-mc_func!(m22;  luma_mc_22_16,        16);
-mc_func!(m22;  luma_mc_22_8,          8);
-
-const RV30_CHROMA_FRAC1: [u16; 3] = [ 8, 5, 3 ];
-const RV30_CHROMA_FRAC2: [u16; 3] = [ 0, 3, 5 ];
-fn rv30_chroma_mc(dst: &mut [u8], mut didx: usize, dstride: usize, src: &[u8], mut sidx: usize, sstride: usize, size: usize, x: usize, y: usize) {
-    if (x == 0) && (y == 0) {
-        for _ in 0..size {
-            for x in 0..size { dst[didx + x] = src[sidx + x]; }
-            didx += dstride;
-            sidx += sstride;
-        }
-        return;
-    }
-    let a = RV30_CHROMA_FRAC1[x] * RV30_CHROMA_FRAC1[y];
-    let b = RV30_CHROMA_FRAC2[x] * RV30_CHROMA_FRAC1[y];
-    let c = RV30_CHROMA_FRAC1[x] * RV30_CHROMA_FRAC2[y];
-    let d = RV30_CHROMA_FRAC2[x] * RV30_CHROMA_FRAC2[y];
-    for _ in 0..size {
-        for x in 0..size {
-            dst[didx + x] = ((a * (src[sidx + x] as u16)
-                            + b * (src[sidx + x + 1] as u16)
-                            + c * (src[sidx + x + sstride] as u16)
-                            + d * (src[sidx + x + 1 + sstride] as u16) + 32) >> 6) as u8;
-        }
-        didx += dstride;
-        sidx += sstride;
-    }
-}
-
-pub struct RV30DSP {
-    luma_mc: [[fn (&mut [u8], usize, usize, &[u8], usize, usize); 9]; 2],
-}
-
-impl RV30DSP {
-    pub fn new() -> Self {
-        RV30DSP {
-            luma_mc: [
-                    [ copy_16,       luma_mc_10_16,  luma_mc_20_16,
-                      luma_mc_01_16, luma_mc_11_16,  luma_mc_21_16,
-                      luma_mc_02_16, luma_mc_12_16,  luma_mc_22_16 ],
-                    [ copy_8,        luma_mc_10_8,   luma_mc_20_8,
-                      luma_mc_01_8,  luma_mc_11_8,   luma_mc_21_8,
-                      luma_mc_02_8,  luma_mc_12_8,   luma_mc_22_8  ] ],
-        }
-    }
-}
-
-macro_rules! el {
-    ($src: ident, $o: expr) => ($src[$o] as i16);
-}
-
-fn clip_symm(a: i16, lim: i16) -> i16 {
-    if a < -lim {
-        -lim
-    } else if a > lim {
-        lim
-    } else {
-        a
-    }
-}
-
-const RV30_LOOP_FILTER_STRENGTH: [i16; 32] = [
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
-    2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5
-];
-
-macro_rules! test_bit {
-    ($pat: expr, $x: expr) => ( (($pat >> $x) & 1) != 0 )
-}
-
-fn rv30_loop_filter4(pix: &mut [u8], mut off: usize, step: usize, stride: usize, lim: i16) {
-    for _ in 0..4 {
-        let a = el!(pix, off - 2*step);
-        let b = el!(pix, off -   step);
-        let c = el!(pix, off);
-        let d = el!(pix, off +   step);
-        let diff0 = ((a - d) - (b - c) * 4) >> 3;
-        let diff = clip_symm(diff0, lim);
-        pix[off - step] = clip8(b + diff);
-        pix[off       ] = clip8(c - diff);
-        off += stride;
-    }
-}
-
-fn rv30_div_mv(mv: i16) -> (i16, usize) {
-    let i = mv / 3;
-    let f = mv - i * 3;
-    if f < 0 {
-        (i - 1, (f + 3) as usize)
-    } else {
-        (i, f as usize)
-    }
-}
-
-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 {
-    let xn = (x as isize) + (dx as isize);
-    let yn = (y as isize) + (dy as isize);
-
-    (xn - e0 >= 0) && (xn + (size as isize) + e1 <= (w as isize)) && (yn - e2 >= 0) && (yn + (size as isize) + e3 <= (h as isize))
-}
-
-const RV30_EDGE1: [isize; 3] = [ 0, 1, 1 ];
-const RV30_EDGE2: [isize; 3] = [ 0, 2, 2 ];
-
-impl RV34DSP for RV30DSP {
-    fn loop_filter(&self, frame: &mut NAVideoBuffer<u8>, _ftype: FrameType, mbinfo: &[RV34MBInfo], mb_w: usize, row: usize) {
-        let mut offs:   [usize; 3] = [0; 3];
-        let mut stride: [usize; 3] = [0; 3];
-
-        for comp in 0..3 {
-            stride[comp] = frame.get_stride(comp);
-            let start = if comp == 0 { row * 16 } else { row * 8 };
-            offs[comp] = frame.get_offset(comp) + start * stride[comp];
-        }
-
-        let mut data = frame.get_data_mut();
-        let dst: &mut [u8] = data.as_mut_slice();
-
-        // vertical filter
-        let mut left_cbp = 0;
-        let mut left_lim = 0;
-        let mut left_dbk = 0;
-        let mut mb_pos: usize = row * mb_w;
-        for mb_x in 0..mb_w {
-            let cur_lim = RV30_LOOP_FILTER_STRENGTH[mbinfo[mb_pos].q as usize];
-            let cur_dbk = mbinfo[mb_pos].deblock;
-            let cur_cbp = mbinfo[mb_pos].cbp_c;
-            let xstart = if mb_x == 0 { 1 } else { 0 };
-            for y in 0..4 {
-                let yoff = offs[0] + mb_x * 16 + y * 4 * stride[0];
-                for x in xstart..4 {
-                    let cs = x + y*4;
-                    let loc_lim;
-
-                    if test_bit!(cur_dbk, cs) {
-                        loc_lim = cur_lim;
-                    } else if (x == 0) && test_bit!(left_dbk, cs + 3) {
-                        loc_lim = left_lim;
-                    } else if (x != 0) && test_bit!(cur_dbk,  cs - 1) {
-                        loc_lim = cur_lim;
-                    } else {
-                        loc_lim = 0;
-                    }
-                    if loc_lim != 0 {
-                        rv30_loop_filter4(dst, yoff + x * 4, 1, stride[0], loc_lim);
-                    }
-                }
-            }
-
-            for comp in 1..3 {
-                for y in 0..2 {
-                    let coff = offs[comp] + mb_x * 8 + y * 4 * stride[comp];
-                    for x in xstart..2 {
-                        let cs = x + y * 2 + (comp - 1) * 4;
-                        let loc_lim;
-
-                        if test_bit!(cur_cbp, cs) {
-                            loc_lim = cur_lim;
-                        } else if (x == 0) && test_bit!(left_cbp, cs + 1) {
-                            loc_lim = left_lim;
-                        } else if (x != 0) && test_bit!(cur_cbp,  cs - 1) {
-                            loc_lim = cur_lim;
-                        } else {
-                            loc_lim = 0;
-                        }
-                        if loc_lim != 0 {
-                            rv30_loop_filter4(dst, coff + x * 4, 1, stride[comp], loc_lim);
-                        }
-                    }
-                }
-            }
-
-            left_lim = cur_lim;
-            left_dbk = cur_dbk;
-            left_cbp = cur_cbp;
-            mb_pos += 1;
-        }
-
-        // horizontal filter
-        let mut mb_pos: usize = row * mb_w;
-        for mb_x in 0..mb_w {
-            let cur_lim = RV30_LOOP_FILTER_STRENGTH[mbinfo[mb_pos].q as usize];
-            let cur_dbk = mbinfo[mb_pos].deblock;
-            let cur_cbp = mbinfo[mb_pos].cbp_c;
-            let ystart = if row == 0 { 1 } else { 0 };
-            let top_lim;
-            let top_dbk;
-            let top_cbp;
-            if row > 0 {
-                top_lim = RV30_LOOP_FILTER_STRENGTH[mbinfo[mb_pos - mb_w].q as usize];
-                top_dbk = mbinfo[mb_pos - mb_w].deblock;
-                top_cbp = mbinfo[mb_pos - mb_w].cbp_c;
-            } else {
-                top_lim = 0;
-                top_dbk = 0;
-                top_cbp = 0;
-            }
-            for y in ystart..4 {
-                let yoff = offs[0] + mb_x * 16 + y * 4 * stride[0];
-                for x in 0..4 {
-                    let cs = x + y*4;
-                    let loc_lim;
-
-                    if test_bit!(cur_dbk, cs) {
-                        loc_lim = cur_lim;
-                    } else if (y == 0) && test_bit!(top_dbk, cs + 12) {
-                        loc_lim = top_lim;
-                    } else if (y != 0) && test_bit!(cur_dbk, cs - 4) {
-                        loc_lim = cur_lim;
-                    } else {
-                        loc_lim = 0;
-                    }
-                    if loc_lim != 0 {
-                        rv30_loop_filter4(dst, yoff + x * 4, stride[0], 1, loc_lim);
-                    }
-                }
-            }
-
-            for comp in 1..3 {
-                for y in ystart..2 {
-                    let coff = offs[comp] + mb_x * 8 + y * 4 * stride[comp];
-                    for x in 0..2 {
-                        let cs = x + y * 2 + (comp - 1) * 4;
-                        let loc_lim;
-
-                        if test_bit!(cur_cbp, cs) {
-                            loc_lim = cur_lim;
-                        } else if (y == 0) && test_bit!(top_cbp, cs + 2) {
-                            loc_lim = top_lim;
-                        } else if (y != 0) && test_bit!(cur_cbp, cs - 2) {
-                            loc_lim = cur_lim;
-                        } else {
-                            loc_lim = 0;
-                        }
-                        if loc_lim != 0 {
-                            rv30_loop_filter4(dst, coff + x * 4, stride[comp], 1, loc_lim);
-                        }
-                    }
-                }
-            }
-
-            mb_pos += 1;
-        }
-    }
-    fn do_luma_mc(&self, frame: &mut NAVideoBuffer<u8>, prev_frame: &NAVideoBuffer<u8>, x: usize, y: usize, mv: MV, use16: bool, avg: bool) {
-        let size: usize = if use16 { 16 } else { 8 };
-        let dstride = frame.get_stride(0);
-        let doffset = frame.get_offset(0) + (if !avg { x + y * dstride } else { 0 });
-        let mut data = frame.get_data_mut();
-        let dst: &mut [u8] = data.as_mut_slice();
-
-        let (w_, h_) = prev_frame.get_dimensions(0);
-        let w = (w_ + 15) & !15;
-        let h = (h_ + 15) & !15;
-
-        let (dx, cx) = rv30_div_mv(mv.x);
-        let (dy, cy) = rv30_div_mv(mv.y);
-        let mode = cx + cy * 3;
-
-        if check_pos(x, y, size, w, h, dx, dy, RV30_EDGE1[cx], RV30_EDGE2[cx], RV30_EDGE1[cy], RV30_EDGE2[cy]) {
-            let sstride = prev_frame.get_stride(0);
-            let mut soffset = prev_frame.get_offset(0) + x + y * sstride;
-            let data = prev_frame.get_data();
-            let src: &[u8] = data.as_slice();
-            soffset = ((soffset as isize) + (dx as isize) + (dy as isize) * (sstride as isize)) as usize;
-            self.luma_mc[if use16 { 0 } else { 1 }][mode](dst, doffset, dstride, src, soffset, sstride);
-        } else {
-            let mut ebuf: [u8; 32*20] = [0; 32*20];
-            edge_emu(prev_frame, (x as isize) + (dx as isize) - 1, (y as isize) + (dy as isize) - 1, 16+3, 16+3, &mut ebuf, 32, 0);
-            self.luma_mc[if use16 { 0 } else { 1 }][mode](dst, doffset, dstride, &ebuf, 32 + 1, 32);
-        }
-    }
-    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) {
-        let size: usize = if use8 { 8 } else { 4 };
-        let dstride = frame.get_stride(comp);
-        let doffset = frame.get_offset(comp) + (if !avg { x + y * dstride } else { 0 });
-        let mut data = frame.get_data_mut();
-        let dst: &mut [u8] = data.as_mut_slice();
-
-        let (w_, h_) = prev_frame.get_dimensions(comp);
-        let w = (w_ + 7) & !7;
-        let h = (h_ + 7) & !7;
-
-        let (dx, cx) = rv30_div_mv(mv.x / 2);
-        let (dy, cy) = rv30_div_mv(mv.y / 2);
-
-        if check_pos(x, y, size, w, h, dx, dy, 0, 1, 0, 1) {
-            let sstride = prev_frame.get_stride(comp);
-            let mut soffset = prev_frame.get_offset(comp) + x + y * sstride;
-            let data = prev_frame.get_data();
-            let src: &[u8] = data.as_slice();
-            soffset = ((soffset as isize) + (dx as isize) + (dy as isize) * (sstride as isize)) as usize;
-            rv30_chroma_mc(dst, doffset, dstride, src, soffset, sstride, size, cx, cy);
-        } else {
-            let mut ebuf: [u8; 16*10] = [0; 16*10];
-            edge_emu(prev_frame, (x as isize) + (dx as isize), (y as isize) + (dy as isize), 8+1, 8+1, &mut ebuf, 16, comp);
-            rv30_chroma_mc(dst, doffset, dstride, &ebuf, 0, 16, size, cx, cy);
-        }
-    }
-}