Pack MVCost variables in MACROBLOCK to its own struct
BUG=aomedia:2618
Change-Id: I3d0e401d9ba504ab83f897fdb3b7ccac4cc839c0
diff --git a/av1/encoder/av1_quantize.c b/av1/encoder/av1_quantize.c
index 569784a..390124f 100644
--- a/av1/encoder/av1_quantize.c
+++ b/av1/encoder/av1_quantize.c
@@ -729,9 +729,9 @@
x->skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
x->qindex = qindex;
- set_error_per_bit(x, rdmult);
-
- av1_initialize_me_consts(cpi, x, qindex);
+ MvCostInfo *mv_cost_info = &x->mv_cost_info;
+ av1_set_error_per_bit(mv_cost_info, rdmult);
+ av1_set_sad_per_bit(cpi, mv_cost_info, qindex);
}
void av1_frame_init_quantizer(AV1_COMP *cpi) {
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 5a74567..826107a 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -209,13 +209,28 @@
uint8_t *tmp_best_mask_buf; // backup of the best segmentation mask
} CompoundTypeRdBuffers;
-enum {
- MV_COST_ENTROPY, // Use the entropy rate of the mv as the cost
- MV_COST_L1_LOWRES, // Use the l1 norm of the mv as the cost (<480p)
- MV_COST_L1_MIDRES, // Use the l1 norm of the mv as the cost (>=480p)
- MV_COST_L1_HDRES, // Use the l1 norm of the mv as the cost (>=720p)
- MV_COST_NONE // Use 0 as as cost irrespective of the current mv
-} UENUM1BYTE(MV_COST_TYPE);
+typedef struct {
+ // A multiplier that converts mv cost to l2 error.
+ int errorperbit;
+ // A multiplier that converts mv cost to l1 error.
+ int sadperbit;
+
+ int nmv_joint_cost[MV_JOINTS];
+
+ // Below are the entropy costs needed to encode a given mv.
+ // nmv_costs_(hp_)alloc are two arrays that holds the memory
+ // for holding the mv cost. But since the motion vectors can be negative, we
+ // shift them to the middle and store the resulting pointer in nmvcost(_hp)
+ // for easier referencing. Finally, nmv_cost_stack points to the nmvcost array
+ // with the mv precision we are currently working with. In essence, only
+ // mv_cost_stack is needed for motion search, the other can be considered
+ // private.
+ int nmv_cost_alloc[2][MV_VALS];
+ int nmv_cost_hp_alloc[2][MV_VALS];
+ int *nmv_cost[2];
+ int *nmv_cost_hp[2];
+ int **mv_cost_stack;
+} MvCostInfo;
struct inter_modes_info;
typedef struct macroblock MACROBLOCK;
@@ -252,12 +267,6 @@
int skip_block;
int qindex;
- // The equivalent error at the current rdmult of one whole bit (not one
- // bitcost unit).
- int errorperbit;
- // The equivalend SAD error of one (whole) bit at the current quantizer
- // for large blocks.
- int sadperbit;
int rdmult;
int mb_energy;
int sb_energy_level;
@@ -279,13 +288,6 @@
int pred_mv_sad[REF_FRAMES];
int best_pred_mv_sad;
- int nmv_vec_cost[MV_JOINTS];
- int nmv_costs[2][MV_VALS];
- int nmv_costs_hp[2][MV_VALS];
- int *nmvcost[2];
- int *nmvcost_hp[2];
- int **mv_cost_stack;
-
int32_t *wsrc_buf;
int32_t *mask_buf;
uint8_t *above_pred_buf;
@@ -314,6 +316,9 @@
// from extending outside the UMV borders
FullMvLimits mv_limits;
+ // Stores the entropy cost needed to encode a motion vector.
+ MvCostInfo mv_cost_info;
+
uint8_t blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
uint8_t tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
@@ -466,9 +471,6 @@
[INTER_REFS_PER_FRAME];
int cost_stride;
- // The type of mv cost used during motion search
- MV_COST_TYPE mv_cost_type;
-
uint8_t search_ref_frame[REF_FRAMES];
#if CONFIG_AV1_HIGHBITDEPTH
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 6fd73e7..429405d 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -246,7 +246,7 @@
}
static AOM_INLINE void set_ssim_rdmult(const AV1_COMP *const cpi,
- MACROBLOCK *const x,
+ MvCostInfo *const mv_cost_info,
const BLOCK_SIZE bsize, const int mi_row,
const int mi_col, int *const rdmult) {
const AV1_COMMON *const cm = &cpi->common;
@@ -278,7 +278,7 @@
*rdmult = (int)((double)(*rdmult) * geom_mean_of_scale + 0.5);
*rdmult = AOMMAX(*rdmult, 0);
- set_error_per_bit(x, *rdmult);
+ av1_set_error_per_bit(mv_cost_info, *rdmult);
aom_clear_system_state();
}
@@ -321,7 +321,7 @@
geom_mean_of_scale = exp(geom_mean_of_scale / base_block_count);
int rdmult = (int)((double)orig_rdmult * geom_mean_of_scale + 0.5);
rdmult = AOMMAX(rdmult, 0);
- set_error_per_bit(x, rdmult);
+ av1_set_error_per_bit(&x->mv_cost_info, rdmult);
aom_clear_system_state();
if (bsize == cm->seq_params.sb_size) {
const int rdmult_sb = set_deltaq_rdmult(cpi, xd);
@@ -374,7 +374,7 @@
}
if (cpi->oxcf.tuning == AOM_TUNE_SSIM) {
- set_ssim_rdmult(cpi, x, bsize, mi_row, mi_col, &x->rdmult);
+ set_ssim_rdmult(cpi, &x->mv_cost_info, bsize, mi_row, mi_col, &x->rdmult);
}
#if CONFIG_TUNE_VMAF
if (cpi->oxcf.tuning == AOM_TUNE_VMAF_WITHOUT_PREPROCESSING ||
@@ -821,7 +821,7 @@
const int orig_rdmult = x->rdmult;
setup_block_rdmult(cpi, x, mi_row, mi_col, bsize, aq_mode, mbmi);
// Set error per bit for current rdmult
- set_error_per_bit(x, x->rdmult);
+ av1_set_error_per_bit(&x->mv_cost_info, x->rdmult);
av1_rd_cost_update(x->rdmult, &best_rd);
// Find best coding mode & reconstruct the MB so it is available
@@ -4986,7 +4986,7 @@
mi_col != tile_info->mi_col_start)
break;
av1_fill_mv_costs(xd->tile_ctx, cm->features.cur_frame_force_integer_mv,
- cm->features.allow_high_precision_mv, x);
+ cm->features.allow_high_precision_mv, &x->mv_cost_info);
break;
default: assert(0);
}
@@ -5898,7 +5898,7 @@
av1_frame_init_quantizer(cpi);
av1_initialize_rd_consts(cpi);
- av1_initialize_me_consts(cpi, x, quant_params->base_qindex);
+ av1_set_sad_per_bit(cpi, &x->mv_cost_info, quant_params->base_qindex);
init_encode_frame_mb_context(cpi);
set_default_interp_skip_flags(cm, &cpi->interp_search_flags);
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 706c24d..41331f4 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -219,7 +219,6 @@
FULLPEL_MV start_mv = get_fullmv_from_mv(ref_mv);
int tmp_err;
const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
- aom_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
const int new_mv_mode_penalty = NEW_MV_MODE_PENALTY;
const int sr = get_search_range(&cpi->initial_dimensions);
const int step_param = 3 + sr;
@@ -237,7 +236,10 @@
&this_best_mv, NULL);
if (tmp_err < INT_MAX) {
- tmp_err = av1_get_mvpred_sse(x, &this_best_mv, ref_mv, &v_fn_ptr) +
+ aom_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
+ const MSBuffers *ms_buffers = &ms_params.ms_buffers;
+ tmp_err = av1_get_mvpred_sse(&ms_params.mv_cost_params, this_best_mv,
+ &v_fn_ptr, ms_buffers->src, ms_buffers->ref) +
new_mv_mode_penalty;
}
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c
index 424c162..13fa807 100644
--- a/av1/encoder/mcomp.c
+++ b/av1/encoder/mcomp.c
@@ -33,15 +33,16 @@
#include "av1/encoder/reconinter_enc.h"
static INLINE void init_mv_cost_params(MV_COST_PARAMS *mv_cost_params,
- const MACROBLOCK *x, const MV *ref_mv) {
+ const MvCostInfo *mv_cost_info,
+ const MV *ref_mv) {
mv_cost_params->ref_mv = ref_mv;
mv_cost_params->full_ref_mv = get_fullmv_from_mv(ref_mv);
- mv_cost_params->error_per_bit = x->errorperbit;
- mv_cost_params->sad_per_bit = x->sadperbit;
- mv_cost_params->mvjcost = x->nmv_vec_cost;
- mv_cost_params->mvcost[0] = x->mv_cost_stack[0];
- mv_cost_params->mvcost[1] = x->mv_cost_stack[1];
- mv_cost_params->mv_cost_type = x->mv_cost_type;
+ mv_cost_params->mv_cost_type = MV_COST_ENTROPY;
+ mv_cost_params->error_per_bit = mv_cost_info->errorperbit;
+ mv_cost_params->sad_per_bit = mv_cost_info->sadperbit;
+ mv_cost_params->mvjcost = mv_cost_info->nmv_joint_cost;
+ mv_cost_params->mvcost[0] = mv_cost_info->mv_cost_stack[0];
+ mv_cost_params->mvcost[1] = mv_cost_info->mv_cost_stack[1];
}
static INLINE void init_ms_buffers(MSBuffers *ms_buffers, const MACROBLOCK *x) {
@@ -84,7 +85,7 @@
av1_set_mv_search_range(&ms_params->mv_limits, ref_mv);
// Mvcost params
- init_mv_cost_params(&ms_params->mv_cost_params, x, ref_mv);
+ init_mv_cost_params(&ms_params->mv_cost_params, &x->mv_cost_info, ref_mv);
}
void av1_make_default_subpel_ms_params(SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
@@ -101,7 +102,7 @@
av1_set_subpel_mv_search_range(&ms_params->mv_limits, &x->mv_limits, ref_mv);
// Mvcost params
- init_mv_cost_params(&ms_params->mv_cost_params, x, ref_mv);
+ init_mv_cost_params(&ms_params->mv_cost_params, &x->mv_cost_info, ref_mv);
// Subpel variance params
ms_params->var_params.vfp = &cpi->fn_ptr[bsize];
@@ -3385,22 +3386,18 @@
// =============================================================================
// Public cost function: mv_cost + pred error
// =============================================================================
-int av1_get_mvpred_sse(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
- const MV *ref_mv, const aom_variance_fn_ptr_t *vfp) {
- const MACROBLOCKD *const xd = &x->e_mbd;
- const struct buf_2d *const what = &x->plane[0].src;
- const struct buf_2d *const in_what = &xd->plane[0].pre[0];
- const MV mv = get_mv_from_fullmv(best_mv);
- const MV_COST_TYPE mv_cost_type = x->mv_cost_type;
+int av1_get_mvpred_sse(const MV_COST_PARAMS *mv_cost_params,
+ const FULLPEL_MV best_mv,
+ const aom_variance_fn_ptr_t *vfp,
+ const struct buf_2d *src, const struct buf_2d *pre) {
+ const MV mv = get_mv_from_fullmv(&best_mv);
unsigned int sse, var;
- var = vfp->vf(what->buf, what->stride, get_buf_from_fullmv(in_what, best_mv),
- in_what->stride, &sse);
+ var = vfp->vf(src->buf, src->stride, get_buf_from_fullmv(pre, &best_mv),
+ pre->stride, &sse);
(void)var;
- return sse + mv_err_cost(&mv, ref_mv, x->nmv_vec_cost,
- CONVERT_TO_CONST_MVCOST(x->mv_cost_stack),
- x->errorperbit, mv_cost_type);
+ return sse + mv_err_cost_(&mv, mv_cost_params);
}
static INLINE int get_mvpred_av_var(const MV_COST_PARAMS *mv_cost_params,
@@ -3409,13 +3406,11 @@
const aom_variance_fn_ptr_t *vfp,
const struct buf_2d *src,
const struct buf_2d *pre) {
- const struct buf_2d *const what = src;
- const struct buf_2d *const in_what = pre;
const MV mv = get_mv_from_fullmv(&best_mv);
unsigned int unused;
- return vfp->svaf(get_buf_from_fullmv(in_what, &best_mv), in_what->stride, 0,
- 0, what->buf, what->stride, &unused, second_pred) +
+ return vfp->svaf(get_buf_from_fullmv(pre, &best_mv), pre->stride, 0, 0,
+ src->buf, src->stride, &unused, second_pred) +
mv_err_cost_(&mv, mv_cost_params);
}
@@ -3424,14 +3419,12 @@
const uint8_t *second_pred, const uint8_t *mask, int mask_stride,
int invert_mask, const aom_variance_fn_ptr_t *vfp, const struct buf_2d *src,
const struct buf_2d *pre) {
- const struct buf_2d *const what = src;
- const struct buf_2d *const in_what = pre;
const MV mv = get_mv_from_fullmv(&best_mv);
unsigned int unused;
- return vfp->msvf(what->buf, what->stride, 0, 0,
- get_buf_from_fullmv(in_what, &best_mv), in_what->stride,
- second_pred, mask, mask_stride, invert_mask, &unused) +
+ return vfp->msvf(src->buf, src->stride, 0, 0,
+ get_buf_from_fullmv(pre, &best_mv), pre->stride, second_pred,
+ mask, mask_stride, invert_mask, &unused) +
mv_err_cost_(&mv, mv_cost_params);
}
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h
index 7d1b3f0..b3db173 100644
--- a/av1/encoder/mcomp.h
+++ b/av1/encoder/mcomp.h
@@ -60,21 +60,32 @@
// =============================================================================
// Cost functions
// =============================================================================
+
+enum {
+ MV_COST_ENTROPY, // Use the entropy rate of the mv as the cost
+ MV_COST_L1_LOWRES, // Use the l1 norm of the mv as the cost (<480p)
+ MV_COST_L1_MIDRES, // Use the l1 norm of the mv as the cost (>=480p)
+ MV_COST_L1_HDRES, // Use the l1 norm of the mv as the cost (>=720p)
+ MV_COST_NONE // Use 0 as as cost irrespective of the current mv
+} UENUM1BYTE(MV_COST_TYPE);
+
typedef struct {
const MV *ref_mv;
FULLPEL_MV full_ref_mv;
+ MV_COST_TYPE mv_cost_type;
const int *mvjcost;
const int *mvcost[2];
int error_per_bit;
int sad_per_bit;
- MV_COST_TYPE mv_cost_type;
} MV_COST_PARAMS;
int av1_mv_bit_cost(const MV *mv, const MV *ref_mv, const int *mvjcost,
int *mvcost[2], int weight);
-int av1_get_mvpred_sse(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
- const MV *ref_mv, const aom_variance_fn_ptr_t *vfp);
+int av1_get_mvpred_sse(const MV_COST_PARAMS *mv_cost_params,
+ const FULLPEL_MV best_mv,
+ const aom_variance_fn_ptr_t *vfp,
+ const struct buf_2d *src, const struct buf_2d *pre);
int av1_get_mvpred_compound_var(const MV_COST_PARAMS *ms_params,
const FULLPEL_MV best_mv,
const uint8_t *second_pred, const uint8_t *mask,
diff --git a/av1/encoder/motion_search_facade.c b/av1/encoder/motion_search_facade.c
index 83e8318..92aae90 100644
--- a/av1/encoder/motion_search_facade.c
+++ b/av1/encoder/motion_search_facade.c
@@ -60,6 +60,7 @@
av1_get_scaled_ref_frame(cpi, ref);
const int mi_row = xd->mi_row;
const int mi_col = xd->mi_col;
+ const MvCostInfo *mv_cost_info = &x->mv_cost_info;
if (scaled_ref_frame) {
// Swap out the reference frame for a version that's been scaled to
@@ -270,8 +271,8 @@
this_mv.as_mv = get_mv_from_fullmv(&best_mv->as_fullmv);
const int ref_mv_idx = mbmi->ref_mv_idx;
const int this_mv_rate =
- av1_mv_bit_cost(&this_mv.as_mv, &ref_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ av1_mv_bit_cost(&this_mv.as_mv, &ref_mv, mv_cost_info->nmv_joint_cost,
+ mv_cost_info->mv_cost_stack, MV_COST_WEIGHT);
mode_info[ref_mv_idx].full_search_mv.as_int = this_mv.as_int;
mode_info[ref_mv_idx].full_mv_rate = this_mv_rate;
@@ -347,8 +348,9 @@
default: assert(0 && "Invalid motion mode!\n");
}
}
- *rate_mv = av1_mv_bit_cost(&best_mv->as_mv, &ref_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ *rate_mv =
+ av1_mv_bit_cost(&best_mv->as_mv, &ref_mv, mv_cost_info->nmv_joint_cost,
+ mv_cost_info->mv_cost_stack, MV_COST_WEIGHT);
if (cpi->sf.mv_sf.adaptive_motion_search &&
mbmi->motion_mode == SIMPLE_TRANSLATION)
@@ -370,6 +372,7 @@
assert(has_second_ref(mbmi));
const int_mv init_mv[2] = { cur_mv[0], cur_mv[1] };
const int refs[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
+ const MvCostInfo *mv_cost_info = &x->mv_cost_info;
int_mv ref_mv[2];
int ite, ref;
@@ -525,9 +528,9 @@
for (ref = 0; ref < 2; ++ref) {
const int_mv curr_ref_mv = av1_get_ref_mv(x, ref);
- *rate_mv +=
- av1_mv_bit_cost(&cur_mv[ref].as_mv, &curr_ref_mv.as_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ *rate_mv += av1_mv_bit_cost(&cur_mv[ref].as_mv, &curr_ref_mv.as_mv,
+ mv_cost_info->nmv_joint_cost,
+ mv_cost_info->mv_cost_stack, MV_COST_WEIGHT);
}
}
@@ -545,6 +548,7 @@
const int ref = mbmi->ref_frame[ref_idx];
const int_mv ref_mv = av1_get_ref_mv(x, ref_idx);
struct macroblockd_plane *const pd = &xd->plane[0];
+ const MvCostInfo *mv_cost_info = &x->mv_cost_info;
struct buf_2d backup_yv12[MAX_MB_PLANE];
const YV12_BUFFER_CONFIG *const scaled_ref_frame =
@@ -632,8 +636,9 @@
*rate_mv = 0;
- *rate_mv += av1_mv_bit_cost(this_mv, &ref_mv.as_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ *rate_mv +=
+ av1_mv_bit_cost(this_mv, &ref_mv.as_mv, mv_cost_info->nmv_joint_cost,
+ mv_cost_info->mv_cost_stack, MV_COST_WEIGHT);
}
static AOM_INLINE void build_second_inter_pred(const AV1_COMP *cpi,
diff --git a/av1/encoder/mv_prec.h b/av1/encoder/mv_prec.h
index 8df8b96..9e31c74 100644
--- a/av1/encoder/mv_prec.h
+++ b/av1/encoder/mv_prec.h
@@ -32,15 +32,16 @@
static AOM_INLINE void av1_set_high_precision_mv(
AV1_COMP *cpi, int allow_high_precision_mv,
int cur_frame_force_integer_mv) {
- MACROBLOCK *const x = &cpi->td.mb;
+ MvCostInfo *const mv_cost_info = &cpi->td.mb.mv_cost_info;
const int copy_hp = cpi->common.features.allow_high_precision_mv =
allow_high_precision_mv && !cur_frame_force_integer_mv;
- x->nmvcost[0] = &x->nmv_costs[0][MV_MAX];
- x->nmvcost[1] = &x->nmv_costs[1][MV_MAX];
- x->nmvcost_hp[0] = &x->nmv_costs_hp[0][MV_MAX];
- x->nmvcost_hp[1] = &x->nmv_costs_hp[1][MV_MAX];
- int *(*src)[2] = copy_hp ? &x->nmvcost_hp : &x->nmvcost;
- x->mv_cost_stack = *src;
+
+ mv_cost_info->nmv_cost[0] = &mv_cost_info->nmv_cost_alloc[0][MV_MAX];
+ mv_cost_info->nmv_cost[1] = &mv_cost_info->nmv_cost_alloc[1][MV_MAX];
+ mv_cost_info->nmv_cost_hp[0] = &mv_cost_info->nmv_cost_hp_alloc[0][MV_MAX];
+ mv_cost_info->nmv_cost_hp[1] = &mv_cost_info->nmv_cost_hp_alloc[1][MV_MAX];
+ mv_cost_info->mv_cost_stack =
+ copy_hp ? mv_cost_info->nmv_cost_hp : mv_cost_info->nmv_cost;
}
void av1_pick_and_set_high_precision_mv(AV1_COMP *cpi, int qindex);
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 43b1928..5564f0d 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -167,8 +167,8 @@
// calculate the bit cost on motion vector
MV mvp_full = get_mv_from_fullmv(&tmp_mv->as_fullmv);
- *rate_mv = av1_mv_bit_cost(&mvp_full, &ref_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ *rate_mv = av1_mv_bit_cost(&mvp_full, &ref_mv, x->mv_cost_info.nmv_joint_cost,
+ x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
// TODO(kyslov) Account for Rate Mode!
rv = !(RDCOST(x->rdmult, (*rate_mv), 0) > best_rd_sofar);
@@ -182,8 +182,9 @@
xd, cm, &ms_params, subpel_start_mv, &tmp_mv->as_mv, &dis,
&x->pred_sse[ref], NULL);
- *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ *rate_mv =
+ av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->mv_cost_info.nmv_joint_cost,
+ x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
}
if (scaled_ref_frame) {
@@ -222,9 +223,9 @@
best_mv.as_mv.col >>= 3;
MV ref_mv = av1_get_ref_mv(x, 0).as_mv;
- *rate_mv =
- av1_mv_bit_cost(&frame_mv[NEWMV][ref_frame].as_mv, &ref_mv,
- x->nmv_vec_cost, x->mv_cost_stack, MV_COST_WEIGHT);
+ *rate_mv = av1_mv_bit_cost(&frame_mv[NEWMV][ref_frame].as_mv, &ref_mv,
+ x->mv_cost_info.nmv_joint_cost,
+ x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
frame_mv[NEWMV][ref_frame].as_mv.row >>= 3;
frame_mv[NEWMV][ref_frame].as_mv.col >>= 3;
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index e48c771..81a77a2 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -437,11 +437,16 @@
return AOMMAX((int)(pow(q, RD_THRESH_POW) * 5.12), 8);
}
-void av1_initialize_me_consts(const AV1_COMP *cpi, MACROBLOCK *x, int qindex) {
+void av1_set_sad_per_bit(const AV1_COMP *cpi, MvCostInfo *mv_cost_info,
+ int qindex) {
switch (cpi->common.seq_params.bit_depth) {
- case AOM_BITS_8: x->sadperbit = sad_per_bit_lut_8[qindex]; break;
- case AOM_BITS_10: x->sadperbit = sad_per_bit_lut_10[qindex]; break;
- case AOM_BITS_12: x->sadperbit = sad_per_bit_lut_12[qindex]; break;
+ case AOM_BITS_8: mv_cost_info->sadperbit = sad_per_bit_lut_8[qindex]; break;
+ case AOM_BITS_10:
+ mv_cost_info->sadperbit = sad_per_bit_lut_10[qindex];
+ break;
+ case AOM_BITS_12:
+ mv_cost_info->sadperbit = sad_per_bit_lut_12[qindex];
+ break;
default:
assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
}
@@ -565,20 +570,21 @@
}
void av1_fill_mv_costs(const FRAME_CONTEXT *fc, int integer_mv, int usehp,
- MACROBLOCK *x) {
- x->nmvcost[0] = &x->nmv_costs[0][MV_MAX];
- x->nmvcost[1] = &x->nmv_costs[1][MV_MAX];
- x->nmvcost_hp[0] = &x->nmv_costs_hp[0][MV_MAX];
- x->nmvcost_hp[1] = &x->nmv_costs_hp[1][MV_MAX];
+ MvCostInfo *mv_cost_info) {
+ mv_cost_info->nmv_cost[0] = &mv_cost_info->nmv_cost_alloc[0][MV_MAX];
+ mv_cost_info->nmv_cost[1] = &mv_cost_info->nmv_cost_alloc[1][MV_MAX];
+ mv_cost_info->nmv_cost_hp[0] = &mv_cost_info->nmv_cost_hp_alloc[0][MV_MAX];
+ mv_cost_info->nmv_cost_hp[1] = &mv_cost_info->nmv_cost_hp_alloc[1][MV_MAX];
if (integer_mv) {
- av1_build_nmv_cost_table(x->nmv_vec_cost, x->nmvcost, &fc->nmvc,
+ mv_cost_info->mv_cost_stack = (int **)&mv_cost_info->nmv_cost;
+ av1_build_nmv_cost_table(mv_cost_info->nmv_joint_cost,
+ mv_cost_info->mv_cost_stack, &fc->nmvc,
MV_SUBPEL_NONE);
- x->mv_cost_stack = (int **)&x->nmvcost;
} else {
- int *(*src)[2] = usehp ? &x->nmvcost_hp : &x->nmvcost;
- x->mv_cost_stack = *src;
- av1_build_nmv_cost_table(
- x->nmv_vec_cost, usehp ? x->nmvcost_hp : x->nmvcost, &fc->nmvc, usehp);
+ mv_cost_info->mv_cost_stack =
+ usehp ? mv_cost_info->nmv_cost_hp : mv_cost_info->nmv_cost;
+ av1_build_nmv_cost_table(mv_cost_info->nmv_joint_cost,
+ mv_cost_info->mv_cost_stack, &fc->nmvc, usehp);
}
}
@@ -586,13 +592,14 @@
AV1_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->td.mb;
RD_OPT *const rd = &cpi->rd;
+ MvCostInfo *mv_cost_info = &x->mv_cost_info;
aom_clear_system_state();
rd->RDMULT = av1_compute_rd_mult(
cpi, cm->quant_params.base_qindex + cm->quant_params.y_dc_delta_q);
- set_error_per_bit(x, rd->RDMULT);
+ av1_set_error_per_bit(mv_cost_info, rd->RDMULT);
set_block_thresholds(cm, rd);
@@ -600,7 +607,7 @@
cpi->oxcf.mv_cost_upd_freq != COST_UPD_OFF) ||
frame_is_intra_only(cm) || (cm->current_frame.frame_number & 0x07) == 1)
av1_fill_mv_costs(cm->fc, cm->features.cur_frame_force_integer_mv,
- cm->features.allow_high_precision_mv, x);
+ cm->features.allow_high_precision_mv, mv_cost_info);
if (!cpi->sf.rt_sf.use_nonrd_pick_mode && frame_is_intra_only(cm) &&
cm->features.allow_screen_content_tools &&
diff --git a/av1/encoder/rd.h b/av1/encoder/rd.h
index 1addbae..d56813e 100644
--- a/av1/encoder/rd.h
+++ b/av1/encoder/rd.h
@@ -231,8 +231,9 @@
void av1_initialize_rd_consts(struct AV1_COMP *cpi);
-void av1_initialize_me_consts(const struct AV1_COMP *cpi, MACROBLOCK *x,
- int qindex);
+// Sets the multiplier to convert mv cost to l1 error during motion search.
+void av1_set_sad_per_bit(const struct AV1_COMP *cpi, MvCostInfo *mv_cost_info,
+ int qindex);
void av1_model_rd_from_var_lapndz(int64_t var, unsigned int n,
unsigned int qstep, int *rate, int64_t *dist);
@@ -280,9 +281,9 @@
uint8_t *ref_y_buffer, int ref_y_stride, int ref_frame,
BLOCK_SIZE block_size);
-static INLINE void set_error_per_bit(MACROBLOCK *x, int rdmult) {
- x->errorperbit = rdmult >> RD_EPB_SHIFT;
- x->errorperbit += (x->errorperbit == 0);
+// Sets the multiplier to convert mv cost to l2 error during motion search.
+static INLINE void av1_set_error_per_bit(MvCostInfo *mv_cost_info, int rdmult) {
+ mv_cost_info->errorperbit = AOMMAX(rdmult >> RD_EPB_SHIFT, 1);
}
// Get the threshold for R-D optimization of coefficients depending upon mode
@@ -357,7 +358,7 @@
const int num_planes);
void av1_fill_mv_costs(const FRAME_CONTEXT *fc, int integer_mv, int usehp,
- MACROBLOCK *x);
+ MvCostInfo *mv_cost_info);
int av1_get_adaptive_rdmult(const struct AV1_COMP *cpi, double beta);
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 3c3fccd..9152ad5 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -1085,9 +1085,9 @@
*rate_mv = 0;
for (int i = 0; i < 2; ++i) {
const int_mv ref_mv = av1_get_ref_mv(x, i);
- *rate_mv +=
- av1_mv_bit_cost(&cur_mv[i].as_mv, &ref_mv.as_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ *rate_mv += av1_mv_bit_cost(
+ &cur_mv[i].as_mv, &ref_mv.as_mv, x->mv_cost_info.nmv_joint_cost,
+ x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
}
}
} else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
@@ -1103,9 +1103,9 @@
NULL, 0, rate_mv, 1);
} else {
const int_mv ref_mv = av1_get_ref_mv(x, 1);
- *rate_mv =
- av1_mv_bit_cost(&cur_mv[1].as_mv, &ref_mv.as_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ *rate_mv = av1_mv_bit_cost(
+ &cur_mv[1].as_mv, &ref_mv.as_mv, x->mv_cost_info.nmv_joint_cost,
+ x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
}
} else {
assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
@@ -1121,9 +1121,9 @@
NULL, 0, rate_mv, 0);
} else {
const int_mv ref_mv = av1_get_ref_mv(x, 0);
- *rate_mv =
- av1_mv_bit_cost(&cur_mv[0].as_mv, &ref_mv.as_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ *rate_mv = av1_mv_bit_cost(
+ &cur_mv[0].as_mv, &ref_mv.as_mv, x->mv_cost_info.nmv_joint_cost,
+ x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
}
}
} else {
@@ -1391,9 +1391,10 @@
// Keep the refined MV and WM parameters.
if (mv0.as_int != mbmi->mv[0].as_int) {
- tmp_rate_mv = av1_mv_bit_cost(&mbmi->mv[0].as_mv, &ref_mv.as_mv,
- x->nmv_vec_cost, x->mv_cost_stack,
- MV_COST_WEIGHT);
+ tmp_rate_mv =
+ av1_mv_bit_cost(&mbmi->mv[0].as_mv, &ref_mv.as_mv,
+ x->mv_cost_info.nmv_joint_cost,
+ x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
if (cpi->sf.mv_sf.adaptive_motion_search) {
x->pred_mv[mbmi->ref_frame[0]] = mbmi->mv[0].as_mv;
}
@@ -2390,8 +2391,9 @@
mode_info[i].rate_mv + mode_info[i].drl_cost;
const int_mv ref_mv = av1_get_ref_mv(x, 0);
this_rate_mv = av1_mv_bit_cost(
- &mode_info[i].mv.as_mv, &ref_mv.as_mv, x->nmv_vec_cost,
- x->mv_cost_stack, MV_COST_WEIGHT);
+ &mode_info[i].mv.as_mv, &ref_mv.as_mv,
+ x->mv_cost_info.nmv_joint_cost,
+ x->mv_cost_info.mv_cost_stack, MV_COST_WEIGHT);
const int this_cost = this_rate_mv + drl_cost;
if (compare_cost <= this_cost) {
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index 4b76a54..98ce7e4 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -91,7 +91,6 @@
MACROBLOCKD *const mbd = &mb->e_mbd;
const struct buf_2d ori_src_buf = mb->plane[0].src;
const struct buf_2d ori_pre_buf = mbd->plane[0].pre[0];
- const MV_COST_TYPE ori_mv_cost_type = mb->mv_cost_type;
// Parameters used for motion search.
FULLPEL_MOTION_SEARCH_PARAMS full_ms_params;
@@ -127,20 +126,18 @@
int_mv best_mv; // Searched motion vector.
int block_mse = INT_MAX;
MV block_mv = kZeroMv;
- mb->mv_cost_type = mv_cost_type;
av1_make_default_fullpel_ms_params(&full_ms_params, cpi, mb, block_size,
&baseline_mv, &ss_cfg,
/*fine_search_interval=*/0);
full_ms_params.run_mesh_search = 1;
full_ms_params.search_method = full_search_method;
+ full_ms_params.mv_cost_params.mv_cost_type = mv_cost_type;
+
av1_full_pixel_search(start_mv, &full_ms_params, step_param,
cond_cost_list(cpi, cost_list), &best_mv.as_fullmv,
NULL);
- // Since we are merely refining the result from full pixel search, we don't
- // need regularization for subpel search
- mb->mv_cost_type = MV_COST_NONE;
if (force_integer_mv == 1) { // Only do full search on the entire block.
const int mv_row = best_mv.as_mv.row;
const int mv_col = best_mv.as_mv.col;
@@ -157,6 +154,10 @@
&baseline_mv, cost_list);
ms_params.forced_stop = EIGHTH_PEL;
ms_params.var_params.subpel_search_type = subpel_search_type;
+ // Since we are merely refining the result from full pixel search, we don't
+ // need regularization for subpel search
+ ms_params.mv_cost_params.mv_cost_type = MV_COST_NONE;
+
MV subpel_start_mv = get_mv_from_fullmv(&best_mv.as_fullmv);
error = cpi->mv_search_params.find_fractional_mv_step(
&mb->e_mbd, &cpi->common, &ms_params, subpel_start_mv, &best_mv.as_mv,
@@ -177,24 +178,26 @@
const int offset = i * y_stride + j;
mb->plane[0].src.buf = frame_to_filter->y_buffer + y_offset + offset;
mbd->plane[0].pre[0].buf = ref_frame->y_buffer + y_offset + offset;
- mb->mv_cost_type = mv_cost_type;
av1_make_default_fullpel_ms_params(&full_ms_params, cpi, mb,
subblock_size, &baseline_mv, &ss_cfg,
/*fine_search_interval=*/0);
full_ms_params.run_mesh_search = 1;
full_ms_params.search_method = full_search_method;
+ full_ms_params.mv_cost_params.mv_cost_type = mv_cost_type;
+
av1_full_pixel_search(start_mv, &full_ms_params, step_param,
cond_cost_list(cpi, cost_list),
&best_mv.as_fullmv, NULL);
- // Since we are merely refining the result from full pixel search, we
- // don't need regularization for subpel search
- mb->mv_cost_type = MV_COST_NONE;
av1_make_default_subpel_ms_params(&ms_params, cpi, mb, subblock_size,
&baseline_mv, cost_list);
ms_params.forced_stop = EIGHTH_PEL;
ms_params.var_params.subpel_search_type = subpel_search_type;
+ // Since we are merely refining the result from full pixel search, we
+ // don't need regularization for subpel search
+ ms_params.mv_cost_params.mv_cost_type = MV_COST_NONE;
+
subpel_start_mv = get_mv_from_fullmv(&best_mv.as_fullmv);
error = cpi->mv_search_params.find_fractional_mv_step(
&mb->e_mbd, &cpi->common, &ms_params, subpel_start_mv,
@@ -209,7 +212,6 @@
// Restore input state.
mb->plane[0].src = ori_src_buf;
mbd->plane[0].pre[0] = ori_pre_buf;
- mb->mv_cost_type = ori_mv_cost_type;
// Make partition decision.
tf_determine_block_partition(block_mv, block_mse, subblock_mvs,
@@ -961,13 +963,14 @@
// TODO(yunqing): For INTNL_ARF_UPDATE type, the following me initialization
// is used somewhere unexpectedly. Should be resolved later.
- // Initialize errorperbit, sadperbit16 and sadperbit4.
+ // Initialize errorperbit and sadperbit
const int rdmult = av1_compute_rd_mult_based_on_qindex(cpi, TF_QINDEX);
- set_error_per_bit(&cpi->td.mb, rdmult);
- av1_initialize_me_consts(cpi, &cpi->td.mb, TF_QINDEX);
+ MvCostInfo *mv_cost_info = &cpi->td.mb.mv_cost_info;
+ av1_set_error_per_bit(mv_cost_info, rdmult);
+ av1_set_sad_per_bit(cpi, mv_cost_info, TF_QINDEX);
av1_fill_mv_costs(cpi->common.fc,
cpi->common.features.cur_frame_force_integer_mv,
- cpi->common.features.allow_high_precision_mv, &cpi->td.mb);
+ cpi->common.features.allow_high_precision_mv, mv_cost_info);
// Setup frame buffer for filtering.
YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = { NULL };
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index b63aada..471bcff 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -27,6 +27,7 @@
#include "av1/encoder/encoder.h"
#include "av1/encoder/encode_strategy.h"
#include "av1/encoder/hybrid_fwd_txfm.h"
+#include "av1/encoder/rd.h"
#include "av1/encoder/rdopt.h"
#include "av1/encoder/reconinter_enc.h"
#include "av1/encoder/tpl_model.h"
@@ -738,8 +739,9 @@
// Get rd multiplier set up.
rdmult = (int)av1_compute_rd_mult(cpi, base_qindex);
if (rdmult < 1) rdmult = 1;
- set_error_per_bit(x, rdmult);
- av1_initialize_me_consts(cpi, x, base_qindex);
+ MvCostInfo *mv_cost_info = &x->mv_cost_info;
+ av1_set_error_per_bit(mv_cost_info, rdmult);
+ av1_set_sad_per_bit(cpi, mv_cost_info, base_qindex);
tpl_frame->is_valid = 1;
diff --git a/av1/encoder/tune_vmaf.c b/av1/encoder/tune_vmaf.c
index 1527c7e..66bd07d 100644
--- a/av1/encoder/tune_vmaf.c
+++ b/av1/encoder/tune_vmaf.c
@@ -623,7 +623,7 @@
*rdmult = (int)((double)(*rdmult) * geom_mean_of_scale + 0.5);
*rdmult = AOMMAX(*rdmult, 0);
- set_error_per_bit(x, *rdmult);
+ av1_set_error_per_bit(&x->mv_cost_info, *rdmult);
aom_clear_system_state();
}