1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <limits.h> 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <math.h> 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdio.h> 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vp9_rtcd.h" 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vpx_config.h" 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_ports/vpx_timer.h" 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_common.h" 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_entropy.h" 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_entropymode.h" 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_idct.h" 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_mvref_common.h" 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_pred_common.h" 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_quant_common.h" 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_reconintra.h" 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_reconinter.h" 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_seg_common.h" 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_systemdependent.h" 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_tile_common.h" 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_aq_complexity.h" 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_aq_cyclicrefresh.h" 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_aq_variance.h" 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_encodeframe.h" 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_encodemb.h" 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_encodemv.h" 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_extend.h" 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_pickmode.h" 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_rdopt.h" 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_segmentation.h" 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/encoder/vp9_tokenize.h" 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define GF_ZEROMV_ZBIN_BOOST 0 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LF_ZEROMV_ZBIN_BOOST 0 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define MV_ZBIN_BOOST 0 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define SPLIT_MV_ZBIN_BOOST 0 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define INTRA_ZBIN_BOOST 0 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan 51233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE uint8_t *get_sb_index(MACROBLOCK *x, BLOCK_SIZE subsize) { 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (subsize) { 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_64X64: 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_64X32: 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_32X64: 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_32X32: 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &x->sb_index; 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_32X16: 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_16X32: 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_16X16: 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &x->mb_index; 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_16X8: 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_8X16: 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_8X8: 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &x->b_index; 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_8X4: 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_4X8: 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_4X4: 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &x->ab_index; 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(0); 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan 76233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, BLOCK_SIZE bsize); 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan 79233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x); 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan// activity_avg must be positive, or flat regions could get a zero weight 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan// (infinite lambda), which confounds analysis. 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan// This also avoids the need for divide by zero checks in 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan// vp9_activity_masking(). 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ACTIVITY_AVG_MIN 64 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Motion vector component magnitude threshold for defining fast motion. 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define FAST_MOTION_MV_THRESH 24 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan// This is used as a reference when computing the source variance for the 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan// purposes of activity masking. 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Eventually this should be replaced by custom no-reference routines, 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan// which will be faster. 94233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const uint8_t VP9_VAR_OFFS[64] = { 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128, 128, 128, 128, 128, 128, 128, 128, 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128, 128, 128, 128, 128, 128, 128, 128, 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128, 128, 128, 128, 128, 128, 128, 128, 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128, 128, 128, 128, 128, 128, 128, 128, 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128, 128, 128, 128, 128, 128, 128, 128, 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128, 128, 128, 128, 128, 128, 128, 128, 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128, 128, 128, 128, 128, 128, 128, 128, 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128, 128, 128, 128, 128, 128, 128, 128 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan 105233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *x, 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bs) { 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int var, sse; 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride, 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_VAR_OFFS, 0, &sse); 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]); 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan 114233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic unsigned int get_sby_perpixel_diff_variance(VP9_COMP *cpi, 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *x, 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col, 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bs) { 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME); 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan int offset = (mi_row * MI_SIZE) * yv12->y_stride + (mi_col * MI_SIZE); 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int var, sse; 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->plane[0].src.stride, 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan yv12->y_buffer + offset, 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan yv12->y_stride, 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan &sse); 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]); 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan 130233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi, 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col) { 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb, 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row, mi_col, 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_64X64); 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (var < 8) 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan return BLOCK_64X64; 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (var < 128) 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan return BLOCK_32X32; 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (var < 2048) 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan return BLOCK_16X16; 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan return BLOCK_8X8; 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan 146233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi, 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col) { 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb, 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row, mi_col, 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_64X64); 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (var < 4) 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan return BLOCK_64X64; 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (var < 10) 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan return BLOCK_32X32; 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan return BLOCK_16X16; 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 159233d2500723e5594f3e7c70896ffeeef32b9c950ywan 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Lighter version of set_offsets that only sets the mode info 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan// pointers. 162233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE void set_modeinfo_offsets(VP9_COMMON *const cm, 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd, 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col) { 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int idx_str = xd->mi_stride * mi_row + mi_col; 167233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi = cm->mi_grid_visible + idx_str; 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0] = cm->mi + idx_str; 169233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan 171233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int is_block_in_mb_map(const VP9_COMP *cpi, int mi_row, int mi_col, 172233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize) { 173233d2500723e5594f3e7c70896ffeeef32b9c950ywan const VP9_COMMON *const cm = &cpi->common; 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mb_rows = cm->mb_rows; 175233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mb_cols = cm->mb_cols; 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mb_row = mi_row >> 1; 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mb_col = mi_col >> 1; 178233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mb_width = num_8x8_blocks_wide_lookup[bsize] >> 1; 179233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mb_height = num_8x8_blocks_high_lookup[bsize] >> 1; 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r, c; 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize <= BLOCK_16X16) { 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan return cpi->active_map[mb_row * mb_cols + mb_col]; 183233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (r = 0; r < mb_height; ++r) { 185233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (c = 0; c < mb_width; ++c) { 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan int row = mb_row + r; 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan int col = mb_col + c; 188233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (row >= mb_rows || col >= mb_cols) 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->active_map[row * mb_cols + col]) 191233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 192233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 193233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 194233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 195233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 196233d2500723e5594f3e7c70896ffeeef32b9c950ywan 197233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int check_active_map(const VP9_COMP *cpi, const MACROBLOCK *x, 198233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, 199233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize) { 200233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->active_map_enabled && !x->e_mbd.lossless) { 201233d2500723e5594f3e7c70896ffeeef32b9c950ywan return is_block_in_mb_map(cpi, mi_row, mi_col, bsize); 202233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 203233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 204233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 205233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 206233d2500723e5594f3e7c70896ffeeef32b9c950ywan 207233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, 208233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, BLOCK_SIZE bsize) { 209233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 210233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 211233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 212233d2500723e5594f3e7c70896ffeeef32b9c950ywan MB_MODE_INFO *mbmi; 213233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mi_width = num_8x8_blocks_wide_lookup[bsize]; 214233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mi_height = num_8x8_blocks_high_lookup[bsize]; 215233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mb_row = mi_row >> 1; 216233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mb_col = mi_col >> 1; 217233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int idx_map = mb_row * cm->mb_cols + mb_col; 218233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct segmentation *const seg = &cm->seg; 219233d2500723e5594f3e7c70896ffeeef32b9c950ywan 220233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_skip_context(xd, mi_row, mi_col); 221233d2500723e5594f3e7c70896ffeeef32b9c950ywan 222233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Activity map pointer 223233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mb_activity_ptr = &cpi->mb_activity_map[idx_map]; 224233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize); 225233d2500723e5594f3e7c70896ffeeef32b9c950ywan 226233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_modeinfo_offsets(cm, xd, mi_row, mi_col); 227233d2500723e5594f3e7c70896ffeeef32b9c950ywan 228233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi = &xd->mi[0]->mbmi; 229233d2500723e5594f3e7c70896ffeeef32b9c950ywan 230233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Set up destination pointers. 231233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col); 232233d2500723e5594f3e7c70896ffeeef32b9c950ywan 233233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Set up limit values for MV components. 234233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Mv beyond the range do not produce new/different prediction block. 235233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND); 236233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND); 237233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND; 238233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND; 239233d2500723e5594f3e7c70896ffeeef32b9c950ywan 240233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Set up distance of MB to edge of frame in 1/8th pel units. 241233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1))); 242233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_mi_row_col(xd, tile, mi_row, mi_height, mi_col, mi_width, 243233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->mi_rows, cm->mi_cols); 244233d2500723e5594f3e7c70896ffeeef32b9c950ywan 245233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Set up source buffers. 246233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); 247233d2500723e5594f3e7c70896ffeeef32b9c950ywan 248233d2500723e5594f3e7c70896ffeeef32b9c950ywan // R/D setup. 249233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->rddiv = cpi->RDDIV; 250233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->rdmult = cpi->RDMULT; 251233d2500723e5594f3e7c70896ffeeef32b9c950ywan 252233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Setup segment ID. 253233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (seg->enabled) { 254233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.aq_mode != VARIANCE_AQ) { 255233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const map = seg->update_map ? cpi->segmentation_map 256233d2500723e5594f3e7c70896ffeeef32b9c950ywan : cm->last_frame_seg_map; 257233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col); 258233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 259233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_init_plane_quantizers(cpi, x); 260233d2500723e5594f3e7c70896ffeeef32b9c950ywan 261233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (seg->enabled && cpi->seg0_cnt > 0 && 262233d2500723e5594f3e7c70896ffeeef32b9c950ywan !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) && 263233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) { 264233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt; 265233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 266233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y = mb_row & ~3; 267233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int x = mb_col & ~3; 268233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int p16 = ((mb_row & 1) << 1) + (mb_col & 1); 269233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int p32 = ((mb_row & 2) << 2) + ((mb_col & 2) << 1); 270233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int tile_progress = tile->mi_col_start * cm->mb_rows >> 1; 271233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mb_cols = (tile->mi_col_end - tile->mi_col_start) >> 1; 272233d2500723e5594f3e7c70896ffeeef32b9c950ywan 273233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->seg0_progress = ((y * mb_cols + x * 4 + p32 + p16 + tile_progress) 274233d2500723e5594f3e7c70896ffeeef32b9c950ywan << 16) / cm->MBs; 275233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 276233d2500723e5594f3e7c70896ffeeef32b9c950ywan 277233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id]; 278233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 279233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->segment_id = 0; 280233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->encode_breakout = cpi->encode_breakout; 281233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 282233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 283233d2500723e5594f3e7c70896ffeeef32b9c950ywan 284233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void duplicate_mode_info_in_sb(VP9_COMMON * const cm, 285233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd, 286233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, 287233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col, 288233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize) { 289233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int block_width = num_8x8_blocks_wide_lookup[bsize]; 290233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int block_height = num_8x8_blocks_high_lookup[bsize]; 291233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j; 292233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < block_height; ++j) 293233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < block_width; ++i) { 294233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + j < cm->mi_rows && mi_col + i < cm->mi_cols) 295233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[j * xd->mi_stride + i] = xd->mi[0]; 296233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 297233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 298233d2500723e5594f3e7c70896ffeeef32b9c950ywan 299233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void set_block_size(VP9_COMP * const cpi, 300233d2500723e5594f3e7c70896ffeeef32b9c950ywan const TileInfo *const tile, 301233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, 302233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize) { 303233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) { 304233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &cpi->mb.e_mbd; 305233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_modeinfo_offsets(&cpi->common, xd, mi_row, mi_col); 306233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0]->mbmi.sb_type = bsize; 307233d2500723e5594f3e7c70896ffeeef32b9c950ywan duplicate_mode_info_in_sb(&cpi->common, xd, mi_row, mi_col, bsize); 308233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 309233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 310233d2500723e5594f3e7c70896ffeeef32b9c950ywan 311233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct { 312233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t sum_square_error; 313233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t sum_error; 314233d2500723e5594f3e7c70896ffeeef32b9c950ywan int count; 315233d2500723e5594f3e7c70896ffeeef32b9c950ywan int variance; 316233d2500723e5594f3e7c70896ffeeef32b9c950ywan} var; 317233d2500723e5594f3e7c70896ffeeef32b9c950ywan 318233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct { 319233d2500723e5594f3e7c70896ffeeef32b9c950ywan var none; 320233d2500723e5594f3e7c70896ffeeef32b9c950ywan var horz[2]; 321233d2500723e5594f3e7c70896ffeeef32b9c950ywan var vert[2]; 322233d2500723e5594f3e7c70896ffeeef32b9c950ywan} partition_variance; 323233d2500723e5594f3e7c70896ffeeef32b9c950ywan 324233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct { 325233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_variance part_variances; 326233d2500723e5594f3e7c70896ffeeef32b9c950ywan var split[4]; 327233d2500723e5594f3e7c70896ffeeef32b9c950ywan} v8x8; 328233d2500723e5594f3e7c70896ffeeef32b9c950ywan 329233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct { 330233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_variance part_variances; 331233d2500723e5594f3e7c70896ffeeef32b9c950ywan v8x8 split[4]; 332233d2500723e5594f3e7c70896ffeeef32b9c950ywan} v16x16; 333233d2500723e5594f3e7c70896ffeeef32b9c950ywan 334233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct { 335233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_variance part_variances; 336233d2500723e5594f3e7c70896ffeeef32b9c950ywan v16x16 split[4]; 337233d2500723e5594f3e7c70896ffeeef32b9c950ywan} v32x32; 338233d2500723e5594f3e7c70896ffeeef32b9c950ywan 339233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct { 340233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_variance part_variances; 341233d2500723e5594f3e7c70896ffeeef32b9c950ywan v32x32 split[4]; 342233d2500723e5594f3e7c70896ffeeef32b9c950ywan} v64x64; 343233d2500723e5594f3e7c70896ffeeef32b9c950ywan 344233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef struct { 345233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_variance *part_variances; 346233d2500723e5594f3e7c70896ffeeef32b9c950ywan var *split[4]; 347233d2500723e5594f3e7c70896ffeeef32b9c950ywan} variance_node; 348233d2500723e5594f3e7c70896ffeeef32b9c950ywan 349233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef enum { 350233d2500723e5594f3e7c70896ffeeef32b9c950ywan V16X16, 351233d2500723e5594f3e7c70896ffeeef32b9c950ywan V32X32, 352233d2500723e5594f3e7c70896ffeeef32b9c950ywan V64X64, 353233d2500723e5594f3e7c70896ffeeef32b9c950ywan} TREE_LEVEL; 354233d2500723e5594f3e7c70896ffeeef32b9c950ywan 355233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) { 356233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 357233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (bsize) { 358233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_64X64: { 359233d2500723e5594f3e7c70896ffeeef32b9c950ywan v64x64 *vt = (v64x64 *) data; 360233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->part_variances = &vt->part_variances; 361233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) 362233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->split[i] = &vt->split[i].part_variances.none; 363233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 364233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 365233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_32X32: { 366233d2500723e5594f3e7c70896ffeeef32b9c950ywan v32x32 *vt = (v32x32 *) data; 367233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->part_variances = &vt->part_variances; 368233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) 369233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->split[i] = &vt->split[i].part_variances.none; 370233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 371233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 372233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_16X16: { 373233d2500723e5594f3e7c70896ffeeef32b9c950ywan v16x16 *vt = (v16x16 *) data; 374233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->part_variances = &vt->part_variances; 375233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) 376233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->split[i] = &vt->split[i].part_variances.none; 377233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 378233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 379233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_8X8: { 380233d2500723e5594f3e7c70896ffeeef32b9c950ywan v8x8 *vt = (v8x8 *) data; 381233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->part_variances = &vt->part_variances; 382233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) 383233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->split[i] = &vt->split[i]; 384233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 385233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 386233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: { 387233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(0); 388233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 389233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 390233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 391233d2500723e5594f3e7c70896ffeeef32b9c950ywan 392233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Set variance values given sum square error, sum error, count. 393233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void fill_variance(int64_t s2, int64_t s, int c, var *v) { 394233d2500723e5594f3e7c70896ffeeef32b9c950ywan v->sum_square_error = s2; 395233d2500723e5594f3e7c70896ffeeef32b9c950ywan v->sum_error = s; 396233d2500723e5594f3e7c70896ffeeef32b9c950ywan v->count = c; 397233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (c > 0) 398233d2500723e5594f3e7c70896ffeeef32b9c950ywan v->variance = (int)(256 * 399233d2500723e5594f3e7c70896ffeeef32b9c950ywan (v->sum_square_error - v->sum_error * v->sum_error / 400233d2500723e5594f3e7c70896ffeeef32b9c950ywan v->count) / v->count); 401233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 402233d2500723e5594f3e7c70896ffeeef32b9c950ywan v->variance = 0; 403233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 404233d2500723e5594f3e7c70896ffeeef32b9c950ywan 405233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid sum_2_variances(const var *a, const var *b, var *r) { 406233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_variance(a->sum_square_error + b->sum_square_error, 407233d2500723e5594f3e7c70896ffeeef32b9c950ywan a->sum_error + b->sum_error, a->count + b->count, r); 408233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 409233d2500723e5594f3e7c70896ffeeef32b9c950ywan 410233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void fill_variance_tree(void *data, BLOCK_SIZE bsize) { 411233d2500723e5594f3e7c70896ffeeef32b9c950ywan variance_node node; 412233d2500723e5594f3e7c70896ffeeef32b9c950ywan tree_to_node(data, bsize, &node); 413233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_2_variances(node.split[0], node.split[1], &node.part_variances->horz[0]); 414233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_2_variances(node.split[2], node.split[3], &node.part_variances->horz[1]); 415233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_2_variances(node.split[0], node.split[2], &node.part_variances->vert[0]); 416233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_2_variances(node.split[1], node.split[3], &node.part_variances->vert[1]); 417233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_2_variances(&node.part_variances->vert[0], &node.part_variances->vert[1], 418233d2500723e5594f3e7c70896ffeeef32b9c950ywan &node.part_variances->none); 419233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 420233d2500723e5594f3e7c70896ffeeef32b9c950ywan 421233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int set_vt_partitioning(VP9_COMP *cpi, 422233d2500723e5594f3e7c70896ffeeef32b9c950ywan void *data, 423233d2500723e5594f3e7c70896ffeeef32b9c950ywan const TileInfo *const tile, 424233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize, 425233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, 426233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col, 427233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_size) { 428233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON * const cm = &cpi->common; 429233d2500723e5594f3e7c70896ffeeef32b9c950ywan variance_node vt; 430233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int block_width = num_8x8_blocks_wide_lookup[bsize]; 431233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int block_height = num_8x8_blocks_high_lookup[bsize]; 432233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(debargha): Choose this more intelligently. 433233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t threshold_multiplier = 25; 434233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t threshold = threshold_multiplier * cpi->common.base_qindex; 435233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(block_height == block_width); 436233d2500723e5594f3e7c70896ffeeef32b9c950ywan 437233d2500723e5594f3e7c70896ffeeef32b9c950ywan tree_to_node(data, bsize, &vt); 438233d2500723e5594f3e7c70896ffeeef32b9c950ywan 439233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Split none is available only if we have more than half a block size 440233d2500723e5594f3e7c70896ffeeef32b9c950ywan // in width and height inside the visible image. 441233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_col + block_width / 2 < cm->mi_cols && 442233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row + block_height / 2 < cm->mi_rows && 443233d2500723e5594f3e7c70896ffeeef32b9c950ywan vt.part_variances->none.variance < threshold) { 444233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_block_size(cpi, tile, mi_row, mi_col, bsize); 445233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 446233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 447233d2500723e5594f3e7c70896ffeeef32b9c950ywan 448233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Vertical split is available on all but the bottom border. 449233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + block_height / 2 < cm->mi_rows && 450233d2500723e5594f3e7c70896ffeeef32b9c950ywan vt.part_variances->vert[0].variance < threshold && 451233d2500723e5594f3e7c70896ffeeef32b9c950ywan vt.part_variances->vert[1].variance < threshold) { 452233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT); 453233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_block_size(cpi, tile, mi_row, mi_col, subsize); 454233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_block_size(cpi, tile, mi_row, mi_col + block_width / 2, subsize); 455233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 456233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 457233d2500723e5594f3e7c70896ffeeef32b9c950ywan 458233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Horizontal split is available on all but the right border. 459233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_col + block_width / 2 < cm->mi_cols && 460233d2500723e5594f3e7c70896ffeeef32b9c950ywan vt.part_variances->horz[0].variance < threshold && 461233d2500723e5594f3e7c70896ffeeef32b9c950ywan vt.part_variances->horz[1].variance < threshold) { 462233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ); 463233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_block_size(cpi, tile, mi_row, mi_col, subsize); 464233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_block_size(cpi, tile, mi_row + block_height / 2, mi_col, subsize); 465233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 466233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 467233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 468233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 469233d2500723e5594f3e7c70896ffeeef32b9c950ywan 470233d2500723e5594f3e7c70896ffeeef32b9c950ywan// TODO(debargha): Fix this function and make it work as expected. 471233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void choose_partitioning(VP9_COMP *cpi, 472233d2500723e5594f3e7c70896ffeeef32b9c950ywan const TileInfo *const tile, 473233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col) { 474233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON * const cm = &cpi->common; 475233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *x = &cpi->mb; 476233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *xd = &cpi->mb.e_mbd; 477233d2500723e5594f3e7c70896ffeeef32b9c950ywan 478233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j, k; 479233d2500723e5594f3e7c70896ffeeef32b9c950ywan v64x64 vt; 480233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint8_t *s; 481233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *d; 482233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sp; 483233d2500723e5594f3e7c70896ffeeef32b9c950ywan int dp; 484233d2500723e5594f3e7c70896ffeeef32b9c950ywan int pixels_wide = 64, pixels_high = 64; 485233d2500723e5594f3e7c70896ffeeef32b9c950ywan int_mv nearest_mv, near_mv; 486233d2500723e5594f3e7c70896ffeeef32b9c950ywan const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME); 487233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf; 488233d2500723e5594f3e7c70896ffeeef32b9c950ywan 489233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(vt); 490233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); 491233d2500723e5594f3e7c70896ffeeef32b9c950ywan 492233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (xd->mb_to_right_edge < 0) 493233d2500723e5594f3e7c70896ffeeef32b9c950ywan pixels_wide += (xd->mb_to_right_edge >> 3); 494233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (xd->mb_to_bottom_edge < 0) 495233d2500723e5594f3e7c70896ffeeef32b9c950ywan pixels_high += (xd->mb_to_bottom_edge >> 3); 496233d2500723e5594f3e7c70896ffeeef32b9c950ywan 497233d2500723e5594f3e7c70896ffeeef32b9c950ywan s = x->plane[0].src.buf; 498233d2500723e5594f3e7c70896ffeeef32b9c950ywan sp = x->plane[0].src.stride; 499233d2500723e5594f3e7c70896ffeeef32b9c950ywan 500233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->frame_type != KEY_FRAME) { 501233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, sf); 502233d2500723e5594f3e7c70896ffeeef32b9c950ywan 503233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME; 504233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0]->mbmi.sb_type = BLOCK_64X64; 505233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, 506233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0]->mbmi.ref_mvs[LAST_FRAME], 507233d2500723e5594f3e7c70896ffeeef32b9c950ywan &nearest_mv, &near_mv); 508233d2500723e5594f3e7c70896ffeeef32b9c950ywan 509233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0]->mbmi.mv[0] = nearest_mv; 510233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_build_inter_predictors_sby(xd, mi_row, mi_col, BLOCK_64X64); 511233d2500723e5594f3e7c70896ffeeef32b9c950ywan 512233d2500723e5594f3e7c70896ffeeef32b9c950ywan d = xd->plane[0].dst.buf; 513233d2500723e5594f3e7c70896ffeeef32b9c950ywan dp = xd->plane[0].dst.stride; 514233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 515233d2500723e5594f3e7c70896ffeeef32b9c950ywan d = VP9_VAR_OFFS; 516233d2500723e5594f3e7c70896ffeeef32b9c950ywan dp = 0; 517233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 518233d2500723e5594f3e7c70896ffeeef32b9c950ywan 519233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Fill in the entire tree of 8x8 variances for splits. 520233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) { 521233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int x32_idx = ((i & 1) << 5); 522233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y32_idx = ((i >> 1) << 5); 523233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < 4; j++) { 524233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int x16_idx = x32_idx + ((j & 1) << 4); 525233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y16_idx = y32_idx + ((j >> 1) << 4); 526233d2500723e5594f3e7c70896ffeeef32b9c950ywan v16x16 *vst = &vt.split[i].split[j]; 527233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (k = 0; k < 4; k++) { 528233d2500723e5594f3e7c70896ffeeef32b9c950ywan int x_idx = x16_idx + ((k & 1) << 3); 529233d2500723e5594f3e7c70896ffeeef32b9c950ywan int y_idx = y16_idx + ((k >> 1) << 3); 530233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sse = 0; 531233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sum = 0; 532233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x_idx < pixels_wide && y_idx < pixels_high) 533233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_get_sse_sum_8x8(s + y_idx * sp + x_idx, sp, 534233d2500723e5594f3e7c70896ffeeef32b9c950ywan d + y_idx * dp + x_idx, dp, &sse, &sum); 535233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_variance(sse, sum, 64, &vst->split[k].part_variances.none); 536233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 537233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 538233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 539233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Fill the rest of the variance tree by summing split partition values. 540233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) { 541233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < 4; j++) { 542233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16); 543233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 544233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_variance_tree(&vt.split[i], BLOCK_32X32); 545233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 546233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_variance_tree(&vt, BLOCK_64X64); 547233d2500723e5594f3e7c70896ffeeef32b9c950ywan 548233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Now go through the entire structure, splitting every block size until 549233d2500723e5594f3e7c70896ffeeef32b9c950ywan // we get to one that's got a variance lower than our threshold, or we 550233d2500723e5594f3e7c70896ffeeef32b9c950ywan // hit 8x8. 551233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!set_vt_partitioning(cpi, &vt, tile, BLOCK_64X64, 552233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row, mi_col, 8)) { 553233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; ++i) { 554233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int x32_idx = ((i & 1) << 2); 555233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y32_idx = ((i >> 1) << 2); 556233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!set_vt_partitioning(cpi, &vt.split[i], tile, BLOCK_32X32, 557233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_row + y32_idx), (mi_col + x32_idx), 4)) { 558233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < 4; ++j) { 559233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int x16_idx = ((j & 1) << 1); 560233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y16_idx = ((j >> 1) << 1); 561233d2500723e5594f3e7c70896ffeeef32b9c950ywan // NOTE: This is a temporary hack to disable 8x8 partitions, 562233d2500723e5594f3e7c70896ffeeef32b9c950ywan // since it works really bad - possibly due to a bug 563233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define DISABLE_8X8_VAR_BASED_PARTITION 564233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef DISABLE_8X8_VAR_BASED_PARTITION 565233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + y32_idx + y16_idx + 1 < cm->mi_rows && 566233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row + x32_idx + x16_idx + 1 < cm->mi_cols) { 567233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_block_size(cpi, tile, 568233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_row + y32_idx + y16_idx), 569233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_col + x32_idx + x16_idx), 570233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_16X16); 571233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 572233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (k = 0; k < 4; ++k) { 573233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int x8_idx = (k & 1); 574233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y8_idx = (k >> 1); 575233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_block_size(cpi, tile, 576233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_row + y32_idx + y16_idx + y8_idx), 577233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_col + x32_idx + x16_idx + x8_idx), 578233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_8X8); 579233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 580233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 581233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 582233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!set_vt_partitioning(cpi, &vt.split[i].split[j], tile, 583233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_16X16, 584233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_row + y32_idx + y16_idx), 585233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_col + x32_idx + x16_idx), 2)) { 586233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (k = 0; k < 4; ++k) { 587233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int x8_idx = (k & 1); 588233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y8_idx = (k >> 1); 589233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_block_size(cpi, tile, 590233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_row + y32_idx + y16_idx + y8_idx), 591233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_col + x32_idx + x16_idx + x8_idx), 592233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_8X8); 593233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 594233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 595233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 596233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 597233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 598233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 599233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 600233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 601233d2500723e5594f3e7c70896ffeeef32b9c950ywan 602233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Original activity measure from Tim T's code. 603233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic unsigned int tt_activity_measure(MACROBLOCK *x) { 604233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int sse; 605233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO: This could also be done over smaller areas (8x8), but that would 606233d2500723e5594f3e7c70896ffeeef32b9c950ywan // require extensive changes elsewhere, as lambda is assumed to be fixed 607233d2500723e5594f3e7c70896ffeeef32b9c950ywan // over an entire MB in most of the code. 608233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Another option is to compute four 8x8 variances, and pick a single 609233d2500723e5594f3e7c70896ffeeef32b9c950ywan // lambda using a non-linear combination (e.g., the smallest, or second 610233d2500723e5594f3e7c70896ffeeef32b9c950ywan // smallest, etc.). 611233d2500723e5594f3e7c70896ffeeef32b9c950ywan const unsigned int act = vp9_variance16x16(x->plane[0].src.buf, 612233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->plane[0].src.stride, 613233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_VAR_OFFS, 0, &sse) << 4; 614233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If the region is flat, lower the activity some more. 615233d2500723e5594f3e7c70896ffeeef32b9c950ywan return act < (8 << 12) ? MIN(act, 5 << 12) : act; 616233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 617233d2500723e5594f3e7c70896ffeeef32b9c950ywan 618233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Stub for alternative experimental activity measures. 619233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic unsigned int alt_activity_measure(MACROBLOCK *x, int use_dc_pred) { 620233d2500723e5594f3e7c70896ffeeef32b9c950ywan return vp9_encode_intra(x, use_dc_pred); 621233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 622233d2500723e5594f3e7c70896ffeeef32b9c950ywan 623233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Measure the activity of the current macroblock 624233d2500723e5594f3e7c70896ffeeef32b9c950ywan// What we measure here is TBD so abstracted to this function 625233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ALT_ACT_MEASURE 1 626233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) { 627233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int mb_activity; 628233d2500723e5594f3e7c70896ffeeef32b9c950ywan 629233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ALT_ACT_MEASURE) { 630233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); 631233d2500723e5594f3e7c70896ffeeef32b9c950ywan 632233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Or use and alternative. 633233d2500723e5594f3e7c70896ffeeef32b9c950ywan mb_activity = alt_activity_measure(x, use_dc_pred); 634233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 635233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Original activity measure from Tim T's code. 636233d2500723e5594f3e7c70896ffeeef32b9c950ywan mb_activity = tt_activity_measure(x); 637233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 638233d2500723e5594f3e7c70896ffeeef32b9c950ywan 639233d2500723e5594f3e7c70896ffeeef32b9c950ywan return MAX(mb_activity, ACTIVITY_AVG_MIN); 640233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 641233d2500723e5594f3e7c70896ffeeef32b9c950ywan 642233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Calculate an "average" mb activity value for the frame 643233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ACT_MEDIAN 0 644233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void calc_av_activity(VP9_COMP *cpi, int64_t activity_sum) { 645233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if ACT_MEDIAN 646233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Find median: Simple n^2 algorithm for experimentation 647233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 648233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int median; 649233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int i, j; 650233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int *sortlist; 651233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int tmp; 652233d2500723e5594f3e7c70896ffeeef32b9c950ywan 653233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Create a list to sort to 654233d2500723e5594f3e7c70896ffeeef32b9c950ywan CHECK_MEM_ERROR(&cpi->common, sortlist, vpx_calloc(sizeof(unsigned int), 655233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->common.MBs)); 656233d2500723e5594f3e7c70896ffeeef32b9c950ywan 657233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Copy map to sort list 658233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy(sortlist, cpi->mb_activity_map, 659233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizeof(unsigned int) * cpi->common.MBs); 660233d2500723e5594f3e7c70896ffeeef32b9c950ywan 661233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Ripple each value down to its correct position 662233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 1; i < cpi->common.MBs; i ++) { 663233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = i; j > 0; j --) { 664233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sortlist[j] < sortlist[j - 1]) { 665233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Swap values 666233d2500723e5594f3e7c70896ffeeef32b9c950ywan tmp = sortlist[j - 1]; 667233d2500723e5594f3e7c70896ffeeef32b9c950ywan sortlist[j - 1] = sortlist[j]; 668233d2500723e5594f3e7c70896ffeeef32b9c950ywan sortlist[j] = tmp; 669233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 670233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 671233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 672233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 673233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 674233d2500723e5594f3e7c70896ffeeef32b9c950ywan 675233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Even number MBs so estimate median as mean of two either side. 676233d2500723e5594f3e7c70896ffeeef32b9c950ywan median = (1 + sortlist[cpi->common.MBs >> 1] + 677233d2500723e5594f3e7c70896ffeeef32b9c950ywan sortlist[(cpi->common.MBs >> 1) + 1]) >> 1; 678233d2500723e5594f3e7c70896ffeeef32b9c950ywan 679233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->activity_avg = median; 680233d2500723e5594f3e7c70896ffeeef32b9c950ywan 681233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_free(sortlist); 682233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 683233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 684233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Simple mean for now 685233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->activity_avg = (unsigned int) (activity_sum / cpi->common.MBs); 686233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif // ACT_MEDIAN 687233d2500723e5594f3e7c70896ffeeef32b9c950ywan 688233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->activity_avg < ACTIVITY_AVG_MIN) 689233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->activity_avg = ACTIVITY_AVG_MIN; 690233d2500723e5594f3e7c70896ffeeef32b9c950ywan 691233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Experimental code: return fixed value normalized for several clips 692233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ALT_ACT_MEASURE) 693233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->activity_avg = 100000; 694233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 695233d2500723e5594f3e7c70896ffeeef32b9c950ywan 696233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define USE_ACT_INDEX 0 697233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define OUTPUT_NORM_ACT_STATS 0 698233d2500723e5594f3e7c70896ffeeef32b9c950ywan 699233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if USE_ACT_INDEX 700233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Calculate an activity index for each mb 701233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void calc_activity_index(VP9_COMP *cpi, MACROBLOCK *x) { 702233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 703233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mb_row, mb_col; 704233d2500723e5594f3e7c70896ffeeef32b9c950ywan 705233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t act; 706233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t a; 707233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t b; 708233d2500723e5594f3e7c70896ffeeef32b9c950ywan 709233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if OUTPUT_NORM_ACT_STATS 710233d2500723e5594f3e7c70896ffeeef32b9c950ywan FILE *f = fopen("norm_act.stt", "a"); 711233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(f, "\n%12d\n", cpi->activity_avg); 712233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 713233d2500723e5594f3e7c70896ffeeef32b9c950ywan 714233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Reset pointers to start of activity map 715233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mb_activity_ptr = cpi->mb_activity_map; 716233d2500723e5594f3e7c70896ffeeef32b9c950ywan 717233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Calculate normalized mb activity number. 718233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { 719233d2500723e5594f3e7c70896ffeeef32b9c950ywan // for each macroblock col in image 720233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { 721233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Read activity from the map 722233d2500723e5594f3e7c70896ffeeef32b9c950ywan act = *(x->mb_activity_ptr); 723233d2500723e5594f3e7c70896ffeeef32b9c950ywan 724233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Calculate a normalized activity number 725233d2500723e5594f3e7c70896ffeeef32b9c950ywan a = act + 4 * cpi->activity_avg; 726233d2500723e5594f3e7c70896ffeeef32b9c950ywan b = 4 * act + cpi->activity_avg; 727233d2500723e5594f3e7c70896ffeeef32b9c950ywan 728233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (b >= a) 729233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(x->activity_ptr) = (int)((b + (a >> 1)) / a) - 1; 730233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 731233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(x->activity_ptr) = 1 - (int)((a + (b >> 1)) / b); 732233d2500723e5594f3e7c70896ffeeef32b9c950ywan 733233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if OUTPUT_NORM_ACT_STATS 734233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(f, " %6d", *(x->mb_activity_ptr)); 735233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 736233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Increment activity map pointers 737233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mb_activity_ptr++; 738233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 739233d2500723e5594f3e7c70896ffeeef32b9c950ywan 740233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if OUTPUT_NORM_ACT_STATS 741233d2500723e5594f3e7c70896ffeeef32b9c950ywan fprintf(f, "\n"); 742233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 743233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 744233d2500723e5594f3e7c70896ffeeef32b9c950ywan 745233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if OUTPUT_NORM_ACT_STATS 746233d2500723e5594f3e7c70896ffeeef32b9c950ywan fclose(f); 747233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 748233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 749233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif // USE_ACT_INDEX 750233d2500723e5594f3e7c70896ffeeef32b9c950ywan 751233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Loop through all MBs. Note activity of each, average activity and 752233d2500723e5594f3e7c70896ffeeef32b9c950ywan// calculate a normalized activity for each 753233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void build_activity_map(VP9_COMP *cpi) { 754233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 755233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *xd = &x->e_mbd; 756233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 757233d2500723e5594f3e7c70896ffeeef32b9c950ywan 758233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if ALT_ACT_MEASURE 759233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG *new_yv12 = get_frame_new_buffer(cm); 760233d2500723e5594f3e7c70896ffeeef32b9c950ywan int recon_yoffset; 761233d2500723e5594f3e7c70896ffeeef32b9c950ywan int recon_y_stride = new_yv12->y_stride; 762233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 763233d2500723e5594f3e7c70896ffeeef32b9c950ywan 764233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mb_row, mb_col; 765233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int mb_activity; 766233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t activity_sum = 0; 767233d2500723e5594f3e7c70896ffeeef32b9c950ywan 768233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mb_activity_ptr = cpi->mb_activity_map; 769233d2500723e5594f3e7c70896ffeeef32b9c950ywan 770233d2500723e5594f3e7c70896ffeeef32b9c950ywan // for each macroblock row in image 771233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { 772233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if ALT_ACT_MEASURE 773233d2500723e5594f3e7c70896ffeeef32b9c950ywan // reset above block coeffs 774233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->up_available = (mb_row != 0); 775233d2500723e5594f3e7c70896ffeeef32b9c950ywan recon_yoffset = (mb_row * recon_y_stride * 16); 776233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 777233d2500723e5594f3e7c70896ffeeef32b9c950ywan // for each macroblock col in image 778233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { 779233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if ALT_ACT_MEASURE 780233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset; 781233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->left_available = (mb_col != 0); 782233d2500723e5594f3e7c70896ffeeef32b9c950ywan recon_yoffset += 16; 783233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 784233d2500723e5594f3e7c70896ffeeef32b9c950ywan 785233d2500723e5594f3e7c70896ffeeef32b9c950ywan // measure activity 786233d2500723e5594f3e7c70896ffeeef32b9c950ywan mb_activity = mb_activity_measure(x, mb_row, mb_col); 787233d2500723e5594f3e7c70896ffeeef32b9c950ywan 788233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Keep frame sum 789233d2500723e5594f3e7c70896ffeeef32b9c950ywan activity_sum += mb_activity; 790233d2500723e5594f3e7c70896ffeeef32b9c950ywan 791233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Store MB level activity details. 792233d2500723e5594f3e7c70896ffeeef32b9c950ywan *x->mb_activity_ptr = mb_activity; 793233d2500723e5594f3e7c70896ffeeef32b9c950ywan 794233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Increment activity map pointer 795233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mb_activity_ptr++; 796233d2500723e5594f3e7c70896ffeeef32b9c950ywan 797233d2500723e5594f3e7c70896ffeeef32b9c950ywan // adjust to the next column of source macroblocks 798233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->plane[0].src.buf += 16; 799233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 800233d2500723e5594f3e7c70896ffeeef32b9c950ywan 801233d2500723e5594f3e7c70896ffeeef32b9c950ywan // adjust to the next row of mbs 802233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols; 803233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 804233d2500723e5594f3e7c70896ffeeef32b9c950ywan 805233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Calculate an "average" MB activity 806233d2500723e5594f3e7c70896ffeeef32b9c950ywan calc_av_activity(cpi, activity_sum); 807233d2500723e5594f3e7c70896ffeeef32b9c950ywan 808233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if USE_ACT_INDEX 809233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Calculate an activity index number of each mb 810233d2500723e5594f3e7c70896ffeeef32b9c950ywan calc_activity_index(cpi, x); 811233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 812233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 813233d2500723e5594f3e7c70896ffeeef32b9c950ywan 814233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Macroblock activity masking 815233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void activity_masking(VP9_COMP *cpi, MACROBLOCK *x) { 816233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if USE_ACT_INDEX 817233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2); 818233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->errorperbit = x->rdmult * 100 / (110 * x->rddiv); 819233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->errorperbit += (x->errorperbit == 0); 820233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 821233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t act = *(x->mb_activity_ptr); 822233d2500723e5594f3e7c70896ffeeef32b9c950ywan 823233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Apply the masking to the RD multiplier. 824233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t a = act + (2 * cpi->activity_avg); 825233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t b = (2 * act) + cpi->activity_avg; 826233d2500723e5594f3e7c70896ffeeef32b9c950ywan 827233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->rdmult = (unsigned int) (((int64_t) x->rdmult * b + (a >> 1)) / a); 828233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->errorperbit = x->rdmult * 100 / (110 * x->rddiv); 829233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->errorperbit += (x->errorperbit == 0); 830233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 831233d2500723e5594f3e7c70896ffeeef32b9c950ywan 832233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Activity based Zbin adjustment 833233d2500723e5594f3e7c70896ffeeef32b9c950ywan adjust_act_zbin(cpi, x); 834233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 835233d2500723e5594f3e7c70896ffeeef32b9c950ywan 836233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, 837233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, BLOCK_SIZE bsize, 838233d2500723e5594f3e7c70896ffeeef32b9c950ywan int output_enabled) { 839233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, x_idx, y; 840233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 841233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 842233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 843233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct macroblock_plane *const p = x->plane; 844233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct macroblockd_plane *const pd = xd->plane; 845233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO *mi = &ctx->mic; 846233d2500723e5594f3e7c70896ffeeef32b9c950ywan MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; 847233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO *mi_addr = xd->mi[0]; 848233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct segmentation *const seg = &cm->seg; 849233d2500723e5594f3e7c70896ffeeef32b9c950ywan 850233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mis = cm->mi_stride; 851233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mi_width = num_8x8_blocks_wide_lookup[bsize]; 852233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mi_height = num_8x8_blocks_high_lookup[bsize]; 853233d2500723e5594f3e7c70896ffeeef32b9c950ywan int max_plane; 854233d2500723e5594f3e7c70896ffeeef32b9c950ywan 855233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(mi->mbmi.sb_type == bsize); 856233d2500723e5594f3e7c70896ffeeef32b9c950ywan 857233d2500723e5594f3e7c70896ffeeef32b9c950ywan *mi_addr = *mi; 858233d2500723e5594f3e7c70896ffeeef32b9c950ywan 859233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If segmentation in use 860233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (seg->enabled && output_enabled) { 861233d2500723e5594f3e7c70896ffeeef32b9c950ywan // For in frame complexity AQ copy the segment id from the segment map. 862233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) { 863233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const map = seg->update_map ? cpi->segmentation_map 864233d2500723e5594f3e7c70896ffeeef32b9c950ywan : cm->last_frame_seg_map; 865233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_addr->mbmi.segment_id = 866233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_get_segment_id(cm, map, bsize, mi_row, mi_col); 867233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 868233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Else for cyclic refresh mode update the segment map, set the segment id 869233d2500723e5594f3e7c70896ffeeef32b9c950ywan // and then update the quantizer. 870233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { 871233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, 872233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row, mi_col, bsize, 1); 873233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_init_plane_quantizers(cpi, x); 874233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 875233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 876233d2500723e5594f3e7c70896ffeeef32b9c950ywan 877233d2500723e5594f3e7c70896ffeeef32b9c950ywan max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1; 878233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < max_plane; ++i) { 879233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].coeff = ctx->coeff_pbuf[i][1]; 880233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].qcoeff = ctx->qcoeff_pbuf[i][1]; 881233d2500723e5594f3e7c70896ffeeef32b9c950ywan pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1]; 882233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].eobs = ctx->eobs_pbuf[i][1]; 883233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 884233d2500723e5594f3e7c70896ffeeef32b9c950ywan 885233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = max_plane; i < MAX_MB_PLANE; ++i) { 886233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].coeff = ctx->coeff_pbuf[i][2]; 887233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].qcoeff = ctx->qcoeff_pbuf[i][2]; 888233d2500723e5594f3e7c70896ffeeef32b9c950ywan pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][2]; 889233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].eobs = ctx->eobs_pbuf[i][2]; 890233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 891233d2500723e5594f3e7c70896ffeeef32b9c950ywan 892233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Restore the coding context of the MB to that that was in place 893233d2500723e5594f3e7c70896ffeeef32b9c950ywan // when the mode was picked for it 894233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (y = 0; y < mi_height; y++) 895233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (x_idx = 0; x_idx < mi_width; x_idx++) 896233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx 897233d2500723e5594f3e7c70896ffeeef32b9c950ywan && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) { 898233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[x_idx + y * mis] = mi_addr; 899233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 900233d2500723e5594f3e7c70896ffeeef32b9c950ywan 901233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.aq_mode) 902233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_init_plane_quantizers(cpi, x); 903233d2500723e5594f3e7c70896ffeeef32b9c950ywan 904233d2500723e5594f3e7c70896ffeeef32b9c950ywan // FIXME(rbultje) I'm pretty sure this should go to the end of this block 905233d2500723e5594f3e7c70896ffeeef32b9c950ywan // (i.e. after the output_enabled) 906233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize < BLOCK_32X32) { 907233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize < BLOCK_16X16) 908233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->tx_rd_diff[ALLOW_16X16] = ctx->tx_rd_diff[ALLOW_8X8]; 909233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->tx_rd_diff[ALLOW_32X32] = ctx->tx_rd_diff[ALLOW_16X16]; 910233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 911233d2500723e5594f3e7c70896ffeeef32b9c950ywan 912233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_inter_block(mbmi) && mbmi->sb_type < BLOCK_8X8) { 913233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int; 914233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int; 915233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 916233d2500723e5594f3e7c70896ffeeef32b9c950ywan 917233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->skip = ctx->skip; 918233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy(x->zcoeff_blk[mbmi->tx_size], ctx->zcoeff_blk, 919233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizeof(uint8_t) * ctx->num_4x4_blk); 920233d2500723e5594f3e7c70896ffeeef32b9c950ywan 921233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!output_enabled) 922233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 923233d2500723e5594f3e7c70896ffeeef32b9c950ywan 924233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) { 925233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < TX_MODES; i++) 926233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_tx_select_diff[i] += ctx->tx_rd_diff[i]; 927233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 928233d2500723e5594f3e7c70896ffeeef32b9c950ywan 929233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_INTERNAL_STATS 930233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frame_is_intra_only(cm)) { 931233d2500723e5594f3e7c70896ffeeef32b9c950ywan static const int kf_mode_index[] = { 932233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_DC /*DC_PRED*/, 933233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_V_PRED /*V_PRED*/, 934233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_H_PRED /*H_PRED*/, 935233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_D45_PRED /*D45_PRED*/, 936233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_D135_PRED /*D135_PRED*/, 937233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_D117_PRED /*D117_PRED*/, 938233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_D153_PRED /*D153_PRED*/, 939233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_D207_PRED /*D207_PRED*/, 940233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_D63_PRED /*D63_PRED*/, 941233d2500723e5594f3e7c70896ffeeef32b9c950ywan THR_TM /*TM_PRED*/, 942233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 943233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++cpi->mode_chosen_counts[kf_mode_index[mbmi->mode]]; 944233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 945233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Note how often each mode chosen as best 946233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++cpi->mode_chosen_counts[ctx->best_mode_index]; 947233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 948233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 949233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!frame_is_intra_only(cm)) { 950233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_inter_block(mbmi)) { 951233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_update_mv_count(cm, xd); 952233d2500723e5594f3e7c70896ffeeef32b9c950ywan 953233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->interp_filter == SWITCHABLE) { 954233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int ctx = vp9_get_pred_context_switchable_interp(xd); 955233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++cm->counts.switchable_interp[ctx][mbmi->interp_filter]; 956233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 957233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 958233d2500723e5594f3e7c70896ffeeef32b9c950ywan 959233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff; 960233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff; 961233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff; 962233d2500723e5594f3e7c70896ffeeef32b9c950ywan 963233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) 964233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_filter_diff[i] += ctx->best_filter_diff[i]; 965233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 966233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 967233d2500723e5594f3e7c70896ffeeef32b9c950ywan 968233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src, 969233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col) { 970233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint8_t *const buffers[4] = {src->y_buffer, src->u_buffer, src->v_buffer, 971233d2500723e5594f3e7c70896ffeeef32b9c950ywan src->alpha_buffer}; 972233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int strides[4] = {src->y_stride, src->uv_stride, src->uv_stride, 973233d2500723e5594f3e7c70896ffeeef32b9c950ywan src->alpha_stride}; 974233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 975233d2500723e5594f3e7c70896ffeeef32b9c950ywan 976233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Set current frame pointer. 977233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->e_mbd.cur_buf = src; 978233d2500723e5594f3e7c70896ffeeef32b9c950ywan 979233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < MAX_MB_PLANE; i++) 980233d2500723e5594f3e7c70896ffeeef32b9c950ywan setup_pred_plane(&x->plane[i].src, buffers[i], strides[i], mi_row, mi_col, 981233d2500723e5594f3e7c70896ffeeef32b9c950ywan NULL, x->e_mbd.plane[i].subsampling_x, 982233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->e_mbd.plane[i].subsampling_y); 983233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 984233d2500723e5594f3e7c70896ffeeef32b9c950ywan 985233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, 986233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, 987233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *totalrate, int64_t *totaldist, 988233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, 989233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t best_rd) { 990233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 991233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 992233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 993233d2500723e5594f3e7c70896ffeeef32b9c950ywan MB_MODE_INFO *mbmi; 994233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct macroblock_plane *const p = x->plane; 995233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct macroblockd_plane *const pd = xd->plane; 996233d2500723e5594f3e7c70896ffeeef32b9c950ywan const AQ_MODE aq_mode = cpi->oxcf.aq_mode; 997233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, orig_rdmult; 998233d2500723e5594f3e7c70896ffeeef32b9c950ywan double rdmult_ratio; 999233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1000233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_clear_system_state(); 1001233d2500723e5594f3e7c70896ffeeef32b9c950ywan rdmult_ratio = 1.0; // avoid uninitialized warnings 1002233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1003233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Use the lower precision, but faster, 32x32 fdct for mode selection. 1004233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->use_lp32x32fdct = 1; 1005233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1006233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize < BLOCK_8X8) { 1007233d2500723e5594f3e7c70896ffeeef32b9c950ywan // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 1008233d2500723e5594f3e7c70896ffeeef32b9c950ywan // there is nothing to be done. 1009233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->ab_index != 0) { 1010233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totalrate = 0; 1011233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totaldist = 0; 1012233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 1013233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1014233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1015233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1016233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, bsize); 1017233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi = &xd->mi[0]->mbmi; 1018233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->sb_type = bsize; 1019233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1020233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < MAX_MB_PLANE; ++i) { 1021233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].coeff = ctx->coeff_pbuf[i][0]; 1022233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].qcoeff = ctx->qcoeff_pbuf[i][0]; 1023233d2500723e5594f3e7c70896ffeeef32b9c950ywan pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0]; 1024233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].eobs = ctx->eobs_pbuf[i][0]; 1025233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1026233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->is_coded = 0; 1027233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->skip_recode = 0; 1028233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1029233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Set to zero to make sure we do not use the previous encoded frame stats 1030233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->skip = 0; 1031233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1032233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->source_variance = get_sby_perpixel_variance(cpi, x, bsize); 1033233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1034233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (aq_mode == VARIANCE_AQ) { 1035233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int energy = bsize <= BLOCK_16X16 ? x->mb_energy 1036233d2500723e5594f3e7c70896ffeeef32b9c950ywan : vp9_block_energy(cpi, x, bsize); 1037233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1038233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->frame_type == KEY_FRAME || 1039233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->refresh_alt_ref_frame || 1040233d2500723e5594f3e7c70896ffeeef32b9c950ywan (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) { 1041233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->segment_id = vp9_vaq_segment_id(energy); 1042233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1043233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map 1044233d2500723e5594f3e7c70896ffeeef32b9c950ywan : cm->last_frame_seg_map; 1045233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col); 1046233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1047233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1048233d2500723e5594f3e7c70896ffeeef32b9c950ywan rdmult_ratio = vp9_vaq_rdmult_ratio(energy); 1049233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_init_plane_quantizers(cpi, x); 1050233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1051233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1052233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Save rdmult before it might be changed, so it can be restored later. 1053233d2500723e5594f3e7c70896ffeeef32b9c950ywan orig_rdmult = x->rdmult; 1054233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.tuning == VP8_TUNE_SSIM) 1055233d2500723e5594f3e7c70896ffeeef32b9c950ywan activity_masking(cpi, x); 1056233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1057233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (aq_mode == VARIANCE_AQ) { 1058233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_clear_system_state(); 1059233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->rdmult = (int)round(x->rdmult * rdmult_ratio); 1060233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (aq_mode == COMPLEXITY_AQ) { 1061233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mi_offset = mi_row * cm->mi_cols + mi_col; 1062233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char complexity = cpi->complexity_map[mi_offset]; 1063233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int is_edge = (mi_row <= 1) || (mi_row >= (cm->mi_rows - 2)) || 1064233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mi_col <= 1) || (mi_col >= (cm->mi_cols - 2)); 1065233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!is_edge && (complexity > 128)) 1066233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->rdmult += ((x->rdmult * (complexity - 128)) / 256); 1067233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { 1068233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map 1069233d2500723e5594f3e7c70896ffeeef32b9c950ywan : cm->last_frame_seg_map; 1070233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If segment 1, use rdmult for that segment. 1071233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vp9_get_segment_id(cm, map, bsize, mi_row, mi_col)) 1072233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh); 1073233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1074233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1075233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Find best coding mode & reconstruct the MB so it is available 1076233d2500723e5594f3e7c70896ffeeef32b9c950ywan // as a predictor for MBs that follow in the SB 1077233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frame_is_intra_only(cm)) { 1078233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx, 1079233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd); 1080233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1081233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize >= BLOCK_8X8) 1082233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col, 1083233d2500723e5594f3e7c70896ffeeef32b9c950ywan totalrate, totaldist, bsize, ctx, best_rd); 1084233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 1085233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate, 1086233d2500723e5594f3e7c70896ffeeef32b9c950ywan totaldist, bsize, ctx, best_rd); 1087233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1088233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1089233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (aq_mode == VARIANCE_AQ) { 1090233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->rdmult = orig_rdmult; 1091233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (*totalrate != INT_MAX) { 1092233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_clear_system_state(); 1093233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totalrate = (int)round(*totalrate * rdmult_ratio); 1094233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1095233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) || 1096233d2500723e5594f3e7c70896ffeeef32b9c950ywan (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)) { 1097233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->rdmult = orig_rdmult; 1098233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1099233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1100233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1101233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void update_stats(VP9_COMP *cpi) { 1102233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 1103233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCK *const x = &cpi->mb; 1104233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 1105233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MODE_INFO *const mi = xd->mi[0]; 1106233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MB_MODE_INFO *const mbmi = &mi->mbmi; 1107233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1108233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!frame_is_intra_only(cm)) { 1109233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id, 1110233d2500723e5594f3e7c70896ffeeef32b9c950ywan SEG_LVL_REF_FRAME); 1111233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!seg_ref_active) { 1112233d2500723e5594f3e7c70896ffeeef32b9c950ywan FRAME_COUNTS *const counts = &cm->counts; 1113233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int inter_block = is_inter_block(mbmi); 1114233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1115233d2500723e5594f3e7c70896ffeeef32b9c950ywan counts->intra_inter[vp9_get_intra_inter_context(xd)][inter_block]++; 1116233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1117233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If the segment reference feature is enabled we have only a single 1118233d2500723e5594f3e7c70896ffeeef32b9c950ywan // reference frame allowed for the segment so exclude it from 1119233d2500723e5594f3e7c70896ffeeef32b9c950ywan // the reference frame counts used to work out probabilities. 1120233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (inter_block) { 1121233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0]; 1122233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1123233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->reference_mode == REFERENCE_MODE_SELECT) 1124233d2500723e5594f3e7c70896ffeeef32b9c950ywan counts->comp_inter[vp9_get_reference_mode_context(cm, xd)] 1125233d2500723e5594f3e7c70896ffeeef32b9c950ywan [has_second_ref(mbmi)]++; 1126233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1127233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (has_second_ref(mbmi)) { 1128233d2500723e5594f3e7c70896ffeeef32b9c950ywan counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)] 1129233d2500723e5594f3e7c70896ffeeef32b9c950ywan [ref0 == GOLDEN_FRAME]++; 1130233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1131233d2500723e5594f3e7c70896ffeeef32b9c950ywan counts->single_ref[vp9_get_pred_context_single_ref_p1(xd)][0] 1132233d2500723e5594f3e7c70896ffeeef32b9c950ywan [ref0 != LAST_FRAME]++; 1133233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ref0 != LAST_FRAME) 1134233d2500723e5594f3e7c70896ffeeef32b9c950ywan counts->single_ref[vp9_get_pred_context_single_ref_p2(xd)][1] 1135233d2500723e5594f3e7c70896ffeeef32b9c950ywan [ref0 != GOLDEN_FRAME]++; 1136233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1137233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1138233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1139233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1140233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1141233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1142233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic BLOCK_SIZE *get_sb_partitioning(MACROBLOCK *x, BLOCK_SIZE bsize) { 1143233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (bsize) { 1144233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_64X64: 1145233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &x->sb64_partitioning; 1146233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_32X32: 1147233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &x->sb_partitioning[x->sb_index]; 1148233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_16X16: 1149233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &x->mb_partitioning[x->sb_index][x->mb_index]; 1150233d2500723e5594f3e7c70896ffeeef32b9c950ywan case BLOCK_8X8: 1151233d2500723e5594f3e7c70896ffeeef32b9c950ywan return &x->b_partitioning[x->sb_index][x->mb_index][x->b_index]; 1152233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 1153233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(0); 1154233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 1155233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1156233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1157233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1158233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void restore_context(VP9_COMP *cpi, int mi_row, int mi_col, 1159233d2500723e5594f3e7c70896ffeeef32b9c950ywan ENTROPY_CONTEXT a[16 * MAX_MB_PLANE], 1160233d2500723e5594f3e7c70896ffeeef32b9c950ywan ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], 1161233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8], 1162233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize) { 1163233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 1164233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 1165233d2500723e5594f3e7c70896ffeeef32b9c950ywan int p; 1166233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; 1167233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; 1168233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_width = num_8x8_blocks_wide_lookup[bsize]; 1169233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_height = num_8x8_blocks_high_lookup[bsize]; 1170233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (p = 0; p < MAX_MB_PLANE; p++) { 1171233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy( 1172233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->above_context[p] + ((mi_col * 2) >> xd->plane[p].subsampling_x), 1173233d2500723e5594f3e7c70896ffeeef32b9c950ywan a + num_4x4_blocks_wide * p, 1174233d2500723e5594f3e7c70896ffeeef32b9c950ywan (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >> 1175233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->plane[p].subsampling_x); 1176233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy( 1177233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->left_context[p] 1178233d2500723e5594f3e7c70896ffeeef32b9c950ywan + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y), 1179233d2500723e5594f3e7c70896ffeeef32b9c950ywan l + num_4x4_blocks_high * p, 1180233d2500723e5594f3e7c70896ffeeef32b9c950ywan (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >> 1181233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->plane[p].subsampling_y); 1182233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1183233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy(xd->above_seg_context + mi_col, sa, 1184233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizeof(*xd->above_seg_context) * mi_width); 1185233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy(xd->left_seg_context + (mi_row & MI_MASK), sl, 1186233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizeof(xd->left_seg_context[0]) * mi_height); 1187233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1188233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void save_context(VP9_COMP *cpi, int mi_row, int mi_col, 1189233d2500723e5594f3e7c70896ffeeef32b9c950ywan ENTROPY_CONTEXT a[16 * MAX_MB_PLANE], 1190233d2500723e5594f3e7c70896ffeeef32b9c950ywan ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], 1191233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_CONTEXT sa[8], PARTITION_CONTEXT sl[8], 1192233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize) { 1193233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCK *const x = &cpi->mb; 1194233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MACROBLOCKD *const xd = &x->e_mbd; 1195233d2500723e5594f3e7c70896ffeeef32b9c950ywan int p; 1196233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; 1197233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; 1198233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_width = num_8x8_blocks_wide_lookup[bsize]; 1199233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_height = num_8x8_blocks_high_lookup[bsize]; 1200233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1201233d2500723e5594f3e7c70896ffeeef32b9c950ywan // buffer the above/left context information of the block in search. 1202233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (p = 0; p < MAX_MB_PLANE; ++p) { 1203233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy( 1204233d2500723e5594f3e7c70896ffeeef32b9c950ywan a + num_4x4_blocks_wide * p, 1205233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->above_context[p] + (mi_col * 2 >> xd->plane[p].subsampling_x), 1206233d2500723e5594f3e7c70896ffeeef32b9c950ywan (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >> 1207233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->plane[p].subsampling_x); 1208233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy( 1209233d2500723e5594f3e7c70896ffeeef32b9c950ywan l + num_4x4_blocks_high * p, 1210233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->left_context[p] 1211233d2500723e5594f3e7c70896ffeeef32b9c950ywan + ((mi_row & MI_MASK) * 2 >> xd->plane[p].subsampling_y), 1212233d2500723e5594f3e7c70896ffeeef32b9c950ywan (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >> 1213233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->plane[p].subsampling_y); 1214233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1215233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy(sa, xd->above_seg_context + mi_col, 1216233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizeof(*xd->above_seg_context) * mi_width); 1217233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy(sl, xd->left_seg_context + (mi_row & MI_MASK), 1218233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizeof(xd->left_seg_context[0]) * mi_height); 1219233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1220233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1221233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_b(VP9_COMP *cpi, const TileInfo *const tile, 1222233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA **tp, int mi_row, int mi_col, 1223233d2500723e5594f3e7c70896ffeeef32b9c950ywan int output_enabled, BLOCK_SIZE bsize) { 1224233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 1225233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1226233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize < BLOCK_8X8) { 1227233d2500723e5594f3e7c70896ffeeef32b9c950ywan // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 1228233d2500723e5594f3e7c70896ffeeef32b9c950ywan // there is nothing to be done. 1229233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->ab_index > 0) 1230233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 1231233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1232233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, bsize); 1233233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_state(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize, 1234233d2500723e5594f3e7c70896ffeeef32b9c950ywan output_enabled); 1235233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize); 1236233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1237233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) { 1238233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_stats(cpi); 1239233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1240233d2500723e5594f3e7c70896ffeeef32b9c950ywan (*tp)->token = EOSB_TOKEN; 1241233d2500723e5594f3e7c70896ffeeef32b9c950ywan (*tp)++; 1242233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1243233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1244233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1245233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_sb(VP9_COMP *cpi, const TileInfo *const tile, 1246233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA **tp, int mi_row, int mi_col, 1247233d2500723e5594f3e7c70896ffeeef32b9c950ywan int output_enabled, BLOCK_SIZE bsize) { 1248233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 1249233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 1250233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 1251233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1252233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4; 1253233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctx; 1254233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_TYPE partition; 1255233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE subsize; 1256233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1257233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) 1258233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 1259233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1260233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize >= BLOCK_8X8) { 1261233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx = partition_plane_context(xd, mi_row, mi_col, bsize); 1262233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = *get_sb_partitioning(x, bsize); 1263233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1264233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx = 0; 1265233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = BLOCK_4X4; 1266233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1267233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1268233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition = partition_lookup[bsl][subsize]; 1269233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1270233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (partition) { 1271233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_NONE: 1272233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled && bsize >= BLOCK_8X8) 1273233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->counts.partition[ctx][PARTITION_NONE]++; 1274233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize); 1275233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1276233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_VERT: 1277233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) 1278233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->counts.partition[ctx][PARTITION_VERT]++; 1279233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 1280233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize); 1281233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_col + hbs < cm->mi_cols) { 1282233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 1283233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize); 1284233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1285233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1286233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_HORZ: 1287233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) 1288233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->counts.partition[ctx][PARTITION_HORZ]++; 1289233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 1290233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize); 1291233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + hbs < cm->mi_rows) { 1292233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 1293233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize); 1294233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1295233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1296233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_SPLIT: 1297233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, PARTITION_SPLIT); 1298233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) 1299233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->counts.partition[ctx][PARTITION_SPLIT]++; 1300233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1301233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 1302233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize); 1303233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 1304233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, subsize); 1305233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 2; 1306233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, subsize); 1307233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 3; 1308233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled, 1309233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize); 1310233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1311233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 1312233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert("Invalid partition type."); 1313233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1314233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1315233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) 1316233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_partition_context(xd, mi_row, mi_col, subsize, bsize); 1317233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1318233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1319233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Check to see if the given partition size is allowed for a specified number 1320233d2500723e5594f3e7c70896ffeeef32b9c950ywan// of 8x8 block rows and columns remaining in the image. 1321233d2500723e5594f3e7c70896ffeeef32b9c950ywan// If not then return the largest allowed partition size 1322233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, 1323233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rows_left, int cols_left, 1324233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *bh, int *bw) { 1325233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rows_left <= 0 || cols_left <= 0) { 1326233d2500723e5594f3e7c70896ffeeef32b9c950ywan return MIN(bsize, BLOCK_8X8); 1327233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1328233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (; bsize > 0; bsize -= 3) { 1329233d2500723e5594f3e7c70896ffeeef32b9c950ywan *bh = num_8x8_blocks_high_lookup[bsize]; 1330233d2500723e5594f3e7c70896ffeeef32b9c950ywan *bw = num_8x8_blocks_wide_lookup[bsize]; 1331233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((*bh <= rows_left) && (*bw <= cols_left)) { 1332233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1333233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1334233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1335233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1336233d2500723e5594f3e7c70896ffeeef32b9c950ywan return bsize; 1337233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1338233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1339233d2500723e5594f3e7c70896ffeeef32b9c950ywan// This function attempts to set all mode info entries in a given SB64 1340233d2500723e5594f3e7c70896ffeeef32b9c950ywan// to the same block partition size. 1341233d2500723e5594f3e7c70896ffeeef32b9c950ywan// However, at the bottom and right borders of the image the requested size 1342233d2500723e5594f3e7c70896ffeeef32b9c950ywan// may not be allowed in which case this code attempts to choose the largest 1343233d2500723e5594f3e7c70896ffeeef32b9c950ywan// allowable partition. 1344233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void set_fixed_partitioning(VP9_COMP *cpi, const TileInfo *const tile, 1345233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **mi_8x8, int mi_row, int mi_col, 1346233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize) { 1347233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 1348233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mis = cm->mi_stride; 1349233d2500723e5594f3e7c70896ffeeef32b9c950ywan int row8x8_remaining = tile->mi_row_end - mi_row; 1350233d2500723e5594f3e7c70896ffeeef32b9c950ywan int col8x8_remaining = tile->mi_col_end - mi_col; 1351233d2500723e5594f3e7c70896ffeeef32b9c950ywan int block_row, block_col; 1352233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col; 1353233d2500723e5594f3e7c70896ffeeef32b9c950ywan int bh = num_8x8_blocks_high_lookup[bsize]; 1354233d2500723e5594f3e7c70896ffeeef32b9c950ywan int bw = num_8x8_blocks_wide_lookup[bsize]; 1355233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1356233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert((row8x8_remaining > 0) && (col8x8_remaining > 0)); 1357233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1358233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Apply the requested partition size to the SB64 if it is all "in image" 1359233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((col8x8_remaining >= MI_BLOCK_SIZE) && 1360233d2500723e5594f3e7c70896ffeeef32b9c950ywan (row8x8_remaining >= MI_BLOCK_SIZE)) { 1361233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) { 1362233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) { 1363233d2500723e5594f3e7c70896ffeeef32b9c950ywan int index = block_row * mis + block_col; 1364233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[index] = mi_upper_left + index; 1365233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[index]->mbmi.sb_type = bsize; 1366233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1367233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1368233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1369233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Else this is a partial SB64. 1370233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (block_row = 0; block_row < MI_BLOCK_SIZE; block_row += bh) { 1371233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (block_col = 0; block_col < MI_BLOCK_SIZE; block_col += bw) { 1372233d2500723e5594f3e7c70896ffeeef32b9c950ywan int index = block_row * mis + block_col; 1373233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Find a partition size that fits 1374233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize = find_partition_size(bsize, 1375233d2500723e5594f3e7c70896ffeeef32b9c950ywan (row8x8_remaining - block_row), 1376233d2500723e5594f3e7c70896ffeeef32b9c950ywan (col8x8_remaining - block_col), &bh, &bw); 1377233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[index] = mi_upper_left + index; 1378233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[index]->mbmi.sb_type = bsize; 1379233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1380233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1381233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1382233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1383233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1384233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void copy_partitioning(VP9_COMMON *cm, MODE_INFO **mi_8x8, 1385233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **prev_mi_8x8) { 1386233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mis = cm->mi_stride; 1387233d2500723e5594f3e7c70896ffeeef32b9c950ywan int block_row, block_col; 1388233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1389233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (block_row = 0; block_row < 8; ++block_row) { 1390233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (block_col = 0; block_col < 8; ++block_col) { 1391233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO *const prev_mi = prev_mi_8x8[block_row * mis + block_col]; 1392233d2500723e5594f3e7c70896ffeeef32b9c950ywan const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0; 1393233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1394233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (prev_mi) { 1395233d2500723e5594f3e7c70896ffeeef32b9c950ywan const ptrdiff_t offset = prev_mi - cm->prev_mi; 1396233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[block_row * mis + block_col] = cm->mi + offset; 1397233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[block_row * mis + block_col]->mbmi.sb_type = sb_type; 1398233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1399233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1400233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1401233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1402233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1403233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) { 1404233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mis = cm->mi_stride; 1405233d2500723e5594f3e7c70896ffeeef32b9c950ywan int block_row, block_col; 1406233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1407233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->prev_mi) { 1408233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (block_row = 0; block_row < 8; ++block_row) { 1409233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (block_col = 0; block_col < 8; ++block_col) { 1410233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MODE_INFO *prev_mi = prev_mi_8x8[block_row * mis + block_col]; 1411233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (prev_mi) { 1412233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (abs(prev_mi->mbmi.mv[0].as_mv.row) >= 8 || 1413233d2500723e5594f3e7c70896ffeeef32b9c950ywan abs(prev_mi->mbmi.mv[0].as_mv.col) >= 8) 1414233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1415233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1416233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1417233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1418233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1419233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1420233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1421233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1422233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void update_state_rt(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, 1423233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, int bsize) { 1424233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 1425233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 1426233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 1427233d2500723e5594f3e7c70896ffeeef32b9c950ywan MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; 1428233d2500723e5594f3e7c70896ffeeef32b9c950ywan const struct segmentation *const seg = &cm->seg; 1429233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1430233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(xd->mi[0]) = ctx->mic; 1431233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1432233d2500723e5594f3e7c70896ffeeef32b9c950ywan // For in frame adaptive Q, check for reseting the segment_id and updating 1433233d2500723e5594f3e7c70896ffeeef32b9c950ywan // the cyclic refresh map. 1434233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) && seg->enabled) { 1435233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_cyclic_refresh_update_segment(cpi, &xd->mi[0]->mbmi, 1436233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row, mi_col, bsize, 1); 1437233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_init_plane_quantizers(cpi, x); 1438233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1439233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1440233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_inter_block(mbmi)) { 1441233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_update_mv_count(cm, xd); 1442233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1443233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->interp_filter == SWITCHABLE) { 1444233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int pred_ctx = vp9_get_pred_context_switchable_interp(xd); 1445233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++cm->counts.switchable_interp[pred_ctx][mbmi->interp_filter]; 1446233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1447233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1448233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1449233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->skip = ctx->skip; 1450233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1451233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1452233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_b_rt(VP9_COMP *cpi, const TileInfo *const tile, 1453233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA **tp, int mi_row, int mi_col, 1454233d2500723e5594f3e7c70896ffeeef32b9c950ywan int output_enabled, BLOCK_SIZE bsize) { 1455233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 1456233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1457233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize < BLOCK_8X8) { 1458233d2500723e5594f3e7c70896ffeeef32b9c950ywan // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 1459233d2500723e5594f3e7c70896ffeeef32b9c950ywan // there is nothing to be done. 1460233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->ab_index > 0) 1461233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 1462233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1463233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1464233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, bsize); 1465233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_state_rt(cpi, get_block_context(x, bsize), mi_row, mi_col, bsize); 1466233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1467233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_superblock(cpi, tp, output_enabled, mi_row, mi_col, bsize); 1468233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_stats(cpi); 1469233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1470233d2500723e5594f3e7c70896ffeeef32b9c950ywan (*tp)->token = EOSB_TOKEN; 1471233d2500723e5594f3e7c70896ffeeef32b9c950ywan (*tp)++; 1472233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1473233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1474233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_sb_rt(VP9_COMP *cpi, const TileInfo *const tile, 1475233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA **tp, int mi_row, int mi_col, 1476233d2500723e5594f3e7c70896ffeeef32b9c950ywan int output_enabled, BLOCK_SIZE bsize) { 1477233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 1478233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 1479233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 1480233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1481233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4; 1482233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ctx; 1483233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_TYPE partition; 1484233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE subsize; 1485233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1486233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) 1487233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 1488233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1489233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize >= BLOCK_8X8) { 1490233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &cpi->mb.e_mbd; 1491233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int idx_str = xd->mi_stride * mi_row + mi_col; 1492233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO ** mi_8x8 = cm->mi_grid_visible + idx_str; 1493233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx = partition_plane_context(xd, mi_row, mi_col, bsize); 1494233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = mi_8x8[0]->mbmi.sb_type; 1495233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1496233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx = 0; 1497233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = BLOCK_4X4; 1498233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1499233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1500233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition = partition_lookup[bsl][subsize]; 1501233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1502233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (partition) { 1503233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_NONE: 1504233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled && bsize >= BLOCK_8X8) 1505233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->counts.partition[ctx][PARTITION_NONE]++; 1506233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize); 1507233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1508233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_VERT: 1509233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) 1510233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->counts.partition[ctx][PARTITION_VERT]++; 1511233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 1512233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize); 1513233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_col + hbs < cm->mi_cols) { 1514233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 1515233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, 1516233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize); 1517233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1518233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1519233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_HORZ: 1520233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) 1521233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->counts.partition[ctx][PARTITION_HORZ]++; 1522233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 1523233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize); 1524233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + hbs < cm->mi_rows) { 1525233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 1526233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_b_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, 1527233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize); 1528233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1529233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1530233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_SPLIT: 1531233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, PARTITION_SPLIT); 1532233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) 1533233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->counts.partition[ctx][PARTITION_SPLIT]++; 1534233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1535233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 1536233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, subsize); 1537233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 1538233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb_rt(cpi, tile, tp, mi_row, mi_col + hbs, output_enabled, 1539233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize); 1540233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 2; 1541233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col, output_enabled, 1542233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize); 1543233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 3; 1544233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb_rt(cpi, tile, tp, mi_row + hbs, mi_col + hbs, output_enabled, 1545233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize); 1546233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1547233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 1548233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert("Invalid partition type."); 1549233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1550233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1551233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition != PARTITION_SPLIT || bsize == BLOCK_8X8) 1552233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_partition_context(xd, mi_row, mi_col, subsize, bsize); 1553233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1554233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1555233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void rd_use_partition(VP9_COMP *cpi, 1556233d2500723e5594f3e7c70896ffeeef32b9c950ywan const TileInfo *const tile, 1557233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **mi_8x8, 1558233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA **tp, int mi_row, int mi_col, 1559233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize, int *rate, int64_t *dist, 1560233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_recon) { 1561233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 1562233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 1563233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 1564233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mis = cm->mi_stride; 1565233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int bsl = b_width_log2(bsize); 1566233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mi_step = num_4x4_blocks_wide_lookup[bsize] / 2; 1567233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int bss = (1 << bsl) / 4; 1568233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, pl; 1569233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_TYPE partition = PARTITION_NONE; 1570233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE subsize; 1571233d2500723e5594f3e7c70896ffeeef32b9c950ywan ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; 1572233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_CONTEXT sl[8], sa[8]; 1573233d2500723e5594f3e7c70896ffeeef32b9c950ywan int last_part_rate = INT_MAX; 1574233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t last_part_dist = INT64_MAX; 1575233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t last_part_rd = INT64_MAX; 1576233d2500723e5594f3e7c70896ffeeef32b9c950ywan int none_rate = INT_MAX; 1577233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t none_dist = INT64_MAX; 1578233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t none_rd = INT64_MAX; 1579233d2500723e5594f3e7c70896ffeeef32b9c950ywan int chosen_rate = INT_MAX; 1580233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t chosen_dist = INT64_MAX; 1581233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t chosen_rd = INT64_MAX; 1582233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE sub_subsize = BLOCK_4X4; 1583233d2500723e5594f3e7c70896ffeeef32b9c950ywan int splits_below = 0; 1584233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type; 1585233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_partition_search = 1; 1586233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1587233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) 1588233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 1589233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1590233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(num_4x4_blocks_wide_lookup[bsize] == 1591233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_4x4_blocks_high_lookup[bsize]); 1592233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1593233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition = partition_lookup[bsl][bs_type]; 1594233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, partition); 1595233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1596233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize < BLOCK_8X8) { 1597233d2500723e5594f3e7c70896ffeeef32b9c950ywan // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 1598233d2500723e5594f3e7c70896ffeeef32b9c950ywan // there is nothing to be done. 1599233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->ab_index != 0) { 1600233d2500723e5594f3e7c70896ffeeef32b9c950ywan *rate = 0; 1601233d2500723e5594f3e7c70896ffeeef32b9c950ywan *dist = 0; 1602233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 1603233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1604233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1605233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = subsize; 1606233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1607233d2500723e5594f3e7c70896ffeeef32b9c950ywan save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 1608233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1609233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize == BLOCK_16X16) { 1610233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, bsize); 1611233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mb_energy = vp9_block_energy(cpi, x, bsize); 1612233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1613233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize); 1614233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1615233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1616233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!x->in_active_map) { 1617233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_partition_search = 0; 1618233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + (mi_step >> 1) < cm->mi_rows && 1619233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_col + (mi_step >> 1) < cm->mi_cols) { 1620233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = bsize; 1621233d2500723e5594f3e7c70896ffeeef32b9c950ywan bs_type = mi_8x8[0]->mbmi.sb_type = bsize; 1622233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = bsize; 1623233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition = PARTITION_NONE; 1624233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1625233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1626233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (do_partition_search && 1627233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.partition_search_type == SEARCH_PARTITION && 1628233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.adjust_partitioning_from_last_frame) { 1629233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check if any of the sub blocks are further split. 1630233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) { 1631233d2500723e5594f3e7c70896ffeeef32b9c950ywan sub_subsize = get_subsize(subsize, PARTITION_SPLIT); 1632233d2500723e5594f3e7c70896ffeeef32b9c950ywan splits_below = 1; 1633233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) { 1634233d2500723e5594f3e7c70896ffeeef32b9c950ywan int jj = i >> 1, ii = i & 0x01; 1635233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO * this_mi = mi_8x8[jj * bss * mis + ii * bss]; 1636233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (this_mi && this_mi->mbmi.sb_type >= sub_subsize) { 1637233d2500723e5594f3e7c70896ffeeef32b9c950ywan splits_below = 0; 1638233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1639233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1640233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1641233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1642233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If partition is not none try none unless each of the 4 splits are split 1643233d2500723e5594f3e7c70896ffeeef32b9c950ywan // even further.. 1644233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition != PARTITION_NONE && !splits_below && 1645233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row + (mi_step >> 1) < cm->mi_rows && 1646233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_col + (mi_step >> 1) < cm->mi_cols) { 1647233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = bsize; 1648233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize, 1649233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, bsize), INT64_MAX); 1650233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1651233d2500723e5594f3e7c70896ffeeef32b9c950ywan pl = partition_plane_context(xd, mi_row, mi_col, bsize); 1652233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1653233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (none_rate < INT_MAX) { 1654233d2500723e5594f3e7c70896ffeeef32b9c950ywan none_rate += x->partition_cost[pl][PARTITION_NONE]; 1655233d2500723e5594f3e7c70896ffeeef32b9c950ywan none_rd = RDCOST(x->rdmult, x->rddiv, none_rate, none_dist); 1656233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1657233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1658233d2500723e5594f3e7c70896ffeeef32b9c950ywan restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 1659233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[0]->mbmi.sb_type = bs_type; 1660233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = subsize; 1661233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1662233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1663233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1664233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (partition) { 1665233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_NONE: 1666233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, 1667233d2500723e5594f3e7c70896ffeeef32b9c950ywan &last_part_dist, bsize, 1668233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, bsize), INT64_MAX); 1669233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1670233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_HORZ: 1671233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 1672233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, 1673233d2500723e5594f3e7c70896ffeeef32b9c950ywan &last_part_dist, subsize, 1674233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize), INT64_MAX); 1675233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (last_part_rate != INT_MAX && 1676233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize >= BLOCK_8X8 && mi_row + (mi_step >> 1) < cm->mi_rows) { 1677233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rt = 0; 1678233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t dt = 0; 1679233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_state(cpi, get_block_context(x, subsize), mi_row, mi_col, 1680233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize, 0); 1681233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); 1682233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 1683233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &rt, &dt, 1684233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize, get_block_context(x, subsize), INT64_MAX); 1685233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rt == INT_MAX || dt == INT64_MAX) { 1686233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_rate = INT_MAX; 1687233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_dist = INT64_MAX; 1688233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1689233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1690233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1691233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_rate += rt; 1692233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_dist += dt; 1693233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1694233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1695233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_VERT: 1696233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 1697233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate, 1698233d2500723e5594f3e7c70896ffeeef32b9c950ywan &last_part_dist, subsize, 1699233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize), INT64_MAX); 1700233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (last_part_rate != INT_MAX && 1701233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) { 1702233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rt = 0; 1703233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t dt = 0; 1704233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_state(cpi, get_block_context(x, subsize), mi_row, mi_col, 1705233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize, 0); 1706233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); 1707233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 1708233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &rt, &dt, 1709233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize, get_block_context(x, subsize), INT64_MAX); 1710233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rt == INT_MAX || dt == INT64_MAX) { 1711233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_rate = INT_MAX; 1712233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_dist = INT64_MAX; 1713233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1714233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1715233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_rate += rt; 1716233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_dist += dt; 1717233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1718233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1719233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_SPLIT: 1720233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Split partition. 1721233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_rate = 0; 1722233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_dist = 0; 1723233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) { 1724233d2500723e5594f3e7c70896ffeeef32b9c950ywan int x_idx = (i & 1) * (mi_step >> 1); 1725233d2500723e5594f3e7c70896ffeeef32b9c950ywan int y_idx = (i >> 1) * (mi_step >> 1); 1726233d2500723e5594f3e7c70896ffeeef32b9c950ywan int jj = i >> 1, ii = i & 0x01; 1727233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rt; 1728233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t dt; 1729233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1730233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) 1731233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 1732233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1733233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = i; 1734233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1735233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp, 1736233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt, 1737233d2500723e5594f3e7c70896ffeeef32b9c950ywan i != 3); 1738233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rt == INT_MAX || dt == INT64_MAX) { 1739233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_rate = INT_MAX; 1740233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_dist = INT64_MAX; 1741233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1742233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1743233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_rate += rt; 1744233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_dist += dt; 1745233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1746233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1747233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 1748233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(0); 1749233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1750233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1751233d2500723e5594f3e7c70896ffeeef32b9c950ywan pl = partition_plane_context(xd, mi_row, mi_col, bsize); 1752233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (last_part_rate < INT_MAX) { 1753233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_rate += x->partition_cost[pl][partition]; 1754233d2500723e5594f3e7c70896ffeeef32b9c950ywan last_part_rd = RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist); 1755233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1756233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1757233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (do_partition_search 1758233d2500723e5594f3e7c70896ffeeef32b9c950ywan && cpi->sf.adjust_partitioning_from_last_frame 1759233d2500723e5594f3e7c70896ffeeef32b9c950ywan && cpi->sf.partition_search_type == SEARCH_PARTITION 1760233d2500723e5594f3e7c70896ffeeef32b9c950ywan && partition != PARTITION_SPLIT && bsize > BLOCK_8X8 1761233d2500723e5594f3e7c70896ffeeef32b9c950ywan && (mi_row + mi_step < cm->mi_rows || 1762233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row + (mi_step >> 1) == cm->mi_rows) 1763233d2500723e5594f3e7c70896ffeeef32b9c950ywan && (mi_col + mi_step < cm->mi_cols || 1764233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_col + (mi_step >> 1) == cm->mi_cols)) { 1765233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT); 1766233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rate = 0; 1767233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_dist = 0; 1768233d2500723e5594f3e7c70896ffeeef32b9c950ywan restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 1769233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1770233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Split partition. 1771233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4; i++) { 1772233d2500723e5594f3e7c70896ffeeef32b9c950ywan int x_idx = (i & 1) * (mi_step >> 1); 1773233d2500723e5594f3e7c70896ffeeef32b9c950ywan int y_idx = (i >> 1) * (mi_step >> 1); 1774233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rt = 0; 1775233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t dt = 0; 1776233d2500723e5594f3e7c70896ffeeef32b9c950ywan ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; 1777233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_CONTEXT sl[8], sa[8]; 1778233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1779233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols)) 1780233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 1781233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1782233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, split_subsize) = i; 1783233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_partitioning(x, bsize) = split_subsize; 1784233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_partitioning(x, split_subsize) = split_subsize; 1785233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1786233d2500723e5594f3e7c70896ffeeef32b9c950ywan save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 1787233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1788233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &rt, &dt, 1789233d2500723e5594f3e7c70896ffeeef32b9c950ywan split_subsize, get_block_context(x, split_subsize), 1790233d2500723e5594f3e7c70896ffeeef32b9c950ywan INT64_MAX); 1791233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1792233d2500723e5594f3e7c70896ffeeef32b9c950ywan restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 1793233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1794233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rt == INT_MAX || dt == INT64_MAX) { 1795233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rate = INT_MAX; 1796233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_dist = INT64_MAX; 1797233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1798233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1799233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1800233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rate += rt; 1801233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_dist += dt; 1802233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1803233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (i != 3) 1804233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0, 1805233d2500723e5594f3e7c70896ffeeef32b9c950ywan split_subsize); 1806233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1807233d2500723e5594f3e7c70896ffeeef32b9c950ywan pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx, 1808233d2500723e5594f3e7c70896ffeeef32b9c950ywan split_subsize); 1809233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rate += x->partition_cost[pl][PARTITION_NONE]; 1810233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1811233d2500723e5594f3e7c70896ffeeef32b9c950ywan pl = partition_plane_context(xd, mi_row, mi_col, bsize); 1812233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (chosen_rate < INT_MAX) { 1813233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rate += x->partition_cost[pl][PARTITION_SPLIT]; 1814233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rd = RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist); 1815233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1816233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1817233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1818233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If last_part is better set the partitioning to that... 1819233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (last_part_rd < chosen_rd) { 1820233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[0]->mbmi.sb_type = bsize; 1821233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize >= BLOCK_8X8) 1822233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = subsize; 1823233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rate = last_part_rate; 1824233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_dist = last_part_dist; 1825233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rd = last_part_rd; 1826233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1827233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If none was better set the partitioning to that... 1828233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (none_rd < chosen_rd) { 1829233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize >= BLOCK_8X8) 1830233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = bsize; 1831233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rate = none_rate; 1832233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_dist = none_dist; 1833233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1834233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1835233d2500723e5594f3e7c70896ffeeef32b9c950ywan restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 1836233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1837233d2500723e5594f3e7c70896ffeeef32b9c950ywan // We must have chosen a partitioning and encoding or we'll fail later on. 1838233d2500723e5594f3e7c70896ffeeef32b9c950ywan // No other opportunities for success. 1839233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ( bsize == BLOCK_64X64) 1840233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(chosen_rate < INT_MAX && chosen_dist < INT64_MAX); 1841233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1842233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (do_recon) { 1843233d2500723e5594f3e7c70896ffeeef32b9c950ywan int output_enabled = (bsize == BLOCK_64X64); 1844233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1845233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check the projected output rate for this SB against it's target 1846233d2500723e5594f3e7c70896ffeeef32b9c950ywan // and and if necessary apply a Q delta using segmentation to get 1847233d2500723e5594f3e7c70896ffeeef32b9c950ywan // closer to the target. 1848233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) { 1849233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, 1850233d2500723e5594f3e7c70896ffeeef32b9c950ywan output_enabled, chosen_rate); 1851233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1852233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1853233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) 1854233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, 1855233d2500723e5594f3e7c70896ffeeef32b9c950ywan chosen_rate, chosen_dist); 1856233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1857233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize); 1858233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1859233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1860233d2500723e5594f3e7c70896ffeeef32b9c950ywan *rate = chosen_rate; 1861233d2500723e5594f3e7c70896ffeeef32b9c950ywan *dist = chosen_dist; 1862233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1863233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1864233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = { 1865233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, 1866233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, 1867233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_8X8, BLOCK_8X8, BLOCK_8X8, 1868233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, 1869233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_16X16 1870233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 1871233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1872233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = { 1873233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, 1874233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_16X16, BLOCK_32X32, BLOCK_32X32, 1875233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_32X32, BLOCK_64X64, BLOCK_64X64, 1876233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, 1877233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_64X64 1878233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 1879233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1880233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Look at all the mode_info entries for blocks that are part of this 1881233d2500723e5594f3e7c70896ffeeef32b9c950ywan// partition and find the min and max values for sb_type. 1882233d2500723e5594f3e7c70896ffeeef32b9c950ywan// At the moment this is designed to work on a 64x64 SB but could be 1883233d2500723e5594f3e7c70896ffeeef32b9c950ywan// adjusted to use a size parameter. 1884233d2500723e5594f3e7c70896ffeeef32b9c950ywan// 1885233d2500723e5594f3e7c70896ffeeef32b9c950ywan// The min and max are assumed to have been initialized prior to calling this 1886233d2500723e5594f3e7c70896ffeeef32b9c950ywan// function so repeat calls can accumulate a min and max of more than one sb64. 1887233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void get_sb_partition_size_range(VP9_COMP *cpi, MODE_INFO ** mi_8x8, 1888233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE * min_block_size, 1889233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE * max_block_size ) { 1890233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &cpi->mb.e_mbd; 1891233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sb_width_in_blocks = MI_BLOCK_SIZE; 1892233d2500723e5594f3e7c70896ffeeef32b9c950ywan int sb_height_in_blocks = MI_BLOCK_SIZE; 1893233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, j; 1894233d2500723e5594f3e7c70896ffeeef32b9c950ywan int index = 0; 1895233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1896233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check the sb_type for each block that belongs to this region. 1897233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < sb_height_in_blocks; ++i) { 1898233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < sb_width_in_blocks; ++j) { 1899233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO * mi = mi_8x8[index+j]; 1900233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : 0; 1901233d2500723e5594f3e7c70896ffeeef32b9c950ywan *min_block_size = MIN(*min_block_size, sb_type); 1902233d2500723e5594f3e7c70896ffeeef32b9c950ywan *max_block_size = MAX(*max_block_size, sb_type); 1903233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1904233d2500723e5594f3e7c70896ffeeef32b9c950ywan index += xd->mi_stride; 1905233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1906233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1907233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1908233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Next square block size less or equal than current block size. 1909233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const BLOCK_SIZE next_square_size[BLOCK_SIZES] = { 1910233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, 1911233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_8X8, BLOCK_8X8, BLOCK_8X8, 1912233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, 1913233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, 1914233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_64X64 1915233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 1916233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1917233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Look at neighboring blocks and set a min and max partition size based on 1918233d2500723e5594f3e7c70896ffeeef32b9c950ywan// what they chose. 1919233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile, 1920233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, 1921233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE *min_block_size, 1922233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE *max_block_size) { 1923233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 1924233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &cpi->mb.e_mbd; 1925233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **mi_8x8 = xd->mi; 1926233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int left_in_image = xd->left_available && mi_8x8[-1]; 1927233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int above_in_image = xd->up_available && 1928233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[-xd->mi_stride]; 1929233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **above_sb64_mi_8x8; 1930233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **left_sb64_mi_8x8; 1931233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1932233d2500723e5594f3e7c70896ffeeef32b9c950ywan int row8x8_remaining = tile->mi_row_end - mi_row; 1933233d2500723e5594f3e7c70896ffeeef32b9c950ywan int col8x8_remaining = tile->mi_col_end - mi_col; 1934233d2500723e5594f3e7c70896ffeeef32b9c950ywan int bh, bw; 1935233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE min_size = BLOCK_4X4; 1936233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE max_size = BLOCK_64X64; 1937233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Trap case where we do not have a prediction. 1938233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) { 1939233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Default "min to max" and "max to min" 1940233d2500723e5594f3e7c70896ffeeef32b9c950ywan min_size = BLOCK_64X64; 1941233d2500723e5594f3e7c70896ffeeef32b9c950ywan max_size = BLOCK_4X4; 1942233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1943233d2500723e5594f3e7c70896ffeeef32b9c950ywan // NOTE: each call to get_sb_partition_size_range() uses the previous 1944233d2500723e5594f3e7c70896ffeeef32b9c950ywan // passed in values for min and max as a starting point. 1945233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Find the min and max partition used in previous frame at this location 1946233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->frame_type != KEY_FRAME) { 1947233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **const prev_mi = 1948233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col]; 1949233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_sb_partition_size_range(cpi, prev_mi, &min_size, &max_size); 1950233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1951233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Find the min and max partition sizes used in the left SB64 1952233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (left_in_image) { 1953233d2500723e5594f3e7c70896ffeeef32b9c950ywan left_sb64_mi_8x8 = &mi_8x8[-MI_BLOCK_SIZE]; 1954233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_sb_partition_size_range(cpi, left_sb64_mi_8x8, 1955233d2500723e5594f3e7c70896ffeeef32b9c950ywan &min_size, &max_size); 1956233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1957233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Find the min and max partition sizes used in the above SB64. 1958233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (above_in_image) { 1959233d2500723e5594f3e7c70896ffeeef32b9c950ywan above_sb64_mi_8x8 = &mi_8x8[-xd->mi_stride * MI_BLOCK_SIZE]; 1960233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_sb_partition_size_range(cpi, above_sb64_mi_8x8, 1961233d2500723e5594f3e7c70896ffeeef32b9c950ywan &min_size, &max_size); 1962233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1963233d2500723e5594f3e7c70896ffeeef32b9c950ywan // adjust observed min and max 1964233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) { 1965233d2500723e5594f3e7c70896ffeeef32b9c950ywan min_size = min_partition_size[min_size]; 1966233d2500723e5594f3e7c70896ffeeef32b9c950ywan max_size = max_partition_size[max_size]; 1967233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1968233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1969233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1970233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check border cases where max and min from neighbors may not be legal. 1971233d2500723e5594f3e7c70896ffeeef32b9c950ywan max_size = find_partition_size(max_size, 1972233d2500723e5594f3e7c70896ffeeef32b9c950ywan row8x8_remaining, col8x8_remaining, 1973233d2500723e5594f3e7c70896ffeeef32b9c950ywan &bh, &bw); 1974233d2500723e5594f3e7c70896ffeeef32b9c950ywan min_size = MIN(min_size, max_size); 1975233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1976233d2500723e5594f3e7c70896ffeeef32b9c950ywan // When use_square_partition_only is true, make sure at least one square 1977233d2500723e5594f3e7c70896ffeeef32b9c950ywan // partition is allowed by selecting the next smaller square size as 1978233d2500723e5594f3e7c70896ffeeef32b9c950ywan // *min_block_size. 1979233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.use_square_partition_only && 1980233d2500723e5594f3e7c70896ffeeef32b9c950ywan next_square_size[max_size] < min_size) { 1981233d2500723e5594f3e7c70896ffeeef32b9c950ywan min_size = next_square_size[max_size]; 1982233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1983233d2500723e5594f3e7c70896ffeeef32b9c950ywan *min_block_size = min_size; 1984233d2500723e5594f3e7c70896ffeeef32b9c950ywan *max_block_size = max_size; 1985233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1986233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1987233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE void store_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) { 1988233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy(ctx->pred_mv, x->pred_mv, sizeof(x->pred_mv)); 1989233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1990233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1991233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) { 1992233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memcpy(x->pred_mv, ctx->pred_mv, sizeof(x->pred_mv)); 1993233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1994233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1995233d2500723e5594f3e7c70896ffeeef32b9c950ywan// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are 1996233d2500723e5594f3e7c70896ffeeef32b9c950ywan// unlikely to be selected depending on previous rate-distortion optimization 1997233d2500723e5594f3e7c70896ffeeef32b9c950ywan// results, for encoding speed-up. 1998233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, 1999233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA **tp, int mi_row, 2000233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col, BLOCK_SIZE bsize, int *rate, 2001233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t *dist, int do_recon, int64_t best_rd) { 2002233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 2003233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 2004233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 2005233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mi_step = num_8x8_blocks_wide_lookup[bsize] / 2; 2006233d2500723e5594f3e7c70896ffeeef32b9c950ywan ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE]; 2007233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_CONTEXT sl[8], sa[8]; 2008233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA *tp_orig = *tp; 2009233d2500723e5594f3e7c70896ffeeef32b9c950ywan PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize); 2010233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i, pl; 2011233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE subsize; 2012233d2500723e5594f3e7c70896ffeeef32b9c950ywan int this_rate, sum_rate = 0, best_rate = INT_MAX; 2013233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX; 2014233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t sum_rd = 0; 2015233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_split = bsize >= BLOCK_8X8; 2016233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_rect = 1; 2017233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Override skipping rectangular partition operations for edge blocks 2018233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int force_horz_split = (mi_row + mi_step >= cm->mi_rows); 2019233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int force_vert_split = (mi_col + mi_step >= cm->mi_cols); 2020233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int xss = x->e_mbd.plane[1].subsampling_x; 2021233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int yss = x->e_mbd.plane[1].subsampling_y; 2022233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2023233d2500723e5594f3e7c70896ffeeef32b9c950ywan int partition_none_allowed = !force_horz_split && !force_vert_split; 2024233d2500723e5594f3e7c70896ffeeef32b9c950ywan int partition_horz_allowed = !force_vert_split && yss <= xss && 2025233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize >= BLOCK_8X8; 2026233d2500723e5594f3e7c70896ffeeef32b9c950ywan int partition_vert_allowed = !force_horz_split && xss <= yss && 2027233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize >= BLOCK_8X8; 2028233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void) *tp_orig; 2029233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2030233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize < BLOCK_8X8) { 2031233d2500723e5594f3e7c70896ffeeef32b9c950ywan // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 2032233d2500723e5594f3e7c70896ffeeef32b9c950ywan // there is nothing to be done. 2033233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->ab_index != 0) { 2034233d2500723e5594f3e7c70896ffeeef32b9c950ywan *rate = 0; 2035233d2500723e5594f3e7c70896ffeeef32b9c950ywan *dist = 0; 2036233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 2037233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2038233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2039233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(num_8x8_blocks_wide_lookup[bsize] == 2040233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_8x8_blocks_high_lookup[bsize]); 2041233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2042233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize == BLOCK_16X16) { 2043233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, bsize); 2044233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->mb_energy = vp9_block_energy(cpi, x, bsize); 2045233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2046233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize); 2047233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2048233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2049233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Determine partition types in search according to the speed features. 2050233d2500723e5594f3e7c70896ffeeef32b9c950ywan // The threshold set here has to be of square block size. 2051233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.auto_min_max_partition_size) { 2052233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_none_allowed &= (bsize <= cpi->sf.max_partition_size && 2053233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize >= cpi->sf.min_partition_size); 2054233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size && 2055233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize > cpi->sf.min_partition_size) || 2056233d2500723e5594f3e7c70896ffeeef32b9c950ywan force_horz_split); 2057233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size && 2058233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize > cpi->sf.min_partition_size) || 2059233d2500723e5594f3e7c70896ffeeef32b9c950ywan force_vert_split); 2060233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_split &= bsize > cpi->sf.min_partition_size; 2061233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2062233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.use_square_partition_only) { 2063233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_horz_allowed &= force_horz_split; 2064233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_vert_allowed &= force_vert_split; 2065233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2066233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2067233d2500723e5594f3e7c70896ffeeef32b9c950ywan save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 2068233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2069233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.disable_split_var_thresh && partition_none_allowed) { 2070233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int source_variancey; 2071233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_setup_src_planes(x, cpi->Source, mi_row, mi_col); 2072233d2500723e5594f3e7c70896ffeeef32b9c950ywan source_variancey = get_sby_perpixel_variance(cpi, x, bsize); 2073233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (source_variancey < cpi->sf.disable_split_var_thresh) { 2074233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_split = 0; 2075233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (source_variancey < cpi->sf.disable_split_var_thresh / 2) 2076233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_rect = 0; 2077233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2078233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2079233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2080233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!x->in_active_map && (partition_horz_allowed || partition_vert_allowed)) 2081233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_split = 0; 2082233d2500723e5594f3e7c70896ffeeef32b9c950ywan // PARTITION_NONE 2083233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition_none_allowed) { 2084233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, bsize, 2085233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx, best_rd); 2086233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (this_rate != INT_MAX) { 2087233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize >= BLOCK_8X8) { 2088233d2500723e5594f3e7c70896ffeeef32b9c950ywan pl = partition_plane_context(xd, mi_row, mi_col, bsize); 2089233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_rate += x->partition_cost[pl][PARTITION_NONE]; 2090233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2091233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist); 2092233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2093233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t stop_thresh = 4096; 2094233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t stop_thresh_rd; 2095233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2096233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate = this_rate; 2097233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_dist = this_dist; 2098233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd = sum_rd; 2099233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize >= BLOCK_8X8) 2100233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = bsize; 2101233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2102233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Adjust threshold according to partition size. 2103233d2500723e5594f3e7c70896ffeeef32b9c950ywan stop_thresh >>= 8 - (b_width_log2_lookup[bsize] + 2104233d2500723e5594f3e7c70896ffeeef32b9c950ywan b_height_log2_lookup[bsize]); 2105233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2106233d2500723e5594f3e7c70896ffeeef32b9c950ywan stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh); 2107233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If obtained distortion is very small, choose current partition 2108233d2500723e5594f3e7c70896ffeeef32b9c950ywan // and stop splitting. 2109233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!x->e_mbd.lossless && best_rd < stop_thresh_rd) { 2110233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_split = 0; 2111233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_rect = 0; 2112233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2113233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2114233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2115233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!x->in_active_map) { 2116233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_split = 0; 2117233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_rect = 0; 2118233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2119233d2500723e5594f3e7c70896ffeeef32b9c950ywan restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 2120233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2121233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2122233d2500723e5594f3e7c70896ffeeef32b9c950ywan // store estimated motion vector 2123233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_motion_search) 2124233d2500723e5594f3e7c70896ffeeef32b9c950ywan store_pred_mv(x, ctx); 2125233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2126233d2500723e5594f3e7c70896ffeeef32b9c950ywan // PARTITION_SPLIT 2127233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = 0; 2128233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(jingning): use the motion vectors given by the above search as 2129233d2500723e5594f3e7c70896ffeeef32b9c950ywan // the starting point of motion search in the following partition type check. 2130233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (do_split) { 2131233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, PARTITION_SPLIT); 2132233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4 && sum_rd < best_rd; ++i) { 2133233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int x_idx = (i & 1) * mi_step; 2134233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y_idx = (i >> 1) * mi_step; 2135233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2136233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols) 2137233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 2138233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2139233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = i; 2140233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_motion_search) 2141233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2142233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 && 2143233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_none_allowed) 2144233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->pred_interp_filter = 2145233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->mic.mbmi.interp_filter; 2146233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, subsize, 2147233d2500723e5594f3e7c70896ffeeef32b9c950ywan &this_rate, &this_dist, i != 3, best_rd - sum_rd); 2148233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2149233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (this_rate == INT_MAX) { 2150233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = INT64_MAX; 2151233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2152233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += this_rate; 2153233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_dist += this_dist; 2154233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2155233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2156233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2157233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd && i == 4) { 2158233d2500723e5594f3e7c70896ffeeef32b9c950ywan pl = partition_plane_context(xd, mi_row, mi_col, bsize); 2159233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += x->partition_cost[pl][PARTITION_SPLIT]; 2160233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2161233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2162233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate = sum_rate; 2163233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_dist = sum_dist; 2164233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd = sum_rd; 2165233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = subsize; 2166233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2167233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2168233d2500723e5594f3e7c70896ffeeef32b9c950ywan // skip rectangular partition test when larger block size 2169233d2500723e5594f3e7c70896ffeeef32b9c950ywan // gives better rd cost 2170233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.less_rectangular_check) 2171233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_rect &= !partition_none_allowed; 2172233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2173233d2500723e5594f3e7c70896ffeeef32b9c950ywan restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 2174233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2175233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2176233d2500723e5594f3e7c70896ffeeef32b9c950ywan // PARTITION_HORZ 2177233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition_horz_allowed && do_rect) { 2178233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, PARTITION_HORZ); 2179233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2180233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_motion_search) 2181233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2182233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 && 2183233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_none_allowed) 2184233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->pred_interp_filter = 2185233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->mic.mbmi.interp_filter; 2186233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize, 2187233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize), best_rd); 2188233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2189233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2190233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd && mi_row + mi_step < cm->mi_rows) { 2191233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_state(cpi, get_block_context(x, subsize), mi_row, mi_col, 2192233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize, 0); 2193233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); 2194233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2195233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2196233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_motion_search) 2197233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2198233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 && 2199233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_none_allowed) 2200233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->pred_interp_filter = 2201233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->mic.mbmi.interp_filter; 2202233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row + mi_step, mi_col, &this_rate, 2203233d2500723e5594f3e7c70896ffeeef32b9c950ywan &this_dist, subsize, get_block_context(x, subsize), 2204233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd - sum_rd); 2205233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (this_rate == INT_MAX) { 2206233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = INT64_MAX; 2207233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2208233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += this_rate; 2209233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_dist += this_dist; 2210233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2211233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2212233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2213233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2214233d2500723e5594f3e7c70896ffeeef32b9c950ywan pl = partition_plane_context(xd, mi_row, mi_col, bsize); 2215233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += x->partition_cost[pl][PARTITION_HORZ]; 2216233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2217233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2218233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd = sum_rd; 2219233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate = sum_rate; 2220233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_dist = sum_dist; 2221233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = subsize; 2222233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2223233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2224233d2500723e5594f3e7c70896ffeeef32b9c950ywan restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 2225233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2226233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2227233d2500723e5594f3e7c70896ffeeef32b9c950ywan // PARTITION_VERT 2228233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition_vert_allowed && do_rect) { 2229233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, PARTITION_VERT); 2230233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2231233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2232233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_motion_search) 2233233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2234233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 && 2235233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_none_allowed) 2236233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->pred_interp_filter = 2237233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->mic.mbmi.interp_filter; 2238233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize, 2239233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize), best_rd); 2240233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2241233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd && mi_col + mi_step < cm->mi_cols) { 2242233d2500723e5594f3e7c70896ffeeef32b9c950ywan update_state(cpi, get_block_context(x, subsize), mi_row, mi_col, 2243233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize, 0); 2244233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); 2245233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2246233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2247233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_motion_search) 2248233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2249233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 && 2250233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_none_allowed) 2251233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->pred_interp_filter = 2252233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->mic.mbmi.interp_filter; 2253233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_sb_modes(cpi, tile, mi_row, mi_col + mi_step, &this_rate, 2254233d2500723e5594f3e7c70896ffeeef32b9c950ywan &this_dist, subsize, get_block_context(x, subsize), 2255233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd - sum_rd); 2256233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (this_rate == INT_MAX) { 2257233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = INT64_MAX; 2258233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2259233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += this_rate; 2260233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_dist += this_dist; 2261233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2262233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2263233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2264233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2265233d2500723e5594f3e7c70896ffeeef32b9c950ywan pl = partition_plane_context(xd, mi_row, mi_col, bsize); 2266233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += x->partition_cost[pl][PARTITION_VERT]; 2267233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2268233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2269233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate = sum_rate; 2270233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_dist = sum_dist; 2271233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd = sum_rd; 2272233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = subsize; 2273233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2274233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2275233d2500723e5594f3e7c70896ffeeef32b9c950ywan restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); 2276233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2277233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2278233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(jbb): This code added so that we avoid static analysis 2279233d2500723e5594f3e7c70896ffeeef32b9c950ywan // warning related to the fact that best_rd isn't used after this 2280233d2500723e5594f3e7c70896ffeeef32b9c950ywan // point. This code should be refactored so that the duplicate 2281233d2500723e5594f3e7c70896ffeeef32b9c950ywan // checks occur in some sub function and thus are used... 2282233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void) best_rd; 2283233d2500723e5594f3e7c70896ffeeef32b9c950ywan *rate = best_rate; 2284233d2500723e5594f3e7c70896ffeeef32b9c950ywan *dist = best_dist; 2285233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2286233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) { 2287233d2500723e5594f3e7c70896ffeeef32b9c950ywan int output_enabled = (bsize == BLOCK_64X64); 2288233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2289233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check the projected output rate for this SB against it's target 2290233d2500723e5594f3e7c70896ffeeef32b9c950ywan // and and if necessary apply a Q delta using segmentation to get 2291233d2500723e5594f3e7c70896ffeeef32b9c950ywan // closer to the target. 2292233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) { 2293233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled, 2294233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate); 2295233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2296233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2297233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) 2298233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, 2299233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate, best_dist); 2300233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2301233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize); 2302233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2303233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize == BLOCK_64X64) { 2304233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(tp_orig < *tp); 2305233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(best_rate < INT_MAX); 2306233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(best_dist < INT64_MAX); 2307233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2308233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(tp_orig == *tp); 2309233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2310233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2311233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2312233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, 2313233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, TOKENEXTRA **tp) { 2314233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 2315233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &cpi->mb.e_mbd; 2316233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col; 2317233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2318233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Initialize the left context for the new SB row 2319233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memset(&xd->left_context, 0, sizeof(xd->left_context)); 2320233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context)); 2321233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2322233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Code each SB in the row 2323233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; 2324233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_col += MI_BLOCK_SIZE) { 2325233d2500723e5594f3e7c70896ffeeef32b9c950ywan int dummy_rate; 2326233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t dummy_dist; 2327233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2328233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE i; 2329233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *x = &cpi->mb; 2330233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2331233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_pred_interp_filter) { 2332233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = BLOCK_4X4; i < BLOCK_8X8; ++i) { 2333233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_4x4_w = num_4x4_blocks_wide_lookup[i]; 2334233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_4x4_h = num_4x4_blocks_high_lookup[i]; 2335233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_4x4_blk = MAX(4, num_4x4_w * num_4x4_h); 2336233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (x->sb_index = 0; x->sb_index < 4; ++x->sb_index) 2337233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (x->mb_index = 0; x->mb_index < 4; ++x->mb_index) 2338233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (x->b_index = 0; x->b_index < 16 / num_4x4_blk; ++x->b_index) 2339233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, i)->pred_interp_filter = SWITCHABLE; 2340233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2341233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2342233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2343233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cpi->mb.pred_mv); 2344233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2345233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((cpi->sf.partition_search_type == SEARCH_PARTITION && 2346233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.use_lastframe_partitioning) || 2347233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.partition_search_type == FIXED_PARTITION || 2348233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.partition_search_type == VAR_BASED_PARTITION || 2349233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) { 2350233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int idx_str = cm->mi_stride * mi_row + mi_col; 2351233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; 2352233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; 2353233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.source_variance = UINT_MAX; 2354233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.partition_search_type == FIXED_PARTITION) { 2355233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); 2356233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, 2357233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.always_this_block_size); 2358233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, 2359233d2500723e5594f3e7c70896ffeeef32b9c950ywan &dummy_rate, &dummy_dist, 1); 2360233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (cpi->sf.partition_search_type == VAR_BASED_FIXED_PARTITION) { 2361233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize; 2362233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); 2363233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col); 2364233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize); 2365233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, 2366233d2500723e5594f3e7c70896ffeeef32b9c950ywan &dummy_rate, &dummy_dist, 1); 2367233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (cpi->sf.partition_search_type == VAR_BASED_PARTITION) { 2368233d2500723e5594f3e7c70896ffeeef32b9c950ywan choose_partitioning(cpi, tile, mi_row, mi_col); 2369233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, 2370233d2500723e5594f3e7c70896ffeeef32b9c950ywan &dummy_rate, &dummy_dist, 1); 2371233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2372233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((cm->current_video_frame 2373233d2500723e5594f3e7c70896ffeeef32b9c950ywan % cpi->sf.last_partitioning_redo_frequency) == 0 2374233d2500723e5594f3e7c70896ffeeef32b9c950ywan || cm->prev_mi == 0 2375233d2500723e5594f3e7c70896ffeeef32b9c950ywan || cm->show_frame == 0 2376233d2500723e5594f3e7c70896ffeeef32b9c950ywan || cm->frame_type == KEY_FRAME 2377233d2500723e5594f3e7c70896ffeeef32b9c950ywan || cpi->rc.is_src_frame_alt_ref 2378233d2500723e5594f3e7c70896ffeeef32b9c950ywan || ((cpi->sf.use_lastframe_partitioning == 2379233d2500723e5594f3e7c70896ffeeef32b9c950ywan LAST_FRAME_PARTITION_LOW_MOTION) && 2380233d2500723e5594f3e7c70896ffeeef32b9c950ywan sb_has_motion(cm, prev_mi_8x8))) { 2381233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If required set upper and lower partition size limits 2382233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.auto_min_max_partition_size) { 2383233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); 2384233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_auto_partition_range(cpi, tile, mi_row, mi_col, 2385233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cpi->sf.min_partition_size, 2386233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cpi->sf.max_partition_size); 2387233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2388233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, 2389233d2500723e5594f3e7c70896ffeeef32b9c950ywan &dummy_rate, &dummy_dist, 1, INT64_MAX); 2390233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2391233d2500723e5594f3e7c70896ffeeef32b9c950ywan copy_partitioning(cm, mi_8x8, prev_mi_8x8); 2392233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, 2393233d2500723e5594f3e7c70896ffeeef32b9c950ywan &dummy_rate, &dummy_dist, 1); 2394233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2395233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2396233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2397233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If required set upper and lower partition size limits 2398233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.auto_min_max_partition_size) { 2399233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); 2400233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_auto_partition_range(cpi, tile, mi_row, mi_col, 2401233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cpi->sf.min_partition_size, 2402233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cpi->sf.max_partition_size); 2403233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2404233d2500723e5594f3e7c70896ffeeef32b9c950ywan rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, 2405233d2500723e5594f3e7c70896ffeeef32b9c950ywan &dummy_rate, &dummy_dist, 1, INT64_MAX); 2406233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2407233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2408233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2409233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2410233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void init_encode_frame_mb_context(VP9_COMP *cpi) { 2411233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 2412233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 2413233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 2414233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols); 2415233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2416233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->act_zbin_adj = 0; 2417233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->seg0_idx = 0; 2418233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2419233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Copy data over into macro block data structures. 2420233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_setup_src_planes(x, cpi->Source, 0, 0); 2421233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2422233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(jkoleszar): are these initializations required? 2423233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_setup_pre_planes(xd, 0, get_ref_frame_buffer(cpi, LAST_FRAME), 0, 0, 2424233d2500723e5594f3e7c70896ffeeef32b9c950ywan NULL); 2425233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), 0, 0); 2426233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2427233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y); 2428233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2429233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0]->mbmi.mode = DC_PRED; 2430233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0]->mbmi.uv_mode = DC_PRED; 2431233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2432233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Note: this memset assumes above_context[0], [1] and [2] 2433233d2500723e5594f3e7c70896ffeeef32b9c950ywan // are allocated as part of the same buffer. 2434233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memset(xd->above_context[0], 0, 2435233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizeof(*xd->above_context[0]) * 2436233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2 * aligned_mi_cols * MAX_MB_PLANE); 2437233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memset(xd->above_seg_context, 0, 2438233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizeof(*xd->above_seg_context) * aligned_mi_cols); 2439233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2440233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2441233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void switch_lossless_mode(VP9_COMP *cpi, int lossless) { 2442233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (lossless) { 2443233d2500723e5594f3e7c70896ffeeef32b9c950ywan // printf("Switching to lossless\n"); 2444233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.fwd_txm4x4 = vp9_fwht4x4; 2445233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.e_mbd.itxm_add = vp9_iwht4x4_add; 2446233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.optimize = 0; 2447233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->common.lf.filter_level = 0; 2448233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->zbin_mode_boost_enabled = 0; 2449233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->common.tx_mode = ONLY_4X4; 2450233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2451233d2500723e5594f3e7c70896ffeeef32b9c950ywan // printf("Not lossless\n"); 2452233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.fwd_txm4x4 = vp9_fdct4x4; 2453233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add; 2454233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2455233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2456233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2457233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int check_dual_ref_flags(VP9_COMP *cpi) { 2458233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int ref_flags = cpi->ref_frame_flags; 2459233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2460233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vp9_segfeature_active(&cpi->common.seg, 1, SEG_LVL_REF_FRAME)) { 2461233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2462233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2463233d2500723e5594f3e7c70896ffeeef32b9c950ywan return (!!(ref_flags & VP9_GOLD_FLAG) + !!(ref_flags & VP9_LAST_FLAG) 2464233d2500723e5594f3e7c70896ffeeef32b9c950ywan + !!(ref_flags & VP9_ALT_FLAG)) >= 2; 2465233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2466233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2467233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2468233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int get_skip_flag(MODE_INFO **mi_8x8, int mis, int ymbs, int xmbs) { 2469233d2500723e5594f3e7c70896ffeeef32b9c950ywan int x, y; 2470233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2471233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (y = 0; y < ymbs; y++) { 2472233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (x = 0; x < xmbs; x++) { 2473233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!mi_8x8[y * mis + x]->mbmi.skip) 2474233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2475233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2476233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2477233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2478233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 2479233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2480233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2481233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void reset_skip_txfm_size(VP9_COMMON *cm, TX_SIZE txfm_max) { 2482233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, mi_col; 2483233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mis = cm->mi_stride; 2484233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **mi_ptr = cm->mi_grid_visible; 2485233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2486233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mi_row = 0; mi_row < cm->mi_rows; ++mi_row, mi_ptr += mis) { 2487233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mi_col = 0; mi_col < cm->mi_cols; ++mi_col) { 2488233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_ptr[mi_col]->mbmi.tx_size > txfm_max) 2489233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_ptr[mi_col]->mbmi.tx_size = txfm_max; 2490233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2491233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2492233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2493233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2494233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic MV_REFERENCE_FRAME get_frame_type(const VP9_COMP *cpi) { 2495233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frame_is_intra_only(&cpi->common)) 2496233d2500723e5594f3e7c70896ffeeef32b9c950ywan return INTRA_FRAME; 2497233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) 2498233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ALTREF_FRAME; 2499233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) 2500233d2500723e5594f3e7c70896ffeeef32b9c950ywan return LAST_FRAME; 2501233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 2502233d2500723e5594f3e7c70896ffeeef32b9c950ywan return GOLDEN_FRAME; 2503233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2504233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2505233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic TX_MODE select_tx_mode(const VP9_COMP *cpi) { 2506233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.lossless) { 2507233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ONLY_4X4; 2508233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (cpi->common.current_video_frame == 0) { 2509233d2500723e5594f3e7c70896ffeeef32b9c950ywan return TX_MODE_SELECT; 2510233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2511233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.tx_size_search_method == USE_LARGESTALL) { 2512233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ALLOW_32X32; 2513233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (cpi->sf.tx_size_search_method == USE_FULL_RD) { 2514233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi); 2515233d2500723e5594f3e7c70896ffeeef32b9c950ywan return cpi->rd_tx_select_threshes[frame_type][ALLOW_32X32] > 2516233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_tx_select_threshes[frame_type][TX_MODE_SELECT] ? 2517233d2500723e5594f3e7c70896ffeeef32b9c950ywan ALLOW_32X32 : TX_MODE_SELECT; 2518233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2519233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int total = 0; 2520233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 2521233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < TX_SIZES; ++i) 2522233d2500723e5594f3e7c70896ffeeef32b9c950ywan total += cpi->tx_stepdown_count[i]; 2523233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2524233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (total) { 2525233d2500723e5594f3e7c70896ffeeef32b9c950ywan const double fraction = (double)cpi->tx_stepdown_count[0] / total; 2526233d2500723e5594f3e7c70896ffeeef32b9c950ywan return fraction > 0.90 ? ALLOW_32X32 : TX_MODE_SELECT; 2527233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2528233d2500723e5594f3e7c70896ffeeef32b9c950ywan return cpi->common.tx_mode; 2529233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2530233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2531233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2532233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2533233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2534233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Start RTC Exploration 2535233d2500723e5594f3e7c70896ffeeef32b9c950ywantypedef enum { 2536233d2500723e5594f3e7c70896ffeeef32b9c950ywan BOTH_ZERO = 0, 2537233d2500723e5594f3e7c70896ffeeef32b9c950ywan ZERO_PLUS_PREDICTED = 1, 2538233d2500723e5594f3e7c70896ffeeef32b9c950ywan BOTH_PREDICTED = 2, 2539233d2500723e5594f3e7c70896ffeeef32b9c950ywan NEW_PLUS_NON_INTRA = 3, 2540233d2500723e5594f3e7c70896ffeeef32b9c950ywan BOTH_NEW = 4, 2541233d2500723e5594f3e7c70896ffeeef32b9c950ywan INTRA_PLUS_NON_INTRA = 5, 2542233d2500723e5594f3e7c70896ffeeef32b9c950ywan BOTH_INTRA = 6, 2543233d2500723e5594f3e7c70896ffeeef32b9c950ywan INVALID_CASE = 9 2544233d2500723e5594f3e7c70896ffeeef32b9c950ywan} motion_vector_context; 2545233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2546233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void set_mode_info(MB_MODE_INFO *mbmi, BLOCK_SIZE bsize, 2547233d2500723e5594f3e7c70896ffeeef32b9c950ywan MB_PREDICTION_MODE mode) { 2548233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->mode = mode; 2549233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->uv_mode = mode; 2550233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->mv[0].as_int = 0; 2551233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->mv[1].as_int = 0; 2552233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->ref_frame[0] = INTRA_FRAME; 2553233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->ref_frame[1] = NONE; 2554233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->tx_size = max_txsize_lookup[bsize]; 2555233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->skip = 0; 2556233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->sb_type = bsize; 2557233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->segment_id = 0; 2558233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2559233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2560233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, 2561233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, 2562233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *rate, int64_t *dist, 2563233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize) { 2564233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 2565233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 2566233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 2567233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_offsets(cpi, tile, mi_row, mi_col, bsize); 2568233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0]->mbmi.sb_type = bsize; 2569233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2570233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!frame_is_intra_only(cm)) { 2571233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col, 2572233d2500723e5594f3e7c70896ffeeef32b9c950ywan rate, dist, bsize); 2573233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2574233d2500723e5594f3e7c70896ffeeef32b9c950ywan MB_PREDICTION_MODE intramode = DC_PRED; 2575233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_mode_info(&xd->mi[0]->mbmi, bsize, intramode); 2576233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2577233d2500723e5594f3e7c70896ffeeef32b9c950ywan duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); 2578233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2579233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2580233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x, 2581233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, 2582233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize, BLOCK_SIZE subsize) { 2583233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *xd = &x->e_mbd; 2584233d2500723e5594f3e7c70896ffeeef32b9c950ywan int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4; 2585233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_TYPE partition = partition_lookup[bsl][subsize]; 2586233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2587233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(bsize >= BLOCK_8X8); 2588233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2589233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) 2590233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 2591233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2592233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (partition) { 2593233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_NONE: 2594233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_modeinfo_offsets(cm, xd, mi_row, mi_col); 2595233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(xd->mi[0]) = get_block_context(x, subsize)->mic; 2596233d2500723e5594f3e7c70896ffeeef32b9c950ywan duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); 2597233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 2598233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_VERT: 2599233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2600233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_modeinfo_offsets(cm, xd, mi_row, mi_col); 2601233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(xd->mi[0]) = get_block_context(x, subsize)->mic; 2602233d2500723e5594f3e7c70896ffeeef32b9c950ywan duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); 2603233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2604233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_col + hbs < cm->mi_cols) { 2605233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2606233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_modeinfo_offsets(cm, xd, mi_row, mi_col + hbs); 2607233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(xd->mi[0]) = get_block_context(x, subsize)->mic; 2608233d2500723e5594f3e7c70896ffeeef32b9c950ywan duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, bsize); 2609233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2610233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 2611233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_HORZ: 2612233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2613233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_modeinfo_offsets(cm, xd, mi_row, mi_col); 2614233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(xd->mi[0]) = get_block_context(x, subsize)->mic; 2615233d2500723e5594f3e7c70896ffeeef32b9c950ywan duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize); 2616233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + hbs < cm->mi_rows) { 2617233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2618233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_modeinfo_offsets(cm, xd, mi_row + hbs, mi_col); 2619233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(xd->mi[0]) = get_block_context(x, subsize)->mic; 2620233d2500723e5594f3e7c70896ffeeef32b9c950ywan duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, bsize); 2621233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2622233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 2623233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_SPLIT: 2624233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2625233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_mode_info_sb(cm, x, mi_row, mi_col, subsize, 2626233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, subsize))); 2627233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2628233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_mode_info_sb(cm, x, mi_row, mi_col + hbs, subsize, 2629233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, subsize))); 2630233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 2; 2631233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_mode_info_sb(cm, x, mi_row + hbs, mi_col, subsize, 2632233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, subsize))); 2633233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 3; 2634233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_mode_info_sb(cm, x, mi_row + hbs, mi_col + hbs, subsize, 2635233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, subsize))); 2636233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 2637233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 2638233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 2639233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2640233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2641233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2642233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile, 2643233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA **tp, int mi_row, 2644233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col, BLOCK_SIZE bsize, int *rate, 2645233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t *dist, int do_recon, int64_t best_rd) { 2646233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 2647233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 2648233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 2649233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int ms = num_8x8_blocks_wide_lookup[bsize] / 2; 2650233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA *tp_orig = *tp; 2651233d2500723e5594f3e7c70896ffeeef32b9c950ywan PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize); 2652233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 2653233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE subsize; 2654233d2500723e5594f3e7c70896ffeeef32b9c950ywan int this_rate, sum_rate = 0, best_rate = INT_MAX; 2655233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX; 2656233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t sum_rd = 0; 2657233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_split = bsize >= BLOCK_8X8; 2658233d2500723e5594f3e7c70896ffeeef32b9c950ywan int do_rect = 1; 2659233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Override skipping rectangular partition operations for edge blocks 2660233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int force_horz_split = (mi_row + ms >= cm->mi_rows); 2661233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int force_vert_split = (mi_col + ms >= cm->mi_cols); 2662233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int xss = x->e_mbd.plane[1].subsampling_x; 2663233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int yss = x->e_mbd.plane[1].subsampling_y; 2664233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2665233d2500723e5594f3e7c70896ffeeef32b9c950ywan int partition_none_allowed = !force_horz_split && !force_vert_split; 2666233d2500723e5594f3e7c70896ffeeef32b9c950ywan int partition_horz_allowed = !force_vert_split && yss <= xss && 2667233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize >= BLOCK_8X8; 2668233d2500723e5594f3e7c70896ffeeef32b9c950ywan int partition_vert_allowed = !force_horz_split && xss <= yss && 2669233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize >= BLOCK_8X8; 2670233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void) *tp_orig; 2671233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2672233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize < BLOCK_8X8) { 2673233d2500723e5594f3e7c70896ffeeef32b9c950ywan // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 2674233d2500723e5594f3e7c70896ffeeef32b9c950ywan // there is nothing to be done. 2675233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->ab_index != 0) { 2676233d2500723e5594f3e7c70896ffeeef32b9c950ywan *rate = 0; 2677233d2500723e5594f3e7c70896ffeeef32b9c950ywan *dist = 0; 2678233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 2679233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2680233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2681233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2682233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(num_8x8_blocks_wide_lookup[bsize] == 2683233d2500723e5594f3e7c70896ffeeef32b9c950ywan num_8x8_blocks_high_lookup[bsize]); 2684233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2685233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->in_active_map = check_active_map(cpi, x, mi_row, mi_col, bsize); 2686233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2687233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Determine partition types in search according to the speed features. 2688233d2500723e5594f3e7c70896ffeeef32b9c950ywan // The threshold set here has to be of square block size. 2689233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.auto_min_max_partition_size) { 2690233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_none_allowed &= (bsize <= cpi->sf.max_partition_size && 2691233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize >= cpi->sf.min_partition_size); 2692233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_horz_allowed &= ((bsize <= cpi->sf.max_partition_size && 2693233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize > cpi->sf.min_partition_size) || 2694233d2500723e5594f3e7c70896ffeeef32b9c950ywan force_horz_split); 2695233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_vert_allowed &= ((bsize <= cpi->sf.max_partition_size && 2696233d2500723e5594f3e7c70896ffeeef32b9c950ywan bsize > cpi->sf.min_partition_size) || 2697233d2500723e5594f3e7c70896ffeeef32b9c950ywan force_vert_split); 2698233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_split &= bsize > cpi->sf.min_partition_size; 2699233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2700233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.use_square_partition_only) { 2701233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_horz_allowed &= force_horz_split; 2702233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition_vert_allowed &= force_vert_split; 2703233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2704233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2705233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!x->in_active_map && (partition_horz_allowed || partition_vert_allowed)) 2706233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_split = 0; 2707233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2708233d2500723e5594f3e7c70896ffeeef32b9c950ywan // PARTITION_NONE 2709233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition_none_allowed) { 2710233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, 2711233d2500723e5594f3e7c70896ffeeef32b9c950ywan &this_rate, &this_dist, bsize); 2712233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->mic.mbmi = xd->mi[0]->mbmi; 2713233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2714233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (this_rate != INT_MAX) { 2715233d2500723e5594f3e7c70896ffeeef32b9c950ywan int pl = partition_plane_context(xd, mi_row, mi_col, bsize); 2716233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_rate += x->partition_cost[pl][PARTITION_NONE]; 2717233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist); 2718233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2719233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t stop_thresh = 4096; 2720233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t stop_thresh_rd; 2721233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2722233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate = this_rate; 2723233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_dist = this_dist; 2724233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd = sum_rd; 2725233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize >= BLOCK_8X8) 2726233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = bsize; 2727233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2728233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Adjust threshold according to partition size. 2729233d2500723e5594f3e7c70896ffeeef32b9c950ywan stop_thresh >>= 8 - (b_width_log2_lookup[bsize] + 2730233d2500723e5594f3e7c70896ffeeef32b9c950ywan b_height_log2_lookup[bsize]); 2731233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2732233d2500723e5594f3e7c70896ffeeef32b9c950ywan stop_thresh_rd = RDCOST(x->rdmult, x->rddiv, 0, stop_thresh); 2733233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If obtained distortion is very small, choose current partition 2734233d2500723e5594f3e7c70896ffeeef32b9c950ywan // and stop splitting. 2735233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!x->e_mbd.lossless && best_rd < stop_thresh_rd) { 2736233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_split = 0; 2737233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_rect = 0; 2738233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2739233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2740233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2741233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!x->in_active_map) { 2742233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_split = 0; 2743233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_rect = 0; 2744233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2745233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2746233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2747233d2500723e5594f3e7c70896ffeeef32b9c950ywan // store estimated motion vector 2748233d2500723e5594f3e7c70896ffeeef32b9c950ywan store_pred_mv(x, ctx); 2749233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2750233d2500723e5594f3e7c70896ffeeef32b9c950ywan // PARTITION_SPLIT 2751233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = 0; 2752233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (do_split) { 2753233d2500723e5594f3e7c70896ffeeef32b9c950ywan int pl = partition_plane_context(xd, mi_row, mi_col, bsize); 2754233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += x->partition_cost[pl][PARTITION_SPLIT]; 2755233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, PARTITION_SPLIT); 2756233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < 4 && sum_rd < best_rd; ++i) { 2757233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int x_idx = (i & 1) * ms; 2758233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int y_idx = (i >> 1) * ms; 2759233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2760233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + y_idx >= cm->mi_rows || mi_col + x_idx >= cm->mi_cols) 2761233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 2762233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2763233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = i; 2764233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2765233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2766233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 2767233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize, &this_rate, &this_dist, 0, 2768233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd - sum_rd); 2769233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2770233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (this_rate == INT_MAX) { 2771233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = INT64_MAX; 2772233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2773233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += this_rate; 2774233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_dist += this_dist; 2775233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2776233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2777233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2778233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2779233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2780233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate = sum_rate; 2781233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_dist = sum_dist; 2782233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd = sum_rd; 2783233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = subsize; 2784233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2785233d2500723e5594f3e7c70896ffeeef32b9c950ywan // skip rectangular partition test when larger block size 2786233d2500723e5594f3e7c70896ffeeef32b9c950ywan // gives better rd cost 2787233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.less_rectangular_check) 2788233d2500723e5594f3e7c70896ffeeef32b9c950ywan do_rect &= !partition_none_allowed; 2789233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2790233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2791233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2792233d2500723e5594f3e7c70896ffeeef32b9c950ywan // PARTITION_HORZ 2793233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition_horz_allowed && do_rect) { 2794233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, PARTITION_HORZ); 2795233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2796233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_motion_search) 2797233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2798233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2799233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, 2800233d2500723e5594f3e7c70896ffeeef32b9c950ywan &this_rate, &this_dist, subsize); 2801233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2802233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; 2803233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2804233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2805233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2806233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd && mi_row + ms < cm->mi_rows) { 2807233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2808233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2809233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2810233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2811233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col, 2812233d2500723e5594f3e7c70896ffeeef32b9c950ywan &this_rate, &this_dist, subsize); 2813233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2814233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; 2815233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2816233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (this_rate == INT_MAX) { 2817233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = INT64_MAX; 2818233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2819233d2500723e5594f3e7c70896ffeeef32b9c950ywan int pl = partition_plane_context(xd, mi_row, mi_col, bsize); 2820233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_rate += x->partition_cost[pl][PARTITION_HORZ]; 2821233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += this_rate; 2822233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_dist += this_dist; 2823233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2824233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2825233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2826233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2827233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd = sum_rd; 2828233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate = sum_rate; 2829233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_dist = sum_dist; 2830233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = subsize; 2831233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2832233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2833233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2834233d2500723e5594f3e7c70896ffeeef32b9c950ywan // PARTITION_VERT 2835233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (partition_vert_allowed && do_rect) { 2836233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, PARTITION_VERT); 2837233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2838233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2839233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.adaptive_motion_search) 2840233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2841233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2842233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, 2843233d2500723e5594f3e7c70896ffeeef32b9c950ywan &this_rate, &this_dist, subsize); 2844233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; 2845233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2846233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) { 2847233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2848233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2849233d2500723e5594f3e7c70896ffeeef32b9c950ywan load_pred_mv(x, ctx); 2850233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2851233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms, 2852233d2500723e5594f3e7c70896ffeeef32b9c950ywan &this_rate, &this_dist, subsize); 2853233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2854233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; 2855233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2856233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (this_rate == INT_MAX) { 2857233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = INT64_MAX; 2858233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2859233d2500723e5594f3e7c70896ffeeef32b9c950ywan int pl = partition_plane_context(xd, mi_row, mi_col, bsize); 2860233d2500723e5594f3e7c70896ffeeef32b9c950ywan this_rate += x->partition_cost[pl][PARTITION_VERT]; 2861233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rate += this_rate; 2862233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_dist += this_dist; 2863233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist); 2864233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2865233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2866233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sum_rd < best_rd) { 2867233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate = sum_rate; 2868233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_dist = sum_dist; 2869233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rd = sum_rd; 2870233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize)) = subsize; 2871233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2872233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2873233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2874233d2500723e5594f3e7c70896ffeeef32b9c950ywan *rate = best_rate; 2875233d2500723e5594f3e7c70896ffeeef32b9c950ywan *dist = best_dist; 2876233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2877233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_rate == INT_MAX) 2878233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 2879233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2880233d2500723e5594f3e7c70896ffeeef32b9c950ywan // update mode info array 2881233d2500723e5594f3e7c70896ffeeef32b9c950ywan fill_mode_info_sb(cm, x, mi_row, mi_col, bsize, 2882233d2500723e5594f3e7c70896ffeeef32b9c950ywan *(get_sb_partitioning(x, bsize))); 2883233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2884233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) { 2885233d2500723e5594f3e7c70896ffeeef32b9c950ywan int output_enabled = (bsize == BLOCK_64X64); 2886233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2887233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check the projected output rate for this SB against it's target 2888233d2500723e5594f3e7c70896ffeeef32b9c950ywan // and and if necessary apply a Q delta using segmentation to get 2889233d2500723e5594f3e7c70896ffeeef32b9c950ywan // closer to the target. 2890233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) { 2891233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled, 2892233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate); 2893233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2894233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2895233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) 2896233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, 2897233d2500723e5594f3e7c70896ffeeef32b9c950ywan best_rate, best_dist); 2898233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2899233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize); 2900233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2901233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2902233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize == BLOCK_64X64) { 2903233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(tp_orig < *tp); 2904233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(best_rate < INT_MAX); 2905233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(best_dist < INT64_MAX); 2906233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2907233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(tp_orig == *tp); 2908233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2909233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2910233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2911233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void nonrd_use_partition(VP9_COMP *cpi, 2912233d2500723e5594f3e7c70896ffeeef32b9c950ywan const TileInfo *const tile, 2913233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **mi_8x8, 2914233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA **tp, 2915233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, 2916233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize, int output_enabled, 2917233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *totrate, int64_t *totdist) { 2918233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 2919233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 2920233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 2921233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int bsl = b_width_log2(bsize), hbs = (1 << bsl) / 4; 2922233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mis = cm->mi_stride; 2923233d2500723e5594f3e7c70896ffeeef32b9c950ywan PARTITION_TYPE partition; 2924233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE subsize; 2925233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rate = INT_MAX; 2926233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t dist = INT64_MAX; 2927233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2928233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) 2929233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 2930233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2931233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize >= BLOCK_8X8) { 2932233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = mi_8x8[0]->mbmi.sb_type; 2933233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2934233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = BLOCK_4X4; 2935233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2936233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2937233d2500723e5594f3e7c70896ffeeef32b9c950ywan partition = partition_lookup[bsl][subsize]; 2938233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2939233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (partition) { 2940233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_NONE: 2941233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize); 2942233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; 2943233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 2944233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_VERT: 2945233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2946233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize); 2947233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; 2948233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_col + hbs < cm->mi_cols) { 2949233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2950233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs, 2951233d2500723e5594f3e7c70896ffeeef32b9c950ywan &rate, &dist, subsize); 2952233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; 2953233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rate != INT_MAX && dist != INT64_MAX && 2954233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate != INT_MAX && *totdist != INT64_MAX) { 2955233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate += rate; 2956233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totdist += dist; 2957233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2958233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2959233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 2960233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_HORZ: 2961233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2962233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist, subsize); 2963233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->mic.mbmi = xd->mi[0]->mbmi; 2964233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_row + hbs < cm->mi_rows) { 2965233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2966233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col, 2967233d2500723e5594f3e7c70896ffeeef32b9c950ywan &rate, &dist, subsize); 2968233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_block_context(x, subsize)->mic.mbmi = mi_8x8[0]->mbmi; 2969233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rate != INT_MAX && dist != INT64_MAX && 2970233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate != INT_MAX && *totdist != INT64_MAX) { 2971233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate += rate; 2972233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totdist += dist; 2973233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2974233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2975233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 2976233d2500723e5594f3e7c70896ffeeef32b9c950ywan case PARTITION_SPLIT: 2977233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize = get_subsize(bsize, PARTITION_SPLIT); 2978233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 0; 2979233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, 2980233d2500723e5594f3e7c70896ffeeef32b9c950ywan subsize, output_enabled, totrate, totdist); 2981233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 1; 2982233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_use_partition(cpi, tile, mi_8x8 + hbs, tp, 2983233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row, mi_col + hbs, subsize, output_enabled, 2984233d2500723e5594f3e7c70896ffeeef32b9c950ywan &rate, &dist); 2985233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rate != INT_MAX && dist != INT64_MAX && 2986233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate != INT_MAX && *totdist != INT64_MAX) { 2987233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate += rate; 2988233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totdist += dist; 2989233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2990233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 2; 2991233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis, tp, 2992233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row + hbs, mi_col, subsize, output_enabled, 2993233d2500723e5594f3e7c70896ffeeef32b9c950ywan &rate, &dist); 2994233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rate != INT_MAX && dist != INT64_MAX && 2995233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate != INT_MAX && *totdist != INT64_MAX) { 2996233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate += rate; 2997233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totdist += dist; 2998233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2999233d2500723e5594f3e7c70896ffeeef32b9c950ywan *get_sb_index(x, subsize) = 3; 3000233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_use_partition(cpi, tile, mi_8x8 + hbs * mis + hbs, tp, 3001233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row + hbs, mi_col + hbs, subsize, output_enabled, 3002233d2500723e5594f3e7c70896ffeeef32b9c950ywan &rate, &dist); 3003233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (rate != INT_MAX && dist != INT64_MAX && 3004233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate != INT_MAX && *totdist != INT64_MAX) { 3005233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate += rate; 3006233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totdist += dist; 3007233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3008233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 3009233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 3010233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert("Invalid partition type."); 3011233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3012233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3013233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize == BLOCK_64X64 && output_enabled) { 3014233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) 3015233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh, 3016233d2500723e5594f3e7c70896ffeeef32b9c950ywan *totrate, *totdist); 3017233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, bsize); 3018233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3019233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 3020233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3021233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, 3022233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, TOKENEXTRA **tp) { 3023233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *cm = &cpi->common; 3024233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *xd = &cpi->mb.e_mbd; 3025233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_col; 3026233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3027233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Initialize the left context for the new SB row 3028233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memset(&xd->left_context, 0, sizeof(xd->left_context)); 3029233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context)); 3030233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3031233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Code each SB in the row 3032233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; 3033233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_col += MI_BLOCK_SIZE) { 3034233d2500723e5594f3e7c70896ffeeef32b9c950ywan int dummy_rate = 0; 3035233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t dummy_dist = 0; 3036233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int idx_str = cm->mi_stride * mi_row + mi_col; 3037233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; 3038233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str; 3039233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3040233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_SIZE bsize = cpi->sf.partition_search_type == FIXED_PARTITION ? 3041233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.always_this_block_size : 3042233d2500723e5594f3e7c70896ffeeef32b9c950ywan get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col); 3043233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3044233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.source_variance = UINT_MAX; 3045233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cpi->mb.pred_mv); 3046233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3047233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Set the partition type of the 64X64 block 3048233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (cpi->sf.partition_search_type) { 3049233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VAR_BASED_PARTITION: 3050233d2500723e5594f3e7c70896ffeeef32b9c950ywan choose_partitioning(cpi, tile, mi_row, mi_col); 3051233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, 3052233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1, &dummy_rate, &dummy_dist); 3053233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 3054233d2500723e5594f3e7c70896ffeeef32b9c950ywan case VAR_BASED_FIXED_PARTITION: 3055233d2500723e5594f3e7c70896ffeeef32b9c950ywan case FIXED_PARTITION: 3056233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize); 3057233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, 3058233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1, &dummy_rate, &dummy_dist); 3059233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 3060233d2500723e5594f3e7c70896ffeeef32b9c950ywan case REFERENCE_PARTITION: 3061233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.partition_check || sb_has_motion(cm, prev_mi_8x8)) { 3062233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64, 3063233d2500723e5594f3e7c70896ffeeef32b9c950ywan &dummy_rate, &dummy_dist, 1, INT64_MAX); 3064233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3065233d2500723e5594f3e7c70896ffeeef32b9c950ywan copy_partitioning(cm, mi_8x8, prev_mi_8x8); 3066233d2500723e5594f3e7c70896ffeeef32b9c950ywan nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, 3067233d2500723e5594f3e7c70896ffeeef32b9c950ywan BLOCK_64X64, 1, &dummy_rate, &dummy_dist); 3068233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3069233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 3070233d2500723e5594f3e7c70896ffeeef32b9c950ywan default: 3071233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(0); 3072233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3073233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3074233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 3075233d2500723e5594f3e7c70896ffeeef32b9c950ywan// end RTC play code 3076233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3077233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_frame_internal(VP9_COMP *cpi) { 3078233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row; 3079233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 3080233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 3081233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 3082233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3083233d2500723e5594f3e7c70896ffeeef32b9c950ywan// fprintf(stderr, "encode_frame_internal frame %d (%d) type %d\n", 3084233d2500723e5594f3e7c70896ffeeef32b9c950ywan// cpi->common.current_video_frame, cpi->common.show_frame, 3085233d2500723e5594f3e7c70896ffeeef32b9c950ywan// cm->frame_type); 3086233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3087233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi = cm->mi_grid_visible; 3088233d2500723e5594f3e7c70896ffeeef32b9c950ywan xd->mi[0] = cm->mi; 3089233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3090233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cm->counts); 3091233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cpi->coef_counts); 3092233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cpi->tx_stepdown_count); 3093233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3094233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Set frame level transform size use case 3095233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->tx_mode = select_tx_mode(cpi); 3096233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3097233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.e_mbd.lossless = cm->base_qindex == 0 && cm->y_dc_delta_q == 0 3098233d2500723e5594f3e7c70896ffeeef32b9c950ywan && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0; 3099233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch_lossless_mode(cpi, cpi->mb.e_mbd.lossless); 3100233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3101233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_frame_init_quantizer(cpi); 3102233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3103233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_initialize_rd_consts(cpi); 3104233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_initialize_me_consts(cpi, cm->base_qindex); 3105233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3106233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { 3107233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Initialize encode frame context. 3108233d2500723e5594f3e7c70896ffeeef32b9c950ywan init_encode_frame_mb_context(cpi); 3109233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3110233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Build a frame level activity map 3111233d2500723e5594f3e7c70896ffeeef32b9c950ywan build_activity_map(cpi); 3112233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3113233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3114233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Re-initialize encode frame context. 3115233d2500723e5594f3e7c70896ffeeef32b9c950ywan init_encode_frame_mb_context(cpi); 3116233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3117233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cpi->rd_comp_pred_diff); 3118233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cpi->rd_filter_diff); 3119233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cpi->rd_tx_select_diff); 3120233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cpi->rd_tx_select_threshes); 3121233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3122233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_prev_mi(cm); 3123233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3124233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.use_nonrd_pick_mode) { 3125233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Initialize internal buffer pointers for rtc coding, where non-RD 3126233d2500723e5594f3e7c70896ffeeef32b9c950ywan // mode decision is used and hence no buffer pointer swap needed. 3127233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 3128233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct macroblock_plane *const p = x->plane; 3129233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct macroblockd_plane *const pd = xd->plane; 3130233d2500723e5594f3e7c70896ffeeef32b9c950ywan PICK_MODE_CONTEXT *ctx = &cpi->mb.sb64_context; 3131233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3132233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < MAX_MB_PLANE; ++i) { 3133233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].coeff = ctx->coeff_pbuf[i][0]; 3134233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].qcoeff = ctx->qcoeff_pbuf[i][0]; 3135233d2500723e5594f3e7c70896ffeeef32b9c950ywan pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][0]; 3136233d2500723e5594f3e7c70896ffeeef32b9c950ywan p[i].eobs = ctx->eobs_pbuf[i][0]; 3137233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3138233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(x->zcoeff_blk); 3139233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3140233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3141233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 3142233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct vpx_usec_timer emr_timer; 3143233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_usec_timer_start(&emr_timer); 3144233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3145233d2500723e5594f3e7c70896ffeeef32b9c950ywan { 3146233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Take tiles into account and give start/end MB 3147233d2500723e5594f3e7c70896ffeeef32b9c950ywan int tile_col, tile_row; 3148233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA *tp = cpi->tok; 3149233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int tile_cols = 1 << cm->log2_tile_cols; 3150233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int tile_rows = 1 << cm->log2_tile_rows; 3151233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3152233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (tile_row = 0; tile_row < tile_rows; tile_row++) { 3153233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (tile_col = 0; tile_col < tile_cols; tile_col++) { 3154233d2500723e5594f3e7c70896ffeeef32b9c950ywan TileInfo tile; 3155233d2500723e5594f3e7c70896ffeeef32b9c950ywan TOKENEXTRA *tp_old = tp; 3156233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3157233d2500723e5594f3e7c70896ffeeef32b9c950ywan // For each row of SBs in the frame 3158233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_tile_init(&tile, cm, tile_row, tile_col); 3159233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mi_row = tile.mi_row_start; 3160233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_row < tile.mi_row_end; mi_row += MI_BLOCK_SIZE) { 3161233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.use_nonrd_pick_mode && cm->frame_type != KEY_FRAME) 3162233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_nonrd_sb_row(cpi, &tile, mi_row, &tp); 3163233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 3164233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_rd_sb_row(cpi, &tile, mi_row, &tp); 3165233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3166233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old); 3167233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols)); 3168233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3169233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3170233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3171233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3172233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_usec_timer_mark(&emr_timer); 3173233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer); 3174233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3175233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3176233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.skip_encode_sb) { 3177233d2500723e5594f3e7c70896ffeeef32b9c950ywan int j; 3178233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int intra_count = 0, inter_count = 0; 3179233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < INTRA_INTER_CONTEXTS; ++j) { 3180233d2500723e5594f3e7c70896ffeeef32b9c950ywan intra_count += cm->counts.intra_inter[j][0]; 3181233d2500723e5594f3e7c70896ffeeef32b9c950ywan inter_count += cm->counts.intra_inter[j][1]; 3182233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3183233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.skip_encode_frame = (intra_count << 2) < inter_count && 3184233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->frame_type != KEY_FRAME && 3185233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->show_frame; 3186233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3187233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.skip_encode_frame = 0; 3188233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3189233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3190233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if 0 3191233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Keep record of the total distortion this time around for future use 3192233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->last_frame_distortion = cpi->frame_distortion; 3193233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 3194233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 3195233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3196233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_encode_frame(VP9_COMP *cpi) { 3197233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 3198233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3199233d2500723e5594f3e7c70896ffeeef32b9c950ywan // In the longer term the encoder should be generalized to match the 3200233d2500723e5594f3e7c70896ffeeef32b9c950ywan // decoder such that we allow compound where one of the 3 buffers has a 3201233d2500723e5594f3e7c70896ffeeef32b9c950ywan // different sign bias and that buffer is then the fixed ref. However, this 3202233d2500723e5594f3e7c70896ffeeef32b9c950ywan // requires further work in the rd loop. For now the only supported encoder 3203233d2500723e5594f3e7c70896ffeeef32b9c950ywan // side behavior is where the ALT ref buffer has opposite sign bias to 3204233d2500723e5594f3e7c70896ffeeef32b9c950ywan // the other two. 3205233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!frame_is_intra_only(cm)) { 3206233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((cm->ref_frame_sign_bias[ALTREF_FRAME] == 3207233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->ref_frame_sign_bias[GOLDEN_FRAME]) || 3208233d2500723e5594f3e7c70896ffeeef32b9c950ywan (cm->ref_frame_sign_bias[ALTREF_FRAME] == 3209233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->ref_frame_sign_bias[LAST_FRAME])) { 3210233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->allow_comp_inter_inter = 0; 3211233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3212233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->allow_comp_inter_inter = 1; 3213233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->comp_fixed_ref = ALTREF_FRAME; 3214233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->comp_var_ref[0] = LAST_FRAME; 3215233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->comp_var_ref[1] = GOLDEN_FRAME; 3216233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3217233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3218233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3219233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->sf.frame_parameter_update) { 3220233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 3221233d2500723e5594f3e7c70896ffeeef32b9c950ywan REFERENCE_MODE reference_mode; 3222233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* 3223233d2500723e5594f3e7c70896ffeeef32b9c950ywan * This code does a single RD pass over the whole frame assuming 3224233d2500723e5594f3e7c70896ffeeef32b9c950ywan * either compound, single or hybrid prediction as per whatever has 3225233d2500723e5594f3e7c70896ffeeef32b9c950ywan * worked best for that type of frame in the past. 3226233d2500723e5594f3e7c70896ffeeef32b9c950ywan * It also predicts whether another coding mode would have worked 3227233d2500723e5594f3e7c70896ffeeef32b9c950ywan * better that this coding mode. If that is the case, it remembers 3228233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that for subsequent frames. 3229233d2500723e5594f3e7c70896ffeeef32b9c950ywan * It does the same analysis for transform size selection also. 3230233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 3231233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MV_REFERENCE_FRAME frame_type = get_frame_type(cpi); 3232233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t *mode_thresh = cpi->rd_prediction_type_threshes[frame_type]; 3233233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t *filter_thresh = cpi->rd_filter_threshes[frame_type]; 3234233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3235233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* prediction (compound, single or hybrid) mode selection */ 3236233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frame_type == 3 || !cm->allow_comp_inter_inter) 3237233d2500723e5594f3e7c70896ffeeef32b9c950ywan reference_mode = SINGLE_REFERENCE; 3238233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (mode_thresh[COMPOUND_REFERENCE] > mode_thresh[SINGLE_REFERENCE] && 3239233d2500723e5594f3e7c70896ffeeef32b9c950ywan mode_thresh[COMPOUND_REFERENCE] > 3240233d2500723e5594f3e7c70896ffeeef32b9c950ywan mode_thresh[REFERENCE_MODE_SELECT] && 3241233d2500723e5594f3e7c70896ffeeef32b9c950ywan check_dual_ref_flags(cpi) && 3242233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->static_mb_pct == 100) 3243233d2500723e5594f3e7c70896ffeeef32b9c950ywan reference_mode = COMPOUND_REFERENCE; 3244233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (mode_thresh[SINGLE_REFERENCE] > mode_thresh[REFERENCE_MODE_SELECT]) 3245233d2500723e5594f3e7c70896ffeeef32b9c950ywan reference_mode = SINGLE_REFERENCE; 3246233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 3247233d2500723e5594f3e7c70896ffeeef32b9c950ywan reference_mode = REFERENCE_MODE_SELECT; 3248233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3249233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->interp_filter == SWITCHABLE) { 3250233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frame_type != ALTREF_FRAME && 3251233d2500723e5594f3e7c70896ffeeef32b9c950ywan filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[EIGHTTAP] && 3252233d2500723e5594f3e7c70896ffeeef32b9c950ywan filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[EIGHTTAP_SHARP] && 3253233d2500723e5594f3e7c70896ffeeef32b9c950ywan filter_thresh[EIGHTTAP_SMOOTH] > filter_thresh[SWITCHABLE - 1]) { 3254233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->interp_filter = EIGHTTAP_SMOOTH; 3255233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (filter_thresh[EIGHTTAP_SHARP] > filter_thresh[EIGHTTAP] && 3256233d2500723e5594f3e7c70896ffeeef32b9c950ywan filter_thresh[EIGHTTAP_SHARP] > filter_thresh[SWITCHABLE - 1]) { 3257233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->interp_filter = EIGHTTAP_SHARP; 3258233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (filter_thresh[EIGHTTAP] > filter_thresh[SWITCHABLE - 1]) { 3259233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->interp_filter = EIGHTTAP; 3260233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3261233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3262233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3263233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.e_mbd.lossless = cpi->oxcf.lossless; 3264233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->reference_mode = reference_mode; 3265233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3266233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_frame_internal(cpi); 3267233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3268233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < REFERENCE_MODES; ++i) { 3269233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int diff = (int) (cpi->rd_comp_pred_diff[i] / cm->MBs); 3270233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_prediction_type_threshes[frame_type][i] += diff; 3271233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_prediction_type_threshes[frame_type][i] >>= 1; 3272233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3273233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3274233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) { 3275233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t diff = cpi->rd_filter_diff[i] / cm->MBs; 3276233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_filter_threshes[frame_type][i] = 3277233d2500723e5594f3e7c70896ffeeef32b9c950ywan (cpi->rd_filter_threshes[frame_type][i] + diff) / 2; 3278233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3279233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3280233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < TX_MODES; ++i) { 3281233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t pd = cpi->rd_tx_select_diff[i]; 3282233d2500723e5594f3e7c70896ffeeef32b9c950ywan int diff; 3283233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (i == TX_MODE_SELECT) 3284233d2500723e5594f3e7c70896ffeeef32b9c950ywan pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv, 2048 * (TX_SIZES - 1), 0); 3285233d2500723e5594f3e7c70896ffeeef32b9c950ywan diff = (int) (pd / cm->MBs); 3286233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_tx_select_threshes[frame_type][i] += diff; 3287233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->rd_tx_select_threshes[frame_type][i] /= 2; 3288233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3289233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3290233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->reference_mode == REFERENCE_MODE_SELECT) { 3291233d2500723e5594f3e7c70896ffeeef32b9c950ywan int single_count_zero = 0; 3292233d2500723e5594f3e7c70896ffeeef32b9c950ywan int comp_count_zero = 0; 3293233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3294233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < COMP_INTER_CONTEXTS; i++) { 3295233d2500723e5594f3e7c70896ffeeef32b9c950ywan single_count_zero += cm->counts.comp_inter[i][0]; 3296233d2500723e5594f3e7c70896ffeeef32b9c950ywan comp_count_zero += cm->counts.comp_inter[i][1]; 3297233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3298233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3299233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (comp_count_zero == 0) { 3300233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->reference_mode = SINGLE_REFERENCE; 3301233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cm->counts.comp_inter); 3302233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (single_count_zero == 0) { 3303233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->reference_mode = COMPOUND_REFERENCE; 3304233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(cm->counts.comp_inter); 3305233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3306233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3307233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3308233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->tx_mode == TX_MODE_SELECT) { 3309233d2500723e5594f3e7c70896ffeeef32b9c950ywan int count4x4 = 0; 3310233d2500723e5594f3e7c70896ffeeef32b9c950ywan int count8x8_lp = 0, count8x8_8x8p = 0; 3311233d2500723e5594f3e7c70896ffeeef32b9c950ywan int count16x16_16x16p = 0, count16x16_lp = 0; 3312233d2500723e5594f3e7c70896ffeeef32b9c950ywan int count32x32 = 0; 3313233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3314233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < TX_SIZE_CONTEXTS; ++i) { 3315233d2500723e5594f3e7c70896ffeeef32b9c950ywan count4x4 += cm->counts.tx.p32x32[i][TX_4X4]; 3316233d2500723e5594f3e7c70896ffeeef32b9c950ywan count4x4 += cm->counts.tx.p16x16[i][TX_4X4]; 3317233d2500723e5594f3e7c70896ffeeef32b9c950ywan count4x4 += cm->counts.tx.p8x8[i][TX_4X4]; 3318233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3319233d2500723e5594f3e7c70896ffeeef32b9c950ywan count8x8_lp += cm->counts.tx.p32x32[i][TX_8X8]; 3320233d2500723e5594f3e7c70896ffeeef32b9c950ywan count8x8_lp += cm->counts.tx.p16x16[i][TX_8X8]; 3321233d2500723e5594f3e7c70896ffeeef32b9c950ywan count8x8_8x8p += cm->counts.tx.p8x8[i][TX_8X8]; 3322233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3323233d2500723e5594f3e7c70896ffeeef32b9c950ywan count16x16_16x16p += cm->counts.tx.p16x16[i][TX_16X16]; 3324233d2500723e5594f3e7c70896ffeeef32b9c950ywan count16x16_lp += cm->counts.tx.p32x32[i][TX_16X16]; 3325233d2500723e5594f3e7c70896ffeeef32b9c950ywan count32x32 += cm->counts.tx.p32x32[i][TX_32X32]; 3326233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3327233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3328233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (count4x4 == 0 && count16x16_lp == 0 && count16x16_16x16p == 0 && 3329233d2500723e5594f3e7c70896ffeeef32b9c950ywan count32x32 == 0) { 3330233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->tx_mode = ALLOW_8X8; 3331233d2500723e5594f3e7c70896ffeeef32b9c950ywan reset_skip_txfm_size(cm, TX_8X8); 3332233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (count8x8_8x8p == 0 && count16x16_16x16p == 0 && 3333233d2500723e5594f3e7c70896ffeeef32b9c950ywan count8x8_lp == 0 && count16x16_lp == 0 && count32x32 == 0) { 3334233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->tx_mode = ONLY_4X4; 3335233d2500723e5594f3e7c70896ffeeef32b9c950ywan reset_skip_txfm_size(cm, TX_4X4); 3336233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (count8x8_lp == 0 && count16x16_lp == 0 && count4x4 == 0) { 3337233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->tx_mode = ALLOW_32X32; 3338233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (count32x32 == 0 && count8x8_lp == 0 && count4x4 == 0) { 3339233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->tx_mode = ALLOW_16X16; 3340233d2500723e5594f3e7c70896ffeeef32b9c950ywan reset_skip_txfm_size(cm, TX_16X16); 3341233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3342233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3343233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3344233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->mb.e_mbd.lossless = cpi->oxcf.lossless; 3345233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->reference_mode = SINGLE_REFERENCE; 3346233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Force the usage of the BILINEAR interp_filter. 3347233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->interp_filter = BILINEAR; 3348233d2500723e5594f3e7c70896ffeeef32b9c950ywan encode_frame_internal(cpi); 3349233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3350233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 3351233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3352233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) { 3353233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MB_PREDICTION_MODE y_mode = mi->mbmi.mode; 3354233d2500723e5594f3e7c70896ffeeef32b9c950ywan const MB_PREDICTION_MODE uv_mode = mi->mbmi.uv_mode; 3355233d2500723e5594f3e7c70896ffeeef32b9c950ywan const BLOCK_SIZE bsize = mi->mbmi.sb_type; 3356233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3357233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (bsize < BLOCK_8X8) { 3358233d2500723e5594f3e7c70896ffeeef32b9c950ywan int idx, idy; 3359233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize]; 3360233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int num_4x4_h = num_4x4_blocks_high_lookup[bsize]; 3361233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (idy = 0; idy < 2; idy += num_4x4_h) 3362233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (idx = 0; idx < 2; idx += num_4x4_w) 3363233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode]; 3364233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3365233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++counts->y_mode[size_group_lookup[bsize]][y_mode]; 3366233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3367233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3368233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++counts->uv_mode[y_mode][uv_mode]; 3369233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 3370233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3371233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Experimental stub function to create a per MB zbin adjustment based on 3372233d2500723e5594f3e7c70896ffeeef32b9c950ywan// some previously calculated measure of MB activity. 3373233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x) { 3374233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if USE_ACT_INDEX 3375233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->act_zbin_adj = *(x->mb_activity_ptr); 3376233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 3377233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Apply the masking to the RD multiplier. 3378233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t act = *(x->mb_activity_ptr); 3379233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t a = act + 4 * cpi->activity_avg; 3380233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int64_t b = 4 * act + cpi->activity_avg; 3381233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3382233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (act > cpi->activity_avg) 3383233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->act_zbin_adj = (int) (((int64_t) b + (a >> 1)) / a) - 1; 3384233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 3385233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->act_zbin_adj = 1 - (int) (((int64_t) a + (b >> 1)) / b); 3386233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 3387233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 3388233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3389233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int get_zbin_mode_boost(const MB_MODE_INFO *mbmi, int enabled) { 3390233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (enabled) { 3391233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_inter_block(mbmi)) { 3392233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mbmi->mode == ZEROMV) { 3393233d2500723e5594f3e7c70896ffeeef32b9c950ywan return mbmi->ref_frame[0] != LAST_FRAME ? GF_ZEROMV_ZBIN_BOOST 3394233d2500723e5594f3e7c70896ffeeef32b9c950ywan : LF_ZEROMV_ZBIN_BOOST; 3395233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3396233d2500723e5594f3e7c70896ffeeef32b9c950ywan return mbmi->sb_type < BLOCK_8X8 ? SPLIT_MV_ZBIN_BOOST 3397233d2500723e5594f3e7c70896ffeeef32b9c950ywan : MV_ZBIN_BOOST; 3398233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3399233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3400233d2500723e5594f3e7c70896ffeeef32b9c950ywan return INTRA_ZBIN_BOOST; 3401233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3402233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3403233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 3404233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3405233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 3406233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3407233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, 3408233d2500723e5594f3e7c70896ffeeef32b9c950ywan int mi_row, int mi_col, BLOCK_SIZE bsize) { 3409233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &cpi->common; 3410233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCK *const x = &cpi->mb; 3411233d2500723e5594f3e7c70896ffeeef32b9c950ywan MACROBLOCKD *const xd = &x->e_mbd; 3412233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO **mi_8x8 = xd->mi; 3413233d2500723e5594f3e7c70896ffeeef32b9c950ywan MODE_INFO *mi = mi_8x8[0]; 3414233d2500723e5594f3e7c70896ffeeef32b9c950ywan MB_MODE_INFO *mbmi = &mi->mbmi; 3415233d2500723e5594f3e7c70896ffeeef32b9c950ywan PICK_MODE_CONTEXT *ctx = get_block_context(x, bsize); 3416233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int segment_id = mbmi->segment_id; 3417233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mis = cm->mi_stride; 3418233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mi_width = num_8x8_blocks_wide_lookup[bsize]; 3419233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int mi_height = num_8x8_blocks_high_lookup[bsize]; 3420233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3421233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8 && 3422233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->oxcf.aq_mode != COMPLEXITY_AQ && 3423233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->oxcf.aq_mode != CYCLIC_REFRESH_AQ && 3424233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->sf.allow_skip_recode; 3425233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3426233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->skip_optimize = ctx->is_coded; 3427233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->is_coded = 1; 3428233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct; 3429233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->skip_encode = (!output_enabled && cpi->sf.skip_encode_frame && 3430233d2500723e5594f3e7c70896ffeeef32b9c950ywan x->q_index < QIDX_SKIP_THRESH); 3431233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3432233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (x->skip_encode) 3433233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 3434233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3435233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->frame_type == KEY_FRAME) { 3436233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { 3437233d2500723e5594f3e7c70896ffeeef32b9c950ywan adjust_act_zbin(cpi, x); 3438233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_update_zbin_extra(cpi, x); 3439233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3440233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3441233d2500723e5594f3e7c70896ffeeef32b9c950ywan set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]); 3442233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3443233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cpi->oxcf.tuning == VP8_TUNE_SSIM) { 3444233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Adjust the zbin based on this MB rate. 3445233d2500723e5594f3e7c70896ffeeef32b9c950ywan adjust_act_zbin(cpi, x); 3446233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3447233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3448233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Experimental code. Special case for gf and arf zeromv modes. 3449233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Increase zbin size to suppress noise 3450233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->zbin_mode_boost = get_zbin_mode_boost(mbmi, 3451233d2500723e5594f3e7c70896ffeeef32b9c950ywan cpi->zbin_mode_boost_enabled); 3452233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_update_zbin_extra(cpi, x); 3453233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3454233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3455233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!is_inter_block(mbmi)) { 3456233d2500723e5594f3e7c70896ffeeef32b9c950ywan int plane; 3457233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->skip = 1; 3458233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (plane = 0; plane < MAX_MB_PLANE; ++plane) 3459233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_encode_intra_block_plane(x, MAX(bsize, BLOCK_8X8), plane); 3460233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) 3461233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum_intra_stats(&cm->counts, mi); 3462233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8)); 3463233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3464233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref; 3465233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int is_compound = has_second_ref(mbmi); 3466233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (ref = 0; ref < 1 + is_compound; ++ref) { 3467233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi, 3468233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->ref_frame[ref]); 3469233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_setup_pre_planes(xd, ref, cfg, mi_row, mi_col, 3470233d2500723e5594f3e7c70896ffeeef32b9c950ywan &xd->block_refs[ref]->sf); 3471233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3472233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8)); 3473233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3474233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!x->skip) { 3475233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->skip = 1; 3476233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_encode_sb(x, MAX(bsize, BLOCK_8X8)); 3477233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_tokenize_sb(cpi, t, !output_enabled, MAX(bsize, BLOCK_8X8)); 3478233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3479233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->skip = 1; 3480233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) 3481233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->counts.skip[vp9_get_skip_context(xd)][1]++; 3482233d2500723e5594f3e7c70896ffeeef32b9c950ywan reset_skip_context(xd, MAX(bsize, BLOCK_8X8)); 3483233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3484233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3485233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3486233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (output_enabled) { 3487233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->tx_mode == TX_MODE_SELECT && 3488233d2500723e5594f3e7c70896ffeeef32b9c950ywan mbmi->sb_type >= BLOCK_8X8 && 3489233d2500723e5594f3e7c70896ffeeef32b9c950ywan !(is_inter_block(mbmi) && 3490233d2500723e5594f3e7c70896ffeeef32b9c950ywan (mbmi->skip || 3491233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)))) { 3492233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++get_tx_counts(max_txsize_lookup[bsize], vp9_get_tx_size_context(xd), 3493233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cm->counts.tx)[mbmi->tx_size]; 3494233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3495233d2500723e5594f3e7c70896ffeeef32b9c950ywan int x, y; 3496233d2500723e5594f3e7c70896ffeeef32b9c950ywan TX_SIZE tx_size; 3497233d2500723e5594f3e7c70896ffeeef32b9c950ywan // The new intra coding scheme requires no change of transform size 3498233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (is_inter_block(&mi->mbmi)) { 3499233d2500723e5594f3e7c70896ffeeef32b9c950ywan tx_size = MIN(tx_mode_to_biggest_tx_size[cm->tx_mode], 3500233d2500723e5594f3e7c70896ffeeef32b9c950ywan max_txsize_lookup[bsize]); 3501233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 3502233d2500723e5594f3e7c70896ffeeef32b9c950ywan tx_size = (bsize >= BLOCK_8X8) ? mbmi->tx_size : TX_4X4; 3503233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3504233d2500723e5594f3e7c70896ffeeef32b9c950ywan 3505233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (y = 0; y < mi_height; y++) 3506233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (x = 0; x < mi_width; x++) 3507233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mi_col + x < cm->mi_cols && mi_row + y < cm->mi_rows) 3508233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_8x8[mis * y + x]->mbmi.tx_size = tx_size; 3509233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3510233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 3511233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 3512