Unverified Commit 982d16c3 authored by fbossen's avatar fbossen Committed by GitHub

Use padded frames (#537)

* Modify plane data structure to allow for padded border

* Pad reconstructed frame

* Have ME consider motion vectors pointing outside frame boundary

* Remove clamping inside motion compensation loop

Clamping is now done outside the loop and relies on the frame
being padded.

* Reduce size of intermediate buffer in motion compensation

* Update encode/decode tests
parent d1ebacea
......@@ -154,7 +154,7 @@ pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants,
fs.rec.planes[1].cfg.stride,
fs.rec.planes[2].cfg.stride);
for (line, line_out) in fs.rec.planes[0].data.chunks(stride_y).zip(rec_y.chunks_mut(pitch_y)) {
for (line, line_out) in fs.rec.planes[0].data_origin().chunks(stride_y).zip(rec_y.chunks_mut(pitch_y)) {
if sequence.bit_depth > 8 {
unsafe {
line_out.copy_from_slice(
......@@ -165,7 +165,7 @@ pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants,
&line.iter().map(|&v| v as u8).collect::<Vec<u8>>()[..pitch_y]);
}
}
for (line, line_out) in fs.rec.planes[1].data.chunks(stride_u).zip(rec_u.chunks_mut(pitch_uv)) {
for (line, line_out) in fs.rec.planes[1].data_origin().chunks(stride_u).zip(rec_u.chunks_mut(pitch_uv)) {
if sequence.bit_depth > 8 {
unsafe {
line_out.copy_from_slice(
......@@ -176,7 +176,7 @@ pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants,
&line.iter().map(|&v| v as u8).collect::<Vec<u8>>()[..pitch_uv]);
}
}
for (line, line_out) in fs.rec.planes[2].data.chunks(stride_v).zip(rec_v.chunks_mut(pitch_uv)) {
for (line, line_out) in fs.rec.planes[2].data_origin().chunks(stride_v).zip(rec_v.chunks_mut(pitch_uv)) {
if sequence.bit_depth > 8 {
unsafe {
line_out.copy_from_slice(
......@@ -192,6 +192,7 @@ pub fn process_frame(sequence: &mut Sequence, fi: &mut FrameInvariants,
y4m_enc.write_frame(&rec_frame).unwrap();
}
fs.rec.pad();
update_rec_buffer(fi, fs);
true
},
......
......@@ -339,9 +339,9 @@ pub fn cdef_filter_frame(fi: &FrameInvariants, rec: &mut Frame, bc: &mut BlockCo
}
let mut cdef_frame = Frame {
planes: [
Plane::new(padded_px[0][0], padded_px[0][1], rec.planes[0].cfg.xdec, rec.planes[0].cfg.ydec),
Plane::new(padded_px[1][0], padded_px[1][1], rec.planes[1].cfg.xdec, rec.planes[1].cfg.ydec),
Plane::new(padded_px[2][0], padded_px[2][1], rec.planes[2].cfg.xdec, rec.planes[2].cfg.ydec)
Plane::new(padded_px[0][0], padded_px[0][1], rec.planes[0].cfg.xdec, rec.planes[0].cfg.ydec, 0, 0),
Plane::new(padded_px[1][0], padded_px[1][1], rec.planes[1].cfg.xdec, rec.planes[1].cfg.ydec, 0, 0),
Plane::new(padded_px[2][0], padded_px[2][1], rec.planes[2].cfg.xdec, rec.planes[2].cfg.ydec, 0, 0)
]
};
for p in 0..3 {
......@@ -350,14 +350,14 @@ pub fn cdef_filter_frame(fi: &FrameInvariants, rec: &mut Frame, bc: &mut BlockCo
for row in 0..padded_px[p][1] {
// pad first two elements of current row
{
let mut cdef_slice = cdef_frame.planes[p].mut_slice(&PlaneOffset { x: 0, y: row});
let mut cdef_slice = cdef_frame.planes[p].mut_slice(&PlaneOffset { x: 0, y: row as isize });
let mut cdef_row = &mut cdef_slice.as_mut_slice()[..2];
cdef_row[0] = CDEF_VERY_LARGE;
cdef_row[1] = CDEF_VERY_LARGE;
}
// pad out end of current row
{
let mut cdef_slice = cdef_frame.planes[p].mut_slice(&PlaneOffset { x: rec_w+2, y: row });
let mut cdef_slice = cdef_frame.planes[p].mut_slice(&PlaneOffset { x: rec_w as isize + 2, y: row as isize });
let mut cdef_row = &mut cdef_slice.as_mut_slice()[..padded_px[p][0]-rec_w-2];
for x in cdef_row {
*x = CDEF_VERY_LARGE;
......@@ -365,7 +365,7 @@ pub fn cdef_filter_frame(fi: &FrameInvariants, rec: &mut Frame, bc: &mut BlockCo
}
// copy current row from rec if we're in data, or pad if we're in first two rows/last N rows
{
let mut cdef_slice = cdef_frame.planes[p].mut_slice(&PlaneOffset { x: 2, y: row });
let mut cdef_slice = cdef_frame.planes[p].mut_slice(&PlaneOffset { x: 2, y: row as isize });
let mut cdef_row = &mut cdef_slice.as_mut_slice()[..rec_w];
if row < 2 || row >= rec_h+2 {
for x in cdef_row {
......@@ -373,7 +373,7 @@ pub fn cdef_filter_frame(fi: &FrameInvariants, rec: &mut Frame, bc: &mut BlockCo
}
} else {
let rec_stride = rec.planes[p].cfg.stride;
cdef_row.copy_from_slice(&rec.planes[p].data[(row-2)*rec_stride..(row-1)*rec_stride][..rec_w]);
cdef_row.copy_from_slice(&rec.planes[p].data_origin()[(row-2)*rec_stride..(row-1)*rec_stride][..rec_w]);
}
}
}
......
......@@ -1253,8 +1253,8 @@ impl SuperBlockOffset {
/// Offset of the top-left pixel of this block.
pub fn plane_offset(&self, plane: &PlaneConfig) -> PlaneOffset {
PlaneOffset {
x: self.x << (SUPERBLOCK_TO_PLANE_SHIFT - plane.xdec),
y: self.y << (SUPERBLOCK_TO_PLANE_SHIFT - plane.ydec)
x: (self.x as isize) << (SUPERBLOCK_TO_PLANE_SHIFT - plane.xdec),
y: (self.y as isize) << (SUPERBLOCK_TO_PLANE_SHIFT - plane.ydec)
}
}
}
......@@ -1284,8 +1284,8 @@ impl BlockOffset {
let y_offset = self.y & LOCAL_BLOCK_MASK;
PlaneOffset {
x: po.x + (x_offset >> plane.xdec << BLOCK_TO_PLANE_SHIFT),
y: po.y + (y_offset >> plane.ydec << BLOCK_TO_PLANE_SHIFT)
x: po.x + (x_offset as isize >> plane.xdec << BLOCK_TO_PLANE_SHIFT),
y: po.y + (y_offset as isize >> plane.ydec << BLOCK_TO_PLANE_SHIFT)
}
}
......
......@@ -30,12 +30,18 @@ impl Frame {
pub fn new(width: usize, height:usize) -> Frame {
Frame {
planes: [
Plane::new(width, height, 0, 0),
Plane::new(width/2, height/2, 1, 1),
Plane::new(width/2, height/2, 1, 1)
Plane::new(width, height, 0, 0, 128+8, 128+8),
Plane::new(width/2, height/2, 1, 1, 64+8, 64+8),
Plane::new(width/2, height/2, 1, 1, 64+8, 64+8)
]
}
}
pub fn pad(&mut self) {
for p in self.planes.iter_mut() {
p.pad();
}
}
}
#[derive(Debug, Clone)]
......@@ -1507,8 +1513,8 @@ pub fn write_tx_blocks(fi: &FrameInvariants, fs: &mut FrameState,
};
let mut po = bo.plane_offset(&fs.input.planes[p].cfg);
po.x += bx * uv_tx_size.width();
po.y += by * uv_tx_size.height();
po.x += (bx * uv_tx_size.width()) as isize;
po.y += (by * uv_tx_size.height()) as isize;
encode_tx_block(fi, fs, cw, w, p, &tx_bo, chroma_mode, uv_tx_size, uv_tx_type,
plane_bsize, &po, skip, bit_depth, ac, alpha);
......
......@@ -7,7 +7,6 @@
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.
use std::cmp;
use FrameInvariants;
use FrameState;
use partition::*;
......@@ -37,14 +36,14 @@ pub fn motion_estimation(fi: &FrameInvariants, fs: &mut FrameState, bsize: Block
match fi.rec_buffer.frames[fi.ref_frames[ref_frame - LAST_FRAME]] {
Some(ref rec) => {
let po = PlaneOffset { x: bo.x << BLOCK_TO_PLANE_SHIFT, y: bo.y << BLOCK_TO_PLANE_SHIFT };
let range = 16 as usize;
let po = PlaneOffset { x: (bo.x as isize) << BLOCK_TO_PLANE_SHIFT, y: (bo.y as isize) << BLOCK_TO_PLANE_SHIFT };
let range = 16 as isize;
let blk_w = bsize.width();
let blk_h = bsize.height();
let x_lo = cmp::max(0, po.x as isize - range as isize) as usize;
let x_hi = cmp::min(fs.input.planes[0].cfg.width - blk_w, po.x + range);
let y_lo = cmp::max(0, po.y as isize - range as isize) as usize;
let y_hi = cmp::min(fs.input.planes[0].cfg.height - blk_h, po.y + range);
let x_lo = po.x - range;
let x_hi = po.x + range;
let y_lo = po.y - range;
let y_hi = po.y + range;
let mut lowest_sad = 128*128*4096 as u32;
let mut best_mv = MotionVector { row: 0, col: 0 };
......@@ -65,7 +64,7 @@ pub fn motion_estimation(fi: &FrameInvariants, fs: &mut FrameState, bsize: Block
}
let mode = PredictionMode::NEWMV;
let mut tmp_plane = Plane::new(blk_w, blk_h, 0, 0);
let mut tmp_plane = Plane::new(blk_w, blk_h, 0, 0, 0, 0);
let mut steps = vec![4, 2];
if fi.allow_high_precision_mv {
......
......@@ -10,7 +10,6 @@
#![allow(non_camel_case_types)]
#![allow(dead_code)]
use std::cmp;
use self::BlockSize::*;
use self::TxSize::*;
use encoder::FrameInvariants;
......@@ -533,8 +532,6 @@ impl PredictionMode {
} else if self == PredictionMode::V_PRED && y == 0 {
for i in 0..B::H {
left[i + 1] = dst.go_left(1).p(0, 0);
// FIXME(yushin): Figure out why below does not work??
//left[i + 1] = dst.go_left(1).plane.data[0];
}
}
}
......@@ -635,8 +632,7 @@ impl PredictionMode {
let col_offset = mv.col as i32 >> shift_col;
let row_frac = (mv.row as i32 - (row_offset << shift_row)) << (4 - shift_row);
let col_frac = (mv.col as i32 - (col_offset << shift_col)) << (4 - shift_col);
let ref_width = rec_cfg.width;
let ref_height = rec_cfg.height;
let ref_stride = rec_cfg.stride;
let stride = dst.plane.cfg.stride;
let slice = dst.as_mut_slice();
......@@ -647,23 +643,25 @@ impl PredictionMode {
match (col_frac, row_frac) {
(0,0) => {
let qo = PlaneOffset { x: po.x + col_offset as isize, y: po.y + row_offset as isize };
let ps = rec.frame.planes[p].slice(&qo);
let s = ps.as_slice_clamped();
for r in 0..height {
for c in 0..width {
let rs = cmp::min(ref_height as i32 - 1, cmp::max(0, po.y as i32 + row_offset + r as i32)) as usize;
let cs = cmp::min(ref_width as i32 - 1, cmp::max(0, po.x as i32 + col_offset + c as i32)) as usize;
let output_index = r * stride + c;
slice[output_index] = rec.frame.planes[p].p(cs, rs);
slice[output_index] = s[r * ref_stride + c];
}
}
}
(0,_) => {
let qo = PlaneOffset { x: po.x + col_offset as isize, y: po.y + row_offset as isize - 3 };
let ps = rec.frame.planes[p].slice(&qo);
let s = ps.as_slice_clamped();
for r in 0..height {
for c in 0..width {
let mut sum: i32 = 0;
for k in 0..8 {
let rs = cmp::min(ref_height as i32 - 1, cmp::max(0, po.y as i32 + row_offset + r as i32 - 3 + k as i32)) as usize;
let cs = cmp::min(ref_width as i32 - 1, cmp::max(0, po.x as i32 + col_offset + c as i32)) as usize;
sum += rec.frame.planes[p].p(cs, rs) as i32 * SUBPEL_FILTERS[y_filter_idx][row_frac as usize][k];
sum += s[(r + k) * ref_stride + c] as i32 * SUBPEL_FILTERS[y_filter_idx][row_frac as usize][k];
}
let output_index = r * stride + c;
let val = ((sum + 64) >> 7).max(0).min(max_sample_val);
......@@ -672,13 +670,14 @@ impl PredictionMode {
}
}
(_,0) => {
let qo = PlaneOffset { x: po.x + col_offset as isize - 3, y: po.y + row_offset as isize };
let ps = rec.frame.planes[p].slice(&qo);
let s = ps.as_slice_clamped();
for r in 0..height {
for c in 0..width {
let mut sum: i32 = 0;
for k in 0..8 {
let rs = cmp::min(ref_height as i32 - 1, cmp::max(0, po.y as i32 + row_offset + r as i32)) as usize;
let cs = cmp::min(ref_width as i32 - 1, cmp::max(0, po.x as i32 + col_offset + c as i32 - 3 + k as i32)) as usize;
sum += rec.frame.planes[p].p(cs, rs) as i32 * SUBPEL_FILTERS[x_filter_idx][col_frac as usize][k];
sum += s[r * ref_stride + (c + k)] as i32 * SUBPEL_FILTERS[x_filter_idx][col_frac as usize][k];
}
let output_index = r * stride + c;
let val = ((((sum + 4) >> 3) + 8) >> 4).max(0).min(max_sample_val);
......@@ -687,34 +686,37 @@ impl PredictionMode {
}
}
(_,_) => {
let mut intermediate = [[0 as i16; 128]; 128+7];
for r in 0..height+7 {
for c in 0..width {
let mut sum: i32 = 0;
for k in 0..8 {
let rs = cmp::min(ref_height as i32 - 1, cmp::max(0, po.y as i32 + row_offset + r as i32 - 3)) as usize;
let cs = cmp::min(ref_width as i32 - 1, cmp::max(0, po.x as i32 + col_offset + c as i32 - 3 + k as i32)) as usize;
sum += rec.frame.planes[p].p(cs, rs) as i32 * SUBPEL_FILTERS[x_filter_idx][col_frac as usize][k];
let mut intermediate = [0 as i16; 8 * (128 + 7)];
let qo = PlaneOffset { x: po.x + col_offset as isize - 3, y: po.y + row_offset as isize - 3 };
let ps = rec.frame.planes[p].slice(&qo);
let s = ps.as_slice_clamped();
for cg in (0..width).step_by(8) {
for r in 0..height+7 {
for c in cg..(cg+8).min(width) {
let mut sum: i32 = 0;
for k in 0..8 {
sum += s[r * ref_stride + (c + k)] as i32 * SUBPEL_FILTERS[x_filter_idx][col_frac as usize][k];
}
let val = (sum + 4) >> 3;
intermediate[8 * r + (c - cg)] = val as i16;
}
let val = (sum + 4) >> 3;
intermediate[r][c] = val as i16;
}
}
for r in 0..height {
for c in 0..width {
let mut sum: i32 = 0;
for k in 0..8 {
sum += intermediate[r + k][c] as i32 * SUBPEL_FILTERS[y_filter_idx][row_frac as usize][k];
}
let output_index = r * stride + c;
let val = ((sum + 1024) >> 11).max(0).min(max_sample_val);
slice[output_index] = val as u16;
for r in 0..height {
for c in cg..(cg+8).min(width) {
let mut sum: i32 = 0;
for k in 0..8 {
sum += intermediate[8 * (r + k) + c - cg] as i32 * SUBPEL_FILTERS[y_filter_idx][row_frac as usize][k];
}
let output_index = r * stride + c;
let val = ((sum + 1024) >> 11).max(0).min(max_sample_val);
slice[output_index] = val as u16;
}
}
}
}
}
},
None => (),
}
......
......@@ -15,17 +15,20 @@ use util::*;
#[derive(Debug, Clone)]
pub struct PlaneConfig {
pub stride: usize,
pub alloc_height: usize,
pub width: usize,
pub height: usize,
pub xdec: usize,
pub ydec: usize
pub ydec: usize,
pub xorigin: usize,
pub yorigin: usize
}
/// Absolute offset in pixels inside a plane
#[derive(Debug)]
pub struct PlaneOffset {
pub x: usize,
pub y: usize
pub x: isize,
pub y: isize
}
#[derive(Debug, Clone)]
......@@ -41,11 +44,57 @@ impl Plane {
/// Data alignment in bytes.
const DATA_ALIGNMENT_LOG2: usize = 4;
pub fn new(width: usize, height: usize, xdec: usize, ydec: usize) -> Plane {
let stride = width.align_power_of_two(Plane::STRIDE_ALIGNMENT_LOG2 - 1);
let data = vec![128u16; stride * height];
pub fn new(width: usize, height: usize, xdec: usize, ydec: usize, xpad: usize, ypad: usize) -> Plane {
let xorigin = xpad.align_power_of_two(Plane::STRIDE_ALIGNMENT_LOG2 - 1);
let yorigin = ypad;
let stride = (xorigin + width + xpad).align_power_of_two(Plane::STRIDE_ALIGNMENT_LOG2 - 1);
let alloc_height = yorigin + height + ypad;
let data = vec![128u16; stride * alloc_height];
assert!(is_aligned(data.as_ptr(), Plane::DATA_ALIGNMENT_LOG2));
Plane { data, cfg: PlaneConfig { stride, width, height, xdec, ydec } }
Plane { data, cfg: PlaneConfig { stride, alloc_height, width, height, xdec, ydec, xorigin, yorigin } }
}
pub fn pad(&mut self) {
let xorigin = self.cfg.xorigin;
let yorigin = self.cfg.yorigin;
let stride = self.cfg.stride;
let width = self.cfg.width;
let height = self.cfg.height;
if xorigin > 0 {
for y in 0..height {
let mut ps = self.mut_slice(&PlaneOffset { x: -(xorigin as isize), y: y as isize });
let s = ps.as_mut_slice_w_width(xorigin + 1);
let fill_val = s[xorigin];
for val in s[..xorigin].iter_mut() { *val = fill_val; }
}
}
if xorigin + width < stride {
for y in 0..height {
let mut ps = self.mut_slice(&PlaneOffset { x: width as isize - 1, y: y as isize });
let s = ps.as_mut_slice_w_width(stride - xorigin - width + 1);
let fill_val = s[0];
for val in s[1..].iter_mut() { *val = fill_val; }
}
}
if yorigin > 0 {
let mut ps = self.mut_slice(&PlaneOffset { x: -(xorigin as isize), y: -(yorigin as isize) });
let (s1, s2) = ps.as_mut_slice().split_at_mut(yorigin*stride);
for y in 0 .. yorigin {
s1[y*stride..y*stride+stride].copy_from_slice(&s2[..stride]);
}
}
if yorigin + height < self.cfg.alloc_height {
let mut ps = self.mut_slice(&PlaneOffset { x: -(xorigin as isize), y: height as isize - 1 });
let (s2, s1) = ps.as_mut_slice().split_at_mut(stride);
for y in 0 .. yorigin {
s1[y*stride..y*stride+stride].copy_from_slice(&s2[..stride]);
}
}
}
pub fn slice<'a>(&'a self, po: &PlaneOffset) -> PlaneSlice<'a> {
......@@ -57,7 +106,15 @@ impl Plane {
}
pub fn p(&self, x: usize, y: usize) -> u16 {
self.data[y * self.cfg.stride + x]
self.data[(y + self.cfg.yorigin) * self.cfg.stride + (x + self.cfg.xorigin)]
}
pub fn data_origin(&self) -> &[u16] {
&self.data[self.cfg.yorigin * self.cfg.stride + self.cfg.xorigin..]
}
pub fn data_origin_mut(&mut self) -> &mut [u16] {
&mut self.data[self.cfg.yorigin * self.cfg.stride + self.cfg.xorigin..]
}
pub fn copy_from_raw_u8(
......@@ -65,7 +122,7 @@ impl Plane {
) {
let stride = self.cfg.stride;
for (self_row, source_row) in
self.data.chunks_mut(stride).zip(source.chunks(source_stride))
self.data_origin_mut().chunks_mut(stride).zip(source.chunks(source_stride))
{
match source_bytewidth {
1 => for (self_pixel, source_pixel) in
......@@ -87,66 +144,86 @@ impl Plane {
pub struct PlaneSlice<'a> {
pub plane: &'a Plane,
pub x: usize,
pub y: usize
pub x: isize,
pub y: isize
}
impl<'a> PlaneSlice<'a> {
pub fn as_slice(&'a self) -> &'a [u16] {
let stride = self.plane.cfg.stride;
&self.plane.data[self.y * stride + self.x..]
let base = (self.y + self.plane.cfg.yorigin as isize) as usize * stride + (self.x + self.plane.cfg.xorigin as isize) as usize;
&self.plane.data[base..]
}
pub fn as_slice_clamped(&'a self) -> &'a [u16] {
let stride = self.plane.cfg.stride;
let y = (self.y.min(self.plane.cfg.height as isize) + self.plane.cfg.yorigin as isize).max(0) as usize;
let x = (self.x.min(self.plane.cfg.width as isize) + self.plane.cfg.xorigin as isize).max(0) as usize;
&self.plane.data[y * stride + x..]
}
pub fn as_slice_w_width(&'a self, width: usize) -> &'a [u16] {
let stride = self.plane.cfg.stride;
let base = self.y * stride + self.x;
let base = (self.y + self.plane.cfg.yorigin as isize) as usize * stride + (self.x + self.plane.cfg.xorigin as isize) as usize;
&self.plane.data[base .. base + width]
}
pub fn subslice(&'a self, xo: usize, yo: usize) -> PlaneSlice<'a> {
PlaneSlice { plane: self.plane, x: self.x + xo, y: self.y + yo }
PlaneSlice { plane: self.plane, x: self.x + xo as isize, y: self.y + yo as isize }
}
/// A slice starting i pixels above the current one.
pub fn go_up(&'a self, i: usize) -> PlaneSlice<'a> {
PlaneSlice { plane: self.plane, x: self.x, y: self.y - i }
PlaneSlice { plane: self.plane, x: self.x, y: self.y - i as isize }
}
/// A slice starting i pixels to the left of the current one.
pub fn go_left(&'a self, i: usize) -> PlaneSlice<'a> {
PlaneSlice { plane: self.plane, x: self.x - i, y: self.y }
PlaneSlice { plane: self.plane, x: self.x - i as isize, y: self.y }
}
pub fn p(&self, add_x: usize, add_y: usize) -> u16 {
let new_y = self.y + add_y;
let new_x = self.x + add_x;
let new_y = (self.y + add_y as isize + self.plane.cfg.yorigin as isize) as usize;
let new_x = (self.x + add_x as isize + self.plane.cfg.xorigin as isize) as usize;
self.plane.data[new_y * self.plane.cfg.stride + new_x]
}
}
pub struct PlaneMutSlice<'a> {
pub plane: &'a mut Plane,
pub x: usize,
pub y: usize
pub x: isize,
pub y: isize
}
impl<'a> PlaneMutSlice<'a> {
pub fn as_mut_slice(&'a mut self) -> &'a mut [u16] {
let stride = self.plane.cfg.stride;
&mut self.plane.data[self.y * stride + self.x..]
let base = (self.y + self.plane.cfg.yorigin as isize) as usize * stride + (self.x + self.plane.cfg.xorigin as isize) as usize;
&mut self.plane.data[base..]
}
pub fn as_mut_slice_w_width(&'a mut self, width: usize) -> &'a mut [u16] {
let stride = self.plane.cfg.stride;
let y = self.y + self.plane.cfg.yorigin as isize;
let x = self.x + self.plane.cfg.xorigin as isize;
assert!(y >= 0);
assert!(x >= 0);
let base = y as usize * stride + x as usize;
&mut self.plane.data[base .. base + width]
}
pub fn offset(&self, add_x: usize, add_y: usize) -> &[u16] {
let new_y = self.y + add_y;
let new_x = self.x + add_x;
let new_y = (self.y + add_y as isize + self.plane.cfg.yorigin as isize) as usize;
let new_x = (self.x + add_x as isize + self.plane.cfg.xorigin as isize) as usize;
&self.plane.data[new_y * self.plane.cfg.stride + new_x..]
}
pub fn offset_as_mutable(
&'a mut self, add_x: usize, add_y: usize
) -> &'a mut [u16] {
let new_y = self.y + add_y;
let new_x = self.x + add_x;
let new_y = (self.y + add_y as isize + self.plane.cfg.yorigin as isize) as usize;
let new_x = (self.x + add_x as isize + self.plane.cfg.xorigin as isize) as usize;
&mut self.plane.data[new_y * self.plane.cfg.stride + new_x..]
}
......@@ -154,17 +231,17 @@ impl<'a> PlaneMutSlice<'a> {
/// A slice starting i pixels above the current one.
pub fn go_up(&'a self, i: usize) -> PlaneSlice<'a> {
PlaneSlice { plane: self.plane, x: self.x, y: self.y - i }
PlaneSlice { plane: self.plane, x: self.x, y: self.y - i as isize }
}
/// A slice starting i pixels to the left of the current one.
pub fn go_left(&'a self, i: usize) -> PlaneSlice<'a> {
PlaneSlice { plane: self.plane, x: self.x - i, y: self.y }
PlaneSlice { plane: self.plane, x: self.x - i as isize, y: self.y }
}
pub fn p(&self, add_x: usize, add_y: usize) -> u16 {
let new_y = self.y + add_y;
let new_x = self.x + add_x;
let new_y = (self.y + add_y as isize + self.plane.cfg.yorigin as isize) as usize;
let new_x = (self.x + add_x as isize + self.plane.cfg.xorigin as isize) as usize;
self.plane.data[new_y * self.plane.cfg.stride + new_x]
}
}
......@@ -584,30 +584,30 @@ pub fn rdo_cdef_decision(sbo: &SuperBlockOffset, fi: &FrameInvariants,
let mut cdef_output = Frame {
planes: [
Plane::new(64 >> fs.rec.planes[0].cfg.xdec, 64 >> fs.rec.planes[0].cfg.ydec,
fs.rec.planes[0].cfg.xdec, fs.rec.planes[0].cfg.ydec),
fs.rec.planes[0].cfg.xdec, fs.rec.planes[0].cfg.ydec, 0, 0),
Plane::new(64 >> fs.rec.planes[1].cfg.xdec, 64 >> fs.rec.planes[1].cfg.ydec,
fs.rec.planes[1].cfg.xdec, fs.rec.planes[1].cfg.ydec),
fs.rec.planes[1].cfg.xdec, fs.rec.planes[1].cfg.ydec, 0, 0),
Plane::new(64 >> fs.rec.planes[2].cfg.xdec, 64 >> fs.rec.planes[2].cfg.ydec,
fs.rec.planes[2].cfg.xdec, fs.rec.planes[2].cfg.ydec),
fs.rec.planes[2].cfg.xdec, fs.rec.planes[2].cfg.ydec, 0, 0),
]
};
// Construct a padded input
let mut rec_input = Frame {
planes: [
Plane::new((64 >> fs.rec.planes[0].cfg.xdec)+4, (64 >> fs.rec.planes[0].cfg.ydec)+4,
fs.rec.planes[0].cfg.xdec, fs.rec.planes[0].cfg.ydec),
fs.rec.planes[0].cfg.xdec, fs.rec.planes[0].cfg.ydec, 0, 0),
Plane::new((64 >> fs.rec.planes[1].cfg.xdec)+4, (64 >> fs.rec.planes[1].cfg.ydec)+4,
fs.rec.planes[1].cfg.xdec, fs.rec.planes[1].cfg.ydec),
fs.rec.planes[1].cfg.xdec, fs.rec.planes[1].cfg.ydec, 0, 0),
Plane::new((64 >> fs.rec.planes[2].cfg.xdec)+4, (64 >> fs.rec.planes[2].cfg.ydec)+4,
fs.rec.planes[2].cfg.xdec, fs.rec.planes[2].cfg.ydec),
fs.rec.planes[2].cfg.xdec, fs.rec.planes[2].cfg.ydec, 0, 0),
]
};
// Copy reconstructed data into padded input
for p in 0..3 {
let xdec = fs.rec.planes[p].cfg.xdec;
let ydec = fs.rec.planes[p].cfg.ydec;
let h = fi.padded_h >> ydec;
let w = fi.padded_w >> xdec;
let h = fi.padded_h as isize >> ydec;
let w = fi.padded_w as isize >> xdec;
let offset = sbo.plane_offset(&fs.rec.planes[p].cfg);
for y in 0..(64>>ydec)+4 {
let mut rec_slice = rec_input.planes[p].mut_slice(&PlaneOffset {x:0, y:y});
......@@ -623,14 +623,14 @@ pub fn rdo_cdef_decision(sbo: &SuperBlockOffset, fi: &FrameInvariants,
// No; do it the hard way. off left or right edge, fill with flag.
for x in 0..(64>>xdec)+4 {
if offset.x+x >= 2 && offset.x+x < w+2 {
rec_row[x] = in_row[offset.x+x-2]
rec_row[x as usize] = in_row[(offset.x+x-2) as usize]
} else {
rec_row[x] = CDEF_VERY_LARGE;
rec_row[x as usize] = CDEF_VERY_LARGE;
}
}
} else {
// Yes, do it the easy way: just copy
rec_row[0..(64>>xdec)+4].copy_from_slice(&in_row[offset.x-2..offset.x+(64>>xdec)+2]);
rec_row[0..(64>>xdec)+4].copy_from_slice(&in_row[(offset.x-2) as usize..(offset.x+(64>>xdec)+2) as usize]);
}
}
}
......
......@@ -182,7 +182,7 @@ use std::collections::VecDeque;
slice::from_raw_parts(data, size)
};
let rec: Vec<u16> = frame_plane.data.iter().map(|&v| v).collect();
let rec: Vec<u16> = frame_plane.data_origin().iter().map(|&v| v).collect();
compare_plane::<u16>(&rec[..], rec_stride, dec, dec_stride, w, h);
} else {
......@@ -195,7 +195,7 @@ use std::collections::VecDeque;
slice::from_raw_parts(data, size)
};
let rec: Vec<u8> = frame_plane.data.iter().map(|&v| v as u8).collect();
let rec: Vec<u8> = frame_plane.data_origin().iter().map(|&v| v as u8).collect();
compare_plane::<u8>(&rec[..], rec_stride, dec, dec_stride, w, h);
}
......@@ -228,6 +228,8 @@ use std::collections::VecDeque;
let packet = encode_frame(&mut seq, &mut fi, &mut fs);
println!("Encoded.");
fs.rec.pad();
rec_fifo.push_back(fs.rec.clone());
update_rec_buffer(&mut fi, fs);
......