Merge "Enable iterative motion search for 4x4 inter pred" into experimental
This commit is contained in:
Коммит
5e97862a71
|
@ -774,7 +774,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
|
||||||
sf->optimize_coefficients = !cpi->oxcf.lossless;
|
sf->optimize_coefficients = !cpi->oxcf.lossless;
|
||||||
sf->first_step = 0;
|
sf->first_step = 0;
|
||||||
sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
|
sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
|
||||||
sf->comp_inter_joint_serach = 1;
|
sf->comp_inter_joint_search = 1;
|
||||||
#if CONFIG_MULTIPLE_ARF
|
#if CONFIG_MULTIPLE_ARF
|
||||||
// Switch segmentation off.
|
// Switch segmentation off.
|
||||||
sf->static_segmentation = 0;
|
sf->static_segmentation = 0;
|
||||||
|
@ -809,7 +809,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
|
||||||
/* Disable coefficient optimization above speed 0 */
|
/* Disable coefficient optimization above speed 0 */
|
||||||
sf->optimize_coefficients = 0;
|
sf->optimize_coefficients = 0;
|
||||||
sf->no_skip_block4x4_search = 0;
|
sf->no_skip_block4x4_search = 0;
|
||||||
sf->comp_inter_joint_serach = 0;
|
sf->comp_inter_joint_search = 0;
|
||||||
|
|
||||||
sf->first_step = 1;
|
sf->first_step = 1;
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,7 @@ typedef struct {
|
||||||
int search_best_filter;
|
int search_best_filter;
|
||||||
int mb16_breakout;
|
int mb16_breakout;
|
||||||
int static_segmentation;
|
int static_segmentation;
|
||||||
int comp_inter_joint_serach;
|
int comp_inter_joint_search;
|
||||||
} SPEED_FEATURES;
|
} SPEED_FEATURES;
|
||||||
|
|
||||||
enum BlockSize {
|
enum BlockSize {
|
||||||
|
|
|
@ -1003,7 +1003,7 @@ static int labels2mode(MACROBLOCK *x, int i,
|
||||||
MB_PREDICTION_MODE this_mode,
|
MB_PREDICTION_MODE this_mode,
|
||||||
int_mv *this_mv, int_mv *this_second_mv,
|
int_mv *this_mv, int_mv *this_second_mv,
|
||||||
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
|
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
|
||||||
int_mv seg_mvs[MAX_REF_FRAMES - 1],
|
int_mv seg_mvs[MAX_REF_FRAMES],
|
||||||
int_mv *best_ref_mv,
|
int_mv *best_ref_mv,
|
||||||
int_mv *second_best_ref_mv,
|
int_mv *second_best_ref_mv,
|
||||||
int *mvjcost, int *mvcost[2], VP9_COMP *cpi) {
|
int *mvjcost, int *mvcost[2], VP9_COMP *cpi) {
|
||||||
|
@ -1024,14 +1024,11 @@ static int labels2mode(MACROBLOCK *x, int i,
|
||||||
// is when we are on a new label (jbb May 08, 2007)
|
// is when we are on a new label (jbb May 08, 2007)
|
||||||
switch (m = this_mode) {
|
switch (m = this_mode) {
|
||||||
case NEWMV:
|
case NEWMV:
|
||||||
if (mbmi->second_ref_frame > 0) {
|
this_mv->as_int = seg_mvs[mbmi->ref_frame].as_int;
|
||||||
this_mv->as_int = seg_mvs[mbmi->ref_frame - 1].as_int;
|
|
||||||
this_second_mv->as_int = seg_mvs[mbmi->second_ref_frame - 1].as_int;
|
|
||||||
}
|
|
||||||
|
|
||||||
thismvcost = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost,
|
thismvcost = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost,
|
||||||
102, xd->allow_high_precision_mv);
|
102, xd->allow_high_precision_mv);
|
||||||
if (mbmi->second_ref_frame > 0) {
|
if (mbmi->second_ref_frame > 0) {
|
||||||
|
this_second_mv->as_int = seg_mvs[mbmi->second_ref_frame].as_int;
|
||||||
thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv,
|
thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv,
|
||||||
mvjcost, mvcost, 102,
|
mvjcost, mvcost, 102,
|
||||||
xd->allow_high_precision_mv);
|
xd->allow_high_precision_mv);
|
||||||
|
@ -1236,9 +1233,44 @@ static enum BlockSize get_block_size(int bw, int bh) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
|
||||||
|
MB_MODE_INFO *mbmi = &x->e_mbd.mode_info_context->mbmi;
|
||||||
|
x->plane[0].src.buf =
|
||||||
|
raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
|
||||||
|
x->plane[0].src.buf,
|
||||||
|
x->plane[0].src.stride);
|
||||||
|
assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0x7) == 0);
|
||||||
|
x->e_mbd.plane[0].pre[0].buf =
|
||||||
|
raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
|
||||||
|
x->e_mbd.plane[0].pre[0].buf,
|
||||||
|
x->e_mbd.plane[0].pre[0].stride);
|
||||||
|
if (mbmi->second_ref_frame)
|
||||||
|
x->e_mbd.plane[0].pre[1].buf =
|
||||||
|
raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
|
||||||
|
x->e_mbd.plane[0].pre[1].buf,
|
||||||
|
x->e_mbd.plane[0].pre[1].stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
|
||||||
|
struct buf_2d orig_pre[2]) {
|
||||||
|
MB_MODE_INFO *mbmi = &x->e_mbd.mode_info_context->mbmi;
|
||||||
|
x->plane[0].src = orig_src;
|
||||||
|
x->e_mbd.plane[0].pre[0] = orig_pre[0];
|
||||||
|
if (mbmi->second_ref_frame)
|
||||||
|
x->e_mbd.plane[0].pre[1] = orig_pre[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
|
BLOCK_SIZE_TYPE bsize,
|
||||||
|
int_mv *frame_mv,
|
||||||
|
YV12_BUFFER_CONFIG **scaled_ref_frame,
|
||||||
|
int mi_row, int mi_col,
|
||||||
|
int_mv single_newmv[MAX_REF_FRAMES]);
|
||||||
|
|
||||||
static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
|
static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
BEST_SEG_INFO *bsi,
|
BEST_SEG_INFO *bsi,
|
||||||
int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
|
int_mv seg_mvs[4][MAX_REF_FRAMES],
|
||||||
|
int mi_row, int mi_col) {
|
||||||
int i, j;
|
int i, j;
|
||||||
int br = 0, bd = 0;
|
int br = 0, bd = 0;
|
||||||
MB_PREDICTION_MODE this_mode;
|
MB_PREDICTION_MODE this_mode;
|
||||||
|
@ -1255,7 +1287,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
int bhl = b_height_log2(bsize), bh = 1 << bhl;
|
int bhl = b_height_log2(bsize), bh = 1 << bhl;
|
||||||
int idx, idy;
|
int idx, idy;
|
||||||
vp9_variance_fn_ptr_t *v_fn_ptr;
|
vp9_variance_fn_ptr_t *v_fn_ptr;
|
||||||
|
YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL};
|
||||||
ENTROPY_CONTEXT t_above[4], t_left[4];
|
ENTROPY_CONTEXT t_above[4], t_left[4];
|
||||||
ENTROPY_CONTEXT t_above_b[4], t_left_b[4];
|
ENTROPY_CONTEXT t_above_b[4], t_left_b[4];
|
||||||
|
|
||||||
|
@ -1302,6 +1334,10 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
int distortion;
|
int distortion;
|
||||||
int labelyrate;
|
int labelyrate;
|
||||||
ENTROPY_CONTEXT t_above_s[4], t_left_s[4];
|
ENTROPY_CONTEXT t_above_s[4], t_left_s[4];
|
||||||
|
const struct buf_2d orig_src = x->plane[0].src;
|
||||||
|
struct buf_2d orig_pre[2];
|
||||||
|
|
||||||
|
vpx_memcpy(orig_pre, x->e_mbd.plane[0].pre, sizeof(orig_pre));
|
||||||
|
|
||||||
vpx_memcpy(t_above_s, t_above, sizeof(t_above_s));
|
vpx_memcpy(t_above_s, t_above, sizeof(t_above_s));
|
||||||
vpx_memcpy(t_left_s, t_left, sizeof(t_left_s));
|
vpx_memcpy(t_left_s, t_left, sizeof(t_left_s));
|
||||||
|
@ -1311,8 +1347,6 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
int step_param = 0;
|
int step_param = 0;
|
||||||
int further_steps;
|
int further_steps;
|
||||||
int thissme, bestsme = INT_MAX;
|
int thissme, bestsme = INT_MAX;
|
||||||
const struct buf_2d orig_src = x->plane[0].src;
|
|
||||||
const struct buf_2d orig_pre = x->e_mbd.plane[0].pre[0];
|
|
||||||
int sadpb = x->sadperbit4;
|
int sadpb = x->sadperbit4;
|
||||||
int_mv mvp_full;
|
int_mv mvp_full;
|
||||||
|
|
||||||
|
@ -1338,17 +1372,8 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3;
|
mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3;
|
||||||
mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3;
|
mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3;
|
||||||
|
|
||||||
// adjust src pointer for this segment
|
// adjust src pointer for this block
|
||||||
x->plane[0].src.buf =
|
mi_buf_shift(x, i);
|
||||||
raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
|
|
||||||
x->plane[0].src.buf,
|
|
||||||
x->plane[0].src.stride);
|
|
||||||
assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0x7) == 0);
|
|
||||||
x->e_mbd.plane[0].pre[0].buf =
|
|
||||||
raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
|
|
||||||
x->e_mbd.plane[0].pre[0].buf,
|
|
||||||
x->e_mbd.plane[0].pre[0].stride);
|
|
||||||
|
|
||||||
bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
|
bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
|
||||||
sadpb, further_steps, 0, v_fn_ptr,
|
sadpb, further_steps, 0, v_fn_ptr,
|
||||||
bsi->ref_mv, &mode_mv[NEWMV]);
|
bsi->ref_mv, &mode_mv[NEWMV]);
|
||||||
|
@ -1385,16 +1410,29 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
&distortion, &sse);
|
&distortion, &sse);
|
||||||
|
|
||||||
// safe motion search result for use in compound prediction
|
// safe motion search result for use in compound prediction
|
||||||
seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEWMV].as_int;
|
seg_mvs[i][mbmi->ref_frame].as_int = mode_mv[NEWMV].as_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore src pointers
|
// restore src pointers
|
||||||
x->plane[0].src = orig_src;
|
mi_buf_restore(x, orig_src, orig_pre);
|
||||||
x->e_mbd.plane[0].pre[0] = orig_pre;
|
|
||||||
} else if (mbmi->second_ref_frame > 0 && this_mode == NEWMV) {
|
} else if (mbmi->second_ref_frame > 0 && this_mode == NEWMV) {
|
||||||
if (seg_mvs[i][mbmi->second_ref_frame - 1].as_int == INVALID_MV ||
|
if (seg_mvs[i][mbmi->second_ref_frame].as_int == INVALID_MV ||
|
||||||
seg_mvs[i][mbmi->ref_frame - 1].as_int == INVALID_MV)
|
seg_mvs[i][mbmi->ref_frame ].as_int == INVALID_MV)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// adjust src pointers
|
||||||
|
mi_buf_shift(x, i);
|
||||||
|
if (cpi->sf.comp_inter_joint_search) {
|
||||||
|
iterative_motion_search(cpi, x, bsize, frame_mv[this_mode],
|
||||||
|
scaled_ref_frame,
|
||||||
|
mi_row, mi_col, seg_mvs[i]);
|
||||||
|
seg_mvs[i][mbmi->ref_frame].as_int =
|
||||||
|
frame_mv[this_mode][mbmi->ref_frame].as_int;
|
||||||
|
seg_mvs[i][mbmi->second_ref_frame].as_int =
|
||||||
|
frame_mv[this_mode][mbmi->second_ref_frame].as_int;
|
||||||
|
}
|
||||||
|
// restore src pointers
|
||||||
|
mi_buf_restore(x, orig_src, orig_pre);
|
||||||
}
|
}
|
||||||
|
|
||||||
rate = labels2mode(x, i, this_mode, &mode_mv[this_mode],
|
rate = labels2mode(x, i, this_mode, &mode_mv[this_mode],
|
||||||
|
@ -1473,12 +1511,6 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rd_check_segment(VP9_COMP *cpi, MACROBLOCK *x,
|
|
||||||
BEST_SEG_INFO *bsi,
|
|
||||||
int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
|
|
||||||
rd_check_segment_txsize(cpi, x, bsi, seg_mvs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
|
static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
int_mv *best_ref_mv,
|
int_mv *best_ref_mv,
|
||||||
int_mv *second_best_ref_mv,
|
int_mv *second_best_ref_mv,
|
||||||
|
@ -1487,7 +1519,8 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
int *returnyrate,
|
int *returnyrate,
|
||||||
int *returndistortion,
|
int *returndistortion,
|
||||||
int *skippable, int mvthresh,
|
int *skippable, int mvthresh,
|
||||||
int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
|
int_mv seg_mvs[4][MAX_REF_FRAMES],
|
||||||
|
int mi_row, int mi_col) {
|
||||||
int i;
|
int i;
|
||||||
BEST_SEG_INFO bsi;
|
BEST_SEG_INFO bsi;
|
||||||
MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
|
MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
|
||||||
|
@ -1503,7 +1536,7 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
bsi.modes[i] = ZEROMV;
|
bsi.modes[i] = ZEROMV;
|
||||||
|
|
||||||
rd_check_segment(cpi, x, &bsi, seg_mvs);
|
rd_check_segment_txsize(cpi, x, &bsi, seg_mvs, mi_row, mi_col);
|
||||||
|
|
||||||
/* set it to the best */
|
/* set it to the best */
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
|
@ -2106,7 +2139,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
|
frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
|
||||||
frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
|
frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
|
||||||
|
|
||||||
if (cpi->sf.comp_inter_joint_serach)
|
if (cpi->sf.comp_inter_joint_search)
|
||||||
iterative_motion_search(cpi, x, bsize, frame_mv, scaled_ref_frame,
|
iterative_motion_search(cpi, x, bsize, frame_mv, scaled_ref_frame,
|
||||||
mi_row, mi_col, single_newmv);
|
mi_row, mi_col, single_newmv);
|
||||||
|
|
||||||
|
@ -2504,14 +2537,14 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
int64_t frame_distortions[MAX_REF_FRAMES] = {-1};
|
int64_t frame_distortions[MAX_REF_FRAMES] = {-1};
|
||||||
int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
|
int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
|
||||||
cpi->common.y_dc_delta_q);
|
cpi->common.y_dc_delta_q);
|
||||||
int_mv seg_mvs[4][MAX_REF_FRAMES - 1];
|
int_mv seg_mvs[4][MAX_REF_FRAMES];
|
||||||
union b_mode_info best_bmodes[4];
|
union b_mode_info best_bmodes[4];
|
||||||
PARTITION_INFO best_partition;
|
PARTITION_INFO best_partition;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 0; j < MAX_REF_FRAMES - 1; j++)
|
for (j = 0; j < MAX_REF_FRAMES; j++)
|
||||||
seg_mvs[i][j].as_int = INVALID_MV;
|
seg_mvs[i][j].as_int = INVALID_MV;
|
||||||
}
|
}
|
||||||
// Everywhere the flag is set the error is much higher than its neighbors.
|
// Everywhere the flag is set the error is much higher than its neighbors.
|
||||||
|
@ -2804,7 +2837,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
second_ref, INT64_MAX,
|
second_ref, INT64_MAX,
|
||||||
&rate, &rate_y, &distortion,
|
&rate, &rate_y, &distortion,
|
||||||
&skippable,
|
&skippable,
|
||||||
(int)this_rd_thresh, seg_mvs);
|
(int)this_rd_thresh, seg_mvs,
|
||||||
|
mi_row, mi_col);
|
||||||
if (cpi->common.mcomp_filter_type == SWITCHABLE) {
|
if (cpi->common.mcomp_filter_type == SWITCHABLE) {
|
||||||
const int rs = get_switchable_rate(cm, x);
|
const int rs = get_switchable_rate(cm, x);
|
||||||
tmp_rd += RDCOST(x->rdmult, x->rddiv, rs, 0);
|
tmp_rd += RDCOST(x->rdmult, x->rddiv, rs, 0);
|
||||||
|
@ -2843,7 +2877,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
|
||||||
second_ref, INT64_MAX,
|
second_ref, INT64_MAX,
|
||||||
&rate, &rate_y, &distortion,
|
&rate, &rate_y, &distortion,
|
||||||
&skippable,
|
&skippable,
|
||||||
(int)this_rd_thresh, seg_mvs);
|
(int)this_rd_thresh, seg_mvs,
|
||||||
|
mi_row, mi_col);
|
||||||
} else {
|
} else {
|
||||||
if (cpi->common.mcomp_filter_type == SWITCHABLE) {
|
if (cpi->common.mcomp_filter_type == SWITCHABLE) {
|
||||||
int rs = get_switchable_rate(cm, x);
|
int rs = get_switchable_rate(cm, x);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче