ref: d4158283e79fbdf684ec4f2f983509b793c59090
parent: ba3b2604f0cc43e2c26bad67518163a02f48455a
author: Jim Bankoski <jimbankoski@google.com>
date: Mon Jul 1 14:18:50 EDT 2013
use partitioning from last frame This cl converts use partition from last frame to do the following: if part is none,horz, vert -> try split if part != none and one of the children is not split - try none Change-Id: I5b6c659e35f3ac9f11c051b92ba98af6d7e8aa87 Signed-off-by: Jim Bankoski <jimbankoski@google.com>
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -322,6 +322,7 @@
MACROBLOCKD * const xd = &x->e_mbd;
MODE_INFO *mi = &ctx->mic;
MB_MODE_INFO * const mbmi = &xd->mode_info_context->mbmi;
+
int mb_mode_index = ctx->best_mode_index;
const int mis = cpi->common.mode_info_stride;
const int bh = 1 << mi_height_log2(bsize), bw = 1 << mi_width_log2(bsize);
@@ -690,8 +691,8 @@
vpx_memcpy(cm->above_seg_context + mi_col, sa,
sizeof(PARTITION_CONTEXT) * mw);
vpx_memcpy(cm->left_seg_context + (mi_row & MI_MASK), sl,
- sizeof(PARTITION_CONTEXT) * mh)
- ;}
+ sizeof(PARTITION_CONTEXT) * mh);
+}
static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
ENTROPY_CONTEXT a[16 * MAX_MB_PLANE],
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
@@ -1158,8 +1159,10 @@
int bwl = b_width_log2(m->mbmi.sb_type);
int bhl = b_height_log2(m->mbmi.sb_type);
int bsl = b_width_log2(bsize);
- int bh = (1 << bhl);
int bs = (1 << bsl);
+ int bh = (1 << bhl);
+ int ms = bs / 2;
+ int mh = bh / 2;
int bss = (1 << bsl) / 4;
int i, pl;
PARTITION_TYPE partition;
@@ -1166,8 +1169,17 @@
BLOCK_SIZE_TYPE subsize;
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
PARTITION_CONTEXT sl[8], sa[8];
- int r = 0;
- int64_t d = 0;
+ int last_part_rate = INT_MAX;
+ int64_t last_part_dist = INT_MAX;
+ int split_rate = INT_MAX;
+ int64_t split_dist = INT_MAX;
+ int none_rate = INT_MAX;
+ int64_t none_dist = INT_MAX;
+ int chosen_rate = INT_MAX;
+ int64_t chosen_dist = INT_MAX;
+ BLOCK_SIZE_TYPE sub_subsize = BLOCK_SIZE_AB4X4;
+ int splits_below = 0;
+ BLOCK_SIZE_TYPE bs_type = m->mbmi.sb_type;
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
@@ -1195,60 +1207,96 @@
} else {
*(get_sb_partitioning(x, bsize)) = subsize;
}
- pl = partition_plane_context(xd, bsize);
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
+
+ if (cpi->sf.adjust_partitioning_from_last_frame) {
+ // Check if any of the sub blocks are further split.
+ if (partition == PARTITION_SPLIT && subsize > BLOCK_SIZE_SB8X8) {
+ sub_subsize = get_subsize(subsize, PARTITION_SPLIT);
+ splits_below = 1;
+ for (i = 0; i < 4; i++) {
+ int jj = i >> 1, ii = i & 0x01;
+ if (m[jj * bss * mis + ii * bss].mbmi.sb_type >= sub_subsize) {
+ splits_below = 0;
+ }
+ }
+ }
+
+ // If partition is not none try none unless each of the 4 splits are split
+ // even further..
+ if (partition != PARTITION_NONE && !splits_below &&
+ mi_row + (ms >> 1) < cm->mi_rows &&
+ mi_col + (ms >> 1) < cm->mi_cols) {
+ *(get_sb_partitioning(x, bsize)) = bsize;
+ pick_sb_modes(cpi, mi_row, mi_col, tp, &none_rate, &none_dist, bsize,
+ get_block_context(x, bsize));
+
+ set_partition_seg_context(cm, xd, mi_row, mi_col);
+ pl = partition_plane_context(xd, bsize);
+ none_rate += x->partition_cost[pl][PARTITION_NONE];
+
+ restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
+ m->mbmi.sb_type = bs_type;
+ *(get_sb_partitioning(x, bsize)) = subsize;
+ }
+ }
+
switch (partition) {
case PARTITION_NONE:
- pick_sb_modes(cpi, mi_row, mi_col, tp, &r, &d, bsize,
- get_block_context(x, bsize));
- r += x->partition_cost[pl][PARTITION_NONE];
+ pick_sb_modes(cpi, mi_row, mi_col, tp, &last_part_rate, &last_part_dist,
+ bsize, get_block_context(x, bsize));
+ set_partition_seg_context(cm, xd, mi_row, mi_col);
+ pl = partition_plane_context(xd, bsize);
+ last_part_rate += x->partition_cost[pl][PARTITION_NONE];
break;
case PARTITION_HORZ:
*(get_sb_index(xd, subsize)) = 0;
- pick_sb_modes(cpi, mi_row, mi_col, tp, &r, &d, subsize,
- get_block_context(x, subsize));
- if (mi_row + (bh >> 1) <= cm->mi_rows) {
+ pick_sb_modes(cpi, mi_row, mi_col, tp, &last_part_rate, &last_part_dist,
+ subsize, get_block_context(x, subsize));
+ if (bsize >= BLOCK_SIZE_SB8X8 && mi_row + (mh >> 1) < cm->mi_rows) {
int rt = 0;
int64_t dt = 0;
update_state(cpi, get_block_context(x, subsize), subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
*(get_sb_index(xd, subsize)) = 1;
- pick_sb_modes(cpi, mi_row + (bs >> 2), mi_col, tp, &rt, &dt, subsize,
+ pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, tp, &rt, &dt, subsize,
get_block_context(x, subsize));
- r += rt;
- d += dt;
+ last_part_rate += rt;
+ last_part_dist += dt;
}
set_partition_seg_context(cm, xd, mi_row, mi_col);
pl = partition_plane_context(xd, bsize);
- r += x->partition_cost[pl][PARTITION_HORZ];
+ last_part_rate += x->partition_cost[pl][PARTITION_HORZ];
break;
case PARTITION_VERT:
*(get_sb_index(xd, subsize)) = 0;
- pick_sb_modes(cpi, mi_row, mi_col, tp, &r, &d, subsize,
- get_block_context(x, subsize));
- if (mi_col + (bs >> 1) <= cm->mi_cols) {
+ pick_sb_modes(cpi, mi_row, mi_col, tp, &last_part_rate, &last_part_dist,
+ subsize, get_block_context(x, subsize));
+ if (bsize >= BLOCK_SIZE_SB8X8 && mi_col + (ms >> 1) < cm->mi_cols) {
int rt = 0;
int64_t dt = 0;
update_state(cpi, get_block_context(x, subsize), subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
*(get_sb_index(xd, subsize)) = 1;
- pick_sb_modes(cpi, mi_row, mi_col + (bs >> 2), tp, &rt, &dt, subsize,
+ pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), tp, &rt, &dt, subsize,
get_block_context(x, subsize));
- r += rt;
- d += dt;
+ last_part_rate += rt;
+ last_part_dist += dt;
}
set_partition_seg_context(cm, xd, mi_row, mi_col);
pl = partition_plane_context(xd, bsize);
- r += x->partition_cost[pl][PARTITION_VERT];
- restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
+ last_part_rate += x->partition_cost[pl][PARTITION_VERT];
break;
case PARTITION_SPLIT:
+ // Split partition.
+ last_part_rate = 0;
+ last_part_dist = 0;
for (i = 0; i < 4; i++) {
- int x_idx = (i & 1) * (bs >> 2);
- int y_idx = (i >> 1) * (bs >> 2);
+ int x_idx = (i & 1) * (ms >> 1);
+ int y_idx = (i >> 1) * (ms >> 1);
int jj = i >> 1, ii = i & 0x01;
- int rt = 0;
- int64_t dt = 0;
+ int rt;
+ int64_t dt;
if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
continue;
@@ -1257,23 +1305,94 @@
rd_use_partition(cpi, m + jj * bss * mis + ii * bss, tp, mi_row + y_idx,
mi_col + x_idx, subsize, &rt, &dt);
- r += rt;
- d += dt;
+ last_part_rate += rt;
+ last_part_dist += dt;
}
set_partition_seg_context(cm, xd, mi_row, mi_col);
pl = partition_plane_context(xd, bsize);
- r += x->partition_cost[pl][PARTITION_SPLIT];
+ last_part_rate += x->partition_cost[pl][PARTITION_SPLIT];
break;
default:
assert(0);
}
+ if (cpi->sf.adjust_partitioning_from_last_frame
+ && partition != PARTITION_SPLIT && bsize > BLOCK_SIZE_SB8X8
+ && (mi_row + ms < cm->mi_rows || mi_row + (ms >> 1) == cm->mi_rows)
+ && (mi_col + ms < cm->mi_cols || mi_col + (ms >> 1) == cm->mi_cols)) {
+ BLOCK_SIZE_TYPE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
+ split_rate = 0;
+ split_dist = 0;
+ restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
+ // Split partition.
+ for (i = 0; i < 4; i++) {
+ int x_idx = (i & 1) * (bs >> 2);
+ int y_idx = (i >> 1) * (bs >> 2);
+ int rt = 0;
+ int64_t dt = 0;
+ ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
+ PARTITION_CONTEXT sl[8], sa[8];
+
+ if ((mi_row + y_idx >= cm->mi_rows)
+ || (mi_col + x_idx >= cm->mi_cols))
+ continue;
+
+ *(get_sb_index(xd, split_subsize)) = i;
+ *(get_sb_partitioning(x, bsize)) = split_subsize;
+ *(get_sb_partitioning(x, split_subsize)) = split_subsize;
+
+ save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
+
+ pick_sb_modes(cpi, mi_row + y_idx, mi_col + x_idx, tp, &rt, &dt,
+ split_subsize, get_block_context(x, split_subsize));
+
+ restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
+
+ if (rt < INT_MAX && dt < INT_MAX)
+ encode_sb(cpi, tp, mi_row + y_idx, mi_col + x_idx, 0,
+ split_subsize);
+
+ split_rate += rt;
+ split_dist += dt;
+ set_partition_seg_context(cm, xd, mi_row + y_idx, mi_col + x_idx);
+ pl = partition_plane_context(xd, bsize);
+ split_rate += x->partition_cost[pl][PARTITION_NONE];
+ }
+ set_partition_seg_context(cm, xd, mi_row, mi_col);
+ pl = partition_plane_context(xd, bsize);
+ split_rate += x->partition_cost[pl][PARTITION_SPLIT];
+
+ chosen_rate = split_rate;
+ chosen_dist = split_dist;
+ }
+
+ // If last_part is better set the partitioning to that...
+ if (RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist)
+ < RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist)) {
+ m->mbmi.sb_type = bsize;
+ if (bsize >= BLOCK_SIZE_SB8X8)
+ *(get_sb_partitioning(x, bsize)) = subsize;
+ chosen_rate = last_part_rate;
+ chosen_dist = last_part_dist;
+ }
+ // If none was better set the partitioning to that...
+ if (RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist)
+ > RDCOST(x->rdmult, x->rddiv, none_rate, none_dist)) {
+ if (bsize >= BLOCK_SIZE_SB8X8)
+ *(get_sb_partitioning(x, bsize)) = bsize;
+ chosen_rate = none_rate;
+ chosen_dist = none_dist;
+ }
+
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
- if (r < INT_MAX && d < INT_MAX)
- encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_SIZE_SB64X64, bsize);
- *rate = r;
- *dist = d;
+ // We must have chosen a partitioning and encoding or we'll fail later on.
+ // No other opportunities for success.
+ assert(chosen_rate < INT_MAX && chosen_dist < INT_MAX);
+
+ encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_SIZE_SB64X64, bsize);
+ *rate = chosen_rate;
+ *dist = chosen_dist;
}
@@ -1483,7 +1602,9 @@
rd_use_partition(cpi, m, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
&dummy_rate, &dummy_dist);
} else {
- if ((cpi->common.current_video_frame & 1) == 0 || cm->prev_mi == 0
+ if ((cpi->common.current_video_frame
+ % cpi->sf.last_partitioning_redo_frequency) == 0
+ || cm->prev_mi == 0
|| cpi->common.show_frame == 0
|| cpi->common.frame_type == KEY_FRAME
|| cpi->is_src_frame_alt_ref) {
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -545,52 +545,49 @@
for (i = 0; i < MAX_MODES; ++i)
sf->thresh_mult[i] = mode == 0 ? -500 : 0;
- sf->thresh_mult[THR_ZEROMV ] = 0;
- sf->thresh_mult[THR_ZEROG ] = 0;
- sf->thresh_mult[THR_ZEROA ] = 0;
+ sf->thresh_mult[THR_ZEROMV] = 0;
+ sf->thresh_mult[THR_ZEROG] = 0;
+ sf->thresh_mult[THR_ZEROA] = 0;
sf->thresh_mult[THR_NEARESTMV] = 0;
- sf->thresh_mult[THR_NEARESTG ] = 0;
- sf->thresh_mult[THR_NEARESTA ] = 0;
+ sf->thresh_mult[THR_NEARESTG] = 0;
+ sf->thresh_mult[THR_NEARESTA] = 0;
- sf->thresh_mult[THR_NEARMV ] += speed_multiplier * 1000;
- sf->thresh_mult[THR_NEARG ] += speed_multiplier * 1000;
- sf->thresh_mult[THR_NEARA ] += speed_multiplier * 1000;
+ sf->thresh_mult[THR_NEARMV] += speed_multiplier * 1000;
+ sf->thresh_mult[THR_NEARG] += speed_multiplier * 1000;
+ sf->thresh_mult[THR_NEARA] += speed_multiplier * 1000;
- sf->thresh_mult[THR_DC ] += speed_multiplier * 1000;
- sf->thresh_mult[THR_TM ] += speed_multiplier * 1000;
- sf->thresh_mult[THR_V_PRED ] += speed_multiplier * 1500;
- sf->thresh_mult[THR_H_PRED ] += speed_multiplier * 1500;
- sf->thresh_mult[THR_D45_PRED ] += speed_multiplier * 2000;
+ sf->thresh_mult[THR_DC] += speed_multiplier * 1000;
+ sf->thresh_mult[THR_TM] += speed_multiplier * 1000;
+ sf->thresh_mult[THR_V_PRED] += speed_multiplier * 1500;
+ sf->thresh_mult[THR_H_PRED] += speed_multiplier * 1500;
+ sf->thresh_mult[THR_D45_PRED] += speed_multiplier * 2000;
sf->thresh_mult[THR_D135_PRED] += speed_multiplier * 2000;
sf->thresh_mult[THR_D117_PRED] += speed_multiplier * 2000;
sf->thresh_mult[THR_D153_PRED] += speed_multiplier * 2000;
- sf->thresh_mult[THR_D27_PRED ] += speed_multiplier * 2000;
- sf->thresh_mult[THR_D63_PRED ] += speed_multiplier * 2000;
+ sf->thresh_mult[THR_D27_PRED] += speed_multiplier * 2000;
+ sf->thresh_mult[THR_D63_PRED] += speed_multiplier * 2000;
- sf->thresh_mult[THR_NEWMV ] += new_motion_multiplier * 1000;
- sf->thresh_mult[THR_NEWG ] += new_motion_multiplier * 1000;
- sf->thresh_mult[THR_NEWA ] += new_motion_multiplier * 1000;
+ sf->thresh_mult[THR_NEWMV] += new_motion_multiplier * 1000;
+ sf->thresh_mult[THR_NEWG] += new_motion_multiplier * 1000;
+ sf->thresh_mult[THR_NEWA] += new_motion_multiplier * 1000;
- sf->thresh_mult[THR_COMP_ZEROLA ] += speed_multiplier * 1500;
- sf->thresh_mult[THR_COMP_ZEROGA ] += speed_multiplier * 1500;
+ sf->thresh_mult[THR_COMP_ZEROLA] += speed_multiplier * 1500;
+ sf->thresh_mult[THR_COMP_ZEROGA] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARESTLA] += speed_multiplier * 1500;
sf->thresh_mult[THR_COMP_NEARESTGA] += speed_multiplier * 1500;
- sf->thresh_mult[THR_COMP_NEARLA ] += speed_multiplier * 1500;
- sf->thresh_mult[THR_COMP_NEARGA ] += speed_multiplier * 1500;
+ sf->thresh_mult[THR_COMP_NEARLA] += speed_multiplier * 1500;
+ sf->thresh_mult[THR_COMP_NEARGA] += speed_multiplier * 1500;
- sf->thresh_mult[THR_COMP_NEWLA ] += new_motion_multiplier * 2000;
- sf->thresh_mult[THR_COMP_NEWGA ] += new_motion_multiplier * 2000;
+ sf->thresh_mult[THR_COMP_NEWLA] += new_motion_multiplier * 2000;
+ sf->thresh_mult[THR_COMP_NEWGA] += new_motion_multiplier * 2000;
- sf->thresh_mult[THR_B_PRED ] += speed_multiplier * 2500;
+ sf->thresh_mult[THR_B_PRED] += speed_multiplier * 2500;
- sf->thresh_mult[THR_SPLITMV ] += new_motion_multiplier * 2500;
- sf->thresh_mult[THR_SPLITG ] += new_motion_multiplier * 2500;
- sf->thresh_mult[THR_SPLITA ] += new_motion_multiplier * 2500;
- sf->thresh_mult[THR_COMP_SPLITLA ] += new_motion_multiplier * 4500;
- sf->thresh_mult[THR_COMP_SPLITGA ] += new_motion_multiplier * 4500;
+ sf->thresh_mult[THR_SPLITMV] += new_motion_multiplier * 2500;
+ sf->thresh_mult[THR_SPLITG] += new_motion_multiplier * 2500;
if (cpi->sf.skip_lots_of_modes) {
for (i = 0; i < MAX_MODES; ++i)
@@ -660,6 +657,7 @@
int mode = cpi->compressor_speed;
int speed = cpi->speed;
int i;
+
// Only modes 0 and 1 supported for now in experimental code basae
if (mode > 1)
mode = 1;
@@ -698,6 +696,7 @@
sf->use_8tap_always = 0;
sf->use_avoid_tested_higherror = 0;
sf->skip_lots_of_modes = 0;
+ sf->adjust_thresholds_by_speed = 0;
sf->partition_by_variance = 0;
sf->use_one_partition_size_always = 0;
sf->less_rectangular_check = 0;
@@ -705,6 +704,8 @@
sf->less_than_block_size = BLOCK_SIZE_MB16X16;
sf->use_partitions_greater_than = 0;
sf->greater_than_block_size = BLOCK_SIZE_SB8X8;
+ sf->adjust_partitioning_from_last_frame = 0;
+ sf->last_partitioning_redo_frequency = 4;
#if CONFIG_MULTIPLE_ARF
// Switch segmentation off.
@@ -737,9 +738,7 @@
cpi->common.show_frame == 0);
}
if (speed == 2) {
- sf->use_largest_txform = !(cpi->common.frame_type == KEY_FRAME ||
- cpi->common.intra_only ||
- cpi->common.show_frame == 0);
+ sf->use_largest_txform = 1;
sf->adjust_thresholds_by_speed = 1;
sf->less_rectangular_check = 1;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
@@ -746,30 +745,32 @@
sf->reduce_first_step_size = 1;
sf->optimize_coefficients = 0;
sf->use_lastframe_partitioning = 1;
+ sf->adjust_partitioning_from_last_frame = 1;
+ sf->last_partitioning_redo_frequency = 3;
}
if (speed == 3) {
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
sf->partition_by_variance = 1;
- sf->reduce_first_step_size = 1;
}
if (speed == 4) {
- sf->reduce_first_step_size = 1;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
sf->use_one_partition_size_always = 1;
sf->always_this_block_size = BLOCK_SIZE_MB16X16;
}
-/* if (speed == 2) {
- sf->reduce_first_step_size = 0;
+ /*
+ if (speed == 2) {
+ sf->first_step = 0;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_SB8X8;
sf->use_partitions_less_than = 1;
sf->less_than_block_size = BLOCK_SIZE_MB16X16;
}
if (speed == 3) {
- sf->reduce_first_step_size = 0;
+ sf->first_step = 0;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_SB8X8;
sf->use_partitions_greater_than = 1;
sf->greater_than_block_size = BLOCK_SIZE_SB8X8;
- }*/
+ }
+ */
break;
@@ -776,7 +777,10 @@
}; /* switch */
// Set rd thresholds based on mode and speed setting
- set_rd_speed_thresholds(cpi, mode, speed);
+ if (cpi->sf.adjust_thresholds_by_speed)
+ set_rd_speed_thresholds(cpi, mode, speed);
+ else
+ set_rd_speed_thresholds(cpi, mode, 0);
// Slow quant, dct and trellis not worthwhile for first pass
// so make sure they are always turned off.
@@ -3430,7 +3434,7 @@
vp9_second_pass(cpi);
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
- //vp9_print_modes_and_motion_vectors(&cpi->common, "encode.stt");
+ // vp9_print_modes_and_motion_vectors(&cpi->common, "encode.stt");
#ifdef DISABLE_RC_LONG_TERM_MEM
cpi->twopass.bits_left -= cpi->this_frame_target;
#else
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -233,6 +233,8 @@
BLOCK_SIZE_TYPE greater_than_block_size;
int use_partitions_less_than;
BLOCK_SIZE_TYPE less_than_block_size;
+ int adjust_partitioning_from_last_frame;
+ int last_partitioning_redo_frequency;
} SPEED_FEATURES;
enum BlockSize {
--
⑨