Commit 861d7071 authored by Alex Converse's avatar Alex Converse

intrabc: Allow displacement to the left in the same superblock row

-9.1 BD-RATE PSNR on wikipedia_420 1st keyframe
-1.04 BD-RATE PSNR on twitch-1 set 1st keyframe

Change-Id: Ia9cc5b26bc587bcc2375d137768ac3af3238fe0c
parent 94d84461
......@@ -8999,6 +8999,7 @@ static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
const int w = block_size_wide[bsize];
const int h = block_size_high[bsize];
const int sb_row = mi_row / MAX_MIB_SIZE;
const int sb_col = mi_col / MAX_MIB_SIZE;
MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
MV_REFERENCE_FRAME ref_frame = INTRA_FRAME;
......@@ -9018,110 +9019,135 @@ static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
if (dv_ref.as_int == 0) av1_find_ref_dv(&dv_ref, mi_row, mi_col);
mbmi_ext->ref_mvs[INTRA_FRAME][0] = dv_ref;
const MvLimits tmp_mv_limits = x->mv_limits;
// TODO(aconverse@google.com): Handle same row DV.
x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
if (x->mv_limits.col_max < x->mv_limits.col_min ||
x->mv_limits.row_max < x->mv_limits.row_min) {
x->mv_limits = tmp_mv_limits;
return INT64_MAX;
}
struct buf_2d yv12_mb[MAX_MB_PLANE];
av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL);
for (int i = 0; i < MAX_MB_PLANE; ++i) {
xd->plane[i].pre[0] = yv12_mb[i];
}
int step_param = cpi->mv_step_param;
MV mvp_full = dv_ref.as_mv;
mvp_full.col >>= 3;
mvp_full.row >>= 3;
int sadpb = x->sadperbit16;
int cost_list[5];
int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
sadpb, cond_cost_list(cpi, cost_list),
&dv_ref.as_mv, INT_MAX, 1);
enum IntrabcMotionDirection {
IBC_MOTION_ABOVE,
IBC_MOTION_LEFT,
IBC_MOTION_DIRECTIONS
};
x->mv_limits = tmp_mv_limits;
if (bestsme == INT_MAX) return INT64_MAX;
mvp_full = x->best_mv.as_mv;
MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
if (mv_check_bounds(&x->mv_limits, &dv)) return INT64_MAX;
if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) return INT64_MAX;
MB_MODE_INFO *mbmi = &mi->mbmi;
MB_MODE_INFO best_mbmi = *mbmi;
RD_STATS best_rdcost = *rd_cost;
int best_skip = x->skip;
for (enum IntrabcMotionDirection dir = IBC_MOTION_ABOVE;
dir < IBC_MOTION_DIRECTIONS; ++dir) {
const MvLimits tmp_mv_limits = x->mv_limits;
switch (dir) {
case IBC_MOTION_ABOVE:
x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
break;
case IBC_MOTION_LEFT:
x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
x->mv_limits.col_max = (sb_col * MAX_MIB_SIZE - mi_col) * MI_SIZE - w;
// TODO(aconverse@google.com): Minimize the overlap between above and
// left areas.
x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
int bottom_coded_mi_edge =
AOMMIN((sb_row + 1) * MAX_MIB_SIZE, tile->mi_row_end);
x->mv_limits.row_max = (bottom_coded_mi_edge - mi_row) * MI_SIZE - h;
break;
default: assert(0);
}
assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
if (x->mv_limits.col_max < x->mv_limits.col_min ||
x->mv_limits.row_max < x->mv_limits.row_min) {
x->mv_limits = tmp_mv_limits;
continue;
}
int step_param = cpi->mv_step_param;
MV mvp_full = dv_ref.as_mv;
mvp_full.col >>= 3;
mvp_full.row >>= 3;
int sadpb = x->sadperbit16;
int cost_list[5];
int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
sadpb, cond_cost_list(cpi, cost_list),
&dv_ref.as_mv, INT_MAX, 1);
x->mv_limits = tmp_mv_limits;
if (bestsme == INT_MAX) continue;
mvp_full = x->best_mv.as_mv;
MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
if (mv_check_bounds(&x->mv_limits, &dv)) continue;
if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) continue;
#if CONFIG_PALETTE
memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
#endif
mbmi->use_intrabc = 1;
mbmi->mode = DC_PRED;
mbmi->uv_mode = DC_PRED;
mbmi->mv[0].as_mv = dv;
mbmi->use_intrabc = 1;
mbmi->mode = DC_PRED;
mbmi->uv_mode = DC_PRED;
mbmi->mv[0].as_mv = dv;
#if CONFIG_DUAL_FILTER
for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
#else
mbmi->interp_filter = BILINEAR;
mbmi->interp_filter = BILINEAR;
#endif
mbmi->skip = 0;
x->skip = 0;
av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
mbmi->skip = 0;
x->skip = 0;
av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
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(INTRABC_PROB, 1);
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(INTRABC_PROB, 1);
RD_STATS rd_stats, rd_stats_uv;
av1_subtract_plane(x, bsize, 0);
super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
RD_STATS rd_stats, rd_stats_uv;
av1_subtract_plane(x, bsize, 0);
super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
#if CONFIG_RD_DEBUG
mbmi->rd_stats = rd_stats;
mbmi->rd_stats = rd_stats;
#endif
const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
RD_STATS rdc_noskip;
av1_init_rd_stats(&rdc_noskip);
rdc_noskip.rate =
rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
rdc_noskip.dist = rd_stats.dist;
rdc_noskip.rdcost =
RDCOST(x->rdmult, x->rddiv, rdc_noskip.rate, rdc_noskip.dist);
if (rdc_noskip.rdcost < best_rd) {
best_rd = rdc_noskip.rdcost;
best_mbmi = *mbmi;
best_skip = x->skip;
best_rdcost = rdc_noskip;
}
x->skip = 1;
mbmi->skip = 1;
RD_STATS rdc_skip;
av1_init_rd_stats(&rdc_skip);
rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
rdc_skip.dist = rd_stats.sse;
rdc_skip.rdcost = RDCOST(x->rdmult, x->rddiv, rdc_skip.rate, rdc_skip.dist);
if (rdc_skip.rdcost < best_rd) {
best_rd = rdc_skip.rdcost;
best_mbmi = *mbmi;
best_skip = x->skip;
best_rdcost = rdc_skip;
const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
RD_STATS rdc_noskip;
av1_init_rd_stats(&rdc_noskip);
rdc_noskip.rate =
rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
rdc_noskip.dist = rd_stats.dist;
rdc_noskip.rdcost =
RDCOST(x->rdmult, x->rddiv, rdc_noskip.rate, rdc_noskip.dist);
if (rdc_noskip.rdcost < best_rd) {
best_rd = rdc_noskip.rdcost;
best_mbmi = *mbmi;
best_skip = x->skip;
best_rdcost = rdc_noskip;
}
x->skip = 1;
mbmi->skip = 1;
RD_STATS rdc_skip;
av1_init_rd_stats(&rdc_skip);
rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
rdc_skip.dist = rd_stats.sse;
rdc_skip.rdcost = RDCOST(x->rdmult, x->rddiv, rdc_skip.rate, rdc_skip.dist);
if (rdc_skip.rdcost < best_rd) {
best_rd = rdc_skip.rdcost;
best_mbmi = *mbmi;
best_skip = x->skip;
best_rdcost = rdc_skip;
}
}
*mbmi = best_mbmi;
*rd_cost = best_rdcost;
......
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