Index: source/libvpx/vp9/encoder/vp9_encodeframe.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_encodeframe.c (revision 271012) |
+++ source/libvpx/vp9/encoder/vp9_encodeframe.c (working copy) |
@@ -254,7 +254,6 @@ |
} |
static void set_block_size(VP9_COMP * const cpi, |
- const TileInfo *const tile, |
int mi_row, int mi_col, |
BLOCK_SIZE bsize) { |
if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) { |
@@ -377,11 +376,9 @@ |
static int set_vt_partitioning(VP9_COMP *cpi, |
void *data, |
- const TileInfo *const tile, |
BLOCK_SIZE bsize, |
int mi_row, |
- int mi_col, |
- int mi_size) { |
+ int mi_col) { |
VP9_COMMON * const cm = &cpi->common; |
variance_node vt; |
const int block_width = num_8x8_blocks_wide_lookup[bsize]; |
@@ -398,7 +395,7 @@ |
if (mi_col + block_width / 2 < cm->mi_cols && |
mi_row + block_height / 2 < cm->mi_rows && |
vt.part_variances->none.variance < threshold) { |
- set_block_size(cpi, tile, mi_row, mi_col, bsize); |
+ set_block_size(cpi, mi_row, mi_col, bsize); |
return 1; |
} |
@@ -407,8 +404,8 @@ |
vt.part_variances->vert[0].variance < threshold && |
vt.part_variances->vert[1].variance < threshold) { |
BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT); |
- set_block_size(cpi, tile, mi_row, mi_col, subsize); |
- set_block_size(cpi, tile, mi_row, mi_col + block_width / 2, subsize); |
+ set_block_size(cpi, mi_row, mi_col, subsize); |
+ set_block_size(cpi, mi_row, mi_col + block_width / 2, subsize); |
return 1; |
} |
@@ -417,8 +414,8 @@ |
vt.part_variances->horz[0].variance < threshold && |
vt.part_variances->horz[1].variance < threshold) { |
BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ); |
- set_block_size(cpi, tile, mi_row, mi_col, subsize); |
- set_block_size(cpi, tile, mi_row + block_height / 2, mi_col, subsize); |
+ set_block_size(cpi, mi_row, mi_col, subsize); |
+ set_block_size(cpi, mi_row + block_height / 2, mi_col, subsize); |
return 1; |
} |
return 0; |
@@ -505,13 +502,13 @@ |
// Now go through the entire structure, splitting every block size until |
// we get to one that's got a variance lower than our threshold, or we |
// hit 8x8. |
- if (!set_vt_partitioning(cpi, &vt, tile, BLOCK_64X64, |
- mi_row, mi_col, 8)) { |
+ if (!set_vt_partitioning(cpi, &vt, BLOCK_64X64, |
+ mi_row, mi_col)) { |
for (i = 0; i < 4; ++i) { |
const int x32_idx = ((i & 1) << 2); |
const int y32_idx = ((i >> 1) << 2); |
- if (!set_vt_partitioning(cpi, &vt.split[i], tile, BLOCK_32X32, |
- (mi_row + y32_idx), (mi_col + x32_idx), 4)) { |
+ if (!set_vt_partitioning(cpi, &vt.split[i], BLOCK_32X32, |
+ (mi_row + y32_idx), (mi_col + x32_idx))) { |
for (j = 0; j < 4; ++j) { |
const int x16_idx = ((j & 1) << 1); |
const int y16_idx = ((j >> 1) << 1); |
@@ -521,7 +518,7 @@ |
#ifdef DISABLE_8X8_VAR_BASED_PARTITION |
if (mi_row + y32_idx + y16_idx + 1 < cm->mi_rows && |
mi_row + x32_idx + x16_idx + 1 < cm->mi_cols) { |
- set_block_size(cpi, tile, |
+ set_block_size(cpi, |
(mi_row + y32_idx + y16_idx), |
(mi_col + x32_idx + x16_idx), |
BLOCK_16X16); |
@@ -529,7 +526,7 @@ |
for (k = 0; k < 4; ++k) { |
const int x8_idx = (k & 1); |
const int y8_idx = (k >> 1); |
- set_block_size(cpi, tile, |
+ set_block_size(cpi, |
(mi_row + y32_idx + y16_idx + y8_idx), |
(mi_col + x32_idx + x16_idx + x8_idx), |
BLOCK_8X8); |
@@ -543,7 +540,7 @@ |
for (k = 0; k < 4; ++k) { |
const int x8_idx = (k & 1); |
const int y8_idx = (k >> 1); |
- set_block_size(cpi, tile, |
+ set_block_size(cpi, |
(mi_row + y32_idx + y16_idx + y8_idx), |
(mi_col + x32_idx + x16_idx + x8_idx), |
BLOCK_8X8); |
@@ -1456,8 +1453,7 @@ |
MODE_INFO **mi_8x8, |
TOKENEXTRA **tp, int mi_row, int mi_col, |
BLOCK_SIZE bsize, int *rate, int64_t *dist, |
- int do_recon, PC_TREE *pc_tree, |
- int block) { |
+ int do_recon, PC_TREE *pc_tree) { |
VP9_COMMON *const cm = &cpi->common; |
MACROBLOCK *const x = &cpi->mb; |
MACROBLOCKD *const xd = &x->e_mbd; |
@@ -1624,7 +1620,7 @@ |
rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp, |
mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt, |
- i != 3, pc_tree->split[i], i); |
+ i != 3, pc_tree->split[i]); |
if (rt == INT_MAX || dt == INT64_MAX) { |
last_part_rate = INT_MAX; |
last_part_dist = INT64_MAX; |
@@ -1809,15 +1805,11 @@ |
BLOCK_SIZE *max_block_size) { |
VP9_COMMON *const cm = &cpi->common; |
MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
- MODE_INFO **mi_8x8 = xd->mi; |
- const int left_in_image = xd->left_available && mi_8x8[-1]; |
- const int above_in_image = xd->up_available && |
- mi_8x8[-xd->mi_stride]; |
- MODE_INFO **above_sb64_mi_8x8; |
- MODE_INFO **left_sb64_mi_8x8; |
- |
- int row8x8_remaining = tile->mi_row_end - mi_row; |
- int col8x8_remaining = tile->mi_col_end - mi_col; |
+ MODE_INFO **mi = xd->mi; |
+ const int left_in_image = xd->left_available && mi[-1]; |
+ const int above_in_image = xd->up_available && mi[-xd->mi_stride]; |
+ const int row8x8_remaining = tile->mi_row_end - mi_row; |
+ const int col8x8_remaining = tile->mi_col_end - mi_col; |
int bh, bw; |
BLOCK_SIZE min_size = BLOCK_4X4; |
BLOCK_SIZE max_size = BLOCK_64X64; |
@@ -1837,15 +1829,13 @@ |
} |
// Find the min and max partition sizes used in the left SB64 |
if (left_in_image) { |
- left_sb64_mi_8x8 = &mi_8x8[-MI_BLOCK_SIZE]; |
- get_sb_partition_size_range(cpi, left_sb64_mi_8x8, |
- &min_size, &max_size); |
+ MODE_INFO **left_sb64_mi = &mi[-MI_BLOCK_SIZE]; |
+ get_sb_partition_size_range(cpi, left_sb64_mi, &min_size, &max_size); |
} |
// Find the min and max partition sizes used in the above SB64. |
if (above_in_image) { |
- above_sb64_mi_8x8 = &mi_8x8[-xd->mi_stride * MI_BLOCK_SIZE]; |
- get_sb_partition_size_range(cpi, above_sb64_mi_8x8, |
- &min_size, &max_size); |
+ MODE_INFO **above_sb64_mi = &mi[-xd->mi_stride * MI_BLOCK_SIZE]; |
+ get_sb_partition_size_range(cpi, above_sb64_mi, &min_size, &max_size); |
} |
// adjust observed min and max |
if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) { |
@@ -1871,6 +1861,67 @@ |
*max_block_size = max_size; |
} |
+static void auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile, |
+ int mi_row, int mi_col, |
+ BLOCK_SIZE *min_block_size, |
+ BLOCK_SIZE *max_block_size) { |
+ VP9_COMMON *const cm = &cpi->common; |
+ MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
+ MODE_INFO **mi_8x8 = xd->mi; |
+ const int left_in_image = xd->left_available && mi_8x8[-1]; |
+ const int above_in_image = xd->up_available && |
+ mi_8x8[-xd->mi_stride]; |
+ int row8x8_remaining = tile->mi_row_end - mi_row; |
+ int col8x8_remaining = tile->mi_col_end - mi_col; |
+ int bh, bw; |
+ BLOCK_SIZE min_size = BLOCK_32X32; |
+ BLOCK_SIZE max_size = BLOCK_8X8; |
+ int bsl = mi_width_log2_lookup[BLOCK_64X64]; |
+ int search_range_ctrl = (((mi_row + mi_col) >> bsl) + |
+ cpi->sf.chessboard_index) & 0x01; |
+ // Trap case where we do not have a prediction. |
+ if (search_range_ctrl && |
+ (left_in_image || above_in_image || cm->frame_type != KEY_FRAME)) { |
+ int block; |
+ MODE_INFO **mi; |
+ BLOCK_SIZE sb_type; |
+ |
+ // Find the min and max partition sizes used in the left SB64. |
+ if (left_in_image) { |
+ MODE_INFO *cur_mi; |
+ mi = &mi_8x8[-1]; |
+ for (block = 0; block < MI_BLOCK_SIZE; ++block) { |
+ cur_mi = mi[block * xd->mi_stride]; |
+ sb_type = cur_mi ? cur_mi->mbmi.sb_type : 0; |
+ min_size = MIN(min_size, sb_type); |
+ max_size = MAX(max_size, sb_type); |
+ } |
+ } |
+ // Find the min and max partition sizes used in the above SB64. |
+ if (above_in_image) { |
+ mi = &mi_8x8[-xd->mi_stride * MI_BLOCK_SIZE]; |
+ for (block = 0; block < MI_BLOCK_SIZE; ++block) { |
+ sb_type = mi[block] ? mi[block]->mbmi.sb_type : 0; |
+ min_size = MIN(min_size, sb_type); |
+ max_size = MAX(max_size, sb_type); |
+ } |
+ } |
+ |
+ min_size = min_partition_size[min_size]; |
+ max_size = find_partition_size(max_size, row8x8_remaining, col8x8_remaining, |
+ &bh, &bw); |
+ min_size = MIN(min_size, max_size); |
+ min_size = MAX(min_size, BLOCK_8X8); |
+ max_size = MIN(max_size, BLOCK_32X32); |
+ } else { |
+ min_size = BLOCK_8X8; |
+ max_size = BLOCK_32X32; |
+ } |
+ |
+ *min_block_size = min_size; |
+ *max_block_size = max_size; |
+} |
+ |
static INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) { |
vpx_memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv)); |
} |
@@ -1886,7 +1937,7 @@ |
TOKENEXTRA **tp, int mi_row, |
int mi_col, BLOCK_SIZE bsize, int *rate, |
int64_t *dist, int do_recon, int64_t best_rd, |
- PC_TREE *pc_tree, int block) { |
+ PC_TREE *pc_tree) { |
VP9_COMMON *const cm = &cpi->common; |
MACROBLOCK *const x = &cpi->mb; |
MACROBLOCKD *const xd = &x->e_mbd; |
@@ -2038,7 +2089,7 @@ |
rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, |
subsize, &this_rate, &this_dist, i != 3, |
- best_rd - sum_rd, pc_tree->split[i], i); |
+ best_rd - sum_rd, pc_tree->split[i]); |
if (this_rate == INT_MAX) { |
sum_rd = INT64_MAX; |
@@ -2239,26 +2290,26 @@ |
sf->partition_search_type == VAR_BASED_PARTITION || |
sf->partition_search_type == VAR_BASED_FIXED_PARTITION) { |
const int idx_str = cm->mi_stride * mi_row + mi_col; |
- MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; |
- MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; |
+ MODE_INFO **mi = cm->mi_grid_visible + idx_str; |
+ MODE_INFO **prev_mi = cm->prev_mi_grid_visible + idx_str; |
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_8x8, mi_row, mi_col, |
+ set_fixed_partitioning(cpi, tile, mi, mi_row, mi_col, |
sf->always_this_block_size); |
- rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, x->pc_root, 0); |
+ rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
+ &dummy_rate, &dummy_dist, 1, x->pc_root); |
} else if (sf->partition_search_type == VAR_BASED_FIXED_PARTITION) { |
BLOCK_SIZE bsize; |
set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); |
bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col); |
- set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize); |
- rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, x->pc_root, 0); |
+ 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, x->pc_root); |
} else if (sf->partition_search_type == VAR_BASED_PARTITION) { |
choose_partitioning(cpi, tile, mi_row, mi_col); |
- rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, x->pc_root, 0); |
+ rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
+ &dummy_rate, &dummy_dist, 1, x->pc_root); |
} else { |
if ((cm->current_video_frame |
% sf->last_partitioning_redo_frequency) == 0 |
@@ -2268,7 +2319,7 @@ |
|| cpi->rc.is_src_frame_alt_ref |
|| ((sf->use_lastframe_partitioning == |
LAST_FRAME_PARTITION_LOW_MOTION) && |
- sb_has_motion(cm, prev_mi_8x8))) { |
+ sb_has_motion(cm, prev_mi))) { |
// 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); |
@@ -2277,17 +2328,16 @@ |
&sf->max_partition_size); |
} |
rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, INT64_MAX, x->pc_root, |
- 0); |
+ &dummy_rate, &dummy_dist, 1, INT64_MAX, x->pc_root); |
} else { |
if (sf->constrain_copy_partition && |
- sb_has_motion(cm, prev_mi_8x8)) |
- constrain_copy_partitioning(cpi, tile, mi_8x8, prev_mi_8x8, |
+ sb_has_motion(cm, prev_mi)) |
+ constrain_copy_partitioning(cpi, tile, mi, prev_mi, |
mi_row, mi_col, BLOCK_16X16); |
else |
- copy_partitioning(cm, mi_8x8, prev_mi_8x8); |
- rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, x->pc_root, 0); |
+ copy_partitioning(cm, mi, prev_mi); |
+ rd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
+ &dummy_rate, &dummy_dist, 1, x->pc_root); |
} |
} |
} else { |
@@ -2299,7 +2349,7 @@ |
&sf->max_partition_size); |
} |
rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1, INT64_MAX, x->pc_root, 0); |
+ &dummy_rate, &dummy_dist, 1, INT64_MAX, x->pc_root); |
} |
} |
} |
@@ -2623,9 +2673,7 @@ |
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]); |
@@ -2768,7 +2816,7 @@ |
static void nonrd_use_partition(VP9_COMP *cpi, |
const TileInfo *const tile, |
- MODE_INFO **mi_8x8, |
+ MODE_INFO **mi, |
TOKENEXTRA **tp, |
int mi_row, int mi_col, |
BLOCK_SIZE bsize, int output_enabled, |
@@ -2787,7 +2835,7 @@ |
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
return; |
- subsize = (bsize >= BLOCK_8X8) ? mi_8x8[0]->mbmi.sb_type : BLOCK_4X4; |
+ subsize = (bsize >= BLOCK_8X8) ? mi[0]->mbmi.sb_type : BLOCK_4X4; |
partition = partition_lookup[bsl][subsize]; |
switch (partition) { |
@@ -2815,7 +2863,7 @@ |
if (mi_row + hbs < cm->mi_rows) { |
nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col, |
&rate, &dist, subsize); |
- pc_tree->horizontal[1].mic.mbmi = mi_8x8[0]->mbmi; |
+ pc_tree->horizontal[1].mic.mbmi = mi[0]->mbmi; |
if (rate != INT_MAX && dist != INT64_MAX && |
*totrate != INT_MAX && *totdist != INT64_MAX) { |
*totrate += rate; |
@@ -2825,10 +2873,10 @@ |
break; |
case PARTITION_SPLIT: |
subsize = get_subsize(bsize, PARTITION_SPLIT); |
- nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, |
+ nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, |
subsize, output_enabled, totrate, totdist, |
pc_tree->split[0]); |
- nonrd_use_partition(cpi, tile, mi_8x8 + hbs, tp, |
+ nonrd_use_partition(cpi, tile, mi + hbs, tp, |
mi_row, mi_col + hbs, subsize, output_enabled, |
&rate, &dist, pc_tree->split[1]); |
if (rate != INT_MAX && dist != INT64_MAX && |
@@ -2836,7 +2884,7 @@ |
*totrate += rate; |
*totdist += dist; |
} |
- nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis, tp, |
+ nonrd_use_partition(cpi, tile, 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 && |
@@ -2844,7 +2892,7 @@ |
*totrate += rate; |
*totdist += dist; |
} |
- nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis + hbs, tp, |
+ nonrd_use_partition(cpi, tile, 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 && |
@@ -2883,8 +2931,8 @@ |
int dummy_rate = 0; |
int64_t dummy_dist = 0; |
const int idx_str = cm->mi_stride * mi_row + mi_col; |
- MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; |
- MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; |
+ MODE_INFO **mi = cm->mi_grid_visible + idx_str; |
+ MODE_INFO **prev_mi = cm->prev_mi_grid_visible + idx_str; |
BLOCK_SIZE bsize; |
x->in_static_area = 0; |
@@ -2895,12 +2943,12 @@ |
switch (cpi->sf.partition_search_type) { |
case VAR_BASED_PARTITION: |
choose_partitioning(cpi, tile, mi_row, mi_col); |
- nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
+ nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64, |
1, &dummy_rate, &dummy_dist, x->pc_root); |
break; |
case SOURCE_VAR_BASED_PARTITION: |
- set_source_var_based_partition(cpi, tile, mi_8x8, mi_row, mi_col); |
- nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
+ 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, x->pc_root); |
break; |
case VAR_BASED_FIXED_PARTITION: |
@@ -2908,19 +2956,23 @@ |
bsize = cpi->sf.partition_search_type == FIXED_PARTITION ? |
cpi->sf.always_this_block_size : |
get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col); |
- set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize); |
- nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
+ 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, x->pc_root); |
break; |
case REFERENCE_PARTITION: |
if (cpi->sf.partition_check || |
!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, |
+ &cpi->sf.min_partition_size, |
+ &cpi->sf.max_partition_size); |
nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
&dummy_rate, &dummy_dist, 1, INT64_MAX, |
x->pc_root); |
} else { |
- copy_partitioning(cm, mi_8x8, prev_mi_8x8); |
- nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, |
+ copy_partitioning(cm, mi, prev_mi); |
+ nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, |
BLOCK_64X64, 1, &dummy_rate, &dummy_dist, |
x->pc_root); |
} |