Commit d797ea9e authored by Yunqing Wang's avatar Yunqing Wang

Refactor setup_ref_mv_list

This patch eliminates the is_inside() checking for each neighouring
block in scan_row_mbmi() and scan_col_mbmi(). Instead, in
setup_ref_mv_list(), find maximum above row_offset and left col_offset
for current block, and use them to decide which above rows and left
columns to search on. This patch doesn't change bitstream. No
noticeable speedup is seen.

Change-Id: Ic4ae74412605d86e9e675f86d23de3a69c04e8f3
parent 6e439653
......@@ -153,123 +153,81 @@ static uint8_t add_ref_mv_candidate(
}
static uint8_t scan_row_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, const int mi_col, int block,
const int mi_col, int block,
const MV_REFERENCE_FRAME rf[2], int row_offset,
CANDIDATE_MV *ref_mv_stack, uint8_t *refmv_count) {
const TileInfo *const tile = &xd->tile;
const int end_mi = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
int i;
uint8_t newmv_count = 0;
int col_offset = 0;
#if CONFIG_CB4X4
const int bsize = xd->mi[0]->mbmi.sb_type;
const int mi_width = mi_size_wide[bsize];
const int mi_col_offset =
((abs(row_offset) > 1) || (mi_width < mi_size_wide[BLOCK_8X8]))
? mi_size_wide[BLOCK_4X4]
: mi_size_wide[BLOCK_8X8];
// TODO(jingning): Revisit this part after cb4x4 is stable.
if (abs(row_offset) > 1) {
row_offset *= 2;
row_offset += 1;
col_offset = 1;
if (mi_row & 0x01 && mi_size_high[bsize] < mi_size_high[BLOCK_8X8])
++row_offset;
if (mi_col & 0x01 && mi_width < mi_size_wide[BLOCK_8X8]) --col_offset;
}
const int use_step_16 = (xd->n8_w >= 16);
#else
const int mi_col_offset = mi_size_wide[BLOCK_8X8];
#endif
for (i = 0; i < xd->n8_w && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
POSITION mi_pos;
#if CONFIG_CB4X4
const int use_step_16 = (xd->n8_w >= 16);
#else
const int use_step_16 = (xd->n8_w >= 8);
const int use_step_16 = (xd->n8_w >= 8);
#endif
MODE_INFO **const candidate_mi0 = xd->mi + row_offset * xd->mi_stride;
const int n8_w_8 = mi_size_wide[BLOCK_8X8];
const int n8_w_16 = mi_size_wide[BLOCK_16X16];
mi_pos.row = row_offset;
mi_pos.col = col_offset + i;
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, &mi_pos)) {
const MODE_INFO *const candidate_mi =
xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col];
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
int len = AOMMIN(xd->n8_w, mi_size_wide[candidate->sb_type]);
if (abs(row_offset) > 1) len = AOMMAX(len, mi_size_wide[BLOCK_8X8]);
if (use_step_16) len = AOMMAX(mi_size_wide[BLOCK_16X16], len);
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, mi_pos.col);
i += len;
} else {
if (use_step_16)
i += (mi_col_offset << 1);
else
i += mi_col_offset;
}
for (i = 0; i < end_mi && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
const MODE_INFO *const candidate_mi = candidate_mi0[col_offset + i];
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
int len = AOMMIN(xd->n8_w, mi_size_wide[candidate->sb_type]);
if (use_step_16)
len = AOMMAX(n8_w_16, len);
else if (abs(row_offset) > 1)
len = AOMMAX(len, n8_w_8);
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, col_offset + i);
i += len;
}
return newmv_count;
}
static uint8_t scan_col_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, const int mi_col, int block,
const int mi_row, int block,
const MV_REFERENCE_FRAME rf[2], int col_offset,
CANDIDATE_MV *ref_mv_stack, uint8_t *refmv_count) {
const TileInfo *const tile = &xd->tile;
const int end_mi = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
int i;
uint8_t newmv_count = 0;
int row_offset = 0;
#if CONFIG_CB4X4
const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
const int mi_height = mi_size_high[bsize];
const int mi_row_offset =
((abs(col_offset) > 1) || (mi_height < mi_size_high[BLOCK_8X8]))
? mi_size_high[BLOCK_4X4]
: mi_size_high[BLOCK_8X8];
if (abs(col_offset) > 1) {
col_offset *= 2;
col_offset += 1;
row_offset = 1;
if (mi_row & 0x01 && mi_height < mi_size_high[BLOCK_8X8]) --row_offset;
if (mi_col & 0x01 && mi_size_wide[bsize] < mi_size_wide[BLOCK_8X8])
++col_offset;
}
const int use_step_16 = (xd->n8_h >= 16);
#else
const int mi_row_offset = mi_size_wide[BLOCK_8X8];
#endif
for (i = 0; i < xd->n8_h && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
POSITION mi_pos;
#if CONFIG_CB4X4
const int use_step_16 = (xd->n8_h >= 16);
#else
const int use_step_16 = (xd->n8_h >= 8);
const int use_step_16 = (xd->n8_h >= 8);
#endif
const int n8_h_8 = mi_size_high[BLOCK_8X8];
const int n8_h_16 = mi_size_high[BLOCK_16X16];
mi_pos.row = row_offset + i;
mi_pos.col = col_offset;
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, &mi_pos)) {
const MODE_INFO *const candidate_mi =
xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col];
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
int len = AOMMIN(xd->n8_h, mi_size_high[candidate->sb_type]);
if (abs(col_offset) > 1) len = AOMMAX(len, mi_size_high[BLOCK_8X8]);
if (use_step_16) len = AOMMAX(mi_size_high[BLOCK_16X16], len);
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, mi_pos.col);
i += len;
} else {
if (use_step_16)
i += (mi_row_offset << 1);
else
i += mi_row_offset;
}
for (i = 0; i < end_mi && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
const MODE_INFO *const candidate_mi =
xd->mi[(row_offset + i) * xd->mi_stride + col_offset];
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
int len = AOMMIN(xd->n8_h, mi_size_high[candidate->sb_type]);
if (use_step_16)
len = AOMMAX(n8_h_16, len);
else if (abs(col_offset) > 1)
len = AOMMAX(len, n8_h_8);
newmv_count += add_ref_mv_candidate(
candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
cm->allow_high_precision_mv, len, block, col_offset);
i += len;
}
return newmv_count;
......@@ -426,16 +384,42 @@ static void setup_ref_mv_list(const AV1_COMMON *cm, const MACROBLOCKD *xd,
const int has_tr = has_top_right(xd, mi_row, mi_col, bs);
MV_REFERENCE_FRAME rf[2];
const TileInfo *const tile = &xd->tile;
#if CONFIG_CB4X4
const int bsize = xd->mi[0]->mbmi.sb_type;
int max_row_offset = xd->up_available ? -(MVREF_ROWS << 1) : 0;
int max_col_offset = xd->left_available ? -(MVREF_COLS << 1) : 0;
const int row_adj =
(mi_size_high[bsize] < mi_size_high[BLOCK_8X8]) && (mi_row & 0x01);
const int col_adj =
(mi_size_wide[bsize] < mi_size_wide[BLOCK_8X8]) && (mi_col & 0x01);
#else
int max_row_offset = xd->up_available ? -MVREF_ROWS : 0;
int max_col_offset = xd->left_available ? -MVREF_COLS : 0;
#endif
int row_offset, col_offset;
av1_set_ref_frame(rf, ref_frame);
mode_context[ref_frame] = 0;
*refmv_count = 0;
// Scan the first above row mode info.
newmv_count += scan_row_mbmi(cm, xd, mi_row, mi_col, block, rf, -1,
ref_mv_stack, refmv_count);
if (max_row_offset) {
max_row_offset =
find_valid_row_offset(tile, mi_row, cm->mi_rows, cm, max_row_offset);
// row_offset = -1;
if (abs(max_row_offset) >= 1)
newmv_count += scan_row_mbmi(cm, xd, mi_col, block, rf, -1, ref_mv_stack,
refmv_count);
}
// Scan the first left column mode info.
newmv_count += scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf, -1,
ref_mv_stack, refmv_count);
if (max_col_offset) {
max_col_offset = find_valid_col_offset(tile, mi_col, max_col_offset);
// col_offset = -1;
if (abs(max_col_offset) >= 1)
newmv_count += scan_col_mbmi(cm, xd, mi_row, block, rf, -1, ref_mv_stack,
refmv_count);
}
// Check top-right boundary
if (has_tr)
......@@ -498,14 +482,40 @@ static void setup_ref_mv_list(const AV1_COMMON *cm, const MACROBLOCKD *xd,
// Scan the second outer area.
scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, -1, -1, ref_mv_stack,
refmv_count);
for (idx = 2; idx <= 3; ++idx) {
scan_row_mbmi(cm, xd, mi_row, mi_col, block, rf, -idx, ref_mv_stack,
refmv_count);
scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf, -idx, ref_mv_stack,
refmv_count);
for (idx = 2; idx <= MVREF_ROWS; ++idx) {
if (max_row_offset) {
#if CONFIG_CB4X4
row_offset = -(idx << 1) + 1 + row_adj;
#else
row_offset = -idx;
#endif
if (abs(row_offset) <= abs(max_row_offset))
scan_row_mbmi(cm, xd, mi_col, block, rf, row_offset, ref_mv_stack,
refmv_count);
}
if (max_col_offset) {
#if CONFIG_CB4X4
col_offset = -(idx << 1) + 1 + col_adj;
#else
col_offset = -idx;
#endif
if (abs(col_offset) <= abs(max_col_offset))
scan_col_mbmi(cm, xd, mi_row, block, rf, col_offset, ref_mv_stack,
refmv_count);
}
}
if (max_col_offset) {
#if CONFIG_CB4X4
col_offset = -(MVREF_COLS << 1) + 1 + col_adj;
#else
col_offset = -MVREF_COLS;
#endif
if (abs(col_offset) <= abs(max_col_offset))
scan_col_mbmi(cm, xd, mi_row, block, rf, col_offset, ref_mv_stack,
refmv_count);
}
scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf, -4, ref_mv_stack,
refmv_count);
switch (nearest_refmv_count) {
case 0:
......
......@@ -19,6 +19,8 @@ extern "C" {
#endif
#define MVREF_NEIGHBOURS 9
#define MVREF_ROWS 3
#define MVREF_COLS 4
typedef struct position {
int row;
......@@ -207,6 +209,28 @@ static INLINE int is_inside(const TileInfo *const tile, int mi_col, int mi_row,
}
}
static INLINE int find_valid_row_offset(const TileInfo *const tile, int mi_row,
int mi_rows, const AV1_COMMON *cm,
int row_offset) {
#if CONFIG_DEPENDENT_HORZTILES
const int dependent_horz_tile_flag = cm->dependent_horz_tiles;
#else
const int dependent_horz_tile_flag = 0;
(void)cm;
#endif
if (dependent_horz_tile_flag && !tile->tg_horz_boundary)
return clamp(row_offset, -mi_row, mi_rows - mi_row - 1);
else
return clamp(row_offset, tile->mi_row_start - mi_row,
tile->mi_row_end - mi_row - 1);
}
static INLINE int find_valid_col_offset(const TileInfo *const tile, int mi_col,
int col_offset) {
return clamp(col_offset, tile->mi_col_start - mi_col,
tile->mi_col_end - mi_col - 1);
}
static INLINE void lower_mv_precision(MV *mv, int allow_hp) {
if (!allow_hp) {
if (mv->row & 1) mv->row += (mv->row > 0 ? -1 : 1);
......
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