| Index: source/libvpx/vp9/encoder/vp9_rdopt.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_rdopt.c (revision 291857)
|
| +++ source/libvpx/vp9/encoder/vp9_rdopt.c (working copy)
|
| @@ -171,30 +171,53 @@
|
| int64_t dist_sum = 0;
|
| const int ref = xd->mi[0]->mbmi.ref_frame[0];
|
| unsigned int sse;
|
| + unsigned int var = 0;
|
| + unsigned int sum_sse = 0;
|
| const int shift = 8;
|
| + int rate;
|
| + int64_t dist;
|
|
|
| + x->pred_sse[ref] = 0;
|
| +
|
| for (i = 0; i < MAX_MB_PLANE; ++i) {
|
| struct macroblock_plane *const p = &x->plane[i];
|
| struct macroblockd_plane *const pd = &xd->plane[i];
|
| const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
|
| + const TX_SIZE max_tx_size = max_txsize_lookup[bs];
|
| + const BLOCK_SIZE unit_size = txsize_to_bsize[max_tx_size];
|
| + int bw = 1 << (b_width_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
|
| + int bh = 1 << (b_height_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
|
| + int idx, idy;
|
| + int lw = b_width_log2_lookup[unit_size] + 2;
|
| + int lh = b_height_log2_lookup[unit_size] + 2;
|
|
|
| - const unsigned int var = cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
|
| - pd->dst.buf, pd->dst.stride,
|
| - &sse);
|
| + sum_sse = 0;
|
|
|
| - if (!x->select_tx_size) {
|
| - if (sse < p->quant_thred[0] >> shift)
|
| - x->skip_txfm[i] = 1;
|
| - else if (var < p->quant_thred[1] >> shift)
|
| - x->skip_txfm[i] = 2;
|
| - else
|
| - x->skip_txfm[i] = 0;
|
| + for (idy = 0; idy < bh; ++idy) {
|
| + for (idx = 0; idx < bw; ++idx) {
|
| + uint8_t *src = p->src.buf + (idy * p->src.stride << lh) + (idx << lw);
|
| + uint8_t *dst = pd->dst.buf + (idy * pd->dst.stride << lh) + (idx << lh);
|
| + int block_idx = (idy << 1) + idx;
|
| +
|
| + var = cpi->fn_ptr[unit_size].vf(src, p->src.stride,
|
| + dst, pd->dst.stride, &sse);
|
| + x->bsse[(i << 2) + block_idx] = sse;
|
| + sum_sse += sse;
|
| +
|
| + if (!x->select_tx_size) {
|
| + if (x->bsse[(i << 2) + block_idx] < p->quant_thred[0] >> shift)
|
| + x->skip_txfm[(i << 2) + block_idx] = 1;
|
| + else if (var < p->quant_thred[1] >> shift)
|
| + x->skip_txfm[(i << 2) + block_idx] = 2;
|
| + else
|
| + x->skip_txfm[(i << 2) + block_idx] = 0;
|
| + }
|
| +
|
| + if (i == 0)
|
| + x->pred_sse[ref] += sse;
|
| + }
|
| }
|
|
|
| - x->bsse[i] = sse;
|
| - if (i == 0)
|
| - x->pred_sse[ref] = sse;
|
| -
|
| // Fast approximate the modelling function.
|
| if (cpi->oxcf.speed > 4) {
|
| int64_t rate;
|
| @@ -210,9 +233,7 @@
|
| rate_sum += rate;
|
| dist_sum += dist;
|
| } else {
|
| - int rate;
|
| - int64_t dist;
|
| - vp9_model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
|
| + vp9_model_rd_from_var_lapndz(sum_sse, 1 << num_pels_log2_lookup[bs],
|
| pd->dequant[1] >> 3, &rate, &dist);
|
| rate_sum += rate;
|
| dist_sum += dist;
|
| @@ -372,17 +393,17 @@
|
| if (!is_inter_block(mbmi)) {
|
| vp9_encode_block_intra(x, plane, block, plane_bsize, tx_size, &mbmi->skip);
|
| dist_block(plane, block, tx_size, args);
|
| - } else {
|
| - if (x->skip_txfm[plane] == 0) {
|
| + } else if (max_txsize_lookup[plane_bsize] == tx_size) {
|
| + if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] == 0) {
|
| // full forward transform and quantization
|
| vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
|
| dist_block(plane, block, tx_size, args);
|
| - } else if (x->skip_txfm[plane] == 2) {
|
| + } else if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] == 2) {
|
| // compute DC coefficient
|
| int16_t *const coeff = BLOCK_OFFSET(x->plane[plane].coeff, block);
|
| int16_t *const dqcoeff = BLOCK_OFFSET(xd->plane[plane].dqcoeff, block);
|
| vp9_xform_quant_dc(x, plane, block, plane_bsize, tx_size);
|
| - args->sse = x->bsse[plane] << 4;
|
| + args->sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
|
| args->dist = args->sse;
|
| if (!x->plane[plane].eobs[block])
|
| args->dist = args->sse - ((coeff[0] * coeff[0] -
|
| @@ -390,9 +411,13 @@
|
| } else {
|
| // skip forward transform
|
| x->plane[plane].eobs[block] = 0;
|
| - args->sse = x->bsse[plane] << 4;
|
| + args->sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
|
| args->dist = args->sse;
|
| }
|
| + } else {
|
| + // full forward transform and quantization
|
| + vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
|
| + dist_block(plane, block, tx_size, args);
|
| }
|
|
|
| rate_block(plane, block, plane_bsize, tx_size, args);
|
| @@ -468,7 +493,6 @@
|
| txfm_rd_in_plane(x, rate, distortion, skip,
|
| sse, ref_best_rd, 0, bs,
|
| mbmi->tx_size, cpi->sf.use_fast_coef_costing);
|
| - cpi->tx_stepdown_count[0]++;
|
| }
|
|
|
| static void choose_tx_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
|
| @@ -551,60 +575,36 @@
|
|
|
| if (max_tx_size == TX_32X32 && best_tx == TX_32X32) {
|
| tx_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
|
| - cpi->tx_stepdown_count[0]++;
|
| } else if (max_tx_size >= TX_16X16 && best_tx == TX_16X16) {
|
| tx_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
|
| - cpi->tx_stepdown_count[max_tx_size - TX_16X16]++;
|
| } else if (rd[TX_8X8][1] < rd[TX_4X4][1]) {
|
| tx_cache[TX_MODE_SELECT] = rd[TX_8X8][1];
|
| - cpi->tx_stepdown_count[max_tx_size - TX_8X8]++;
|
| } else {
|
| tx_cache[TX_MODE_SELECT] = rd[TX_4X4][1];
|
| - cpi->tx_stepdown_count[max_tx_size - TX_4X4]++;
|
| }
|
| }
|
|
|
| -static void inter_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
|
| - int64_t *distortion, int *skip,
|
| - int64_t *psse, BLOCK_SIZE bs,
|
| - int64_t txfm_cache[TX_MODES],
|
| - int64_t ref_best_rd) {
|
| +static void super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
|
| + int64_t *distortion, int *skip,
|
| + int64_t *psse, BLOCK_SIZE bs,
|
| + int64_t txfm_cache[TX_MODES],
|
| + int64_t ref_best_rd) {
|
| MACROBLOCKD *xd = &x->e_mbd;
|
| + int64_t sse;
|
| + int64_t *ret_sse = psse ? psse : &sse;
|
|
|
| assert(bs == xd->mi[0]->mbmi.sb_type);
|
|
|
| - vp9_subtract_plane(x, bs, 0);
|
| -
|
| if (cpi->sf.tx_size_search_method == USE_LARGESTALL || xd->lossless) {
|
| vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
|
| - choose_largest_tx_size(cpi, x, rate, distortion, skip, psse, ref_best_rd,
|
| + choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
|
| bs);
|
| } else {
|
| - choose_tx_size_from_rd(cpi, x, rate, distortion, skip, psse,
|
| + choose_tx_size_from_rd(cpi, x, rate, distortion, skip, ret_sse,
|
| txfm_cache, ref_best_rd, bs);
|
| }
|
| }
|
|
|
| -static void intra_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
|
| - int64_t *distortion, int *skip,
|
| - BLOCK_SIZE bs,
|
| - int64_t txfm_cache[TX_MODES],
|
| - int64_t ref_best_rd) {
|
| - MACROBLOCKD *xd = &x->e_mbd;
|
| - int64_t sse;
|
| -
|
| - assert(bs == xd->mi[0]->mbmi.sb_type);
|
| - if (cpi->sf.tx_size_search_method != USE_FULL_RD || xd->lossless) {
|
| - vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
|
| - choose_largest_tx_size(cpi, x, rate, distortion, skip, &sse, ref_best_rd,
|
| - bs);
|
| - } else {
|
| - choose_tx_size_from_rd(cpi, x, rate, distortion, skip, &sse,
|
| - txfm_cache, ref_best_rd, bs);
|
| - }
|
| -}
|
| -
|
| -
|
| static int conditional_skipintra(PREDICTION_MODE mode,
|
| PREDICTION_MODE best_intra_mode) {
|
| if (mode == D117_PRED &&
|
| @@ -854,8 +854,8 @@
|
| }
|
| mic->mbmi.mode = mode;
|
|
|
| - intra_super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
|
| - &s, bsize, local_tx_cache, best_rd);
|
| + super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
|
| + &s, NULL, bsize, local_tx_cache, best_rd);
|
|
|
| if (this_rate_tokenonly == INT_MAX)
|
| continue;
|
| @@ -1365,13 +1365,14 @@
|
| int sadpb = x->sadperbit4;
|
| MV mvp_full;
|
| int max_mv;
|
| + int sad_list[5];
|
|
|
| /* Is the best so far sufficiently good that we cant justify doing
|
| * and new motion search. */
|
| if (best_rd < label_mv_thresh)
|
| break;
|
|
|
| - if (!is_best_mode(cpi->oxcf.mode)) {
|
| + if (cpi->oxcf.mode != BEST) {
|
| // use previous block's result as next block's MV predictor.
|
| if (i > 0) {
|
| bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
|
| @@ -1397,7 +1398,7 @@
|
| mvp_full.row = bsi->mvp.as_mv.row >> 3;
|
| mvp_full.col = bsi->mvp.as_mv.col >> 3;
|
|
|
| - if (cpi->sf.adaptive_motion_search && cm->show_frame) {
|
| + if (cpi->sf.adaptive_motion_search) {
|
| mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
|
| mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
|
| step_param = MAX(step_param, 8);
|
| @@ -1408,12 +1409,14 @@
|
|
|
| vp9_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
|
|
|
| - bestsme = vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
|
| - sadpb, &bsi->ref_mv[0]->as_mv, new_mv,
|
| - INT_MAX, 1);
|
| + bestsme = vp9_full_pixel_search(
|
| + cpi, x, bsize, &mvp_full, step_param, sadpb,
|
| + cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? sad_list : NULL,
|
| + &bsi->ref_mv[0]->as_mv, new_mv,
|
| + INT_MAX, 1);
|
|
|
| // Should we do a full search (best quality only)
|
| - if (is_best_mode(cpi->oxcf.mode)) {
|
| + if (cpi->oxcf.mode == BEST) {
|
| int_mv *const best_mv = &mi->bmi[i].as_mv[0];
|
| /* Check if mvp_full is within the range. */
|
| clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
|
| @@ -1422,6 +1425,7 @@
|
| sadpb, 16, &cpi->fn_ptr[bsize],
|
| &bsi->ref_mv[0]->as_mv,
|
| &best_mv->as_mv);
|
| + sad_list[1] = sad_list[2] = sad_list[3] = sad_list[4] = INT_MAX;
|
| if (thissme < bestsme) {
|
| bestsme = thissme;
|
| *new_mv = best_mv->as_mv;
|
| @@ -1434,17 +1438,19 @@
|
|
|
| if (bestsme < INT_MAX) {
|
| int distortion;
|
| - cpi->find_fractional_mv_step(x,
|
| - new_mv,
|
| - &bsi->ref_mv[0]->as_mv,
|
| - cm->allow_high_precision_mv,
|
| - x->errorperbit, &cpi->fn_ptr[bsize],
|
| - cpi->sf.mv.subpel_force_stop,
|
| - cpi->sf.mv.subpel_iters_per_step,
|
| - x->nmvjointcost, x->mvcost,
|
| - &distortion,
|
| - &x->pred_sse[mbmi->ref_frame[0]],
|
| - NULL, 0, 0);
|
| + cpi->find_fractional_mv_step(
|
| + x,
|
| + new_mv,
|
| + &bsi->ref_mv[0]->as_mv,
|
| + cm->allow_high_precision_mv,
|
| + x->errorperbit, &cpi->fn_ptr[bsize],
|
| + cpi->sf.mv.subpel_force_stop,
|
| + cpi->sf.mv.subpel_iters_per_step,
|
| + cond_sad_list(cpi, sad_list),
|
| + x->nmvjointcost, x->mvcost,
|
| + &distortion,
|
| + &x->pred_sse[mbmi->ref_frame[0]],
|
| + NULL, 0, 0);
|
|
|
| // save motion search result for use in compound prediction
|
| seg_mvs[i][mbmi->ref_frame[0]].as_mv = *new_mv;
|
| @@ -1701,12 +1707,14 @@
|
| int mode_index,
|
| int64_t comp_pred_diff[REFERENCE_MODES],
|
| const int64_t tx_size_diff[TX_MODES],
|
| - int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]) {
|
| + int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS],
|
| + int skippable) {
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
|
|
| // Take a snapshot of the coding context so it can be
|
| // restored if we decide to encode this way
|
| ctx->skip = x->skip;
|
| + ctx->skippable = skippable;
|
| ctx->best_mode_index = mode_index;
|
| ctx->mic = *xd->mi[0];
|
| ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
|
| @@ -1772,6 +1780,7 @@
|
| int tmp_col_max = x->mv_col_max;
|
| int tmp_row_min = x->mv_row_min;
|
| int tmp_row_max = x->mv_row_max;
|
| + int sad_list[5];
|
|
|
| const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
|
| ref);
|
| @@ -1806,8 +1815,7 @@
|
| step_param = cpi->mv_step_param;
|
| }
|
|
|
| - if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64 &&
|
| - cm->show_frame) {
|
| + if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64) {
|
| int boffset = 2 * (b_width_log2(BLOCK_64X64) - MIN(b_height_log2(bsize),
|
| b_width_log2(bsize)));
|
| step_param = MAX(step_param, boffset);
|
| @@ -1844,6 +1852,7 @@
|
| mvp_full.row >>= 3;
|
|
|
| bestsme = vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb,
|
| + cond_sad_list(cpi, sad_list),
|
| &ref_mv, &tmp_mv->as_mv, INT_MAX, 1);
|
|
|
| x->mv_col_min = tmp_col_min;
|
| @@ -1859,13 +1868,14 @@
|
| &cpi->fn_ptr[bsize],
|
| cpi->sf.mv.subpel_force_stop,
|
| cpi->sf.mv.subpel_iters_per_step,
|
| + cond_sad_list(cpi, sad_list),
|
| x->nmvjointcost, x->mvcost,
|
| &dis, &x->pred_sse[ref], NULL, 0, 0);
|
| }
|
| *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
|
| x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
|
|
|
| - if (cpi->sf.adaptive_motion_search && cm->show_frame)
|
| + if (cpi->sf.adaptive_motion_search)
|
| x->pred_mv[ref] = tmp_mv->as_mv;
|
|
|
| if (scaled_ref_frame) {
|
| @@ -1983,6 +1993,7 @@
|
| x->errorperbit,
|
| &cpi->fn_ptr[bsize],
|
| 0, cpi->sf.mv.subpel_iters_per_step,
|
| + NULL,
|
| x->nmvjointcost, x->mvcost,
|
| &dis, &sse, second_pred,
|
| pw, ph);
|
| @@ -2118,6 +2129,8 @@
|
| int_mv (*mode_mv)[MAX_REF_FRAMES],
|
| int mi_row, int mi_col,
|
| int_mv single_newmv[MAX_REF_FRAMES],
|
| + INTERP_FILTER (*single_filter)[MAX_REF_FRAMES],
|
| + int (*single_skippable)[MAX_REF_FRAMES],
|
| int64_t *psse,
|
| const int64_t ref_best_rd) {
|
| VP9_COMMON *cm = &cpi->common;
|
| @@ -2135,14 +2148,14 @@
|
| DECLARE_ALIGNED_ARRAY(16, uint8_t, tmp_buf, MAX_MB_PLANE * 64 * 64);
|
| int pred_exists = 0;
|
| int intpel_mv;
|
| - int64_t rd, best_rd = INT64_MAX;
|
| + int64_t rd, tmp_rd, best_rd = INT64_MAX;
|
| int best_needs_copy = 0;
|
| uint8_t *orig_dst[MAX_MB_PLANE];
|
| int orig_dst_stride[MAX_MB_PLANE];
|
| int rs = 0;
|
| INTERP_FILTER best_filter = SWITCHABLE;
|
| - int skip_txfm[MAX_MB_PLANE] = {0};
|
| - int64_t bsse[MAX_MB_PLANE] = {0};
|
| + uint8_t skip_txfm[MAX_MB_PLANE << 2] = {0};
|
| + int64_t bsse[MAX_MB_PLANE << 2] = {0};
|
|
|
| int bsl = mi_width_log2_lookup[bsize];
|
| int pred_filter_search = cpi->sf.cb_pred_filter_search ?
|
| @@ -2164,6 +2177,12 @@
|
| if (frame_mv[refs[0]].as_int == INVALID_MV ||
|
| frame_mv[refs[1]].as_int == INVALID_MV)
|
| return INT64_MAX;
|
| +
|
| + if (cpi->sf.adaptive_mode_search) {
|
| + if (single_filter[this_mode][refs[0]] ==
|
| + single_filter[this_mode][refs[1]])
|
| + best_filter = single_filter[this_mode][refs[0]];
|
| + }
|
| }
|
|
|
| if (this_mode == NEWMV) {
|
| @@ -2225,6 +2244,10 @@
|
| * if the first is known */
|
| *rate2 += cost_mv_ref(cpi, this_mode, mbmi->mode_context[refs[0]]);
|
|
|
| + if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
|
| + mbmi->mode != NEARESTMV)
|
| + return INT64_MAX;
|
| +
|
| pred_exists = 0;
|
| // Are all MVs integer pel for Y and UV
|
| intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
|
| @@ -2263,6 +2286,13 @@
|
| } else {
|
| int rate_sum = 0;
|
| int64_t dist_sum = 0;
|
| + if (i > 0 && cpi->sf.adaptive_interp_filter_search &&
|
| + (cpi->sf.interp_filter_search_mask & (1 << i))) {
|
| + rate_sum = INT_MAX;
|
| + dist_sum = INT64_MAX;
|
| + continue;
|
| + }
|
| +
|
| if ((cm->interp_filter == SWITCHABLE &&
|
| (!i || best_needs_copy)) ||
|
| (cm->interp_filter != SWITCHABLE &&
|
| @@ -2313,6 +2343,7 @@
|
| (cm->interp_filter != SWITCHABLE &&
|
| cm->interp_filter == mbmi->interp_filter)) {
|
| pred_exists = 1;
|
| + tmp_rd = best_rd;
|
| }
|
| }
|
| restore_dst_buf(xd, orig_dst, orig_dst_stride);
|
| @@ -2331,17 +2362,30 @@
|
| xd->plane[i].dst.stride = 64;
|
| }
|
| }
|
| + rd = tmp_rd + RDCOST(x->rdmult, x->rddiv, rs, 0);
|
| } else {
|
| + int tmp_rate;
|
| + int64_t tmp_dist;
|
| // Handles the special case when a filter that is not in the
|
| - // switchable list (ex. bilinear, 6-tap) is indicated at the frame level
|
| + // switchable list (ex. bilinear) is indicated at the frame level, or
|
| + // skip condition holds.
|
| vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
|
| + model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist);
|
| + rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
|
| + vpx_memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
|
| + vpx_memcpy(bsse, x->bsse, sizeof(bsse));
|
| }
|
|
|
| + if (!is_comp_pred)
|
| + single_filter[this_mode][refs[0]] = mbmi->interp_filter;
|
| +
|
| + if (cpi->sf.adaptive_mode_search)
|
| + if (is_comp_pred)
|
| + if (single_skippable[this_mode][refs[0]] &&
|
| + single_skippable[this_mode][refs[1]])
|
| + vpx_memset(skip_txfm, 1, sizeof(skip_txfm));
|
| +
|
| if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
|
| - int tmp_rate;
|
| - int64_t tmp_dist;
|
| - model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist);
|
| - rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
|
| // if current pred_error modeled rd is substantially more than the best
|
| // so far, do not bother doing full rd
|
| if (rd / 2 > ref_best_rd) {
|
| @@ -2351,7 +2395,7 @@
|
| }
|
|
|
| if (cm->interp_filter == SWITCHABLE)
|
| - *rate2 += vp9_get_switchable_rate(cpi);
|
| + *rate2 += rs;
|
|
|
| if (!is_comp_pred) {
|
| if (cpi->allow_encode_breakout)
|
| @@ -2368,8 +2412,9 @@
|
| int64_t rdcosty = INT64_MAX;
|
|
|
| // Y cost and distortion
|
| - inter_super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
|
| - bsize, txfm_cache, ref_best_rd);
|
| + vp9_subtract_plane(x, bsize, 0);
|
| + super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
|
| + bsize, txfm_cache, ref_best_rd);
|
|
|
| if (*rate_y == INT_MAX) {
|
| *rate2 = INT_MAX;
|
| @@ -2399,6 +2444,9 @@
|
| *skippable = skippable_y && skippable_uv;
|
| }
|
|
|
| + if (!is_comp_pred)
|
| + single_skippable[this_mode][refs[0]] = *skippable;
|
| +
|
| restore_dst_buf(xd, orig_dst, orig_dst_stride);
|
| return this_rd; // if 0, this will be re-calculated by caller
|
| }
|
| @@ -2505,10 +2553,12 @@
|
| PREDICTION_MODE this_mode;
|
| MV_REFERENCE_FRAME ref_frame, second_ref_frame;
|
| unsigned char segment_id = mbmi->segment_id;
|
| - int comp_pred, i;
|
| + int comp_pred, i, k;
|
| int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
|
| struct buf_2d yv12_mb[4][MAX_MB_PLANE];
|
| int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
|
| + INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
|
| + int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
|
| static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
|
| VP9_ALT_FLAG };
|
| int64_t best_rd = best_rd_so_far;
|
| @@ -2519,6 +2569,7 @@
|
| int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
|
| int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
|
| MB_MODE_INFO best_mbmode;
|
| + int best_mode_skippable = 0;
|
| int mode_index, best_mode_index = -1;
|
| unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
|
| vp9_prob comp_mode_p;
|
| @@ -2556,6 +2607,12 @@
|
| rate_uv_intra[i] = INT_MAX;
|
| for (i = 0; i < MAX_REF_FRAMES; ++i)
|
| x->pred_sse[i] = INT_MAX;
|
| + for (i = 0; i < MB_MODE_COUNT; ++i) {
|
| + for (k = 0; k < MAX_REF_FRAMES; ++k) {
|
| + single_inter_filter[i][k] = SWITCHABLE;
|
| + single_skippable[i][k] = 0;
|
| + }
|
| + }
|
|
|
| *returnrate = INT_MAX;
|
|
|
| @@ -2732,6 +2789,9 @@
|
|
|
| comp_pred = second_ref_frame > INTRA_FRAME;
|
| if (comp_pred) {
|
| + if (!cm->allow_comp_inter_inter)
|
| + continue;
|
| +
|
| if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
|
| best_mode_index >=0 &&
|
| vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
|
| @@ -2747,6 +2807,10 @@
|
| }
|
|
|
| if (ref_frame == INTRA_FRAME) {
|
| + if (cpi->sf.adaptive_mode_search)
|
| + if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_intra_rd)
|
| + continue;
|
| +
|
| if (!(intra_y_mode_mask & (1 << this_mode)))
|
| continue;
|
| if (this_mode != DC_PRED) {
|
| @@ -2785,6 +2849,8 @@
|
| // them for this frame.
|
| mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
|
| : cm->interp_filter;
|
| + mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
|
| +
|
| x->skip = 0;
|
| set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
|
|
|
| @@ -2800,8 +2866,8 @@
|
|
|
| if (ref_frame == INTRA_FRAME) {
|
| TX_SIZE uv_tx;
|
| - intra_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
|
| - bsize, tx_cache, best_rd);
|
| + super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
|
| + NULL, bsize, tx_cache, best_rd);
|
|
|
| if (rate_y == INT_MAX)
|
| continue;
|
| @@ -2831,7 +2897,8 @@
|
| &rate_uv, &distortion_uv,
|
| &disable_skip, frame_mv,
|
| mi_row, mi_col,
|
| - single_newmv, &total_sse, best_rd);
|
| + single_newmv, single_inter_filter,
|
| + single_skippable, &total_sse, best_rd);
|
| if (this_rd == INT64_MAX)
|
| continue;
|
|
|
| @@ -2919,6 +2986,8 @@
|
| /* required for left and above block mv */
|
| mbmi->mv[0].as_int = 0;
|
| max_plane = 1;
|
| + } else {
|
| + best_intra_rd = x->pred_sse[ref_frame];
|
| }
|
|
|
| *returnrate = rate2;
|
| @@ -2926,6 +2995,8 @@
|
| best_rd = this_rd;
|
| best_mbmode = *mbmi;
|
| best_skip2 = this_skip2;
|
| + best_mode_skippable = skippable;
|
| +
|
| if (!x->select_tx_size)
|
| swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
|
| vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
|
| @@ -3025,6 +3096,28 @@
|
| break;
|
| }
|
|
|
| + // The inter modes' rate costs are not calculated precisely in some cases.
|
| + // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
|
| + // ZEROMV. Here, checks are added for those cases, and the mode decisions
|
| + // are corrected.
|
| + if (best_mbmode.mode == NEWMV) {
|
| + const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
|
| + best_mbmode.ref_frame[1]};
|
| + int comp_pred_mode = refs[1] > INTRA_FRAME;
|
| +
|
| + if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
|
| + ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
|
| + best_mbmode.mv[1].as_int) || !comp_pred_mode))
|
| + best_mbmode.mode = NEARESTMV;
|
| + else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
|
| + ((comp_pred_mode && frame_mv[NEARMV][refs[1]].as_int ==
|
| + best_mbmode.mv[1].as_int) || !comp_pred_mode))
|
| + best_mbmode.mode = NEARMV;
|
| + else if (best_mbmode.mv[0].as_int == 0 &&
|
| + ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
|
| + best_mbmode.mode = ZEROMV;
|
| + }
|
| +
|
| if (best_mode_index < 0 || best_rd >= best_rd_so_far)
|
| return INT64_MAX;
|
|
|
| @@ -3082,8 +3175,8 @@
|
| }
|
|
|
| set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
|
| - store_coding_context(x, ctx, best_mode_index,
|
| - best_pred_diff, best_tx_diff, best_filter_diff);
|
| + store_coding_context(x, ctx, best_mode_index, best_pred_diff,
|
| + best_tx_diff, best_filter_diff, best_mode_skippable);
|
|
|
| return best_rd;
|
| }
|
| @@ -3188,7 +3281,7 @@
|
| if (!x->select_tx_size)
|
| swap_block_ptr(x, ctx, 1, 0, 0, MAX_MB_PLANE);
|
| store_coding_context(x, ctx, THR_ZEROMV,
|
| - best_pred_diff, best_tx_diff, best_filter_diff);
|
| + best_pred_diff, best_tx_diff, best_filter_diff, 0);
|
|
|
| return this_rd;
|
| }
|
| @@ -3325,6 +3418,9 @@
|
|
|
| comp_pred = second_ref_frame > INTRA_FRAME;
|
| if (comp_pred) {
|
| + if (!cm->allow_comp_inter_inter)
|
| + continue;
|
| +
|
| if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
|
| continue;
|
| // Do not allow compound prediction if the segment level reference frame
|
| @@ -3793,7 +3889,7 @@
|
|
|
| set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
|
| store_coding_context(x, ctx, best_ref_index,
|
| - best_pred_diff, best_tx_diff, best_filter_diff);
|
| + best_pred_diff, best_tx_diff, best_filter_diff, 0);
|
|
|
| return best_rd;
|
| }
|
|
|