Index: source/libvpx/vp9/encoder/vp9_encodeframe.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_encodeframe.c (revision 219822) |
+++ source/libvpx/vp9/encoder/vp9_encodeframe.c (working copy) |
@@ -8,33 +8,36 @@ |
* be found in the AUTHORS file in the root of the source tree. |
*/ |
+#include <limits.h> |
+#include <math.h> |
+#include <stdio.h> |
+ |
+#include "./vp9_rtcd.h" |
#include "./vpx_config.h" |
-#include "./vp9_rtcd.h" |
-#include "vp9/encoder/vp9_encodeframe.h" |
-#include "vp9/encoder/vp9_encodemb.h" |
-#include "vp9/encoder/vp9_encodemv.h" |
+ |
+#include "vpx_ports/vpx_timer.h" |
+ |
#include "vp9/common/vp9_common.h" |
-#include "vp9/encoder/vp9_onyx_int.h" |
-#include "vp9/common/vp9_extend.h" |
#include "vp9/common/vp9_entropy.h" |
#include "vp9/common/vp9_entropymode.h" |
+#include "vp9/common/vp9_extend.h" |
+#include "vp9/common/vp9_findnearmv.h" |
+#include "vp9/common/vp9_mvref_common.h" |
+#include "vp9/common/vp9_pred_common.h" |
#include "vp9/common/vp9_quant_common.h" |
-#include "vp9/encoder/vp9_segmentation.h" |
-#include "vp9/encoder/vp9_encodeintra.h" |
+#include "vp9/common/vp9_reconintra.h" |
#include "vp9/common/vp9_reconinter.h" |
-#include "vp9/encoder/vp9_rdopt.h" |
-#include "vp9/common/vp9_findnearmv.h" |
-#include "vp9/common/vp9_reconintra.h" |
#include "vp9/common/vp9_seg_common.h" |
#include "vp9/common/vp9_tile_common.h" |
+ |
+#include "vp9/encoder/vp9_encodeframe.h" |
+#include "vp9/encoder/vp9_encodeintra.h" |
+#include "vp9/encoder/vp9_encodemb.h" |
+#include "vp9/encoder/vp9_encodemv.h" |
+#include "vp9/encoder/vp9_onyx_int.h" |
+#include "vp9/encoder/vp9_rdopt.h" |
+#include "vp9/encoder/vp9_segmentation.h" |
#include "vp9/encoder/vp9_tokenize.h" |
-#include "./vp9_rtcd.h" |
-#include <stdio.h> |
-#include <math.h> |
-#include <limits.h> |
-#include "vpx_ports/vpx_timer.h" |
-#include "vp9/common/vp9_pred_common.h" |
-#include "vp9/common/vp9_mvref_common.h" |
#define DBG_PRNT_SEGMAP 0 |
@@ -44,7 +47,7 @@ |
#endif |
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, |
- int mi_row, int mi_col, BLOCK_SIZE_TYPE bsize); |
+ int mi_row, int mi_col, BLOCK_SIZE bsize); |
static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x); |
@@ -53,18 +56,39 @@ |
* This also avoids the need for divide by zero checks in |
* vp9_activity_masking(). |
*/ |
-#define VP9_ACTIVITY_AVG_MIN (64) |
+#define ACTIVITY_AVG_MIN (64) |
+/* Motion vector component magnitude threshold for defining fast motion. */ |
+#define FAST_MOTION_MV_THRESH (24) |
+ |
/* This is used as a reference when computing the source variance for the |
* purposes of activity masking. |
* 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_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x, |
+ BLOCK_SIZE 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 + (1 << (num_pels_log2_lookup[bs] - 1))) >> |
+ 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 |
@@ -86,31 +110,29 @@ |
} |
// Stub for alternative experimental activity measures. |
-static unsigned int alt_activity_measure(VP9_COMP *cpi, MACROBLOCK *x, |
- int use_dc_pred) { |
- return vp9_encode_intra(cpi, x, use_dc_pred); |
+static unsigned int alt_activity_measure(MACROBLOCK *x, int use_dc_pred) { |
+ return vp9_encode_intra(x, use_dc_pred); |
} |
DECLARE_ALIGNED(16, static const uint8_t, vp9_64x64_zeros[64*64]) = {0}; |
// Measure the activity of the current macroblock |
// What we measure here is TBD so abstracted to this function |
#define ALT_ACT_MEASURE 1 |
-static unsigned int mb_activity_measure(VP9_COMP *cpi, MACROBLOCK *x, |
- int mb_row, int mb_col) { |
+static unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) { |
unsigned int mb_activity; |
if (ALT_ACT_MEASURE) { |
int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); |
// Or use and alternative. |
- mb_activity = alt_activity_measure(cpi, x, use_dc_pred); |
+ mb_activity = alt_activity_measure(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) |
- mb_activity = VP9_ACTIVITY_AVG_MIN; |
+ if (mb_activity < ACTIVITY_AVG_MIN) |
+ mb_activity = ACTIVITY_AVG_MIN; |
return mb_activity; |
} |
@@ -158,10 +180,10 @@ |
#else |
// Simple mean for now |
cpi->activity_avg = (unsigned int) (activity_sum / cpi->common.MBs); |
-#endif |
+#endif // ACT_MEDIAN |
- if (cpi->activity_avg < VP9_ACTIVITY_AVG_MIN) |
- cpi->activity_avg = VP9_ACTIVITY_AVG_MIN; |
+ if (cpi->activity_avg < ACTIVITY_AVG_MIN) |
+ cpi->activity_avg = ACTIVITY_AVG_MIN; |
// Experimental code: return fixed value normalized for several clips |
if (ALT_ACT_MEASURE) |
@@ -223,7 +245,7 @@ |
#endif |
} |
-#endif |
+#endif // USE_ACT_INDEX |
// Loop through all MBs. Note activity of each, average activity and |
// calculate a normalized activity for each |
@@ -260,7 +282,7 @@ |
#endif |
// measure activity |
- mb_activity = mb_activity_measure(cpi, x, mb_row, mb_col); |
+ mb_activity = mb_activity_measure(x, mb_row, mb_col); |
// Keep frame sum |
activity_sum += mb_activity; |
@@ -314,17 +336,18 @@ |
} |
static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, |
- BLOCK_SIZE_TYPE bsize, int output_enabled) { |
+ BLOCK_SIZE bsize, int output_enabled) { |
int i, x_idx, y; |
- 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; |
MODE_INFO *mi = &ctx->mic; |
- MB_MODE_INFO * const mbmi = &xd->mode_info_context->mbmi; |
+ 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 mis = cm->mode_info_stride; |
+ const int mi_width = num_8x8_blocks_wide_lookup[bsize]; |
const int mi_height = num_8x8_blocks_high_lookup[bsize]; |
- const int mi_width = num_8x8_blocks_wide_lookup[bsize]; |
assert(mi->mbmi.mode < MB_MODE_COUNT); |
assert(mb_mode_index < MAX_MODES); |
@@ -334,24 +357,21 @@ |
// Restore the coding context of the MB to that that was in place |
// when the mode was picked for it |
- for (y = 0; y < mi_height; y++) { |
- for (x_idx = 0; x_idx < mi_width; x_idx++) { |
- if ((xd->mb_to_right_edge >> (3 + LOG2_MI_SIZE)) + mi_width > x_idx |
- && (xd->mb_to_bottom_edge >> (3 + LOG2_MI_SIZE)) + mi_height > y) { |
- MODE_INFO *mi_addr = xd->mode_info_context + x_idx + y * mis; |
- *mi_addr = *mi; |
- } |
- } |
- } |
+ for (y = 0; y < mi_height; y++) |
+ for (x_idx = 0; x_idx < mi_width; x_idx++) |
+ if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx |
+ && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) |
+ xd->mode_info_context[x_idx + y * mis] = *mi; |
+ |
// 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; |
@@ -361,13 +381,12 @@ |
if (!output_enabled) |
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]; |
- } |
+ if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) { |
+ 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) { |
+ if (cm->frame_type == KEY_FRAME) { |
// Restore the coding modes to that held in the coding context |
// if (mb_mode == I4X4_PRED) |
// for (i = 0; i < 16; i++) |
@@ -385,7 +404,7 @@ |
THR_D135_PRED /*D135_PRED*/, |
THR_D117_PRED /*D117_PRED*/, |
THR_D153_PRED /*D153_PRED*/, |
- THR_D27_PRED /*D27_PRED*/, |
+ THR_D207_PRED /*D207_PRED*/, |
THR_D63_PRED /*D63_PRED*/, |
THR_TM /*TM_PRED*/, |
THR_B_PRED /*I4X4_PRED*/, |
@@ -395,8 +414,8 @@ |
} else { |
// Note how often each mode chosen as best |
cpi->mode_chosen_counts[mb_mode_index]++; |
- if (mbmi->ref_frame[0] != INTRA_FRAME |
- && (mbmi->sb_type < BLOCK_SIZE_SB8X8 || mbmi->mode == NEWMV)) { |
+ if (is_inter_block(mbmi) |
+ && (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV)) { |
int_mv best_mv, best_second_mv; |
const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0]; |
const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1]; |
@@ -411,29 +430,26 @@ |
vp9_update_nmv_count(cpi, x, &best_mv, &best_second_mv); |
} |
- if (bsize > BLOCK_SIZE_SB8X8 && mbmi->mode == NEWMV) { |
+ if (bsize > BLOCK_8X8 && mbmi->mode == NEWMV) { |
int i, j; |
for (j = 0; j < mi_height; ++j) |
for (i = 0; i < mi_width; ++i) |
- if ((xd->mb_to_right_edge >> (3 + LOG2_MI_SIZE)) + mi_width > i |
- && (xd->mb_to_bottom_edge >> (3 + LOG2_MI_SIZE)) + mi_height > j) |
+ if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > i |
+ && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > j) |
xd->mode_info_context[mis * j + i].mbmi = *mbmi; |
} |
- if (cpi->common.mcomp_filter_type == SWITCHABLE |
- && is_inter_mode(mbmi->mode)) { |
- ++cpi->common.counts.switchable_interp[ |
- vp9_get_pred_context_switchable_interp(xd)] |
- [vp9_switchable_interp_map[mbmi->interp_filter]]; |
+ if (cm->mcomp_filter_type == SWITCHABLE && is_inter_mode(mbmi->mode)) { |
+ const int ctx = vp9_get_pred_context_switchable_interp(xd); |
+ ++cm->counts.switchable_interp[ctx][mbmi->interp_filter]; |
} |
cpi->rd_comp_pred_diff[SINGLE_PREDICTION_ONLY] += ctx->single_pred_diff; |
cpi->rd_comp_pred_diff[COMP_PREDICTION_ONLY] += ctx->comp_pred_diff; |
cpi->rd_comp_pred_diff[HYBRID_PREDICTION] += ctx->hybrid_pred_diff; |
- for (i = 0; i <= VP9_SWITCHABLE_FILTERS; i++) { |
+ for (i = 0; i <= SWITCHABLE_FILTERS; i++) |
cpi->rd_filter_diff[i] += ctx->best_filter_diff[i]; |
- } |
} |
} |
@@ -453,10 +469,10 @@ |
} |
static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col, |
- BLOCK_SIZE_TYPE bsize) { |
- MACROBLOCK * const x = &cpi->mb; |
- VP9_COMMON * const cm = &cpi->common; |
- MACROBLOCKD * const xd = &x->e_mbd; |
+ BLOCK_SIZE bsize) { |
+ MACROBLOCK *const x = &cpi->mb; |
+ VP9_COMMON *const cm = &cpi->common; |
+ MACROBLOCKD *const xd = &x->e_mbd; |
MB_MODE_INFO *mbmi; |
const int dst_fb_idx = cm->new_fb_idx; |
const int idx_str = xd->mode_info_stride * mi_row + mi_col; |
@@ -465,17 +481,9 @@ |
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; |
- int i; |
+ const struct segmentation *const seg = &cm->seg; |
- // entropy context structures |
- for (i = 0; i < MAX_MB_PLANE; i++) { |
- xd->plane[i].above_context = cm->above_context[i] |
- + (mi_col * 2 >> xd->plane[i].subsampling_x); |
- xd->plane[i].left_context = cm->left_context[i] |
- + (((mi_row * 2) & 15) >> xd->plane[i].subsampling_y); |
- } |
- |
- // partition contexts |
+ set_skip_context(cm, xd, mi_row, mi_col); |
set_partition_seg_context(cm, xd, mi_row, mi_col); |
// Activity map pointer |
@@ -493,14 +501,12 @@ |
// Set up destination pointers |
setup_dst_planes(xd, &cm->yv12_fb[dst_fb_idx], mi_row, mi_col); |
- /* Set up limit values for MV components to prevent them from |
- * extending beyond the UMV borders assuming 16x16 block size */ |
- x->mv_row_min = -((mi_row * MI_SIZE)+ VP9BORDERINPIXELS - VP9_INTERP_EXTEND); |
- x->mv_col_min = -((mi_col * MI_SIZE)+ VP9BORDERINPIXELS - VP9_INTERP_EXTEND); |
- x->mv_row_max = ((cm->mi_rows - mi_row) * MI_SIZE |
- + (VP9BORDERINPIXELS - MI_SIZE * mi_height - VP9_INTERP_EXTEND)); |
- x->mv_col_max = ((cm->mi_cols - mi_col) * MI_SIZE |
- + (VP9BORDERINPIXELS - MI_SIZE * mi_width - VP9_INTERP_EXTEND)); |
+ // Set up limit values for MV components |
+ // mv beyond the range do not produce new/different prediction block |
+ x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND); |
+ x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND); |
+ x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND; |
+ x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND; |
// Set up distance of MB to edge of frame in 1/8th pel units |
assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1))); |
@@ -514,16 +520,16 @@ |
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,27 +543,43 @@ |
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; |
} |
} |
static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col, |
int *totalrate, int64_t *totaldist, |
- BLOCK_SIZE_TYPE bsize, PICK_MODE_CONTEXT *ctx, |
+ BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, |
int64_t best_rd) { |
VP9_COMMON *const cm = &cpi->common; |
MACROBLOCK *const x = &cpi->mb; |
MACROBLOCKD *const xd = &x->e_mbd; |
- x->rd_search = 1; |
+ // Use the lower precision, but faster, 32x32 fdct for mode selection. |
+ x->use_lp32x32fdct = 1; |
- if (bsize < BLOCK_SIZE_SB8X8) |
- if (xd->ab_index != 0) |
+ if (bsize < BLOCK_8X8) { |
+ // 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) { |
+ *totalrate = 0; |
+ *totaldist = 0; |
return; |
+ } |
+ } |
set_offsets(cpi, mi_row, mi_col, bsize); |
xd->mode_info_context->mbmi.sb_type = bsize; |
+ |
+ // Set to zero to make sure we do not use the previous encoded frame stats |
+ xd->mode_info_context->mbmi.skip_coeff = 0; |
+ |
+ x->source_variance = get_sby_perpixel_variance(cpi, x, bsize); |
+ |
if (cpi->oxcf.tuning == VP8_TUNE_SSIM) |
vp9_activity_masking(cpi, x); |
@@ -571,79 +593,79 @@ |
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, |
+ const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id, |
SEG_LVL_REF_FRAME); |
if (!seg_ref_active) |
- cpi->intra_inter_count[vp9_get_pred_context_intra_inter(xd)][mbmi |
- ->ref_frame[0] > INTRA_FRAME]++; |
+ cpi->intra_inter_count[vp9_get_pred_context_intra_inter(xd)] |
+ [is_inter_block(mbmi)]++; |
// If the segment reference feature is enabled we have only a single |
// reference frame allowed for the segment so exclude it from |
// the reference frame counts used to work out probabilities. |
- if ((mbmi->ref_frame[0] > INTRA_FRAME) && !seg_ref_active) { |
+ if (is_inter_block(mbmi) && !seg_ref_active) { |
if (cm->comp_pred_mode == HYBRID_PREDICTION) |
cpi->comp_inter_count[vp9_get_pred_context_comp_inter_inter(cm, xd)] |
- [mbmi->ref_frame[1] > INTRA_FRAME]++; |
+ [has_second_ref(mbmi)]++; |
- if (mbmi->ref_frame[1] > INTRA_FRAME) { |
- cpi->comp_ref_count[vp9_get_pred_context_comp_ref_p(cm, xd)][mbmi |
- ->ref_frame[0] == GOLDEN_FRAME]++; |
+ if (has_second_ref(mbmi)) { |
+ cpi->comp_ref_count[vp9_get_pred_context_comp_ref_p(cm, xd)] |
+ [mbmi->ref_frame[0] == GOLDEN_FRAME]++; |
} else { |
- cpi->single_ref_count[vp9_get_pred_context_single_ref_p1(xd)] |
- [0][mbmi->ref_frame[0] != LAST_FRAME]++; |
+ cpi->single_ref_count[vp9_get_pred_context_single_ref_p1(xd)][0] |
+ [mbmi->ref_frame[0] != LAST_FRAME]++; |
if (mbmi->ref_frame[0] != LAST_FRAME) |
cpi->single_ref_count[vp9_get_pred_context_single_ref_p2(xd)][1] |
- [mbmi->ref_frame[0] != GOLDEN_FRAME]++; |
+ [mbmi->ref_frame[0] != GOLDEN_FRAME]++; |
} |
} |
+ |
// Count of last ref frame 0,0 usage |
- if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame[0] == LAST_FRAME)) |
+ if (mbmi->mode == ZEROMV && mbmi->ref_frame[0] == LAST_FRAME) |
cpi->inter_zz_count++; |
} |
} |
// 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; |
+static PICK_MODE_CONTEXT *get_block_context(MACROBLOCK *x, BLOCK_SIZE 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); |
@@ -651,17 +673,16 @@ |
} |
} |
-static BLOCK_SIZE_TYPE *get_sb_partitioning(MACROBLOCK *x, |
- BLOCK_SIZE_TYPE bsize) { |
- MACROBLOCKD *xd = &x->e_mbd; |
+static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) { |
+ MACROBLOCKD *const 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); |
@@ -673,13 +694,13 @@ |
ENTROPY_CONTEXT a[16 * MAX_MB_PLANE], |
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; |
+ BLOCK_SIZE bsize) { |
+ 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++) { |
@@ -704,13 +725,13 @@ |
ENTROPY_CONTEXT a[16 * MAX_MB_PLANE], |
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; |
+ BLOCK_SIZE bsize) { |
+ 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]; |
@@ -735,7 +756,7 @@ |
} |
static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, |
- int output_enabled, BLOCK_SIZE_TYPE bsize, int sub_index) { |
+ int output_enabled, BLOCK_SIZE bsize, int sub_index) { |
VP9_COMMON * const cm = &cpi->common; |
MACROBLOCK * const x = &cpi->mb; |
MACROBLOCKD * const xd = &x->e_mbd; |
@@ -746,15 +767,18 @@ |
if (sub_index != -1) |
*(get_sb_index(xd, bsize)) = sub_index; |
- if (bsize < BLOCK_SIZE_SB8X8) |
+ if (bsize < BLOCK_8X8) { |
+ // 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)++; |
@@ -762,22 +786,22 @@ |
} |
static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, |
- int output_enabled, BLOCK_SIZE_TYPE bsize) { |
+ int output_enabled, BLOCK_SIZE bsize) { |
VP9_COMMON * const cm = &cpi->common; |
MACROBLOCK * const x = &cpi->mb; |
MACROBLOCKD * const xd = &x->e_mbd; |
- BLOCK_SIZE_TYPE c1 = BLOCK_SIZE_SB8X8; |
+ BLOCK_SIZE c1 = BLOCK_8X8; |
const int bsl = b_width_log2(bsize), bs = (1 << bsl) / 4; |
int UNINITIALIZED_IS_SAFE(pl); |
PARTITION_TYPE partition; |
- BLOCK_SIZE_TYPE subsize; |
+ BLOCK_SIZE subsize; |
int i; |
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
return; |
- c1 = BLOCK_SIZE_AB4X4; |
- if (bsize >= BLOCK_SIZE_SB8X8) { |
+ c1 = BLOCK_4X4; |
+ if (bsize >= BLOCK_8X8) { |
set_partition_seg_context(cm, xd, mi_row, mi_col); |
pl = partition_plane_context(xd, bsize); |
c1 = *(get_sb_partitioning(x, bsize)); |
@@ -786,7 +810,7 @@ |
switch (partition) { |
case PARTITION_NONE: |
- if (output_enabled && bsize >= BLOCK_SIZE_SB8X8) |
+ if (output_enabled && bsize >= BLOCK_8X8) |
cpi->partition_count[pl][PARTITION_NONE]++; |
encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, -1); |
break; |
@@ -821,14 +845,13 @@ |
break; |
} |
- if (partition != PARTITION_SPLIT || bsize == BLOCK_SIZE_SB8X8) { |
+ if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) { |
set_partition_seg_context(cm, xd, mi_row, mi_col); |
update_partition_context(xd, c1, bsize); |
} |
} |
-static void set_partitioning(VP9_COMP *cpi, MODE_INFO *m, |
- BLOCK_SIZE_TYPE bsize) { |
+static void set_partitioning(VP9_COMP *cpi, MODE_INFO *m, BLOCK_SIZE bsize) { |
VP9_COMMON *const cm = &cpi->common; |
const int mis = cm->mode_info_stride; |
int block_row, block_col; |
@@ -851,14 +874,14 @@ |
} |
static void set_block_size(VP9_COMMON * const cm, MODE_INFO *m, |
- BLOCK_SIZE_TYPE bsize, int mis, int mi_row, |
+ BLOCK_SIZE bsize, int mis, int mi_row, |
int mi_col) { |
int row, col; |
int bwl = b_width_log2(bsize); |
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++) { |
@@ -903,31 +926,31 @@ |
V64X64, |
} TREE_LEVEL; |
-static void tree_to_node(void *data, BLOCK_SIZE_TYPE block_size, vt_node *node) { |
+static void tree_to_node(void *data, BLOCK_SIZE bsize, vt_node *node) { |
int i; |
- switch (block_size) { |
- case BLOCK_SIZE_SB64X64: { |
+ switch (bsize) { |
+ 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++) |
@@ -962,9 +985,9 @@ |
a->sum_error + b->sum_error, a->count + b->count); |
} |
-static void fill_variance_tree(void *data, BLOCK_SIZE_TYPE block_size) { |
+static void fill_variance_tree(void *data, BLOCK_SIZE bsize) { |
vt_node node; |
- tree_to_node(data, block_size, &node); |
+ tree_to_node(data, bsize, &node); |
sum_2_variances(&node.vt->horz[0], node.split[0], node.split[1]); |
sum_2_variances(&node.vt->horz[1], node.split[2], node.split[3]); |
sum_2_variances(&node.vt->vert[0], node.split[0], node.split[2]); |
@@ -974,7 +997,7 @@ |
#if PERFORM_RANDOM_PARTITIONING |
static int set_vt_partitioning(VP9_COMP *cpi, void *data, MODE_INFO *m, |
- BLOCK_SIZE_TYPE block_size, int mi_row, |
+ BLOCK_SIZE block_size, int mi_row, |
int mi_col, int mi_size) { |
VP9_COMMON * const cm = &cpi->common; |
vt_node vt; |
@@ -1010,30 +1033,30 @@ |
return 0; |
} |
-#else |
+#else // !PERFORM_RANDOM_PARTITIONING |
static int set_vt_partitioning(VP9_COMP *cpi, void *data, MODE_INFO *m, |
- BLOCK_SIZE_TYPE block_size, int mi_row, |
+ BLOCK_SIZE bsize, int mi_row, |
int mi_col, int mi_size) { |
VP9_COMMON * const cm = &cpi->common; |
vt_node vt; |
const int mis = cm->mode_info_stride; |
int64_t threshold = 50 * cpi->common.base_qindex; |
- tree_to_node(data, block_size, &vt); |
+ tree_to_node(data, bsize, &vt); |
// split none is available only if we have more than half a block size |
// in width and height inside the visible image |
if (mi_col + mi_size < cm->mi_cols && mi_row + mi_size < cm->mi_rows |
&& vt.vt->none.variance < threshold) { |
- set_block_size(cm, m, block_size, mis, mi_row, mi_col); |
+ set_block_size(cm, m, bsize, mis, mi_row, mi_col); |
return 1; |
} |
// vertical split is available on all but the bottom border |
if (mi_row + mi_size < cm->mi_rows && vt.vt->vert[0].variance < threshold |
&& vt.vt->vert[1].variance < threshold) { |
- set_block_size(cm, m, get_subsize(block_size, PARTITION_VERT), mis, mi_row, |
+ set_block_size(cm, m, get_subsize(bsize, PARTITION_VERT), mis, mi_row, |
mi_col); |
return 1; |
} |
@@ -1041,14 +1064,14 @@ |
// horizontal split is available on all but the right border |
if (mi_col + mi_size < cm->mi_cols && vt.vt->horz[0].variance < threshold |
&& vt.vt->horz[1].variance < threshold) { |
- set_block_size(cm, m, get_subsize(block_size, PARTITION_HORZ), mis, mi_row, |
+ set_block_size(cm, m, get_subsize(bsize, PARTITION_HORZ), mis, mi_row, |
mi_col); |
return 1; |
} |
return 0; |
} |
-#endif |
+#endif // PERFORM_RANDOM_PARTITIONING |
static void choose_partitioning(VP9_COMP *cpi, MODE_INFO *m, int mi_row, |
int mi_col) { |
@@ -1066,10 +1089,9 @@ |
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_64X64); |
- set_offsets(cpi, mi_row, mi_col, BLOCK_SIZE_SB64X64); |
- |
if (xd->mb_to_right_edge < 0) |
pixels_wide += (xd->mb_to_right_edge >> 3); |
@@ -1087,7 +1109,8 @@ |
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, |
@@ -1095,15 +1118,14 @@ |
setup_pre_planes(xd, 1, second_ref_fb, mi_row, mi_col, |
&xd->scale_factor[1]); |
xd->mode_info_context->mbmi.ref_frame[0] = LAST_FRAME; |
- xd->mode_info_context->mbmi.sb_type = BLOCK_SIZE_SB64X64; |
+ xd->mode_info_context->mbmi.sb_type = BLOCK_64X64; |
vp9_find_best_ref_mvs(xd, m->mbmi.ref_mvs[m->mbmi.ref_frame[0]], |
&nearest_mv, &near_mv); |
xd->mode_info_context->mbmi.mv[0] = nearest_mv; |
- vp9_build_inter_predictors_sby(xd, mi_row, mi_col, BLOCK_SIZE_SB64X64); |
+ vp9_build_inter_predictors_sby(xd, mi_row, mi_col, BLOCK_64X64); |
d = xd->plane[0].dst.buf; |
dp = xd->plane[0].dst.stride; |
- |
} |
// Fill in the entire tree of 8x8 variances for splits. |
@@ -1130,32 +1152,32 @@ |
// 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,22 +1187,23 @@ |
} |
} |
} |
+ |
static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp, |
- int mi_row, int mi_col, BLOCK_SIZE_TYPE bsize, |
+ int mi_row, int mi_col, BLOCK_SIZE bsize, |
int *rate, int64_t *dist, int do_recon) { |
VP9_COMMON * const cm = &cpi->common; |
MACROBLOCK * const x = &cpi->mb; |
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; |
int i, pl; |
PARTITION_TYPE partition = PARTITION_NONE; |
- BLOCK_SIZE_TYPE subsize; |
+ BLOCK_SIZE subsize; |
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; |
PARTITION_CONTEXT sl[8], sa[8]; |
int last_part_rate = INT_MAX; |
@@ -1191,9 +1214,9 @@ |
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 sub_subsize = BLOCK_4X4; |
int splits_below = 0; |
- BLOCK_SIZE_TYPE bs_type = m->mbmi.sb_type; |
+ BLOCK_SIZE bs_type = m->mbmi.sb_type; |
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
return; |
@@ -1202,7 +1225,9 @@ |
subsize = get_subsize(bsize, partition); |
- if (bsize < BLOCK_SIZE_SB8X8) { |
+ if (bsize < BLOCK_8X8) { |
+ // 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,9 +1238,13 @@ |
} |
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) { |
+ if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) { |
sub_subsize = get_subsize(subsize, PARTITION_SPLIT); |
splits_below = 1; |
for (i = 0; i < 4; i++) { |
@@ -1255,7 +1284,7 @@ |
pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, |
subsize, get_block_context(x, subsize), INT64_MAX); |
if (last_part_rate != INT_MAX && |
- bsize >= BLOCK_SIZE_SB8X8 && mi_row + (mh >> 1) < cm->mi_rows) { |
+ bsize >= BLOCK_8X8 && mi_row + (mh >> 1) < cm->mi_rows) { |
int rt = 0; |
int64_t dt = 0; |
update_state(cpi, get_block_context(x, subsize), subsize, 0); |
@@ -1278,7 +1307,7 @@ |
pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, |
subsize, get_block_context(x, subsize), INT64_MAX); |
if (last_part_rate != INT_MAX && |
- bsize >= BLOCK_SIZE_SB8X8 && mi_col + (ms >> 1) < cm->mi_cols) { |
+ bsize >= BLOCK_8X8 && mi_col + (ms >> 1) < cm->mi_cols) { |
int rt = 0; |
int64_t dt = 0; |
update_state(cpi, get_block_context(x, subsize), subsize, 0); |
@@ -1331,10 +1360,10 @@ |
last_part_rate += x->partition_cost[pl][partition]; |
if (cpi->sf.adjust_partitioning_from_last_frame |
- && partition != PARTITION_SPLIT && bsize > BLOCK_SIZE_SB8X8 |
+ && partition != PARTITION_SPLIT && bsize > BLOCK_8X8 |
&& (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); |
+ BLOCK_SIZE 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); |
@@ -1394,7 +1423,7 @@ |
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) |
+ if (bsize >= BLOCK_8X8) |
*(get_sb_partitioning(x, bsize)) = subsize; |
chosen_rate = last_part_rate; |
chosen_dist = last_part_dist; |
@@ -1402,7 +1431,7 @@ |
// 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) |
+ if (bsize >= BLOCK_8X8) |
*(get_sb_partitioning(x, bsize)) = bsize; |
chosen_rate = none_rate; |
chosen_dist = none_dist; |
@@ -1412,22 +1441,209 @@ |
// We must have chosen a partitioning and encoding or we'll fail later on. |
// No other opportunities for success. |
- if ( bsize == BLOCK_SIZE_SB64X64) |
+ if ( bsize == BLOCK_64X64) |
assert(chosen_rate < INT_MAX && chosen_dist < INT_MAX); |
if (do_recon) |
- encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_SIZE_SB64X64, bsize); |
+ encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); |
*rate = chosen_rate; |
*dist = chosen_dist; |
} |
+static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = { |
+ 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 const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = { |
+ 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 all the mode_info entries for blocks that are part of this |
+// partition and find the min and max values for sb_type. |
+// At the moment this is designed to work on a 64x64 SB but could be |
+// adjusted to use a size parameter. |
+// |
+// The min and max are assumed to have been initialized prior to calling this |
+// function so repeat calls can accumulate a min and max of more than one sb64. |
+static void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO * mi, |
+ BLOCK_SIZE *min_block_size, |
+ BLOCK_SIZE *max_block_size ) { |
+ MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
+ int sb_width_in_blocks = MI_BLOCK_SIZE; |
+ int sb_height_in_blocks = MI_BLOCK_SIZE; |
+ int i, j; |
+ int index = 0; |
+ |
+ // Check the sb_type for each block that belongs to this region. |
+ for (i = 0; i < sb_height_in_blocks; ++i) { |
+ for (j = 0; j < sb_width_in_blocks; ++j) { |
+ *min_block_size = MIN(*min_block_size, mi[index + j].mbmi.sb_type); |
+ *max_block_size = MAX(*max_block_size, mi[index + j].mbmi.sb_type); |
+ } |
+ index += xd->mode_info_stride; |
+ } |
+} |
+ |
+// 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 *min_block_size, |
+ BLOCK_SIZE *max_block_size) { |
+ MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
+ MODE_INFO *mi = xd->mode_info_context; |
+ MODE_INFO *above_sb64_mi; |
+ MODE_INFO *left_sb64_mi; |
+ 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->in_image; |
+ const int above_in_image = xd->up_available && above_mbmi->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; |
+ } |
+ |
+ // Set default values if not left or above neighbour |
+ if (!left_in_image && !above_in_image) { |
+ *min_block_size = BLOCK_4X4; |
+ *max_block_size = BLOCK_64X64; |
+ } else { |
+ // Default "min to max" and "max to min" |
+ *min_block_size = BLOCK_64X64; |
+ *max_block_size = BLOCK_4X4; |
+ |
+ // Find the min and max partition sizes used in the left SB64 |
+ if (left_in_image) { |
+ left_sb64_mi = &mi[-MI_BLOCK_SIZE]; |
+ get_sb_partition_size_range(cpi, left_sb64_mi, |
+ min_block_size, max_block_size); |
+ } |
+ |
+ // Find the min and max partition sizes used in the above SB64 taking |
+ // the values found for left as a starting point. |
+ if (above_in_image) { |
+ above_sb64_mi = &mi[-xd->mode_info_stride * MI_BLOCK_SIZE]; |
+ get_sb_partition_size_range(cpi, above_sb64_mi, |
+ min_block_size, max_block_size); |
+ } |
+ |
+ // give a bit of leaway either side of the observed min and max |
+ *min_block_size = min_partition_size[*min_block_size]; |
+ *max_block_size = max_partition_size[*max_block_size]; |
+ } |
+} |
+ |
+static void compute_fast_motion_search_level(VP9_COMP *cpi, BLOCK_SIZE bsize) { |
+ VP9_COMMON *const cm = &cpi->common; |
+ MACROBLOCK *const x = &cpi->mb; |
+ MACROBLOCKD *const xd = &x->e_mbd; |
+ |
+ // 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_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_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_64X64) { |
+ 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 reference frames. |
+ if (ref0 && ref1 && ref2 && ref3) { |
+ int d01, d23, d02, d13; |
+ |
+ // Motion vectors for the four subblocks. |
+ int16_t mvr0 = block_context[0].mic.mbmi.mv[0].as_mv.row; |
+ int16_t mvc0 = block_context[0].mic.mbmi.mv[0].as_mv.col; |
+ int16_t mvr1 = block_context[1].mic.mbmi.mv[0].as_mv.row; |
+ int16_t mvc1 = block_context[1].mic.mbmi.mv[0].as_mv.col; |
+ int16_t mvr2 = block_context[2].mic.mbmi.mv[0].as_mv.row; |
+ int16_t mvc2 = block_context[2].mic.mbmi.mv[0].as_mv.col; |
+ int16_t mvr3 = block_context[3].mic.mbmi.mv[0].as_mv.row; |
+ int16_t 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]) { |
+ mvr0 *= -1; |
+ mvc0 *= -1; |
+ } |
+ |
+ if (cm->ref_frame_sign_bias[ref1]) { |
+ mvr1 *= -1; |
+ mvc1 *= -1; |
+ } |
+ |
+ if (cm->ref_frame_sign_bias[ref2]) { |
+ mvr2 *= -1; |
+ mvc2 *= -1; |
+ } |
+ |
+ if (cm->ref_frame_sign_bias[ref3]) { |
+ mvr3 *= -1; |
+ mvc3 *= -1; |
+ } |
+ |
+ // Calculate mv distances. |
+ d01 = MAX(abs(mvr0 - mvr1), abs(mvc0 - mvc1)); |
+ d23 = MAX(abs(mvr2 - mvr3), abs(mvc2 - mvc3)); |
+ d02 = MAX(abs(mvr0 - mvr2), abs(mvc0 - mvc2)); |
+ d13 = MAX(abs(mvr1 - mvr3), abs(mvc1 - mvc3)); |
+ |
+ if (d01 < FAST_MOTION_MV_THRESH && d23 < FAST_MOTION_MV_THRESH && |
+ d02 < FAST_MOTION_MV_THRESH && d13 < FAST_MOTION_MV_THRESH) { |
+ // Set fast motion search level. |
+ x->fast_ms = 1; |
+ |
+ // Calculate prediction MV. |
+ x->pred_mv.as_mv.row = (mvr0 + mvr1 + mvr2 + mvr3) >> 2; |
+ x->pred_mv.as_mv.col = (mvc0 + mvc1 + mvc2 + mvc3) >> 2; |
+ |
+ if (ref0 == ref1 && ref1 == ref2 && ref2 == ref3 && |
+ d01 < 2 && d23 < 2 && d02 < 2 && d13 < 2) { |
+ // Set fast motion search level. |
+ x->fast_ms = 2; |
+ |
+ if (!d01 && !d23 && !d02 && !d13) { |
+ x->fast_ms = 3; |
+ x->subblock_ref = ref0; |
+ } |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
// 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, |
+ int mi_col, BLOCK_SIZE bsize, int *rate, |
int64_t *dist, int do_recon, int64_t best_rd) { |
VP9_COMMON * const cm = &cpi->common; |
MACROBLOCK * const x = &cpi->mb; |
@@ -1438,378 +1654,243 @@ |
PARTITION_CONTEXT sl[8], sa[8]; |
TOKENEXTRA *tp_orig = *tp; |
int i, pl; |
- BLOCK_SIZE_TYPE subsize; |
- int srate = INT_MAX; |
- int64_t sdist = INT_MAX; |
+ BLOCK_SIZE subsize; |
+ 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; |
+ int do_split = bsize >= BLOCK_8X8; |
+ int do_rect = 1; |
+ // Override skipping rectangular partition operations for edge blocks |
+ const int force_horz_split = (mi_row + (ms >> 1) >= cm->mi_rows); |
+ const int force_vert_split = (mi_col + (ms >> 1) >= cm->mi_cols); |
+ int partition_none_allowed = !force_horz_split && !force_vert_split; |
+ int partition_horz_allowed = !force_vert_split && bsize >= BLOCK_8X8; |
+ int partition_vert_allowed = !force_horz_split && bsize >= BLOCK_8X8; |
+ |
+ int partition_split_done = 0; |
(void) *tp_orig; |
- if (bsize < BLOCK_SIZE_SB8X8) |
+ if (bsize < BLOCK_8X8) { |
+ // 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)); |
+ // Determine partition types in search according to the speed features. |
+ // The threshold set here has to be of square block size. |
+ if (cpi->sf.auto_min_max_partition_size) { |
+ partition_none_allowed &= (bsize <= cpi->sf.max_partition_size && |
+ bsize >= cpi->sf.min_partition_size); |
+ partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size && |
+ bsize > cpi->sf.min_partition_size) || |
+ force_horz_split); |
+ partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size && |
+ bsize > cpi->sf.min_partition_size) || |
+ force_vert_split); |
+ do_split &= bsize > cpi->sf.min_partition_size; |
+ } |
+ if (cpi->sf.use_square_partition_only) { |
+ partition_horz_allowed &= force_horz_split; |
+ partition_vert_allowed &= force_vert_split; |
+ } |
+ |
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
+ if (cpi->sf.disable_split_var_thresh && partition_none_allowed) { |
+ unsigned int source_variancey; |
+ vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); |
+ source_variancey = get_sby_perpixel_variance(cpi, x, bsize); |
+ if (source_variancey < cpi->sf.disable_split_var_thresh) { |
+ do_split = 0; |
+ if (source_variancey < cpi->sf.disable_split_var_thresh / 2) |
+ do_rect = 0; |
+ } |
+ } |
+ |
+ // PARTITION_NONE |
+ if (partition_none_allowed) { |
+ pick_sb_modes(cpi, mi_row, mi_col, &this_rate, &this_dist, bsize, |
+ get_block_context(x, bsize), best_rd); |
+ if (this_rate != INT_MAX) { |
+ if (bsize >= BLOCK_8X8) { |
+ set_partition_seg_context(cm, xd, mi_row, mi_col); |
+ pl = partition_plane_context(xd, bsize); |
+ this_rate += x->partition_cost[pl][PARTITION_NONE]; |
+ } |
+ sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist); |
+ if (sum_rd < best_rd) { |
+ best_rate = this_rate; |
+ best_dist = this_dist; |
+ best_rd = sum_rd; |
+ if (bsize >= BLOCK_8X8) |
+ *(get_sb_partitioning(x, bsize)) = bsize; |
+ } |
+ } |
+ restore_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 (bsize > BLOCK_SIZE_SB8X8) { |
- int r4 = 0; |
- int64_t d4 = 0, sum_rd = 0; |
- subsize = get_subsize(bsize, PARTITION_SPLIT); |
+ sum_rd = 0; |
+ // TODO(jingning): use the motion vectors given by the above search as |
+ // the starting point of motion search in the following partition type check. |
+ if (do_split) { |
+ subsize = get_subsize(bsize, PARTITION_SPLIT); |
+ for (i = 0; i < 4 && sum_rd < best_rd; ++i) { |
+ int x_idx = (i & 1) * (ms >> 1); |
+ int y_idx = (i >> 1) * (ms >> 1); |
- for (i = 0; i < 4 && sum_rd < best_rd; ++i) { |
- int x_idx = (i & 1) * (ms >> 1); |
- int y_idx = (i >> 1) * (ms >> 1); |
- int r = 0; |
- int64_t d = 0; |
+ if ((mi_row + y_idx >= cm->mi_rows) || |
+ (mi_col + x_idx >= cm->mi_cols)) |
+ continue; |
- if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) |
- continue; |
+ *(get_sb_index(xd, subsize)) = i; |
- *(get_sb_index(xd, subsize)) = i; |
- rd_pick_partition(cpi, tp, mi_row + y_idx, mi_col + x_idx, subsize, &r, |
- &d, i != 3, best_rd - sum_rd); |
+ rd_pick_partition(cpi, tp, mi_row + y_idx, mi_col + x_idx, subsize, |
+ &this_rate, &this_dist, i != 3, best_rd - sum_rd); |
- if (r == INT_MAX) { |
- r4 = INT_MAX; |
- sum_rd = INT64_MAX; |
- } else { |
- r4 += r; |
- d4 += d; |
- sum_rd = RDCOST(x->rdmult, x->rddiv, r4, d4); |
- } |
+ if (this_rate == INT_MAX) { |
+ sum_rd = INT64_MAX; |
+ } else { |
+ sum_rate += this_rate; |
+ sum_dist += this_dist; |
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
} |
+ } |
+ if (sum_rd < best_rd && i == 4) { |
set_partition_seg_context(cm, xd, mi_row, mi_col); |
pl = partition_plane_context(xd, bsize); |
- if (r4 != INT_MAX && i == 4) { |
- r4 += x->partition_cost[pl][PARTITION_SPLIT]; |
+ sum_rate += x->partition_cost[pl][PARTITION_SPLIT]; |
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
+ if (sum_rd < best_rd) { |
+ best_rate = sum_rate; |
+ best_dist = sum_dist; |
+ best_rd = sum_rd; |
*(get_sb_partitioning(x, bsize)) = subsize; |
- assert(r4 >= 0); |
- assert(d4 >= 0); |
- srate = r4; |
- sdist = d4; |
- best_rd = MIN(best_rd, RDCOST(x->rdmult, x->rddiv, r4, d4)); |
+ } else { |
+ // skip rectangular partition test when larger block size |
+ // gives better rd cost |
+ if (cpi->sf.less_rectangular_check) |
+ do_rect &= !partition_none_allowed; |
} |
- restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
} |
+ partition_split_done = 1; |
+ restore_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; |
- // Use 4 subblocks' motion estimation results to speed up current |
- // partition's checking. |
- if (cpi->sf.using_small_partition_info) { |
- // 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 (partition_split_done && |
+ cpi->sf.using_small_partition_info) { |
+ compute_fast_motion_search_level(cpi, bsize); |
+ } |
- if (cm->frame_type && !cpi->is_src_frame_alt_ref && |
- ((use_8x8 && bsize == BLOCK_SIZE_MB16X16) || |
- bsize == BLOCK_SIZE_SB32X32 || bsize == BLOCK_SIZE_SB64X64)) { |
- int ref0 = 0, ref1 = 0, ref2 = 0, ref3 = 0; |
+ // PARTITION_HORZ |
+ if (partition_horz_allowed && do_rect) { |
+ subsize = get_subsize(bsize, PARTITION_HORZ); |
+ *(get_sb_index(xd, subsize)) = 0; |
+ pick_sb_modes(cpi, mi_row, mi_col, &sum_rate, &sum_dist, subsize, |
+ get_block_context(x, subsize), best_rd); |
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
- 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]; |
- } 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]; |
- } |
+ if (sum_rd < best_rd && mi_row + (ms >> 1) < cm->mi_rows) { |
+ update_state(cpi, get_block_context(x, subsize), subsize, 0); |
+ encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); |
- // Currently, only consider 4 inter ref frames. |
- if (ref0 && ref1 && ref2 && ref3) { |
- int16_t mvr0 = 0, mvc0 = 0, mvr1 = 0, mvc1 = 0, mvr2 = 0, mvc2 = 0, |
- mvr3 = 0, mvc3 = 0; |
- 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; |
- } |
- |
- // Adjust sign if ref is alt_ref |
- if (cm->ref_frame_sign_bias[ref0]) { |
- mvr0 *= -1; |
- mvc0 *= -1; |
- } |
- |
- if (cm->ref_frame_sign_bias[ref1]) { |
- mvr1 *= -1; |
- mvc1 *= -1; |
- } |
- |
- if (cm->ref_frame_sign_bias[ref2]) { |
- mvr2 *= -1; |
- mvc2 *= -1; |
- } |
- |
- if (cm->ref_frame_sign_bias[ref3]) { |
- mvr3 *= -1; |
- mvc3 *= -1; |
- } |
- |
- // Calculate mv distances. |
- d01 = MAX(abs(mvr0 - mvr1), abs(mvc0 - mvc1)); |
- d23 = MAX(abs(mvr2 - mvr3), abs(mvc2 - mvc3)); |
- d02 = MAX(abs(mvr0 - mvr2), abs(mvc0 - mvc2)); |
- d13 = MAX(abs(mvr1 - mvr3), abs(mvc1 - mvc3)); |
- |
- if (d01 < 24 && d23 < 24 && d02 < 24 && d13 < 24) { |
- // Set fast motion search level. |
- x->fast_ms = 1; |
- |
- // Calculate prediction MV |
- x->pred_mv.as_mv.row = (mvr0 + mvr1 + mvr2 + mvr3) >> 2; |
- x->pred_mv.as_mv.col = (mvc0 + mvc1 + mvc2 + mvc3) >> 2; |
- |
- if (ref0 == ref1 && ref1 == ref2 && ref2 == ref3 && |
- d01 < 2 && d23 < 2 && d02 < 2 && d13 < 2) { |
- // Set fast motion search level. |
- x->fast_ms = 2; |
- |
- if (!d01 && !d23 && !d02 && !d13) { |
- x->fast_ms = 3; |
- x->subblock_ref = ref0; |
- } |
- } |
- } |
+ *(get_sb_index(xd, subsize)) = 1; |
+ pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, &this_rate, |
+ &this_dist, subsize, get_block_context(x, subsize), |
+ best_rd - sum_rd); |
+ if (this_rate == INT_MAX) { |
+ sum_rd = INT64_MAX; |
+ } else { |
+ sum_rate += this_rate; |
+ sum_dist += this_dist; |
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
} |
} |
- } |
- |
- if (!cpi->sf.use_partitions_less_than |
- || (cpi->sf.use_partitions_less_than |
- && bsize <= cpi->sf.less_than_block_size)) { |
- int larger_is_better = 0; |
- // PARTITION_NONE |
- if ((mi_row + (ms >> 1) < cm->mi_rows) && |
- (mi_col + (ms >> 1) < cm->mi_cols)) { |
- int r; |
- int64_t d; |
- pick_sb_modes(cpi, mi_row, mi_col, &r, &d, bsize, |
- get_block_context(x, bsize), best_rd); |
- if (r != INT_MAX && bsize >= BLOCK_SIZE_SB8X8) { |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
- r += x->partition_cost[pl][PARTITION_NONE]; |
+ if (sum_rd < best_rd) { |
+ set_partition_seg_context(cm, xd, mi_row, mi_col); |
+ pl = partition_plane_context(xd, bsize); |
+ sum_rate += x->partition_cost[pl][PARTITION_HORZ]; |
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
+ if (sum_rd < best_rd) { |
+ best_rd = sum_rd; |
+ best_rate = sum_rate; |
+ best_dist = sum_dist; |
+ *(get_sb_partitioning(x, bsize)) = subsize; |
} |
- |
- if (r != INT_MAX && |
- (bsize == BLOCK_SIZE_SB8X8 || |
- RDCOST(x->rdmult, x->rddiv, r, d) < |
- RDCOST(x->rdmult, x->rddiv, srate, sdist))) { |
- best_rd = MIN(best_rd, RDCOST(x->rdmult, x->rddiv, r, d)); |
- srate = r; |
- sdist = d; |
- larger_is_better = 1; |
- if (bsize >= BLOCK_SIZE_SB8X8) |
- *(get_sb_partitioning(x, bsize)) = bsize; |
- } |
} |
+ restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
+ } |
- if (bsize == BLOCK_SIZE_SB8X8) { |
- int r4 = 0; |
- int64_t d4 = 0, sum_rd = 0; |
- subsize = get_subsize(bsize, PARTITION_SPLIT); |
+ // PARTITION_VERT |
+ if (partition_vert_allowed && do_rect) { |
+ subsize = get_subsize(bsize, PARTITION_VERT); |
- for (i = 0; i < 4 && sum_rd < best_rd; ++i) { |
- int x_idx = (i & 1) * (ms >> 1); |
- int y_idx = (i >> 1) * (ms >> 1); |
- int r = 0; |
- int64_t d = 0; |
+ *(get_sb_index(xd, subsize)) = 0; |
+ pick_sb_modes(cpi, mi_row, mi_col, &sum_rate, &sum_dist, subsize, |
+ get_block_context(x, subsize), best_rd); |
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
+ if (sum_rd < best_rd && mi_col + (ms >> 1) < cm->mi_cols) { |
+ update_state(cpi, get_block_context(x, subsize), subsize, 0); |
+ encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); |
- if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) |
- continue; |
- |
- *(get_sb_index(xd, subsize)) = i; |
- rd_pick_partition(cpi, tp, mi_row + y_idx, mi_col + x_idx, subsize, &r, |
- &d, i != 3, best_rd - sum_rd); |
- |
- if (r == INT_MAX) { |
- r4 = INT_MAX; |
- sum_rd = INT64_MAX; |
- } else { |
- r4 += r; |
- d4 += d; |
- sum_rd = RDCOST(x->rdmult, x->rddiv, r4, d4); |
- } |
+ *(get_sb_index(xd, subsize)) = 1; |
+ pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), &this_rate, |
+ &this_dist, subsize, get_block_context(x, subsize), |
+ best_rd - sum_rd); |
+ if (this_rate == INT_MAX) { |
+ sum_rd = INT64_MAX; |
+ } else { |
+ sum_rate += this_rate; |
+ sum_dist += this_dist; |
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
} |
+ } |
+ if (sum_rd < best_rd) { |
set_partition_seg_context(cm, xd, mi_row, mi_col); |
pl = partition_plane_context(xd, bsize); |
- if (r4 != INT_MAX && i == 4) { |
- r4 += x->partition_cost[pl][PARTITION_SPLIT]; |
- if (RDCOST(x->rdmult, x->rddiv, r4, d4) < |
- RDCOST(x->rdmult, x->rddiv, srate, sdist)) { |
- srate = r4; |
- sdist = d4; |
- larger_is_better = 0; |
- *(get_sb_partitioning(x, bsize)) = subsize; |
- best_rd = MIN(best_rd, RDCOST(x->rdmult, x->rddiv, r4, d4)); |
- } |
+ sum_rate += x->partition_cost[pl][PARTITION_VERT]; |
+ sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
+ if (sum_rd < best_rd) { |
+ best_rate = sum_rate; |
+ best_dist = sum_dist; |
+ best_rd = sum_rd; |
+ *(get_sb_partitioning(x, bsize)) = subsize; |
} |
- restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
} |
- |
- if (!cpi->sf.use_square_partition_only && |
- (!cpi->sf.less_rectangular_check ||!larger_is_better)) { |
- // PARTITION_HORZ |
- if (bsize >= BLOCK_SIZE_SB8X8 && mi_col + (ms >> 1) < cm->mi_cols) { |
- int r2, r = 0; |
- int64_t d2, d = 0, h_rd; |
- subsize = get_subsize(bsize, PARTITION_HORZ); |
- *(get_sb_index(xd, subsize)) = 0; |
- pick_sb_modes(cpi, mi_row, mi_col, &r2, &d2, subsize, |
- get_block_context(x, subsize), best_rd); |
- h_rd = RDCOST(x->rdmult, x->rddiv, r2, d2); |
- |
- if (r2 != INT_MAX && h_rd < best_rd && |
- mi_row + (ms >> 1) < cm->mi_rows) { |
- 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 + (ms >> 1), mi_col, &r, &d, subsize, |
- get_block_context(x, subsize), best_rd - h_rd); |
- if (r == INT_MAX) { |
- r2 = INT_MAX; |
- } else { |
- r2 += r; |
- d2 += d; |
- } |
- } |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
- if (r2 < INT_MAX) |
- r2 += x->partition_cost[pl][PARTITION_HORZ]; |
- if (r2 != INT_MAX && RDCOST(x->rdmult, x->rddiv, r2, d2) |
- < RDCOST(x->rdmult, x->rddiv, srate, sdist)) { |
- best_rd = MIN(best_rd, RDCOST(x->rdmult, x->rddiv, r2, d2)); |
- srate = r2; |
- sdist = d2; |
- *(get_sb_partitioning(x, bsize)) = subsize; |
- } |
- restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
- } |
- |
- // PARTITION_VERT |
- if (bsize >= BLOCK_SIZE_SB8X8 && mi_row + (ms >> 1) < cm->mi_rows) { |
- int r2; |
- int64_t d2, v_rd; |
- subsize = get_subsize(bsize, PARTITION_VERT); |
- *(get_sb_index(xd, subsize)) = 0; |
- pick_sb_modes(cpi, mi_row, mi_col, &r2, &d2, subsize, |
- get_block_context(x, subsize), best_rd); |
- v_rd = RDCOST(x->rdmult, x->rddiv, r2, d2); |
- if (r2 != INT_MAX && v_rd < best_rd && |
- mi_col + (ms >> 1) < cm->mi_cols) { |
- int r = 0; |
- int64_t d = 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 + (ms >> 1), &r, &d, subsize, |
- get_block_context(x, subsize), best_rd - v_rd); |
- if (r == INT_MAX) { |
- r2 = INT_MAX; |
- } else { |
- r2 += r; |
- d2 += d; |
- } |
- } |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
- if (r2 < INT_MAX) |
- r2 += x->partition_cost[pl][PARTITION_VERT]; |
- if (r2 != INT_MAX && |
- RDCOST(x->rdmult, x->rddiv, r2, d2) |
- < RDCOST(x->rdmult, x->rddiv, srate, sdist)) { |
- srate = r2; |
- sdist = d2; |
- *(get_sb_partitioning(x, bsize)) = subsize; |
- } |
- restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
- } |
- } |
+ restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
} |
- *rate = srate; |
- *dist = sdist; |
- restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
- if (srate < INT_MAX && sdist < INT_MAX && do_recon) |
- encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_SIZE_SB64X64, bsize); |
+ *rate = best_rate; |
+ *dist = best_dist; |
- if (bsize == BLOCK_SIZE_SB64X64) { |
+ if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) |
+ encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); |
+ if (bsize == BLOCK_64X64) { |
assert(tp_orig < *tp); |
- assert(srate < INT_MAX); |
- assert(sdist < INT_MAX); |
+ assert(best_rate < INT_MAX); |
+ assert(best_dist < INT_MAX); |
} else { |
assert(tp_orig == *tp); |
} |
} |
// 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; |
- int bsl = b_width_log2(BLOCK_SIZE_SB64X64), bs = 1 << bsl; |
+ int bsl = b_width_log2(BLOCK_64X64), bs = 1 << bsl; |
int ms = bs / 2; |
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; |
PARTITION_CONTEXT sl[8], sa[8]; |
@@ -1817,7 +1898,7 @@ |
int r; |
int64_t d; |
- save_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_SIZE_SB64X64); |
+ save_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_64X64); |
// Default is non mask (all reference frames allowed. |
cpi->ref_frame_mask = 0; |
@@ -1826,33 +1907,17 @@ |
if ((mi_row + (ms >> 1) < cm->mi_rows) && |
(mi_col + (ms >> 1) < cm->mi_cols)) { |
cpi->set_ref_frame_mask = 1; |
- pick_sb_modes(cpi, mi_row, mi_col, &r, &d, BLOCK_SIZE_SB64X64, |
- get_block_context(x, BLOCK_SIZE_SB64X64), INT64_MAX); |
+ pick_sb_modes(cpi, mi_row, mi_col, &r, &d, BLOCK_64X64, |
+ get_block_context(x, BLOCK_64X64), INT64_MAX); |
set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, BLOCK_SIZE_SB64X64); |
+ pl = partition_plane_context(xd, BLOCK_64X64); |
r += x->partition_cost[pl][PARTITION_NONE]; |
- *(get_sb_partitioning(x, BLOCK_SIZE_SB64X64)) = BLOCK_SIZE_SB64X64; |
+ *(get_sb_partitioning(x, BLOCK_64X64)) = BLOCK_64X64; |
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); |
- } |
- */ |
+ restore_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_64X64); |
} |
static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, |
@@ -1877,10 +1942,8 @@ |
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,14 +1951,15 @@ |
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_offsets(cpi, mi_row, mi_col, BLOCK_64X64); |
set_partitioning(cpi, m, cpi->sf.always_this_block_size); |
- rd_use_partition(cpi, m, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64, |
+ rd_use_partition(cpi, m, tp, mi_row, mi_col, BLOCK_64X64, |
&dummy_rate, &dummy_dist, 1); |
} else if (cpi->sf.partition_by_variance) { |
choose_partitioning(cpi, cm->mi, mi_row, mi_col); |
- rd_use_partition(cpi, m, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64, |
+ rd_use_partition(cpi, m, tp, mi_row, mi_col, BLOCK_64X64, |
&dummy_rate, &dummy_dist, 1); |
} else { |
if ((cpi->common.current_video_frame |
@@ -1904,16 +1968,30 @@ |
|| cpi->common.show_frame == 0 |
|| cpi->common.frame_type == KEY_FRAME |
|| cpi->is_src_frame_alt_ref) { |
- rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64, |
+ // If required set upper and lower partition size limits |
+ if (cpi->sf.auto_min_max_partition_size) { |
+ set_offsets(cpi, mi_row, mi_col, BLOCK_64X64); |
+ 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_64X64, |
&dummy_rate, &dummy_dist, 1, INT64_MAX); |
} else { |
copy_partitioning(cpi, m, p); |
- rd_use_partition(cpi, m, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64, |
+ rd_use_partition(cpi, m, tp, mi_row, mi_col, BLOCK_64X64, |
&dummy_rate, &dummy_dist, 1); |
} |
} |
} else { |
- rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64, |
+ // If required set upper and lower partition size limits |
+ if (cpi->sf.auto_min_max_partition_size) { |
+ set_offsets(cpi, mi_row, mi_col, BLOCK_64X64); |
+ 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_64X64, |
&dummy_rate, &dummy_dist, 1, INT64_MAX); |
} |
} |
@@ -1974,7 +2052,7 @@ |
cpi->mb.e_mbd.inv_txm4x4_1_add = vp9_short_iwalsh4x4_1_add; |
cpi->mb.e_mbd.inv_txm4x4_add = vp9_short_iwalsh4x4_add; |
cpi->mb.optimize = 0; |
- cpi->mb.e_mbd.lf.filter_level = 0; |
+ cpi->common.lf.filter_level = 0; |
cpi->zbin_mode_boost_enabled = 0; |
cpi->common.tx_mode = ONLY_4X4; |
} else { |
@@ -2046,7 +2124,7 @@ |
build_activity_map(cpi); |
} |
- // re-initencode frame context. |
+ // Re-initialize encode frame context. |
init_encode_frame_mb_context(cpi); |
vp9_zero(cpi->rd_comp_pred_diff); |
@@ -2086,7 +2164,7 @@ |
} |
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) { |
@@ -2115,10 +2193,9 @@ |
} |
static int check_dual_ref_flags(VP9_COMP *cpi) { |
- MACROBLOCKD *xd = &cpi->mb.e_mbd; |
- int ref_flags = cpi->ref_frame_flags; |
+ const int ref_flags = cpi->ref_frame_flags; |
- if (vp9_segfeature_active(&xd->seg, 1, SEG_LVL_REF_FRAME)) { |
+ if (vp9_segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) { |
return 0; |
} else { |
return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG) |
@@ -2131,7 +2208,7 @@ |
for (y = 0; y < ymbs; y++) { |
for (x = 0; x < xmbs; x++) { |
- if (!mi[y * mis + x].mbmi.mb_skip_coeff) |
+ if (!mi[y * mis + x].mbmi.skip_coeff) |
return 0; |
} |
} |
@@ -2150,74 +2227,66 @@ |
} |
static void reset_skip_txfm_size_b(VP9_COMP *cpi, MODE_INFO *mi, int mis, |
- TX_SIZE txfm_max, int bw, int bh, int mi_row, |
- int mi_col, BLOCK_SIZE_TYPE bsize) { |
- VP9_COMMON * const cm = &cpi->common; |
- MB_MODE_INFO * const mbmi = &mi->mbmi; |
+ TX_SIZE max_tx_size, int bw, int bh, |
+ int mi_row, int mi_col, BLOCK_SIZE bsize) { |
+ VP9_COMMON *const cm = &cpi->common; |
+ MB_MODE_INFO *const mbmi = &mi->mbmi; |
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
return; |
- if (mbmi->txfm_size > txfm_max) { |
+ if (mbmi->txfm_size > max_tx_size) { |
MACROBLOCK * const x = &cpi->mb; |
MACROBLOCKD * const xd = &x->e_mbd; |
const int ymbs = MIN(bh, cm->mi_rows - mi_row); |
const int xmbs = MIN(bw, cm->mi_cols - mi_col); |
xd->mode_info_context = mi; |
- assert(vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP) || |
+ assert(vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) || |
get_skip_flag(mi, mis, ymbs, xmbs)); |
- set_txfm_flag(mi, mis, ymbs, xmbs, txfm_max); |
+ set_txfm_flag(mi, mis, ymbs, xmbs, max_tx_size); |
} |
} |
static void reset_skip_txfm_size_sb(VP9_COMP *cpi, MODE_INFO *mi, |
- TX_SIZE txfm_max, int mi_row, int mi_col, |
- BLOCK_SIZE_TYPE bsize) { |
- VP9_COMMON * const cm = &cpi->common; |
+ TX_SIZE max_tx_size, int mi_row, int mi_col, |
+ BLOCK_SIZE bsize) { |
+ const VP9_COMMON *const cm = &cpi->common; |
const int mis = cm->mode_info_stride; |
- int bwl, bhl; |
- const int bsl = mi_width_log2(bsize), bs = 1 << (bsl - 1); |
+ int bw, bh; |
+ const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2; |
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
return; |
- bwl = mi_width_log2(mi->mbmi.sb_type); |
- bhl = mi_height_log2(mi->mbmi.sb_type); |
+ bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type]; |
+ bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type]; |
- if (bwl == bsl && bhl == bsl) { |
- reset_skip_txfm_size_b(cpi, mi, mis, txfm_max, 1 << bsl, 1 << bsl, mi_row, |
+ if (bw == bs && bh == bs) { |
+ reset_skip_txfm_size_b(cpi, mi, mis, max_tx_size, bs, bs, mi_row, |
mi_col, bsize); |
- } else if (bwl == bsl && bhl < bsl) { |
- reset_skip_txfm_size_b(cpi, mi, mis, txfm_max, 1 << bsl, bs, mi_row, mi_col, |
+ } else if (bw == bs && bh < bs) { |
+ reset_skip_txfm_size_b(cpi, mi, mis, max_tx_size, bs, hbs, mi_row, mi_col, |
bsize); |
- reset_skip_txfm_size_b(cpi, mi + bs * mis, mis, txfm_max, 1 << bsl, bs, |
- mi_row + bs, mi_col, bsize); |
- } else if (bwl < bsl && bhl == bsl) { |
- reset_skip_txfm_size_b(cpi, mi, mis, txfm_max, bs, 1 << bsl, mi_row, mi_col, |
+ reset_skip_txfm_size_b(cpi, mi + hbs * mis, mis, max_tx_size, bs, hbs, |
+ mi_row + hbs, mi_col, bsize); |
+ } else if (bw < bs && bh == bs) { |
+ reset_skip_txfm_size_b(cpi, mi, mis, max_tx_size, hbs, bs, mi_row, mi_col, |
bsize); |
- reset_skip_txfm_size_b(cpi, mi + bs, mis, txfm_max, bs, 1 << bsl, mi_row, |
- mi_col + bs, bsize); |
+ reset_skip_txfm_size_b(cpi, mi + hbs, mis, max_tx_size, hbs, bs, mi_row, |
+ mi_col + hbs, bsize); |
} else { |
- BLOCK_SIZE_TYPE subsize; |
+ const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize]; |
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; |
- } else { |
- assert(bsize == BLOCK_SIZE_MB16X16); |
- subsize = BLOCK_SIZE_SB8X8; |
- } |
+ assert(bw < bs && bh < bs); |
for (n = 0; n < 4; n++) { |
- const int y_idx = n >> 1, x_idx = n & 0x01; |
+ const int mi_dc = hbs * (n & 1); |
+ const int mi_dr = hbs * (n >> 1); |
- reset_skip_txfm_size_sb(cpi, mi + y_idx * bs * mis + x_idx * bs, txfm_max, |
- mi_row + y_idx * bs, mi_col + x_idx * bs, |
- subsize); |
+ reset_skip_txfm_size_sb(cpi, &mi[mi_dr * mis + mi_dc], max_tx_size, |
+ mi_row + mi_dr, mi_col + mi_dc, subsize); |
} |
} |
} |
@@ -2230,10 +2299,8 @@ |
for (mi_row = 0; mi_row < cm->mi_rows; mi_row += 8, mi_ptr += 8 * mis) { |
mi = mi_ptr; |
- for (mi_col = 0; mi_col < cm->mi_cols; mi_col += 8, mi += 8) { |
- reset_skip_txfm_size_sb(cpi, mi, txfm_max, mi_row, mi_col, |
- BLOCK_SIZE_SB64X64); |
- } |
+ for (mi_col = 0; mi_col < cm->mi_cols; mi_col += 8, mi += 8) |
+ reset_skip_txfm_size_sb(cpi, mi, txfm_max, mi_row, mi_col, BLOCK_64X64); |
} |
} |
@@ -2267,7 +2334,7 @@ |
} 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; |
@@ -2285,7 +2352,7 @@ |
// decoder such that we allow compound where one of the 3 buffers has a |
// different sign bias and that buffer is then the fixed ref. However, this |
// requires further work in the rd loop. For now the only supported encoder |
- // side behaviour is where the ALT ref buffer has opposite sign bias to |
+ // side behavior is where the ALT ref buffer has opposite sign bias to |
// the other two. |
if ((cm->ref_frame_sign_bias[ALTREF_FRAME] |
== cm->ref_frame_sign_bias[GOLDEN_FRAME]) |
@@ -2338,27 +2405,26 @@ |
cpi->rd_filter_threshes[frame_type][1] > |
cpi->rd_filter_threshes[frame_type][2] && |
cpi->rd_filter_threshes[frame_type][1] > |
- cpi->rd_filter_threshes[frame_type][VP9_SWITCHABLE_FILTERS]) { |
- filter_type = vp9_switchable_interp[1]; |
+ cpi->rd_filter_threshes[frame_type][SWITCHABLE_FILTERS]) { |
+ filter_type = EIGHTTAP_SMOOTH; |
} else if (cpi->rd_filter_threshes[frame_type][2] > |
cpi->rd_filter_threshes[frame_type][0] && |
cpi->rd_filter_threshes[frame_type][2] > |
- cpi->rd_filter_threshes[frame_type][VP9_SWITCHABLE_FILTERS]) { |
- filter_type = vp9_switchable_interp[2]; |
+ cpi->rd_filter_threshes[frame_type][SWITCHABLE_FILTERS]) { |
+ filter_type = EIGHTTAP_SHARP; |
} else if (cpi->rd_filter_threshes[frame_type][0] > |
- cpi->rd_filter_threshes[frame_type][VP9_SWITCHABLE_FILTERS]) { |
- filter_type = vp9_switchable_interp[0]; |
+ cpi->rd_filter_threshes[frame_type][SWITCHABLE_FILTERS]) { |
+ filter_type = EIGHTTAP; |
} else { |
filter_type = SWITCHABLE; |
} |
- /* transform size (4x4, 8x8, 16x16 or select-per-mb) selection */ |
- |
cpi->mb.e_mbd.lossless = 0; |
if (cpi->oxcf.lossless) { |
cpi->mb.e_mbd.lossless = 1; |
} |
+ /* transform size selection (4x4, 8x8, 16x16 or select-per-mb) */ |
select_tx_mode(cpi); |
cpi->common.comp_pred_mode = pred_type; |
cpi->common.mcomp_filter_type = filter_type; |
@@ -2370,18 +2436,18 @@ |
cpi->rd_prediction_type_threshes[frame_type][i] >>= 1; |
} |
- for (i = 0; i <= VP9_SWITCHABLE_FILTERS; i++) { |
+ for (i = 0; i <= SWITCHABLE_FILTERS; i++) { |
const int64_t diff = cpi->rd_filter_diff[i] / cpi->common.MBs; |
cpi->rd_filter_threshes[frame_type][i] = |
(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; |
@@ -2446,29 +2512,22 @@ |
} |
-static void sum_intra_stats(VP9_COMP *cpi, MACROBLOCK *x) { |
- const MACROBLOCKD *xd = &x->e_mbd; |
- const MB_PREDICTION_MODE m = xd->mode_info_context->mbmi.mode; |
- const MB_PREDICTION_MODE uvm = xd->mode_info_context->mbmi.uv_mode; |
+static void sum_intra_stats(VP9_COMP *cpi, const MODE_INFO *mi) { |
+ const MB_PREDICTION_MODE y_mode = mi->mbmi.mode; |
+ const MB_PREDICTION_MODE uv_mode = mi->mbmi.uv_mode; |
+ const BLOCK_SIZE bsize = mi->mbmi.sb_type; |
- ++cpi->y_uv_mode_count[m][uvm]; |
- if (xd->mode_info_context->mbmi.sb_type >= BLOCK_SIZE_SB8X8) { |
- const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type; |
- const int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize); |
- const int bsl = MIN(bwl, bhl); |
- ++cpi->y_mode_count[MIN(bsl, 3)][m]; |
+ ++cpi->y_uv_mode_count[y_mode][uv_mode]; |
+ |
+ if (bsize < BLOCK_8X8) { |
+ int idx, idy; |
+ const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; |
+ const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; |
+ for (idy = 0; idy < 2; idy += num_4x4_blocks_high) |
+ for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) |
+ ++cpi->y_mode_count[0][mi->bmi[idy * 2 + idx].as_mode]; |
} else { |
- int idx, idy; |
- int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[ |
- xd->mode_info_context->mbmi.sb_type]; |
- int num_4x4_blocks_high = num_4x4_blocks_high_lookup[ |
- xd->mode_info_context->mbmi.sb_type]; |
- for (idy = 0; idy < 2; idy += num_4x4_blocks_high) { |
- for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) { |
- int m = xd->mode_info_context->bmi[idy * 2 + idx].as_mode; |
- ++cpi->y_mode_count[0][m]; |
- } |
- } |
+ ++cpi->y_mode_count[size_group_lookup[bsize]][y_mode]; |
} |
} |
@@ -2494,7 +2553,7 @@ |
} |
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, |
- int mi_row, int mi_col, BLOCK_SIZE_TYPE bsize) { |
+ int mi_row, int mi_col, BLOCK_SIZE bsize) { |
VP9_COMMON * const cm = &cpi->common; |
MACROBLOCK * const x = &cpi->mb; |
MACROBLOCKD * const xd = &x->e_mbd; |
@@ -2504,7 +2563,7 @@ |
const int mis = cm->mode_info_stride; |
const int mi_width = num_8x8_blocks_wide_lookup[bsize]; |
const int mi_height = num_8x8_blocks_high_lookup[bsize]; |
- x->rd_search = 0; |
+ x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct; |
x->skip_encode = (!output_enabled && cpi->sf.skip_encode_frame && |
xd->q_index < QIDX_SKIP_THRESH); |
if (x->skip_encode) |
@@ -2527,13 +2586,13 @@ |
// 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; |
else |
cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST; |
- } else if (mbmi->sb_type < BLOCK_SIZE_SB8X8) { |
+ } else if (mbmi->sb_type < BLOCK_8X8) { |
cpi->zbin_mode_boost = SPLIT_MV_ZBIN_BOOST; |
} else { |
cpi->zbin_mode_boost = MV_ZBIN_BOOST; |
@@ -2546,13 +2605,11 @@ |
vp9_update_zbin_extra(cpi, x); |
} |
- if (mbmi->ref_frame[0] == INTRA_FRAME) { |
- vp9_encode_intra_block_y( |
- cm, x, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); |
- vp9_encode_intra_block_uv( |
- cm, x, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); |
+ if (!is_inter_block(mbmi)) { |
+ vp9_encode_intra_block_y(x, MAX(bsize, BLOCK_8X8)); |
+ vp9_encode_intra_block_uv(x, MAX(bsize, BLOCK_8X8)); |
if (output_enabled) |
- sum_intra_stats(cpi, x); |
+ sum_intra_stats(cpi, mi); |
} else { |
int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame[0])]; |
YV12_BUFFER_CONFIG *ref_fb = &cm->yv12_fb[idx]; |
@@ -2570,53 +2627,48 @@ |
&xd->scale_factor[1]); |
- vp9_build_inter_predictors_sb( |
- xd, mi_row, mi_col, |
- bsize < BLOCK_SIZE_SB8X8 ? BLOCK_SIZE_SB8X8 : bsize); |
+ vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8)); |
} |
- if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) { |
- vp9_tokenize_sb(cpi, t, !output_enabled, |
- (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); |
+ if (!is_inter_block(mbmi)) { |
+ vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8)); |
} else if (!x->skip) { |
- vp9_encode_sb(cm, x, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); |
- vp9_tokenize_sb(cpi, t, !output_enabled, |
- (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); |
+ vp9_encode_sb(x, MAX(bsize, BLOCK_8X8)); |
+ vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8)); |
} else { |
- int mb_skip_context = xd->left_available ? (mi - 1)->mbmi.mb_skip_coeff : 0; |
- mb_skip_context += (mi - mis)->mbmi.mb_skip_coeff; |
+ int mb_skip_context = xd->left_available ? (mi - 1)->mbmi.skip_coeff : 0; |
+ mb_skip_context += (mi - mis)->mbmi.skip_coeff; |
- mbmi->mb_skip_coeff = 1; |
+ mbmi->skip_coeff = 1; |
if (output_enabled) |
cm->counts.mbskip[mb_skip_context][1]++; |
- vp9_reset_sb_tokens_context( |
- xd, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); |
+ reset_skip_context(xd, MAX(bsize, BLOCK_8X8)); |
} |
// copy skip flag on all mb_mode_info contexts in this SB |
// if this was a skip at this txfm size |
- vp9_set_pred_flag_mbskip(cm, bsize, mi_row, mi_col, mi->mbmi.mb_skip_coeff); |
+ vp9_set_pred_flag_mbskip(cm, bsize, mi_row, mi_col, mi->mbmi.skip_coeff); |
if (output_enabled) { |
if (cm->tx_mode == TX_MODE_SELECT && |
- mbmi->sb_type >= BLOCK_SIZE_SB8X8 && |
- !(mbmi->ref_frame[0] != INTRA_FRAME && |
- (mbmi->mb_skip_coeff || |
- vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP)))) { |
+ mbmi->sb_type >= BLOCK_8X8 && |
+ !(is_inter_block(mbmi) && |
+ (mbmi->skip_coeff || |
+ vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)))) { |
const uint8_t context = vp9_get_pred_context_tx_size(xd); |
update_tx_counts(bsize, context, mbmi->txfm_size, &cm->counts.tx); |
} else { |
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; |