Index: source/libvpx/vp9/encoder/vp9_encodeframe.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_encodeframe.c (revision 232232) |
+++ source/libvpx/vp9/encoder/vp9_encodeframe.c (working copy) |
@@ -22,6 +22,7 @@ |
#include "vp9/common/vp9_entropymode.h" |
#include "vp9/common/vp9_extend.h" |
#include "vp9/common/vp9_findnearmv.h" |
+#include "vp9/common/vp9_idct.h" |
#include "vp9/common/vp9_mvref_common.h" |
#include "vp9/common/vp9_pred_common.h" |
#include "vp9/common/vp9_quant_common.h" |
@@ -29,7 +30,6 @@ |
#include "vp9/common/vp9_reconinter.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" |
@@ -37,24 +37,44 @@ |
#include "vp9/encoder/vp9_onyx_int.h" |
#include "vp9/encoder/vp9_rdopt.h" |
#include "vp9/encoder/vp9_segmentation.h" |
+#include "vp9/common/vp9_systemdependent.h" |
#include "vp9/encoder/vp9_tokenize.h" |
+#include "vp9/encoder/vp9_vaq.h" |
+ |
#define DBG_PRNT_SEGMAP 0 |
-static const TX_SIZE tx_mode_to_biggest_tx_size[TX_MODES] = { |
- TX_4X4, // ONLY_4X4 |
- TX_8X8, // ONLY_8X8 |
- TX_16X16, // ONLY_16X16 |
- TX_32X32, // ONLY_32X32 |
- TX_32X32, // TX_MODE_SELECT |
-}; |
- |
// #define ENC_DEBUG |
#ifdef ENC_DEBUG |
int enc_debug = 0; |
#endif |
+static INLINE uint8_t *get_sb_index(MACROBLOCKD *xd, BLOCK_SIZE subsize) { |
+ switch (subsize) { |
+ case BLOCK_64X64: |
+ case BLOCK_64X32: |
+ case BLOCK_32X64: |
+ case BLOCK_32X32: |
+ return &xd->sb_index; |
+ case BLOCK_32X16: |
+ case BLOCK_16X32: |
+ case BLOCK_16X16: |
+ return &xd->mb_index; |
+ case BLOCK_16X8: |
+ case BLOCK_8X16: |
+ case BLOCK_8X8: |
+ return &xd->b_index; |
+ case BLOCK_8X4: |
+ case BLOCK_4X8: |
+ case BLOCK_4X4: |
+ return &xd->ab_index; |
+ default: |
+ assert(0); |
+ return NULL; |
+ } |
+} |
+ |
static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, |
int mi_row, int mi_col, BLOCK_SIZE bsize); |
@@ -122,7 +142,6 @@ |
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 |
@@ -173,8 +192,9 @@ |
tmp = sortlist[j - 1]; |
sortlist[j - 1] = sortlist[j]; |
sortlist[j] = tmp; |
- } else |
- break; |
+ } else { |
+ break; |
+ } |
} |
} |
@@ -246,13 +266,11 @@ |
#if OUTPUT_NORM_ACT_STATS |
fprintf(f, "\n"); |
#endif |
- |
} |
#if OUTPUT_NORM_ACT_STATS |
fclose(f); |
#endif |
- |
} |
#endif // USE_ACT_INDEX |
@@ -264,7 +282,7 @@ |
VP9_COMMON * const cm = &cpi->common; |
#if ALT_ACT_MEASURE |
- YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx]; |
+ YV12_BUFFER_CONFIG *new_yv12 = get_frame_new_buffer(cm); |
int recon_yoffset; |
int recon_y_stride = new_yv12->y_stride; |
#endif |
@@ -317,7 +335,6 @@ |
// Calculate an activity index number of each mb |
calc_activity_index(cpi, x); |
#endif |
- |
} |
// Macroblock activity masking |
@@ -351,8 +368,8 @@ |
MACROBLOCK *const x = &cpi->mb; |
MACROBLOCKD *const xd = &x->e_mbd; |
MODE_INFO *mi = &ctx->mic; |
- MB_MODE_INFO * const mbmi = &xd->this_mi->mbmi; |
- MODE_INFO *mi_addr = xd->this_mi; |
+ MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; |
+ MODE_INFO *mi_addr = xd->mi_8x8[0]; |
int mb_mode_index = ctx->best_mode_index; |
const int mis = cm->mode_info_stride; |
@@ -360,7 +377,6 @@ |
const int mi_height = num_8x8_blocks_high_lookup[bsize]; |
assert(mi->mbmi.mode < MB_MODE_COUNT); |
- assert(mb_mode_index < MAX_MODES); |
assert(mi->mbmi.ref_frame[0] < MAX_REF_FRAMES); |
assert(mi->mbmi.ref_frame[1] < MAX_REF_FRAMES); |
assert(mi->mbmi.sb_type == bsize); |
@@ -375,6 +391,10 @@ |
&& (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) |
xd->mi_8x8[x_idx + y * mis] = mi_addr; |
+ if (cpi->sf.variance_adaptive_quantization) { |
+ vp9_mb_init_quantizer(cpi, x); |
+ } |
+ |
// FIXME(rbultje) I'm pretty sure this should go to the end of this block |
// (i.e. after the output_enabled) |
if (bsize < BLOCK_32X32) { |
@@ -384,12 +404,14 @@ |
} |
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; |
} |
x->skip = ctx->skip; |
+ vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk, |
+ sizeof(uint8_t) * ctx->num_4x4_blk); |
+ |
if (!output_enabled) |
return; |
@@ -398,15 +420,7 @@ |
cpi->rd_tx_select_diff[i] += ctx->tx_rd_diff[i]; |
} |
- 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++) |
- // { |
- // xd->block[i].bmi.as_mode = |
- // xd->mode_info_context->bmi[i].as_mode; |
- // assert(xd->mode_info_context->bmi[i].as_mode < MB_MODE_COUNT); |
- // } |
+ if (frame_is_intra_only(cm)) { |
#if CONFIG_INTERNAL_STATS |
static const int kf_mode_index[] = { |
THR_DC /*DC_PRED*/, |
@@ -419,7 +433,6 @@ |
THR_D207_PRED /*D207_PRED*/, |
THR_D63_PRED /*D63_PRED*/, |
THR_TM /*TM_PRED*/, |
- THR_B_PRED /*I4X4_PRED*/, |
}; |
cpi->mode_chosen_counts[kf_mode_index[mi->mbmi.mode]]++; |
#endif |
@@ -428,18 +441,19 @@ |
cpi->mode_chosen_counts[mb_mode_index]++; |
if (is_inter_block(mbmi) |
&& (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV)) { |
- int_mv best_mv, best_second_mv; |
+ int_mv best_mv[2]; |
const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0]; |
const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1]; |
- best_mv.as_int = ctx->best_ref_mv.as_int; |
- best_second_mv.as_int = ctx->second_best_ref_mv.as_int; |
+ best_mv[0].as_int = ctx->best_ref_mv.as_int; |
+ best_mv[1].as_int = ctx->second_best_ref_mv.as_int; |
if (mbmi->mode == NEWMV) { |
- best_mv.as_int = mbmi->ref_mvs[rf1][0].as_int; |
- best_second_mv.as_int = mbmi->ref_mvs[rf2][0].as_int; |
+ best_mv[0].as_int = mbmi->ref_mvs[rf1][0].as_int; |
+ if (rf2 > 0) |
+ best_mv[1].as_int = mbmi->ref_mvs[rf2][0].as_int; |
} |
- mbmi->best_mv.as_int = best_mv.as_int; |
- mbmi->best_second_mv.as_int = best_second_mv.as_int; |
- vp9_update_nmv_count(cpi, x, &best_mv, &best_second_mv); |
+ mbmi->best_mv[0].as_int = best_mv[0].as_int; |
+ mbmi->best_mv[1].as_int = best_mv[1].as_int; |
+ vp9_update_mv_count(cpi, x, best_mv); |
} |
if (cm->mcomp_filter_type == SWITCHABLE && is_inter_mode(mbmi->mode)) { |
@@ -451,28 +465,27 @@ |
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 <= SWITCHABLE_FILTERS; i++) |
+ for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) |
cpi->rd_filter_diff[i] += ctx->best_filter_diff[i]; |
} |
} |
void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src, |
- int mb_row, int mb_col) { |
- uint8_t *buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer, src |
- ->alpha_buffer}; |
- int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride, src |
- ->alpha_stride}; |
+ int mi_row, int mi_col) { |
+ uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer, |
+ src->alpha_buffer}; |
+ const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride, |
+ src->alpha_stride}; |
int i; |
- for (i = 0; i < MAX_MB_PLANE; i++) { |
- setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mb_row, mb_col, |
+ for (i = 0; i < MAX_MB_PLANE; i++) |
+ setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col, |
NULL, x->e_mbd.plane[i].subsampling_x, |
x->e_mbd.plane[i].subsampling_y); |
- } |
} |
-static void set_offsets(VP9_COMP *cpi, int mi_row, int mi_col, |
- BLOCK_SIZE bsize) { |
+static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, |
+ int mi_row, int mi_col, BLOCK_SIZE bsize) { |
MACROBLOCK *const x = &cpi->mb; |
VP9_COMMON *const cm = &cpi->common; |
MACROBLOCKD *const xd = &x->e_mbd; |
@@ -486,16 +499,12 @@ |
const int idx_map = mb_row * cm->mb_cols + mb_col; |
const struct segmentation *const seg = &cm->seg; |
- set_skip_context(cm, xd, mi_row, mi_col); |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
+ set_skip_context(xd, cpi->above_context, cpi->left_context, mi_row, mi_col); |
// Activity map pointer |
x->mb_activity_ptr = &cpi->mb_activity_map[idx_map]; |
x->active_ptr = cpi->active_map + idx_map; |
- /* pointers to mode info contexts */ |
- x->partition_info = x->pi + idx_str; |
- |
xd->mi_8x8 = cm->mi_grid_visible + idx_str; |
xd->prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; |
@@ -503,10 +512,9 @@ |
// cannot be used. |
xd->last_mi = cm->prev_mi ? xd->prev_mi_8x8[0] : NULL; |
- xd->this_mi = |
xd->mi_8x8[0] = cm->mi + idx_str; |
- mbmi = &xd->this_mi->mbmi; |
+ mbmi = &xd->mi_8x8[0]->mbmi; |
// Set up destination pointers |
setup_dst_planes(xd, &cm->yv12_fb[dst_fb_idx], mi_row, mi_col); |
@@ -520,7 +528,8 @@ |
// 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))); |
- set_mi_row_col(cm, xd, mi_row, mi_height, mi_col, mi_width); |
+ set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, |
+ cm->mi_rows, cm->mi_cols); |
/* set up source buffers */ |
vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); |
@@ -531,10 +540,11 @@ |
/* segment ID */ |
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); |
- |
+ if (!cpi->sf.variance_adaptive_quantization) { |
+ 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 (seg->enabled && cpi->seg0_cnt > 0 |
@@ -546,9 +556,8 @@ |
const int x = mb_col & ~3; |
const int p16 = ((mb_row & 1) << 1) + (mb_col & 1); |
const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1); |
- const int tile_progress = cm->cur_tile_mi_col_start * cm->mb_rows >> 1; |
- const int mb_cols = (cm->cur_tile_mi_col_end - cm->cur_tile_mi_col_start) |
- >> 1; |
+ const int tile_progress = tile->mi_col_start * cm->mb_rows >> 1; |
+ const int mb_cols = (tile->mi_col_end - tile->mi_col_start) >> 1; |
cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress) |
<< 16) / cm->MBs; |
@@ -561,14 +570,20 @@ |
} |
} |
-static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col, |
+static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, |
+ int mi_row, int mi_col, |
int *totalrate, int64_t *totaldist, |
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; |
+ int orig_rdmult = x->rdmult; |
+ double rdmult_ratio; |
+ vp9_clear_system_state(); // __asm emms; |
+ rdmult_ratio = 1.0; // avoid uninitialized warnings |
+ |
// Use the lower precision, but faster, 32x32 fdct for mode selection. |
x->use_lp32x32fdct = 1; |
@@ -582,35 +597,66 @@ |
} |
} |
- set_offsets(cpi, mi_row, mi_col, bsize); |
- xd->this_mi->mbmi.sb_type = bsize; |
+ set_offsets(cpi, tile, mi_row, mi_col, bsize); |
+ xd->mi_8x8[0]->mbmi.sb_type = bsize; |
// Set to zero to make sure we do not use the previous encoded frame stats |
- xd->this_mi->mbmi.skip_coeff = 0; |
+ xd->mi_8x8[0]->mbmi.skip_coeff = 0; |
x->source_variance = get_sby_perpixel_variance(cpi, x, bsize); |
+ if (cpi->sf.variance_adaptive_quantization) { |
+ int energy; |
+ if (bsize <= BLOCK_16X16) { |
+ energy = x->mb_energy; |
+ } else { |
+ energy = vp9_block_energy(cpi, x, bsize); |
+ } |
+ |
+ xd->mi_8x8[0]->mbmi.segment_id = vp9_vaq_segment_id(energy); |
+ rdmult_ratio = vp9_vaq_rdmult_ratio(energy); |
+ vp9_mb_init_quantizer(cpi, x); |
+ } |
+ |
if (cpi->oxcf.tuning == VP8_TUNE_SSIM) |
vp9_activity_masking(cpi, x); |
+ if (cpi->sf.variance_adaptive_quantization) { |
+ vp9_clear_system_state(); // __asm emms; |
+ x->rdmult = round(x->rdmult * rdmult_ratio); |
+ } |
+ |
// Find best coding mode & reconstruct the MB so it is available |
// as a predictor for MBs that follow in the SB |
- if (cm->frame_type == KEY_FRAME) |
+ if (frame_is_intra_only(cm)) { |
vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx, |
best_rd); |
- else |
- vp9_rd_pick_inter_mode_sb(cpi, x, mi_row, mi_col, totalrate, totaldist, |
- bsize, ctx, best_rd); |
+ } else { |
+ if (bsize >= BLOCK_8X8) |
+ vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col, |
+ totalrate, totaldist, bsize, ctx, best_rd); |
+ else |
+ vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate, |
+ totaldist, bsize, ctx, best_rd); |
+ } |
+ |
+ if (cpi->sf.variance_adaptive_quantization) { |
+ x->rdmult = orig_rdmult; |
+ if (*totalrate != INT_MAX) { |
+ vp9_clear_system_state(); // __asm emms; |
+ *totalrate = round(*totalrate * rdmult_ratio); |
+ } |
+ } |
} |
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->this_mi; |
+ MODE_INFO *mi = xd->mi_8x8[0]; |
MB_MODE_INFO *const mbmi = &mi->mbmi; |
- if (cm->frame_type != KEY_FRAME) { |
+ if (!frame_is_intra_only(cm)) { |
const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id, |
SEG_LVL_REF_FRAME); |
@@ -644,45 +690,6 @@ |
} |
} |
-// TODO(jingning): the variables used here are little complicated. need further |
-// 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 bsize) { |
- MACROBLOCKD *const xd = &x->e_mbd; |
- |
- switch (bsize) { |
- case BLOCK_64X64: |
- return &x->sb64_context; |
- case BLOCK_64X32: |
- return &x->sb64x32_context[xd->sb_index]; |
- case BLOCK_32X64: |
- return &x->sb32x64_context[xd->sb_index]; |
- case BLOCK_32X32: |
- return &x->sb32_context[xd->sb_index]; |
- case BLOCK_32X16: |
- return &x->sb32x16_context[xd->sb_index][xd->mb_index]; |
- case BLOCK_16X32: |
- return &x->sb16x32_context[xd->sb_index][xd->mb_index]; |
- case BLOCK_16X16: |
- return &x->mb_context[xd->sb_index][xd->mb_index]; |
- case BLOCK_16X8: |
- return &x->sb16x8_context[xd->sb_index][xd->mb_index][xd->b_index]; |
- case BLOCK_8X16: |
- return &x->sb8x16_context[xd->sb_index][xd->mb_index][xd->b_index]; |
- case BLOCK_8X8: |
- return &x->sb8x8_context[xd->sb_index][xd->mb_index][xd->b_index]; |
- case BLOCK_8X4: |
- return &x->sb8x4_context[xd->sb_index][xd->mb_index][xd->b_index]; |
- case BLOCK_4X8: |
- return &x->sb4x8_context[xd->sb_index][xd->mb_index][xd->b_index]; |
- case BLOCK_4X4: |
- return &x->ab4x4_context[xd->sb_index][xd->mb_index][xd->b_index]; |
- default: |
- assert(0); |
- return NULL ; |
- } |
-} |
- |
static BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) { |
MACROBLOCKD *const xd = &x->e_mbd; |
switch (bsize) { |
@@ -696,7 +703,7 @@ |
return &x->b_partitioning[xd->sb_index][xd->mb_index][xd->b_index]; |
default: |
assert(0); |
- return NULL ; |
+ return NULL; |
} |
} |
@@ -705,7 +712,6 @@ |
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], |
PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8], |
BLOCK_SIZE bsize) { |
- VP9_COMMON *const cm = &cpi->common; |
MACROBLOCK *const x = &cpi->mb; |
MACROBLOCKD *const xd = &x->e_mbd; |
int p; |
@@ -715,28 +721,27 @@ |
int mi_height = num_8x8_blocks_high_lookup[bsize]; |
for (p = 0; p < MAX_MB_PLANE; p++) { |
vpx_memcpy( |
- cm->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x), |
+ cpi->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x), |
a + num_4x4_blocks_wide * p, |
(sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >> |
xd->plane[p].subsampling_x); |
vpx_memcpy( |
- cm->left_context[p] |
+ cpi->left_context[p] |
+ ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y), |
l + num_4x4_blocks_high * p, |
(sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >> |
xd->plane[p].subsampling_y); |
} |
- vpx_memcpy(cm->above_seg_context + mi_col, sa, |
- sizeof(PARTITION_CONTEXT) * mi_width); |
- vpx_memcpy(cm->left_seg_context + (mi_row & MI_MASK), sl, |
- sizeof(PARTITION_CONTEXT) * mi_height); |
+ vpx_memcpy(cpi->above_seg_context + mi_col, sa, |
+ sizeof(*cpi->above_seg_context) * mi_width); |
+ vpx_memcpy(cpi->left_seg_context + (mi_row & MI_MASK), sl, |
+ sizeof(cpi->left_seg_context[0]) * mi_height); |
} |
static void save_context(VP9_COMP *cpi, int mi_row, int mi_col, |
ENTROPY_CONTEXT a[16 * MAX_MB_PLANE], |
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], |
PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8], |
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; |
@@ -749,23 +754,24 @@ |
for (p = 0; p < MAX_MB_PLANE; ++p) { |
vpx_memcpy( |
a + num_4x4_blocks_wide * p, |
- cm->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x), |
+ cpi->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x), |
(sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >> |
xd->plane[p].subsampling_x); |
vpx_memcpy( |
l + num_4x4_blocks_high * p, |
- cm->left_context[p] |
+ cpi->left_context[p] |
+ ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y), |
(sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >> |
xd->plane[p].subsampling_y); |
} |
- vpx_memcpy(sa, cm->above_seg_context + mi_col, |
- sizeof(PARTITION_CONTEXT) * mi_width); |
- vpx_memcpy(sl, cm->left_seg_context + (mi_row & MI_MASK), |
- sizeof(PARTITION_CONTEXT) * mi_height); |
+ vpx_memcpy(sa, cpi->above_seg_context + mi_col, |
+ sizeof(*cpi->above_seg_context) * mi_width); |
+ vpx_memcpy(sl, cpi->left_seg_context + (mi_row & MI_MASK), |
+ sizeof(cpi->left_seg_context[0]) * mi_height); |
} |
-static void encode_b(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, |
+static void encode_b(VP9_COMP *cpi, const TileInfo *const tile, |
+ TOKENEXTRA **tp, int mi_row, int mi_col, |
int output_enabled, BLOCK_SIZE bsize, int sub_index) { |
VP9_COMMON * const cm = &cpi->common; |
MACROBLOCK * const x = &cpi->mb; |
@@ -783,7 +789,7 @@ |
if (xd->ab_index > 0) |
return; |
} |
- set_offsets(cpi, mi_row, mi_col, bsize); |
+ set_offsets(cpi, tile, 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); |
@@ -795,7 +801,8 @@ |
} |
} |
-static void encode_sb(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, int mi_col, |
+static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile, |
+ TOKENEXTRA **tp, int mi_row, int mi_col, |
int output_enabled, BLOCK_SIZE bsize) { |
VP9_COMMON * const cm = &cpi->common; |
MACROBLOCK * const x = &cpi->mb; |
@@ -812,8 +819,8 @@ |
c1 = BLOCK_4X4; |
if (bsize >= BLOCK_8X8) { |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
+ pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context, |
+ mi_row, mi_col, bsize); |
c1 = *(get_sb_partitioning(x, bsize)); |
} |
partition = partition_lookup[bsl][c1]; |
@@ -822,19 +829,19 @@ |
case PARTITION_NONE: |
if (output_enabled && bsize >= BLOCK_8X8) |
cpi->partition_count[pl][PARTITION_NONE]++; |
- encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, -1); |
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, -1); |
break; |
case PARTITION_VERT: |
if (output_enabled) |
cpi->partition_count[pl][PARTITION_VERT]++; |
- encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, 0); |
- encode_b(cpi, tp, mi_row, mi_col + bs, output_enabled, c1, 1); |
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, 0); |
+ encode_b(cpi, tile, tp, mi_row, mi_col + bs, output_enabled, c1, 1); |
break; |
case PARTITION_HORZ: |
if (output_enabled) |
cpi->partition_count[pl][PARTITION_HORZ]++; |
- encode_b(cpi, tp, mi_row, mi_col, output_enabled, c1, 0); |
- encode_b(cpi, tp, mi_row + bs, mi_col, output_enabled, c1, 1); |
+ encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, c1, 0); |
+ encode_b(cpi, tile, tp, mi_row + bs, mi_col, output_enabled, c1, 1); |
break; |
case PARTITION_SPLIT: |
subsize = get_subsize(bsize, PARTITION_SPLIT); |
@@ -846,7 +853,7 @@ |
const int x_idx = i & 1, y_idx = i >> 1; |
*get_sb_index(xd, subsize) = i; |
- encode_sb(cpi, tp, mi_row + y_idx * bs, mi_col + x_idx * bs, |
+ encode_sb(cpi, tile, tp, mi_row + y_idx * bs, mi_col + x_idx * bs, |
output_enabled, subsize); |
} |
break; |
@@ -855,10 +862,9 @@ |
break; |
} |
- if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) { |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- update_partition_context(xd, c1, bsize); |
- } |
+ if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) |
+ update_partition_context(cpi->above_seg_context, cpi->left_seg_context, |
+ mi_row, mi_col, c1, bsize); |
} |
// Check to see if the given partition size is allowed for a specified number |
@@ -886,13 +892,13 @@ |
// However, at the bottom and right borders of the image the requested size |
// may not be allowed in which case this code attempts to choose the largest |
// allowable partition. |
-static void set_partitioning(VP9_COMP *cpi, MODE_INFO **mi_8x8, |
- int mi_row, int mi_col) { |
+static void set_partitioning(VP9_COMP *cpi, const TileInfo *const tile, |
+ MODE_INFO **mi_8x8, int mi_row, int mi_col) { |
VP9_COMMON *const cm = &cpi->common; |
BLOCK_SIZE bsize = cpi->sf.always_this_block_size; |
const int mis = cm->mode_info_stride; |
- int row8x8_remaining = cm->cur_tile_mi_row_end - mi_row; |
- int col8x8_remaining = cm->cur_tile_mi_col_end - mi_col; |
+ int row8x8_remaining = tile->mi_row_end - mi_row; |
+ int col8x8_remaining = tile->mi_col_end - mi_col; |
int block_row, block_col; |
MODE_INFO * mi_upper_left = cm->mi + mi_row * mis + mi_col; |
int bh = num_8x8_blocks_high_lookup[bsize]; |
@@ -947,324 +953,29 @@ |
} |
} |
-static void set_block_size(VP9_COMMON * const cm, MODE_INFO **mi_8x8, |
- BLOCK_SIZE bsize, int mis, int mi_row, |
- int mi_col) { |
- int r, c; |
- const int bs = MAX(num_8x8_blocks_wide_lookup[bsize], |
- num_8x8_blocks_high_lookup[bsize]); |
- const int idx_str = mis * mi_row + mi_col; |
- MODE_INFO **const mi2 = &mi_8x8[idx_str]; |
- |
- mi2[0] = cm->mi + idx_str; |
- mi2[0]->mbmi.sb_type = bsize; |
- |
- for (r = 0; r < bs; r++) |
- for (c = 0; c < bs; c++) |
- if (mi_row + r < cm->mi_rows && mi_col + c < cm->mi_cols) |
- mi2[r * mis + c] = mi2[0]; |
-} |
- |
-typedef struct { |
- int64_t sum_square_error; |
- int64_t sum_error; |
- int count; |
- int variance; |
-} var; |
- |
-typedef struct { |
- var none; |
- var horz[2]; |
- var vert[2]; |
-} partition_variance; |
- |
-#define VT(TYPE, BLOCKSIZE) \ |
- typedef struct { \ |
- partition_variance vt; \ |
- BLOCKSIZE split[4]; } TYPE; |
- |
-VT(v8x8, var) |
-VT(v16x16, v8x8) |
-VT(v32x32, v16x16) |
-VT(v64x64, v32x32) |
- |
-typedef struct { |
- partition_variance *vt; |
- var *split[4]; |
-} vt_node; |
- |
-typedef enum { |
- V16X16, |
- V32X32, |
- V64X64, |
-} TREE_LEVEL; |
- |
-static void tree_to_node(void *data, BLOCK_SIZE bsize, vt_node *node) { |
- int i; |
- 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_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_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_8X8: { |
- v8x8 *vt = (v8x8 *) data; |
- node->vt = &vt->vt; |
- for (i = 0; i < 4; i++) |
- node->split[i] = &vt->split[i]; |
- break; |
- } |
- default: |
- node->vt = 0; |
- for (i = 0; i < 4; i++) |
- node->split[i] = 0; |
- assert(-1); |
- } |
-} |
- |
-// Set variance values given sum square error, sum error, count. |
-static void fill_variance(var *v, int64_t s2, int64_t s, int c) { |
- v->sum_square_error = s2; |
- v->sum_error = s; |
- v->count = c; |
- if (c > 0) |
- v->variance = (int)(256 |
- * (v->sum_square_error - v->sum_error * v->sum_error / v->count) |
- / v->count); |
- else |
- v->variance = 0; |
-} |
- |
-// Combine 2 variance structures by summing the sum_error, sum_square_error, |
-// and counts and then calculating the new variance. |
-void sum_2_variances(var *r, var *a, var*b) { |
- fill_variance(r, a->sum_square_error + b->sum_square_error, |
- a->sum_error + b->sum_error, a->count + b->count); |
-} |
- |
-static void fill_variance_tree(void *data, BLOCK_SIZE bsize) { |
- vt_node 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]); |
- sum_2_variances(&node.vt->vert[1], node.split[1], node.split[3]); |
- sum_2_variances(&node.vt->none, &node.vt->vert[0], &node.vt->vert[1]); |
-} |
- |
-#if PERFORM_RANDOM_PARTITIONING |
-static int set_vt_partitioning(VP9_COMP *cpi, void *data, MODE_INFO *m, |
- BLOCK_SIZE block_size, int mi_row, |
- int mi_col, int mi_size) { |
- VP9_COMMON * const cm = &cpi->common; |
- vt_node vt; |
+static int sb_has_motion(VP9_COMP *cpi, MODE_INFO **prev_mi_8x8) { |
+ VP9_COMMON *const cm = &cpi->common; |
const int mis = cm->mode_info_stride; |
- int64_t threshold = 4 * cpi->common.base_qindex * cpi->common.base_qindex; |
+ int block_row, block_col; |
- tree_to_node(data, block_size, &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 && |
- (rand() & 3) < 1) { |
- set_block_size(cm, m, block_size, 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 |
- && (rand() & 3) < 1) { |
- set_block_size(cm, m, get_subsize(block_size, PARTITION_VERT), mis, mi_row, |
- mi_col); |
- return 1; |
- } |
- |
- // horizontal split is available on all but the right border |
- if (mi_col + mi_size < cm->mi_cols && vt.vt->horz[0].variance < threshold |
- && (rand() & 3) < 1) { |
- set_block_size(cm, m, get_subsize(block_size, PARTITION_HORZ), mis, mi_row, |
- mi_col); |
- return 1; |
- } |
- |
- return 0; |
-} |
- |
-#else // !PERFORM_RANDOM_PARTITIONING |
- |
-static int set_vt_partitioning(VP9_COMP *cpi, void *data, MODE_INFO **m, |
- 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, 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, 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(bsize, PARTITION_VERT), mis, mi_row, |
- mi_col); |
- return 1; |
- } |
- |
- // 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(bsize, PARTITION_HORZ), mis, mi_row, |
- mi_col); |
- return 1; |
- } |
- |
- return 0; |
-} |
-#endif // PERFORM_RANDOM_PARTITIONING |
- |
-static void choose_partitioning(VP9_COMP *cpi, MODE_INFO **mi_8x8, |
- int mi_row, int mi_col) { |
- VP9_COMMON * const cm = &cpi->common; |
- MACROBLOCK *x = &cpi->mb; |
- MACROBLOCKD *xd = &cpi->mb.e_mbd; |
- const int mis = cm->mode_info_stride; |
- // TODO(JBB): More experimentation or testing of this threshold; |
- int64_t threshold = 4; |
- int i, j, k; |
- v64x64 vt; |
- unsigned char * s; |
- int sp; |
- const unsigned char * d; |
- int dp; |
- int pixels_wide = 64, pixels_high = 64; |
- |
- vp9_zero(vt); |
- set_offsets(cpi, mi_row, mi_col, BLOCK_64X64); |
- |
- if (xd->mb_to_right_edge < 0) |
- pixels_wide += (xd->mb_to_right_edge >> 3); |
- |
- if (xd->mb_to_bottom_edge < 0) |
- pixels_high += (xd->mb_to_bottom_edge >> 3); |
- |
- s = x->plane[0].src.buf; |
- sp = x->plane[0].src.stride; |
- |
- // TODO(JBB): Clearly the higher the quantizer the fewer partitions we want |
- // but this needs more experimentation. |
- threshold = threshold * cpi->common.base_qindex * cpi->common.base_qindex; |
- |
- d = vp9_64x64_zeros; |
- dp = 64; |
- if (cm->frame_type != KEY_FRAME) { |
- int_mv nearest_mv, near_mv; |
- 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, |
- &xd->scale_factor[0]); |
- setup_pre_planes(xd, 1, second_ref_fb, mi_row, mi_col, |
- &xd->scale_factor[1]); |
- |
- xd->this_mi->mbmi.ref_frame[0] = LAST_FRAME; |
- xd->this_mi->mbmi.sb_type = BLOCK_64X64; |
- vp9_find_best_ref_mvs(xd, |
- mi_8x8[0]->mbmi.ref_mvs[mi_8x8[0]->mbmi.ref_frame[0]], |
- &nearest_mv, &near_mv); |
- |
- xd->this_mi->mbmi.mv[0] = nearest_mv; |
- 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. |
- for (i = 0; i < 4; i++) { |
- const int x32_idx = ((i & 1) << 5); |
- const int y32_idx = ((i >> 1) << 5); |
- for (j = 0; j < 4; j++) { |
- const int x16_idx = x32_idx + ((j & 1) << 4); |
- const int y16_idx = y32_idx + ((j >> 1) << 4); |
- v16x16 *vst = &vt.split[i].split[j]; |
- for (k = 0; k < 4; k++) { |
- int x_idx = x16_idx + ((k & 1) << 3); |
- int y_idx = y16_idx + ((k >> 1) << 3); |
- unsigned int sse = 0; |
- int sum = 0; |
- if (x_idx < pixels_wide && y_idx < pixels_high) |
- vp9_get_sse_sum_8x8(s + y_idx * sp + x_idx, sp, |
- d + y_idx * dp + x_idx, dp, &sse, &sum); |
- fill_variance(&vst->split[k].vt.none, sse, sum, 64); |
- } |
- } |
- } |
- // Fill the rest of the variance tree by summing the split partition |
- // values. |
- for (i = 0; i < 4; i++) { |
- for (j = 0; j < 4; j++) { |
- fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16); |
- } |
- fill_variance_tree(&vt.split[i], BLOCK_32X32); |
- } |
- 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, mi_8x8, 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], mi_8x8, 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], mi_8x8, |
- 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, mi_8x8, BLOCK_8X8, mis, |
- (mi_row + y32_idx + y16_idx + y8_idx), |
- (mi_col + x32_idx + x16_idx + x8_idx)); |
- } |
- } |
+ if (cm->prev_mi) { |
+ for (block_row = 0; block_row < 8; ++block_row) { |
+ for (block_col = 0; block_col < 8; ++block_col) { |
+ MODE_INFO * prev_mi = prev_mi_8x8[block_row * mis + block_col]; |
+ if (prev_mi) { |
+ if (abs(prev_mi->mbmi.mv[0].as_mv.row) >= 8 || |
+ abs(prev_mi->mbmi.mv[0].as_mv.col) >= 8) |
+ return 1; |
} |
} |
} |
} |
+ return 0; |
} |
-static void rd_use_partition(VP9_COMP *cpi, MODE_INFO **mi_8x8, |
+static void rd_use_partition(VP9_COMP *cpi, |
+ const TileInfo *const tile, |
+ MODE_INFO **mi_8x8, |
TOKENEXTRA **tp, int mi_row, int mi_col, |
BLOCK_SIZE bsize, int *rate, int64_t *dist, |
int do_recon) { |
@@ -1315,6 +1026,11 @@ |
} |
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
+ if (bsize == BLOCK_16X16) { |
+ set_offsets(cpi, tile, mi_row, mi_col, bsize); |
+ x->mb_energy = vp9_block_energy(cpi, x, bsize); |
+ } |
+ |
x->fast_ms = 0; |
x->subblock_ref = 0; |
@@ -1338,11 +1054,12 @@ |
mi_row + (ms >> 1) < cm->mi_rows && |
mi_col + (ms >> 1) < cm->mi_cols) { |
*(get_sb_partitioning(x, bsize)) = bsize; |
- pick_sb_modes(cpi, mi_row, mi_col, &none_rate, &none_dist, bsize, |
+ pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize, |
get_block_context(x, bsize), INT64_MAX); |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
+ pl = partition_plane_context(cpi->above_seg_context, |
+ cpi->left_seg_context, |
+ mi_row, mi_col, bsize); |
none_rate += x->partition_cost[pl][PARTITION_NONE]; |
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
@@ -1353,12 +1070,12 @@ |
switch (partition) { |
case PARTITION_NONE: |
- pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, |
+ pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, &last_part_dist, |
bsize, get_block_context(x, bsize), INT64_MAX); |
break; |
case PARTITION_HORZ: |
*get_sb_index(xd, subsize) = 0; |
- pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, |
+ pick_sb_modes(cpi, tile, 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_8X8 && mi_row + (mh >> 1) < cm->mi_rows) { |
@@ -1367,7 +1084,7 @@ |
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, &rt, &dt, subsize, |
+ pick_sb_modes(cpi, tile, mi_row + (ms >> 1), mi_col, &rt, &dt, subsize, |
get_block_context(x, subsize), INT64_MAX); |
if (rt == INT_MAX || dt == INT_MAX) { |
last_part_rate = INT_MAX; |
@@ -1381,7 +1098,7 @@ |
break; |
case PARTITION_VERT: |
*get_sb_index(xd, subsize) = 0; |
- pick_sb_modes(cpi, mi_row, mi_col, &last_part_rate, &last_part_dist, |
+ pick_sb_modes(cpi, tile, 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_8X8 && mi_col + (ms >> 1) < cm->mi_cols) { |
@@ -1390,7 +1107,7 @@ |
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), &rt, &dt, subsize, |
+ pick_sb_modes(cpi, tile, mi_row, mi_col + (ms >> 1), &rt, &dt, subsize, |
get_block_context(x, subsize), INT64_MAX); |
if (rt == INT_MAX || dt == INT_MAX) { |
last_part_rate = INT_MAX; |
@@ -1417,7 +1134,7 @@ |
*get_sb_index(xd, subsize) = i; |
- rd_use_partition(cpi, mi_8x8 + jj * bss * mis + ii * bss, tp, |
+ rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp, |
mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt, |
i != 3); |
if (rt == INT_MAX || dt == INT_MAX) { |
@@ -1432,8 +1149,9 @@ |
default: |
assert(0); |
} |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
+ |
+ pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context, |
+ mi_row, mi_col, bsize); |
if (last_part_rate < INT_MAX) |
last_part_rate += x->partition_cost[pl][partition]; |
@@ -1465,7 +1183,7 @@ |
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
- pick_sb_modes(cpi, mi_row + y_idx, mi_col + x_idx, &rt, &dt, |
+ pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &rt, &dt, |
split_subsize, get_block_context(x, split_subsize), |
INT64_MAX); |
@@ -1478,17 +1196,18 @@ |
} |
if (i != 3) |
- encode_sb(cpi, tp, mi_row + y_idx, mi_col + x_idx, 0, |
+ encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0, |
split_subsize); |
split_rate += rt; |
split_dist += dt; |
- set_partition_seg_context(cm, xd, mi_row + y_idx, mi_col + x_idx); |
- pl = partition_plane_context(xd, bsize); |
+ pl = partition_plane_context(cpi->above_seg_context, |
+ cpi->left_seg_context, |
+ mi_row + y_idx, mi_col + x_idx, bsize); |
split_rate += x->partition_cost[pl][PARTITION_NONE]; |
} |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
+ pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context, |
+ mi_row, mi_col, bsize); |
if (split_rate < INT_MAX) { |
split_rate += x->partition_cost[pl][PARTITION_SPLIT]; |
@@ -1523,7 +1242,7 @@ |
assert(chosen_rate < INT_MAX && chosen_dist < INT_MAX); |
if (do_recon) |
- encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); |
+ encode_sb(cpi, tile, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); |
*rate = chosen_rate; |
*dist = chosen_dist; |
@@ -1571,66 +1290,68 @@ |
// 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, int row, int col, |
+static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile, |
+ int row, int col, |
BLOCK_SIZE *min_block_size, |
BLOCK_SIZE *max_block_size) { |
+ VP9_COMMON * const cm = &cpi->common; |
MACROBLOCKD *const xd = &cpi->mb.e_mbd; |
MODE_INFO ** mi_8x8 = xd->mi_8x8; |
+ MODE_INFO ** prev_mi_8x8 = xd->prev_mi_8x8; |
+ |
const int left_in_image = xd->left_available && mi_8x8[-1]; |
const int above_in_image = xd->up_available && |
mi_8x8[-xd->mode_info_stride]; |
MODE_INFO ** above_sb64_mi_8x8; |
MODE_INFO ** left_sb64_mi_8x8; |
- // 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; |
+ int row8x8_remaining = tile->mi_row_end - row; |
+ int col8x8_remaining = tile->mi_col_end - col; |
+ int bh, bw; |
+ |
+ // Trap case where we do not have a prediction. |
+ if (!left_in_image && !above_in_image && |
+ ((cm->frame_type == KEY_FRAME) || !cm->prev_mi)) { |
*min_block_size = BLOCK_4X4; |
*max_block_size = BLOCK_64X64; |
} else { |
- --cpi->sf.auto_min_max_partition_count; |
+ // Default "min to max" and "max to min" |
+ *min_block_size = BLOCK_64X64; |
+ *max_block_size = BLOCK_4X4; |
- // Set default values if no left or above neighbour |
- if (!left_in_image && !above_in_image) { |
- *min_block_size = BLOCK_4X4; |
- *max_block_size = BLOCK_64X64; |
- } else { |
- VP9_COMMON *const cm = &cpi->common; |
- int row8x8_remaining = cm->cur_tile_mi_row_end - row; |
- int col8x8_remaining = cm->cur_tile_mi_col_end - col; |
- int bh, bw; |
+ // NOTE: each call to get_sb_partition_size_range() uses the previous |
+ // passed in values for min and max as a starting point. |
+ // |
+ // Find the min and max partition used in previous frame at this location |
+ if (cm->prev_mi && (cm->frame_type != KEY_FRAME)) { |
+ get_sb_partition_size_range(cpi, prev_mi_8x8, |
+ min_block_size, max_block_size); |
+ } |
- // 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_8x8 = &mi_8x8[-MI_BLOCK_SIZE]; |
+ get_sb_partition_size_range(cpi, left_sb64_mi_8x8, |
+ min_block_size, max_block_size); |
+ } |
- // Find the min and max partition sizes used in the left SB64 |
- if (left_in_image) { |
- left_sb64_mi_8x8 = &mi_8x8[-MI_BLOCK_SIZE]; |
- get_sb_partition_size_range(cpi, left_sb64_mi_8x8, |
- min_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_8x8 = &mi_8x8[-xd->mode_info_stride * MI_BLOCK_SIZE]; |
- get_sb_partition_size_range(cpi, above_sb64_mi_8x8, |
- 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]; |
- |
- // Check border cases where max and min from neighbours may not be legal. |
- *max_block_size = find_partition_size(*max_block_size, |
- row8x8_remaining, col8x8_remaining, |
- &bh, &bw); |
- *min_block_size = MIN(*min_block_size, *max_block_size); |
+ // Find the min and max partition sizes used in the above SB64. |
+ if (above_in_image) { |
+ above_sb64_mi_8x8 = &mi_8x8[-xd->mode_info_stride * MI_BLOCK_SIZE]; |
+ get_sb_partition_size_range(cpi, above_sb64_mi_8x8, |
+ 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]; |
+ |
+ // Check border cases where max and min from neighbours may not be legal. |
+ *max_block_size = find_partition_size(*max_block_size, |
+ row8x8_remaining, col8x8_remaining, |
+ &bh, &bw); |
+ *min_block_size = MIN(*min_block_size, *max_block_size); |
} |
static void compute_fast_motion_search_level(VP9_COMP *cpi, BLOCK_SIZE bsize) { |
@@ -1735,7 +1456,8 @@ |
// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are |
// unlikely to be selected depending on previous rate-distortion optimization |
// results, for encoding speed-up. |
-static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, |
+static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, |
+ TOKENEXTRA **tp, int mi_row, |
int mi_col, BLOCK_SIZE bsize, int *rate, |
int64_t *dist, int do_recon, int64_t best_rd) { |
VP9_COMMON * const cm = &cpi->common; |
@@ -1774,6 +1496,11 @@ |
} |
assert(mi_height_log2(bsize) == mi_width_log2(bsize)); |
+ if (bsize == BLOCK_16X16) { |
+ set_offsets(cpi, tile, mi_row, mi_col, bsize); |
+ x->mb_energy = vp9_block_energy(cpi, x, 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) { |
@@ -1807,12 +1534,13 @@ |
// PARTITION_NONE |
if (partition_none_allowed) { |
- pick_sb_modes(cpi, mi_row, mi_col, &this_rate, &this_dist, bsize, |
+ pick_sb_modes(cpi, tile, 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); |
+ pl = partition_plane_context(cpi->above_seg_context, |
+ cpi->left_seg_context, |
+ mi_row, mi_col, bsize); |
this_rate += x->partition_cost[pl][PARTITION_NONE]; |
} |
sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist); |
@@ -1860,7 +1588,7 @@ |
*get_sb_index(xd, subsize) = i; |
if (cpi->sf.adaptive_motion_search) |
load_pred_mv(x, get_block_context(x, bsize)); |
- rd_pick_partition(cpi, tp, mi_row + y_idx, mi_col + x_idx, subsize, |
+ rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, subsize, |
&this_rate, &this_dist, i != 3, best_rd - sum_rd); |
if (this_rate == INT_MAX) { |
@@ -1872,8 +1600,9 @@ |
} |
} |
if (sum_rd < best_rd && i == 4) { |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
+ pl = partition_plane_context(cpi->above_seg_context, |
+ cpi->left_seg_context, |
+ mi_row, mi_col, bsize); |
sum_rate += x->partition_cost[pl][PARTITION_SPLIT]; |
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
if (sum_rd < best_rd) { |
@@ -1881,12 +1610,12 @@ |
best_dist = sum_dist; |
best_rd = sum_rd; |
*(get_sb_partitioning(x, bsize)) = subsize; |
- } else { |
- // skip rectangular partition test when larger block size |
- // gives better rd cost |
- if (cpi->sf.less_rectangular_check) |
- do_rect &= !partition_none_allowed; |
} |
+ } else { |
+ // skip rectangular partition test when larger block size |
+ // gives better rd cost |
+ if (cpi->sf.less_rectangular_check) |
+ do_rect &= !partition_none_allowed; |
} |
partition_split_done = 1; |
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); |
@@ -1906,7 +1635,7 @@ |
*get_sb_index(xd, subsize) = 0; |
if (cpi->sf.adaptive_motion_search) |
load_pred_mv(x, get_block_context(x, bsize)); |
- pick_sb_modes(cpi, mi_row, mi_col, &sum_rate, &sum_dist, subsize, |
+ pick_sb_modes(cpi, tile, 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); |
@@ -1917,7 +1646,7 @@ |
*get_sb_index(xd, subsize) = 1; |
if (cpi->sf.adaptive_motion_search) |
load_pred_mv(x, get_block_context(x, bsize)); |
- pick_sb_modes(cpi, mi_row + ms, mi_col, &this_rate, |
+ pick_sb_modes(cpi, tile, mi_row + ms, mi_col, &this_rate, |
&this_dist, subsize, get_block_context(x, subsize), |
best_rd - sum_rd); |
if (this_rate == INT_MAX) { |
@@ -1929,8 +1658,9 @@ |
} |
} |
if (sum_rd < best_rd) { |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
+ pl = partition_plane_context(cpi->above_seg_context, |
+ cpi->left_seg_context, |
+ mi_row, mi_col, 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) { |
@@ -1950,7 +1680,7 @@ |
*get_sb_index(xd, subsize) = 0; |
if (cpi->sf.adaptive_motion_search) |
load_pred_mv(x, get_block_context(x, bsize)); |
- pick_sb_modes(cpi, mi_row, mi_col, &sum_rate, &sum_dist, subsize, |
+ pick_sb_modes(cpi, tile, 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 < cm->mi_cols) { |
@@ -1960,7 +1690,7 @@ |
*get_sb_index(xd, subsize) = 1; |
if (cpi->sf.adaptive_motion_search) |
load_pred_mv(x, get_block_context(x, bsize)); |
- pick_sb_modes(cpi, mi_row, mi_col + ms, &this_rate, |
+ pick_sb_modes(cpi, tile, mi_row, mi_col + ms, &this_rate, |
&this_dist, subsize, get_block_context(x, subsize), |
best_rd - sum_rd); |
if (this_rate == INT_MAX) { |
@@ -1972,8 +1702,9 @@ |
} |
} |
if (sum_rd < best_rd) { |
- set_partition_seg_context(cm, xd, mi_row, mi_col); |
- pl = partition_plane_context(xd, bsize); |
+ pl = partition_plane_context(cpi->above_seg_context, |
+ cpi->left_seg_context, |
+ mi_row, mi_col, bsize); |
sum_rate += x->partition_cost[pl][PARTITION_VERT]; |
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); |
if (sum_rd < best_rd) { |
@@ -1991,7 +1722,7 @@ |
*dist = best_dist; |
if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) |
- encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); |
+ encode_sb(cpi, tile, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize); |
if (bsize == BLOCK_64X64) { |
assert(tp_orig < *tp); |
assert(best_rate < INT_MAX); |
@@ -2002,10 +1733,10 @@ |
} |
// Examines 64x64 block and chooses a best reference frame |
-static void rd_pick_reference_frame(VP9_COMP *cpi, int mi_row, int mi_col) { |
+static void rd_pick_reference_frame(VP9_COMP *cpi, const TileInfo *const tile, |
+ 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_64X64), bs = 1 << bsl; |
int ms = bs / 2; |
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; |
@@ -2023,10 +1754,10 @@ |
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_64X64, |
+ pick_sb_modes(cpi, tile, 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_64X64); |
+ pl = partition_plane_context(cpi->above_seg_context, cpi->left_seg_context, |
+ mi_row, mi_col, BLOCK_64X64); |
r += x->partition_cost[pl][PARTITION_NONE]; |
*(get_sb_partitioning(x, BLOCK_64X64)) = BLOCK_64X64; |
@@ -2036,27 +1767,27 @@ |
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, |
- int *totalrate) { |
+static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile, |
+ int mi_row, TOKENEXTRA **tp, int *totalrate) { |
VP9_COMMON * const cm = &cpi->common; |
int mi_col; |
// Initialize the left context for the new SB row |
- vpx_memset(&cm->left_context, 0, sizeof(cm->left_context)); |
- vpx_memset(cm->left_seg_context, 0, sizeof(cm->left_seg_context)); |
+ vpx_memset(&cpi->left_context, 0, sizeof(cpi->left_context)); |
+ vpx_memset(cpi->left_seg_context, 0, sizeof(cpi->left_seg_context)); |
// Code each SB in the row |
- for (mi_col = cm->cur_tile_mi_col_start; mi_col < cm->cur_tile_mi_col_end; |
+ for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; |
mi_col += MI_BLOCK_SIZE) { |
int dummy_rate; |
int64_t dummy_dist; |
- vpx_memset(cpi->mb.pred_mv, 0, sizeof(cpi->mb.pred_mv)); |
+ vp9_zero(cpi->mb.pred_mv); |
if (cpi->sf.reference_masking) |
- rd_pick_reference_frame(cpi, mi_row, mi_col); |
+ rd_pick_reference_frame(cpi, tile, mi_row, mi_col); |
- if (cpi->sf.partition_by_variance || cpi->sf.use_lastframe_partitioning || |
+ if (cpi->sf.use_lastframe_partitioning || |
cpi->sf.use_one_partition_size_always ) { |
const int idx_str = cm->mode_info_stride * mi_row + mi_col; |
MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; |
@@ -2064,45 +1795,44 @@ |
cpi->mb.source_variance = UINT_MAX; |
if (cpi->sf.use_one_partition_size_always) { |
- set_offsets(cpi, mi_row, mi_col, BLOCK_64X64); |
- set_partitioning(cpi, mi_8x8, mi_row, mi_col); |
- rd_use_partition(cpi, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
+ set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); |
+ set_partitioning(cpi, tile, mi_8x8, mi_row, mi_col); |
+ rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
&dummy_rate, &dummy_dist, 1); |
- } else if (cpi->sf.partition_by_variance) { |
- choose_partitioning(cpi, cm->mi_grid_visible, mi_row, mi_col); |
- rd_use_partition(cpi, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
- &dummy_rate, &dummy_dist, 1); |
} else { |
if ((cpi->common.current_video_frame |
% cpi->sf.last_partitioning_redo_frequency) == 0 |
|| cm->prev_mi == 0 |
|| cpi->common.show_frame == 0 |
|| cpi->common.frame_type == KEY_FRAME |
- || cpi->is_src_frame_alt_ref) { |
+ || cpi->is_src_frame_alt_ref |
+ || ((cpi->sf.use_lastframe_partitioning == |
+ LAST_FRAME_PARTITION_LOW_MOTION) && |
+ sb_has_motion(cpi, prev_mi_8x8))) { |
// 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, mi_row, mi_col, |
+ set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); |
+ rd_auto_partition_range(cpi, tile, mi_row, mi_col, |
&cpi->sf.min_partition_size, |
&cpi->sf.max_partition_size); |
} |
- rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_64X64, |
+ rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
&dummy_rate, &dummy_dist, 1, INT64_MAX); |
} else { |
copy_partitioning(cpi, mi_8x8, prev_mi_8x8); |
- rd_use_partition(cpi, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
+ rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, |
&dummy_rate, &dummy_dist, 1); |
} |
} |
} else { |
// 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, mi_row, mi_col, |
+ set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); |
+ rd_auto_partition_range(cpi, tile, mi_row, mi_col, |
&cpi->sf.min_partition_size, |
&cpi->sf.max_partition_size); |
} |
- rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_64X64, |
+ rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, |
&dummy_rate, &dummy_dist, 1, INT64_MAX); |
} |
} |
@@ -2120,7 +1850,7 @@ |
xd->mode_info_stride = cm->mode_info_stride; |
// reset intra mode contexts |
- if (cm->frame_type == KEY_FRAME) |
+ if (frame_is_intra_only(cm)) |
vp9_init_mbmode_probs(cm); |
// Copy data over into macro block data structures. |
@@ -2129,16 +1859,16 @@ |
// TODO(jkoleszar): are these initializations required? |
setup_pre_planes(xd, 0, &cm->yv12_fb[cm->ref_frame_map[cpi->lst_fb_idx]], |
0, 0, NULL); |
- setup_dst_planes(xd, &cm->yv12_fb[cm->new_fb_idx], 0, 0); |
+ setup_dst_planes(xd, get_frame_new_buffer(cm), 0, 0); |
setup_block_dptrs(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); |
- xd->this_mi->mbmi.mode = DC_PRED; |
- xd->this_mi->mbmi.uv_mode = DC_PRED; |
+ xd->mi_8x8[0]->mbmi.mode = DC_PRED; |
+ xd->mi_8x8[0]->mbmi.uv_mode = DC_PRED; |
- vp9_zero(cpi->y_mode_count) |
- vp9_zero(cpi->y_uv_mode_count) |
- vp9_zero(cm->counts.inter_mode) |
+ vp9_zero(cpi->y_mode_count); |
+ vp9_zero(cpi->y_uv_mode_count); |
+ vp9_zero(cm->counts.inter_mode); |
vp9_zero(cpi->partition_count); |
vp9_zero(cpi->intra_inter_count); |
vp9_zero(cpi->comp_inter_count); |
@@ -2149,29 +1879,26 @@ |
// Note: this memset assumes above_context[0], [1] and [2] |
// are allocated as part of the same buffer. |
- vpx_memset(cm->above_context[0], 0, |
- sizeof(ENTROPY_CONTEXT) * 2 * MAX_MB_PLANE * aligned_mi_cols); |
- vpx_memset(cm->above_seg_context, 0, |
- sizeof(PARTITION_CONTEXT) * aligned_mi_cols); |
+ vpx_memset(cpi->above_context[0], 0, |
+ sizeof(*cpi->above_context[0]) * |
+ 2 * aligned_mi_cols * MAX_MB_PLANE); |
+ vpx_memset(cpi->above_seg_context, 0, |
+ sizeof(*cpi->above_seg_context) * aligned_mi_cols); |
} |
static void switch_lossless_mode(VP9_COMP *cpi, int lossless) { |
if (lossless) { |
// printf("Switching to lossless\n"); |
- cpi->mb.fwd_txm8x4 = vp9_short_walsh8x4; |
- cpi->mb.fwd_txm4x4 = vp9_short_walsh4x4; |
- 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.fwd_txm4x4 = vp9_fwht4x4; |
+ cpi->mb.e_mbd.itxm_add = vp9_iwht4x4_add; |
cpi->mb.optimize = 0; |
cpi->common.lf.filter_level = 0; |
cpi->zbin_mode_boost_enabled = 0; |
cpi->common.tx_mode = ONLY_4X4; |
} else { |
// printf("Not lossless\n"); |
- cpi->mb.fwd_txm8x4 = vp9_short_fdct8x4; |
- cpi->mb.fwd_txm4x4 = vp9_short_fdct4x4; |
- cpi->mb.e_mbd.inv_txm4x4_1_add = vp9_short_idct4x4_1_add; |
- cpi->mb.e_mbd.inv_txm4x4_add = vp9_short_idct4x4_add; |
+ cpi->mb.fwd_txm4x4 = vp9_fdct4x4; |
+ cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add; |
} |
} |
@@ -2208,17 +1935,14 @@ |
cpi->inter_zz_count = 0; |
vp9_zero(cm->counts.switchable_interp); |
- vp9_zero(cpi->txfm_stepdown_count); |
+ vp9_zero(cpi->tx_stepdown_count); |
xd->mi_8x8 = cm->mi_grid_visible; |
// required for vp9_frame_init_quantizer |
- xd->this_mi = |
xd->mi_8x8[0] = cm->mi; |
- xd->mic_stream_ptr = cm->mi; |
xd->last_mi = cm->prev_mi; |
- |
vp9_zero(cpi->NMVcount); |
vp9_zero(cpi->coef_counts); |
vp9_zero(cm->counts.eob_branch); |
@@ -2229,7 +1953,7 @@ |
vp9_frame_init_quantizer(cpi); |
- vp9_initialize_rd_consts(cpi, cm->base_qindex + cm->y_dc_delta_q); |
+ vp9_initialize_rd_consts(cpi); |
vp9_initialize_me_consts(cpi, cm->base_qindex); |
switch_tx_mode(cpi); |
@@ -2263,16 +1987,15 @@ |
const int tile_rows = 1 << cm->log2_tile_rows; |
for (tile_row = 0; tile_row < tile_rows; tile_row++) { |
- vp9_get_tile_row_offsets(cm, tile_row); |
- |
for (tile_col = 0; tile_col < tile_cols; tile_col++) { |
+ TileInfo tile; |
TOKENEXTRA *tp_old = tp; |
// For each row of SBs in the frame |
- vp9_get_tile_col_offsets(cm, tile_col); |
- for (mi_row = cm->cur_tile_mi_row_start; |
- mi_row < cm->cur_tile_mi_row_end; mi_row += 8) |
- encode_sb_row(cpi, mi_row, &tp, &totalrate); |
+ vp9_tile_init(&tile, cm, tile_row, tile_col); |
+ for (mi_row = tile.mi_row_start; |
+ mi_row < tile.mi_row_end; mi_row += 8) |
+ encode_sb_row(cpi, &tile, mi_row, &tp, &totalrate); |
cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old); |
assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols)); |
@@ -2306,7 +2029,6 @@ |
// Keep record of the total distortion this time around for future use |
cpi->last_frame_distortion = cpi->frame_distortion; |
#endif |
- |
} |
static int check_dual_ref_flags(VP9_COMP *cpi) { |
@@ -2347,18 +2069,19 @@ |
int mis, 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_8x8[0]->mbmi; |
- if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) |
+ if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) { |
return; |
+ } else { |
+ MB_MODE_INFO * const mbmi = &mi_8x8[0]->mbmi; |
+ if (mbmi->tx_size > max_tx_size) { |
+ const int ymbs = MIN(bh, cm->mi_rows - mi_row); |
+ const int xmbs = MIN(bw, cm->mi_cols - mi_col); |
- if (mbmi->tx_size > max_tx_size) { |
- const int ymbs = MIN(bh, cm->mi_rows - mi_row); |
- const int xmbs = MIN(bw, cm->mi_cols - mi_col); |
- |
- assert(vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) || |
- get_skip_flag(mi_8x8, mis, ymbs, xmbs)); |
- set_txfm_flag(mi_8x8, mis, ymbs, xmbs, max_tx_size); |
+ assert(vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) || |
+ get_skip_flag(mi_8x8, mis, ymbs, xmbs)); |
+ set_txfm_flag(mi_8x8, mis, ymbs, xmbs, max_tx_size); |
+ } |
} |
} |
@@ -2424,7 +2147,7 @@ |
static int get_frame_type(VP9_COMP *cpi) { |
int frame_type; |
- if (cpi->common.frame_type == KEY_FRAME) |
+ if (frame_is_intra_only(&cpi->common)) |
frame_type = 0; |
else if (cpi->is_src_frame_alt_ref && cpi->refresh_golden_frame) |
frame_type = 3; |
@@ -2453,9 +2176,9 @@ |
unsigned int total = 0; |
int i; |
for (i = 0; i < TX_SIZES; ++i) |
- total += cpi->txfm_stepdown_count[i]; |
+ total += cpi->tx_stepdown_count[i]; |
if (total) { |
- double fraction = (double)cpi->txfm_stepdown_count[0] / total; |
+ double fraction = (double)cpi->tx_stepdown_count[0] / total; |
cpi->common.tx_mode = fraction > 0.90 ? ALLOW_32X32 : TX_MODE_SELECT; |
// printf("fraction = %f\n", fraction); |
} // else keep unchanged |
@@ -2472,21 +2195,23 @@ |
// requires further work in the rd loop. For now the only supported encoder |
// 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]) |
- || (cm->ref_frame_sign_bias[ALTREF_FRAME] |
- == cm->ref_frame_sign_bias[LAST_FRAME])) { |
- cm->allow_comp_inter_inter = 0; |
- } else { |
- cm->allow_comp_inter_inter = 1; |
- cm->comp_fixed_ref = ALTREF_FRAME; |
- cm->comp_var_ref[0] = LAST_FRAME; |
- cm->comp_var_ref[1] = GOLDEN_FRAME; |
+ if (!frame_is_intra_only(cm)) { |
+ if ((cm->ref_frame_sign_bias[ALTREF_FRAME] |
+ == cm->ref_frame_sign_bias[GOLDEN_FRAME]) |
+ || (cm->ref_frame_sign_bias[ALTREF_FRAME] |
+ == cm->ref_frame_sign_bias[LAST_FRAME])) { |
+ cm->allow_comp_inter_inter = 0; |
+ } else { |
+ cm->allow_comp_inter_inter = 1; |
+ cm->comp_fixed_ref = ALTREF_FRAME; |
+ cm->comp_var_ref[0] = LAST_FRAME; |
+ cm->comp_var_ref[1] = GOLDEN_FRAME; |
+ } |
} |
if (cpi->sf.RD) { |
int i, pred_type; |
- INTERPOLATIONFILTERTYPE filter_type; |
+ INTERPOLATION_TYPE filter_type; |
/* |
* This code does a single RD pass over the whole frame assuming |
* either compound, single or hybrid prediction as per whatever has |
@@ -2554,7 +2279,7 @@ |
cpi->rd_prediction_type_threshes[frame_type][i] >>= 1; |
} |
- for (i = 0; i <= SWITCHABLE_FILTERS; i++) { |
+ for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; 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; |
@@ -2627,7 +2352,6 @@ |
} else { |
encode_frame_internal(cpi); |
} |
- |
} |
static void sum_intra_stats(VP9_COMP *cpi, const MODE_INFO *mi) { |
@@ -2732,7 +2456,7 @@ |
int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame[0])]; |
YV12_BUFFER_CONFIG *ref_fb = &cm->yv12_fb[idx]; |
YV12_BUFFER_CONFIG *second_ref_fb = NULL; |
- if (mbmi->ref_frame[1] > 0) { |
+ if (has_second_ref(mbmi)) { |
idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame[1])]; |
second_ref_fb = &cm->yv12_fb[idx]; |
} |
@@ -2744,7 +2468,6 @@ |
setup_pre_planes(xd, 1, second_ref_fb, mi_row, mi_col, |
&xd->scale_factor[1]); |
- |
vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8)); |
} |
@@ -2770,7 +2493,7 @@ |
(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->tx_size, &cm->counts.tx); |
+ ++get_tx_counts(bsize, context, &cm->counts.tx)[mbmi->tx_size]; |
} else { |
int x, y; |
TX_SIZE sz = tx_mode_to_biggest_tx_size[cm->tx_mode]; |