From 86081fed61d59fb1ea35ac34628450c9b0c00702 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Tue, 24 Mar 2020 11:00:29 +0100 Subject: [PATCH] make edge_emu() accept block alignment --- nihav-codec-support/src/codecs/blockdsp.rs | 17 +++++++++++++---- nihav-duck/src/codecs/vp6.rs | 2 +- nihav-duck/src/codecs/vp7dsp.rs | 4 ++-- nihav-duck/src/codecs/vpcommon.rs | 2 +- nihav-realmedia/src/codecs/rv30dsp.rs | 4 ++-- nihav-realmedia/src/codecs/rv40dsp.rs | 4 ++-- nihav-realmedia/src/codecs/rv60dsp.rs | 4 ++-- 7 files changed, 23 insertions(+), 14 deletions(-) diff --git a/nihav-codec-support/src/codecs/blockdsp.rs b/nihav-codec-support/src/codecs/blockdsp.rs index da92742..94dcfc0 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 { diff --git a/nihav-duck/src/codecs/vp6.rs b/nihav-duck/src/codecs/vp6.rs index dfed31f..241a13a 100644 --- a/nihav-duck/src/codecs/vp6.rs +++ b/nihav-duck/src/codecs/vp6.rs @@ -557,7 +557,7 @@ fn get_block(dst: &mut [u8], dstride: usize, src: NAVideoBufferRef, comp: us if (sx - 2 < 0) || (sx + 8 + 2 > (w as isize)) || (sy - 2 < 0) || (sy + 8 + 2 > (h as isize)) { edge_emu(&src, sx - 2, sy - 2, 8 + 2 + 2, 8 + 2 + 2, - dst, dstride, comp); + dst, dstride, comp, 0); } else { let sstride = src.get_stride(comp); let soff = src.get_offset(comp); diff --git a/nihav-duck/src/codecs/vp7dsp.rs b/nihav-duck/src/codecs/vp7dsp.rs index 6dfc98f..bf21d62 100644 --- a/nihav-duck/src/codecs/vp7dsp.rs +++ b/nihav-duck/src/codecs/vp7dsp.rs @@ -582,7 +582,7 @@ fn mc_block(dst: &mut [u8], doff: usize, dstride: usize, xpos: usize, ypos: usiz let ref_y = (ypos as isize) + ((mvy >> 3) as isize) - (EDGE_PRE as isize); let (src, sstride) = if (ref_x < 0) || (ref_x + bsize > wa) || (ref_y < 0) || (ref_y + bsize > ha) { - edge_emu(&reffrm, ref_x, ref_y, bsize as usize, bsize as usize, mc_buf, 32, plane); + edge_emu(&reffrm, ref_x, ref_y, bsize as usize, bsize as usize, mc_buf, 32, plane, 0); (mc_buf as &[u8], 32) } else { let off = reffrm.get_offset(plane); @@ -647,7 +647,7 @@ pub fn mc_block_special(dst: &mut [u8], doff: usize, dstride: usize, xpos: usize let bw = size + EDGE_PRE + EDGE_POST + add; let bh = (end_y - start_y) as usize; let bo = if xstep >= 0 { 0 } else { add }; - edge_emu(&reffrm, start_x + (bo as isize), start_y, bw, bh, mc_buf, 128, plane); + edge_emu(&reffrm, start_x + (bo as isize), start_y, bw, bh, mc_buf, 128, plane, 0); (&mc_buf[bo..], (128 + xstep) as usize) }; let mx = (mvx & 7) as usize; diff --git a/nihav-duck/src/codecs/vpcommon.rs b/nihav-duck/src/codecs/vpcommon.rs index f41b89b..e6446af 100644 --- a/nihav-duck/src/codecs/vpcommon.rs +++ b/nihav-duck/src/codecs/vpcommon.rs @@ -396,7 +396,7 @@ pub fn vp_copy_block(dst: &mut NASimpleVideoFrame, src: NAVideoBufferRef let src_y = sy - (pre as isize); { let tmp_buf = NASimpleVideoFrame::from_video_buf(&mut mc_buf).unwrap(); - edge_emu(src.as_ref(), src_x, src_y, bsize, bsize, &mut tmp_buf.data[tmp_buf.offset[comp]..], tmp_buf.stride[comp], comp); + edge_emu(src.as_ref(), src_x, src_y, bsize, bsize, &mut tmp_buf.data[tmp_buf.offset[comp]..], tmp_buf.stride[comp], comp, 0); // copy_block(&mut tmp_buf, src, comp, 0, 0, src_x as i16, src_y as i16, // bsize, bsize, 0, 0, 0, interp); if (sx & 7) != 0 { diff --git a/nihav-realmedia/src/codecs/rv30dsp.rs b/nihav-realmedia/src/codecs/rv30dsp.rs index fbe0360..6065f7e 100644 --- a/nihav-realmedia/src/codecs/rv30dsp.rs +++ b/nihav-realmedia/src/codecs/rv30dsp.rs @@ -401,7 +401,7 @@ impl RV34DSP for RV30DSP { 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); + 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, 4); self.luma_mc[if use16 { 0 } else { 1 }][mode](dst, doffset, dstride, &ebuf, 32 + 1, 32); } } @@ -428,7 +428,7 @@ impl RV34DSP for RV30DSP { 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); + edge_emu(prev_frame, (x as isize) + (dx as isize), (y as isize) + (dy as isize), 8+1, 8+1, &mut ebuf, 16, comp, 4); rv30_chroma_mc(dst, doffset, dstride, &ebuf, 0, 16, size, cx, cy); } } diff --git a/nihav-realmedia/src/codecs/rv40dsp.rs b/nihav-realmedia/src/codecs/rv40dsp.rs index 9d7e443..8e08077 100644 --- a/nihav-realmedia/src/codecs/rv40dsp.rs +++ b/nihav-realmedia/src/codecs/rv40dsp.rs @@ -849,7 +849,7 @@ impl RV34DSP for RV40DSP { self.luma_mc[if use16 { 0 } else { 1 }][mode](dst, doffset, dstride, src, soffset, sstride); } else { let mut ebuf: [u8; 32*22] = [0; 32*22]; - 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); + 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, 4); self.luma_mc[if use16 { 0 } else { 1 }][mode](dst, doffset, dstride, &ebuf, 32*2 + 2, 32); } } @@ -885,7 +885,7 @@ impl RV34DSP for RV40DSP { rv40_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); + edge_emu(prev_frame, (x as isize) + (dx as isize), (y as isize) + (dy as isize), 8+1, 8+1, &mut ebuf, 16, comp, 4); rv40_chroma_mc(dst, doffset, dstride, &ebuf, 0, 16, size, cx, cy); } } diff --git a/nihav-realmedia/src/codecs/rv60dsp.rs b/nihav-realmedia/src/codecs/rv60dsp.rs index c62e212..e037366 100644 --- a/nihav-realmedia/src/codecs/rv60dsp.rs +++ b/nihav-realmedia/src/codecs/rv60dsp.rs @@ -491,7 +491,7 @@ impl RV60DSP { luma_mc(dst, doffset, dstride, src, soffset, sstride, w, h, cx, cy); } else { let mut ebuf: [u8; 70*70] = [0; 70*70]; - edge_emu(prev_frame, (x as isize) + (dx as isize) - 2, (y as isize) + (dy as isize) - 2, w+5, h+5, &mut ebuf, 70, 0); + edge_emu(prev_frame, (x as isize) + (dx as isize) - 2, (y as isize) + (dy as isize) - 2, w+5, h+5, &mut ebuf, 70, 0, 0); luma_mc(dst, doffset, dstride, &ebuf, 70*2 + 2, 70, w, h, cx, cy); } } @@ -519,7 +519,7 @@ impl RV60DSP { chroma_mc(frame.data, doffset, dstride, src, soffset, sstride, cw, ch, cx, cy); } else { let mut ebuf: [u8; 40*40] = [0; 40*40]; - edge_emu(prev_frame, ((x >> 1) as isize) + (dx as isize), ((y >> 1) as isize) + (dy as isize), cw+1, ch+1, &mut ebuf, 40, comp); + edge_emu(prev_frame, ((x >> 1) as isize) + (dx as isize), ((y >> 1) as isize) + (dy as isize), cw+1, ch+1, &mut ebuf, 40, comp, 0); chroma_mc(frame.data, doffset, dstride, &ebuf, 0, 40, cw, ch, cx, cy); } } -- 2.39.5