intrabc: Fix mode and MV cost
objective-1-fast 1st KF: -0.07 BDRATE-PSNR
twitch-1 1st KF: -0.04 BDRATE-PSNR
Change-Id: I089900514c40f3b8b77708dac2c8bfbce2f540ff
diff --git a/av1/encoder/encodemv.c b/av1/encoder/encodemv.c
index 19167d1..e1b515b 100644
--- a/av1/encoder/encodemv.c
+++ b/av1/encoder/encodemv.c
@@ -74,7 +74,7 @@
static void build_nmv_component_cost_table(int *mvcost,
const nmv_component *const mvcomp,
- int usehp) {
+ MvSubpelPrecision precision) {
int i, v;
int sign_cost[2], class_cost[MV_CLASSES], class0_cost[CLASS0_SIZE];
int bits_cost[MV_OFFSET_BITS][2];
@@ -94,7 +94,7 @@
av1_cost_tokens(class0_fp_cost[i], mvcomp->class0_fp[i], av1_mv_fp_tree);
av1_cost_tokens(fp_cost, mvcomp->fp, av1_mv_fp_tree);
- if (usehp) {
+ if (precision > MV_SUBPEL_LOW_PRECISION) {
class0_hp_cost[0] = av1_cost_zero(mvcomp->class0_hp);
class0_hp_cost[1] = av1_cost_one(mvcomp->class0_hp);
hp_cost[0] = av1_cost_zero(mvcomp->hp);
@@ -115,16 +115,21 @@
const int b = c + CLASS0_BITS - 1; /* number of bits */
for (i = 0; i < b; ++i) cost += bits_cost[i][((d >> i) & 1)];
}
- if (c == MV_CLASS_0) {
- cost += class0_fp_cost[d][f];
- } else {
- cost += fp_cost[f];
- }
- if (usehp) {
+#if CONFIG_INTRABC
+ if (precision > MV_SUBPEL_NONE)
+#endif // CONFIG_INTRABC
+ {
if (c == MV_CLASS_0) {
- cost += class0_hp_cost[e];
+ cost += class0_fp_cost[d][f];
} else {
- cost += hp_cost[e];
+ cost += fp_cost[f];
+ }
+ if (precision > MV_SUBPEL_LOW_PRECISION) {
+ if (c == MV_CLASS_0) {
+ cost += class0_hp_cost[e];
+ } else {
+ cost += hp_cost[e];
+ }
}
}
mvcost[v] = cost + sign_cost[0];
@@ -243,10 +248,11 @@
#endif // CONFIG_INTRABC
void av1_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
- const nmv_context *ctx, int usehp) {
+ const nmv_context *ctx,
+ MvSubpelPrecision precision) {
av1_cost_tokens(mvjoint, ctx->joints, av1_mv_joint_tree);
- build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], usehp);
- build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], usehp);
+ build_nmv_component_cost_table(mvcost[0], &ctx->comps[0], precision);
+ build_nmv_component_cost_table(mvcost[1], &ctx->comps[1], precision);
}
#if CONFIG_EXT_INTER
diff --git a/av1/encoder/encodemv.h b/av1/encoder/encodemv.h
index 6d44214..e32c1b9 100644
--- a/av1/encoder/encodemv.h
+++ b/av1/encoder/encodemv.h
@@ -27,7 +27,8 @@
nmv_context *mvctx, int usehp);
void av1_build_nmv_cost_table(int *mvjoint, int *mvcost[2],
- const nmv_context *mvctx, int usehp);
+ const nmv_context *mvctx,
+ MvSubpelPrecision precision);
void av1_update_mv_count(ThreadData *td);
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c
index 6320af1..a0cb1a4 100644
--- a/av1/encoder/rd.c
+++ b/av1/encoder/rd.c
@@ -367,6 +367,16 @@
x->mvcost = x->mv_cost_stack[0];
x->nmvjointcost = x->nmv_vec_cost[0];
+#if CONFIG_INTRABC
+ if (frame_is_intra_only(cm) && cm->allow_screen_content_tools &&
+ cpi->oxcf.pass != 1) {
+ av1_build_nmv_cost_table(
+ x->nmv_vec_cost[0],
+ cm->allow_high_precision_mv ? x->nmvcost_hp[0] : x->nmvcost[0],
+ &cm->fc->ndvc, MV_SUBPEL_NONE);
+ }
+#endif
+
if (cpi->oxcf.pass != 1) {
av1_fill_token_costs(x->token_costs, cm->fc->coef_probs);
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index b953d6d..396c0a0 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -8232,12 +8232,12 @@
x->skip = 0;
av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
+ assert(x->mvcost == x->mv_cost_stack[0]);
+ // TODO(aconverse@google.com): The full motion field defining discount
+ // in MV_COST_WEIGHT is too large. Explore other values.
int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, x->nmvjointcost,
- x->mvcost, MV_COST_WEIGHT);
- const PREDICTION_MODE A = av1_above_block_mode(mi, xd->above_mi, 0);
- const PREDICTION_MODE L = av1_left_block_mode(mi, xd->left_mi, 0);
- const int rate_mode = cpi->y_mode_costs[A][L][DC_PRED] +
- av1_cost_bit(ec_ctx->intrabc_prob, 1);
+ x->mvcost, MV_COST_WEIGHT_SUB);
+ const int rate_mode = av1_cost_bit(ec_ctx->intrabc_prob, 1);
RD_STATS rd_stats, rd_stats_uv;
av1_subtract_plane(x, bsize, 0);