Commit 24c346df authored by Yunqing Wang's avatar Yunqing Wang
Browse files

Add biasing to ZEROMV for videos with static background

For videos with big static background(such as video conferencing
clips), the mode decision was biased to ZEROMV in order to
obtain a stable background. The percentage of ZEROMV on last
frame was used to predict if there is static area in current frame,
and checking already-encoded neighboring macroblocks' motion
vectors to make sure the local area has low motion.

Change-Id: I05b3241d3a56a0bda88b6681e5646c1c8baf2e57
parent 272974af
......@@ -1104,6 +1104,7 @@ void vp8_alloc_compressor_data(VP8_COMP *cpi)
/* Data used for real time vc mode to see if gf needs refreshing */
cpi->inter_zz_count = 0;
cpi->zeromv_count = 0;
cpi->gf_bad_count = 0;
cpi->gf_update_recommended = 0;
......@@ -4306,6 +4307,7 @@ static void encode_frame_to_data_rate
MODE_INFO *tmp = cm->mi;
cpi->inter_zz_count = 0;
cpi->zeromv_count = 0;
if(cm->frame_type != KEY_FRAME)
{
......@@ -4315,6 +4317,8 @@ static void encode_frame_to_data_rate
{
if(tmp->mbmi.mode == ZEROMV && tmp->mbmi.ref_frame == LAST_FRAME)
cpi->inter_zz_count++;
if(tmp->mbmi.mode == ZEROMV)
cpi->zeromv_count++;
tmp++;
}
tmp++;
......@@ -5116,6 +5120,8 @@ int vp8_get_compressed_data(VP8_COMP *cpi, unsigned int *frame_flags, unsigned l
vpx_usec_timer_start(&ticktimer);
}
cpi->lf_zeromv_pct = (cpi->zeromv_count * 100)/cm->MBs;
#if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
{
int i;
......
......@@ -515,6 +515,9 @@ typedef struct VP8_COMP
* would be good to update the gf
*/
int inter_zz_count;
/* Count ZEROMV on all reference frames. */
int zeromv_count;
int lf_zeromv_pct;
int gf_bad_count;
int gf_update_recommended;
int skip_true_count;
......
......@@ -480,7 +480,8 @@ static void check_for_encode_breakout(unsigned int sse, MACROBLOCK* x)
}
}
static int evaluate_inter_mode(unsigned int* sse, int rate2, int* distortion2, VP8_COMP *cpi, MACROBLOCK *x)
static int evaluate_inter_mode(unsigned int* sse, int rate2, int* distortion2,
VP8_COMP *cpi, MACROBLOCK *x, int rd_adj)
{
MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode;
int_mv mv = x->e_mbd.mode_info_context->mbmi.mv;
......@@ -503,10 +504,63 @@ static int evaluate_inter_mode(unsigned int* sse, int rate2, int* distortion2, V
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, *distortion2);
/* Adjust rd to bias to ZEROMV */
if(this_mode == ZEROMV)
{
/* Bias to ZEROMV on LAST_FRAME reference when it is available. */
if ((cpi->ref_frame_flags & VP8_LAST_FRAME &
cpi->common.refresh_last_frame)
&& x->e_mbd.mode_info_context->mbmi.ref_frame != LAST_FRAME)
rd_adj = 100;
this_rd = this_rd * rd_adj/100;
}
check_for_encode_breakout(*sse, x);
return this_rd;
}
static void calculate_zeromv_rd_adjustment(VP8_COMP *cpi, MACROBLOCK *x,
int *rd_adjustment)
{
MODE_INFO *mic = x->e_mbd.mode_info_context;
int_mv mv_l, mv_a, mv_al;
int local_motion_check = 0;
if (cpi->lf_zeromv_pct > 40)
{
/* left mb */
mic -= 1;
mv_l = mic->mbmi.mv;
if (mic->mbmi.ref_frame != INTRA_FRAME)
if( abs(mv_l.as_mv.row) < 8 && abs(mv_l.as_mv.col) < 8)
local_motion_check++;
/* above-left mb */
mic -= x->e_mbd.mode_info_stride;
mv_al = mic->mbmi.mv;
if (mic->mbmi.ref_frame != INTRA_FRAME)
if( abs(mv_al.as_mv.row) < 8 && abs(mv_al.as_mv.col) < 8)
local_motion_check++;
/* above mb */
mic += 1;
mv_a = mic->mbmi.mv;
if (mic->mbmi.ref_frame != INTRA_FRAME)
if( abs(mv_a.as_mv.row) < 8 && abs(mv_a.as_mv.col) < 8)
local_motion_check++;
if (((!x->e_mbd.mb_to_top_edge || !x->e_mbd.mb_to_left_edge)
&& local_motion_check >0) || local_motion_check >2 )
*rd_adjustment = 80;
else if (local_motion_check > 0)
*rd_adjustment = 90;
}
}
void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int recon_uvoffset, int *returnrate,
int *returndistortion, int *returnintra, int mb_row,
......@@ -525,6 +579,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int num00;
int mdcounts[4];
int best_rd = INT_MAX;
int rd_adjustment = 100;
int best_intra_rd = INT_MAX;
int mode_index;
int rate;
......@@ -594,6 +649,11 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
/* If the frame has big static background and current MB is in low
* motion area, its mode decision is biased to ZEROMV mode.
*/
calculate_zeromv_rd_adjustment(cpi, x, &rd_adjustment);
/* if we encode a new mv this is important
* find the best new motion vector
*/
......@@ -981,7 +1041,8 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
rate2 += vp8_cost_mv_ref(this_mode, mdcounts);
x->e_mbd.mode_info_context->mbmi.mv.as_int =
mode_mv[this_mode].as_int;
this_rd = evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x);
this_rd = evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x,
rd_adjustment);
break;
default:
......@@ -1119,7 +1180,8 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
x->e_mbd.mode_info_context->mbmi.mode = ZEROMV;
x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
x->e_mbd.mode_info_context->mbmi.mv.as_int = 0;
this_rd = evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x);
this_rd = evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x,
rd_adjustment);
if (this_rd < best_rd)
{
......
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