/* * Copyright (c) 2010 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
typedefstruct rate_distortion_struct { int rate2; int rate_y; int rate_uv; int distortion2; int distortion_uv;
} RATE_DISTORTION;
typedefstruct best_mode_struct { int yrd; int rd; int intra_rd;
MB_MODE_INFO mbmode; union b_mode_info bmodes[16];
PARTITION_INFO partition;
} BEST_MODE;
/* This table determines the search order in reference frame priority order, * which may not necessarily match INTRA,LAST,GOLDEN,ARF
*/ constint vp8_ref_frame_order[MAX_MODES] = {
1, 0,
1, 1,
2, 2,
3, 3,
2, 3,
0, 0, 0,
1, 2, 3,
1, 2, 3,
0,
};
staticvoid fill_token_costs( int c[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS], const vp8_prob p[BLOCK_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS]
[ENTROPY_NODES]) { int i, j, k;
for (i = 0; i < BLOCK_TYPES; ++i) { for (j = 0; j < COEF_BANDS; ++j) { for (k = 0; k < PREV_COEF_CONTEXTS; ++k) { /* check for pt=0 and band > 1 if block type 0 * and 0 if blocktype 1
*/ if (k == 0 && j > (i == 0)) {
vp8_cost_tokens2(c[i][j][k], p[i][j][k], vp8_coef_tree, 2);
} else {
vp8_cost_tokens(c[i][j][k], p[i][j][k], vp8_coef_tree);
}
}
}
}
}
void vp8_initialize_rd_consts(VP8_COMP *cpi, MACROBLOCK *x, int Qvalue) { int q; int i; double capped_q = (Qvalue < 160) ? (double)Qvalue : 160.0; double rdconst = 2.80;
vpx_clear_system_state();
/* Further tests required to see if optimum is different * for key frames, golden frames and arf frames.
*/
cpi->RDMULT = (int)(rdconst * (capped_q * capped_q));
/* Extend rate multiplier along side quantizer zbin increases */ if (cpi->mb.zbin_over_quant > 0) { double oq_factor; double modq;
/* Experimental code using the same basic equation as used for Q above * The units of cpi->mb.zbin_over_quant are 1/128 of Q bin size
*/
oq_factor = 1.0 + ((double)0.0015625 * cpi->mb.zbin_over_quant);
modq = (int)((double)capped_q * oq_factor);
cpi->RDMULT = (int)(rdconst * (modq * modq));
}
staticint cost_coeffs(MACROBLOCK *mb, BLOCKD *b, int type, ENTROPY_CONTEXT *a,
ENTROPY_CONTEXT *l) { int c = !type; /* start at coef 0, unless Y with Y2 */ int eob = (int)(*b->eob); int pt; /* surrounding block/prev coef predictor */ int cost = 0; short *qcoeff_ptr = b->qcoeff;
VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
assert(eob <= 16); for (; c < eob; ++c) { constint v = qcoeff_ptr[vp8_default_zig_zag1d[c]]; constint t = vp8_dct_value_tokens_ptr[v].Token;
cost += mb->token_costs[type][vp8_coef_bands[c]][pt][t];
cost += vp8_dct_value_cost_ptr[v];
pt = vp8_prev_token_class[t];
}
if (c < 16) {
cost += mb->token_costs[type][vp8_coef_bands[c]][pt][DCT_EOB_TOKEN];
}
pt = (c != !type); /* is eob first coefficient; */
*a = *l = pt;
int *bestrate, int *bestratey, int *bestdistortion) {
B_PREDICTION_MODE mode; int best_rd = INT_MAX; int rate = 0; int distortion;
ENTROPY_CONTEXT ta = *a, tempa = *a;
ENTROPY_CONTEXT tl = *l, templ = *l; /* * The predictor buffer is a 2d buffer with a stride of 16. Create * a temp buffer that meets the stride requirements, but we are only * interested in the left 4x4 block
* */
DECLARE_ALIGNED(16, unsignedchar, best_predictor[16 * 4]);
DECLARE_ALIGNED(16, short, best_dqcoeff[16]); int dst_stride = x->e_mbd.dst.y_stride; unsignedchar *dst = x->e_mbd.dst.y_buffer + b->offset;
for (i = 0; i < 16; ++i) {
MODE_INFO *const mic = xd->mode_info_context; constint mis = xd->mode_info_stride;
B_PREDICTION_MODE best_mode = B_MODE_COUNT; int r = 0, ry = 0, d = 0;
if (mb->e_mbd.frame_type == KEY_FRAME) { const B_PREDICTION_MODE A = above_block_mode(mic, i, mis); const B_PREDICTION_MODE L = left_block_mode(mic, i);
bmode_costs = mb->bmode_costs[A][L];
}
total_rd += rd_pick_intra4x4block(
mb, mb->block + i, xd->block + i, &best_mode, bmode_costs,
ta + vp8_block2above[i], tl + vp8_block2left[i], &r, &ry, &d);
staticint rd_pick_intra16x16mby_mode(MACROBLOCK *x, int *Rate, int *rate_y, int *Distortion) {
MB_PREDICTION_MODE mode;
MB_PREDICTION_MODE mode_selected = MB_MODE_COUNT; int rate, ratey; int distortion; int best_rd = INT_MAX; int this_rd;
MACROBLOCKD *xd = &x->e_mbd;
/* Y Search for 16x16 intra prediction mode */ for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
xd->mode_info_context->mbmi.mode = mode;
staticvoid rd_pick_intra_mbuv_mode(MACROBLOCK *x, int *rate, int *rate_tokenonly, int *distortion) {
MB_PREDICTION_MODE mode;
MB_PREDICTION_MODE mode_selected = MB_MODE_COUNT; int best_rd = INT_MAX; int d = 0, r = 0; int rate_to;
MACROBLOCKD *xd = &x->e_mbd;
for (mode = DC_PRED; mode <= TM_PRED; ++mode) { int this_rate; int this_distortion; int this_rd;
staticint labels2mode(MACROBLOCK *x, intconst *labelings, int which_label,
B_PREDICTION_MODE this_mode, int_mv *this_mv,
int_mv *best_ref_mv, int *mvcost[2]) {
MACROBLOCKD *const xd = &x->e_mbd;
MODE_INFO *const mic = xd->mode_info_context; constint mis = xd->mode_info_stride;
int cost = 0; int thismvcost = 0;
/* We have to be careful retrieving previously-encoded motion vectors. Ones from this macroblock have to be pulled from the BLOCKD array
as they have not yet made it to the bmi array in our MB_MODE_INFO. */
int i = 0;
do {
BLOCKD *const d = xd->block + i; constint row = i >> 2, col = i & 3;
B_PREDICTION_MODE m;
if (labelings[i] != which_label) continue;
if (col && labelings[i] == labelings[i - 1]) {
m = LEFT4X4;
} elseif (row && labelings[i] == labelings[i - 4]) {
m = ABOVE4X4;
} else { /* the only time we should do costing for new motion vector * or mode is when we are on a new label (jbb May 08, 2007)
*/ switch (m = this_mode) { case NEW4X4:
thismvcost = vp8_mv_bit_cost(this_mv, best_ref_mv, mvcost, 102); break; case LEFT4X4:
this_mv->as_int = col ? d[-1].bmi.mv.as_int : left_block_mv(mic, i); break; case ABOVE4X4:
this_mv->as_int =
row ? d[-4].bmi.mv.as_int : above_block_mv(mic, i, mis); break; case ZERO4X4: this_mv->as_int = 0; break; default: break;
}
if (m == ABOVE4X4) { /* replace above with left if same */
int_mv left_mv;
left_mv.as_int = col ? d[-1].bmi.mv.as_int : left_block_mv(mic, i);
if (left_mv.as_int == this_mv->as_int) m = LEFT4X4;
}
cost = x->inter_bmode_costs[m];
}
d->bmi.mv.as_int = this_mv->as_int;
x->partition_info->bmi[i].mode = m;
x->partition_info->bmi[i].mv.as_int = this_mv->as_int;
} while (++i < 16);
cost += thismvcost; return cost;
}
staticint rdcost_mbsegment_y(MACROBLOCK *mb, constint *labels, int which_label, ENTROPY_CONTEXT *ta,
ENTROPY_CONTEXT *tl) { int cost = 0; int b;
MACROBLOCKD *x = &mb->e_mbd;
for (b = 0; b < 16; ++b) { if (labels[b] == which_label) {
cost += cost_coeffs(mb, x->block + b, PLANE_TYPE_Y_WITH_DC,
ta + vp8_block2above[b], tl + vp8_block2left[b]);
}
}
return cost;
} staticunsignedint vp8_encode_inter_mb_segment(MACROBLOCK *x, intconst *labels, int which_label) { int i; unsignedint distortion = 0; int pre_stride = x->e_mbd.pre.y_stride; unsignedchar *base_pre = x->e_mbd.pre.y_buffer;
for (i = 0; i < 16; ++i) { if (labels[i] == which_label) {
BLOCKD *bd = &x->e_mbd.block[i];
BLOCK *be = &x->block[i];
/* 64 makes this threshold really big effectively making it so that we * very rarely check mvs on segments. setting this to 1 would make mv * thresh roughly equal to what it is for macroblocks
*/
label_mv_thresh = 1 * bsi->mvthresh / label_count;
for (i = 0; i < label_count; ++i) {
int_mv mode_mv[B_MODE_COUNT] = { { 0 }, { 0 } }; int best_label_rd = INT_MAX;
B_PREDICTION_MODE mode_selected = ZERO4X4; int bestlabelyrate = 0;
/* search for the best motion vector on this segment */ for (this_mode = LEFT4X4; this_mode <= NEW4X4; ++this_mode) { int this_rd; int distortion; int labelyrate;
ENTROPY_CONTEXT_PLANES t_above_s, t_left_s;
ENTROPY_CONTEXT *ta_s;
ENTROPY_CONTEXT *tl_s;
if (this_mode == NEW4X4) { int sseshift; int num00; int step_param = 0; int further_steps; int n; int thissme; int bestsme = INT_MAX;
int_mv temp_mv;
BLOCK *c;
BLOCKD *e;
/* Is the best so far sufficiently good that we can't justify * doing a new motion search.
*/ if (best_label_rd < label_mv_thresh) break;
if (cpi->compressor_speed) { if (segmentation == BLOCK_8X16 || segmentation == BLOCK_16X8) {
bsi->mvp.as_int = bsi->sv_mvp[i].as_int; if (i == 1 && segmentation == BLOCK_16X8) {
bsi->mvp.as_int = bsi->sv_mvp[2].as_int;
}
step_param = bsi->sv_istep[i];
}
/* use previous block's result as next block's MV * predictor.
*/ if (segmentation == BLOCK_4X4 && i > 0) {
bsi->mvp.as_int = x->e_mbd.block[i - 1].bmi.mv.as_int; if (i == 4 || i == 8 || i == 12) {
bsi->mvp.as_int = x->e_mbd.block[i - 4].bmi.mv.as_int;
}
step_param = 2;
}
}
/* Should we do a full search (best quality only) */ if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000) { /* Check if mvp_full is within the range. */
vp8_clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max, x->mv_row_min,
x->mv_row_max);
if (thissme < bestsme) {
bestsme = thissme;
mode_mv[NEW4X4].as_int = e->bmi.mv.as_int;
} else { /* The full search result is actually worse so * re-instate the previous best vector
*/
e->bmi.mv.as_int = mode_mv[NEW4X4].as_int;
}
}
}
if (bestsme < INT_MAX) { int disto; unsignedint sse;
cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4], bsi->ref_mv,
x->errorperbit, v_fn_ptr, x->mvcost,
&disto, &sse);
}
} /* NEW4X4 */
rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode],
bsi->ref_mv, x->mvcost);
/* store everything needed to come back to this!! */ for (i = 0; i < 16; ++i) {
bsi->mvs[i].as_mv = x->partition_info->bmi[i].mv.as_mv;
bsi->modes[i] = x->partition_info->bmi[i].mode;
bsi->eobs[i] = x->e_mbd.eobs[i];
}
}
}
staticvoid vp8_cal_step_param(int sr, int *sp) { int step = 0;
if (sr > MAX_FIRST_STEP) {
sr = MAX_FIRST_STEP;
} elseif (sr < 1) {
sr = 1;
}
while (sr >>= 1) step++;
*sp = MAX_MVSEARCH_STEPS - 1 - step;
}
staticint vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x,
int_mv *best_ref_mv, int best_rd, int *mdcounts, int *returntotrate, int *returnyrate, int *returndistortion, int mvthresh) { int i;
BEST_SEG_INFO bsi;
for (i = 0; i < 16; ++i) {
bsi.modes[i] = ZERO4X4;
}
if (cpi->compressor_speed == 0) { /* for now, we will keep the original segmentation order
when in best quality mode */
rd_check_segment(cpi, x, &bsi, BLOCK_16X8);
rd_check_segment(cpi, x, &bsi, BLOCK_8X16);
rd_check_segment(cpi, x, &bsi, BLOCK_8X8);
rd_check_segment(cpi, x, &bsi, BLOCK_4X4);
} else { int sr;
rd_check_segment(cpi, x, &bsi, BLOCK_8X8);
if (bsi.segment_rd < best_rd) { int col_min = ((best_ref_mv->as_mv.col + 7) >> 3) - MAX_FULL_PEL_VAL; int row_min = ((best_ref_mv->as_mv.row + 7) >> 3) - MAX_FULL_PEL_VAL; int col_max = (best_ref_mv->as_mv.col >> 3) + MAX_FULL_PEL_VAL; int row_max = (best_ref_mv->as_mv.row >> 3) + MAX_FULL_PEL_VAL;
int tmp_col_min = x->mv_col_min; int tmp_col_max = x->mv_col_max; int tmp_row_min = x->mv_row_min; int tmp_row_max = x->mv_row_max;
/* Get intersection of UMV window and valid MV window to reduce # of
* checks in diamond search. */ if (x->mv_col_min < col_min) x->mv_col_min = col_min; if (x->mv_col_max > col_max) x->mv_col_max = col_max; if (x->mv_row_min < row_min) x->mv_row_min = row_min; if (x->mv_row_max > row_max) x->mv_row_max = row_max;
/* Get 8x8 result */
bsi.sv_mvp[0].as_int = bsi.mvs[0].as_int;
bsi.sv_mvp[1].as_int = bsi.mvs[2].as_int;
bsi.sv_mvp[2].as_int = bsi.mvs[8].as_int;
bsi.sv_mvp[3].as_int = bsi.mvs[10].as_int;
/* Use 8x8 result as 16x8/8x16's predictor MV. Adjust search range
* according to the closeness of 2 MV. */ /* block 8X16 */
{
sr =
MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[2].as_mv.row)) >> 3,
(abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[2].as_mv.col)) >> 3);
vp8_cal_step_param(sr, &bsi.sv_istep[0]);
/* calculate sad for current frame 3 nearby MBs. */ if (xd->mb_to_top_edge == 0 && xd->mb_to_left_edge == 0) {
near_sad[0] = near_sad[1] = near_sad[2] = INT_MAX;
} elseif (xd->mb_to_top_edge ==
0) { /* only has left MB for sad calculation. */
near_sad[0] = near_sad[2] = INT_MAX;
near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(
src_y_ptr, b->src_stride, xd->dst.y_buffer - 16, xd->dst.y_stride);
} elseif (xd->mb_to_left_edge ==
0) { /* only has left MB for sad calculation. */
near_sad[1] = near_sad[2] = INT_MAX;
near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(
src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16,
xd->dst.y_stride);
} else {
near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(
src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16,
xd->dst.y_stride);
near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(
src_y_ptr, b->src_stride, xd->dst.y_buffer - 16, xd->dst.y_stride);
near_sad[2] = cpi->fn_ptr[BLOCK_16X16].sdf(
src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16 - 16,
xd->dst.y_stride);
}
if (cpi->common.last_frame_type != KEY_FRAME) { /* calculate sad for last frame 5 nearby MBs. */ unsignedchar *pre_y_buffer =
cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_buffer + recon_yoffset; int pre_y_stride = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_stride;
if (xd->mb_to_top_edge == 0) near_sad[4] = INT_MAX; if (xd->mb_to_left_edge == 0) near_sad[5] = INT_MAX; if (xd->mb_to_right_edge == 0) near_sad[6] = INT_MAX; if (xd->mb_to_bottom_edge == 0) near_sad[7] = INT_MAX;
if (threshold < x->encode_breakout) threshold = x->encode_breakout;
var = vpx_variance16x16(*(b->base_src), b->src_stride, x->e_mbd.predictor,
16, &sse);
if (sse < threshold) { unsignedint q2dc = xd->block[24].dequant[0]; /* If theres is no codeable 2nd order dc
or a very small uniform pixel change change */ if ((sse - var < q2dc * q2dc >> 4) || (sse / 2 > var && sse - var < 64)) { /* Check u and v to make sure skip is ok */ unsignedint sse2 = VP8_UVSSE(x); if (sse2 * 2 < threshold) {
x->skip = 1;
rd->distortion2 = sse + sse2;
rd->rate2 = 500;
staticint calculate_final_rd_costs(int this_rd, RATE_DISTORTION *rd, int *other_cost, int disable_skip, int uv_intra_tteob, int intra_rd_penalty,
VP8_COMP *cpi, MACROBLOCK *x) {
MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode;
/* Where skip is allowable add in the default per mb cost for the no * skip case. where we then decide to skip we have to delete this and * replace it with the cost of signalling a skip
*/ if (cpi->common.mb_no_coeff_skip) {
*other_cost += vp8_cost_bit(cpi->prob_skip_false, 0);
rd->rate2 += *other_cost;
}
/* Estimate the reference frame signaling cost and add it * to the rolling cost variable.
*/
rd->rate2 += x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
if (!disable_skip) { /* Test for the condition where skip block will be activated * because there are no non zero coefficients and make any * necessary adjustment for rate
*/ if (cpi->common.mb_no_coeff_skip) { int i; int tteob; int has_y2_block = (this_mode != SPLITMV && this_mode != B_PRED);
tteob = 0; if (has_y2_block) tteob += x->e_mbd.eobs[24];
for (i = 0; i < 16; ++i) tteob += (x->e_mbd.eobs[i] > has_y2_block);
if (x->e_mbd.mode_info_context->mbmi.ref_frame) { for (i = 16; i < 24; ++i) tteob += x->e_mbd.eobs[i];
} else {
tteob += uv_intra_tteob;
}
if (tteob == 0) {
rd->rate2 -= (rd->rate_y + rd->rate_uv); /* for best_yrd calculation */
rd->rate_uv = 0;
/* Back out no skip flag costing and add in skip flag costing */ if (cpi->prob_skip_false) { int prob_skip_cost;
prob_skip_cost = vp8_cost_bit(cpi->prob_skip_false, 1);
prob_skip_cost -= (int)vp8_cost_bit(cpi->prob_skip_false, 0);
rd->rate2 += prob_skip_cost;
*other_cost += prob_skip_cost;
}
}
} /* Calculate the final RD estimate for this mode */
this_rd = RDCOST(x->rdmult, x->rddiv, rd->rate2, rd->distortion2); if (this_rd < INT_MAX &&
x->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
this_rd += intra_rd_penalty;
}
} return this_rd;
}
staticvoid update_best_mode(BEST_MODE *best_mode, int this_rd,
RATE_DISTORTION *rd, int other_cost,
MACROBLOCK *x) {
MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode;
/* Calculate the final y RD estimate for this mode */
best_mode->yrd =
RDCOST(x->rdmult, x->rddiv, (rd->rate2 - rd->rate_uv - other_cost),
(rd->distortion2 - rd->distortion_uv));
if ((this_mode == B_PRED) || (this_mode == SPLITMV)) { int i; for (i = 0; i < 16; ++i) {
best_mode->bmodes[i] = x->e_mbd.block[i].bmi;
}
}
}
void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra, int mb_row, int mb_col) {
BLOCK *b = &x->block[0];
BLOCKD *d = &x->e_mbd.block[0];
MACROBLOCKD *xd = &x->e_mbd;
int_mv best_ref_mv_sb[2];
int_mv mode_mv_sb[2][MB_MODE_COUNT];
int_mv best_ref_mv;
int_mv *mode_mv;
MB_PREDICTION_MODE this_mode; int num00; int best_mode_index = 0;
BEST_MODE best_mode;
int i; int mode_index; int mdcounts[4]; int rate;
RATE_DISTORTION rd; int uv_intra_rate, uv_intra_distortion, uv_intra_rate_tokenonly; int uv_intra_tteob = 0; int uv_intra_done = 0;
MB_PREDICTION_MODE uv_intra_mode = 0;
int_mv mvp; int near_sadidx[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; int saddone = 0; /* search range got from mv_pred(). It uses step_param levels. (0-7) */ int sr = 0;
unsignedchar *plane[4][3] = { { 0, 0 } }; int ref_frame_map[4]; int sign_bias = 0;
int intra_rd_penalty =
10 * vp8_dc_quant(cpi->common.base_qindex, cpi->common.y1dc_delta_q);
/* Check to see if there is at least 1 valid reference frame that we need * to calculate near_mvs.
*/ if (ref_frame_map[1] > 0) {
sign_bias = vp8_find_near_mvs_bias(
&x->e_mbd, x->e_mbd.mode_info_context, mode_mv_sb, best_ref_mv_sb,
mdcounts, ref_frame_map[1], cpi->common.ref_frame_sign_bias);
*returnintra = INT_MAX; /* Count of the number of MBs tested so far this frame */
x->mbs_tested_so_far++;
x->skip = 0;
for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) { int this_rd = INT_MAX; int disable_skip = 0; int other_cost = 0; int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]];
/* Test best rd so far against threshold for trying this mode. */ if (best_mode.rd <= x->rd_threshes[mode_index]) continue;
if (this_ref_frame < 0) continue;
/* These variables hold are rolling total cost and distortion for * this mode
*/
rd.rate2 = 0;
rd.distortion2 = 0;
/* Only consider ZEROMV/ALTREF_FRAME for alt ref frame, * unless ARNR filtering is enabled in which case we want * an unfiltered alternative
*/ if (cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) { if (this_mode != ZEROMV ||
x->e_mbd.mode_info_context->mbmi.ref_frame != ALTREF_FRAME) { continue;
}
}
/* everything but intra */ if (x->e_mbd.mode_info_context->mbmi.ref_frame) {
assert(plane[this_ref_frame][0] != NULL &&
plane[this_ref_frame][1] != NULL &&
plane[this_ref_frame][2] != NULL);
x->e_mbd.pre.y_buffer = plane[this_ref_frame][0];
x->e_mbd.pre.u_buffer = plane[this_ref_frame][1];
x->e_mbd.pre.v_buffer = plane[this_ref_frame][2];
/* 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 (x->mode_test_hit_counts[mode_index] &&
(cpi->mode_check_freq[mode_index] > 1)) { if (x->mbs_tested_so_far <= cpi->mode_check_freq[mode_index] *
x->mode_test_hit_counts[mode_index]) { /* Increase the threshold for coding this mode to make it * less likely to be chosen
*/
x->rd_thresh_mult[mode_index] += 4;
if (x->rd_thresh_mult[mode_index] > MAX_THRESHMULT) {
x->rd_thresh_mult[mode_index] = MAX_THRESHMULT;
}
/* We have now reached the point where we are going to test the * current mode so increment the counter for the number of times * it has been tested
*/
x->mode_test_hit_counts[mode_index]++;
/* Experimental code. Special case for gf and arf zeromv modes. * Increase zbin size to supress noise
*/ if (x->zbin_mode_boost_enabled) { if (this_ref_frame == INTRA_FRAME) {
x->zbin_mode_boost = 0;
} else { if (vp8_mode_order[mode_index] == ZEROMV) { if (this_ref_frame != LAST_FRAME) {
x->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
} else {
x->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
}
} elseif (vp8_mode_order[mode_index] == SPLITMV) {
x->zbin_mode_boost = 0;
} else {
x->zbin_mode_boost = MV_ZBIN_BOOST;
}
}
/* * Total of the eobs is used later to further adjust rate2. Since uv * block's intra eobs will be overwritten when we check inter modes, * we need to save uv_intra_tteob here.
*/ for (i = 16; i < 24; ++i) uv_intra_tteob += x->e_mbd.eobs[i];
uv_intra_done = 1;
}
switch (this_mode) { case B_PRED: { int tmp_rd;
/* Note the rate value returned here includes the cost of * coding the BPRED mode: x->mbmode_cost[x->e_mbd.frame_type][BPRED]
*/ int distortion;
tmp_rd = rd_pick_intra4x4mby_modes(x, &rate, &rd.rate_y, &distortion,
best_mode.yrd);
rd.rate2 += rate;
rd.distortion2 += distortion;
/* If even the 'Y' rd value of split is higher than best so far * then don't bother looking at UV
*/ if (tmp_rd < best_mode.yrd) { /* Now work out UV cost and add it in */
rd_inter4x4_uv(cpi, x, &rd.rate_uv, &rd.distortion_uv,
cpi->common.full_pixel);
rd.rate2 += rd.rate_uv;
rd.distortion2 += rd.distortion_uv;
} else {
this_rd = INT_MAX;
disable_skip = 1;
} break;
} case DC_PRED: case V_PRED: case H_PRED: case TM_PRED: { int distortion;
x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
case NEWMV: { int thissme; int bestsme = INT_MAX; int step_param = cpi->sf.first_step; int further_steps; int n; /* If last step (1-away) of n-step search doesn't pick the center point as the best match, we will do a final 1-away diamond refining search
*/ int do_refine = 1;
int sadpb = x->sadperbit16;
int_mv mvp_full;
int col_min = ((best_ref_mv.as_mv.col + 7) >> 3) - MAX_FULL_PEL_VAL; int row_min = ((best_ref_mv.as_mv.row + 7) >> 3) - MAX_FULL_PEL_VAL; int col_max = (best_ref_mv.as_mv.col >> 3) + MAX_FULL_PEL_VAL; int row_max = (best_ref_mv.as_mv.row >> 3) + MAX_FULL_PEL_VAL;
int tmp_col_min = x->mv_col_min; int tmp_col_max = x->mv_col_max; int tmp_row_min = x->mv_row_min; int tmp_row_max = x->mv_row_max;
/* Get intersection of UMV window and valid MV window to * reduce # of checks in diamond search.
*/ if (x->mv_col_min < col_min) x->mv_col_min = col_min; if (x->mv_col_max > col_max) x->mv_col_max = col_max; if (x->mv_row_min < row_min) x->mv_row_min = row_min; if (x->mv_row_max > row_max) x->mv_row_max = row_max;
/* adjust search range according to sr from mv prediction */ if (sr > step_param) step_param = sr;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.