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)); |