make edge_emu() accept block alignment
authorKostya Shishkov <kostya.shishkov@gmail.com>
Tue, 24 Mar 2020 10:00:29 +0000 (11:00 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Tue, 24 Mar 2020 10:00:29 +0000 (11:00 +0100)
nihav-codec-support/src/codecs/blockdsp.rs
nihav-duck/src/codecs/vp6.rs
nihav-duck/src/codecs/vp7dsp.rs
nihav-duck/src/codecs/vpcommon.rs
nihav-realmedia/src/codecs/rv30dsp.rs
nihav-realmedia/src/codecs/rv40dsp.rs
nihav-realmedia/src/codecs/rv60dsp.rs

index da92742cec741a09514379aa029ea6eb4b5bf163..94dcfc026424fa29df2a628fac907f51abc9fa6c 100644 (file)
@@ -112,13 +112,22 @@ pub fn add_blocks(buf: &mut NAVideoBuffer<u8>, 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<u8>, xpos: isize, ypos: isize, bw: usize, bh: usize, dst: &mut [u8], dstride: usize, comp: usize) {
+pub fn edge_emu(src: &NAVideoBuffer<u8>, 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<u8>, src: &NAVideoBuffer<u8>,
             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<u8>, src: NAVideoBufferRef<u8>, 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 {
index dfed31f364a95b4a6c03cf61927dda09b8071e50..241a13a72ef947b3e76874de7bdb647f92026ad3 100644 (file)
@@ -557,7 +557,7 @@ fn get_block(dst: &mut [u8], dstride: usize, src: NAVideoBufferRef<u8>, 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);
index 6dfc98fb36ec3607c784950cea24d79c11d13ca0..bf21d62e9957bd806facf27d5501214deb7eef5b 100644 (file)
@@ -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;
index f41b89b1b5ebaefefe7f9c5b39c71eb93aed40a0..e6446afc436830029323a1c05a1d4c000a0b4f98 100644 (file)
@@ -396,7 +396,7 @@ pub fn vp_copy_block(dst: &mut NASimpleVideoFrame<u8>, src: NAVideoBufferRef<u8>
     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 {
index fbe03607c679aef54e9c95d526caadaa1f84fd9f..6065f7ee7d19d04798059ab64fe4ff38b2380d32 100644 (file)
@@ -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);
         }
     }
index 9d7e44354c1953f1722053932ac2f76e86c5b81c..8e080772fb7b19949251d5d7856ec21230095a66 100644 (file)
@@ -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);
         }
     }
index c62e212cecf163533f135cae3c40c24cb7ea2e3e..e03736603d7e633f2ffbce6331bf6c6f99bf1ba8 100644 (file)
@@ -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);
             }
         }