X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-codec-support%2Fsrc%2Fcodecs%2Fblockdsp.rs;h=9f70582c17a09fbf4db08353e4a70f7bc46b9262;hb=0faa067bfda9b9460a1c7275859089f5b01e0a67;hp=da92742cec741a09514379aa029ea6eb4b5bf163;hpb=b4d5b8515e75383b4fc59ea2813c90c615d59a96;p=nihav.git diff --git a/nihav-codec-support/src/codecs/blockdsp.rs b/nihav-codec-support/src/codecs/blockdsp.rs index da92742..9f70582 100644 --- a/nihav-codec-support/src/codecs/blockdsp.rs +++ b/nihav-codec-support/src/codecs/blockdsp.rs @@ -112,13 +112,22 @@ pub fn add_blocks(buf: &mut NAVideoBuffer, xpos: usize, ypos: usize, blk: &[ } /// Copies block from the picture with pixels beyond the picture borders being replaced with replicated edge pixels. -pub fn edge_emu(src: &NAVideoBuffer, xpos: isize, ypos: isize, bw: usize, bh: usize, dst: &mut [u8], dstride: usize, comp: usize) { +pub fn edge_emu(src: &NAVideoBuffer, xpos: isize, ypos: isize, bw: usize, bh: usize, dst: &mut [u8], dstride: usize, comp: usize, align: u8) { let stride = src.get_stride(comp); let offs = src.get_offset(comp); - let (w, h) = src.get_dimensions(comp); + let (w_, h_) = src.get_dimensions(comp); + let (hss, vss) = src.get_info().get_format().get_chromaton(comp).unwrap().get_subsampling(); let data = src.get_data(); let framebuf: &[u8] = data.as_slice(); + let (w, h) = if align == 0 { + (w_, h_) + } else { + let wa = if align > hss { (1 << (align - hss)) - 1 } else { 0 }; + let ha = if align > vss { (1 << (align - vss)) - 1 } else { 0 }; + ((w_ + wa) & !wa, (h_ + ha) & !ha) + }; + for y in 0..bh { let srcy; if (y as isize) + ypos < 0 { srcy = 0; } @@ -182,7 +191,7 @@ pub fn copy_blocks(dst: &mut NAVideoBuffer, src: &NAVideoBuffer, let bw_ = (if comp > 0 { bw/2 } else { bw }) + ((pre + post) as usize); let bh_ = (if comp > 0 { bh/2 } else { bh }) + ((pre + post) as usize); edge_emu(src, sx_ - pre, sy_ - pre, bw_, bh_, - ebuf.as_mut_slice(), ebuf_stride, comp); + ebuf.as_mut_slice(), ebuf_stride, comp, 0); let bw_ = if comp > 0 { bw/2 } else { bw }; let bh_ = if comp > 0 { bh/2 } else { bh }; (interp[mode])(&mut dbuf[doff + x + y * dstride..], dstride, ebuf.as_slice(), ebuf_stride, bw_, bh_); @@ -233,7 +242,7 @@ pub fn copy_block(dst: &mut NASimpleVideoFrame, src: NAVideoBufferRef, c let doff = dst.offset[comp]; let edge = (pre + post) as usize; edge_emu(&src, sx - pre, sy - pre, bw + edge, bh + edge, - ebuf.as_mut_slice(), ebuf_stride, comp); + ebuf.as_mut_slice(), ebuf_stride, comp, 0); (interp[mode])(&mut dst.data[doff + dx + dy * dstride..], dstride, ebuf.as_slice(), ebuf_stride, bw, bh); } else { @@ -248,3 +257,57 @@ pub fn copy_block(dst: &mut NASimpleVideoFrame, src: NAVideoBufferRef, c &sbuf[saddr..], sstride, bw, bh); } } + +fn hpel_interp00(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize) +{ + let mut didx = 0; + let mut sidx = 0; + for _ in 0..bh { + dst[didx..][..bw].copy_from_slice(&src[sidx..][..bw]); + didx += dstride; + sidx += sstride; + } +} + +fn hpel_interp01(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize) +{ + let mut didx = 0; + let mut sidx = 0; + for _ in 0..bh { + for x in 0..bw { dst[didx + x] = ((u16::from(src[sidx + x]) + u16::from(src[sidx + x + 1]) + 1) >> 1) as u8; } + didx += dstride; + sidx += sstride; + } +} + +fn hpel_interp10(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize) +{ + let mut didx = 0; + let mut sidx = 0; + for _ in 0..bh { + for x in 0..bw { dst[didx + x] = ((u16::from(src[sidx + x]) + u16::from(src[sidx + x + sstride]) + 1) >> 1) as u8; } + didx += dstride; + sidx += sstride; + } +} + +fn hpel_interp11(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize) +{ + let mut didx = 0; + let mut sidx = 0; + for _ in 0..bh { + for x in 0..bw { + dst[didx + x] = ((u16::from(src[sidx + x]) + + u16::from(src[sidx + x + 1]) + + u16::from(src[sidx + x + sstride]) + + u16::from(src[sidx + x + sstride + 1]) + 2) >> 2) as u8; + } + didx += dstride; + sidx += sstride; + } +} + +/// Half-pixel interpolation functions. +pub const HALFPEL_INTERP_FUNCS: &[BlkInterpFunc] = &[ + hpel_interp00, hpel_interp01, hpel_interp10, hpel_interp11 ]; +