X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-itu%2Fsrc%2Fcodecs%2Fh264%2Fdsp%2Fmc%2Fmod.rs;fp=nihav-itu%2Fsrc%2Fcodecs%2Fh264%2Fdsp%2Fmc%2Fmod.rs;h=5845d921fb0b27943f539be65aff5ef4d70f4235;hp=f55844194ad6972aabacfaad2c14e5c040b0b0a2;hb=5f223cdb5a7834fe58bf05d4dd0da36325f4f11c;hpb=754ab49a62c862e8c6e66ec88bb7ad626247140e diff --git a/nihav-itu/src/codecs/h264/dsp/mc/mod.rs b/nihav-itu/src/codecs/h264/dsp/mc/mod.rs index f558441..5845d92 100644 --- a/nihav-itu/src/codecs/h264/dsp/mc/mod.rs +++ b/nihav-itu/src/codecs/h264/dsp/mc/mod.rs @@ -1,6 +1,6 @@ use nihav_core::frame::*; use nihav_codec_support::codecs::MV; -use nihav_codec_support::codecs::blockdsp::*; +use super::super::SimpleFrame; macro_rules! module_selector { ($( ($cond:meta, $module:ident) ),*) => { @@ -81,7 +81,7 @@ impl H264MC { self.width = width; self.height = height; } - pub fn do_mc(&mut self, frm: &mut NASimpleVideoFrame, refpic: NAVideoBufferRef, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV) { + pub fn do_mc(&mut self, frm: &mut NASimpleVideoFrame, refpic: &SimpleFrame, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV) { let mut ebuf = [0u8; 22 * 22]; let mvx = mv.x >> 2; let mvy = mv.y >> 2; @@ -89,16 +89,16 @@ impl H264MC { let pre = if mode != 0 { 2isize } else { 0 }; let post = if mode != 0 { 3isize } else { 0 }; let (yw, yh) = (self.width, self.height); - let src = refpic.get_data(); - let systride = refpic.get_stride(0); + let src = refpic.data; + let systride = refpic.stride[0]; let src_x = (xpos as isize) + (mvx as isize); let src_y = (ypos as isize) + (mvy as isize); let (ysrc, ystride) = if (src_x - pre < 0) || (src_x + (w as isize) + post > (yw as isize)) || (src_y - pre < 0) || (src_y + (h as isize) + post > (yh as isize)) { let add = (pre + post) as usize; - edge_emu(&refpic, src_x - pre, src_y - pre, w + add, h + add, &mut ebuf, 22, 0, 0); + edge_emu_sf(refpic, src_x - pre, src_y - pre, yw, yh, w + add, h + add, &mut ebuf, 22, 0); (&ebuf[..], 22) } else { - (&src[refpic.get_offset(0) + ((src_x - pre) as usize) + ((src_y - pre) as usize) * systride..], systride) + (&src[refpic.offset[0] + ((src_x - pre) as usize) + ((src_y - pre) as usize) * systride..], systride) }; let wmode = match w { 4 => 0, @@ -114,15 +114,17 @@ impl H264MC { let dy = (mv.y & 7) as u16; let src_x = ((xpos >> 1) as isize) + (mvx as isize); let src_y = ((ypos >> 1) as isize) + (mvy as isize); - let suoff = refpic.get_offset(1); - let svoff = refpic.get_offset(2); - let sustride = refpic.get_stride(1); - let svstride = refpic.get_stride(2); + let suoff = refpic.offset[1]; + let svoff = refpic.offset[2]; + let sustride = refpic.stride[1]; + let svstride = refpic.stride[2]; let cbw = w / 2; let cbh = h / 2; let (csrc, cstride) = if (src_x < 0) || (src_x + (cbw as isize) + 1 > (cw as isize)) || (src_y < 0) || (src_y + (cbh as isize) + 1 > (ch as isize)) { - edge_emu(&refpic, src_x, src_y, cbw+1, cbh+1, &mut ebuf, 18, 1, 4); - edge_emu(&refpic, src_x, src_y, cbw+1, cbh+1, &mut ebuf[9..], 18, 2, 4); + let aw = (cw + 7) & !7; + let ah = (ch + 7) & !7; + edge_emu_sf(refpic, src_x, src_y, aw, ah, cbw+1, cbh+1, &mut ebuf, 18, 1); + edge_emu_sf(refpic, src_x, src_y, aw, ah, cbw+1, cbh+1, &mut ebuf[9..], 18, 2); ([&ebuf, &ebuf[9..]], [18, 18]) } else { ([&src[suoff + (src_x as usize) + (src_y as usize) * sustride..], @@ -135,7 +137,7 @@ impl H264MC { } } - pub fn mc_blocks(&mut self, dst: &mut McBlock, refpic: NAVideoBufferRef, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV) { + pub fn mc_blocks(&mut self, dst: &mut McBlock, refpic: &SimpleFrame, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV) { let mode = ((mv.x & 3) + (mv.y & 3) * 4) as usize; let pre = if mode != 0 { 2 } else { 0 }; @@ -155,14 +157,13 @@ impl H264MC { if (sx - pre < 0) || (sx + (w as isize) + post > (width as isize)) || (sy - pre < 0) || (sy + (h as isize) + post > (height as isize)) { let edge = (pre + post) as usize; - edge_emu(&refpic, sx - pre, sy - pre, w + edge, h + edge, - &mut ebuf, EBUF_STRIDE, 0, 0); + edge_emu_sf(refpic, sx - pre, sy - pre, width, height, w + edge, h + edge, + &mut ebuf, EBUF_STRIDE, 0); (H264_LUMA_INTERP[wmode][mode])(&mut dst.y, 16, &ebuf, EBUF_STRIDE, h); } else { - let sstride = refpic.get_stride(0); - let soff = refpic.get_offset(0); - let sdta = refpic.get_data(); - let sbuf: &[u8] = sdta.as_slice(); + let sstride = refpic.stride[0]; + let soff = refpic.offset[0]; + let sbuf = refpic.data; let saddr = soff + ((sx - pre) as usize) + ((sy - pre) as usize) * sstride; (H264_LUMA_INTERP[wmode][mode])(&mut dst.y, 16, &sbuf[saddr..], sstride, h); } @@ -174,16 +175,18 @@ impl H264MC { let dy = (mv.y & 7) as u16; let src_x = ((xpos >> 1) as isize) + (mvx as isize); let src_y = ((ypos >> 1) as isize) + (mvy as isize); - let suoff = refpic.get_offset(1); - let svoff = refpic.get_offset(2); - let sustride = refpic.get_stride(1); - let svstride = refpic.get_stride(2); - let src = refpic.get_data(); + let suoff = refpic.offset[1]; + let svoff = refpic.offset[2]; + let sustride = refpic.stride[1]; + let svstride = refpic.stride[2]; + let src = refpic.data; let cbw = w / 2; let cbh = h / 2; let (csrc, cstride) = if (src_x < 0) || (src_x + (cbw as isize) + 1 > (cw as isize)) || (src_y < 0) || (src_y + (cbh as isize) + 1 > (ch as isize)) { - edge_emu(&refpic, src_x, src_y, cbw+1, cbh+1, &mut ebuf, 18, 1, 4); - edge_emu(&refpic, src_x, src_y, cbw+1, cbh+1, &mut ebuf[9..], 18, 2, 4); + let aw = (cw + 7) & !7; + let ah = (ch + 7) & !7; + edge_emu_sf(refpic, src_x, src_y, aw, ah, cbw+1, cbh+1, &mut ebuf, 18, 1); + edge_emu_sf(refpic, src_x, src_y, aw, ah, cbw+1, cbh+1, &mut ebuf[9..], 18, 2); ([&ebuf, &ebuf[9..]], [18, 18]) } else { ([&src[suoff + (src_x as usize) + (src_y as usize) * sustride..], @@ -194,7 +197,7 @@ impl H264MC { (self.chroma_interp[wmode])(&mut dst.v, 16, csrc[1], cstride[1], dx, dy, cbh); } - pub fn do_mc_avg(&mut self, frm: &mut NASimpleVideoFrame, refpic: NAVideoBufferRef, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV) { + pub fn do_mc_avg(&mut self, frm: &mut NASimpleVideoFrame, refpic: &SimpleFrame, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV) { let mut abuf = self.avg_buf.clone(); let mut afrm = NASimpleVideoFrame::from_video_buf(&mut abuf).unwrap(); let amv = MV { x: mv.x + (xpos as i16) * 4, y: mv.y + (ypos as i16) * 4 }; @@ -233,6 +236,27 @@ impl H264MC { } } +fn edge_emu_sf(src: &SimpleFrame, xpos: isize, ypos: isize, w: usize, h: usize, bw: usize, bh: usize, dst: &mut [u8], dstride: usize, comp: usize) { + let stride = src.stride[comp]; + let offs = src.offset[comp]; + let framebuf = src.data; + + for y in 0..bh { + let srcy; + if (y as isize) + ypos < 0 { srcy = 0; } + else if (y as isize) + ypos >= (h as isize) { srcy = h - 1; } + else { srcy = ((y as isize) + ypos) as usize; } + + for x in 0..bw { + let srcx; + if (x as isize) + xpos < 0 { srcx = 0; } + else if (x as isize) + xpos >= (w as isize) { srcx = w - 1; } + else { srcx = ((x as isize) + xpos) as usize; } + dst[x + y * dstride] = framebuf[offs + srcx + srcy * stride]; + } + } +} + fn avg(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize) { for (dline, sline) in dst.chunks_mut(dstride).zip(src.chunks(sstride)).take(bh) { for (dst, src) in dline.iter_mut().zip(sline.iter()).take(bw) {