aboutsummaryrefslogtreecommitdiff
path: root/libvpx/vp9/encoder/vp9_encodeframe.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvpx/vp9/encoder/vp9_encodeframe.c')
-rw-r--r--libvpx/vp9/encoder/vp9_encodeframe.c413
1 files changed, 231 insertions, 182 deletions
diff --git a/libvpx/vp9/encoder/vp9_encodeframe.c b/libvpx/vp9/encoder/vp9_encodeframe.c
index 798adc1f3..66eae41da 100644
--- a/libvpx/vp9/encoder/vp9_encodeframe.c
+++ b/libvpx/vp9/encoder/vp9_encodeframe.c
@@ -60,11 +60,28 @@ static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x);
* Eventually this should be replaced by custom no-reference routines,
* which will be faster.
*/
-static const uint8_t VP9_VAR_OFFS[16] = {128, 128, 128, 128, 128, 128, 128, 128,
- 128, 128, 128, 128, 128, 128, 128, 128};
+static const uint8_t VP9_VAR_OFFS[64] = {
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128
+};
+
+static unsigned int get_sb_variance(VP9_COMP *cpi, MACROBLOCK *x,
+ BLOCK_SIZE_TYPE bs) {
+ unsigned int var, sse;
+ var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf,
+ x->plane[0].src.stride,
+ VP9_VAR_OFFS, 0, &sse);
+ return var >> num_pels_log2_lookup[bs];
+}
// Original activity measure from Tim T's code.
-static unsigned int tt_activity_measure(VP9_COMP *cpi, MACROBLOCK *x) {
+static unsigned int tt_activity_measure(MACROBLOCK *x) {
unsigned int act;
unsigned int sse;
/* TODO: This could also be done over smaller areas (8x8), but that would
@@ -106,7 +123,7 @@ static unsigned int mb_activity_measure(VP9_COMP *cpi, MACROBLOCK *x,
mb_activity = alt_activity_measure(cpi, x, use_dc_pred);
} else {
// Original activity measure from Tim T's code.
- mb_activity = tt_activity_measure(cpi, x);
+ mb_activity = tt_activity_measure(x);
}
if (mb_activity < VP9_ACTIVITY_AVG_MIN)
@@ -323,8 +340,8 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
int mb_mode_index = ctx->best_mode_index;
const int mis = cpi->common.mode_info_stride;
- const int mi_height = num_8x8_blocks_high_lookup[bsize];
const int mi_width = num_8x8_blocks_wide_lookup[bsize];
+ const int mi_height = num_8x8_blocks_high_lookup[bsize];
assert(mi->mbmi.mode < MB_MODE_COUNT);
assert(mb_mode_index < MAX_MODES);
@@ -345,13 +362,13 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
}
// FIXME(rbultje) I'm pretty sure this should go to the end of this block
// (i.e. after the output_enabled)
- if (bsize < BLOCK_SIZE_SB32X32) {
- if (bsize < BLOCK_SIZE_MB16X16)
- ctx->txfm_rd_diff[ALLOW_16X16] = ctx->txfm_rd_diff[ALLOW_8X8];
- ctx->txfm_rd_diff[ALLOW_32X32] = ctx->txfm_rd_diff[ALLOW_16X16];
+ if (bsize < BLOCK_32X32) {
+ if (bsize < BLOCK_16X16)
+ ctx->tx_rd_diff[ALLOW_16X16] = ctx->tx_rd_diff[ALLOW_8X8];
+ ctx->tx_rd_diff[ALLOW_32X32] = ctx->tx_rd_diff[ALLOW_16X16];
}
- if (mbmi->ref_frame[0] != INTRA_FRAME && mbmi->sb_type < BLOCK_SIZE_SB8X8) {
+ if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) {
*x->partition_info = ctx->partition_info;
mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
@@ -362,9 +379,8 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
return;
if (!vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
- for (i = 0; i < NB_TXFM_MODES; i++) {
- cpi->rd_tx_select_diff[i] += ctx->txfm_rd_diff[i];
- }
+ for (i = 0; i < TX_MODES; i++)
+ cpi->rd_tx_select_diff[i] += ctx->tx_rd_diff[i];
}
if (cpi->common.frame_type == KEY_FRAME) {
@@ -395,7 +411,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
} else {
// Note how often each mode chosen as best
cpi->mode_chosen_counts[mb_mode_index]++;
- if (mbmi->ref_frame[0] != INTRA_FRAME
+ if (is_inter_block(mbmi)
&& (mbmi->sb_type < BLOCK_SIZE_SB8X8 || mbmi->mode == NEWMV)) {
int_mv best_mv, best_second_mv;
const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0];
@@ -465,6 +481,7 @@ static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col,
const int mb_row = mi_row >> 1;
const int mb_col = mi_col >> 1;
const int idx_map = mb_row * cm->mb_cols + mb_col;
+ const struct segmentation *const seg = &xd->seg;
int i;
// entropy context structures
@@ -514,16 +531,16 @@ static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col,
x->rdmult = cpi->RDMULT;
/* segment ID */
- if (xd->seg.enabled) {
- uint8_t *map = xd->seg.update_map ? cpi->segmentation_map
- : cm->last_frame_seg_map;
+ if (seg->enabled) {
+ uint8_t *map = seg->update_map ? cpi->segmentation_map
+ : cm->last_frame_seg_map;
mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
vp9_mb_init_quantizer(cpi, x);
- if (xd->seg.enabled && cpi->seg0_cnt > 0
- && !vp9_segfeature_active(&xd->seg, 0, SEG_LVL_REF_FRAME)
- && vp9_segfeature_active(&xd->seg, 1, SEG_LVL_REF_FRAME)) {
+ if (seg->enabled && cpi->seg0_cnt > 0
+ && !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME)
+ && vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) {
cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
} else {
const int y = mb_row & ~3;
@@ -537,8 +554,11 @@ static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col,
cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress)
<< 16) / cm->MBs;
}
+
+ x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
} else {
mbmi->segment_id = 0;
+ x->encode_breakout = cpi->oxcf.encode_breakout;
}
}
@@ -552,12 +572,17 @@ static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
x->rd_search = 1;
- if (bsize < BLOCK_SIZE_SB8X8)
+ if (bsize < BLOCK_SIZE_SB8X8) {
+ // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
+ // there is nothing to be done.
if (xd->ab_index != 0)
return;
+ }
set_offsets(cpi, mi_row, mi_col, bsize);
xd->mode_info_context->mbmi.sb_type = bsize;
+
+ x->source_variance = get_sb_variance(cpi, x, bsize);
if (cpi->oxcf.tuning == VP8_TUNE_SSIM)
vp9_activity_masking(cpi, x);
@@ -571,12 +596,12 @@ static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
bsize, ctx, best_rd);
}
-static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) {
- VP9_COMMON * const cm = &cpi->common;
- MACROBLOCK * const x = &cpi->mb;
- MACROBLOCKD * const xd = &x->e_mbd;
+static void update_stats(VP9_COMP *cpi) {
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCK *const x = &cpi->mb;
+ MACROBLOCKD *const xd = &x->e_mbd;
MODE_INFO *mi = xd->mode_info_context;
- MB_MODE_INFO * const mbmi = &mi->mbmi;
+ MB_MODE_INFO *const mbmi = &mi->mbmi;
if (cm->frame_type != KEY_FRAME) {
const int seg_ref_active = vp9_segfeature_active(&xd->seg, mbmi->segment_id,
@@ -612,38 +637,38 @@ static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) {
}
// TODO(jingning): the variables used here are little complicated. need further
-// refactoring on organizing the the temporary buffers, when recursive
+// refactoring on organizing the temporary buffers, when recursive
// partition down to 4x4 block size is enabled.
static PICK_MODE_CONTEXT *get_block_context(MACROBLOCK *x,
BLOCK_SIZE_TYPE bsize) {
MACROBLOCKD * const xd = &x->e_mbd;
switch (bsize) {
- case BLOCK_SIZE_SB64X64:
+ case BLOCK_64X64:
return &x->sb64_context;
- case BLOCK_SIZE_SB64X32:
+ case BLOCK_64X32:
return &x->sb64x32_context[xd->sb_index];
- case BLOCK_SIZE_SB32X64:
+ case BLOCK_32X64:
return &x->sb32x64_context[xd->sb_index];
- case BLOCK_SIZE_SB32X32:
+ case BLOCK_32X32:
return &x->sb32_context[xd->sb_index];
- case BLOCK_SIZE_SB32X16:
+ case BLOCK_32X16:
return &x->sb32x16_context[xd->sb_index][xd->mb_index];
- case BLOCK_SIZE_SB16X32:
+ case BLOCK_16X32:
return &x->sb16x32_context[xd->sb_index][xd->mb_index];
- case BLOCK_SIZE_MB16X16:
+ case BLOCK_16X16:
return &x->mb_context[xd->sb_index][xd->mb_index];
- case BLOCK_SIZE_SB16X8:
+ case BLOCK_16X8:
return &x->sb16x8_context[xd->sb_index][xd->mb_index][xd->b_index];
- case BLOCK_SIZE_SB8X16:
+ case BLOCK_8X16:
return &x->sb8x16_context[xd->sb_index][xd->mb_index][xd->b_index];
- case BLOCK_SIZE_SB8X8:
+ case BLOCK_8X8:
return &x->sb8x8_context[xd->sb_index][xd->mb_index][xd->b_index];
- case BLOCK_SIZE_SB8X4:
+ case BLOCK_8X4:
return &x->sb8x4_context[xd->sb_index][xd->mb_index][xd->b_index];
- case BLOCK_SIZE_SB4X8:
+ case BLOCK_4X8:
return &x->sb4x8_context[xd->sb_index][xd->mb_index][xd->b_index];
- case BLOCK_SIZE_AB4X4:
+ case BLOCK_4X4:
return &x->ab4x4_context[xd->sb_index][xd->mb_index][xd->b_index];
default:
assert(0);
@@ -655,13 +680,13 @@ static BLOCK_SIZE_TYPE *get_sb_partitioning(MACROBLOCK *x,
BLOCK_SIZE_TYPE bsize) {
MACROBLOCKD *xd = &x->e_mbd;
switch (bsize) {
- case BLOCK_SIZE_SB64X64:
+ case BLOCK_64X64:
return &x->sb64_partitioning;
- case BLOCK_SIZE_SB32X32:
+ case BLOCK_32X32:
return &x->sb_partitioning[xd->sb_index];
- case BLOCK_SIZE_MB16X16:
+ case BLOCK_16X16:
return &x->mb_partitioning[xd->sb_index][xd->mb_index];
- case BLOCK_SIZE_SB8X8:
+ case BLOCK_8X8:
return &x->b_partitioning[xd->sb_index][xd->mb_index][xd->b_index];
default:
assert(0);
@@ -674,12 +699,12 @@ static void restore_context(VP9_COMP *cpi, int mi_row, int mi_col,
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
BLOCK_SIZE_TYPE bsize) {
- VP9_COMMON * const cm = &cpi->common;
- MACROBLOCK * const x = &cpi->mb;
- MACROBLOCKD * const xd = &x->e_mbd;
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCK *const x = &cpi->mb;
+ MACROBLOCKD *const xd = &x->e_mbd;
int p;
- int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
- int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
+ const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
+ const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
int mi_width = num_8x8_blocks_wide_lookup[bsize];
int mi_height = num_8x8_blocks_high_lookup[bsize];
for (p = 0; p < MAX_MB_PLANE; p++) {
@@ -705,12 +730,12 @@ static void save_context(VP9_COMP *cpi, int mi_row, int mi_col,
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE],
PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8],
BLOCK_SIZE_TYPE bsize) {
- VP9_COMMON * const cm = &cpi->common;
- MACROBLOCK * const x = &cpi->mb;
- MACROBLOCKD * const xd = &x->e_mbd;
+ const VP9_COMMON *const cm = &cpi->common;
+ const MACROBLOCK *const x = &cpi->mb;
+ const MACROBLOCKD *const xd = &x->e_mbd;
int p;
- int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
- int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
+ const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
+ const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
int mi_width = num_8x8_blocks_wide_lookup[bsize];
int mi_height = num_8x8_blocks_high_lookup[bsize];
@@ -746,15 +771,18 @@ static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col,
if (sub_index != -1)
*(get_sb_index(xd, bsize)) = sub_index;
- if (bsize < BLOCK_SIZE_SB8X8)
+ if (bsize < BLOCK_SIZE_SB8X8) {
+ // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
+ // there is nothing to be done.
if (xd->ab_index > 0)
return;
+ }
set_offsets(cpi, mi_row, mi_col, bsize);
update_state(cpi, get_block_context(x, bsize), bsize, output_enabled);
encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize);
if (output_enabled) {
- update_stats(cpi, mi_row, mi_col);
+ update_stats(cpi);
(*tp)->token = EOSB_TOKEN;
(*tp)++;
@@ -776,7 +804,7 @@ static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col,
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
- c1 = BLOCK_SIZE_AB4X4;
+ c1 = BLOCK_4X4;
if (bsize >= BLOCK_SIZE_SB8X8) {
set_partition_seg_context(cm, xd, mi_row, mi_col);
pl = partition_plane_context(xd, bsize);
@@ -858,7 +886,7 @@ static void set_block_size(VP9_COMMON * const cm, MODE_INFO *m,
int bhl = b_height_log2(bsize);
int bsl = (bwl > bhl ? bwl : bhl);
- int bs = (1 << bsl) / 2; //
+ int bs = (1 << bsl) / 2; // Block size in units of 8 pels.
MODE_INFO *m2 = m + mi_row * mis + mi_col;
for (row = 0; row < bs; row++) {
for (col = 0; col < bs; col++) {
@@ -906,28 +934,28 @@ typedef enum {
static void tree_to_node(void *data, BLOCK_SIZE_TYPE block_size, vt_node *node) {
int i;
switch (block_size) {
- case BLOCK_SIZE_SB64X64: {
+ case BLOCK_64X64: {
v64x64 *vt = (v64x64 *) data;
node->vt = &vt->vt;
for (i = 0; i < 4; i++)
node->split[i] = &vt->split[i].vt.none;
break;
}
- case BLOCK_SIZE_SB32X32: {
+ case BLOCK_32X32: {
v32x32 *vt = (v32x32 *) data;
node->vt = &vt->vt;
for (i = 0; i < 4; i++)
node->split[i] = &vt->split[i].vt.none;
break;
}
- case BLOCK_SIZE_MB16X16: {
+ case BLOCK_16X16: {
v16x16 *vt = (v16x16 *) data;
node->vt = &vt->vt;
for (i = 0; i < 4; i++)
node->split[i] = &vt->split[i].vt.none;
break;
}
- case BLOCK_SIZE_SB8X8: {
+ case BLOCK_8X8: {
v8x8 *vt = (v8x8 *) data;
node->vt = &vt->vt;
for (i = 0; i < 4; i++)
@@ -1066,8 +1094,7 @@ static void choose_partitioning(VP9_COMP *cpi, MODE_INFO *m, int mi_row,
int dp;
int pixels_wide = 64, pixels_high = 64;
- vpx_memset(&vt, 0, sizeof(vt));
-
+ vp9_zero(vt);
set_offsets(cpi, mi_row, mi_col, BLOCK_SIZE_SB64X64);
if (xd->mb_to_right_edge < 0)
@@ -1087,7 +1114,8 @@ static void choose_partitioning(VP9_COMP *cpi, MODE_INFO *m, int mi_row,
dp = 64;
if (cm->frame_type != KEY_FRAME) {
int_mv nearest_mv, near_mv;
- YV12_BUFFER_CONFIG *ref_fb = &cm->yv12_fb[0];
+ const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, LAST_FRAME)];
+ YV12_BUFFER_CONFIG *ref_fb = &cm->yv12_fb[idx];
YV12_BUFFER_CONFIG *second_ref_fb = NULL;
setup_pre_planes(xd, 0, ref_fb, mi_row, mi_col,
@@ -1103,7 +1131,6 @@ static void choose_partitioning(VP9_COMP *cpi, MODE_INFO *m, int mi_row,
vp9_build_inter_predictors_sby(xd, mi_row, mi_col, BLOCK_SIZE_SB64X64);
d = xd->plane[0].dst.buf;
dp = xd->plane[0].dst.stride;
-
}
// Fill in the entire tree of 8x8 variances for splits.
@@ -1130,32 +1157,32 @@ static void choose_partitioning(VP9_COMP *cpi, MODE_INFO *m, int mi_row,
// values.
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
- fill_variance_tree(&vt.split[i].split[j], BLOCK_SIZE_MB16X16);
+ fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16);
}
- fill_variance_tree(&vt.split[i], BLOCK_SIZE_SB32X32);
+ fill_variance_tree(&vt.split[i], BLOCK_32X32);
}
- fill_variance_tree(&vt, BLOCK_SIZE_SB64X64);
+ fill_variance_tree(&vt, BLOCK_64X64);
// 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, m, BLOCK_SIZE_SB64X64, mi_row, mi_col,
+ if (!set_vt_partitioning(cpi, &vt, m, BLOCK_64X64, mi_row, mi_col,
4)) {
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], m, BLOCK_SIZE_SB32X32,
+ if (!set_vt_partitioning(cpi, &vt.split[i], m, BLOCK_32X32,
(mi_row + y32_idx), (mi_col + x32_idx), 2)) {
for (j = 0; j < 4; ++j) {
const int x16_idx = ((j & 1) << 1);
const int y16_idx = ((j >> 1) << 1);
if (!set_vt_partitioning(cpi, &vt.split[i].split[j], m,
- BLOCK_SIZE_MB16X16,
+ BLOCK_16X16,
(mi_row + y32_idx + y16_idx),
(mi_col + x32_idx + x16_idx), 1)) {
for (k = 0; k < 4; ++k) {
const int x8_idx = (k & 1);
const int y8_idx = (k >> 1);
- set_block_size(cm, m, BLOCK_SIZE_SB8X8, mis,
+ set_block_size(cm, m, BLOCK_8X8, mis,
(mi_row + y32_idx + y16_idx + y8_idx),
(mi_col + x32_idx + x16_idx + x8_idx));
}
@@ -1165,6 +1192,7 @@ static void choose_partitioning(VP9_COMP *cpi, MODE_INFO *m, int mi_row,
}
}
}
+
static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
int mi_row, int mi_col, BLOCK_SIZE_TYPE bsize,
int *rate, int64_t *dist, int do_recon) {
@@ -1173,8 +1201,8 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
MACROBLOCKD *xd = &cpi->mb.e_mbd;
const int mis = cm->mode_info_stride;
int bsl = b_width_log2(bsize);
- int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
- int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
+ const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
+ const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
int ms = num_4x4_blocks_wide / 2;
int mh = num_4x4_blocks_high / 2;
int bss = (1 << bsl) / 4;
@@ -1191,7 +1219,7 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
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;
+ BLOCK_SIZE_TYPE sub_subsize = BLOCK_4X4;
int splits_below = 0;
BLOCK_SIZE_TYPE bs_type = m->mbmi.sb_type;
@@ -1203,6 +1231,8 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
subsize = get_subsize(bsize, partition);
if (bsize < BLOCK_SIZE_SB8X8) {
+ // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
+ // there is nothing to be done.
if (xd->ab_index != 0) {
*rate = 0;
*dist = 0;
@@ -1213,6 +1243,10 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
}
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
+ x->fast_ms = 0;
+ x->pred_mv.as_int = 0;
+ x->subblock_ref = 0;
+
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) {
@@ -1422,9 +1456,59 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
*dist = chosen_dist;
}
+static BLOCK_SIZE_TYPE min_partition_size[BLOCK_SIZE_TYPES] =
+ { BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
+ BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, BLOCK_8X8,
+ BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 };
+static BLOCK_SIZE_TYPE max_partition_size[BLOCK_SIZE_TYPES] =
+ { BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
+ BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, BLOCK_64X64,
+ BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, BLOCK_64X64 };
+
+
+// Look at neighboring blocks and set a min and max partition size based on
+// what they chose.
+static void rd_auto_partition_range(VP9_COMP *cpi,
+ BLOCK_SIZE_TYPE * min_block_size,
+ BLOCK_SIZE_TYPE * max_block_size) {
+ MACROBLOCKD *const xd = &cpi->mb.e_mbd;
+ const MODE_INFO *const mi = xd->mode_info_context;
+ const MB_MODE_INFO *const above_mbmi = &mi[-xd->mode_info_stride].mbmi;
+ const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi;
+ const int left_in_image = xd->left_available && left_mbmi->mb_in_image;
+ const int above_in_image = xd->up_available && above_mbmi->mb_in_image;
+
+ // Frequency check
+ if (cpi->sf.auto_min_max_partition_count <= 0) {
+ cpi->sf.auto_min_max_partition_count =
+ cpi->sf.auto_min_max_partition_interval;
+ *min_block_size = BLOCK_4X4;
+ *max_block_size = BLOCK_64X64;
+ return;
+ } else {
+ --cpi->sf.auto_min_max_partition_count;
+ }
+
+ // Check for edge cases
+ if (!left_in_image && !above_in_image) {
+ *min_block_size = BLOCK_4X4;
+ *max_block_size = BLOCK_64X64;
+ } else if (!left_in_image) {
+ *min_block_size = min_partition_size[above_mbmi->sb_type];
+ *max_block_size = max_partition_size[above_mbmi->sb_type];
+ } else if (!above_in_image) {
+ *min_block_size = min_partition_size[left_mbmi->sb_type];
+ *max_block_size = max_partition_size[left_mbmi->sb_type];
+ } else {
+ *min_block_size =
+ min_partition_size[MIN(left_mbmi->sb_type, above_mbmi->sb_type)];
+ *max_block_size =
+ max_partition_size[MAX(left_mbmi->sb_type, above_mbmi->sb_type)];
+ }
+}
// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
-// unlikely to be selected depending on previously rate-distortion optimization
+// unlikely to be selected depending on previous rate-distortion optimization
// results, for encoding speed-up.
static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
int mi_col, BLOCK_SIZE_TYPE bsize, int *rate,
@@ -1444,20 +1528,22 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
(void) *tp_orig;
- if (bsize < BLOCK_SIZE_SB8X8)
+ if (bsize < BLOCK_SIZE_SB8X8) {
+ // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
+ // there is nothing to be done.
if (xd->ab_index != 0) {
*rate = 0;
*dist = 0;
return;
}
+ }
assert(mi_height_log2(bsize) == mi_width_log2(bsize));
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
// PARTITION_SPLIT
- if (!cpi->sf.use_partitions_greater_than
- || (cpi->sf.use_partitions_greater_than
- && bsize > cpi->sf.greater_than_block_size)) {
+ if (!cpi->sf.auto_min_max_partition_size ||
+ bsize >= cpi->sf.min_partition_size) {
if (bsize > BLOCK_SIZE_SB8X8) {
int r4 = 0;
int64_t d4 = 0, sum_rd = 0;
@@ -1500,41 +1586,39 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
}
}
+ // Use 4 subblocks' motion estimation results to speed up current
+ // partition's checking.
x->fast_ms = 0;
x->pred_mv.as_int = 0;
x->subblock_ref = 0;
- // Use 4 subblocks' motion estimation results to speed up current
- // partition's checking.
- if (cpi->sf.using_small_partition_info) {
+ if (cpi->sf.using_small_partition_info &&
+ (!cpi->sf.auto_min_max_partition_size ||
+ (bsize <= cpi->sf.max_partition_size &&
+ bsize >= cpi->sf.min_partition_size))) {
// Only use 8x8 result for non HD videos.
// int use_8x8 = (MIN(cpi->common.width, cpi->common.height) < 720) ? 1 : 0;
int use_8x8 = 1;
if (cm->frame_type && !cpi->is_src_frame_alt_ref &&
- ((use_8x8 && bsize == BLOCK_SIZE_MB16X16) ||
- bsize == BLOCK_SIZE_SB32X32 || bsize == BLOCK_SIZE_SB64X64)) {
+ ((use_8x8 && bsize == BLOCK_16X16) ||
+ bsize == BLOCK_32X32 || bsize == BLOCK_64X64)) {
int ref0 = 0, ref1 = 0, ref2 = 0, ref3 = 0;
+ PICK_MODE_CONTEXT *block_context = NULL;
- if (bsize == BLOCK_SIZE_MB16X16) {
- ref0 = x->sb8x8_context[xd->sb_index][xd->mb_index][0].mic.mbmi.
- ref_frame[0];
- ref1 = x->sb8x8_context[xd->sb_index][xd->mb_index][1].mic.mbmi.
- ref_frame[0];
- ref2 = x->sb8x8_context[xd->sb_index][xd->mb_index][2].mic.mbmi.
- ref_frame[0];
- ref3 = x->sb8x8_context[xd->sb_index][xd->mb_index][3].mic.mbmi.
- ref_frame[0];
- } else if (bsize == BLOCK_SIZE_SB32X32) {
- ref0 = x->mb_context[xd->sb_index][0].mic.mbmi.ref_frame[0];
- ref1 = x->mb_context[xd->sb_index][1].mic.mbmi.ref_frame[0];
- ref2 = x->mb_context[xd->sb_index][2].mic.mbmi.ref_frame[0];
- ref3 = x->mb_context[xd->sb_index][3].mic.mbmi.ref_frame[0];
+ if (bsize == BLOCK_16X16) {
+ block_context = x->sb8x8_context[xd->sb_index][xd->mb_index];
+ } else if (bsize == BLOCK_32X32) {
+ block_context = x->mb_context[xd->sb_index];
} else if (bsize == BLOCK_SIZE_SB64X64) {
- ref0 = x->sb32_context[0].mic.mbmi.ref_frame[0];
- ref1 = x->sb32_context[1].mic.mbmi.ref_frame[0];
- ref2 = x->sb32_context[2].mic.mbmi.ref_frame[0];
- ref3 = x->sb32_context[3].mic.mbmi.ref_frame[0];
+ block_context = x->sb32_context;
+ }
+
+ if (block_context) {
+ ref0 = block_context[0].mic.mbmi.ref_frame[0];
+ ref1 = block_context[1].mic.mbmi.ref_frame[0];
+ ref2 = block_context[2].mic.mbmi.ref_frame[0];
+ ref3 = block_context[3].mic.mbmi.ref_frame[0];
}
// Currently, only consider 4 inter ref frames.
@@ -1544,42 +1628,14 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
int d01, d23, d02, d13; // motion vector distance between 2 blocks
// Get each subblock's motion vectors.
- if (bsize == BLOCK_SIZE_MB16X16) {
- mvr0 = x->sb8x8_context[xd->sb_index][xd->mb_index][0].mic.mbmi.mv[0].
- as_mv.row;
- mvc0 = x->sb8x8_context[xd->sb_index][xd->mb_index][0].mic.mbmi.mv[0].
- as_mv.col;
- mvr1 = x->sb8x8_context[xd->sb_index][xd->mb_index][1].mic.mbmi.mv[0].
- as_mv.row;
- mvc1 = x->sb8x8_context[xd->sb_index][xd->mb_index][1].mic.mbmi.mv[0].
- as_mv.col;
- mvr2 = x->sb8x8_context[xd->sb_index][xd->mb_index][2].mic.mbmi.mv[0].
- as_mv.row;
- mvc2 = x->sb8x8_context[xd->sb_index][xd->mb_index][2].mic.mbmi.mv[0].
- as_mv.col;
- mvr3 = x->sb8x8_context[xd->sb_index][xd->mb_index][3].mic.mbmi.mv[0].
- as_mv.row;
- mvc3 = x->sb8x8_context[xd->sb_index][xd->mb_index][3].mic.mbmi.mv[0].
- as_mv.col;
- } else if (bsize == BLOCK_SIZE_SB32X32) {
- mvr0 = x->mb_context[xd->sb_index][0].mic.mbmi.mv[0].as_mv.row;
- mvc0 = x->mb_context[xd->sb_index][0].mic.mbmi.mv[0].as_mv.col;
- mvr1 = x->mb_context[xd->sb_index][1].mic.mbmi.mv[0].as_mv.row;
- mvc1 = x->mb_context[xd->sb_index][1].mic.mbmi.mv[0].as_mv.col;
- mvr2 = x->mb_context[xd->sb_index][2].mic.mbmi.mv[0].as_mv.row;
- mvc2 = x->mb_context[xd->sb_index][2].mic.mbmi.mv[0].as_mv.col;
- mvr3 = x->mb_context[xd->sb_index][3].mic.mbmi.mv[0].as_mv.row;
- mvc3 = x->mb_context[xd->sb_index][3].mic.mbmi.mv[0].as_mv.col;
- } else if (bsize == BLOCK_SIZE_SB64X64) {
- mvr0 = x->sb32_context[0].mic.mbmi.mv[0].as_mv.row;
- mvc0 = x->sb32_context[0].mic.mbmi.mv[0].as_mv.col;
- mvr1 = x->sb32_context[1].mic.mbmi.mv[0].as_mv.row;
- mvc1 = x->sb32_context[1].mic.mbmi.mv[0].as_mv.col;
- mvr2 = x->sb32_context[2].mic.mbmi.mv[0].as_mv.row;
- mvc2 = x->sb32_context[2].mic.mbmi.mv[0].as_mv.col;
- mvr3 = x->sb32_context[3].mic.mbmi.mv[0].as_mv.row;
- mvc3 = x->sb32_context[3].mic.mbmi.mv[0].as_mv.col;
- }
+ mvr0 = block_context[0].mic.mbmi.mv[0].as_mv.row;
+ mvc0 = block_context[0].mic.mbmi.mv[0].as_mv.col;
+ mvr1 = block_context[1].mic.mbmi.mv[0].as_mv.row;
+ mvc1 = block_context[1].mic.mbmi.mv[0].as_mv.col;
+ mvr2 = block_context[2].mic.mbmi.mv[0].as_mv.row;
+ mvc2 = block_context[2].mic.mbmi.mv[0].as_mv.col;
+ mvr3 = block_context[3].mic.mbmi.mv[0].as_mv.row;
+ mvc3 = block_context[3].mic.mbmi.mv[0].as_mv.col;
// Adjust sign if ref is alt_ref
if (cm->ref_frame_sign_bias[ref0]) {
@@ -1631,9 +1687,8 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
}
}
- if (!cpi->sf.use_partitions_less_than
- || (cpi->sf.use_partitions_less_than
- && bsize <= cpi->sf.less_than_block_size)) {
+ if (!cpi->sf.auto_min_max_partition_size ||
+ bsize <= cpi->sf.max_partition_size) {
int larger_is_better = 0;
// PARTITION_NONE
if ((mi_row + (ms >> 1) < cm->mi_rows) &&
@@ -1804,8 +1859,7 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
}
// Examines 64x64 block and chooses a best reference frame
-static void rd_pick_reference_frame(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
- int mi_col, int *rate, int64_t *dist) {
+static void rd_pick_reference_frame(VP9_COMP *cpi, int mi_row, int mi_col) {
VP9_COMMON * const cm = &cpi->common;
MACROBLOCK * const x = &cpi->mb;
MACROBLOCKD * const xd = &x->e_mbd;
@@ -1836,23 +1890,7 @@ static void rd_pick_reference_frame(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
cpi->set_ref_frame_mask = 0;
}
- *rate = r;
- *dist = d;
- // RDCOST(x->rdmult, x->rddiv, r, d)
-
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_SIZE_SB64X64);
-
- /*if (srate < INT_MAX && sdist < INT_MAX)
- encode_sb(cpi, tp, mi_row, mi_col, 1, BLOCK_SIZE_SB64X64);
-
- if (bsize == BLOCK_SIZE_SB64X64) {
- assert(tp_orig < *tp);
- assert(srate < INT_MAX);
- assert(sdist < INT_MAX);
- } else {
- assert(tp_orig == *tp);
- }
- */
}
static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
@@ -1877,10 +1915,8 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
else
cpi->unused_mode_skip_mask = 0xFFFFFFFFFFFFFE00;
- if (cpi->sf.reference_masking) {
- rd_pick_reference_frame(cpi, tp, mi_row, mi_col,
- &dummy_rate, &dummy_dist);
- }
+ if (cpi->sf.reference_masking)
+ rd_pick_reference_frame(cpi, mi_row, mi_col);
if (cpi->sf.partition_by_variance || cpi->sf.use_lastframe_partitioning ||
cpi->sf.use_one_partition_size_always ) {
@@ -1888,6 +1924,7 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
MODE_INFO *m = cm->mi + idx_str;
MODE_INFO *p = cm->prev_mi + idx_str;
+ cpi->mb.source_variance = UINT_MAX;
if (cpi->sf.use_one_partition_size_always) {
set_offsets(cpi, mi_row, mi_col, BLOCK_SIZE_SB64X64);
set_partitioning(cpi, m, cpi->sf.always_this_block_size);
@@ -1904,6 +1941,12 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
|| cpi->common.show_frame == 0
|| cpi->common.frame_type == KEY_FRAME
|| cpi->is_src_frame_alt_ref) {
+ // If required set upper and lower partition size limits
+ if (cpi->sf.auto_min_max_partition_size) {
+ rd_auto_partition_range(cpi,
+ &cpi->sf.min_partition_size,
+ &cpi->sf.max_partition_size);
+ }
rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
&dummy_rate, &dummy_dist, 1, INT64_MAX);
} else {
@@ -1913,6 +1956,12 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
}
}
} else {
+ // If required set upper and lower partition size limits
+ if (cpi->sf.auto_min_max_partition_size) {
+ rd_auto_partition_range(cpi, &cpi->sf.min_partition_size,
+ &cpi->sf.max_partition_size);
+ }
+
rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
&dummy_rate, &dummy_dist, 1, INT64_MAX);
}
@@ -2086,7 +2135,7 @@ static void encode_frame_internal(VP9_COMP *cpi) {
}
vpx_usec_timer_mark(&emr_timer);
- cpi->time_encode_mb_row += vpx_usec_timer_elapsed(&emr_timer);
+ cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer);
}
if (cpi->sf.skip_encode_sb) {
@@ -2203,13 +2252,13 @@ static void reset_skip_txfm_size_sb(VP9_COMP *cpi, MODE_INFO *mi,
int n;
assert(bwl < bsl && bhl < bsl);
- if (bsize == BLOCK_SIZE_SB64X64) {
- subsize = BLOCK_SIZE_SB32X32;
- } else if (bsize == BLOCK_SIZE_SB32X32) {
- subsize = BLOCK_SIZE_MB16X16;
+ if (bsize == BLOCK_64X64) {
+ subsize = BLOCK_32X32;
+ } else if (bsize == BLOCK_32X32) {
+ subsize = BLOCK_16X16;
} else {
- assert(bsize == BLOCK_SIZE_MB16X16);
- subsize = BLOCK_SIZE_SB8X8;
+ assert(bsize == BLOCK_16X16);
+ subsize = BLOCK_8X8;
}
for (n = 0; n < 4; n++) {
@@ -2267,7 +2316,7 @@ static void select_tx_mode(VP9_COMP *cpi) {
} else {
unsigned int total = 0;
int i;
- for (i = 0; i < TX_SIZE_MAX_SB; ++i)
+ for (i = 0; i < TX_SIZES; ++i)
total += cpi->txfm_stepdown_count[i];
if (total) {
double fraction = (double)cpi->txfm_stepdown_count[0] / total;
@@ -2376,12 +2425,12 @@ void vp9_encode_frame(VP9_COMP *cpi) {
(cpi->rd_filter_threshes[frame_type][i] + diff) / 2;
}
- for (i = 0; i < NB_TXFM_MODES; ++i) {
+ for (i = 0; i < TX_MODES; ++i) {
int64_t pd = cpi->rd_tx_select_diff[i];
int diff;
if (i == TX_MODE_SELECT)
pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv,
- 2048 * (TX_SIZE_MAX_SB - 1), 0);
+ 2048 * (TX_SIZES - 1), 0);
diff = (int) (pd / cpi->common.MBs);
cpi->rd_tx_select_threshes[frame_type][i] += diff;
cpi->rd_tx_select_threshes[frame_type][i] /= 2;
@@ -2527,7 +2576,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
// Increase zbin size to suppress noise
cpi->zbin_mode_boost = 0;
if (cpi->zbin_mode_boost_enabled) {
- if (mbmi->ref_frame[0] != INTRA_FRAME) {
+ if (is_inter_block(mbmi)) {
if (mbmi->mode == ZEROMV) {
if (mbmi->ref_frame[0] != LAST_FRAME)
cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
@@ -2600,7 +2649,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
if (output_enabled) {
if (cm->tx_mode == TX_MODE_SELECT &&
mbmi->sb_type >= BLOCK_SIZE_SB8X8 &&
- !(mbmi->ref_frame[0] != INTRA_FRAME &&
+ !(is_inter_block(mbmi) &&
(mbmi->mb_skip_coeff ||
vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)))) {
const uint8_t context = vp9_get_pred_context_tx_size(xd);
@@ -2609,14 +2658,14 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
int x, y;
TX_SIZE sz = (cm->tx_mode == TX_MODE_SELECT) ? TX_32X32 : cm->tx_mode;
// The new intra coding scheme requires no change of transform size
- if (mi->mbmi.ref_frame[0] != INTRA_FRAME) {
- if (sz == TX_32X32 && bsize < BLOCK_SIZE_SB32X32)
+ if (is_inter_block(&mi->mbmi)) {
+ if (sz == TX_32X32 && bsize < BLOCK_32X32)
sz = TX_16X16;
- if (sz == TX_16X16 && bsize < BLOCK_SIZE_MB16X16)
+ if (sz == TX_16X16 && bsize < BLOCK_16X16)
sz = TX_8X8;
- if (sz == TX_8X8 && bsize < BLOCK_SIZE_SB8X8)
+ if (sz == TX_8X8 && bsize < BLOCK_8X8)
sz = TX_4X4;
- } else if (bsize >= BLOCK_SIZE_SB8X8) {
+ } else if (bsize >= BLOCK_8X8) {
sz = mbmi->txfm_size;
} else {
sz = TX_4X4;