X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-duck%2Fsrc%2Fcodecs%2Fvpcommon.rs;h=05b07d19eadda854fef417aa8a4c267c387cfcac;hb=8e4b2f445d2c3e530e5fa517e19f9639142479cf;hp=cac264b8c51301060a45e860085799f26a19ceed;hpb=5b24175d582e438c4b8ccb685e2eb5913178fc3e;p=nihav.git diff --git a/nihav-duck/src/codecs/vpcommon.rs b/nihav-duck/src/codecs/vpcommon.rs index cac264b..05b07d1 100644 --- a/nihav-duck/src/codecs/vpcommon.rs +++ b/nihav-duck/src/codecs/vpcommon.rs @@ -1,4 +1,5 @@ use nihav_core::codecs::*; +use nihav_core::codecs::blockdsp::*; #[derive(Clone,Copy,Debug,PartialEq)] #[allow(dead_code)] @@ -186,3 +187,65 @@ pub fn vp_add_block_dc(coeffs: &mut [i16; 64], bx: usize, by: usize, plane: usiz off += frm.stride[plane]; } } + +pub fn vp31_loop_filter(data: &mut [u8], mut off: usize, step: usize, stride: usize, + len: usize, loop_str: i16) { + for _ in 0..len { + let a = data[off - step * 2] as i16; + let b = data[off - step] as i16; + let c = data[off] as i16; + let d = data[off + step] as i16; + let mut diff = ((a - d) + 3 * (c - b) + 4) >> 3; + if diff.abs() >= 2 * loop_str { + diff = 0; + } else if diff.abs() >= loop_str { + if diff < 0 { + diff = -diff - 2 * loop_str; + } else { + diff = -diff + 2 * loop_str; + } + } + if diff != 0 { + data[off - step] = (b + diff).max(0).min(255) as u8; + data[off] = (c - diff).max(0).min(255) as u8; + } + + off += stride; + } +} + +pub fn vp_copy_block(dst: &mut NASimpleVideoFrame, src: NAVideoBufferRef, comp: usize, + dx: usize, dy: usize, mv_x: i16, mv_y: i16, + preborder: usize, postborder: usize, loop_str: i16, + mode: usize, interp: &[BlkInterpFunc], mut mc_buf: NAVideoBufferRef) +{ + let sx = (dx as isize) + (mv_x as isize); + let sy = (dy as isize) + (mv_y as isize); + if ((sx | sy) & 7) == 0 { + copy_block(dst, src, comp, dx, dy, mv_x, mv_y, 8, 8, preborder, postborder, mode, interp); + return; + } + let pre = preborder.max(2); + let post = postborder.max(1); + let bsize = 8 + pre + post; + let src_x = sx - (pre as isize); + let src_y = sy - (pre as isize); + { + let mut tmp_buf = NASimpleVideoFrame::from_video_buf(&mut mc_buf).unwrap(); + copy_block(&mut tmp_buf, src, comp, 0, 0, src_x as i16, src_y as i16, + bsize, bsize, 0, 0, 0, interp); + if (sy & 7) != 0 { + let foff = (8 - (sy & 7)) as usize; + let off = (pre + foff) * tmp_buf.stride[comp]; + vp31_loop_filter(tmp_buf.data, off, tmp_buf.stride[comp], 1, bsize, loop_str); + } + if (sx & 7) != 0 { + let foff = (8 - (sx & 7)) as usize; + let off = pre + foff; + vp31_loop_filter(tmp_buf.data, off, 1, tmp_buf.stride[comp], bsize, loop_str); + } + } + let dxoff = (pre as i16) - (dx as i16); + let dyoff = (pre as i16) - (dy as i16); + copy_block(dst, mc_buf, comp, dx, dy, dxoff, dyoff, 8, 8, preborder, postborder, 0/* mode*/, interp); +}