Commit 97629f59 authored by Jingning Han's avatar Jingning Han Committed by Gerrit Code Review
Browse files

Merge "Refactor ref mv stack system" into nextgenv2

parents 0f840cc3 253a200d
......@@ -83,6 +83,10 @@ typedef struct {
typedef int8_t MV_REFERENCE_FRAME;
#if CONFIG_REF_MV
#define MODE_CTX_REF_FRAMES (MAX_REF_FRAMES + (ALTREF_FRAME - LAST_FRAME))
#endif
typedef struct {
// Number of base colors for Y (0) and UV (1)
uint8_t palette_size[2];
......
......@@ -37,6 +37,7 @@ typedef struct mv32 {
#if CONFIG_REF_MV
typedef struct candidate_mv {
int_mv this_mv;
int_mv comp_mv;
int weight;
} CANDIDATE_MV;
#endif
......
......@@ -12,34 +12,43 @@
#include "vp10/common/mvref_common.h"
#if CONFIG_REF_MV
static uint8_t scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, const int mi_col, int block,
const MV_REFERENCE_FRAME ref_frame,
int row_offset,
CANDIDATE_MV *ref_mv_stack,
uint8_t *refmv_count) {
const TileInfo *const tile = &xd->tile;
int i;
uint8_t newmv_count = 0;
static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
const MB_MODE_INFO *const candidate,
const MV_REFERENCE_FRAME rf[2],
uint8_t *refmv_count,
CANDIDATE_MV *ref_mv_stack,
int len, int block, int col) {
const int weight = len;
int index = 0, ref;
int newmv_count = 0;
if (rf[1] == NONE) {
// single reference frame
for (ref = 0; ref < 2; ++ref) {
if (candidate->ref_frame[ref] == rf[0]) {
int_mv this_refmv =
get_sub_block_mv(candidate_mi, ref, col, block);
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int)
break;
for (i = 0; i < xd->n8_w && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
POSITION mi_pos;
mi_pos.row = row_offset;
mi_pos.col = i;
if (index < *refmv_count)
ref_mv_stack[index].weight += 2 * weight;
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, &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;
const int len = VPXMIN(xd->n8_w,
num_8x8_blocks_wide_lookup[candidate->sb_type]);
const int weight = len;
int index = 0, ref;
// Add a new item to the list.
if (index == *refmv_count) {
ref_mv_stack[index].this_mv = this_refmv;
ref_mv_stack[index].weight = 2 * weight;
++(*refmv_count);
for (ref = 0; ref < 2; ++ref) {
if (candidate->ref_frame[ref] == ref_frame) {
int_mv this_refmv =
get_sub_block_mv(candidate_mi, ref, mi_pos.col, block);
if (candidate->mode == NEWMV)
++newmv_count;
}
if (candidate_mi->mbmi.sb_type < BLOCK_8X8 && block >= 0) {
int alt_block = 3 - block;
this_refmv =
get_sub_block_mv(candidate_mi, ref, col, alt_block);
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int)
break;
......@@ -58,6 +67,89 @@ static uint8_t scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
}
}
}
}
} else {
// compound reference frame
if (candidate->ref_frame[0] == rf[0] &&
candidate->ref_frame[1] == rf[1]) {
int_mv this_refmv[2] = {
get_sub_block_mv(candidate_mi, 0, col, block),
get_sub_block_mv(candidate_mi, 1, col, block)
};
for (index = 0; index < *refmv_count; ++index)
if ((ref_mv_stack[index].this_mv.as_int == this_refmv[0].as_int) &&
(ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int))
break;
if (index < *refmv_count)
ref_mv_stack[index].weight += 2 * weight;
// Add a new item to the list.
if (index == *refmv_count) {
ref_mv_stack[index].this_mv = this_refmv[0];
ref_mv_stack[index].comp_mv = this_refmv[1];
ref_mv_stack[index].weight = 2 * weight;
++(*refmv_count);
if (candidate->mode == NEWMV)
++newmv_count;
}
if (candidate_mi->mbmi.sb_type < BLOCK_8X8 && block >= 0) {
int alt_block = 3 - block;
this_refmv[0] = get_sub_block_mv(candidate_mi, 0, col, alt_block);
this_refmv[1] = get_sub_block_mv(candidate_mi, 1, col, alt_block);
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv[0].as_int &&
ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int)
break;
if (index < *refmv_count)
ref_mv_stack[index].weight += weight;
// Add a new item to the list.
if (index == *refmv_count) {
ref_mv_stack[index].this_mv = this_refmv[0];
ref_mv_stack[index].comp_mv = this_refmv[1];
ref_mv_stack[index].weight = weight;
++(*refmv_count);
if (candidate->mode == NEWMV)
++newmv_count;
}
}
}
}
return newmv_count;
}
static uint8_t scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, 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;
int i;
uint8_t newmv_count = 0;
for (i = 0; i < xd->n8_w && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
POSITION mi_pos;
mi_pos.row = row_offset;
mi_pos.col = i;
if (is_inside(tile, mi_col, mi_row, cm->mi_rows, &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;
const int len = VPXMIN(xd->n8_w,
num_8x8_blocks_wide_lookup[candidate->sb_type]);
newmv_count += add_ref_mv_candidate(candidate_mi, candidate, rf,
refmv_count, ref_mv_stack, len,
block, mi_pos.col);
i += len;
} else {
++i;
......@@ -69,7 +161,7 @@ static uint8_t scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
static uint8_t scan_col_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, const int mi_col, int block,
const MV_REFERENCE_FRAME ref_frame,
const MV_REFERENCE_FRAME rf[2],
int col_offset,
CANDIDATE_MV *ref_mv_stack,
uint8_t *refmv_count) {
......@@ -88,30 +180,10 @@ static uint8_t scan_col_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
const int len = VPXMIN(xd->n8_h,
num_8x8_blocks_high_lookup[candidate->sb_type]);
const int weight = len;
int index = 0, ref;
for (ref = 0; ref < 2; ++ref) {
if (candidate->ref_frame[ref] == ref_frame) {
int_mv this_refmv =
get_sub_block_mv(candidate_mi, ref, mi_pos.col, block);
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int)
break;
if (index < *refmv_count)
ref_mv_stack[index].weight += weight;
if (index == *refmv_count) {
ref_mv_stack[index].this_mv = this_refmv;
ref_mv_stack[index].weight = weight;
++(*refmv_count);
if (candidate->mode == NEWMV)
++newmv_count;
}
}
}
newmv_count += add_ref_mv_candidate(candidate_mi, candidate, rf,
refmv_count, ref_mv_stack, len,
block, mi_pos.col);
i += len;
} else {
++i;
......@@ -123,7 +195,7 @@ static uint8_t scan_col_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
static uint8_t scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, const int mi_col, int block,
const MV_REFERENCE_FRAME ref_frame,
const MV_REFERENCE_FRAME rf[2],
int row_offset, int col_offset,
CANDIDATE_MV *ref_mv_stack,
uint8_t *refmv_count) {
......@@ -140,49 +212,10 @@ static uint8_t scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col];
const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
const int len = 1;
const int weight = len;
int index = 0, ref;
for (ref = 0; ref < 2; ++ref) {
if (candidate->ref_frame[ref] == ref_frame) {
int_mv this_refmv =
get_sub_block_mv(candidate_mi, ref, mi_pos.col, block);
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int)
break;
if (index < *refmv_count)
ref_mv_stack[index].weight += weight;
if (index == *refmv_count) {
ref_mv_stack[index].this_mv = this_refmv;
ref_mv_stack[index].weight = weight;
++(*refmv_count);
if (candidate->mode == NEWMV)
++newmv_count;
}
if (candidate_mi->mbmi.sb_type < BLOCK_8X8 && block >= 0) {
int alt_block = 3 - block;
this_refmv =
get_sub_block_mv(candidate_mi, ref, mi_pos.col, alt_block);
for (index = 0; index < *refmv_count; ++index)
if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int)
break;
if (index < *refmv_count)
ref_mv_stack[index].weight += weight;
// Add a new item to the list.
if (index == *refmv_count) {
ref_mv_stack[index].this_mv = this_refmv;
ref_mv_stack[index].weight = weight;
++(*refmv_count);
}
}
}
}
newmv_count += add_ref_mv_candidate(candidate_mi, candidate, rf,
refmv_count, ref_mv_stack, len,
block, mi_pos.col);
} // Analyze a single 8x8 block motion information.
return newmv_count;
}
......@@ -260,19 +293,22 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd,
int bs = VPXMAX(xd->n8_w, xd->n8_h);
int has_tr = has_top_right(xd, mi_row, mi_col, bs);
MV_REFERENCE_FRAME rf[2];
vp10_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, ref_frame,
newmv_count = scan_row_mbmi(cm, xd, mi_row, 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, ref_frame,
newmv_count += scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf,
-1, ref_mv_stack, refmv_count);
// Check top-right boundary
if (has_tr)
newmv_count += scan_blk_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
newmv_count += scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf,
-1, 1, ref_mv_stack, refmv_count);
nearest_refmv_count = *refmv_count;
......@@ -301,12 +337,12 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd,
break;
if (idx < *refmv_count)
ref_mv_stack[idx].weight += 1;
ref_mv_stack[idx].weight += 2;
if (idx == *refmv_count &&
*refmv_count < MAX_REF_MV_STACK_SIZE) {
ref_mv_stack[idx].this_mv.as_int = prev_frame_mvs->mv[ref].as_int;
ref_mv_stack[idx].weight = 1;
ref_mv_stack[idx].weight = 2;
++(*refmv_count);
if (abs(ref_mv_stack[idx].this_mv.as_mv.row) >= 8 ||
......@@ -327,22 +363,22 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd,
// -1, -1, ref_mv_stack, refmv_count);
// Scan the second outer area.
scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
scan_row_mbmi(cm, xd, mi_row, mi_col, block, rf,
-2, ref_mv_stack, refmv_count);
scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf,
-2, ref_mv_stack, refmv_count);
// Scan the third outer area.
scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
scan_row_mbmi(cm, xd, mi_row, mi_col, block, rf,
-3, ref_mv_stack, refmv_count);
scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf,
-3, ref_mv_stack, refmv_count);
// Scan the fourth outer area.
scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
scan_row_mbmi(cm, xd, mi_row, mi_col, block, rf,
-4, ref_mv_stack, refmv_count);
// Scan the third left row mode info.
scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf,
-4, ref_mv_stack, refmv_count);
switch (nearest_refmv_count) {
......@@ -630,6 +666,7 @@ void vp10_append_sub8x8_mvs_for_idx(VP10_COMMON *cm, MACROBLOCKD *xd,
CANDIDATE_MV tmp_mv;
uint8_t ref_mv_count = 0, idx;
uint8_t above_count = 0, left_count = 0;
MV_REFERENCE_FRAME rf[2] = { mi->mbmi.ref_frame[ref], NONE };
#endif
assert(MAX_MV_REF_CANDIDATES == 2);
......@@ -638,11 +675,11 @@ void vp10_append_sub8x8_mvs_for_idx(VP10_COMMON *cm, MACROBLOCKD *xd,
mi_row, mi_col, NULL, NULL, NULL);
#if CONFIG_REF_MV
scan_blk_mbmi(cm, xd, mi_row, mi_col, block, mi->mbmi.ref_frame[ref],
scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf,
-1, 0, ref_mv_stack, &ref_mv_count);
above_count = ref_mv_count;
scan_blk_mbmi(cm, xd, mi_row, mi_col, block, mi->mbmi.ref_frame[ref],
scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf,
0, -1, ref_mv_stack, &ref_mv_count);
left_count = ref_mv_count - above_count;
......
......@@ -196,6 +196,24 @@ static INLINE int is_inside(const TileInfo *const tile,
}
#if CONFIG_REF_MV
static int8_t vp10_ref_frame_type(const MV_REFERENCE_FRAME *const rf) {
if (rf[1] > INTRA_FRAME)
return rf[0] + ALTREF_FRAME;
return rf[0];
}
static void vp10_set_ref_frame(MV_REFERENCE_FRAME *rf, int8_t ref_frame_type) {
if (ref_frame_type > ALTREF_FRAME) {
rf[0] = ref_frame_type - ALTREF_FRAME;
rf[1] = ALTREF_FRAME;
} else {
rf[0] = ref_frame_type;
rf[1] = NONE;
assert(ref_frame_type > INTRA_FRAME && ref_frame_type < MAX_REF_FRAMES);
}
}
static int16_t vp10_mode_context_analyzer(const int16_t *const mode_context,
const MV_REFERENCE_FRAME *const rf,
BLOCK_SIZE bsize, int block) {
......
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