Merge remote branch 'origin/master' into experimental

Change-Id: I76ed5f6c24f3f71bba47679ff09d28e046ec1db9
This commit is contained in:
John Koleszar 2010-12-08 00:05:06 -05:00
commit c5795b673d
2 changed files with 276 additions and 236 deletions

View File

@ -243,9 +243,9 @@ struct vp8_token_state{
}; };
// TODO: experiments to find optimal multiple numbers // TODO: experiments to find optimal multiple numbers
#define Y1_RD_MULT 1 #define Y1_RD_MULT 4
#define UV_RD_MULT 1 #define UV_RD_MULT 2
#define Y2_RD_MULT 4 #define Y2_RD_MULT 16
static const int plane_rd_mult[4]= static const int plane_rd_mult[4]=
{ {
@ -309,7 +309,7 @@ void vp8_optimize_b(MACROBLOCK *mb, int ib, int type,
eob = d->eob; eob = d->eob;
/* Now set up a Viterbi trellis to evaluate alternative roundings. */ /* Now set up a Viterbi trellis to evaluate alternative roundings. */
rdmult = (mb->rdmult << 2)*err_mult; rdmult = mb->rdmult * err_mult;
if(mb->e_mbd.mode_info_context->mbmi.ref_frame==INTRA_FRAME) if(mb->e_mbd.mode_info_context->mbmi.ref_frame==INTRA_FRAME)
rdmult = (rdmult * 9)>>4; rdmult = (rdmult * 9)>>4;

View File

@ -1023,46 +1023,46 @@ unsigned char vp8_mbsplit_offset2[4][16] = {
{ 0, 2, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, { 0, 2, 8, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
}; };
static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *best_ref_mv, int best_rd, int *mdcounts, int *returntotrate, int *returnyrate, int *returndistortion, int compressor_speed, int *mvcost[2], int mvthresh, int fullpixel)
static const unsigned int segmentation_to_sseshift[4] = {3, 3, 2, 0};
typedef struct
{ {
int i, segmentation; MV *ref_mv;
B_PREDICTION_MODE this_mode;
MACROBLOCKD *xc = &x->e_mbd; int segment_rd;
BLOCK *c; int segment_num;
BLOCKD *e; int r;
int d;
int segment_yrate;
B_PREDICTION_MODE modes[16];
MV mvs[16];
unsigned char eobs[16];
int mvthresh;
int *mdcounts;
} BEST_SEG_INFO;
void vp8_rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, BEST_SEG_INFO *bsi,
unsigned int segmentation)
{
int i;
int const *labels; int const *labels;
int best_segment_rd = INT_MAX;
int best_seg = 0;
int br = 0; int br = 0;
int bd = 0; int bd = 0;
int bsr = 0; B_PREDICTION_MODE this_mode;
int bsd = 0;
int bestsegmentyrate = 0;
static const int segmentation_to_sseshift[4] = {3, 3, 2, 0};
// FIX TO Rd error outrange bug PGW 9 june 2004
B_PREDICTION_MODE bmodes[16] = {ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4,
ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4,
ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4,
ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4
};
MV bmvs[16];
int beobs[16];
vpx_memset(beobs, 0, sizeof(beobs));
for (segmentation = 0; segmentation < VP8_NUMMBSPLITS; segmentation++)
{
int label_count; int label_count;
int this_segment_rd = 0; int this_segment_rd = 0;
int label_mv_thresh; int label_mv_thresh;
int rate = 0; int rate = 0;
int sbr = 0; int sbr = 0;
int sbd = 0; int sbd = 0;
int sseshift;
int segmentyrate = 0; int segmentyrate = 0;
vp8_variance_fn_ptr_t *v_fn_ptr; vp8_variance_fn_ptr_t *v_fn_ptr;
@ -1086,7 +1086,6 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes
bd = 0; bd = 0;
v_fn_ptr = &cpi->fn_ptr[segmentation]; v_fn_ptr = &cpi->fn_ptr[segmentation];
sseshift = segmentation_to_sseshift[segmentation];
labels = vp8_mbsplits[segmentation]; labels = vp8_mbsplits[segmentation];
label_count = vp8_mbsplit_count[segmentation]; label_count = vp8_mbsplit_count[segmentation];
@ -1094,13 +1093,11 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes
// making it so that we very rarely check mvs on // making it so that we very rarely check mvs on
// segments. setting this to 1 would make mv thresh // segments. setting this to 1 would make mv thresh
// roughly equal to what it is for macroblocks // roughly equal to what it is for macroblocks
label_mv_thresh = 1 * mvthresh / label_count ; label_mv_thresh = 1 * bsi->mvthresh / label_count ;
// Segmentation method overheads // Segmentation method overheads
rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + segmentation); rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + segmentation);
rate += vp8_cost_mv_ref(SPLITMV, bsi->mdcounts);
rate += vp8_cost_mv_ref(SPLITMV, mdcounts);
this_segment_rd += RDFUNC(x->rdmult, x->rddiv, rate, 0, cpi->target_bits_per_mb); this_segment_rd += RDFUNC(x->rdmult, x->rddiv, rate, 0, cpi->target_bits_per_mb);
br += rate; br += rate;
@ -1109,22 +1106,13 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes
MV mode_mv[B_MODE_COUNT]; MV mode_mv[B_MODE_COUNT];
int best_label_rd = INT_MAX; int best_label_rd = INT_MAX;
B_PREDICTION_MODE mode_selected = ZERO4X4; B_PREDICTION_MODE mode_selected = ZERO4X4;
int j;
int bestlabelyrate = 0; int bestlabelyrate = 0;
// find first label
j = vp8_mbsplit_offset2[segmentation][i];
c = &x->block[j];
e = &x->e_mbd.block[j];
// search for the best motion vector on this segment // search for the best motion vector on this segment
for (this_mode = LEFT4X4; this_mode <= NEW4X4 ; this_mode ++) for (this_mode = LEFT4X4; this_mode <= NEW4X4 ; this_mode ++)
{ {
int distortion;
int this_rd; int this_rd;
int num00; int distortion;
int labelyrate; int labelyrate;
ENTROPY_CONTEXT_PLANES t_above_s, t_left_s; ENTROPY_CONTEXT_PLANES t_above_s, t_left_s;
ENTROPY_CONTEXT *ta_s; ENTROPY_CONTEXT *ta_s;
@ -1138,12 +1126,16 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes
if (this_mode == NEW4X4) if (this_mode == NEW4X4)
{ {
int sseshift;
int num00;
int step_param = 0; int step_param = 0;
int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
int n; int n;
int thissme; int thissme;
int bestsme = INT_MAX; int bestsme = INT_MAX;
MV temp_mv; MV temp_mv;
BLOCK *c;
BLOCKD *e;
// Is the best so far sufficiently good that we cant justify doing and new motion search. // Is the best so far sufficiently good that we cant justify doing and new motion search.
if (best_label_rd < label_mv_thresh) if (best_label_rd < label_mv_thresh)
@ -1152,11 +1144,21 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes
{ {
int sadpb = x->sadperbit4; int sadpb = x->sadperbit4;
// find first label
n = vp8_mbsplit_offset2[segmentation][i];
c = &x->block[n];
e = &x->e_mbd.block[n];
if (cpi->sf.search_method == HEX) if (cpi->sf.search_method == HEX)
bestsme = vp8_hex_search(x, c, e, best_ref_mv, &mode_mv[NEW4X4], step_param, sadpb/*x->errorperbit*/, &num00, v_fn_ptr, x->mvsadcost, mvcost); bestsme = vp8_hex_search(x, c, e, bsi->ref_mv,
&mode_mv[NEW4X4], step_param, sadpb, &num00, v_fn_ptr, x->mvsadcost, x->mvcost);
else else
{ {
bestsme = cpi->diamond_search_sad(x, c, e, best_ref_mv, &mode_mv[NEW4X4], step_param, sadpb / 2/*x->errorperbit*/, &num00, v_fn_ptr, x->mvsadcost, mvcost, best_ref_mv); bestsme = cpi->diamond_search_sad(x, c, e, bsi->ref_mv,
&mode_mv[NEW4X4], step_param,
sadpb / 2, &num00, v_fn_ptr, x->mvsadcost, x->mvcost, bsi->ref_mv);
n = num00; n = num00;
num00 = 0; num00 = 0;
@ -1169,7 +1171,9 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes
num00--; num00--;
else else
{ {
thissme = cpi->diamond_search_sad(x, c, e, best_ref_mv, &temp_mv, step_param + n, sadpb / 2/*x->errorperbit*/, &num00, v_fn_ptr, x->mvsadcost, mvcost, best_ref_mv); thissme = cpi->diamond_search_sad(x, c, e, bsi->ref_mv,
&temp_mv, step_param + n,
sadpb / 2, &num00, v_fn_ptr, x->mvsadcost, x->mvcost, bsi->ref_mv);
if (thissme < bestsme) if (thissme < bestsme)
{ {
@ -1181,10 +1185,13 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes
} }
} }
sseshift = segmentation_to_sseshift[segmentation];
// Should we do a full search (best quality only) // Should we do a full search (best quality only)
if ((compressor_speed == 0) && (bestsme >> sseshift) > 4000) if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000)
{ {
thissme = cpi->full_search_sad(x, c, e, best_ref_mv, sadpb / 4, 16, v_fn_ptr, x->mvcost, x->mvsadcost, best_ref_mv); thissme = cpi->full_search_sad(x, c, e, bsi->ref_mv,
sadpb / 4, 16, v_fn_ptr, x->mvcost, x->mvsadcost,bsi->ref_mv);
if (thissme < bestsme) if (thissme < bestsme)
{ {
@ -1201,14 +1208,17 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes
if (bestsme < INT_MAX) if (bestsme < INT_MAX)
{ {
if (!fullpixel) if (!cpi->common.full_pixel)
cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4], best_ref_mv, x->errorperbit / 2, v_fn_ptr, mvcost); cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4],
bsi->ref_mv, x->errorperbit / 2, v_fn_ptr, x->mvcost);
else else
vp8_skip_fractional_mv_step(x, c, e, &mode_mv[NEW4X4], best_ref_mv, x->errorperbit, v_fn_ptr, mvcost); vp8_skip_fractional_mv_step(x, c, e, &mode_mv[NEW4X4],
} bsi->ref_mv, x->errorperbit, v_fn_ptr, x->mvcost);
} }
} /* NEW4X4 */
rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode], best_ref_mv, mvcost); rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode],
bsi->ref_mv, x->mvcost);
// Trap vectors that reach beyond the UMV borders // Trap vectors that reach beyond the UMV borders
if (((mode_mv[this_mode].row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].row >> 3) > x->mv_row_max) || if (((mode_mv[this_mode].row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].row >> 3) > x->mv_row_max) ||
@ -1236,72 +1246,101 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *bes
vpx_memcpy(tl_b, tl_s, sizeof(ENTROPY_CONTEXT_PLANES)); vpx_memcpy(tl_b, tl_s, sizeof(ENTROPY_CONTEXT_PLANES));
} }
} } /*for each 4x4 mode*/
vpx_memcpy(ta, ta_b, sizeof(ENTROPY_CONTEXT_PLANES)); vpx_memcpy(ta, ta_b, sizeof(ENTROPY_CONTEXT_PLANES));
vpx_memcpy(tl, tl_b, sizeof(ENTROPY_CONTEXT_PLANES)); vpx_memcpy(tl, tl_b, sizeof(ENTROPY_CONTEXT_PLANES));
labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected], best_ref_mv, mvcost); labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected],
bsi->ref_mv, x->mvcost);
br += sbr; br += sbr;
bd += sbd; bd += sbd;
segmentyrate += bestlabelyrate; segmentyrate += bestlabelyrate;
this_segment_rd += best_label_rd; this_segment_rd += best_label_rd;
if ((this_segment_rd > best_rd) || (this_segment_rd > best_segment_rd)) if (this_segment_rd > bsi->segment_rd)
break; break;
} } /* for each label */
if ((this_segment_rd <= best_rd) && (this_segment_rd < best_segment_rd)) if (this_segment_rd < bsi->segment_rd)
{ {
bsr = br; bsi->r = br;
bsd = bd; bsi->d = bd;
bestsegmentyrate = segmentyrate; bsi->segment_yrate = segmentyrate;
best_segment_rd = this_segment_rd; bsi->segment_rd = this_segment_rd;
best_seg = segmentation; bsi->segment_num = segmentation;
// store everything needed to come back to this!! // store everything needed to come back to this!!
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{ {
BLOCKD *bd = &x->e_mbd.block[i]; BLOCKD *bd = &x->e_mbd.block[i];
bmvs[i] = bd->bmi.mv.as_mv; bsi->mvs[i] = bd->bmi.mv.as_mv;
bmodes[i] = bd->bmi.mode; bsi->modes[i] = bd->bmi.mode;
beobs[i] = bd->eob; bsi->eobs[i] = bd->eob;
} }
} }
} }
static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x,
MV *best_ref_mv, int best_rd,
int *mdcounts, int *returntotrate,
int *returnyrate, int *returndistortion,
int mvthresh)
{
int i;
BEST_SEG_INFO bsi;
BEST_SEG_INFO bsi_8x8;
int check_8x16 = 0;
int check_16x8 = 0;
vpx_memset(&bsi, 0, sizeof(bsi));
bsi.segment_rd = best_rd;
bsi.ref_mv = best_ref_mv;
bsi.mvthresh = mvthresh;
bsi.mdcounts = mdcounts;
for(i = 0; i < 16; i++)
{
bsi.modes[i] = ZERO4X4;
}
// set it to the best /* original */
vp8_rd_check_segment(cpi, x, &bsi, 0);
vp8_rd_check_segment(cpi, x, &bsi, 1);
vp8_rd_check_segment(cpi, x, &bsi, 2);
vp8_rd_check_segment(cpi, x, &bsi, 3);
/* set it to the best */
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{ {
BLOCKD *bd = &x->e_mbd.block[i]; BLOCKD *bd = &x->e_mbd.block[i];
bd->bmi.mv.as_mv = bmvs[i]; bd->bmi.mv.as_mv = bsi.mvs[i];
bd->bmi.mode = bmodes[i]; bd->bmi.mode = bsi.modes[i];
bd->eob = beobs[i]; bd->eob = bsi.eobs[i];
} }
*returntotrate = bsr; *returntotrate = bsi.r;
*returndistortion = bsd; *returndistortion = bsi.d;
*returnyrate = bestsegmentyrate; *returnyrate = bsi.segment_yrate;
// save partitions /* save partitions */
labels = vp8_mbsplits[best_seg]; x->e_mbd.mode_info_context->mbmi.partitioning = bsi.segment_num;
x->e_mbd.mode_info_context->mbmi.partitioning = best_seg; x->partition_info->count = vp8_mbsplit_count[bsi.segment_num];
x->partition_info->count = vp8_mbsplit_count[best_seg];
for (i = 0; i < x->partition_info->count; i++) for (i = 0; i < x->partition_info->count; i++)
{ {
int j; int j;
j = vp8_mbsplit_offset2[best_seg][i]; j = vp8_mbsplit_offset2[bsi.segment_num][i];
x->partition_info->bmi[i].mode = x->e_mbd.block[j].bmi.mode; x->partition_info->bmi[i].mode = x->e_mbd.block[j].bmi.mode;
x->partition_info->bmi[i].mv.as_mv = x->e_mbd.block[j].bmi.mv.as_mv; x->partition_info->bmi[i].mv.as_mv = x->e_mbd.block[j].bmi.mv.as_mv;
} }
return best_segment_rd; return bsi.segment_rd;
} }
@ -1853,14 +1892,6 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
frame_cost = ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame]; frame_cost = ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
rate2 += frame_cost; rate2 += frame_cost;
if (this_mode <= B_PRED)
{
for (i = 0; i < 16; i++)
{
vpx_memset(&x->e_mbd.block[i].bmi, 0, sizeof(B_MODE_INFO));
}
}
// Check to see if the testing frequency for this mode is at its max // Check to see if the testing frequency for this mode is at its max
// If so then prevent it from being tested and increase the threshold for its testing // If so then prevent it from being tested and increase the threshold for its testing
if (cpi->mode_test_hit_counts[mode_index] && (cpi->mode_check_freq[mode_index] > 1)) if (cpi->mode_test_hit_counts[mode_index] && (cpi->mode_check_freq[mode_index] > 1))
@ -1909,6 +1940,10 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
{ {
case B_PRED: case B_PRED:
for (i = 0; i < 16; i++)
{
vpx_memset(&x->e_mbd.block[i].bmi, 0, sizeof(B_MODE_INFO));
}
// Note the rate value returned here includes the cost of coding the BPRED mode : x->mbmode_cost[x->e_mbd.frame_type][BPRED]; // Note the rate value returned here includes the cost of coding the BPRED mode : x->mbmode_cost[x->e_mbd.frame_type][BPRED];
vp8_rd_pick_intra4x4mby_modes(cpi, x, &rate, &rate_y, &distortion); vp8_rd_pick_intra4x4mby_modes(cpi, x, &rate, &rate_y, &distortion);
rate2 += rate; rate2 += rate;
@ -1928,13 +1963,14 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
// (best_rd - frame_cost_rd) is thus a conservative breakout number. // (best_rd - frame_cost_rd) is thus a conservative breakout number.
int breakout_rd = best_rd - frame_cost_rd; int breakout_rd = best_rd - frame_cost_rd;
int tmp_rd; int tmp_rd;
int this_rd_thresh;
if (x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME) this_rd_thresh = (x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME) ? cpi->rd_threshes[THR_NEWMV] : cpi->rd_threshes[THR_NEWA];
tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, breakout_rd, mdcounts, &rate, &rate_y, &distortion, cpi->compressor_speed, x->mvcost, cpi->rd_threshes[THR_NEWMV], cpi->common.full_pixel) ; this_rd_thresh = (x->e_mbd.mode_info_context->mbmi.ref_frame == GOLDEN_FRAME) ? cpi->rd_threshes[THR_NEWG]: this_rd_thresh;
else if (x->e_mbd.mode_info_context->mbmi.ref_frame == GOLDEN_FRAME)
tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, breakout_rd, mdcounts, &rate, &rate_y, &distortion, cpi->compressor_speed, x->mvcost, cpi->rd_threshes[THR_NEWG], cpi->common.full_pixel) ; tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv,
else breakout_rd, mdcounts,
tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, breakout_rd, mdcounts, &rate, &rate_y, &distortion, cpi->compressor_speed, x->mvcost, cpi->rd_threshes[THR_NEWA], cpi->common.full_pixel) ; &rate, &rate_y, &distortion, this_rd_thresh) ;
rate2 += rate; rate2 += rate;
distortion2 += distortion; distortion2 += distortion;
@ -2007,6 +2043,10 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
case V_PRED: case V_PRED:
case H_PRED: case H_PRED:
case TM_PRED: case TM_PRED:
for (i = 0; i < 16; i++)
{
vpx_memset(&x->e_mbd.block[i].bmi, 0, sizeof(B_MODE_INFO));
}
x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME; x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
vp8_build_intra_predictors_mby_ptr(&x->e_mbd); vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
{ {