Commit 5638ae64 authored by Romain Vimont's avatar Romain Vimont Committed by Luca Barbato

Add struct FrameMotionVectors

The motion vectors were stored in a Vec<Vec<MotionVector>>.

The innermost Vec contains a flatten matrix (fi.w_in_b x fi.h_in_b) of
MotionVectors, and there are REF_FRAMES instances of them (the outermost
Vec).

Introduce a typed structure to replace the innermost Vec:
 - this improves readability;
 - this allows to expose it as a 2D array, thanks to Index and IndexMut
   traits;
 - this will allow to split it into (non-overlapping) tiled views,
   containing only the motion vectors for a bounded region of the plane
   (see <https://github.com/xiph/rav1e/pull/1126>).
parent 8f07aebc
......@@ -156,7 +156,7 @@ pub struct ReferenceFrame<T: Pixel> {
pub input_hres: Plane<T>,
pub input_qres: Plane<T>,
pub cdfs: CDFContext,
pub frame_mvs: Vec<Vec<MotionVector>>,
pub frame_mvs: Vec<FrameMotionVectors>,
}
#[derive(Debug, Clone, Default)]
......@@ -392,7 +392,7 @@ pub struct FrameState<T: Pixel> {
pub deblock: DeblockState,
pub segmentation: SegmentationState,
pub restoration: RestorationState,
pub frame_mvs: Vec<Vec<MotionVector>>,
pub frame_mvs: Vec<FrameMotionVectors>,
pub t: RDOTracker,
}
......@@ -420,7 +420,13 @@ impl<T: Pixel> FrameState<T> {
deblock: Default::default(),
segmentation: Default::default(),
restoration: rs,
frame_mvs: vec![vec![MotionVector::default(); fi.w_in_b * fi.h_in_b]; REF_FRAMES],
frame_mvs: {
let mut vec = Vec::with_capacity(REF_FRAMES);
for _ in 0..REF_FRAMES {
vec.push(FrameMotionVectors::new(fi.w_in_b, fi.h_in_b));
}
vec
},
t: RDOTracker::new()
}
}
......
......@@ -19,6 +19,7 @@ use crate::partition::*;
use crate::plane::*;
use crate::util::Pixel;
use std::ops::{Index, IndexMut};
use std::sync::Arc;
#[cfg(all(target_arch = "x86_64", feature = "nasm"))]
......@@ -216,6 +217,38 @@ mod native {
}
}
#[derive(Debug, Clone)]
pub struct FrameMotionVectors {
mvs: Box<[MotionVector]>,
pub cols: usize,
pub rows: usize,
}
impl FrameMotionVectors {
pub fn new(cols: usize, rows: usize) -> Self {
Self {
mvs: vec![MotionVector::default(); cols * rows].into_boxed_slice(),
cols,
rows,
}
}
}
impl Index<usize> for FrameMotionVectors {
type Output = [MotionVector];
#[inline]
fn index(&self, index: usize) -> &Self::Output {
&self.mvs[index * self.cols..(index + 1) * self.cols]
}
}
impl IndexMut<usize> for FrameMotionVectors {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.mvs[index * self.cols..(index + 1) * self.cols]
}
}
fn get_mv_range(
w_in_b: usize, h_in_b: usize, bo: &BlockOffset, blk_w: usize, blk_h: usize
) -> (isize, isize, isize, isize) {
......@@ -231,7 +264,7 @@ fn get_mv_range(
pub fn get_subset_predictors<T: Pixel>(
fi: &FrameInvariants<T>, bo: &BlockOffset, cmv: MotionVector,
frame_mvs: &[MotionVector], frame_ref_opt: &Option<Arc<ReferenceFrame<T>>>,
frame_mvs: &FrameMotionVectors, frame_ref_opt: &Option<Arc<ReferenceFrame<T>>>,
ref_slot: usize
) -> (Vec<MotionVector>) {
let mut predictors = Vec::new();
......@@ -239,15 +272,15 @@ pub fn get_subset_predictors<T: Pixel>(
// EPZS subset A and B predictors.
if bo.x > 0 {
let left = frame_mvs[bo.y * fi.w_in_b + bo.x - 1];
let left = frame_mvs[bo.y][bo.x - 1];
predictors.push(left);
}
if bo.y > 0 {
let top = frame_mvs[(bo.y - 1) * fi.w_in_b + bo.x];
let top = frame_mvs[bo.y - 1][bo.x];
predictors.push(top);
if bo.x < fi.w_in_b - 1 {
let top_right = frame_mvs[(bo.y - 1) * fi.w_in_b + bo.x + 1];
let top_right = frame_mvs[bo.y - 1][bo.x + 1];
predictors.push(top_right);
}
}
......@@ -274,23 +307,23 @@ pub fn get_subset_predictors<T: Pixel>(
let prev_frame_mvs = &frame_ref.frame_mvs[ref_slot];
if bo.x > 0 {
let left = prev_frame_mvs[bo.y * fi.w_in_b + bo.x - 1];
let left = prev_frame_mvs[bo.y][bo.x - 1];
predictors.push(left);
}
if bo.y > 0 {
let top = prev_frame_mvs[(bo.y - 1) * fi.w_in_b + bo.x];
let top = prev_frame_mvs[bo.y - 1][bo.x];
predictors.push(top);
}
if bo.x < fi.w_in_b - 1 {
let right = prev_frame_mvs[bo.y * fi.w_in_b + bo.x + 1];
let right = prev_frame_mvs[bo.y][bo.x + 1];
predictors.push(right);
}
if bo.y < fi.h_in_b - 1 {
let bottom = prev_frame_mvs[(bo.y + 1) * fi.w_in_b + bo.x];
let bottom = prev_frame_mvs[bo.y + 1][bo.x];
predictors.push(bottom);
}
predictors.push(prev_frame_mvs[bo.y * fi.w_in_b + bo.x]);
predictors.push(prev_frame_mvs[bo.y][bo.x]);
}
predictors
......
......@@ -520,8 +520,7 @@ pub fn rdo_mode_decision<T: Pixel>(
let frame_mvs = &mut fs.frame_mvs[ref_slot as usize];
for mi_y in (bo.y)..(bo.y + bsize.height_mi()) {
for mi_x in (bo.x)..(bo.x + bsize.width_mi()) {
let offset = mi_y * fi.w_in_b + mi_x;
frame_mvs[offset] = b_me;
frame_mvs[mi_y][mi_x] = b_me;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment