| Index: source/libvpx/vp9/encoder/vp9_encodeframe.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_encodeframe.c (revision 293081)
|
| +++ source/libvpx/vp9/encoder/vp9_encodeframe.c (working copy)
|
| @@ -467,7 +467,6 @@
|
| int sp;
|
| int dp;
|
| int pixels_wide = 64, pixels_high = 64;
|
| - int_mv nearest_mv, near_mv;
|
| const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
|
| const struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
|
|
|
| @@ -488,11 +487,7 @@
|
|
|
| xd->mi[0].src_mi->mbmi.ref_frame[0] = LAST_FRAME;
|
| xd->mi[0].src_mi->mbmi.sb_type = BLOCK_64X64;
|
| - vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv,
|
| - xd->mi[0].src_mi->mbmi.ref_mvs[LAST_FRAME],
|
| - &nearest_mv, &near_mv);
|
| -
|
| - xd->mi[0].src_mi->mbmi.mv[0] = nearest_mv;
|
| + xd->mi[0].src_mi->mbmi.mv[0].as_int = 0;
|
| vp9_build_inter_predictors_sby(xd, mi_row, mi_col, BLOCK_64X64);
|
|
|
| d = xd->plane[0].dst.buf;
|
| @@ -607,7 +602,7 @@
|
| int output_enabled) {
|
| int i, x_idx, y;
|
| VP9_COMMON *const cm = &cpi->common;
|
| - RD_OPT *const rd_opt = &cpi->rd;
|
| + COUNTS *const counts = cpi->frame_counts;
|
| MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| struct macroblock_plane *const p = x->plane;
|
| @@ -616,6 +611,13 @@
|
| MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
| MODE_INFO *mi_addr = &xd->mi[0];
|
| const struct segmentation *const seg = &cm->seg;
|
| + const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type];
|
| + const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type];
|
| + const int x_mis = MIN(bw, cm->mi_cols - mi_col);
|
| + const int y_mis = MIN(bh, cm->mi_rows - mi_row);
|
| + MV_REF *const frame_mvs =
|
| + cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
|
| + int w, h;
|
|
|
| const int mis = cm->mi_stride;
|
| const int mi_width = num_8x8_blocks_wide_lookup[bsize];
|
| @@ -640,7 +642,7 @@
|
| // and then update the quantizer.
|
| if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
|
| vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0].src_mi->mbmi,
|
| - mi_row, mi_col, bsize, 1);
|
| + mi_row, mi_col, bsize, 1, ctx->rate);
|
| }
|
| }
|
|
|
| @@ -693,7 +695,7 @@
|
|
|
| if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
|
| for (i = 0; i < TX_MODES; i++)
|
| - rd_opt->tx_select_diff[i] += ctx->tx_rd_diff[i];
|
| + counts->tx_select_diff[i] += ctx->tx_rd_diff[i];
|
| }
|
|
|
| #if CONFIG_INTERNAL_STATS
|
| @@ -726,13 +728,24 @@
|
| }
|
| }
|
|
|
| - rd_opt->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
|
| - rd_opt->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
|
| - rd_opt->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
|
| + counts->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
|
| + counts->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
|
| + counts->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
|
|
|
| for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
|
| - rd_opt->filter_diff[i] += ctx->best_filter_diff[i];
|
| + counts->filter_diff[i] += ctx->best_filter_diff[i];
|
| }
|
| +
|
| + for (h = 0; h < y_mis; ++h) {
|
| + MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
|
| + for (w = 0; w < x_mis; ++w) {
|
| + MV_REF *const mv = frame_mv + w;
|
| + mv->ref_frame[0] = mi->src_mi->mbmi.ref_frame[0];
|
| + mv->ref_frame[1] = mi->src_mi->mbmi.ref_frame[1];
|
| + mv->mv[0].as_int = mi->src_mi->mbmi.mv[0].as_int;
|
| + mv->mv[1].as_int = mi->src_mi->mbmi.mv[1].as_int;
|
| + }
|
| + }
|
| }
|
|
|
| void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
|
| @@ -750,8 +763,8 @@
|
| x->e_mbd.plane[i].subsampling_y);
|
| }
|
|
|
| -static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode, int *rate,
|
| - int64_t *dist, BLOCK_SIZE bsize) {
|
| +static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode,
|
| + RD_COST *rd_cost, BLOCK_SIZE bsize) {
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
| INTERP_FILTER filter_ref;
|
| @@ -777,15 +790,16 @@
|
| xd->mi[0].src_mi->bmi[0].as_mv[0].as_int = 0;
|
| x->skip = 1;
|
|
|
| - *rate = 0;
|
| - *dist = 0;
|
| + vp9_rd_cost_init(rd_cost);
|
| }
|
|
|
| -static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
|
| +static void rd_pick_sb_modes(VP9_COMP *cpi,
|
| + TileDataEnc *tile_data,
|
| int mi_row, int mi_col, RD_COST *rd_cost,
|
| BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
|
| int64_t best_rd) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| + TileInfo *const tile_info = &tile_data->tile_info;
|
| MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| MB_MODE_INFO *mbmi;
|
| @@ -793,15 +807,13 @@
|
| struct macroblockd_plane *const pd = xd->plane;
|
| const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
|
| int i, orig_rdmult;
|
| - double rdmult_ratio;
|
|
|
| vp9_clear_system_state();
|
| - rdmult_ratio = 1.0; // avoid uninitialized warnings
|
|
|
| // Use the lower precision, but faster, 32x32 fdct for mode selection.
|
| x->use_lp32x32fdct = 1;
|
|
|
| - set_offsets(cpi, tile, mi_row, mi_col, bsize);
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, bsize);
|
| mbmi = &xd->mi[0].src_mi->mbmi;
|
| mbmi->sb_type = bsize;
|
|
|
| @@ -813,6 +825,7 @@
|
| }
|
| ctx->is_coded = 0;
|
| ctx->skippable = 0;
|
| + ctx->pred_pixel_ready = 0;
|
| x->skip_recode = 0;
|
|
|
| // Set to zero to make sure we do not use the previous encoded frame stats
|
| @@ -836,6 +849,7 @@
|
| if (aq_mode == VARIANCE_AQ) {
|
| const int energy = bsize <= BLOCK_16X16 ? x->mb_energy
|
| : vp9_block_energy(cpi, x, bsize);
|
| + int segment_qindex;
|
| if (cm->frame_type == KEY_FRAME ||
|
| cpi->refresh_alt_ref_frame ||
|
| (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) {
|
| @@ -845,11 +859,11 @@
|
| : cm->last_frame_seg_map;
|
| mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
|
| }
|
| -
|
| - rdmult_ratio = vp9_vaq_rdmult_ratio(energy);
|
| vp9_init_plane_quantizers(cpi, x);
|
| vp9_clear_system_state();
|
| - x->rdmult = (int)round(x->rdmult * rdmult_ratio);
|
| + segment_qindex = vp9_get_qindex(&cm->seg, mbmi->segment_id,
|
| + cm->base_qindex);
|
| + x->rdmult = vp9_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
|
| } else if (aq_mode == COMPLEXITY_AQ) {
|
| const int mi_offset = mi_row * cm->mi_cols + mi_col;
|
| unsigned char complexity = cpi->complexity_map[mi_offset];
|
| @@ -872,23 +886,17 @@
|
| } else {
|
| if (bsize >= BLOCK_8X8) {
|
| if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
|
| - vp9_rd_pick_inter_mode_sb_seg_skip(cpi, x, rd_cost, bsize,
|
| + vp9_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, rd_cost, bsize,
|
| ctx, best_rd);
|
| else
|
| - vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col,
|
| + vp9_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col,
|
| rd_cost, bsize, ctx, best_rd);
|
| } else {
|
| - vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, rd_cost,
|
| - bsize, ctx, best_rd);
|
| + vp9_rd_pick_inter_mode_sub8x8(cpi, tile_data, x, mi_row, mi_col,
|
| + rd_cost, bsize, ctx, best_rd);
|
| }
|
| }
|
|
|
| - if (aq_mode == VARIANCE_AQ && rd_cost->rate != INT_MAX) {
|
| - vp9_clear_system_state();
|
| - rd_cost->rate = (int)round(rd_cost->rate * rdmult_ratio);
|
| - rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
|
| - }
|
| -
|
| x->rdmult = orig_rdmult;
|
|
|
| // TODO(jingning) The rate-distortion optimization flow needs to be
|
| @@ -895,6 +903,9 @@
|
| // refactored to provide proper exit/return handle.
|
| if (rd_cost->rate == INT_MAX)
|
| rd_cost->rdcost = INT64_MAX;
|
| +
|
| + ctx->rate = rd_cost->rate;
|
| + ctx->dist = rd_cost->dist;
|
| }
|
|
|
| static void update_stats(VP9_COMMON *cm, const MACROBLOCK *x) {
|
| @@ -1161,79 +1172,6 @@
|
| }
|
| }
|
|
|
| -static void copy_partitioning(VP9_COMMON *cm, MODE_INFO *mi_8x8,
|
| - MODE_INFO *prev_mi_8x8) {
|
| - const int mis = cm->mi_stride;
|
| - int block_row, block_col;
|
| -
|
| - for (block_row = 0; block_row < 8; ++block_row) {
|
| - for (block_col = 0; block_col < 8; ++block_col) {
|
| - MODE_INFO *const prev_mi =
|
| - prev_mi_8x8[block_row * mis + block_col].src_mi;
|
| - const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0;
|
| -
|
| - if (prev_mi) {
|
| - const ptrdiff_t offset = prev_mi - cm->prev_mi;
|
| - mi_8x8[block_row * mis + block_col].src_mi = cm->mi + offset;
|
| - mi_8x8[block_row * mis + block_col].src_mi->mbmi.sb_type = sb_type;
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -static void constrain_copy_partitioning(VP9_COMP *const cpi,
|
| - const TileInfo *const tile,
|
| - MODE_INFO *mi_8x8,
|
| - MODE_INFO *prev_mi_8x8,
|
| - int mi_row, int mi_col,
|
| - BLOCK_SIZE bsize) {
|
| - VP9_COMMON *const cm = &cpi->common;
|
| - const int mis = cm->mi_stride;
|
| - const int row8x8_remaining = tile->mi_row_end - mi_row;
|
| - const int col8x8_remaining = tile->mi_col_end - mi_col;
|
| - MODE_INFO *const mi_upper_left = cm->mi + mi_row * mis + mi_col;
|
| - const int bh = num_8x8_blocks_high_lookup[bsize];
|
| - const int bw = num_8x8_blocks_wide_lookup[bsize];
|
| - int block_row, block_col;
|
| -
|
| - assert((row8x8_remaining > 0) && (col8x8_remaining > 0));
|
| -
|
| - // If the SB64 if it is all "in image".
|
| - if ((col8x8_remaining >= MI_BLOCK_SIZE) &&
|
| - (row8x8_remaining >= MI_BLOCK_SIZE)) {
|
| - for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) {
|
| - for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) {
|
| - const int index = block_row * mis + block_col;
|
| - MODE_INFO *prev_mi = prev_mi_8x8[index].src_mi;
|
| - const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0;
|
| - // Use previous partition if block size is not larger than bsize.
|
| - if (prev_mi && sb_type <= bsize) {
|
| - int block_row2, block_col2;
|
| - for (block_row2 = 0; block_row2 < bh; ++block_row2) {
|
| - for (block_col2 = 0; block_col2 < bw; ++block_col2) {
|
| - const int index2 = (block_row + block_row2) * mis +
|
| - block_col + block_col2;
|
| - prev_mi = prev_mi_8x8[index2].src_mi;
|
| - if (prev_mi) {
|
| - const ptrdiff_t offset = prev_mi - cm->prev_mi;
|
| - mi_8x8[index2].src_mi = cm->mi + offset;
|
| - mi_8x8[index2].src_mi->mbmi.sb_type = prev_mi->mbmi.sb_type;
|
| - }
|
| - }
|
| - }
|
| - } else {
|
| - // Otherwise, use fixed partition of size bsize.
|
| - mi_8x8[index].src_mi = mi_upper_left + index;
|
| - mi_8x8[index].src_mi->mbmi.sb_type = bsize;
|
| - }
|
| - }
|
| - }
|
| - } else {
|
| - // Else this is a partial SB64, copy previous partition.
|
| - copy_partitioning(cm, mi_8x8, prev_mi_8x8);
|
| - }
|
| -}
|
| -
|
| const struct {
|
| int row;
|
| int col;
|
| @@ -1334,64 +1272,21 @@
|
| }
|
| }
|
|
|
| -static int is_background(const VP9_COMP *cpi, const TileInfo *const tile,
|
| - int mi_row, int mi_col) {
|
| - // This assumes the input source frames are of the same dimension.
|
| - const int row8x8_remaining = tile->mi_row_end - mi_row;
|
| - const int col8x8_remaining = tile->mi_col_end - mi_col;
|
| - const int x = mi_col * MI_SIZE;
|
| - const int y = mi_row * MI_SIZE;
|
| - const int src_stride = cpi->Source->y_stride;
|
| - const uint8_t *const src = &cpi->Source->y_buffer[y * src_stride + x];
|
| - const int pre_stride = cpi->Last_Source->y_stride;
|
| - const uint8_t *const pre = &cpi->Last_Source->y_buffer[y * pre_stride + x];
|
| - int this_sad = 0;
|
| - int threshold = 0;
|
| -
|
| - if (row8x8_remaining >= MI_BLOCK_SIZE &&
|
| - col8x8_remaining >= MI_BLOCK_SIZE) {
|
| - this_sad = cpi->fn_ptr[BLOCK_64X64].sdf(src, src_stride, pre, pre_stride);
|
| - threshold = (1 << 12);
|
| - } else {
|
| - int r, c;
|
| - for (r = 0; r < row8x8_remaining; r += 2)
|
| - for (c = 0; c < col8x8_remaining; c += 2)
|
| - this_sad += cpi->fn_ptr[BLOCK_16X16].sdf(src, src_stride,
|
| - pre, pre_stride);
|
| - threshold = (row8x8_remaining * col8x8_remaining) << 6;
|
| - }
|
| -
|
| - return this_sad < 2 * threshold;
|
| -}
|
| -
|
| -static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO *prev_mi_8x8,
|
| - const int motion_thresh) {
|
| - const int mis = cm->mi_stride;
|
| - int block_row, block_col;
|
| -
|
| - if (cm->prev_mi) {
|
| - for (block_row = 0; block_row < 8; ++block_row) {
|
| - for (block_col = 0; block_col < 8; ++block_col) {
|
| - const MODE_INFO *prev_mi =
|
| - prev_mi_8x8[block_row * mis + block_col].src_mi;
|
| - if (prev_mi) {
|
| - if (abs(prev_mi->mbmi.mv[0].as_mv.row) > motion_thresh ||
|
| - abs(prev_mi->mbmi.mv[0].as_mv.col) > motion_thresh)
|
| - return 1;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| static void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
|
| int mi_row, int mi_col, int bsize) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| + MODE_INFO *const mi = xd->mi[0].src_mi;
|
| MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
|
| const struct segmentation *const seg = &cm->seg;
|
| + const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type];
|
| + const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type];
|
| + const int x_mis = MIN(bw, cm->mi_cols - mi_col);
|
| + const int y_mis = MIN(bh, cm->mi_rows - mi_row);
|
| + MV_REF *const frame_mvs =
|
| + cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
|
| + int w, h;
|
|
|
| *(xd->mi[0].src_mi) = ctx->mic;
|
| xd->mi[0].src_mi = &xd->mi[0];
|
| @@ -1406,7 +1301,8 @@
|
| mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
|
| } else {
|
| // Setting segmentation map for cyclic_refresh
|
| - vp9_cyclic_refresh_update_segment(cpi, mbmi, mi_row, mi_col, bsize, 1);
|
| + vp9_cyclic_refresh_update_segment(cpi, mbmi, mi_row, mi_col, bsize, 1,
|
| + ctx->rate);
|
| }
|
| vp9_init_plane_quantizers(cpi, x);
|
| }
|
| @@ -1420,6 +1316,17 @@
|
| }
|
| }
|
|
|
| + for (h = 0; h < y_mis; ++h) {
|
| + MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
|
| + for (w = 0; w < x_mis; ++w) {
|
| + MV_REF *const mv = frame_mv + w;
|
| + mv->ref_frame[0] = mi->src_mi->mbmi.ref_frame[0];
|
| + mv->ref_frame[1] = mi->src_mi->mbmi.ref_frame[1];
|
| + mv->mv[0].as_int = mi->src_mi->mbmi.mv[0].as_int;
|
| + mv->mv[1].as_int = mi->src_mi->mbmi.mv[1].as_int;
|
| + }
|
| + }
|
| +
|
| x->skip = ctx->skip;
|
| x->skip_txfm[0] = mbmi->segment_id ? 0 : ctx->skip_txfm[0];
|
| }
|
| @@ -1516,12 +1423,15 @@
|
| update_partition_context(xd, mi_row, mi_col, subsize, bsize);
|
| }
|
|
|
| -static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
|
| +static void rd_use_partition(VP9_COMP *cpi,
|
| + TileDataEnc *tile_data,
|
| MODE_INFO *mi_8x8, TOKENEXTRA **tp,
|
| int mi_row, int mi_col,
|
| - BLOCK_SIZE bsize, int *rate, int64_t *dist,
|
| + BLOCK_SIZE bsize,
|
| + int *rate, int64_t *dist,
|
| int do_recon, PC_TREE *pc_tree) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| + TileInfo *const tile_info = &tile_data->tile_info;
|
| MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| const int mis = cm->mi_stride;
|
| @@ -1557,7 +1467,7 @@
|
| save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
|
|
|
| if (bsize == BLOCK_16X16 && cpi->oxcf.aq_mode) {
|
| - set_offsets(cpi, tile, mi_row, mi_col, bsize);
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, bsize);
|
| x->mb_energy = vp9_block_energy(cpi, x, bsize);
|
| }
|
|
|
| @@ -1583,7 +1493,7 @@
|
| mi_row + (mi_step >> 1) < cm->mi_rows &&
|
| mi_col + (mi_step >> 1) < cm->mi_cols) {
|
| pc_tree->partitioning = PARTITION_NONE;
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rdc, bsize,
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &none_rdc, bsize,
|
| ctx, INT64_MAX);
|
|
|
| pl = partition_plane_context(xd, mi_row, mi_col, bsize);
|
| @@ -1602,11 +1512,11 @@
|
|
|
| switch (partition) {
|
| case PARTITION_NONE:
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rdc,
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &last_part_rdc,
|
| bsize, ctx, INT64_MAX);
|
| break;
|
| case PARTITION_HORZ:
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rdc,
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &last_part_rdc,
|
| subsize, &pc_tree->horizontal[0],
|
| INT64_MAX);
|
| if (last_part_rdc.rate != INT_MAX &&
|
| @@ -1616,7 +1526,8 @@
|
| vp9_rd_cost_init(&tmp_rdc);
|
| update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
|
| encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
|
| - rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &tmp_rdc,
|
| + rd_pick_sb_modes(cpi, tile_data,
|
| + mi_row + (mi_step >> 1), mi_col, &tmp_rdc,
|
| subsize, &pc_tree->horizontal[1], INT64_MAX);
|
| if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
|
| vp9_rd_cost_reset(&last_part_rdc);
|
| @@ -1628,7 +1539,7 @@
|
| }
|
| break;
|
| case PARTITION_VERT:
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rdc,
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &last_part_rdc,
|
| subsize, &pc_tree->vertical[0], INT64_MAX);
|
| if (last_part_rdc.rate != INT_MAX &&
|
| bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) {
|
| @@ -1637,7 +1548,8 @@
|
| vp9_rd_cost_init(&tmp_rdc);
|
| update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
|
| encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &tmp_rdc,
|
| + rd_pick_sb_modes(cpi, tile_data,
|
| + mi_row, mi_col + (mi_step >> 1), &tmp_rdc,
|
| subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
|
| INT64_MAX);
|
| if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
|
| @@ -1651,7 +1563,7 @@
|
| break;
|
| case PARTITION_SPLIT:
|
| if (bsize == BLOCK_8X8) {
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rdc,
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &last_part_rdc,
|
| subsize, pc_tree->leaf_split[0], INT64_MAX);
|
| break;
|
| }
|
| @@ -1667,7 +1579,8 @@
|
| continue;
|
|
|
| vp9_rd_cost_init(&tmp_rdc);
|
| - rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp,
|
| + rd_use_partition(cpi, tile_data,
|
| + mi_8x8 + jj * bss * mis + ii * bss, tp,
|
| mi_row + y_idx, mi_col + x_idx, subsize,
|
| &tmp_rdc.rate, &tmp_rdc.dist,
|
| i != 3, pc_tree->split[i]);
|
| @@ -1718,7 +1631,8 @@
|
|
|
| save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
|
| pc_tree->split[i]->partitioning = PARTITION_NONE;
|
| - rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &tmp_rdc,
|
| + rd_pick_sb_modes(cpi, tile_data,
|
| + mi_row + y_idx, mi_col + x_idx, &tmp_rdc,
|
| split_subsize, &pc_tree->split[i]->none, INT64_MAX);
|
|
|
| restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
|
| @@ -1732,7 +1646,7 @@
|
| chosen_rdc.dist += tmp_rdc.dist;
|
|
|
| if (i != 3)
|
| - encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0,
|
| + encode_sb(cpi, tile_info, tp, mi_row + y_idx, mi_col + x_idx, 0,
|
| split_subsize, pc_tree->split[i]);
|
|
|
| pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx,
|
| @@ -1775,14 +1689,10 @@
|
| // and and if necessary apply a Q delta using segmentation to get
|
| // closer to the target.
|
| if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
|
| - vp9_select_in_frame_q_segment(cpi, mi_row, mi_col,
|
| + vp9_select_in_frame_q_segment(cpi, bsize, mi_row, mi_col,
|
| output_enabled, chosen_rdc.rate);
|
| }
|
| -
|
| - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
|
| - vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
|
| - chosen_rdc.rate, chosen_rdc.dist);
|
| - encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize,
|
| + encode_sb(cpi, tile_info, tp, mi_row, mi_col, output_enabled, bsize,
|
| pc_tree);
|
| }
|
|
|
| @@ -2115,11 +2025,13 @@
|
| // TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
|
| // unlikely to be selected depending on previous rate-distortion optimization
|
| // results, for encoding speed-up.
|
| -static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
|
| +static void rd_pick_partition(VP9_COMP *cpi,
|
| + TileDataEnc *tile_data,
|
| TOKENEXTRA **tp, int mi_row, int mi_col,
|
| BLOCK_SIZE bsize, RD_COST *rd_cost,
|
| int64_t best_rd, PC_TREE *pc_tree) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| + TileInfo *const tile_info = &tile_data->tile_info;
|
| MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2;
|
| @@ -2139,8 +2051,8 @@
|
| const int xss = x->e_mbd.plane[1].subsampling_x;
|
| const int yss = x->e_mbd.plane[1].subsampling_y;
|
|
|
| - BLOCK_SIZE min_size = cpi->sf.min_partition_size;
|
| - BLOCK_SIZE max_size = cpi->sf.max_partition_size;
|
| + BLOCK_SIZE min_size = x->min_partition_size;
|
| + BLOCK_SIZE max_size = x->max_partition_size;
|
|
|
| #if CONFIG_FP_MB_STATS
|
| unsigned int src_diff_var = UINT_MAX;
|
| @@ -2162,7 +2074,7 @@
|
| vp9_rd_cost_reset(&best_rdc);
|
| best_rdc.rdcost = best_rd;
|
|
|
| - set_offsets(cpi, tile, mi_row, mi_col, bsize);
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, bsize);
|
|
|
| if (bsize == BLOCK_16X16 && cpi->oxcf.aq_mode)
|
| x->mb_energy = vp9_block_energy(cpi, x, bsize);
|
| @@ -2194,7 +2106,7 @@
|
|
|
| #if CONFIG_FP_MB_STATS
|
| if (cpi->use_fp_mb_stats) {
|
| - set_offsets(cpi, tile, mi_row, mi_col, bsize);
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, bsize);
|
| src_diff_var = get_sby_perpixel_diff_variance(cpi, &cpi->mb.plane[0].src,
|
| mi_row, mi_col, bsize);
|
| }
|
| @@ -2253,8 +2165,8 @@
|
|
|
| // PARTITION_NONE
|
| if (partition_none_allowed) {
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rdc, bsize, ctx,
|
| - best_rdc.rdcost);
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col,
|
| + &this_rdc, bsize, ctx, best_rdc.rdcost);
|
| if (this_rdc.rate != INT_MAX) {
|
| if (bsize >= BLOCK_8X8) {
|
| pl = partition_plane_context(xd, mi_row, mi_col, bsize);
|
| @@ -2323,7 +2235,7 @@
|
| }
|
| if (skip) {
|
| if (src_diff_var == UINT_MAX) {
|
| - set_offsets(cpi, tile, mi_row, mi_col, bsize);
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, bsize);
|
| src_diff_var = get_sby_perpixel_diff_variance(
|
| cpi, &cpi->mb.plane[0].src, mi_row, mi_col, bsize);
|
| }
|
| @@ -2353,7 +2265,7 @@
|
| if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
|
| pc_tree->leaf_split[0]->pred_interp_filter =
|
| ctx->mic.mbmi.interp_filter;
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rdc, subsize,
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &sum_rdc, subsize,
|
| pc_tree->leaf_split[0], best_rdc.rdcost);
|
| if (sum_rdc.rate == INT_MAX)
|
| sum_rdc.rdcost = INT64_MAX;
|
| @@ -2369,7 +2281,8 @@
|
| load_pred_mv(x, ctx);
|
|
|
| pc_tree->split[i]->index = i;
|
| - rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx,
|
| + rd_pick_partition(cpi, tile_data, tp,
|
| + mi_row + y_idx, mi_col + x_idx,
|
| subsize, &this_rdc,
|
| best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[i]);
|
|
|
| @@ -2412,7 +2325,7 @@
|
| partition_none_allowed)
|
| pc_tree->horizontal[0].pred_interp_filter =
|
| ctx->mic.mbmi.interp_filter;
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rdc, subsize,
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &sum_rdc, subsize,
|
| &pc_tree->horizontal[0], best_rdc.rdcost);
|
|
|
| if (sum_rdc.rdcost < best_rdc.rdcost && mi_row + mi_step < cm->mi_rows &&
|
| @@ -2427,8 +2340,8 @@
|
| partition_none_allowed)
|
| pc_tree->horizontal[1].pred_interp_filter =
|
| ctx->mic.mbmi.interp_filter;
|
| - rd_pick_sb_modes(cpi, tile, mi_row + mi_step, mi_col, &this_rdc,
|
| - subsize, &pc_tree->horizontal[1],
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row + mi_step, mi_col,
|
| + &this_rdc, subsize, &pc_tree->horizontal[1],
|
| best_rdc.rdcost - sum_rdc.rdcost);
|
| if (this_rdc.rate == INT_MAX) {
|
| sum_rdc.rdcost = INT64_MAX;
|
| @@ -2460,7 +2373,7 @@
|
| partition_none_allowed)
|
| pc_tree->vertical[0].pred_interp_filter =
|
| ctx->mic.mbmi.interp_filter;
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rdc, subsize,
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &sum_rdc, subsize,
|
| &pc_tree->vertical[0], best_rdc.rdcost);
|
| if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + mi_step < cm->mi_cols &&
|
| bsize > BLOCK_8X8) {
|
| @@ -2474,7 +2387,8 @@
|
| partition_none_allowed)
|
| pc_tree->vertical[1].pred_interp_filter =
|
| ctx->mic.mbmi.interp_filter;
|
| - rd_pick_sb_modes(cpi, tile, mi_row, mi_col + mi_step, &this_rdc, subsize,
|
| + rd_pick_sb_modes(cpi, tile_data, mi_row, mi_col + mi_step,
|
| + &this_rdc, subsize,
|
| &pc_tree->vertical[1], best_rdc.rdcost - sum_rdc.rdcost);
|
| if (this_rdc.rate == INT_MAX) {
|
| sum_rdc.rdcost = INT64_MAX;
|
| @@ -2514,13 +2428,10 @@
|
| // and and if necessary apply a Q delta using segmentation to get
|
| // closer to the target.
|
| if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map)
|
| - vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
|
| + vp9_select_in_frame_q_segment(cpi, bsize, mi_row, mi_col, output_enabled,
|
| best_rdc.rate);
|
| - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
|
| - vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
|
| - best_rdc.rate, best_rdc.dist);
|
| -
|
| - encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize, pc_tree);
|
| + encode_sb(cpi, tile_info, tp, mi_row, mi_col, output_enabled,
|
| + bsize, pc_tree);
|
| }
|
|
|
| if (bsize == BLOCK_64X64) {
|
| @@ -2532,10 +2443,14 @@
|
| }
|
| }
|
|
|
| -static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
|
| - int mi_row, TOKENEXTRA **tp) {
|
| +static void encode_rd_sb_row(VP9_COMP *cpi,
|
| + TileDataEnc *tile_data,
|
| + int mi_row,
|
| + TOKENEXTRA **tp) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| - MACROBLOCKD *const xd = &cpi->mb.e_mbd;
|
| + TileInfo *const tile_info = &tile_data->tile_info;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| SPEED_FEATURES *const sf = &cpi->sf;
|
| int mi_col;
|
|
|
| @@ -2544,7 +2459,7 @@
|
| vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
|
|
|
| // Code each SB in the row
|
| - for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
|
| + for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
|
| mi_col += MI_BLOCK_SIZE) {
|
| int dummy_rate;
|
| int64_t dummy_dist;
|
| @@ -2553,11 +2468,7 @@
|
|
|
| const int idx_str = cm->mi_stride * mi_row + mi_col;
|
| MODE_INFO *mi = cm->mi + idx_str;
|
| - MODE_INFO *prev_mi = NULL;
|
|
|
| - if (cm->frame_type != KEY_FRAME)
|
| - prev_mi = (cm->prev_mip + cm->mi_stride + 1 + idx_str)->src_mi;
|
| -
|
| if (sf->adaptive_pred_interp_filter) {
|
| for (i = 0; i < 64; ++i)
|
| cpi->leaf_tree[i].pred_interp_filter = SWITCHABLE;
|
| @@ -2573,56 +2484,34 @@
|
| vp9_zero(cpi->mb.pred_mv);
|
| cpi->pc_root->index = 0;
|
|
|
| - // TODO(yunqingwang): use_lastframe_partitioning is no longer used in good-
|
| - // quality encoding. Need to evaluate it in real-time encoding later to
|
| - // decide if it can be removed too. And then, do the code cleanup.
|
| cpi->mb.source_variance = UINT_MAX;
|
| if (sf->partition_search_type == FIXED_PARTITION) {
|
| - set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
|
| - set_fixed_partitioning(cpi, tile, mi, mi_row, mi_col,
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, BLOCK_64X64);
|
| + set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col,
|
| sf->always_this_block_size);
|
| - rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
|
| - &dummy_rate, &dummy_dist, 1, cpi->pc_root);
|
| + rd_use_partition(cpi, tile_data, mi, tp, mi_row, mi_col,
|
| + BLOCK_64X64, &dummy_rate, &dummy_dist, 1, cpi->pc_root);
|
| } else if (cpi->partition_search_skippable_frame) {
|
| BLOCK_SIZE bsize;
|
| - set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, BLOCK_64X64);
|
| bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col);
|
| - set_fixed_partitioning(cpi, tile, mi, mi_row, mi_col, bsize);
|
| - rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
|
| - &dummy_rate, &dummy_dist, 1, cpi->pc_root);
|
| + set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
|
| + rd_use_partition(cpi, tile_data, mi, tp, mi_row, mi_col,
|
| + BLOCK_64X64, &dummy_rate, &dummy_dist, 1, cpi->pc_root);
|
| } else if (sf->partition_search_type == VAR_BASED_PARTITION &&
|
| cm->frame_type != KEY_FRAME ) {
|
| - choose_partitioning(cpi, tile, mi_row, mi_col);
|
| - rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
|
| - &dummy_rate, &dummy_dist, 1, cpi->pc_root);
|
| - } else if (sf->partition_search_type == SEARCH_PARTITION &&
|
| - sf->use_lastframe_partitioning &&
|
| - (cpi->rc.frames_since_key %
|
| - sf->last_partitioning_redo_frequency) &&
|
| - cm->prev_mi &&
|
| - cm->show_frame &&
|
| - cm->frame_type != KEY_FRAME &&
|
| - !cpi->rc.is_src_frame_alt_ref &&
|
| - ((sf->use_lastframe_partitioning !=
|
| - LAST_FRAME_PARTITION_LOW_MOTION) ||
|
| - !sb_has_motion(cm, prev_mi, sf->lf_motion_threshold))) {
|
| - if (sf->constrain_copy_partition &&
|
| - sb_has_motion(cm, prev_mi, sf->lf_motion_threshold))
|
| - constrain_copy_partitioning(cpi, tile, mi, prev_mi,
|
| - mi_row, mi_col, BLOCK_16X16);
|
| - else
|
| - copy_partitioning(cm, mi, prev_mi);
|
| - rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
|
| - &dummy_rate, &dummy_dist, 1, cpi->pc_root);
|
| + choose_partitioning(cpi, tile_info, mi_row, mi_col);
|
| + rd_use_partition(cpi, tile_data, mi, tp, mi_row, mi_col,
|
| + BLOCK_64X64, &dummy_rate, &dummy_dist, 1, cpi->pc_root);
|
| } else {
|
| // If required set upper and lower partition size limits
|
| if (sf->auto_min_max_partition_size) {
|
| - set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
|
| - rd_auto_partition_range(cpi, tile, mi_row, mi_col,
|
| - &sf->min_partition_size,
|
| - &sf->max_partition_size);
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, BLOCK_64X64);
|
| + rd_auto_partition_range(cpi, tile_info, mi_row, mi_col,
|
| + &x->min_partition_size,
|
| + &x->max_partition_size);
|
| }
|
| - rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
|
| + rd_pick_partition(cpi, tile_data, tp, mi_row, mi_col, BLOCK_64X64,
|
| &dummy_rdc, INT64_MAX, cpi->pc_root);
|
| }
|
| }
|
| @@ -2695,28 +2584,36 @@
|
| return cpi->common.tx_mode;
|
| }
|
|
|
| -static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
|
| - int mi_row, int mi_col,
|
| - int *rate, int64_t *dist,
|
| +static void nonrd_pick_sb_modes(VP9_COMP *cpi,
|
| + TileDataEnc *tile_data,
|
| + int mi_row, int mi_col, RD_COST *rd_cost,
|
| BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| + TileInfo *const tile_info = &tile_data->tile_info;
|
| MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| MB_MODE_INFO *mbmi;
|
| - set_offsets(cpi, tile, mi_row, mi_col, bsize);
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, bsize);
|
| mbmi = &xd->mi[0].src_mi->mbmi;
|
| mbmi->sb_type = bsize;
|
|
|
| if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled)
|
| - if (mbmi->segment_id && x->in_static_area)
|
| + if (mbmi->segment_id)
|
| x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
|
|
|
| if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
|
| - set_mode_info_seg_skip(x, cm->tx_mode, rate, dist, bsize);
|
| + set_mode_info_seg_skip(x, cm->tx_mode, rd_cost, bsize);
|
| else
|
| - vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col, rate, dist, bsize, ctx);
|
| + vp9_pick_inter_mode(cpi, x, tile_data, mi_row, mi_col,
|
| + rd_cost, bsize, ctx);
|
|
|
| duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
|
| +
|
| + if (rd_cost->rate == INT_MAX)
|
| + vp9_rd_cost_reset(rd_cost);
|
| +
|
| + ctx->rate = rd_cost->rate;
|
| + ctx->dist = rd_cost->dist;
|
| }
|
|
|
| static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
|
| @@ -2776,14 +2673,32 @@
|
| }
|
| }
|
|
|
| -static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
|
| +// Reset the prediction pixel ready flag recursively.
|
| +static void pred_pixel_ready_reset(PC_TREE *pc_tree, BLOCK_SIZE bsize) {
|
| + pc_tree->none.pred_pixel_ready = 0;
|
| + pc_tree->horizontal[0].pred_pixel_ready = 0;
|
| + pc_tree->horizontal[1].pred_pixel_ready = 0;
|
| + pc_tree->vertical[0].pred_pixel_ready = 0;
|
| + pc_tree->vertical[1].pred_pixel_ready = 0;
|
| +
|
| + if (bsize > BLOCK_8X8) {
|
| + BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_SPLIT);
|
| + int i;
|
| + for (i = 0; i < 4; ++i)
|
| + pred_pixel_ready_reset(pc_tree->split[i], subsize);
|
| + }
|
| +}
|
| +
|
| +static void nonrd_pick_partition(VP9_COMP *cpi,
|
| + TileDataEnc *tile_data,
|
| TOKENEXTRA **tp, int mi_row,
|
| - int mi_col, BLOCK_SIZE bsize, int *rate,
|
| - int64_t *dist, int do_recon, int64_t best_rd,
|
| + int mi_col, BLOCK_SIZE bsize, RD_COST *rd_cost,
|
| + int do_recon, int64_t best_rd,
|
| PC_TREE *pc_tree) {
|
| const SPEED_FEATURES *const sf = &cpi->sf;
|
| const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
| VP9_COMMON *const cm = &cpi->common;
|
| + TileInfo *const tile_info = &tile_data->tile_info;
|
| MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| const int ms = num_8x8_blocks_wide_lookup[bsize] / 2;
|
| @@ -2791,9 +2706,7 @@
|
| PICK_MODE_CONTEXT *ctx = &pc_tree->none;
|
| int i;
|
| BLOCK_SIZE subsize = bsize;
|
| - int this_rate, sum_rate = 0, best_rate = INT_MAX;
|
| - int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX;
|
| - int64_t sum_rd = 0;
|
| + RD_COST this_rdc, sum_rdc, best_rdc;
|
| int do_split = bsize >= BLOCK_8X8;
|
| int do_rect = 1;
|
| // Override skipping rectangular partition operations for edge blocks
|
| @@ -2812,18 +2725,22 @@
|
| assert(num_8x8_blocks_wide_lookup[bsize] ==
|
| num_8x8_blocks_high_lookup[bsize]);
|
|
|
| + vp9_rd_cost_init(&sum_rdc);
|
| + vp9_rd_cost_reset(&best_rdc);
|
| + best_rdc.rdcost = best_rd;
|
| +
|
| // Determine partition types in search according to the speed features.
|
| // The threshold set here has to be of square block size.
|
| if (sf->auto_min_max_partition_size) {
|
| - partition_none_allowed &= (bsize <= sf->max_partition_size &&
|
| - bsize >= sf->min_partition_size);
|
| - partition_horz_allowed &= ((bsize <= sf->max_partition_size &&
|
| - bsize > sf->min_partition_size) ||
|
| + partition_none_allowed &= (bsize <= x->max_partition_size &&
|
| + bsize >= x->min_partition_size);
|
| + partition_horz_allowed &= ((bsize <= x->max_partition_size &&
|
| + bsize > x->min_partition_size) ||
|
| force_horz_split);
|
| - partition_vert_allowed &= ((bsize <= sf->max_partition_size &&
|
| - bsize > sf->min_partition_size) ||
|
| + partition_vert_allowed &= ((bsize <= x->max_partition_size &&
|
| + bsize > x->min_partition_size) ||
|
| force_vert_split);
|
| - do_split &= bsize > sf->min_partition_size;
|
| + do_split &= bsize > x->min_partition_size;
|
| }
|
| if (sf->use_square_partition_only) {
|
| partition_horz_allowed &= force_horz_split;
|
| @@ -2830,20 +2747,25 @@
|
| partition_vert_allowed &= force_vert_split;
|
| }
|
|
|
| + ctx->pred_pixel_ready = !(partition_vert_allowed ||
|
| + partition_horz_allowed ||
|
| + do_split);
|
| +
|
| // PARTITION_NONE
|
| if (partition_none_allowed) {
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
|
| - &this_rate, &this_dist, bsize, ctx);
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col,
|
| + &this_rdc, bsize, ctx);
|
| ctx->mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| ctx->skip_txfm[0] = x->skip_txfm[0];
|
| ctx->skip = x->skip;
|
|
|
| - if (this_rate != INT_MAX) {
|
| + if (this_rdc.rate != INT_MAX) {
|
| int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
|
| - this_rate += cpi->partition_cost[pl][PARTITION_NONE];
|
| - sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
|
| - if (sum_rd < best_rd) {
|
| - int dist_breakout_thr = sf->partition_search_breakout_dist_thr;
|
| + this_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
|
| + this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
|
| + this_rdc.rate, this_rdc.dist);
|
| + if (this_rdc.rdcost < best_rdc.rdcost) {
|
| + int64_t dist_breakout_thr = sf->partition_search_breakout_dist_thr;
|
| int64_t rate_breakout_thr = sf->partition_search_breakout_rate_thr;
|
|
|
| dist_breakout_thr >>= 8 - (b_width_log2_lookup[bsize] +
|
| @@ -2851,15 +2773,13 @@
|
|
|
| rate_breakout_thr *= num_pels_log2_lookup[bsize];
|
|
|
| - best_rate = this_rate;
|
| - best_dist = this_dist;
|
| - best_rd = sum_rd;
|
| + best_rdc = this_rdc;
|
| if (bsize >= BLOCK_8X8)
|
| pc_tree->partitioning = PARTITION_NONE;
|
|
|
| if (!x->e_mbd.lossless &&
|
| - this_rate < rate_breakout_thr &&
|
| - this_dist < dist_breakout_thr) {
|
| + this_rdc.rate < rate_breakout_thr &&
|
| + this_rdc.dist < dist_breakout_thr) {
|
| do_split = 0;
|
| do_rect = 0;
|
| }
|
| @@ -2871,12 +2791,12 @@
|
| store_pred_mv(x, ctx);
|
|
|
| // PARTITION_SPLIT
|
| - sum_rd = 0;
|
| if (do_split) {
|
| int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
|
| - sum_rate += cpi->partition_cost[pl][PARTITION_SPLIT];
|
| + sum_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
|
| + sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
|
| subsize = get_subsize(bsize, PARTITION_SPLIT);
|
| - for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
|
| + for (i = 0; i < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++i) {
|
| const int x_idx = (i & 1) * ms;
|
| const int y_idx = (i >> 1) * ms;
|
|
|
| @@ -2883,23 +2803,22 @@
|
| if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols)
|
| continue;
|
| load_pred_mv(x, ctx);
|
| - nonrd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx,
|
| - subsize, &this_rate, &this_dist, 0,
|
| - best_rd - sum_rd, pc_tree->split[i]);
|
| + nonrd_pick_partition(cpi, tile_data, tp,
|
| + mi_row + y_idx, mi_col + x_idx,
|
| + subsize, &this_rdc, 0,
|
| + best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[i]);
|
|
|
| - if (this_rate == INT_MAX) {
|
| - sum_rd = INT64_MAX;
|
| + if (this_rdc.rate == INT_MAX) {
|
| + vp9_rd_cost_reset(&sum_rdc);
|
| } else {
|
| - sum_rate += this_rate;
|
| - sum_dist += this_dist;
|
| - sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
| + sum_rdc.rate += this_rdc.rate;
|
| + sum_rdc.dist += this_rdc.dist;
|
| + sum_rdc.rdcost += this_rdc.rdcost;
|
| }
|
| }
|
|
|
| - if (sum_rd < best_rd) {
|
| - best_rate = sum_rate;
|
| - best_dist = sum_dist;
|
| - best_rd = sum_rd;
|
| + if (sum_rdc.rdcost < best_rdc.rdcost) {
|
| + best_rdc = sum_rdc;
|
| pc_tree->partitioning = PARTITION_SPLIT;
|
| } else {
|
| // skip rectangular partition test when larger block size
|
| @@ -2914,9 +2833,8 @@
|
| subsize = get_subsize(bsize, PARTITION_HORZ);
|
| if (sf->adaptive_motion_search)
|
| load_pred_mv(x, ctx);
|
| -
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
|
| - &this_rate, &this_dist, subsize,
|
| + pc_tree->horizontal[0].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &sum_rdc, subsize,
|
| &pc_tree->horizontal[0]);
|
|
|
| pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| @@ -2923,12 +2841,11 @@
|
| pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0];
|
| pc_tree->horizontal[0].skip = x->skip;
|
|
|
| - sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
| -
|
| - if (sum_rd < best_rd && mi_row + ms < cm->mi_rows) {
|
| + if (sum_rdc.rdcost < best_rdc.rdcost && mi_row + ms < cm->mi_rows) {
|
| load_pred_mv(x, ctx);
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col,
|
| - &this_rate, &this_dist, subsize,
|
| + pc_tree->horizontal[1].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row + ms, mi_col,
|
| + &this_rdc, subsize,
|
| &pc_tree->horizontal[1]);
|
|
|
| pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| @@ -2935,21 +2852,23 @@
|
| pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
|
| pc_tree->horizontal[1].skip = x->skip;
|
|
|
| - if (this_rate == INT_MAX) {
|
| - sum_rd = INT64_MAX;
|
| + if (this_rdc.rate == INT_MAX) {
|
| + vp9_rd_cost_reset(&sum_rdc);
|
| } else {
|
| int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
|
| - this_rate += cpi->partition_cost[pl][PARTITION_HORZ];
|
| - sum_rate += this_rate;
|
| - sum_dist += this_dist;
|
| - sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
| + this_rdc.rate += cpi->partition_cost[pl][PARTITION_HORZ];
|
| + sum_rdc.rate += this_rdc.rate;
|
| + sum_rdc.dist += this_rdc.dist;
|
| + sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
|
| + sum_rdc.rate, sum_rdc.dist);
|
| }
|
| }
|
| - if (sum_rd < best_rd) {
|
| - best_rd = sum_rd;
|
| - best_rate = sum_rate;
|
| - best_dist = sum_dist;
|
| +
|
| + if (sum_rdc.rdcost < best_rdc.rdcost) {
|
| + best_rdc = sum_rdc;
|
| pc_tree->partitioning = PARTITION_HORZ;
|
| + } else {
|
| + pred_pixel_ready_reset(pc_tree, bsize);
|
| }
|
| }
|
|
|
| @@ -2956,52 +2875,51 @@
|
| // PARTITION_VERT
|
| if (partition_vert_allowed && do_rect) {
|
| subsize = get_subsize(bsize, PARTITION_VERT);
|
| -
|
| if (sf->adaptive_motion_search)
|
| load_pred_mv(x, ctx);
|
| -
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
|
| - &this_rate, &this_dist, subsize,
|
| + pc_tree->vertical[0].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, &sum_rdc, subsize,
|
| &pc_tree->vertical[0]);
|
| pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
|
| pc_tree->vertical[0].skip = x->skip;
|
| - sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
| - if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) {
|
| +
|
| + if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + ms < cm->mi_cols) {
|
| load_pred_mv(x, ctx);
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms,
|
| - &this_rate, &this_dist, subsize,
|
| + pc_tree->vertical[1].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col + ms,
|
| + &this_rdc, subsize,
|
| &pc_tree->vertical[1]);
|
| pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
|
| pc_tree->vertical[1].skip = x->skip;
|
| - if (this_rate == INT_MAX) {
|
| - sum_rd = INT64_MAX;
|
| +
|
| + if (this_rdc.rate == INT_MAX) {
|
| + vp9_rd_cost_reset(&sum_rdc);
|
| } else {
|
| int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
|
| - this_rate += cpi->partition_cost[pl][PARTITION_VERT];
|
| - sum_rate += this_rate;
|
| - sum_dist += this_dist;
|
| - sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
| + sum_rdc.rate += cpi->partition_cost[pl][PARTITION_VERT];
|
| + sum_rdc.rate += this_rdc.rate;
|
| + sum_rdc.dist += this_rdc.dist;
|
| + sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
|
| + sum_rdc.rate, sum_rdc.dist);
|
| }
|
| }
|
| - if (sum_rd < best_rd) {
|
| - best_rate = sum_rate;
|
| - best_dist = sum_dist;
|
| - best_rd = sum_rd;
|
| +
|
| + if (sum_rdc.rdcost < best_rdc.rdcost) {
|
| + best_rdc = sum_rdc;
|
| pc_tree->partitioning = PARTITION_VERT;
|
| + } else {
|
| + pred_pixel_ready_reset(pc_tree, bsize);
|
| }
|
| }
|
| - // TODO(JBB): The following line is here just to avoid a static warning
|
| - // that occurs because at this point we never again reuse best_rd
|
| - // despite setting it here. The code should be refactored to avoid this.
|
| - (void) best_rd;
|
|
|
| - *rate = best_rate;
|
| - *dist = best_dist;
|
| + *rd_cost = best_rdc;
|
|
|
| - if (best_rate == INT_MAX)
|
| + if (best_rdc.rate == INT_MAX) {
|
| + vp9_rd_cost_reset(rd_cost);
|
| return;
|
| + }
|
|
|
| // update mode info array
|
| subsize = get_subsize(bsize, pc_tree->partitioning);
|
| @@ -3008,7 +2926,7 @@
|
| fill_mode_info_sb(cm, x, mi_row, mi_col, bsize, subsize,
|
| pc_tree);
|
|
|
| - if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
|
| + if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX && do_recon) {
|
| int output_enabled = (bsize == BLOCK_64X64);
|
|
|
| // Check the projected output rate for this SB against it's target
|
| @@ -3015,35 +2933,159 @@
|
| // and and if necessary apply a Q delta using segmentation to get
|
| // closer to the target.
|
| if ((oxcf->aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
|
| - vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
|
| - best_rate);
|
| + vp9_select_in_frame_q_segment(cpi, bsize, mi_row, mi_col, output_enabled,
|
| + best_rdc.rate);
|
| }
|
| -
|
| - if (oxcf->aq_mode == CYCLIC_REFRESH_AQ)
|
| - vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
|
| - best_rate, best_dist);
|
| -
|
| - encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize, pc_tree);
|
| + encode_sb_rt(cpi, tile_info, tp, mi_row, mi_col, output_enabled,
|
| + bsize, pc_tree);
|
| }
|
|
|
| if (bsize == BLOCK_64X64) {
|
| assert(tp_orig < *tp);
|
| - assert(best_rate < INT_MAX);
|
| - assert(best_dist < INT64_MAX);
|
| + assert(best_rdc.rate < INT_MAX);
|
| + assert(best_rdc.dist < INT64_MAX);
|
| } else {
|
| assert(tp_orig == *tp);
|
| }
|
| }
|
|
|
| +static void nonrd_select_partition(VP9_COMP *cpi,
|
| + TileDataEnc *tile_data,
|
| + MODE_INFO *mi,
|
| + TOKENEXTRA **tp,
|
| + int mi_row, int mi_col,
|
| + BLOCK_SIZE bsize, int output_enabled,
|
| + RD_COST *rd_cost, PC_TREE *pc_tree) {
|
| + VP9_COMMON *const cm = &cpi->common;
|
| + TileInfo *const tile_info = &tile_data->tile_info;
|
| + MACROBLOCK *const x = &cpi->mb;
|
| + MACROBLOCKD *const xd = &x->e_mbd;
|
| + const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
|
| + const int mis = cm->mi_stride;
|
| + PARTITION_TYPE partition;
|
| + BLOCK_SIZE subsize;
|
| + RD_COST this_rdc;
|
| +
|
| + vp9_rd_cost_reset(&this_rdc);
|
| + if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
|
| + return;
|
| +
|
| + subsize = (bsize >= BLOCK_8X8) ? mi[0].src_mi->mbmi.sb_type : BLOCK_4X4;
|
| + partition = partition_lookup[bsl][subsize];
|
| +
|
| + if (bsize == BLOCK_32X32 && partition != PARTITION_NONE &&
|
| + subsize >= BLOCK_16X16) {
|
| + x->max_partition_size = BLOCK_32X32;
|
| + x->min_partition_size = BLOCK_8X8;
|
| + nonrd_pick_partition(cpi, tile_data, tp, mi_row, mi_col, bsize,
|
| + rd_cost, 0, INT64_MAX, pc_tree);
|
| + } else if (bsize == BLOCK_16X16 && partition != PARTITION_NONE) {
|
| + x->max_partition_size = BLOCK_16X16;
|
| + x->min_partition_size = BLOCK_8X8;
|
| + nonrd_pick_partition(cpi, tile_data, tp, mi_row, mi_col, bsize,
|
| + rd_cost, 0, INT64_MAX, pc_tree);
|
| + } else {
|
| + switch (partition) {
|
| + case PARTITION_NONE:
|
| + pc_tree->none.pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost,
|
| + subsize, &pc_tree->none);
|
| + pc_tree->none.mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| + pc_tree->none.skip_txfm[0] = x->skip_txfm[0];
|
| + pc_tree->none.skip = x->skip;
|
| + break;
|
| + case PARTITION_VERT:
|
| + pc_tree->vertical[0].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost,
|
| + subsize, &pc_tree->vertical[0]);
|
| + pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| + pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
|
| + pc_tree->vertical[0].skip = x->skip;
|
| + if (mi_col + hbs < cm->mi_cols) {
|
| + pc_tree->vertical[1].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col + hbs,
|
| + &this_rdc, subsize, &pc_tree->vertical[1]);
|
| + pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| + pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
|
| + pc_tree->vertical[1].skip = x->skip;
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| + }
|
| + }
|
| + break;
|
| + case PARTITION_HORZ:
|
| + pc_tree->horizontal[0].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost,
|
| + subsize, &pc_tree->horizontal[0]);
|
| + pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| + pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0];
|
| + pc_tree->horizontal[0].skip = x->skip;
|
| + if (mi_row + hbs < cm->mi_rows) {
|
| + pc_tree->horizontal[1].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row + hbs, mi_col,
|
| + &this_rdc, subsize, &pc_tree->horizontal[0]);
|
| + pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| + pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
|
| + pc_tree->horizontal[1].skip = x->skip;
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| + }
|
| + }
|
| + break;
|
| + case PARTITION_SPLIT:
|
| + subsize = get_subsize(bsize, PARTITION_SPLIT);
|
| + nonrd_select_partition(cpi, tile_data, mi, tp, mi_row, mi_col,
|
| + subsize, output_enabled, rd_cost,
|
| + pc_tree->split[0]);
|
| + nonrd_select_partition(cpi, tile_data, mi + hbs, tp,
|
| + mi_row, mi_col + hbs, subsize, output_enabled,
|
| + &this_rdc, pc_tree->split[1]);
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| + }
|
| + nonrd_select_partition(cpi, tile_data, mi + hbs * mis, tp,
|
| + mi_row + hbs, mi_col, subsize, output_enabled,
|
| + &this_rdc, pc_tree->split[2]);
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| + }
|
| + nonrd_select_partition(cpi, tile_data, mi + hbs * mis + hbs, tp,
|
| + mi_row + hbs, mi_col + hbs, subsize,
|
| + output_enabled, &this_rdc, pc_tree->split[3]);
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| + }
|
| + break;
|
| + default:
|
| + assert("Invalid partition type.");
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (bsize == BLOCK_64X64 && output_enabled)
|
| + encode_sb_rt(cpi, tile_info, tp, mi_row, mi_col, 1, bsize, pc_tree);
|
| +}
|
| +
|
| +
|
| static void nonrd_use_partition(VP9_COMP *cpi,
|
| - const TileInfo *const tile,
|
| + TileDataEnc *tile_data,
|
| MODE_INFO *mi,
|
| TOKENEXTRA **tp,
|
| int mi_row, int mi_col,
|
| BLOCK_SIZE bsize, int output_enabled,
|
| - int *totrate, int64_t *totdist,
|
| - PC_TREE *pc_tree) {
|
| + RD_COST *rd_cost, PC_TREE *pc_tree) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| + TileInfo *tile_info = &tile_data->tile_info;
|
| MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| const int bsl = b_width_log2_lookup[bsize], hbs = (1 << bsl) / 4;
|
| @@ -3050,9 +3092,9 @@
|
| const int mis = cm->mi_stride;
|
| PARTITION_TYPE partition;
|
| BLOCK_SIZE subsize;
|
| - int rate = INT_MAX;
|
| - int64_t dist = INT64_MAX;
|
| + RD_COST this_rdc;
|
|
|
| + vp9_rd_cost_reset(&this_rdc);
|
| if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
|
| return;
|
|
|
| @@ -3059,80 +3101,103 @@
|
| subsize = (bsize >= BLOCK_8X8) ? mi[0].src_mi->mbmi.sb_type : BLOCK_4X4;
|
| partition = partition_lookup[bsl][subsize];
|
|
|
| + if (output_enabled && bsize != BLOCK_4X4) {
|
| + int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
|
| + cm->counts.partition[ctx][partition]++;
|
| + }
|
| +
|
| switch (partition) {
|
| case PARTITION_NONE:
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist,
|
| + pc_tree->none.pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost,
|
| subsize, &pc_tree->none);
|
| pc_tree->none.mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| pc_tree->none.skip_txfm[0] = x->skip_txfm[0];
|
| pc_tree->none.skip = x->skip;
|
| + encode_b_rt(cpi, tile_info, tp, mi_row, mi_col, output_enabled, subsize,
|
| + &pc_tree->none);
|
| break;
|
| case PARTITION_VERT:
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist,
|
| + pc_tree->vertical[0].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost,
|
| subsize, &pc_tree->vertical[0]);
|
| pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
|
| pc_tree->vertical[0].skip = x->skip;
|
| + encode_b_rt(cpi, tile_info, tp, mi_row, mi_col, output_enabled, subsize,
|
| + &pc_tree->vertical[0]);
|
| if (mi_col + hbs < cm->mi_cols) {
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs,
|
| - &rate, &dist, subsize, &pc_tree->vertical[1]);
|
| + pc_tree->vertical[1].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col + hbs,
|
| + &this_rdc, subsize, &pc_tree->vertical[1]);
|
| pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
|
| pc_tree->vertical[1].skip = x->skip;
|
| - if (rate != INT_MAX && dist != INT64_MAX &&
|
| - *totrate != INT_MAX && *totdist != INT64_MAX) {
|
| - *totrate += rate;
|
| - *totdist += dist;
|
| + encode_b_rt(cpi, tile_info, tp, mi_row, mi_col + hbs,
|
| + output_enabled, subsize, &pc_tree->vertical[1]);
|
| +
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| }
|
| }
|
| break;
|
| case PARTITION_HORZ:
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist,
|
| + pc_tree->horizontal[0].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row, mi_col, rd_cost,
|
| subsize, &pc_tree->horizontal[0]);
|
| pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0];
|
| pc_tree->horizontal[0].skip = x->skip;
|
| + encode_b_rt(cpi, tile_info, tp, mi_row, mi_col, output_enabled, subsize,
|
| + &pc_tree->horizontal[0]);
|
| +
|
| if (mi_row + hbs < cm->mi_rows) {
|
| - nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col,
|
| - &rate, &dist, subsize, &pc_tree->horizontal[0]);
|
| + pc_tree->horizontal[1].pred_pixel_ready = 1;
|
| + nonrd_pick_sb_modes(cpi, tile_data, mi_row + hbs, mi_col,
|
| + &this_rdc, subsize, &pc_tree->horizontal[0]);
|
| pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
|
| pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
|
| pc_tree->horizontal[1].skip = x->skip;
|
| - if (rate != INT_MAX && dist != INT64_MAX &&
|
| - *totrate != INT_MAX && *totdist != INT64_MAX) {
|
| - *totrate += rate;
|
| - *totdist += dist;
|
| + encode_b_rt(cpi, tile_info, tp, mi_row + hbs, mi_col,
|
| + output_enabled, subsize, &pc_tree->horizontal[1]);
|
| +
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| }
|
| }
|
| break;
|
| case PARTITION_SPLIT:
|
| subsize = get_subsize(bsize, PARTITION_SPLIT);
|
| - nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col,
|
| - subsize, output_enabled, totrate, totdist,
|
| + nonrd_use_partition(cpi, tile_data, mi, tp, mi_row, mi_col,
|
| + subsize, output_enabled, rd_cost,
|
| pc_tree->split[0]);
|
| - nonrd_use_partition(cpi, tile, mi + hbs, tp,
|
| + nonrd_use_partition(cpi, tile_data, mi + hbs, tp,
|
| mi_row, mi_col + hbs, subsize, output_enabled,
|
| - &rate, &dist, pc_tree->split[1]);
|
| - if (rate != INT_MAX && dist != INT64_MAX &&
|
| - *totrate != INT_MAX && *totdist != INT64_MAX) {
|
| - *totrate += rate;
|
| - *totdist += dist;
|
| + &this_rdc, pc_tree->split[1]);
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| }
|
| - nonrd_use_partition(cpi, tile, mi + hbs * mis, tp,
|
| + nonrd_use_partition(cpi, tile_data, mi + hbs * mis, tp,
|
| mi_row + hbs, mi_col, subsize, output_enabled,
|
| - &rate, &dist, pc_tree->split[2]);
|
| - if (rate != INT_MAX && dist != INT64_MAX &&
|
| - *totrate != INT_MAX && *totdist != INT64_MAX) {
|
| - *totrate += rate;
|
| - *totdist += dist;
|
| + &this_rdc, pc_tree->split[2]);
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| }
|
| - nonrd_use_partition(cpi, tile, mi + hbs * mis + hbs, tp,
|
| + nonrd_use_partition(cpi, tile_data, mi + hbs * mis + hbs, tp,
|
| mi_row + hbs, mi_col + hbs, subsize, output_enabled,
|
| - &rate, &dist, pc_tree->split[3]);
|
| - if (rate != INT_MAX && dist != INT64_MAX &&
|
| - *totrate != INT_MAX && *totdist != INT64_MAX) {
|
| - *totrate += rate;
|
| - *totdist += dist;
|
| + &this_rdc, pc_tree->split[3]);
|
| + if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
|
| + rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
|
| + rd_cost->rate += this_rdc.rate;
|
| + rd_cost->dist += this_rdc.dist;
|
| }
|
| break;
|
| default:
|
| @@ -3140,18 +3205,17 @@
|
| break;
|
| }
|
|
|
| - if (bsize == BLOCK_64X64 && output_enabled) {
|
| - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
|
| - vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
|
| - *totrate, *totdist);
|
| - encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, bsize, pc_tree);
|
| - }
|
| + if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8)
|
| + update_partition_context(xd, mi_row, mi_col, subsize, bsize);
|
| }
|
|
|
| -static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
|
| - int mi_row, TOKENEXTRA **tp) {
|
| +static void encode_nonrd_sb_row(VP9_COMP *cpi,
|
| + TileDataEnc *tile_data,
|
| + int mi_row,
|
| + TOKENEXTRA **tp) {
|
| SPEED_FEATURES *const sf = &cpi->sf;
|
| VP9_COMMON *const cm = &cpi->common;
|
| + TileInfo *const tile_info = &tile_data->tile_info;
|
| MACROBLOCK *const x = &cpi->mb;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| int mi_col;
|
| @@ -3161,53 +3225,52 @@
|
| vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
|
|
|
| // Code each SB in the row
|
| - for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
|
| + for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
|
| mi_col += MI_BLOCK_SIZE) {
|
| - int dummy_rate = 0;
|
| - int64_t dummy_dist = 0;
|
| + RD_COST dummy_rdc;
|
| const int idx_str = cm->mi_stride * mi_row + mi_col;
|
| MODE_INFO *mi = cm->mi + idx_str;
|
| BLOCK_SIZE bsize;
|
| - x->in_static_area = 0;
|
| x->source_variance = UINT_MAX;
|
| vp9_zero(x->pred_mv);
|
| + vp9_rd_cost_init(&dummy_rdc);
|
|
|
| // Set the partition type of the 64X64 block
|
| switch (sf->partition_search_type) {
|
| case VAR_BASED_PARTITION:
|
| - choose_partitioning(cpi, tile, mi_row, mi_col);
|
| - nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
|
| - 1, &dummy_rate, &dummy_dist, cpi->pc_root);
|
| + choose_partitioning(cpi, tile_info, mi_row, mi_col);
|
| + nonrd_use_partition(cpi, tile_data, mi, tp, mi_row, mi_col,
|
| + BLOCK_64X64, 1, &dummy_rdc, cpi->pc_root);
|
| break;
|
| case SOURCE_VAR_BASED_PARTITION:
|
| - set_source_var_based_partition(cpi, tile, mi, mi_row, mi_col);
|
| - nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
|
| - 1, &dummy_rate, &dummy_dist, cpi->pc_root);
|
| + set_source_var_based_partition(cpi, tile_info, mi, mi_row, mi_col);
|
| + nonrd_use_partition(cpi, tile_data, mi, tp, mi_row, mi_col,
|
| + BLOCK_64X64, 1, &dummy_rdc, cpi->pc_root);
|
| break;
|
| case FIXED_PARTITION:
|
| bsize = sf->partition_search_type == FIXED_PARTITION ?
|
| sf->always_this_block_size :
|
| get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col);
|
| - set_fixed_partitioning(cpi, tile, mi, mi_row, mi_col, bsize);
|
| - nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
|
| - 1, &dummy_rate, &dummy_dist, cpi->pc_root);
|
| + set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
|
| + nonrd_use_partition(cpi, tile_data, mi, tp, mi_row, mi_col,
|
| + BLOCK_64X64, 1, &dummy_rdc, cpi->pc_root);
|
| break;
|
| case REFERENCE_PARTITION:
|
| - if (sf->partition_check ||
|
| - !(x->in_static_area = is_background(cpi, tile, mi_row, mi_col))) {
|
| - set_modeinfo_offsets(cm, xd, mi_row, mi_col);
|
| - auto_partition_range(cpi, tile, mi_row, mi_col,
|
| - &sf->min_partition_size,
|
| - &sf->max_partition_size);
|
| - nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
|
| - &dummy_rate, &dummy_dist, 1, INT64_MAX,
|
| - cpi->pc_root);
|
| + set_offsets(cpi, tile_info, mi_row, mi_col, BLOCK_64X64);
|
| + if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled &&
|
| + xd->mi[0].src_mi->mbmi.segment_id) {
|
| + auto_partition_range(cpi, tile_info, mi_row, mi_col,
|
| + &x->min_partition_size,
|
| + &x->max_partition_size);
|
| + nonrd_pick_partition(cpi, tile_data, tp, mi_row, mi_col,
|
| + BLOCK_64X64, &dummy_rdc, 1,
|
| + INT64_MAX, cpi->pc_root);
|
| } else {
|
| - choose_partitioning(cpi, tile, mi_row, mi_col);
|
| - nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col,
|
| - BLOCK_64X64, 1, &dummy_rate, &dummy_dist,
|
| - cpi->pc_root);
|
| + choose_partitioning(cpi, tile_info, mi_row, mi_col);
|
| + nonrd_select_partition(cpi, tile_data, mi, tp, mi_row, mi_col,
|
| + BLOCK_64X64, 1, &dummy_rdc, cpi->pc_root);
|
| }
|
| +
|
| break;
|
| default:
|
| assert(0);
|
| @@ -3343,43 +3406,64 @@
|
| cm->show_frame;
|
| }
|
|
|
| +static void tile_data_init(TileDataEnc *tile_data) {
|
| + int i, j;
|
| + for (i = 0; i < BLOCK_SIZES; ++i) {
|
| + for (j = 0; j < MAX_MODES; ++j) {
|
| + tile_data->thresh_freq_fact[i][j] = 32;
|
| + tile_data->mode_map[i][j] = j;
|
| + }
|
| + }
|
| +}
|
| +
|
| static void encode_tiles(VP9_COMP *cpi) {
|
| - const VP9_COMMON *const cm = &cpi->common;
|
| + VP9_COMMON *const cm = &cpi->common;
|
| const int tile_cols = 1 << cm->log2_tile_cols;
|
| const int tile_rows = 1 << cm->log2_tile_rows;
|
|
|
| int tile_col, tile_row;
|
| - TileInfo tile[4][1 << 6];
|
| TOKENEXTRA *tok[4][1 << 6];
|
| TOKENEXTRA *pre_tok = cpi->tok;
|
| int tile_tok = 0;
|
|
|
| + if (cpi->tile_data == NULL) {
|
| + CHECK_MEM_ERROR(cm, cpi->tile_data,
|
| + vpx_malloc(tile_cols * tile_rows * sizeof(*cpi->tile_data)));
|
| + for (tile_row = 0; tile_row < tile_rows; ++tile_row)
|
| + for (tile_col = 0; tile_col < tile_cols; ++tile_col)
|
| + tile_data_init(&cpi->tile_data[tile_row * tile_cols + tile_col]);
|
| + }
|
| +
|
| for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
|
| for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
|
| - vp9_tile_init(&tile[tile_row][tile_col], cm, tile_row, tile_col);
|
| + TileInfo *tile_info =
|
| + &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
|
| + vp9_tile_init(tile_info, cm, tile_row, tile_col);
|
|
|
| tok[tile_row][tile_col] = pre_tok + tile_tok;
|
| pre_tok = tok[tile_row][tile_col];
|
| - tile_tok = allocated_tokens(tile[tile_row][tile_col]);
|
| + tile_tok = allocated_tokens(*tile_info);
|
| }
|
| }
|
|
|
| for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
|
| for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
|
| - const TileInfo * const ptile = &tile[tile_row][tile_col];
|
| + const TileInfo * const tile_info =
|
| + &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
|
| TOKENEXTRA * const old_tok = tok[tile_row][tile_col];
|
| int mi_row;
|
| + TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col];
|
|
|
| - for (mi_row = ptile->mi_row_start; mi_row < ptile->mi_row_end;
|
| + for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
|
| mi_row += MI_BLOCK_SIZE) {
|
| if (cpi->sf.use_nonrd_pick_mode && !frame_is_intra_only(cm))
|
| - encode_nonrd_sb_row(cpi, ptile, mi_row, &tok[tile_row][tile_col]);
|
| + encode_nonrd_sb_row(cpi, this_tile, mi_row, &tok[tile_row][tile_col]);
|
| else
|
| - encode_rd_sb_row(cpi, ptile, mi_row, &tok[tile_row][tile_col]);
|
| + encode_rd_sb_row(cpi, this_tile, mi_row, &tok[tile_row][tile_col]);
|
| }
|
| cpi->tok_count[tile_row][tile_col] =
|
| (unsigned int)(tok[tile_row][tile_col] - old_tok);
|
| - assert(tok[tile_row][tile_col] - old_tok <= allocated_tokens(*ptile));
|
| + assert(tok[tile_row][tile_col] - old_tok <= allocated_tokens(*tile_info));
|
| }
|
| }
|
| }
|
| @@ -3405,15 +3489,16 @@
|
| MACROBLOCK *const x = &cpi->mb;
|
| VP9_COMMON *const cm = &cpi->common;
|
| MACROBLOCKD *const xd = &x->e_mbd;
|
| + COUNTS *const counts = cpi->frame_counts;
|
|
|
| xd->mi = cm->mi;
|
| xd->mi[0].src_mi = &xd->mi[0];
|
|
|
| vp9_zero(cm->counts);
|
| - vp9_zero(cpi->coef_counts);
|
| - vp9_zero(rd_opt->comp_pred_diff);
|
| - vp9_zero(rd_opt->filter_diff);
|
| - vp9_zero(rd_opt->tx_select_diff);
|
| + vp9_zero(counts->coef_counts);
|
| + vp9_zero(counts->comp_pred_diff);
|
| + vp9_zero(counts->filter_diff);
|
| + vp9_zero(counts->tx_select_diff);
|
| vp9_zero(rd_opt->tx_select_threshes);
|
|
|
| xd->lossless = cm->base_qindex == 0 &&
|
| @@ -3447,6 +3532,11 @@
|
| vp9_initialize_me_consts(cpi, cm->base_qindex);
|
| init_encode_frame_mb_context(cpi);
|
| set_prev_mi(cm);
|
| + cm->use_prev_frame_mvs = !cm->error_resilient_mode &&
|
| + cm->width == cm->last_width &&
|
| + cm->height == cm->last_height &&
|
| + !cm->intra_only &&
|
| + cm->last_show_frame;
|
|
|
| x->quant_fp = cpi->sf.use_quant_fp;
|
| vp9_zero(x->skip_txfm);
|
| @@ -3515,6 +3605,7 @@
|
| void vp9_encode_frame(VP9_COMP *cpi) {
|
| VP9_COMMON *const cm = &cpi->common;
|
| RD_OPT *const rd_opt = &cpi->rd;
|
| + COUNTS *const counts = cpi->frame_counts;
|
|
|
| // In the longer term the encoder should be generalized to match the
|
| // decoder such that we allow compound where one of the 3 buffers has a
|
| @@ -3572,13 +3663,13 @@
|
| encode_frame_internal(cpi);
|
|
|
| for (i = 0; i < REFERENCE_MODES; ++i)
|
| - mode_thrs[i] = (mode_thrs[i] + rd_opt->comp_pred_diff[i] / cm->MBs) / 2;
|
| + mode_thrs[i] = (mode_thrs[i] + counts->comp_pred_diff[i] / cm->MBs) / 2;
|
|
|
| for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
|
| - filter_thrs[i] = (filter_thrs[i] + rd_opt->filter_diff[i] / cm->MBs) / 2;
|
| + filter_thrs[i] = (filter_thrs[i] + counts->filter_diff[i] / cm->MBs) / 2;
|
|
|
| for (i = 0; i < TX_MODES; ++i) {
|
| - int64_t pd = rd_opt->tx_select_diff[i];
|
| + int64_t pd = counts->tx_select_diff[i];
|
| if (i == TX_MODE_SELECT)
|
| pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv, 2048 * (TX_SIZES - 1), 0);
|
| tx_thrs[i] = (tx_thrs[i] + (int)(pd / cm->MBs)) / 2;
|
| @@ -3737,7 +3828,7 @@
|
| vp9_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
|
| &xd->block_refs[ref]->sf);
|
| }
|
| - if (!cpi->sf.reuse_inter_pred_sby || seg_skip)
|
| + if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
|
| vp9_build_inter_predictors_sby(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
|
|
|
| vp9_build_inter_predictors_sbuv(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
|
|
|