Commit 64463e74 authored by Hui Su's avatar Hui Su
Browse files

intrabc: control reference areas

Change-Id: I853a0e4b5fc7e7b5c1745b401214ef71b65aad60
parent 7a144cd6
......@@ -438,8 +438,11 @@ static INLINE void av1_find_ref_dv(int_mv *ref_dv, int mi_row, int mi_col) {
}
}
static INLINE int is_dv_valid(const MV dv, const TileInfo *const tile,
int mi_row, int mi_col, BLOCK_SIZE bsize) {
#define INTRABC_DELAY 0 // Writing back delay in units of super-block.
#define USE_WAVE_FRONT 0 // Use only top left area of frame for reference.
static INLINE int av1_is_dv_valid(const MV dv, const TileInfo *const tile,
int mi_row, int mi_col, BLOCK_SIZE bsize,
int mib_size_log2) {
const int bw = block_size_wide[bsize];
const int bh = block_size_high[bsize];
const int SCALE_PX_TO_MV = 8;
......@@ -461,17 +464,26 @@ static INLINE int is_dv_valid(const MV dv, const TileInfo *const tile,
const int src_right_edge = (mi_col * MI_SIZE + bw) * SCALE_PX_TO_MV + dv.col;
const int tile_right_edge = tile->mi_col_end * MI_SIZE * SCALE_PX_TO_MV;
if (src_right_edge > tile_right_edge) return 0;
// Is the bottom right within an already coded SB?
const int active_sb_top_edge =
(mi_row & ~MAX_MIB_MASK) * MI_SIZE * SCALE_PX_TO_MV;
const int active_sb_bottom_edge =
((mi_row & ~MAX_MIB_MASK) + MAX_MIB_SIZE) * MI_SIZE * SCALE_PX_TO_MV;
const int active_sb_left_edge =
(mi_col & ~MAX_MIB_MASK) * MI_SIZE * SCALE_PX_TO_MV;
if (src_bottom_edge > active_sb_bottom_edge) return 0;
if (src_bottom_edge > active_sb_top_edge &&
src_right_edge > active_sb_left_edge)
// Is the bottom right within an already coded SB? Also consider additional
// constraints to facilitate HW decoder.
const int max_mib_size = 1 << mib_size_log2;
const int active_sb_row = mi_row >> mib_size_log2;
const int active_sb_col = mi_col >> mib_size_log2;
const int sb_size = max_mib_size * MI_SIZE;
const int src_sb_row = ((src_bottom_edge >> 3) - 1) / sb_size;
const int src_sb_col = ((src_right_edge >> 3) - 1) / sb_size;
#if USE_WAVE_FRONT
if (src_sb_row > active_sb_row ||
src_sb_col >=
active_sb_col - INTRABC_DELAY + 2 * (active_sb_row - src_sb_row))
return 0;
#else
if (src_sb_row > active_sb_row ||
(src_sb_row == active_sb_row &&
src_sb_col >= active_sb_col - INTRABC_DELAY))
return 0;
#endif
return 1;
}
#endif // CONFIG_INTRABC
......
......@@ -997,7 +997,8 @@ static INLINE int assign_dv(AV1_COMMON *cm, MACROBLOCKD *xd, int_mv *mv,
mv->as_mv.col = (mv->as_mv.col >> 3) << 3;
mv->as_mv.row = (mv->as_mv.row >> 3) << 3;
int valid = is_mv_valid(&mv->as_mv) &&
is_dv_valid(mv->as_mv, &xd->tile, mi_row, mi_col, bsize);
av1_is_dv_valid(mv->as_mv, &xd->tile, mi_row, mi_col, bsize,
cm->mib_size_log2);
return valid;
}
#endif // CONFIG_INTRABC
......
......@@ -2699,21 +2699,28 @@ int av1_full_pixel_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
break;
}
#if CONFIG_INTRABC
MACROBLOCKD *const xd = &x->e_mbd;
const TileInfo *tile = &xd->tile;
const int mi_col = x_pos / MI_SIZE;
const int mi_row = y_pos / MI_SIZE;
#endif // CONFIG_INTRABC
Iterator iterator =
av1_hash_get_first_iterator(ref_frame_hash, hash_value1);
for (i = 0; i < count; i++, iterator_increment(&iterator)) {
block_hash ref_block_hash = *(block_hash *)(iterator_get(&iterator));
if (hash_value2 == ref_block_hash.hash_value2) {
// for intra, make sure the prediction is from valid area
// not predict from current block.
// TODO(roger): check if the constrain is necessary
if (intra &&
ref_block_hash.y + block_height >
((y_pos >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2) &&
ref_block_hash.x + block_width >
((x_pos >> MAX_SB_SIZE_LOG2) << MAX_SB_SIZE_LOG2)) {
continue;
// for intra, make sure the prediction is from valid area
// not predict from current block.
#if CONFIG_INTRABC
if (intra) {
const MV dv = { 8 * (ref_block_hash.y - y_pos),
8 * (ref_block_hash.x - x_pos) };
if (!av1_is_dv_valid(dv, tile, mi_row, mi_col, bsize,
cpi->common.mib_size_log2))
continue;
}
#endif // CONFIG_INTRABC
int refCost =
abs(ref_block_hash.x - x_pos) + abs(ref_block_hash.y - y_pos);
add_to_sort_table(block_hashes, costs, &existing,
......
......@@ -8856,7 +8856,8 @@ static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
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 (!av1_is_dv_valid(dv, tile, mi_row, mi_col, bsize, cm->mib_size_log2))
continue;
// DV should not have sub-pel.
assert((dv.col & 7) == 0);
......
......@@ -147,10 +147,10 @@ TEST(IntrabcTest, DvValidation) {
tile.mi_col_end = tile.mi_col_start + kTileMaxMibWidth * MAX_MIB_SIZE;
for (int i = 0; i < static_cast<int>(GTEST_ARRAY_SIZE_(kDvCases)); ++i) {
EXPECT_EQ(kDvCases[i].valid,
is_dv_valid(kDvCases[i].dv, &tile,
tile.mi_row_start + kDvCases[i].mi_row_offset,
tile.mi_col_start + kDvCases[i].mi_col_offset,
kDvCases[i].bsize))
av1_is_dv_valid(kDvCases[i].dv, &tile,
tile.mi_row_start + kDvCases[i].mi_row_offset,
tile.mi_col_start + kDvCases[i].mi_col_offset,
kDvCases[i].bsize, MAX_MIB_SIZE_LOG2))
<< "DvCases[" << i << "]";
}
}
......
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