staticint pick_intra4x4mby_modes(MACROBLOCK *mb, int *Rate, int *best_dist) {
MACROBLOCKD *const xd = &mb->e_mbd; int i; int cost = mb->mbmode_cost[xd->frame_type][B_PRED]; int error; int distortion = 0; constint *bmode_costs;
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, 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];
}
pick_intra4x4block(mb, i, &best_mode, bmode_costs, &r, &d);
staticvoid update_mvcount(MACROBLOCK *x, int_mv *best_ref_mv) {
MACROBLOCKD *xd = &x->e_mbd; /* Split MV modes currently not supported when RD is nopt enabled,
* therefore, only need to modify MVcount in NEWMV mode. */ if (xd->mode_info_context->mbmi.mode == NEWMV) { constint row_val =
((xd->mode_info_context->mbmi.mv.as_mv.row - best_ref_mv->as_mv.row) >> 1); constint row_idx = mv_max + row_val; constint col_val =
((xd->mode_info_context->mbmi.mv.as_mv.col - best_ref_mv->as_mv.col) >> 1); constint col_idx = mv_max + col_val; if (row_idx >= 0 && row_idx < MVvals && col_idx >= 0 && col_idx < MVvals) {
x->MVcount[0][row_idx]++;
x->MVcount[1][col_idx]++;
}
}
}
#if CONFIG_MULTI_RES_ENCODING staticvoid get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd, int *dissim, int *parent_ref_frame,
MB_PREDICTION_MODE *parent_mode,
int_mv *parent_ref_mv, int mb_row, int mb_col) {
LOWER_RES_MB_INFO *store_mode_info =
((LOWER_RES_FRAME_INFO *)cpi->oxcf.mr_low_res_mode_info)->mb_info; unsignedint parent_mb_index;
/* Consider different down_sampling_factor. */
{ /* TODO: Removed the loop that supports special down_sampling_factor *suchas2,4,8.Willrevisititifneeded. *Shouldalsotryusingalook-uptabletoseeifithelps
* performance. */ int parent_mb_row, parent_mb_col;
/* Read lower-resolution mode & motion result from memory.*/
*parent_ref_frame = store_mode_info[parent_mb_index].ref_frame;
*parent_mode = store_mode_info[parent_mb_index].mode;
*dissim = store_mode_info[parent_mb_index].dissim;
/* For highest-resolution encoder, adjust dissim value. Lower its quality
* for good performance. */ if (cpi->oxcf.mr_encoder_id == (cpi->oxcf.mr_total_resolutions - 1))
*dissim >>= 1;
// Adjust rd for ZEROMV and LAST, if LAST is the closest reference frame. // TODO: We should also add condition on distance of closest to current. if (!cpi->oxcf.screen_content_mode && this_mode == ZEROMV &&
x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME &&
(denoise_aggressive || (cpi->closest_reference_frame == LAST_FRAME))) { // No adjustment if block is considered to be skin area. if (x->is_skin) rd_adj = 100;
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, int mb_col) {
BLOCK *b = &x->block[0];
BLOCKD *d = &x->e_mbd.block[0];
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO best_mbmode;
int_mv best_ref_mv_sb[2] = { { 0 }, { 0 } };
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 mdcounts[4]; int best_rd = INT_MAX; int rd_adjustment = 100; int best_intra_rd = INT_MAX; int mode_index; int rate; int rate2; int distortion2; int bestsme = INT_MAX; int best_mode_index = 0; unsignedint sse = UINT_MAX, best_rd_sse = UINT_MAX; #if CONFIG_TEMPORAL_DENOISING unsignedint zero_mv_sse = UINT_MAX, best_sse = UINT_MAX; #endif
int sf_improved_mv_pred = cpi->sf.improved_mv_pred;
#if CONFIG_MULTI_RES_ENCODING int dissim = INT_MAX; int parent_ref_frame = 0;
int_mv parent_ref_mv;
MB_PREDICTION_MODE parent_mode = 0; int parent_ref_valid = 0; #endif
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 dot_artifact_candidate = 0;
get_predictor_pointers(cpi, plane, recon_yoffset, recon_uvoffset);
// If the current frame is using LAST as a reference, check for // biasing the mode selection for dot artifacts. if (cpi->ref_frame_flags & VP8_LAST_FRAME) { unsignedchar *target_y = x->src.y_buffer; unsignedchar *target_u = x->block[16].src + *x->block[16].base_src; unsignedchar *target_v = x->block[20].src + *x->block[20].base_src; int stride = x->src.y_stride; int stride_uv = x->block[16].src_stride; #if CONFIG_TEMPORAL_DENOISING if (cpi->oxcf.noise_sensitivity) { constint uv_denoise = (cpi->oxcf.noise_sensitivity >= 2) ? 1 : 0;
target_y =
cpi->denoiser.yv12_running_avg[LAST_FRAME].y_buffer + recon_yoffset;
stride = cpi->denoiser.yv12_running_avg[LAST_FRAME].y_stride; if (uv_denoise) {
target_u = cpi->denoiser.yv12_running_avg[LAST_FRAME].u_buffer +
recon_uvoffset;
target_v = cpi->denoiser.yv12_running_avg[LAST_FRAME].v_buffer +
recon_uvoffset;
stride_uv = cpi->denoiser.yv12_running_avg[LAST_FRAME].uv_stride;
}
} #endif
assert(plane[LAST_FRAME][0] != NULL);
dot_artifact_candidate = check_dot_artifact_candidate(
cpi, x, target_y, stride, plane[LAST_FRAME][0], mb_row, mb_col, 0); // If not found in Y channel, check UV channel. if (!dot_artifact_candidate) {
assert(plane[LAST_FRAME][1] != NULL);
dot_artifact_candidate = check_dot_artifact_candidate(
cpi, x, target_u, stride_uv, plane[LAST_FRAME][1], mb_row, mb_col, 1); if (!dot_artifact_candidate) {
assert(plane[LAST_FRAME][2] != NULL);
dot_artifact_candidate = check_dot_artifact_candidate(
cpi, x, target_v, stride_uv, plane[LAST_FRAME][2], mb_row, mb_col, 2);
}
}
}
#if CONFIG_MULTI_RES_ENCODING // |parent_ref_valid| will be set here if potentially we can do mv resue for // this higher resol (|cpi->oxcf.mr_encoder_id| > 0) frame. // |parent_ref_valid| may be reset depending on |parent_ref_frame| for // the current macroblock below.
parent_ref_valid = cpi->oxcf.mr_encoder_id && cpi->mr_low_res_mv_avail; if (parent_ref_valid) { int parent_ref_flag;
/* TODO(jkoleszar): The references available (ref_frame_flags) to the *lowerresencodershouldmatchthoseavailabletothisencoder,but *thereseemstobeasituationwherethismismatchcanhappeninthe *caseofframedroppingandtemporallayers.Forexample, *GOLDbeingdisallowedinref_frame_flags,butbeingreturnedas *parent_ref_frame. * *Inthisevent,taketheconservativeapproachofdisablingthe *lowerresinfoforthisMB.
*/
parent_ref_flag = 0; // Note availability for mv reuse is only based on last and golden. if (parent_ref_frame == LAST_FRAME)
parent_ref_flag = (cpi->ref_frame_flags & VP8_LAST_FRAME); elseif (parent_ref_frame == GOLDEN_FRAME)
parent_ref_flag = (cpi->ref_frame_flags & VP8_GOLD_FRAME);
// assert(!parent_ref_frame || parent_ref_flag);
// If |parent_ref_frame| did not match either last or golden then // shut off mv reuse. if (parent_ref_frame && !parent_ref_flag) parent_ref_valid = 0;
// Don't do mv reuse since we want to allow for another mode besides // ZEROMV_LAST to remove dot artifact. if (dot_artifact_candidate) parent_ref_valid = 0;
} #endif
// Check if current macroblock is in skin area.
x->is_skin = 0; if (!cpi->oxcf.screen_content_mode) { int block_index = mb_row * cpi->common.mb_cols + mb_col;
x->is_skin = cpi->skin_map[block_index];
} #if CONFIG_TEMPORAL_DENOISING if (cpi->oxcf.noise_sensitivity) { // Under aggressive denoising mode, should we use skin map to reduce // denoiser // and ZEROMV bias? Will need to revisit the accuracy of this detection for // very noisy input. For now keep this as is (i.e., don't turn it off). // if (cpi->denoiser.denoiser_mode == kDenoiserOnYUVAggressive) // x->is_skin = 0;
} #endif
/* Check to see if there is at least 1 valid reference frame that we need *tocalculatenear_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);
/* If the frame has big static background and current MB is in low *motionarea,itsmodedecisionisbiasedtoZEROMVmode. *Noadjustmentifcpu_usedis<=-12(i.e.,cpi->Speed>=12). *Atsuchspeedsettings,ZEROMVisalreadyheavilyfavored.
*/ if (cpi->Speed < 12) {
calculate_zeromv_rd_adjustment(cpi, x, &rd_adjustment);
}
if (dot_artifact_candidate) { // Bias against ZEROMV_LAST mode.
rd_adjustment = 150;
}
/* if we encode a new mv this is important *findthebestnewmotionvector
*/ for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) { int frame_cost; int this_rd = INT_MAX; int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]];
if (best_rd <= x->rd_threshes[mode_index]) continue;
/* Check to see if the testing frequency for this mode is at its max *Ifsothenpreventitfrombeingtestedandincreasethethreshold
* 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 *modesoincrementthecounterforthenumberoftimesithasbeen
* tested */
x->mode_test_hit_counts[mode_index]++;
/* Work out the cost assosciated with selecting the reference frame */
frame_cost = x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
rate2 += frame_cost;
/* Only consider ZEROMV/ALTREF_FRAME for alt ref frame, *unlessARNRfilteringisenabledinwhichcasewewant
* 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;
}
}
switch (this_mode) { case B_PRED: /* Pass best so far to pick_intra4x4mby_modes to use as breakout */
distortion2 = best_rd_sse;
pick_intra4x4mby_modes(x, &rate, &distortion2);
/* Further step/diamond searches as necessary */
step_param = cpi->sf.first_step + speed_adjust;
#if CONFIG_MULTI_RES_ENCODING /* If lower-res frame is not available for mv reuse (because of framedroppingordifferenttemporallayerpattern),thenhigher resolencoderdoesmotionsearchwithoutanypreviousknowledge. Also,sincelastframemotioninfoisnotstored,thenwecannot
use improved_mv_pred. */ if (cpi->oxcf.mr_encoder_id) sf_improved_mv_pred = 0;
// Only use parent MV as predictor if this candidate reference frame // (|this_ref_frame|) is equal to |parent_ref_frame|. if (parent_ref_valid && (parent_ref_frame == this_ref_frame)) { /* Use parent MV as predictor. Adjust search range *accordingly.
*/
mvp.as_int = parent_ref_mv.as_int;
mvp_full.as_mv.col = parent_ref_mv.as_mv.col >> 3;
mvp_full.as_mv.row = parent_ref_mv.as_mv.row >> 3;
mode_mv[NEWMV].as_int = d->bmi.mv.as_int; // The clamp below is not necessary from the perspective // of VP8 bitstream, but is added to improve ChromeCast // mirroring's robustness. Please do not remove.
vp8_clamp_mv2(&mode_mv[this_mode], xd); /* mv cost; */
rate2 +=
vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, cpi->mb.mvcost, 128);
} // fall through
case NEARESTMV: case NEARMV: if (mode_mv[this_mode].as_int == 0) continue; // fall through
#if CONFIG_TEMPORAL_DENOISING if (cpi->oxcf.noise_sensitivity) { /* Store for later use by denoiser. */ // Don't denoise with GOLDEN OR ALTREF is they are old reference // frames (greater than MAX_GF_ARF_DENOISE_RANGE frames in past). int skip_old_reference = ((this_ref_frame != LAST_FRAME) &&
(cpi->common.current_video_frame -
cpi->current_ref_frames[this_ref_frame] >
MAX_GF_ARF_DENOISE_RANGE))
? 1
: 0; if (this_mode == ZEROMV && sse < zero_mv_sse && !skip_old_reference) {
zero_mv_sse = sse;
x->best_zeromv_reference_frame =
x->e_mbd.mode_info_context->mbmi.ref_frame;
}
// Store the best NEWMV in x for later use in the denoiser. if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV && sse < best_sse &&
!skip_old_reference) {
best_sse = sse;
x->best_sse_inter_mode = NEWMV;
x->best_sse_mv = x->e_mbd.mode_info_context->mbmi.mv;
x->need_to_clamp_best_mvs =
x->e_mbd.mode_info_context->mbmi.need_to_clamp_mvs;
x->best_reference_frame = x->e_mbd.mode_info_context->mbmi.ref_frame;
}
} #endif
if (this_rd < best_rd || x->skip) { /* Note index of best mode */
best_mode_index = mode_index;
/* Testing this mode gave rise to an improvement in best error *score.Lowerthresholdabitfornexttime
*/
x->rd_thresh_mult[mode_index] =
(x->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2))
? x->rd_thresh_mult[mode_index] - 2
: MIN_THRESHMULT;
x->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) *
x->rd_thresh_mult[mode_index];
}
/* If the mode did not help improve the best error case then raise the *thresholdfortestingthatmodenexttimearound.
*/ else {
x->rd_thresh_mult[mode_index] += 4;
if (x->rd_thresh_mult[mode_index] > MAX_THRESHMULT) {
x->rd_thresh_mult[mode_index] = MAX_THRESHMULT;
}
/* Reduce the activation RD thresholds for the best choice mode */ if ((cpi->rd_baseline_thresh[best_mode_index] > 0) &&
(cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2))) { int best_adjustment = (x->rd_thresh_mult[best_mode_index] >> 3);
#if CONFIG_TEMPORAL_DENOISING if (cpi->oxcf.noise_sensitivity) { int block_index = mb_row * cpi->common.mb_cols + mb_col; int reevaluate = 0; int is_noisy = 0; if (x->best_sse_inter_mode == DC_PRED) { /* No best MV found. */
x->best_sse_inter_mode = best_mbmode.mode;
x->best_sse_mv = best_mbmode.mv;
x->need_to_clamp_best_mvs = best_mbmode.need_to_clamp_mvs;
x->best_reference_frame = best_mbmode.ref_frame;
best_sse = best_rd_sse;
} // For non-skin blocks that have selected ZEROMV for this current frame, // and have been selecting ZEROMV_LAST (on the base layer frame) at // least |x~20| consecutive past frames in a row, label the block for // possible increase in denoising strength. We also condition this // labeling on there being significant denoising in the scene if (cpi->oxcf.noise_sensitivity == 4) { if (cpi->denoiser.nmse_source_diff > 70 * cpi->denoiser.threshold_aggressive_mode / 100) {
is_noisy = 1;
}
} else { if (cpi->mse_source_denoised > 1000) is_noisy = 1;
}
x->increase_denoising = 0; if (!x->is_skin && x->best_sse_inter_mode == ZEROMV &&
(x->best_reference_frame == LAST_FRAME ||
x->best_reference_frame == cpi->closest_reference_frame) &&
cpi->consec_zero_last[block_index] >= 20 && is_noisy) {
x->increase_denoising = 1;
}
x->denoise_zeromv = 0;
vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse,
recon_yoffset, recon_uvoffset, &cpi->common.lf_info,
mb_row, mb_col, block_index,
cpi->consec_zero_last_mvbias[block_index]);
// Reevaluate ZEROMV after denoising: for large noise content // (i.e., cpi->mse_source_denoised is above threshold), do this for all // blocks that did not pick ZEROMV as best mode but are using ZEROMV // for denoising. Otherwise, always re-evaluate for blocks that picked // INTRA mode as best mode. // Avoid blocks that have been biased against ZERO_LAST // (i.e., dot artifact candidate blocks).
reevaluate = (best_mbmode.ref_frame == INTRA_FRAME) ||
(best_mbmode.mode != ZEROMV && x->denoise_zeromv &&
cpi->mse_source_denoised > 2000); if (!dot_artifact_candidate && reevaluate &&
x->best_zeromv_reference_frame != INTRA_FRAME) { int this_rd = 0; int this_ref_frame = x->best_zeromv_reference_frame;
rd_adjustment = 100;
rate2 =
x->ref_frame_cost[this_ref_frame] + vp8_cost_mv_ref(ZEROMV, mdcounts);
distortion2 = 0;
/* set up the proper prediction buffers for the frame */
x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;
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];
/* set to the best mb mode, this copy can be skip if x->skip since it
* already has the right content */ if (!x->skip) {
memcpy(&x->e_mbd.mode_info_context->mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
}
if (best_mbmode.mode <= B_PRED) { /* set mode_info_context->mbmi.uv_mode */
pick_intra_mbuv_mode(x);
}
if (sign_bias !=
cpi->common.ref_frame_sign_bias[xd->mode_info_context->mbmi.ref_frame]) {
best_ref_mv.as_int = best_ref_mv_sb[!sign_bias].as_int;
}
update_mvcount(x, &best_ref_mv);
}
void vp8_pick_intra_mode(MACROBLOCK *x, int *rate) { int error4x4, error16x16 = INT_MAX; int rate_, best_rate = 0, distortion, best_sse;
MB_PREDICTION_MODE mode, best_mode = DC_PRED; int this_rd; unsignedint sse;
BLOCK *b = &x->block[0];
MACROBLOCKD *xd = &x->e_mbd;
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.