Commit db58658a authored by Thomas Daede's avatar Thomas Daede

Create RefType enum.

Moves all functions that previously used usize to this type.
Instead of direct conversions to a slot number, use a to_index fn.

This also changes the size of the global mv state and context
ref counting arrays as they don't need LAST_FRAME.
parent 6f320b1c
This diff is collapsed.
......@@ -14,8 +14,8 @@ use crate::DeblockState;
use crate::FrameInvariants;
use crate::FrameState;
use crate::FrameType;
use crate::partition::*;
use crate::partition::PredictionMode::*;
use crate::partition::RefType::*;
use crate::plane::*;
use crate::quantize::*;
use crate::util::Pixel;
......@@ -67,7 +67,7 @@ fn deblock_adjusted_level(
let l5 = level >> 5;
clamp(
level as i32
+ ((deblock.ref_deltas[reference] as i32) << l5)
+ ((deblock.ref_deltas[reference.to_index()] as i32) << l5)
+ if reference == INTRA_FRAME {
0
} else {
......
......@@ -26,6 +26,7 @@ use crate::segmentation::*;
use crate::transform::*;
use crate::util::*;
use crate::partition::PartitionType::*;
use crate::partition::RefType::*;
use crate::header::*;
use arg_enum_proc_macro::ArgEnum;
......@@ -511,7 +512,7 @@ pub struct FrameInvariants<T: Pixel> {
pub reference_mode: ReferenceMode,
pub use_prev_frame_mvs: bool,
pub min_partition_size: BlockSize,
pub globalmv_transformation_type: [GlobalMVMode; ALTREF_FRAME + 1],
pub globalmv_transformation_type: [GlobalMVMode; INTER_REFS_PER_FRAME],
pub num_tg: usize,
pub large_scale_tile: bool,
pub disable_cdf_update: bool,
......@@ -597,7 +598,7 @@ impl<T: Pixel> FrameInvariants<T> {
reference_mode: ReferenceMode::SINGLE,
use_prev_frame_mvs: false,
min_partition_size,
globalmv_transformation_type: [GlobalMVMode::IDENTITY; ALTREF_FRAME + 1],
globalmv_transformation_type: [GlobalMVMode::IDENTITY; INTER_REFS_PER_FRAME],
num_tg: 1,
large_scale_tile: false,
disable_cdf_update: false,
......@@ -736,7 +737,7 @@ impl<T: Pixel> FrameInvariants<T> {
};
let second_ref_frame = if !inter_cfg.multiref {
NONE_FRAME
LAST_FRAME // make second_ref_frame match first
} else if !inter_cfg.reorder || inter_cfg.idx_in_group == 0 {
LAST2_FRAME
} else {
......@@ -748,18 +749,18 @@ impl<T: Pixel> FrameInvariants<T> {
fi.primary_ref_frame = if lvl > 0 {
PRIMARY_REF_NONE
} else {
(ref_in_previous_group - LAST_FRAME) as u32
(ref_in_previous_group.to_index()) as u32
};
for i in 0..INTER_REFS_PER_FRAME {
fi.ref_frames[i] = if lvl == 0 {
if i == second_ref_frame - LAST_FRAME {
if i == second_ref_frame.to_index() {
(slot_idx + 4 - 2) as u8 % 4
} else {
(slot_idx + 4 - 1) as u8 % 4
}
} else {
if i == second_ref_frame - LAST_FRAME {
if i == second_ref_frame.to_index() {
let oh = fi.order_hint + (inter_cfg.group_src_len as u32 >> lvl);
let lvl2 = pos_to_lvl(oh as u64, inter_cfg.pyramid_depth);
if lvl2 == 0 {
......@@ -767,7 +768,7 @@ impl<T: Pixel> FrameInvariants<T> {
} else {
3 + lvl2 as u8
}
} else if i == ref_in_previous_group - LAST_FRAME {
} else if i == ref_in_previous_group.to_index() {
if lvl == 0 {
(slot_idx + 4 - 1) as u8 % 4
} else {
......@@ -1050,7 +1051,7 @@ pub fn encode_tx_block<T: Pixel>(
pub fn motion_compensate<T: Pixel>(
fi: &FrameInvariants<T>, fs: &mut FrameState<T>, cw: &mut ContextWriter,
luma_mode: PredictionMode, ref_frames: [usize; 2], mvs: [MotionVector; 2],
luma_mode: PredictionMode, ref_frames: [RefType; 2], mvs: [MotionVector; 2],
bsize: BlockSize, bo: BlockOffset, luma_only: bool
) {
debug_assert!(!luma_mode.is_intra());
......@@ -1159,7 +1160,7 @@ pub fn encode_block_b<T: Pixel>(
fi: &FrameInvariants<T>, fs: &mut FrameState<T>,
cw: &mut ContextWriter, w: &mut dyn Writer,
luma_mode: PredictionMode, chroma_mode: PredictionMode,
ref_frames: [usize; 2], mvs: [MotionVector; 2],
ref_frames: [RefType; 2], mvs: [MotionVector; 2],
bsize: BlockSize, bo: BlockOffset, skip: bool,
cfl: CFLParams, tx_size: TxSize, tx_type: TxType,
mode_context: usize, mv_stack: &[CandidateMV],
......@@ -1618,7 +1619,7 @@ fn encode_partition_bottomup<T: Pixel>(
// Fill the saved motion structure
save_block_motion(
fs, fi.w_in_b, fi.h_in_b, mode_decision.bsize, mode_decision.bo,
mode_decision.ref_frames[0] - LAST_FRAME, mode_decision.mvs[0]
mode_decision.ref_frames[0].to_index(), mode_decision.mvs[0]
);
}
......@@ -1746,7 +1747,7 @@ fn encode_partition_bottomup<T: Pixel>(
if !mode.pred_mode_luma.is_intra() {
save_block_motion(
fs, fi.w_in_b, fi.h_in_b, mode.bsize, mode.bo,
mode.ref_frames[0] - LAST_FRAME, mode.mvs[0]
mode.ref_frames[0].to_index(), mode.mvs[0]
);
}
......@@ -1924,7 +1925,7 @@ fn encode_partition_topdown<T: Pixel>(
save_block_motion(
fs, fi.w_in_b, fi.h_in_b,
part_decision.bsize, part_decision.bo,
part_decision.ref_frames[0] - LAST_FRAME, part_decision.mvs[0]
part_decision.ref_frames[0].to_index(), part_decision.mvs[0]
);
}
......
......@@ -688,7 +688,7 @@ impl<W: io::Write> UncompressedHeader for BitWriter<W, BigEndian> {
// global motion
if !fi.intra_only {
for i in LAST_FRAME..=ALTREF_FRAME {
for i in 0..7 {
let mode = fi.globalmv_transformation_type[i];
self.write_bit(mode != GlobalMVMode::IDENTITY)?;
if mode != GlobalMVMode::IDENTITY {
......
......@@ -16,6 +16,7 @@ use crate::encoder::ReferenceFrame;
use crate::FrameInvariants;
use crate::FrameState;
use crate::partition::*;
use crate::partition::RefType::*;
use crate::plane::*;
use crate::util::Pixel;
......@@ -341,7 +342,7 @@ pub trait MotionEstimation {
cmv: MotionVector, pmv: [MotionVector; 2],
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize,
blk_w: usize, blk_h: usize, best_mv: &mut MotionVector,
lowest_cost: &mut u64, ref_frame: usize
lowest_cost: &mut u64, ref_frame: RefType
);
fn sub_pixel_me<T: Pixel>(
......@@ -349,15 +350,15 @@ pub trait MotionEstimation {
bo: BlockOffset, lambda: u32, pmv: [MotionVector; 2],
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize,
blk_w: usize, blk_h: usize, best_mv: &mut MotionVector,
lowest_cost: &mut u64, ref_frame: usize
lowest_cost: &mut u64, ref_frame: RefType
);
fn motion_estimation<T: Pixel> (
fi: &FrameInvariants<T>, fs: &FrameState<T>, bsize: BlockSize,
bo: BlockOffset, ref_frame: usize, cmv: MotionVector,
bo: BlockOffset, ref_frame: RefType, cmv: MotionVector,
pmv: [MotionVector; 2]
) -> MotionVector {
match fi.rec_buffer.frames[fi.ref_frames[ref_frame - LAST_FRAME] as usize]
match fi.rec_buffer.frames[fi.ref_frames[ref_frame.to_index()] as usize]
{
Some(ref rec) => {
let blk_w = bsize.width();
......@@ -447,12 +448,12 @@ impl MotionEstimation for DiamondSearch {
bo: BlockOffset, lambda: u32,
cmv: MotionVector, pmv: [MotionVector; 2], mvx_min: isize, mvx_max: isize,
mvy_min: isize, mvy_max: isize, blk_w: usize, blk_h: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: usize
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: RefType
) {
let frame_mvs = &fs.frame_mvs[ref_frame - LAST_FRAME];
let frame_mvs = &fs.frame_mvs[ref_frame.to_index()];
let frame_ref = fi.rec_buffer.frames[fi.ref_frames[0] as usize].as_ref().map(Arc::as_ref);
let predictors =
get_subset_predictors(bo, cmv, fi.w_in_b, fi.h_in_b, frame_mvs, frame_ref, ref_frame - LAST_FRAME);
get_subset_predictors(bo, cmv, fi.w_in_b, fi.h_in_b, frame_mvs, frame_ref, ref_frame.to_index());
diamond_me_search(
fi,
......@@ -481,7 +482,7 @@ impl MotionEstimation for DiamondSearch {
bo: BlockOffset, lambda: u32,
pmv: [MotionVector; 2], mvx_min: isize, mvx_max: isize,
mvy_min: isize, mvy_max: isize, blk_w: usize, blk_h: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: RefType,
)
{
let predictors = vec![*best_mv];
......@@ -539,7 +540,7 @@ impl MotionEstimation for DiamondSearch {
mvx_min >> 1, mvx_max >> 1, mvy_min >> 1, mvy_max >> 1,
blk_w >> 1, blk_h >> 1,
best_mv, lowest_cost,
false, 0
false, LAST_FRAME
);
}
}
......@@ -552,7 +553,7 @@ impl MotionEstimation for FullSearch {
bo: BlockOffset, lambda: u32,
cmv: MotionVector, pmv: [MotionVector; 2], mvx_min: isize, mvx_max: isize,
mvy_min: isize, mvy_max: isize, blk_w: usize, blk_h: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, _ref_frame: usize
best_mv: &mut MotionVector, lowest_cost: &mut u64, _ref_frame: RefType
) {
let po = bo.to_luma_plane_offset();
let range = 16;
......@@ -590,7 +591,7 @@ impl MotionEstimation for FullSearch {
bo: BlockOffset, lambda: u32,
pmv: [MotionVector; 2], mvx_min: isize, mvx_max: isize,
mvy_min: isize, mvy_max: isize, blk_w: usize, blk_h: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: RefType,
)
{
telescopic_subpel_search(
......@@ -659,7 +660,7 @@ fn get_best_predictor<T: Pixel>(
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize,
blk_w: usize, blk_h: usize,
center_mv: &mut MotionVector, center_mv_cost: &mut u64,
tmp_plane_opt: &mut Option<Plane<T>>, ref_frame: usize) {
tmp_plane_opt: &mut Option<Plane<T>>, ref_frame: RefType) {
*center_mv = MotionVector::default();
*center_mv_cost = std::u64::MAX;
......@@ -684,7 +685,7 @@ fn diamond_me_search<T: Pixel>(
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize,
blk_w: usize, blk_h: usize,
center_mv: &mut MotionVector, center_mv_cost: &mut u64,
subpixel: bool, ref_frame: usize)
subpixel: bool, ref_frame: RefType)
{
let diamond_pattern = [(1i16, 0i16), (0, 1), (-1, 0), (0, -1)];
let (mut diamond_radius, diamond_radius_end, mut tmp_plane_opt) = {
......@@ -752,7 +753,7 @@ fn get_mv_rd_cost<T: Pixel>(
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize,
blk_w: usize, blk_h: usize,
cand_mv: MotionVector, tmp_plane_opt: &mut Option<Plane<T>>,
ref_frame: usize) -> u64
ref_frame: RefType) -> u64
{
if (cand_mv.col as isize) < mvx_min || (cand_mv.col as isize) > mvx_max {
return std::u64::MAX;
......@@ -811,7 +812,7 @@ fn compute_mv_rd_cost<T: Pixel>(
fn telescopic_subpel_search<T: Pixel>(
fi: &FrameInvariants<T>, fs: &FrameState<T>, po: PlaneOffset,
lambda: u32, ref_frame: usize, pmv: [MotionVector; 2],
lambda: u32, ref_frame: RefType, pmv: [MotionVector; 2],
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize,
blk_w: usize, blk_h: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64
......
......@@ -20,15 +20,48 @@ use crate::plane::*;
use crate::predict::*;
use crate::util::*;
pub const NONE_FRAME: usize = 8;
pub const INTRA_FRAME: usize = 0;
pub const LAST_FRAME: usize = 1;
pub const LAST2_FRAME: usize = 2;
pub const LAST3_FRAME: usize = 3;
pub const GOLDEN_FRAME: usize = 4;
pub const BWDREF_FRAME: usize = 5;
pub const ALTREF2_FRAME: usize = 6;
pub const ALTREF_FRAME: usize = 7;
// LAST_FRAME through ALTREF_FRAME correspond to slots 0-6.
#[derive(PartialEq, Eq, Copy, Clone)]
pub enum RefType {
INTRA_FRAME = 0,
LAST_FRAME = 1,
LAST2_FRAME = 2,
LAST3_FRAME = 3,
GOLDEN_FRAME = 4,
BWDREF_FRAME = 5,
ALTREF2_FRAME = 6,
ALTREF_FRAME = 7,
NONE_FRAME = 8,
}
impl RefType {
// convert to a ref list index, 0-6 (INTER_REFS_PER_FRAME)
pub fn to_index(self) -> usize {
match self {
NONE_FRAME => { panic!("Tried to get slot of NONE_FRAME"); },
INTRA_FRAME => { panic!("Tried to get slot of INTRA_FRAME"); },
_ => { (self as usize) - 1 }
}
}
pub fn is_fwd_ref(self) -> bool {
(self as usize) < 5
}
pub fn is_bwd_ref(self) -> bool {
(self as usize) >= 5
}
}
use RefType::*;
pub const ALL_INTER_REFS: [RefType; 7] = [
LAST_FRAME,
LAST2_FRAME,
LAST3_FRAME,
GOLDEN_FRAME,
BWDREF_FRAME,
ALTREF2_FRAME,
ALTREF_FRAME
];
pub const LAST_LAST2_FRAMES: usize = 0; // { LAST_FRAME, LAST2_FRAME }
pub const LAST_LAST3_FRAMES: usize = 1; // { LAST_FRAME, LAST3_FRAME }
......@@ -45,11 +78,11 @@ pub const TOTAL_UNIDIR_COMP_REFS: usize = 9;
// that are explicitly signaled.
pub const UNIDIR_COMP_REFS: usize = BWDREF_ALTREF_FRAMES + 1;
pub const FWD_REFS: usize = GOLDEN_FRAME - LAST_FRAME + 1;
pub const BWD_REFS: usize = ALTREF_FRAME - BWDREF_FRAME + 1;
pub const SINGLE_REFS: usize = FWD_REFS + BWD_REFS;
pub const TOTAL_REFS_PER_FRAME: usize = ALTREF_FRAME - INTRA_FRAME + 1;
pub const INTER_REFS_PER_FRAME: usize = ALTREF_FRAME - LAST_FRAME + 1;
pub const FWD_REFS: usize = 4;
pub const BWD_REFS: usize = 3;
pub const SINGLE_REFS: usize = 7;
pub const TOTAL_REFS_PER_FRAME: usize = 8;
pub const INTER_REFS_PER_FRAME: usize = 7;
pub const TOTAL_COMP_REFS: usize =
FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS;
......@@ -1132,13 +1165,13 @@ impl PredictionMode {
pub fn predict_inter<T: Pixel>(
self, fi: &FrameInvariants<T>, p: usize, po: PlaneOffset,
dst: &mut PlaneMutSlice<'_, T>, width: usize, height: usize,
ref_frames: [usize; 2], mvs: [MotionVector; 2]
ref_frames: [RefType; 2], mvs: [MotionVector; 2]
) {
assert!(!self.is_intra());
let mode = FilterMode::REGULAR;
let is_compound =
ref_frames[1] > INTRA_FRAME && ref_frames[1] != NONE_FRAME;
ref_frames[1] != INTRA_FRAME && ref_frames[1] != NONE_FRAME;
fn get_params<'a, T: Pixel>(
rec_plane: &'a Plane<T>, po: PlaneOffset, mv: MotionVector
......@@ -1160,7 +1193,7 @@ impl PredictionMode {
};
if !is_compound {
if let Some(ref rec) = fi.rec_buffer.frames[fi.ref_frames[ref_frames[0] - LAST_FRAME] as usize] {
if let Some(ref rec) = fi.rec_buffer.frames[fi.ref_frames[ref_frames[0].to_index()] as usize] {
let (row_frac, col_frac, src) = get_params(&rec.frame.planes[p], po, mvs[0]);
put_8tap(
dst,
......@@ -1178,7 +1211,7 @@ impl PredictionMode {
let mut tmp: [AlignedArray<[i16; 128 * 128]>; 2] =
[UninitializedAlignedArray(), UninitializedAlignedArray()];
for i in 0..2 {
if let Some(ref rec) = fi.rec_buffer.frames[fi.ref_frames[ref_frames[i] - LAST_FRAME] as usize] {
if let Some(ref rec) = fi.rec_buffer.frames[fi.ref_frames[ref_frames[i].to_index()] as usize] {
let (row_frac, col_frac, src) = get_params(&rec.frame.planes[p], po, mvs[i]);
prep_8tap(
&mut tmp[i].array,
......
......@@ -26,6 +26,7 @@ use crate::luma_ac;
use crate::me::*;
use crate::motion_compensate;
use crate::partition::*;
use crate::partition::RefType::*;
use crate::plane::*;
use crate::predict::{RAV1E_INTRA_MODES, RAV1E_INTER_MODES_MINIMAL, RAV1E_INTER_COMPOUND_MODES};
use crate::Tune;
......@@ -84,7 +85,7 @@ pub struct RDOPartitionOutput {
pub pred_mode_luma: PredictionMode,
pub pred_mode_chroma: PredictionMode,
pub pred_cfl_params: CFLParams,
pub ref_frames: [usize; 2],
pub ref_frames: [RefType; 2],
pub mvs: [MotionVector; 2],
pub skip: bool,
pub tx_size: TxSize,
......@@ -361,7 +362,7 @@ fn compute_rd_cost<T: Pixel>(fi: &FrameInvariants<T>, rate: u32, distortion: u64
pub fn rdo_tx_size_type<T: Pixel>(
fi: &FrameInvariants<T>, fs: &mut FrameState<T>,
cw: &mut ContextWriter, bsize: BlockSize, bo: BlockOffset,
luma_mode: PredictionMode, ref_frames: [usize; 2], mvs: [MotionVector; 2], skip: bool
luma_mode: PredictionMode, ref_frames: [RefType; 2], mvs: [MotionVector; 2], skip: bool
) -> (TxSize, TxType) {
use crate::context::max_txsize_rect_lookup;
......@@ -428,7 +429,7 @@ struct EncodingSettings {
cfl_params: CFLParams,
skip: bool,
rd: f64,
ref_frames: [usize; 2],
ref_frames: [RefType; 2],
mvs: [MotionVector; 2],
tx_size: TxSize,
tx_type: TxType
......@@ -483,18 +484,18 @@ pub fn rdo_mode_decision<T: Pixel>(
};
if fi.frame_type == FrameType::INTER {
for i in LAST_FRAME..NONE_FRAME {
for i in ALL_INTER_REFS.iter() {
// Don't search LAST3 since it's used only for probs
if i == LAST3_FRAME { continue; }
if !ref_slot_set.contains(&fi.ref_frames[i - LAST_FRAME]) {
if fwdref == None && i < BWDREF_FRAME {
if *i == LAST3_FRAME { continue; }
if !ref_slot_set.contains(&fi.ref_frames[i.to_index()]) {
if fwdref == None && i.is_fwd_ref() {
fwdref = Some(ref_frames_set.len());
}
if bwdref == None && i >= BWDREF_FRAME {
if bwdref == None && i.is_bwd_ref() {
bwdref = Some(ref_frames_set.len());
}
ref_frames_set.push([i, NONE_FRAME]);
let slot_idx = fi.ref_frames[i - LAST_FRAME];
ref_frames_set.push([*i, NONE_FRAME]);
let slot_idx = fi.ref_frames[i.to_index()];
ref_slot_set.push(slot_idx);
}
}
......@@ -583,7 +584,7 @@ pub fn rdo_mode_decision<T: Pixel>(
cw: &mut ContextWriter,
best: &mut EncodingSettings,
mvs: [MotionVector; 2],
ref_frames: [usize; 2],
ref_frames: [RefType; 2],
mode_set_chroma: &[PredictionMode],
luma_mode_is_intra: bool,
mode_context: usize,
......@@ -948,7 +949,7 @@ pub fn rdo_cfl_alpha<T: Pixel>(
// RDO-based transform type decision
pub fn rdo_tx_type_decision<T: Pixel>(
fi: &FrameInvariants<T>, fs: &mut FrameState<T>, cw: &mut ContextWriter,
mode: PredictionMode, ref_frames: [usize; 2], mvs: [MotionVector; 2],
mode: PredictionMode, ref_frames: [RefType; 2], mvs: [MotionVector; 2],
bsize: BlockSize, bo: BlockOffset, tx_size: TxSize, tx_set: TxSet,
tx_types: &[TxType]
) -> (TxType, f64) {
......
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