summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/encoder/rdopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/aom/av1/encoder/rdopt.c')
-rw-r--r--third_party/aom/av1/encoder/rdopt.c3785
1 files changed, 1000 insertions, 2785 deletions
diff --git a/third_party/aom/av1/encoder/rdopt.c b/third_party/aom/av1/encoder/rdopt.c
index a1096f782..2a537a06a 100644
--- a/third_party/aom/av1/encoder/rdopt.c
+++ b/third_party/aom/av1/encoder/rdopt.c
@@ -66,11 +66,18 @@
#endif // CONFIG_PVQ || CONFIG_DAALA_DIST
#if CONFIG_DUAL_FILTER
#define DUAL_FILTER_SET_SIZE (SWITCHABLE_FILTERS * SWITCHABLE_FILTERS)
+#if USE_EXTRA_FILTER
static const int filter_sets[DUAL_FILTER_SET_SIZE][2] = {
{ 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 0 }, { 1, 1 },
{ 1, 2 }, { 1, 3 }, { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 },
{ 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 },
};
+#else // USE_EXTRA_FILTER
+static const int filter_sets[DUAL_FILTER_SET_SIZE][2] = {
+ { 0, 0 }, { 0, 1 }, { 0, 2 }, { 1, 0 }, { 1, 1 },
+ { 1, 2 }, { 2, 0 }, { 2, 1 }, { 2, 2 },
+};
+#endif // USE_EXTRA_FILTER
#endif // CONFIG_DUAL_FILTER
#if CONFIG_EXT_REFS
@@ -217,11 +224,13 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
#if CONFIG_ALT_INTRA
{ SMOOTH_PRED, { INTRA_FRAME, NONE_FRAME } },
+#if CONFIG_SMOOTH_HV
+ { SMOOTH_V_PRED, { INTRA_FRAME, NONE_FRAME } },
+ { SMOOTH_H_PRED, { INTRA_FRAME, NONE_FRAME } },
+#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
#if CONFIG_EXT_INTER
- { NEAR_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
- { NEAREST_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
{ NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
{ NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
{ NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
@@ -231,8 +240,6 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
{ ZERO_ZEROMV, { LAST_FRAME, ALTREF_FRAME } },
#if CONFIG_EXT_REFS
- { NEAR_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
- { NEAREST_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
{ NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
{ NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
{ NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
@@ -241,8 +248,6 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
{ NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
{ ZERO_ZEROMV, { LAST2_FRAME, ALTREF_FRAME } },
- { NEAR_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
- { NEAREST_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
{ NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
{ NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
{ NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
@@ -252,8 +257,6 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
{ ZERO_ZEROMV, { LAST3_FRAME, ALTREF_FRAME } },
#endif // CONFIG_EXT_REFS
- { NEAR_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
- { NEAREST_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
{ NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
{ NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
{ NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
@@ -263,8 +266,6 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
{ ZERO_ZEROMV, { GOLDEN_FRAME, ALTREF_FRAME } },
#if CONFIG_EXT_REFS
- { NEAR_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
- { NEAREST_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
{ NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
{ NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
{ NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
@@ -273,8 +274,6 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
{ NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
{ ZERO_ZEROMV, { LAST_FRAME, BWDREF_FRAME } },
- { NEAR_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
- { NEAREST_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
{ NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
{ NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
{ NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
@@ -283,8 +282,6 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
{ NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
{ ZERO_ZEROMV, { LAST2_FRAME, BWDREF_FRAME } },
- { NEAR_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
- { NEAREST_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
{ NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
{ NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
{ NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
@@ -293,8 +290,6 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
{ NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
{ ZERO_ZEROMV, { LAST3_FRAME, BWDREF_FRAME } },
- { NEAR_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
- { NEAREST_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
{ NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
{ NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
{ NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
@@ -390,28 +385,6 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
#endif // CONFIG_EXT_INTER
};
-static const REF_DEFINITION av1_ref_order[MAX_REFS] = {
- { { LAST_FRAME, NONE_FRAME } },
-#if CONFIG_EXT_REFS
- { { LAST2_FRAME, NONE_FRAME } }, { { LAST3_FRAME, NONE_FRAME } },
- { { BWDREF_FRAME, NONE_FRAME } },
-#endif // CONFIG_EXT_REFS
- { { GOLDEN_FRAME, NONE_FRAME } }, { { ALTREF_FRAME, NONE_FRAME } },
-
- { { LAST_FRAME, ALTREF_FRAME } },
-#if CONFIG_EXT_REFS
- { { LAST2_FRAME, ALTREF_FRAME } }, { { LAST3_FRAME, ALTREF_FRAME } },
-#endif // CONFIG_EXT_REFS
- { { GOLDEN_FRAME, ALTREF_FRAME } },
-
-#if CONFIG_EXT_REFS
- { { LAST_FRAME, BWDREF_FRAME } }, { { LAST2_FRAME, BWDREF_FRAME } },
- { { LAST3_FRAME, BWDREF_FRAME } }, { { GOLDEN_FRAME, BWDREF_FRAME } },
-#endif // CONFIG_EXT_REFS
-
- { { INTRA_FRAME, NONE_FRAME } },
-};
-
#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
static INLINE int write_uniform_cost(int n, int v) {
const int l = get_unsigned_bits(n);
@@ -430,22 +403,6 @@ static INLINE int write_uniform_cost(int n, int v) {
#define FAST_EXT_TX_CORR_MARGIN 0.5
#define FAST_EXT_TX_EDST_MARGIN 0.3
-static const TX_TYPE_1D vtx_tab[TX_TYPES] = {
- DCT_1D, ADST_1D, DCT_1D, ADST_1D,
-#if CONFIG_EXT_TX
- FLIPADST_1D, DCT_1D, FLIPADST_1D, ADST_1D, FLIPADST_1D, IDTX_1D,
- DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D, IDTX_1D,
-#endif // CONFIG_EXT_TX
-};
-
-static const TX_TYPE_1D htx_tab[TX_TYPES] = {
- DCT_1D, DCT_1D, ADST_1D, ADST_1D,
-#if CONFIG_EXT_TX
- DCT_1D, FLIPADST_1D, FLIPADST_1D, FLIPADST_1D, ADST_1D, IDTX_1D,
- IDTX_1D, DCT_1D, IDTX_1D, ADST_1D, IDTX_1D, FLIPADST_1D,
-#endif // CONFIG_EXT_TX
-};
-
#if CONFIG_DAALA_DIST
static int od_compute_var_4x4(od_coeff *x, int stride) {
int sum;
@@ -603,10 +560,9 @@ static double od_compute_dist(int qm, int activity_masking, od_coeff *x,
return sum;
}
-static int64_t av1_daala_dist(const uint8_t *src, int src_stride,
- const uint8_t *dst, int dst_stride, int bsw,
- int bsh, int qm, int use_activity_masking,
- int qindex) {
+int64_t av1_daala_dist(const uint8_t *src, int src_stride, const uint8_t *dst,
+ int dst_stride, int bsw, int bsh, int qm,
+ int use_activity_masking, int qindex) {
int i, j;
int64_t d;
DECLARE_ALIGNED(16, od_coeff, orig[MAX_TX_SQUARE]);
@@ -843,7 +799,7 @@ static int prune_one_for_sby(const AV1_COMP *cpi, BLOCK_SIZE bsize,
static int prune_tx_types(const AV1_COMP *cpi, BLOCK_SIZE bsize, MACROBLOCK *x,
const MACROBLOCKD *const xd, int tx_set) {
#if CONFIG_EXT_TX
- const int *tx_set_1D = ext_tx_used_inter_1D[tx_set];
+ const int *tx_set_1D = tx_set >= 0 ? ext_tx_used_inter_1D[tx_set] : NULL;
#else
const int tx_set_1D[TX_TYPES_1D] = { 0 };
#endif // CONFIG_EXT_TX
@@ -1100,13 +1056,10 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
int c, cost;
const int16_t *scan = scan_order->scan;
const int16_t *nb = scan_order->neighbors;
-#if CONFIG_NEW_TOKENSET
const int ref = is_inter_block(mbmi);
aom_prob *blockz_probs =
cm->fc->blockzero_probs[txsize_sqr_map[tx_size]][type][ref];
-#endif // CONFIG_NEW_TOKENSET
-
#if CONFIG_HIGHBITDEPTH
const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
#else
@@ -1120,12 +1073,8 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
(void)cm;
if (eob == 0) {
-#if CONFIG_NEW_TOKENSET
// single eob token
cost = av1_cost_bit(blockz_probs[pt], 0);
-#else
- cost = token_costs[0][0][pt][EOB_TOKEN];
-#endif // CONFIG_NEW_TOKENSET
} else {
if (use_fast_coef_costing) {
int band_left = *band_count++;
@@ -1134,11 +1083,7 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
int v = qcoeff[0];
int16_t prev_t;
cost = av1_get_token_cost(v, &prev_t, cat6_bits);
-#if CONFIG_NEW_TOKENSET
cost += (*token_costs)[!prev_t][pt][prev_t];
-#else
- cost += (*token_costs)[0][pt][prev_t];
-#endif
token_cache[0] = av1_pt_energy_class[prev_t];
++token_costs;
@@ -1150,11 +1095,7 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
v = qcoeff[rc];
cost += av1_get_token_cost(v, &t, cat6_bits);
-#if CONFIG_NEW_TOKENSET
cost += (*token_costs)[!t][!prev_t][t];
-#else
- cost += (*token_costs)[!prev_t][!prev_t][t];
-#endif
prev_t = t;
if (!--band_left) {
band_left = *band_count++;
@@ -1163,8 +1104,7 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
}
// eob token
- if (band_left || CONFIG_NEW_TOKENSET)
- cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
+ cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
} else { // !use_fast_coef_costing
int band_left = *band_count++;
@@ -1172,23 +1112,12 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
// dc token
int v = qcoeff[0];
int16_t tok;
-#if !CONFIG_NEW_TOKENSET
- unsigned int(*tok_cost_ptr)[COEFF_CONTEXTS][ENTROPY_TOKENS];
-#endif
cost = av1_get_token_cost(v, &tok, cat6_bits);
-#if CONFIG_NEW_TOKENSET
cost += (*token_costs)[!tok][pt][tok];
-#else
- cost += (*token_costs)[0][pt][tok];
-#endif
token_cache[0] = av1_pt_energy_class[tok];
++token_costs;
-#if !CONFIG_NEW_TOKENSET
- tok_cost_ptr = &((*token_costs)[!tok]);
-#endif
-
// ac tokens
for (c = 1; c < eob; c++) {
const int rc = scan[c];
@@ -1196,26 +1125,17 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
v = qcoeff[rc];
cost += av1_get_token_cost(v, &tok, cat6_bits);
pt = get_coef_context(nb, token_cache, c);
-#if CONFIG_NEW_TOKENSET
cost += (*token_costs)[!tok][pt][tok];
-#else
- cost += (*tok_cost_ptr)[pt][tok];
-#endif
token_cache[rc] = av1_pt_energy_class[tok];
if (!--band_left) {
band_left = *band_count++;
++token_costs;
}
-#if !CONFIG_NEW_TOKENSET
- tok_cost_ptr = &((*token_costs)[!tok]);
-#endif
}
// eob token
- if (band_left || CONFIG_NEW_TOKENSET) {
- pt = get_coef_context(nb, token_cache, c);
- cost += (*token_costs)[0][pt][EOB_TOKEN];
- }
+ pt = get_coef_context(nb, token_cache, c);
+ cost += (*token_costs)[0][pt][EOB_TOKEN];
}
}
@@ -1262,7 +1182,9 @@ static void get_txb_dimensions(const MACROBLOCKD *xd, int plane,
BLOCK_SIZE plane_bsize, int blk_row, int blk_col,
BLOCK_SIZE tx_bsize, int *width, int *height,
int *visible_width, int *visible_height) {
+#if !(CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT)
assert(tx_bsize <= plane_bsize);
+#endif // !(CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT)
int txb_height = block_size_high[tx_bsize];
int txb_width = block_size_wide[tx_bsize];
const int block_height = block_size_high[plane_bsize];
@@ -1298,7 +1220,12 @@ static unsigned pixel_sse(const AV1_COMP *const cpi, const MACROBLOCKD *xd,
&txb_cols, &txb_rows, &visible_cols, &visible_rows);
assert(visible_rows > 0);
assert(visible_cols > 0);
+#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
+ if ((txb_rows == visible_rows && txb_cols == visible_cols) &&
+ tx_bsize < BLOCK_SIZES) {
+#else
if (txb_rows == visible_rows && txb_cols == visible_cols) {
+#endif
unsigned sse;
cpi->fn_ptr[tx_bsize].vf(src, src_stride, dst, dst_stride, &sse);
return sse;
@@ -1533,7 +1460,36 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
if (args->exit_early) return;
if (!is_inter_block(mbmi)) {
+#if CONFIG_CFL
+
+#if CONFIG_EC_ADAPT
+ FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
+#else
+ FRAME_CONTEXT *const ec_ctx = cm->fc;
+#endif // CONFIG_EC_ADAPT
+
+ av1_predict_intra_block_encoder_facade(x, ec_ctx, plane, block, blk_col,
+ blk_row, tx_size, plane_bsize);
+#else
av1_predict_intra_block_facade(xd, plane, block, blk_col, blk_row, tx_size);
+#endif
+#if CONFIG_DPCM_INTRA
+ const int block_raster_idx =
+ av1_block_index_to_raster_order(tx_size, block);
+ const PREDICTION_MODE mode =
+ (plane == 0) ? get_y_mode(xd->mi[0], block_raster_idx) : mbmi->uv_mode;
+ TX_TYPE tx_type = get_tx_type((plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV,
+ xd, block, tx_size);
+ if (av1_use_dpcm_intra(plane, mode, tx_type, mbmi)) {
+ int8_t skip;
+ av1_encode_block_intra_dpcm(cm, x, mode, plane, block, blk_row, blk_col,
+ plane_bsize, tx_size, tx_type, a, l, &skip);
+ av1_dist_block(args->cpi, x, plane, plane_bsize, block, blk_row, blk_col,
+ tx_size, &this_rd_stats.dist, &this_rd_stats.sse,
+ OUTPUT_HAS_DECODED_PIXELS);
+ goto CALCULATE_RD;
+ }
+#endif // CONFIG_DPCM_INTRA
av1_subtract_txb(x, plane, plane_bsize, blk_col, blk_row, tx_size);
}
@@ -1542,8 +1498,7 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
const int coeff_ctx = combine_entropy_contexts(*a, *l);
av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
coeff_ctx, AV1_XFORM_QUANT_FP);
- if (x->plane[plane].eobs[block] && !xd->lossless[mbmi->segment_id])
- av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
+ av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
if (!is_inter_block(mbmi)) {
struct macroblock_plane *const p = &x->plane[plane];
@@ -1566,6 +1521,9 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
cfl_store(xd->cfl, dst, dst_stride, blk_row, blk_col, tx_size);
}
#endif
+#if CONFIG_DPCM_INTRA
+CALCULATE_RD : {}
+#endif // CONFIG_DPCM_INTRA
rd = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.dist);
if (args->this_rd + rd > args->best_rd) {
args->exit_early = 1;
@@ -1603,7 +1561,7 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
rd = AOMMIN(rd1, rd2);
#if CONFIG_DAALA_DIST
- if (plane == 0 &&
+ if (plane == 0 && plane_bsize >= BLOCK_8X8 &&
(tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4)) {
this_rd_stats.dist = 0;
this_rd_stats.sse = 0;
@@ -1641,6 +1599,9 @@ static void block_8x8_rd_txfm_daala_dist(int plane, int block, int blk_row,
int use_activity_masking = 0;
(void)tx_size;
+
+ assert(plane == 0);
+ assert(plane_bsize >= BLOCK_8X8);
#if CONFIG_PVQ
use_activity_masking = x->daala_enc.use_activity_masking;
#endif // CONFIG_PVQ
@@ -1700,10 +1661,15 @@ static void block_8x8_rd_txfm_daala_dist(int plane, int block, int blk_row,
{
const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
+ const uint8_t txw_unit = tx_size_wide_unit[tx_size];
+ const uint8_t txh_unit = tx_size_high_unit[tx_size];
+ const int step = txw_unit * txh_unit;
+ int offset_h = tx_size_high_unit[TX_4X4];
// The rate of the current 8x8 block is the sum of four 4x4 blocks in it.
- this_rd_stats.rate = x->rate_4x4[block - max_blocks_wide - 1] +
- x->rate_4x4[block - max_blocks_wide] +
- x->rate_4x4[block - 1] + x->rate_4x4[block];
+ this_rd_stats.rate =
+ x->rate_4x4[block - max_blocks_wide * offset_h - step] +
+ x->rate_4x4[block - max_blocks_wide * offset_h] +
+ x->rate_4x4[block - step] + x->rate_4x4[block];
}
rd1 = RDCOST(x->rdmult, x->rddiv, this_rd_stats.rate, this_rd_stats.dist);
rd2 = RDCOST(x->rdmult, x->rddiv, 0, this_rd_stats.sse);
@@ -1740,10 +1706,10 @@ static void txfm_rd_in_plane(MACROBLOCK *x, const AV1_COMP *cpi,
av1_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
#if CONFIG_DAALA_DIST
- if (plane == 0 &&
+ if (plane == 0 && bsize >= BLOCK_8X8 &&
(tx_size == TX_4X4 || tx_size == TX_4X8 || tx_size == TX_8X4))
- av1_foreach_8x8_transformed_block_in_plane(
- xd, bsize, plane, block_rd_txfm, block_8x8_rd_txfm_daala_dist, &args);
+ av1_foreach_8x8_transformed_block_in_yplane(
+ xd, bsize, block_rd_txfm, block_8x8_rd_txfm_daala_dist, &args);
else
#endif // CONFIG_DAALA_DIST
av1_foreach_transformed_block_in_plane(xd, bsize, plane, block_rd_txfm,
@@ -1812,7 +1778,12 @@ static int tx_size_cost(const AV1_COMP *const cpi, const MACROBLOCK *const x,
const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
const int depth = tx_size_to_depth(coded_tx_size);
const int tx_size_ctx = get_tx_size_context(xd);
- const int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
+ int r_tx_size = cpi->tx_size_cost[tx_size_cat][tx_size_ctx][depth];
+#if CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
+ if (is_quarter_tx_allowed(xd, mbmi, is_inter) && tx_size != coded_tx_size)
+ r_tx_size += av1_cost_bit(cm->fc->quarter_tx_size_prob,
+ tx_size == quarter_txsize_lookup[bsize]);
+#endif // CONFIG_EXT_TX && CONFIG_RECT_TX && CONFIG_RECT_TX_EXT
return r_tx_size;
} else {
return 0;
@@ -1924,9 +1895,7 @@ static int skip_txfm_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs,
// transforms should be considered for pruning
prune = prune_tx_types(cpi, bs, x, xd, -1);
-#if CONFIG_REF_MV
if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) return 1;
-#endif // CONFIG_REF_MV
if (FIXED_TX_TYPE && tx_type != get_default_tx_type(0, xd, 0, tx_size))
return 1;
if (!is_inter && x->use_default_intra_tx_type &&
@@ -1960,7 +1929,7 @@ static int skip_txfm_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bs,
return 0;
}
-#if CONFIG_EXT_INTER
+#if CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
MACROBLOCK *x, int *r, int64_t *d, int *s,
int64_t *sse, int64_t ref_best_rd) {
@@ -1973,7 +1942,7 @@ static int64_t estimate_yrd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bs,
*sse = rd_stats.sse;
return rd;
}
-#endif // CONFIG_EXT_INTER
+#endif // CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
static void choose_largest_tx_size(const AV1_COMP *const cpi, MACROBLOCK *x,
RD_STATS *rd_stats, int64_t ref_best_rd,
@@ -2191,9 +2160,7 @@ static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
#endif
TX_TYPE tx_type;
for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
-#if CONFIG_REF_MV
if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
-#endif // CONFIG_REF_MV
const TX_SIZE rect_tx_size = max_txsize_rect_lookup[bs];
RD_STATS this_rd_stats;
int ext_tx_set =
@@ -2219,6 +2186,56 @@ static void choose_tx_size_type_from_rd(const AV1_COMP *const cpi,
#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
}
}
+
+#if CONFIG_RECT_TX_EXT
+ // test 1:4/4:1 tx
+ int evaluate_quarter_tx = 0;
+ if (is_quarter_tx_allowed(xd, mbmi, is_inter)) {
+ if (tx_select) {
+ evaluate_quarter_tx = 1;
+ } else {
+ const TX_SIZE chosen_tx_size =
+ tx_size_from_tx_mode(bs, cm->tx_mode, is_inter);
+ evaluate_quarter_tx = chosen_tx_size == quarter_txsize_lookup[bs];
+ }
+ }
+ if (evaluate_quarter_tx) {
+ TX_TYPE tx_start = DCT_DCT;
+ TX_TYPE tx_end = TX_TYPES;
+#if CONFIG_TXK_SEL
+ // The tx_type becomes dummy when lv_map is on. The tx_type search will be
+ // performed in av1_search_txk_type()
+ tx_end = DCT_DCT + 1;
+#endif
+ TX_TYPE tx_type;
+ for (tx_type = tx_start; tx_type < tx_end; ++tx_type) {
+ if (mbmi->ref_mv_idx > 0 && tx_type != DCT_DCT) continue;
+ const TX_SIZE tx_size = quarter_txsize_lookup[bs];
+ RD_STATS this_rd_stats;
+ int ext_tx_set =
+ get_ext_tx_set(tx_size, bs, is_inter, cm->reduced_tx_set_used);
+ if ((is_inter && ext_tx_used_inter[ext_tx_set][tx_type]) ||
+ (!is_inter && ext_tx_used_intra[ext_tx_set][tx_type])) {
+ rd =
+ txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs, tx_type, tx_size);
+ if (rd < best_rd) {
+#if CONFIG_TXK_SEL
+ memcpy(best_txk_type, mbmi->txk_type,
+ sizeof(best_txk_type[0]) * num_blk);
+#endif
+ best_tx_type = tx_type;
+ best_tx_size = tx_size;
+ best_rd = rd;
+ *rd_stats = this_rd_stats;
+ }
+ }
+#if CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
+ const int is_inter = is_inter_block(mbmi);
+ if (mbmi->sb_type < BLOCK_8X8 && is_inter) break;
+#endif // CONFIG_CB4X4 && !USE_TXTYPE_SEARCH_FOR_SUB8X8_IN_CB4X4
+ }
+ }
+#endif // CONFIG_RECT_TX_EXT
#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
if (tx_select) {
@@ -2334,6 +2351,7 @@ static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
BLOCK_SIZE bsize, int mode_cost) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+ assert(!is_inter_block(mbmi));
RD_STATS this_rd_stats;
int row, col;
int64_t temp_sse, this_rd;
@@ -2348,7 +2366,21 @@ static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
int block = 0;
for (row = 0; row < max_blocks_high; row += stepr) {
for (col = 0; col < max_blocks_wide; col += stepc) {
+#if CONFIG_CFL
+ const struct macroblockd_plane *const pd = &xd->plane[0];
+ const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
+
+#if CONFIG_EC_ADAPT
+ FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
+#else
+ FRAME_CONTEXT *const ec_ctx = cpi->common.fc;
+#endif // CONFIG_EC_ADAPT
+
+ av1_predict_intra_block_encoder_facade(x, ec_ctx, 0, block, col, row,
+ tx_size, plane_bsize);
+#else
av1_predict_intra_block_facade(xd, 0, block, col, row, tx_size);
+#endif
block += step;
}
}
@@ -2403,6 +2435,28 @@ static void extend_palette_color_map(uint8_t *const color_map, int orig_width,
}
}
+#if CONFIG_PALETTE_DELTA_ENCODING
+// Bias toward using colors in the cache.
+// TODO(huisu): Try other schemes to improve compression.
+static void optimize_palette_colors(uint16_t *color_cache, int n_cache,
+ int n_colors, int stride,
+ float *centroids) {
+ if (n_cache <= 0) return;
+ for (int i = 0; i < n_colors * stride; i += stride) {
+ float min_diff = fabsf(centroids[i] - color_cache[0]);
+ int idx = 0;
+ for (int j = 1; j < n_cache; ++j) {
+ float this_diff = fabsf(centroids[i] - color_cache[j]);
+ if (this_diff < min_diff) {
+ min_diff = this_diff;
+ idx = j;
+ }
+ }
+ if (min_diff < 1.5) centroids[i] = color_cache[idx];
+ }
+}
+#endif // CONFIG_PALETTE_DELTA_ENCODING
+
static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
BLOCK_SIZE bsize, int palette_ctx,
int dc_mode_cost, MB_MODE_INFO *best_mbmi,
@@ -2414,6 +2468,7 @@ static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
MACROBLOCKD *const xd = &x->e_mbd;
MODE_INFO *const mic = xd->mi[0];
MB_MODE_INFO *const mbmi = &mic->mbmi;
+ assert(!is_inter_block(mbmi));
int this_rate, colors, n;
const int src_stride = x->plane[0].src.stride;
const uint8_t *const src = x->plane[0].src.buf;
@@ -2488,12 +2543,38 @@ static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
if (rows * cols > PALETTE_MAX_BLOCK_SIZE) return 0;
+#if CONFIG_PALETTE_DELTA_ENCODING
+ const MODE_INFO *above_mi = xd->above_mi;
+ const MODE_INFO *left_mi = xd->left_mi;
+ uint16_t color_cache[2 * PALETTE_MAX_SIZE];
+ const int n_cache =
+ av1_get_palette_cache(above_mi, left_mi, 0, color_cache);
+#endif // CONFIG_PALETTE_DELTA_ENCODING
+
for (n = colors > PALETTE_MAX_SIZE ? PALETTE_MAX_SIZE : colors; n >= 2;
--n) {
- for (i = 0; i < n; ++i)
- centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
- av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
- k = av1_remove_duplicates(centroids, n);
+ if (colors == PALETTE_MIN_SIZE) {
+ // Special case: These colors automatically become the centroids.
+ assert(colors == n);
+ assert(colors == 2);
+ centroids[0] = lb;
+ centroids[1] = ub;
+ k = 2;
+ } else {
+ for (i = 0; i < n; ++i) {
+ centroids[i] = lb + (2 * i + 1) * (ub - lb) / n / 2;
+ }
+ av1_k_means(data, centroids, color_map, rows * cols, n, 1, max_itr);
+#if CONFIG_PALETTE_DELTA_ENCODING
+ optimize_palette_colors(color_cache, n_cache, n, 1, centroids);
+#endif // CONFIG_PALETTE_DELTA_ENCODING
+ k = av1_remove_duplicates(centroids, n);
+ if (k < PALETTE_MIN_SIZE) {
+ // Too few unique colors to create a palette. And DC_PRED will work
+ // well for that case anyway. So skip.
+ continue;
+ }
+ }
#if CONFIG_HIGHBITDEPTH
if (cpi->common.use_highbitdepth)
@@ -2516,7 +2597,11 @@ static int rd_pick_palette_intra_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
av1_cost_bit(
av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
1);
- palette_mode_cost += av1_palette_color_cost_y(pmi, cpi->common.bit_depth);
+ palette_mode_cost += av1_palette_color_cost_y(pmi,
+#if CONFIG_PALETTE_DELTA_ENCODING
+ color_cache, n_cache,
+#endif // CONFIG_PALETTE_DELTA_ENCODING
+ cpi->common.bit_depth);
for (i = 0; i < rows; ++i) {
for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
int color_idx;
@@ -2570,6 +2655,7 @@ static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
const AV1_COMMON *const cm = &cpi->common;
PREDICTION_MODE mode;
MACROBLOCKD *const xd = &x->e_mbd;
+ assert(!is_inter_block(&xd->mi[0]->mbmi));
int64_t best_rd = rd_thresh;
struct macroblock_plane *p = &x->plane[0];
struct macroblockd_plane *pd = &xd->plane[0];
@@ -2577,7 +2663,7 @@ static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
const int dst_stride = pd->dst.stride;
const uint8_t *src_init = &p->src.buf[row * 4 * src_stride + col * 4];
uint8_t *dst_init = &pd->dst.buf[row * 4 * dst_stride + col * 4];
-#if CONFIG_CB4X4
+#if CONFIG_CHROMA_2X2
// TODO(jingning): This is a temporal change. The whole function should be
// out when cb4x4 is enabled.
ENTROPY_CONTEXT ta[4], tempa[4];
@@ -2585,7 +2671,7 @@ static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
#else
ENTROPY_CONTEXT ta[2], tempa[2];
ENTROPY_CONTEXT tl[2], templ[2];
-#endif // CONFIG_CB4X4
+#endif // CONFIG_CHROMA_2X2
const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
@@ -2738,7 +2824,8 @@ static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
#if !CONFIG_PVQ
av1_xform_quant(cm, x, 0, block, row + idy, col + idx, BLOCK_8X8,
tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
- av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
+ av1_optimize_b(cm, x, 0, block, BLOCK_8X8, tx_size, tempa + idx,
+ templ + idy);
ratey += av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order,
tempa + idx, templ + idy,
cpi->sf.use_fast_coef_costing);
@@ -2897,9 +2984,8 @@ static int64_t rd_pick_intra_sub_8x8_y_subblock_mode(
#endif // CONFIG_CB4X4
BLOCK_8X8, tx_size, coeff_ctx, xform_quant);
- if (!is_lossless) {
- av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
- }
+ av1_optimize_b(cm, x, 0, block, BLOCK_8X8, tx_size, tempa + idx,
+ templ + idy);
ratey +=
av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, tempa + idx,
@@ -3013,6 +3099,7 @@ static int64_t rd_pick_intra_sub_8x8_y_mode(const AV1_COMP *const cpi,
const MODE_INFO *above_mi = xd->above_mi;
const MODE_INFO *left_mi = xd->left_mi;
MB_MODE_INFO *const mbmi = &mic->mbmi;
+ assert(!is_inter_block(mbmi));
const BLOCK_SIZE bsize = mbmi->sb_type;
const int pred_width_in_4x4_blocks = num_4x4_blocks_wide_lookup[bsize];
const int pred_height_in_4x4_blocks = num_4x4_blocks_high_lookup[bsize];
@@ -3220,6 +3307,7 @@ static int64_t calc_rd_given_intra_angle(
RD_STATS tokenonly_rd_stats;
int64_t this_rd, this_model_rd;
MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
+ assert(!is_inter_block(mbmi));
mbmi->angle_delta[0] = angle_delta;
this_model_rd = intra_model_yrd(cpi, x, bsize, mode_cost);
@@ -3261,6 +3349,7 @@ static int64_t rd_pick_intra_angle_sby(const AV1_COMP *const cpi, MACROBLOCK *x,
MACROBLOCKD *const xd = &x->e_mbd;
MODE_INFO *const mic = xd->mi[0];
MB_MODE_INFO *mbmi = &mic->mbmi;
+ assert(!is_inter_block(mbmi));
int i, angle_delta, best_angle_delta = 0;
int first_try = 1;
#if CONFIG_INTRA_INTERP
@@ -3393,32 +3482,40 @@ static const uint8_t gradient_to_angle_bin[2][7][16] = {
},
};
+/* clang-format off */
static const uint8_t mode_to_angle_bin[INTRA_MODES] = {
0, 2, 6, 0, 4, 3, 5, 7, 1, 0,
+#if CONFIG_ALT_INTRA
+ 0,
+#endif // CONFIG_ALT_INTRA
};
+/* clang-format on */
static void angle_estimation(const uint8_t *src, int src_stride, int rows,
- int cols, uint8_t *directional_mode_skip_mask) {
- int i, r, c, index, dx, dy, temp, sn, remd, quot;
+ int cols, BLOCK_SIZE bsize,
+ uint8_t *directional_mode_skip_mask) {
+ memset(directional_mode_skip_mask, 0,
+ INTRA_MODES * sizeof(*directional_mode_skip_mask));
+ // Sub-8x8 blocks do not use extra directions.
+ if (bsize < BLOCK_8X8) return;
uint64_t hist[DIRECTIONAL_MODES];
- uint64_t hist_sum = 0;
-
memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
src += src_stride;
+ int r, c, dx, dy;
for (r = 1; r < rows; ++r) {
for (c = 1; c < cols; ++c) {
dx = src[c] - src[c - 1];
dy = src[c] - src[c - src_stride];
- temp = dx * dx + dy * dy;
+ int index;
+ const int temp = dx * dx + dy * dy;
if (dy == 0) {
index = 2;
} else {
- sn = (dx > 0) ^ (dy > 0);
+ const int sn = (dx > 0) ^ (dy > 0);
dx = abs(dx);
dy = abs(dy);
- remd = dx % dy;
- quot = dx / dy;
- remd = remd * 16 / dy;
+ const int remd = (dx % dy) * 16 / dy;
+ const int quot = dx / dy;
index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
}
hist[index] += temp;
@@ -3426,9 +3523,11 @@ static void angle_estimation(const uint8_t *src, int src_stride, int rows,
src += src_stride;
}
+ int i;
+ uint64_t hist_sum = 0;
for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
for (i = 0; i < INTRA_MODES; ++i) {
- if (i != DC_PRED && i != TM_PRED) {
+ if (av1_is_directional_mode(i, bsize)) {
const uint8_t angle_bin = mode_to_angle_bin[i];
uint64_t score = 2 * hist[angle_bin];
int weight = 2;
@@ -3448,29 +3547,31 @@ static void angle_estimation(const uint8_t *src, int src_stride, int rows,
#if CONFIG_HIGHBITDEPTH
static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
- int rows, int cols,
+ int rows, int cols, BLOCK_SIZE bsize,
uint8_t *directional_mode_skip_mask) {
- int i, r, c, index, dx, dy, temp, sn, remd, quot;
- uint64_t hist[DIRECTIONAL_MODES];
- uint64_t hist_sum = 0;
+ memset(directional_mode_skip_mask, 0,
+ INTRA_MODES * sizeof(*directional_mode_skip_mask));
+ // Sub-8x8 blocks do not use extra directions.
+ if (bsize < BLOCK_8X8) return;
uint16_t *src = CONVERT_TO_SHORTPTR(src8);
-
+ uint64_t hist[DIRECTIONAL_MODES];
memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
src += src_stride;
+ int r, c, dx, dy;
for (r = 1; r < rows; ++r) {
for (c = 1; c < cols; ++c) {
dx = src[c] - src[c - 1];
dy = src[c] - src[c - src_stride];
- temp = dx * dx + dy * dy;
+ int index;
+ const int temp = dx * dx + dy * dy;
if (dy == 0) {
index = 2;
} else {
- sn = (dx > 0) ^ (dy > 0);
+ const int sn = (dx > 0) ^ (dy > 0);
dx = abs(dx);
dy = abs(dy);
- remd = dx % dy;
- quot = dx / dy;
- remd = remd * 16 / dy;
+ const int remd = (dx % dy) * 16 / dy;
+ const int quot = dx / dy;
index = gradient_to_angle_bin[sn][AOMMIN(quot, 6)][AOMMIN(remd, 15)];
}
hist[index] += temp;
@@ -3478,9 +3579,11 @@ static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
src += src_stride;
}
+ int i;
+ uint64_t hist_sum = 0;
for (i = 0; i < DIRECTIONAL_MODES; ++i) hist_sum += hist[i];
for (i = 0; i < INTRA_MODES; ++i) {
- if (i != DC_PRED && i != TM_PRED) {
+ if (av1_is_directional_mode(i, bsize)) {
const uint8_t angle_bin = mode_to_angle_bin[i];
uint64_t score = 2 * hist[angle_bin];
int weight = 2;
@@ -3509,6 +3612,7 @@ static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
MACROBLOCKD *const xd = &x->e_mbd;
MODE_INFO *const mic = xd->mi[0];
MB_MODE_INFO *const mbmi = &mic->mbmi;
+ assert(!is_inter_block(mbmi));
MB_MODE_INFO best_mbmi = *mbmi;
int64_t best_model_rd = INT64_MAX;
#if CONFIG_EXT_INTRA
@@ -3552,15 +3656,14 @@ static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
#if CONFIG_EXT_INTRA
mbmi->angle_delta[0] = 0;
- memset(directional_mode_skip_mask, 0,
- sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
#if CONFIG_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
- highbd_angle_estimation(src, src_stride, rows, cols,
+ highbd_angle_estimation(src, src_stride, rows, cols, bsize,
directional_mode_skip_mask);
else
#endif // CONFIG_HIGHBITDEPTH
- angle_estimation(src, src_stride, rows, cols, directional_mode_skip_mask);
+ angle_estimation(src, src_stride, rows, cols, bsize,
+ directional_mode_skip_mask);
#endif // CONFIG_EXT_INTRA
#if CONFIG_FILTER_INTRA
mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
@@ -3833,7 +3936,7 @@ void av1_tx_block_rd_b(const AV1_COMP *cpi, MACROBLOCK *x, TX_SIZE tx_size,
av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
coeff_ctx, AV1_XFORM_QUANT_FP);
- av1_optimize_b(cm, x, plane, block, tx_size, coeff_ctx);
+ av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
// TODO(any): Use av1_dist_block to compute distortion
#if CONFIG_HIGHBITDEPTH
@@ -3936,9 +4039,8 @@ static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
ENTROPY_CONTEXT *pta = ta + blk_col;
ENTROPY_CONTEXT *ptl = tl + blk_row;
int coeff_ctx, i;
- int ctx =
- txfm_partition_context(tx_above + (blk_col >> 1),
- tx_left + (blk_row >> 1), mbmi->sb_type, tx_size);
+ int ctx = txfm_partition_context(tx_above + blk_col, tx_left + blk_row,
+ mbmi->sb_type, tx_size);
int64_t sum_rd = INT64_MAX;
int tmp_eob = 0;
int zero_blk_rate;
@@ -4042,8 +4144,8 @@ static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
int idx, idy;
for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) pta[i] = !(tmp_eob == 0);
for (i = 0; i < tx_size_high_unit[tx_size]; ++i) ptl[i] = !(tmp_eob == 0);
- txfm_partition_update(tx_above + (blk_col >> 1), tx_left + (blk_row >> 1),
- tx_size, tx_size);
+ txfm_partition_update(tx_above + blk_col, tx_left + blk_row, tx_size,
+ tx_size);
inter_tx_size[0][0] = tx_size;
for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
@@ -4082,17 +4184,15 @@ static void inter_block_yrd(const AV1_COMP *cpi, MACROBLOCK *x,
int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
ENTROPY_CONTEXT ctxa[2 * MAX_MIB_SIZE];
ENTROPY_CONTEXT ctxl[2 * MAX_MIB_SIZE];
- TXFM_CONTEXT tx_above[MAX_MIB_SIZE];
- TXFM_CONTEXT tx_left[MAX_MIB_SIZE];
+ TXFM_CONTEXT tx_above[MAX_MIB_SIZE * 2];
+ TXFM_CONTEXT tx_left[MAX_MIB_SIZE * 2];
RD_STATS pn_rd_stats;
av1_init_rd_stats(&pn_rd_stats);
av1_get_entropy_contexts(bsize, 0, pd, ctxa, ctxl);
- memcpy(tx_above, xd->above_txfm_context,
- sizeof(TXFM_CONTEXT) * (mi_width >> 1));
- memcpy(tx_left, xd->left_txfm_context,
- sizeof(TXFM_CONTEXT) * (mi_height >> 1));
+ memcpy(tx_above, xd->above_txfm_context, sizeof(TXFM_CONTEXT) * mi_width);
+ memcpy(tx_left, xd->left_txfm_context, sizeof(TXFM_CONTEXT) * mi_height);
for (idy = 0; idy < mi_height; idy += bh) {
for (idx = 0; idx < mi_width; idx += bw) {
@@ -4137,8 +4237,8 @@ static int64_t select_tx_size_fix_type(const AV1_COMP *cpi, MACROBLOCK *x,
const int max_blocks_wide = max_block_wide(xd, bsize, 0);
mbmi->tx_type = tx_type;
- mbmi->min_tx_size = TX_SIZES_ALL;
inter_block_yrd(cpi, x, rd_stats, bsize, ref_best_rd, rd_stats_stack);
+ mbmi->min_tx_size = get_min_tx_size(mbmi->inter_tx_size[0][0]);
if (rd_stats->rate == INT_MAX) return INT64_MAX;
@@ -4350,7 +4450,8 @@ static int inter_block_uvrd(const AV1_COMP *cpi, MACROBLOCK *x,
#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
if (x->skip_chroma_rd) return is_cost_valid;
- bsize = AOMMAX(BLOCK_8X8, bsize);
+ bsize = scale_chroma_bsize(mbmi->sb_type, xd->plane[1].subsampling_x,
+ xd->plane[1].subsampling_y);
#endif // CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
#if CONFIG_EXT_TX && CONFIG_RECT_TX
@@ -4426,6 +4527,7 @@ static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
int *skippable) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+ assert(!is_inter_block(mbmi));
PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
const BLOCK_SIZE bsize = mbmi->sb_type;
int this_rate;
@@ -4460,6 +4562,13 @@ static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
}
#endif // CONFIG_HIGHBITDEPTH
+#if CONFIG_PALETTE_DELTA_ENCODING
+ const MODE_INFO *above_mi = xd->above_mi;
+ const MODE_INFO *left_mi = xd->left_mi;
+ uint16_t color_cache[2 * PALETTE_MAX_SIZE];
+ const int n_cache = av1_get_palette_cache(above_mi, left_mi, 1, color_cache);
+#endif // CONFIG_PALETTE_DELTA_ENCODING
+
colors = colors_u > colors_v ? colors_u : colors_v;
if (colors > 1 && colors <= 64) {
int r, c, n, i, j;
@@ -4524,6 +4633,7 @@ static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
}
av1_k_means(data, centroids, color_map, rows * cols, n, 2, max_itr);
#if CONFIG_PALETTE_DELTA_ENCODING
+ optimize_palette_colors(color_cache, n_cache, n, 2, centroids);
// Sort the U channel colors in ascending order.
for (i = 0; i < 2 * (n - 1); i += 2) {
int min_idx = i;
@@ -4563,7 +4673,11 @@ static void rd_pick_palette_intra_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
write_uniform_cost(n, color_map[0]) +
av1_cost_bit(
av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0], 1);
- this_rate += av1_palette_color_cost_uv(pmi, cpi->common.bit_depth);
+ this_rate += av1_palette_color_cost_uv(pmi,
+#if CONFIG_PALETTE_DELTA_ENCODING
+ color_cache, n_cache,
+#endif // CONFIG_PALETTE_DELTA_ENCODING
+ cpi->common.bit_depth);
for (i = 0; i < rows; ++i) {
for (j = (i == 0 ? 1 : 0); j < cols; ++j) {
int color_idx;
@@ -4660,6 +4774,7 @@ static int64_t pick_intra_angle_routine_sbuv(
int rate_overhead, int64_t best_rd_in, int *rate, RD_STATS *rd_stats,
int *best_angle_delta, int64_t *best_rd) {
MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
+ assert(!is_inter_block(mbmi));
int this_rate;
int64_t this_rd;
RD_STATS tokenonly_rd_stats;
@@ -4687,6 +4802,7 @@ static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
RD_STATS *rd_stats) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
+ assert(!is_inter_block(mbmi));
int i, angle_delta, best_angle_delta = 0;
int64_t this_rd, best_rd_in, rd_cost[2 * (MAX_ANGLE_DELTA + 2)];
@@ -4736,12 +4852,23 @@ static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
}
#endif // CONFIG_EXT_INTRA
+static void init_sbuv_mode(MB_MODE_INFO *const mbmi) {
+ mbmi->uv_mode = DC_PRED;
+#if CONFIG_PALETTE
+ mbmi->palette_mode_info.palette_size[1] = 0;
+#endif // CONFIG_PALETTE
+#if CONFIG_FILTER_INTRA
+ mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
+#endif // CONFIG_FILTER_INTRA
+}
+
static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
int *rate, int *rate_tokenonly,
int64_t *distortion, int *skippable,
BLOCK_SIZE bsize, TX_SIZE max_tx_size) {
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
+ assert(!is_inter_block(mbmi));
MB_MODE_INFO best_mbmi = *mbmi;
PREDICTION_MODE mode;
int64_t best_rd = INT64_MAX, this_rd;
@@ -4756,12 +4883,6 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
uint8_t *best_palette_color_map = NULL;
#endif // CONFIG_PALETTE
-#if CONFIG_FILTER_INTRA
- mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
-#endif // CONFIG_FILTER_INTRA
-#if CONFIG_PALETTE
- pmi->palette_size[1] = 0;
-#endif // CONFIG_PALETTE
for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
#if CONFIG_EXT_INTRA
const int is_directional_mode =
@@ -4858,12 +4979,12 @@ static void choose_intra_uv_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
// Use an estimated rd for uv_intra based on DC_PRED if the
// appropriate speed flag is set.
(void)ctx;
+ init_sbuv_mode(&x->e_mbd.mi[0]->mbmi);
#if CONFIG_CB4X4
#if CONFIG_CHROMA_2X2
rd_pick_intra_sbuv_mode(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
bsize, max_tx_size);
#else
- max_tx_size = AOMMAX(max_tx_size, TX_4X4);
if (x->skip_chroma_rd) {
*rate_uv = 0;
*rate_uv_tokenonly = 0;
@@ -4893,7 +5014,6 @@ static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
}
#endif
-#if CONFIG_REF_MV
int mode_cost = 0;
int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
@@ -4924,13 +5044,9 @@ static int cost_mv_ref(const AV1_COMP *const cpi, PREDICTION_MODE mode,
return mode_cost;
}
}
-#else
- assert(is_inter_mode(mode));
- return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
-#endif // CONFIG_REF_MV
}
-#if CONFIG_EXT_INTER
+#if CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
COMPOUND_TYPE comp_type) {
(void)bsize;
@@ -4945,304 +5061,7 @@ static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
default: assert(0); return 0;
}
}
-#endif // CONFIG_EXT_INTER
-
-static int set_and_cost_bmi_mvs(
- const AV1_COMP *const cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i,
- PREDICTION_MODE mode, int_mv this_mv[2],
- int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME],
- int_mv seg_mvs[TOTAL_REFS_PER_FRAME],
-#if CONFIG_EXT_INTER
- int_mv compound_seg_newmvs[2],
-#endif // CONFIG_EXT_INTER
- int_mv *best_ref_mv[2], const int *mvjcost, int *mvcost[2], int mi_row,
- int mi_col) {
- MODE_INFO *const mic = xd->mi[0];
- const MB_MODE_INFO *const mbmi = &mic->mbmi;
- const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
- int thismvcost = 0;
- int idx, idy;
- const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
- const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
- const int is_compound = has_second_ref(mbmi);
- int mode_ctx;
- (void)mi_row;
- (void)mi_col;
-
- switch (mode) {
- case NEWMV: this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
-#if CONFIG_EXT_INTER
- if (!cpi->common.allow_high_precision_mv)
- lower_mv_precision(&this_mv[0].as_mv, 0);
-#endif // CONFIG_EXT_INTER
-
-#if CONFIG_REF_MV
- for (idx = 0; idx < 1 + is_compound; ++idx) {
- this_mv[idx] = seg_mvs[mbmi->ref_frame[idx]];
- av1_set_mvcost(x, mbmi->ref_frame[idx], idx, mbmi->ref_mv_idx);
- thismvcost +=
- av1_mv_bit_cost(&this_mv[idx].as_mv, &best_ref_mv[idx]->as_mv,
- x->nmvjointcost, x->mvcost, MV_COST_WEIGHT_SUB);
- }
- (void)mvjcost;
- (void)mvcost;
-#else
- thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
- mvjcost, mvcost, MV_COST_WEIGHT_SUB);
-#if !CONFIG_EXT_INTER
- if (is_compound) {
- this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
- thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
- mvjcost, mvcost, MV_COST_WEIGHT_SUB);
- }
-#endif // !CONFIG_EXT_INTER
-#endif // CONFIG_REF_MV
- break;
- case NEARMV:
- case NEARESTMV:
- this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
- if (is_compound)
- this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
- break;
- case ZEROMV: {
- int ref;
- for (ref = 0; ref < 1 + is_compound; ++ref) {
-#if CONFIG_GLOBAL_MOTION
- this_mv[ref].as_int =
- gm_get_motion_vector(
- &cpi->common.global_motion[mbmi->ref_frame[ref]],
- cpi->common.allow_high_precision_mv, mbmi->sb_type, mi_col,
- mi_row, i)
- .as_int;
-#else
- this_mv[ref].as_int = 0;
-#endif // CONFIG_GLOBAL_MOTION
- }
- break;
- }
-#if CONFIG_EXT_INTER
- case NEW_NEWMV:
- if (compound_seg_newmvs[0].as_int == INVALID_MV ||
- compound_seg_newmvs[1].as_int == INVALID_MV) {
- this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
- this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
- } else {
- this_mv[0].as_int = compound_seg_newmvs[0].as_int;
- this_mv[1].as_int = compound_seg_newmvs[1].as_int;
- }
- if (!cpi->common.allow_high_precision_mv)
- lower_mv_precision(&this_mv[0].as_mv, 0);
- if (!cpi->common.allow_high_precision_mv)
- lower_mv_precision(&this_mv[1].as_mv, 0);
-#if CONFIG_REF_MV
- av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
-#endif
- thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
- mvjcost, mvcost, MV_COST_WEIGHT_SUB);
-#if CONFIG_REF_MV
- av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
-#endif
- thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
- mvjcost, mvcost, MV_COST_WEIGHT_SUB);
- break;
- case NEW_NEARMV:
- case NEW_NEARESTMV:
- this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
- if (!cpi->common.allow_high_precision_mv)
- lower_mv_precision(&this_mv[0].as_mv, 0);
-#if CONFIG_REF_MV
- av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
-#endif
- thismvcost += av1_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
- mvjcost, mvcost, MV_COST_WEIGHT_SUB);
- this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
- break;
- case NEAR_NEWMV:
- case NEAREST_NEWMV:
- this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
- this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
- if (!cpi->common.allow_high_precision_mv)
- lower_mv_precision(&this_mv[1].as_mv, 0);
-#if CONFIG_REF_MV
- av1_set_mvcost(x, mbmi->ref_frame[1], 1, mbmi->ref_mv_idx);
-#endif
- thismvcost += av1_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
- mvjcost, mvcost, MV_COST_WEIGHT_SUB);
- break;
- case NEAREST_NEARMV:
- case NEAR_NEARESTMV:
- case NEAREST_NEARESTMV:
- case NEAR_NEARMV:
- this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
- this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
- break;
- case ZERO_ZEROMV:
-#if CONFIG_GLOBAL_MOTION
- this_mv[0].as_int =
- gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
- cpi->common.allow_high_precision_mv,
- mbmi->sb_type, mi_col, mi_row, i)
- .as_int;
- this_mv[1].as_int =
- gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
- cpi->common.allow_high_precision_mv,
- mbmi->sb_type, mi_col, mi_row, i)
- .as_int;
-#else
- this_mv[0].as_int = 0;
- this_mv[1].as_int = 0;
-#endif // CONFIG_GLOBAL_MOTION
- break;
-#endif // CONFIG_EXT_INTER
- default: break;
- }
-
- mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
- if (is_compound) mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
-
- mic->bmi[i].as_mode = mode;
-
-#if CONFIG_REF_MV
- if (mode == NEWMV) {
- mic->bmi[i].pred_mv[0].as_int =
- mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int;
- if (is_compound)
- mic->bmi[i].pred_mv[1].as_int =
- mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int;
- } else {
- mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int;
- if (is_compound) mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int;
- }
-#endif // CONFIG_REF_MV
-
- for (idy = 0; idy < num_4x4_blocks_high; ++idy)
- for (idx = 0; idx < num_4x4_blocks_wide; ++idx)
- memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
-
-#if CONFIG_REF_MV
-#if CONFIG_EXT_INTER
- if (is_compound)
- mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
- else
-#endif // CONFIG_EXT_INTER
- mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
- mbmi->ref_frame, mbmi->sb_type, i);
-#else // CONFIG_REF_MV
- mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
-#endif // CONFIG_REF_MV
- return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
-}
-
-static int64_t encode_inter_mb_segment_sub8x8(
- const AV1_COMP *const cpi, MACROBLOCK *x, int64_t best_yrd, int i,
- int *labelyrate, int64_t *distortion, int64_t *sse, ENTROPY_CONTEXT *ta,
- ENTROPY_CONTEXT *tl, int ir, int ic, int mi_row, int mi_col) {
- const AV1_COMMON *const cm = &cpi->common;
- MACROBLOCKD *xd = &x->e_mbd;
- struct macroblockd_plane *const pd = &xd->plane[0];
- struct macroblock_plane *const p = &x->plane[0];
- MODE_INFO *const mi = xd->mi[0];
- const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
- const int txb_width = max_block_wide(xd, plane_bsize, 0);
- const int txb_height = max_block_high(xd, plane_bsize, 0);
- const int width = block_size_wide[plane_bsize];
- const int height = block_size_high[plane_bsize];
- int idx, idy;
- const uint8_t *const src =
- &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
- uint8_t *const dst =
- &pd->dst.buf[av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride)];
- int64_t thisdistortion = 0, thissse = 0;
- int thisrate = 0;
- TX_SIZE tx_size = mi->mbmi.tx_size;
- TX_TYPE tx_type = get_tx_type(PLANE_TYPE_Y, xd, i, tx_size);
- const int num_4x4_w = tx_size_wide_unit[tx_size];
- const int num_4x4_h = tx_size_high_unit[tx_size];
-#if !CONFIG_PVQ
- const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, 1);
-#else
- (void)cpi;
- (void)ta;
- (void)tl;
- (void)tx_type;
-#endif // !CONFIG_PVQ
-
-#if CONFIG_EXT_TX && CONFIG_RECT_TX
- assert(IMPLIES(xd->lossless[mi->mbmi.segment_id], tx_size == TX_4X4));
- assert(IMPLIES(!xd->lossless[mi->mbmi.segment_id],
- tx_size == max_txsize_rect_lookup[mi->mbmi.sb_type]));
-#else
- assert(tx_size == TX_4X4);
-#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
-
- assert(tx_type == DCT_DCT);
-
- av1_build_inter_predictor_sub8x8(xd, 0, i, ir, ic, mi_row, mi_col);
-
-#if CONFIG_HIGHBITDEPTH
- if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
- aom_highbd_subtract_block(
- height, width, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
- 8, src, p->src.stride, dst, pd->dst.stride, xd->bd);
- } else {
- aom_subtract_block(height, width,
- av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
- 8, src, p->src.stride, dst, pd->dst.stride);
- }
-#else
- aom_subtract_block(height, width,
- av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
- 8, src, p->src.stride, dst, pd->dst.stride);
-#endif // CONFIG_HIGHBITDEPTH
-
- for (idy = 0; idy < txb_height; idy += num_4x4_h) {
- for (idx = 0; idx < txb_width; idx += num_4x4_w) {
- int64_t dist, ssz, rd, rd1, rd2;
- int coeff_ctx;
- const int k = i + (idy * 2 + idx);
- const int block = av1_raster_order_to_block_index(tx_size, k);
- assert(IMPLIES(tx_size == TX_4X8 || tx_size == TX_8X4,
- idx == 0 && idy == 0));
- coeff_ctx = combine_entropy_contexts(*(ta + (k & 1)), *(tl + (k >> 1)));
- av1_xform_quant(cm, x, 0, block, idy + (i >> 1), idx + (i & 0x01),
- BLOCK_8X8, tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
- if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
- av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
- av1_dist_block(cpi, x, 0, BLOCK_8X8, block, idy + (i >> 1),
- idx + (i & 0x1), tx_size, &dist, &ssz,
- OUTPUT_HAS_PREDICTED_PIXELS);
- thisdistortion += dist;
- thissse += ssz;
-#if !CONFIG_PVQ
- thisrate +=
- av1_cost_coeffs(cpi, x, 0, block, tx_size, scan_order, (ta + (k & 1)),
- (tl + (k >> 1)), cpi->sf.use_fast_coef_costing);
- *(ta + (k & 1)) = !(p->eobs[block] == 0);
- *(tl + (k >> 1)) = !(p->eobs[block] == 0);
-#else
- thisrate += x->rate;
-#endif // !CONFIG_PVQ
-#if CONFIG_EXT_TX
- if (tx_size == TX_8X4) {
- *(ta + (k & 1) + 1) = *(ta + (k & 1));
- }
- if (tx_size == TX_4X8) {
- *(tl + (k >> 1) + 1) = *(tl + (k >> 1));
- }
-#endif // CONFIG_EXT_TX
- rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion);
- rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse);
- rd = AOMMIN(rd1, rd2);
- if (rd >= best_yrd) return INT64_MAX;
- }
- }
-
- *distortion = thisdistortion;
- *labelyrate = thisrate;
- *sse = thissse;
-
- return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion);
-}
+#endif // CONFIG_EXT_INTER && (CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT)
typedef struct {
int eobs;
@@ -5252,20 +5071,18 @@ typedef struct {
int64_t bsse;
int64_t brdcost;
int_mv mvs[2];
-#if CONFIG_REF_MV
int_mv pred_mv[2];
-#endif // CONFIG_REF_MV
#if CONFIG_EXT_INTER
int_mv ref_mv[2];
#endif // CONFIG_EXT_INTER
-#if CONFIG_CB4X4
+#if CONFIG_CHROMA_2X2
ENTROPY_CONTEXT ta[4];
ENTROPY_CONTEXT tl[4];
#else
ENTROPY_CONTEXT ta[2];
ENTROPY_CONTEXT tl[2];
-#endif // CONFIG_CB4X4
+#endif // CONFIG_CHROMA_2X2
} SEG_RDSTAT;
typedef struct {
@@ -5293,37 +5110,13 @@ static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) {
(mv->col >> 3) > mv_limits->col_max;
}
-static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
- MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
- struct macroblock_plane *const p = &x->plane[0];
- struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
-
- p->src.buf =
- &p->src.buf[av1_raster_block_offset(BLOCK_8X8, i, p->src.stride)];
- assert(((intptr_t)pd->pre[0].buf & 0x7) == 0);
- pd->pre[0].buf =
- &pd->pre[0].buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[0].stride)];
- if (has_second_ref(mbmi))
- pd->pre[1].buf =
- &pd->pre[1]
- .buf[av1_raster_block_offset(BLOCK_8X8, i, pd->pre[1].stride)];
-}
-
-static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
- struct buf_2d orig_pre[2]) {
- MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
- x->plane[0].src = orig_src;
- x->e_mbd.plane[0].pre[0] = orig_pre[0];
- if (has_second_ref(mbmi)) x->e_mbd.plane[0].pre[1] = orig_pre[1];
-}
-
// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
// TODO(aconverse): Find out if this is still productive then clean up or remove
static int check_best_zero_mv(
const AV1_COMP *const cpi, const int16_t mode_context[TOTAL_REFS_PER_FRAME],
-#if CONFIG_REF_MV && CONFIG_EXT_INTER
+#if CONFIG_EXT_INTER
const int16_t compound_mode_context[TOTAL_REFS_PER_FRAME],
-#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
+#endif // CONFIG_EXT_INTER
int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME], int this_mode,
const MV_REFERENCE_FRAME ref_frames[2], const BLOCK_SIZE bsize, int block,
int mi_row, int mi_col) {
@@ -5355,21 +5148,12 @@ static int check_best_zero_mv(
frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
(ref_frames[1] <= INTRA_FRAME ||
frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int)) {
-#if CONFIG_REF_MV
int16_t rfc =
av1_mode_context_analyzer(mode_context, ref_frames, bsize, block);
-#else
- int16_t rfc = mode_context[ref_frames[0]];
-#endif // CONFIG_REF_MV
int c1 = cost_mv_ref(cpi, NEARMV, rfc);
int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
-#if !CONFIG_REF_MV
- (void)bsize;
- (void)block;
-#endif // !CONFIG_REF_MV
-
if (this_mode == NEARMV) {
if (c1 > c3) return 0;
} else if (this_mode == NEARESTMV) {
@@ -5390,40 +5174,25 @@ static int check_best_zero_mv(
}
}
#if CONFIG_EXT_INTER
- else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
- this_mode == NEAR_NEARESTMV || this_mode == NEAR_NEARMV ||
+ else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
this_mode == ZERO_ZEROMV) &&
frame_mv[this_mode][ref_frames[0]].as_int == zeromv[0].as_int &&
frame_mv[this_mode][ref_frames[1]].as_int == zeromv[1].as_int) {
-#if CONFIG_REF_MV
int16_t rfc = compound_mode_context[ref_frames[0]];
-#else
- int16_t rfc = mode_context[ref_frames[0]];
-#endif // CONFIG_REF_MV
- int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
- int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
int c5 = cost_mv_ref(cpi, NEAR_NEARMV, rfc);
- if (this_mode == NEAREST_NEARMV) {
- if (c1 > c3) return 0;
- } else if (this_mode == NEAREST_NEARESTMV) {
+ if (this_mode == NEAREST_NEARESTMV) {
if (c2 > c3) return 0;
- } else if (this_mode == NEAR_NEARESTMV) {
- if (c4 > c3) return 0;
} else if (this_mode == NEAR_NEARMV) {
if (c5 > c3) return 0;
} else {
assert(this_mode == ZERO_ZEROMV);
if ((c3 >= c2 && frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
- (c3 >= c1 && frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
- frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
(c3 >= c5 && frame_mv[NEAR_NEARMV][ref_frames[0]].as_int == 0 &&
- frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0) ||
- (c3 >= c4 && frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
- frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
+ frame_mv[NEAR_NEARMV][ref_frames[1]].as_int == 0))
return 0;
}
}
@@ -5435,7 +5204,8 @@ static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
BLOCK_SIZE bsize, int_mv *frame_mv, int mi_row,
int mi_col,
#if CONFIG_EXT_INTER
- int_mv *ref_mv_sub8x8[2],
+ int_mv *ref_mv_sub8x8[2], const uint8_t *mask,
+ int mask_stride,
#endif // CONFIG_EXT_INTER
int *rate_mv, const int block) {
const AV1_COMMON *const cm = &cpi->common;
@@ -5596,17 +5366,26 @@ static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
best_mv->col >>= 3;
best_mv->row >>= 3;
-#if CONFIG_REF_MV
av1_set_mvcost(x, refs[id], id, mbmi->ref_mv_idx);
-#endif // CONFIG_REF_MV
// Small-range full-pixel motion search.
bestsme =
av1_refining_search_8p_c(x, sadpb, search_range, &cpi->fn_ptr[bsize],
+#if CONFIG_EXT_INTER
+ mask, mask_stride, id,
+#endif
&ref_mv[id].as_mv, second_pred);
- if (bestsme < INT_MAX)
- bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
- second_pred, &cpi->fn_ptr[bsize], 1);
+ if (bestsme < INT_MAX) {
+#if CONFIG_EXT_INTER
+ if (mask)
+ bestsme = av1_get_mvpred_mask_var(x, best_mv, &ref_mv[id].as_mv,
+ second_pred, mask, mask_stride, id,
+ &cpi->fn_ptr[bsize], 1);
+ else
+#endif
+ bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
+ second_pred, &cpi->fn_ptr[bsize], 1);
+ }
x->mv_limits = tmp_mv_limits;
@@ -5639,7 +5418,11 @@ static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
x->errorperbit, &cpi->fn_ptr[bsize], 0,
cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
- &dis, &sse, second_pred, pw, ph, 1);
+ &dis, &sse, second_pred,
+#if CONFIG_EXT_INTER
+ mask, mask_stride, id,
+#endif
+ pw, ph, 1);
// Restore the reference frames.
pd->pre[0] = backup_pred;
@@ -5649,7 +5432,11 @@ static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
x, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
x->errorperbit, &cpi->fn_ptr[bsize], 0,
cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
- &dis, &sse, second_pred, pw, ph, 0);
+ &dis, &sse, second_pred,
+#if CONFIG_EXT_INTER
+ mask, mask_stride, id,
+#endif
+ pw, ph, 0);
}
}
@@ -5673,9 +5460,7 @@ static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
for (i = 0; i < MAX_MB_PLANE; i++)
xd->plane[i].pre[ref] = backup_yv12[ref][i];
}
-#if CONFIG_REF_MV
av1_set_mvcost(x, refs[ref], ref, mbmi->ref_mv_idx);
-#endif // CONFIG_REF_MV
#if CONFIG_EXT_INTER && !CONFIG_CB4X4
if (bsize >= BLOCK_8X8)
#endif // CONFIG_EXT_INTER && !CONFIG_CB4X4
@@ -5691,947 +5476,6 @@ static void joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x,
}
}
-#if CONFIG_REF_MV && !CONFIG_EXT_INTER
-static void update_mv_search_and_seg_mvs(
- int *const run_mv_search, int_mv *const seg_mvs, int has_second_rf,
- const MV_REFERENCE_FRAME *const ref_frame,
- const SEG_RDSTAT *const ref_rdstat, int_mv *const bsi_ref_mv[2]) {
- if (has_second_rf) {
- if (seg_mvs[ref_frame[0]].as_int == ref_rdstat->mvs[0].as_int &&
- ref_rdstat->mvs[0].as_int != INVALID_MV)
- if (bsi_ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int)
- --*run_mv_search;
-
- if (seg_mvs[ref_frame[1]].as_int == ref_rdstat->mvs[1].as_int &&
- ref_rdstat->mvs[1].as_int != INVALID_MV)
- if (bsi_ref_mv[1]->as_int == ref_rdstat->pred_mv[1].as_int)
- --*run_mv_search;
- } else {
- if (bsi_ref_mv[0]->as_int == ref_rdstat->pred_mv[0].as_int &&
- ref_rdstat->mvs[0].as_int != INVALID_MV) {
- *run_mv_search = 0;
- seg_mvs[ref_frame[0]].as_int = ref_rdstat->mvs[0].as_int;
- }
- }
-}
-#endif // CONFIG_REF_MV && !CONFIG_EXT_INTER
-
-static int64_t rd_pick_inter_best_sub8x8_mode(
- const AV1_COMP *const cpi, MACROBLOCK *x, int_mv *best_ref_mv,
- int_mv *second_best_ref_mv, int64_t best_rd, int *returntotrate,
- int *returnyrate, int64_t *returndistortion, int *skippable, int64_t *psse,
- int mvthresh, int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME],
-#if CONFIG_EXT_INTER
- int_mv compound_seg_newmvs[4][2],
-#endif // CONFIG_EXT_INTER
- BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) {
- BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
-#if CONFIG_REF_MV
- int_mv tmp_ref_mv[2];
-#endif // CONFIG_REF_MV
- MACROBLOCKD *xd = &x->e_mbd;
- MODE_INFO *mi = xd->mi[0];
- MB_MODE_INFO *mbmi = &mi->mbmi;
- int mode_idx;
- int k, br = 0, idx, idy;
- int64_t bd = 0, block_sse = 0;
- PREDICTION_MODE this_mode;
- const AV1_COMMON *cm = &cpi->common;
- struct macroblock_plane *const p = &x->plane[0];
- struct macroblockd_plane *const pd = &xd->plane[0];
- const int label_count = 4;
- int64_t this_segment_rd = 0;
- int label_mv_thresh;
- int segmentyrate = 0;
- const BLOCK_SIZE bsize = mbmi->sb_type;
- const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
- const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
-#if CONFIG_CB4X4
- ENTROPY_CONTEXT t_above[4], t_left[4];
-#else
- ENTROPY_CONTEXT t_above[2], t_left[2];
-#endif // CONFIG_CB4X4
- int subpelmv = 1, have_ref = 0;
- const int has_second_rf = has_second_ref(mbmi);
- const int inter_mode_mask = cpi->sf.inter_mode_mask[bsize];
- MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
-#if CONFIG_PVQ
- od_rollback_buffer pre_buf;
-
- od_encode_checkpoint(&x->daala_enc, &pre_buf);
-#endif // CONFIG_PVQ
-#if CONFIG_EXT_TX && CONFIG_RECT_TX
- mbmi->tx_size =
- xd->lossless[mbmi->segment_id] ? TX_4X4 : max_txsize_rect_lookup[bsize];
-#else
- mbmi->tx_size = TX_4X4;
-#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
-
- av1_zero(*bsi);
-
- bsi->segment_rd = best_rd;
- bsi->ref_mv[0] = best_ref_mv;
- bsi->ref_mv[1] = second_best_ref_mv;
- bsi->mvp.as_int = best_ref_mv->as_int;
- bsi->mvthresh = mvthresh;
-
- for (idx = 0; idx < 4; ++idx) bsi->modes[idx] = ZEROMV;
-
-#if CONFIG_REF_MV
- for (idx = 0; idx < 4; ++idx) {
- for (k = NEARESTMV; k <= NEWMV; ++k) {
- bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV;
- bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV;
-
- bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV;
- bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV;
- }
- }
-#endif // CONFIG_REF_MV
-
- memcpy(t_above, pd->above_context, sizeof(t_above));
- memcpy(t_left, pd->left_context, sizeof(t_left));
-
- // 64 makes this threshold really big effectively
- // making it so that we very rarely check mvs on
- // segments. setting this to 1 would make mv thresh
- // roughly equal to what it is for macroblocks
- label_mv_thresh = 1 * bsi->mvthresh / label_count;
-
- // Segmentation method overheads
- for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
- for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
- // TODO(jingning,rbultje): rewrite the rate-distortion optimization
- // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
- int_mv mode_mv[MB_MODE_COUNT][2];
- int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
- PREDICTION_MODE mode_selected = ZEROMV;
- int64_t new_best_rd = INT64_MAX;
- const int index = idy * 2 + idx;
- int ref;
-#if CONFIG_REF_MV
- CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE];
- uint8_t ref_mv_count[2];
-#endif // CONFIG_REF_MV
-#if CONFIG_EXT_INTER
- int_mv ref_mvs_sub8x8[2][2];
-#endif // CONFIG_EXT_INTER
-#if CONFIG_PVQ
- od_rollback_buffer idx_buf, post_buf;
- od_encode_checkpoint(&x->daala_enc, &idx_buf);
- od_encode_checkpoint(&x->daala_enc, &post_buf);
-#endif // CONFIG_PVQ
-
- for (ref = 0; ref < 1 + has_second_rf; ++ref) {
- const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
-#if CONFIG_EXT_INTER
- int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
- av1_update_mv_context(cm, xd, mi, frame, mv_ref_list, index, mi_row,
- mi_col, NULL);
-#endif // CONFIG_EXT_INTER
-#if CONFIG_GLOBAL_MOTION
- frame_mv[ZEROMV][frame].as_int =
- gm_get_motion_vector(&cm->global_motion[frame],
- cm->allow_high_precision_mv, mbmi->sb_type,
- mi_col, mi_row, index)
- .as_int;
-#else // CONFIG_GLOBAL_MOTION
- frame_mv[ZEROMV][frame].as_int = 0;
-#endif // CONFIG_GLOBAL_MOTION
- av1_append_sub8x8_mvs_for_idx(cm, xd, index, ref, mi_row, mi_col,
-#if CONFIG_REF_MV
- ref_mv_stack[ref], &ref_mv_count[ref],
-#endif // CONFIG_REF_MV
-#if CONFIG_EXT_INTER
- mv_ref_list,
-#endif // CONFIG_EXT_INTER
- &frame_mv[NEARESTMV][frame],
- &frame_mv[NEARMV][frame]);
-
-#if CONFIG_REF_MV
- tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]];
- lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv);
- bsi->ref_mv[ref] = &tmp_ref_mv[ref];
- mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref];
-#endif // CONFIG_REF_MV
-
-#if CONFIG_EXT_INTER
- mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
- mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
- av1_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
- &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
-
- if (has_second_rf) {
-#if CONFIG_GLOBAL_MOTION
- frame_mv[ZERO_ZEROMV][frame].as_int =
- gm_get_motion_vector(&cm->global_motion[frame],
- cm->allow_high_precision_mv, mbmi->sb_type,
- mi_col, mi_row, index)
- .as_int;
-#else
- frame_mv[ZERO_ZEROMV][frame].as_int = 0;
-#endif // CONFIG_GLOBAL_MOTION
- frame_mv[NEAREST_NEARESTMV][frame].as_int =
- frame_mv[NEARESTMV][frame].as_int;
-
- if (ref == 0) {
- frame_mv[NEAREST_NEARMV][frame].as_int =
- frame_mv[NEARESTMV][frame].as_int;
- frame_mv[NEAR_NEARESTMV][frame].as_int =
- frame_mv[NEARMV][frame].as_int;
- frame_mv[NEAREST_NEWMV][frame].as_int =
- frame_mv[NEARESTMV][frame].as_int;
- frame_mv[NEAR_NEWMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
- frame_mv[NEAR_NEARMV][frame].as_int =
- frame_mv[NEARMV][frame].as_int;
- } else if (ref == 1) {
- frame_mv[NEAREST_NEARMV][frame].as_int =
- frame_mv[NEARMV][frame].as_int;
- frame_mv[NEAR_NEARESTMV][frame].as_int =
- frame_mv[NEARESTMV][frame].as_int;
- frame_mv[NEW_NEARESTMV][frame].as_int =
- frame_mv[NEARESTMV][frame].as_int;
- frame_mv[NEW_NEARMV][frame].as_int = frame_mv[NEARMV][frame].as_int;
- frame_mv[NEAR_NEARMV][frame].as_int =
- frame_mv[NEARMV][frame].as_int;
- }
- }
-#endif // CONFIG_EXT_INTER
- }
-
-// search for the best motion vector on this segment
-#if CONFIG_EXT_INTER
- for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
- this_mode <= (has_second_rf ? NEW_NEWMV : NEWMV); ++this_mode)
-#else
- for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode)
-#endif // CONFIG_EXT_INTER
- {
- const struct buf_2d orig_src = x->plane[0].src;
- struct buf_2d orig_pre[2];
- // This flag controls if the motion estimation will kick off. When it
- // is set to a non-zero value, the encoder will force motion estimation.
- int run_mv_search = 0;
-
- mode_idx = INTER_OFFSET(this_mode);
-#if CONFIG_EXT_INTER
- for (ref = 0; ref < 1 + has_second_rf; ++ref)
- bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[0][ref].as_int;
-#endif // CONFIG_EXT_INTER
- bsi->rdstat[index][mode_idx].brdcost = INT64_MAX;
- if (!(inter_mode_mask & (1 << this_mode))) continue;
-
-#if CONFIG_REF_MV
- run_mv_search = 2;
-#if !CONFIG_EXT_INTER
- if (filter_idx > 0 && this_mode == NEWMV) {
- const BEST_SEG_INFO *ref_bsi = bsi_buf;
- const SEG_RDSTAT *ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
-
- update_mv_search_and_seg_mvs(&run_mv_search, seg_mvs[index],
- has_second_rf, mbmi->ref_frame,
- ref_rdstat, bsi->ref_mv);
-
- if (run_mv_search != 0 && filter_idx > 1) {
- ref_bsi = bsi_buf + 1;
- ref_rdstat = &ref_bsi->rdstat[index][mode_idx];
- run_mv_search = 2;
- update_mv_search_and_seg_mvs(&run_mv_search, seg_mvs[index],
- has_second_rf, mbmi->ref_frame,
- ref_rdstat, bsi->ref_mv);
- }
- }
-#endif // !CONFIG_EXT_INTER
-#endif // CONFIG_REF_MV
-
-#if CONFIG_GLOBAL_MOTION
- if (cm->global_motion[mbmi->ref_frame[0]].wmtype == IDENTITY &&
- (!has_second_rf ||
- cm->global_motion[mbmi->ref_frame[1]].wmtype == IDENTITY))
-#endif // CONFIG_GLOBAL_MOTION
-
- if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
-#if CONFIG_REF_MV && CONFIG_EXT_INTER
- mbmi_ext->compound_mode_context,
-#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
- frame_mv, this_mode, mbmi->ref_frame, bsize,
- index, mi_row, mi_col))
- continue;
-
- memcpy(orig_pre, pd->pre, sizeof(orig_pre));
- memcpy(bsi->rdstat[index][mode_idx].ta, t_above,
- sizeof(bsi->rdstat[index][mode_idx].ta));
- memcpy(bsi->rdstat[index][mode_idx].tl, t_left,
- sizeof(bsi->rdstat[index][mode_idx].tl));
-#if CONFIG_PVQ
- od_encode_rollback(&x->daala_enc, &idx_buf);
-#endif // CONFIG_PVQ
-
- // motion search for newmv (single predictor case only)
- if (!has_second_rf &&
-#if CONFIG_EXT_INTER
- have_newmv_in_inter_mode(this_mode) &&
- (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
-#else
- this_mode == NEWMV &&
- (seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV ||
- run_mv_search)
-#endif // CONFIG_EXT_INTER
- ) {
- int step_param = 0;
- int bestsme = INT_MAX;
- int sadpb = x->sadperbit4;
- MV mvp_full;
- int max_mv;
- int cost_list[5];
- MvLimits tmp_mv_limits = x->mv_limits;
-
- /* Is the best so far sufficiently good that we cant justify doing
- * and new motion search. */
- if (new_best_rd < label_mv_thresh) break;
-
-#if CONFIG_EXT_INTER
- bsi->mvp.as_int = bsi->ref_mv[0]->as_int;
-#else
-// use previous block's result as next block's MV predictor.
-#if !CONFIG_REF_MV
- if (index > 0) {
- bsi->mvp.as_int = mi->bmi[index - 1].as_mv[0].as_int;
- if (index == 2)
- bsi->mvp.as_int = mi->bmi[index - 2].as_mv[0].as_int;
- }
-#endif // !CONFIG_REF_MV
-#endif // CONFIG_EXT_INTER
- max_mv = (index == 0) ? (int)x->max_mv_context[mbmi->ref_frame[0]]
- : AOMMAX(abs(bsi->mvp.as_mv.row),
- abs(bsi->mvp.as_mv.col)) >>
- 3;
-
- if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
- // Take wtd average of the step_params based on the last frame's
- // max mv magnitude and the best ref mvs of the current block for
- // the given reference.
- step_param =
- (av1_init_search_range(max_mv) + cpi->mv_step_param) / 2;
- } else {
- step_param = cpi->mv_step_param;
- }
-
-#if CONFIG_REF_MV
- mvp_full.row = bsi->ref_mv[0]->as_mv.row >> 3;
- mvp_full.col = bsi->ref_mv[0]->as_mv.col >> 3;
-#else
- mvp_full.row = bsi->mvp.as_mv.row >> 3;
- mvp_full.col = bsi->mvp.as_mv.col >> 3;
-#endif // CONFIG_REF_MV
-
- if (cpi->sf.adaptive_motion_search) {
- mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
- mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
- step_param = AOMMAX(step_param, 8);
- }
-
- // adjust src pointer for this block
- mi_buf_shift(x, index);
-
- av1_set_mv_search_range(&x->mv_limits, &bsi->ref_mv[0]->as_mv);
-
- x->best_mv.as_int = x->second_best_mv.as_int = INVALID_MV;
-
-#if CONFIG_REF_MV
- av1_set_mvcost(x, mbmi->ref_frame[0], 0, mbmi->ref_mv_idx);
-#endif // CONFIG_REF_MV
- bestsme = av1_full_pixel_search(
- cpi, x, bsize, &mvp_full, step_param, sadpb,
- cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
- &bsi->ref_mv[0]->as_mv, INT_MAX, 1);
-
- x->mv_limits = tmp_mv_limits;
-
- if (bestsme < INT_MAX) {
- int distortion;
- if (cpi->sf.use_upsampled_references) {
- int best_mv_var;
- const int try_second =
- x->second_best_mv.as_int != INVALID_MV &&
- x->second_best_mv.as_int != x->best_mv.as_int;
- const int pw = block_size_wide[bsize];
- const int ph = block_size_high[bsize];
- // Use up-sampled reference frames.
- struct buf_2d backup_pred = pd->pre[0];
- const YV12_BUFFER_CONFIG *upsampled_ref =
- get_upsampled_ref(cpi, mbmi->ref_frame[0]);
-
- // Set pred for Y plane
- setup_pred_plane(
- &pd->pre[0], bsize, upsampled_ref->y_buffer,
- upsampled_ref->y_crop_width, upsampled_ref->y_crop_height,
- upsampled_ref->y_stride, (mi_row << 3), (mi_col << 3), NULL,
- pd->subsampling_x, pd->subsampling_y);
-
- // adjust pred pointer for this block
- pd->pre[0].buf =
- &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, index,
- pd->pre[0].stride))
- << 3];
-
- best_mv_var = cpi->find_fractional_mv_step(
- x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
- x->errorperbit, &cpi->fn_ptr[bsize],
- cpi->sf.mv.subpel_force_stop,
- cpi->sf.mv.subpel_iters_per_step,
- cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
- &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, pw, ph,
- 1);
-
- if (try_second) {
- int this_var;
- MV best_mv = x->best_mv.as_mv;
- const MV ref_mv = bsi->ref_mv[0]->as_mv;
- const int minc =
- AOMMAX(x->mv_limits.col_min * 8, ref_mv.col - MV_MAX);
- const int maxc =
- AOMMIN(x->mv_limits.col_max * 8, ref_mv.col + MV_MAX);
- const int minr =
- AOMMAX(x->mv_limits.row_min * 8, ref_mv.row - MV_MAX);
- const int maxr =
- AOMMIN(x->mv_limits.row_max * 8, ref_mv.row + MV_MAX);
-
- x->best_mv = x->second_best_mv;
- if (x->best_mv.as_mv.row * 8 <= maxr &&
- x->best_mv.as_mv.row * 8 >= minr &&
- x->best_mv.as_mv.col * 8 <= maxc &&
- x->best_mv.as_mv.col * 8 >= minc) {
- this_var = cpi->find_fractional_mv_step(
- x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
- x->errorperbit, &cpi->fn_ptr[bsize],
- cpi->sf.mv.subpel_force_stop,
- cpi->sf.mv.subpel_iters_per_step,
- cond_cost_list(cpi, cost_list), x->nmvjointcost,
- x->mvcost, &distortion, &x->pred_sse[mbmi->ref_frame[0]],
- NULL, pw, ph, 1);
- if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
- x->best_mv.as_mv = best_mv;
- }
- }
-
- // Restore the reference frames.
- pd->pre[0] = backup_pred;
- } else {
- cpi->find_fractional_mv_step(
- x, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
- x->errorperbit, &cpi->fn_ptr[bsize],
- cpi->sf.mv.subpel_force_stop,
- cpi->sf.mv.subpel_iters_per_step,
- cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
- &distortion, &x->pred_sse[mbmi->ref_frame[0]], NULL, 0, 0, 0);
- }
-
-// save motion search result for use in compound prediction
-#if CONFIG_EXT_INTER
- seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
-#else
- seg_mvs[index][mbmi->ref_frame[0]].as_mv = x->best_mv.as_mv;
-#endif // CONFIG_EXT_INTER
- }
-
- if (cpi->sf.adaptive_motion_search)
- x->pred_mv[mbmi->ref_frame[0]] = x->best_mv.as_mv;
-
-#if CONFIG_EXT_INTER
- mode_mv[this_mode][0] = x->best_mv;
-#else
- mode_mv[NEWMV][0] = x->best_mv;
-#endif // CONFIG_EXT_INTER
-
- // restore src pointers
- mi_buf_restore(x, orig_src, orig_pre);
- }
-
- if (has_second_rf) {
-#if CONFIG_EXT_INTER
- if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
- seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
-#else
- if (seg_mvs[index][mbmi->ref_frame[1]].as_int == INVALID_MV ||
- seg_mvs[index][mbmi->ref_frame[0]].as_int == INVALID_MV)
-#endif // CONFIG_EXT_INTER
- continue;
- }
-
-#if CONFIG_DUAL_FILTER
- (void)run_mv_search;
-#endif // CONFIG_DUAL_FILTER
-
- if (has_second_rf &&
-#if CONFIG_EXT_INTER
- this_mode == NEW_NEWMV &&
-#else
- this_mode == NEWMV &&
-#endif // CONFIG_EXT_INTER
-#if CONFIG_DUAL_FILTER
- (mbmi->interp_filter[0] == EIGHTTAP_REGULAR || run_mv_search))
-#else
- (mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search))
-#endif // CONFIG_DUAL_FILTER
- {
- // adjust src pointers
- mi_buf_shift(x, index);
- if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
- int rate_mv;
- frame_mv[this_mode][mbmi->ref_frame[0]].as_int =
- seg_mvs[index][mbmi->ref_frame[0]].as_int;
- frame_mv[this_mode][mbmi->ref_frame[1]].as_int =
- seg_mvs[index][mbmi->ref_frame[1]].as_int;
- joint_motion_search(cpi, x, bsize, frame_mv[this_mode], mi_row,
- mi_col,
-#if CONFIG_EXT_INTER
- bsi->ref_mv,
-#endif // CONFIG_EXT_INTER
- &rate_mv, index);
-#if CONFIG_EXT_INTER
- compound_seg_newmvs[index][0].as_int =
- frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
- compound_seg_newmvs[index][1].as_int =
- frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
-#else
- seg_mvs[index][mbmi->ref_frame[0]].as_int =
- frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
- seg_mvs[index][mbmi->ref_frame[1]].as_int =
- frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
-#endif // CONFIG_EXT_INTER
- }
- // restore src pointers
- mi_buf_restore(x, orig_src, orig_pre);
- }
-
- bsi->rdstat[index][mode_idx].brate = set_and_cost_bmi_mvs(
- cpi, x, xd, index, this_mode, mode_mv[this_mode], frame_mv,
- seg_mvs[index],
-#if CONFIG_EXT_INTER
- compound_seg_newmvs[index],
-#endif // CONFIG_EXT_INTER
- bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row, mi_col);
-
- for (ref = 0; ref < 1 + has_second_rf; ++ref) {
- bsi->rdstat[index][mode_idx].mvs[ref].as_int =
- mode_mv[this_mode][ref].as_int;
- if (num_4x4_blocks_wide > 1)
- bsi->rdstat[index + 1][mode_idx].mvs[ref].as_int =
- mode_mv[this_mode][ref].as_int;
- if (num_4x4_blocks_high > 1)
- bsi->rdstat[index + 2][mode_idx].mvs[ref].as_int =
- mode_mv[this_mode][ref].as_int;
-#if CONFIG_REF_MV
- bsi->rdstat[index][mode_idx].pred_mv[ref].as_int =
- mi->bmi[index].pred_mv[ref].as_int;
- if (num_4x4_blocks_wide > 1)
- bsi->rdstat[index + 1][mode_idx].pred_mv[ref].as_int =
- mi->bmi[index].pred_mv[ref].as_int;
- if (num_4x4_blocks_high > 1)
- bsi->rdstat[index + 2][mode_idx].pred_mv[ref].as_int =
- mi->bmi[index].pred_mv[ref].as_int;
-#endif // CONFIG_REF_MV
-#if CONFIG_EXT_INTER
- bsi->rdstat[index][mode_idx].ref_mv[ref].as_int =
- bsi->ref_mv[ref]->as_int;
- if (num_4x4_blocks_wide > 1)
- bsi->rdstat[index + 1][mode_idx].ref_mv[ref].as_int =
- bsi->ref_mv[ref]->as_int;
- if (num_4x4_blocks_high > 1)
- bsi->rdstat[index + 2][mode_idx].ref_mv[ref].as_int =
- bsi->ref_mv[ref]->as_int;
-#endif // CONFIG_EXT_INTER
- }
-
- // Trap vectors that reach beyond the UMV borders
- if (mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][0].as_mv) ||
- (has_second_rf &&
- mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][1].as_mv)))
- continue;
-
- if (filter_idx > 0) {
- BEST_SEG_INFO *ref_bsi = bsi_buf;
- subpelmv = 0;
- have_ref = 1;
-
- for (ref = 0; ref < 1 + has_second_rf; ++ref) {
- subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
-#if CONFIG_EXT_INTER
- if (have_newmv_in_inter_mode(this_mode))
- have_ref &=
- ((mode_mv[this_mode][ref].as_int ==
- ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
- (bsi->ref_mv[ref]->as_int ==
- ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
- else
-#endif // CONFIG_EXT_INTER
- have_ref &= mode_mv[this_mode][ref].as_int ==
- ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
- }
-
- have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
-
- if (filter_idx > 1 && !subpelmv && !have_ref) {
- ref_bsi = bsi_buf + 1;
- have_ref = 1;
- for (ref = 0; ref < 1 + has_second_rf; ++ref)
-#if CONFIG_EXT_INTER
- if (have_newmv_in_inter_mode(this_mode))
- have_ref &=
- ((mode_mv[this_mode][ref].as_int ==
- ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int) &&
- (bsi->ref_mv[ref]->as_int ==
- ref_bsi->rdstat[index][mode_idx].ref_mv[ref].as_int));
- else
-#endif // CONFIG_EXT_INTER
- have_ref &= mode_mv[this_mode][ref].as_int ==
- ref_bsi->rdstat[index][mode_idx].mvs[ref].as_int;
-
- have_ref &= ref_bsi->rdstat[index][mode_idx].brate > 0;
- }
-
- if (!subpelmv && have_ref &&
- ref_bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
-#if CONFIG_REF_MV
- bsi->rdstat[index][mode_idx].byrate =
- ref_bsi->rdstat[index][mode_idx].byrate;
- bsi->rdstat[index][mode_idx].bdist =
- ref_bsi->rdstat[index][mode_idx].bdist;
- bsi->rdstat[index][mode_idx].bsse =
- ref_bsi->rdstat[index][mode_idx].bsse;
- bsi->rdstat[index][mode_idx].brate +=
- ref_bsi->rdstat[index][mode_idx].byrate;
- bsi->rdstat[index][mode_idx].eobs =
- ref_bsi->rdstat[index][mode_idx].eobs;
-
- bsi->rdstat[index][mode_idx].brdcost =
- RDCOST(x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate,
- bsi->rdstat[index][mode_idx].bdist);
-
- memcpy(bsi->rdstat[index][mode_idx].ta,
- ref_bsi->rdstat[index][mode_idx].ta,
- sizeof(bsi->rdstat[index][mode_idx].ta));
- memcpy(bsi->rdstat[index][mode_idx].tl,
- ref_bsi->rdstat[index][mode_idx].tl,
- sizeof(bsi->rdstat[index][mode_idx].tl));
-#else
- memcpy(&bsi->rdstat[index][mode_idx],
- &ref_bsi->rdstat[index][mode_idx], sizeof(SEG_RDSTAT));
-#endif // CONFIG_REF_MV
- if (num_4x4_blocks_wide > 1)
- bsi->rdstat[index + 1][mode_idx].eobs =
- ref_bsi->rdstat[index + 1][mode_idx].eobs;
- if (num_4x4_blocks_high > 1)
- bsi->rdstat[index + 2][mode_idx].eobs =
- ref_bsi->rdstat[index + 2][mode_idx].eobs;
-
- if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
-#if CONFIG_REF_MV
- // If the NEWMV mode is using the same motion vector as the
- // NEARESTMV mode, skip the rest rate-distortion calculations
- // and use the inferred motion vector modes.
- if (this_mode == NEWMV) {
- if (has_second_rf) {
- if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
- bsi->ref_mv[0]->as_int &&
- bsi->rdstat[index][mode_idx].mvs[1].as_int ==
- bsi->ref_mv[1]->as_int)
- continue;
- } else {
- if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
- bsi->ref_mv[0]->as_int)
- continue;
- }
- }
-#endif // CONFIG_REF_MV
- mode_selected = this_mode;
- new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
-#if CONFIG_PVQ
- od_encode_checkpoint(&x->daala_enc, &post_buf);
-#endif // CONFIG_PVQ
- }
- continue;
- }
- }
-
- bsi->rdstat[index][mode_idx].brdcost = encode_inter_mb_segment_sub8x8(
- cpi, x, bsi->segment_rd - this_segment_rd, index,
- &bsi->rdstat[index][mode_idx].byrate,
- &bsi->rdstat[index][mode_idx].bdist,
- &bsi->rdstat[index][mode_idx].bsse, bsi->rdstat[index][mode_idx].ta,
- bsi->rdstat[index][mode_idx].tl, idy, idx, mi_row, mi_col);
-
- if (bsi->rdstat[index][mode_idx].brdcost < INT64_MAX) {
- bsi->rdstat[index][mode_idx].brdcost += RDCOST(
- x->rdmult, x->rddiv, bsi->rdstat[index][mode_idx].brate, 0);
- bsi->rdstat[index][mode_idx].brate +=
- bsi->rdstat[index][mode_idx].byrate;
- bsi->rdstat[index][mode_idx].eobs = p->eobs[index];
- if (num_4x4_blocks_wide > 1)
- bsi->rdstat[index + 1][mode_idx].eobs = p->eobs[index + 1];
- if (num_4x4_blocks_high > 1)
- bsi->rdstat[index + 2][mode_idx].eobs = p->eobs[index + 2];
- }
-
- if (bsi->rdstat[index][mode_idx].brdcost < new_best_rd) {
-#if CONFIG_REF_MV
- // If the NEWMV mode is using the same motion vector as the
- // NEARESTMV mode, skip the rest rate-distortion calculations
- // and use the inferred motion vector modes.
- if (this_mode == NEWMV) {
- if (has_second_rf) {
- if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
- bsi->ref_mv[0]->as_int &&
- bsi->rdstat[index][mode_idx].mvs[1].as_int ==
- bsi->ref_mv[1]->as_int)
- continue;
- } else {
- if (bsi->rdstat[index][mode_idx].mvs[0].as_int ==
- bsi->ref_mv[0]->as_int)
- continue;
- }
- }
-#endif // CONFIG_REF_MV
- mode_selected = this_mode;
- new_best_rd = bsi->rdstat[index][mode_idx].brdcost;
-
-#if CONFIG_PVQ
- od_encode_checkpoint(&x->daala_enc, &post_buf);
-#endif // CONFIG_PVQ
- }
- } /*for each 4x4 mode*/
-
- if (new_best_rd == INT64_MAX) {
- int iy, midx;
- for (iy = index + 1; iy < 4; ++iy)
-#if CONFIG_EXT_INTER
- for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
-#else
- for (midx = 0; midx < INTER_MODES; ++midx)
-#endif // CONFIG_EXT_INTER
- bsi->rdstat[iy][midx].brdcost = INT64_MAX;
- bsi->segment_rd = INT64_MAX;
-#if CONFIG_PVQ
- od_encode_rollback(&x->daala_enc, &pre_buf);
-#endif // CONFIG_PVQ
- return INT64_MAX;
- }
-
- mode_idx = INTER_OFFSET(mode_selected);
- memcpy(t_above, bsi->rdstat[index][mode_idx].ta, sizeof(t_above));
- memcpy(t_left, bsi->rdstat[index][mode_idx].tl, sizeof(t_left));
-#if CONFIG_PVQ
- od_encode_rollback(&x->daala_enc, &post_buf);
-#endif // CONFIG_PVQ
-
-#if CONFIG_EXT_INTER
- bsi->ref_mv[0]->as_int = bsi->rdstat[index][mode_idx].ref_mv[0].as_int;
- if (has_second_rf)
- bsi->ref_mv[1]->as_int = bsi->rdstat[index][mode_idx].ref_mv[1].as_int;
-#endif // CONFIG_EXT_INTER
- set_and_cost_bmi_mvs(cpi, x, xd, index, mode_selected,
- mode_mv[mode_selected], frame_mv, seg_mvs[index],
-#if CONFIG_EXT_INTER
- compound_seg_newmvs[index],
-#endif // CONFIG_EXT_INTER
- bsi->ref_mv, x->nmvjointcost, x->mvcost, mi_row,
- mi_col);
-
- br += bsi->rdstat[index][mode_idx].brate;
- bd += bsi->rdstat[index][mode_idx].bdist;
- block_sse += bsi->rdstat[index][mode_idx].bsse;
- segmentyrate += bsi->rdstat[index][mode_idx].byrate;
- this_segment_rd += bsi->rdstat[index][mode_idx].brdcost;
-
- if (this_segment_rd > bsi->segment_rd) {
- int iy, midx;
- for (iy = index + 1; iy < 4; ++iy)
-#if CONFIG_EXT_INTER
- for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
-#else
- for (midx = 0; midx < INTER_MODES; ++midx)
-#endif // CONFIG_EXT_INTER
- bsi->rdstat[iy][midx].brdcost = INT64_MAX;
- bsi->segment_rd = INT64_MAX;
-#if CONFIG_PVQ
- od_encode_rollback(&x->daala_enc, &pre_buf);
-#endif // CONFIG_PVQ
- return INT64_MAX;
- }
- }
- } /* for each label */
-#if CONFIG_PVQ
- od_encode_rollback(&x->daala_enc, &pre_buf);
-#endif // CONFIG_PVQ
-
- bsi->r = br;
- bsi->d = bd;
- bsi->segment_yrate = segmentyrate;
- bsi->segment_rd = this_segment_rd;
- bsi->sse = block_sse;
-
- // update the coding decisions
- for (k = 0; k < 4; ++k) bsi->modes[k] = mi->bmi[k].as_mode;
-
-#if CONFIG_DAALA_DIST
- // Compute prediction (i.e. skip) and decoded distortion by daala-distortion.
- {
- const int src_stride = p->src.stride;
- const int dst_stride = pd->dst.stride;
- uint8_t *src = p->src.buf;
- uint8_t *dst = pd->dst.buf;
- const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
- const int use_activity_masking = 0;
- const int qm = OD_HVS_QM;
- const int bsw = block_size_wide[plane_bsize];
- const int bsh = block_size_high[plane_bsize];
- int64_t rd1, rd2;
- int64_t daala_sse, daala_dist;
- TX_SIZE tx_size = mbmi->tx_size;
-
-#if CONFIG_HIGHBITDEPTH
- uint8_t *recon_8x8;
- DECLARE_ALIGNED(16, uint16_t, recon16[8 * 8]);
-
- if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
- recon_8x8 = CONVERT_TO_BYTEPTR(recon16);
- else
- recon_8x8 = (uint8_t *)recon16;
-#else
- DECLARE_ALIGNED(16, uint8_t, recon_8x8[8 * 8]);
-#endif // CONFIG_HIGHBITDEPTH
-
-#if CONFIG_PVQ
- use_activity_masking = x->daala_enc.use_activity_masking;
-#endif // CONFIG_PVQ
-
- // For each of sub8x8 prediction block in a 8x8 block
- for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
- for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
- int i = idy * 2 + idx;
- const uint8_t *const src_sub8x8 =
- src + av1_raster_block_offset(BLOCK_8X8, i, p->src.stride);
- uint8_t *const dst_sub8x8 =
- dst + av1_raster_block_offset(BLOCK_8X8, i, pd->dst.stride);
- uint8_t *recon_sub8x8 = recon_8x8 + (idy * 8 + idx) * 4;
- const int txb_width = max_block_wide(xd, plane_bsize, 0);
- const int txb_height = max_block_high(xd, plane_bsize, 0);
- int idx_, idy_;
-
- av1_build_inter_predictor_sub8x8(xd, 0, i, idy, idx, mi_row, mi_col);
-#if CONFIG_HIGHBITDEPTH
- if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
- aom_highbd_subtract_block(
- height, width,
- av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
- src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride, xd->bd);
- } else {
- aom_subtract_block(
- height, width,
- av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8,
- src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride);
- }
-#else
- aom_subtract_block(
- bsh, bsw, av1_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff),
- 8, src_sub8x8, p->src.stride, dst_sub8x8, pd->dst.stride);
-#endif // CONFIG_HIGHBITDEPTH
-
-#if CONFIG_HIGHBITDEPTH
- if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
- aom_highbd_convolve_copy(dst_sub8x8, dst_stride, recon_sub8x8, 8,
- NULL, 0, NULL, 0, bsw, bsh, xd->bd);
- } else {
-#endif // CONFIG_HIGHBITDEPTH
- aom_convolve_copy(dst_sub8x8, dst_stride, recon_sub8x8, 8, NULL, 0,
- NULL, 0, bsw, bsh);
-#if CONFIG_HIGHBITDEPTH
- }
-#endif // CONFIG_HIGHBITDEPTH
-
- // To get decoded pixels, do 4x4 xform and quant for each 4x4 block
- // in a sub8x8 prediction block. In case remaining parts of
- // sub8x8 inter mode rdo assume pd->dst stores predicted pixels,
- // use local buffer to store decoded pixels.
- for (idy_ = 0; idy_ < txb_height; idy_++) {
- for (idx_ = 0; idx_ < txb_width; idx_++) {
- int coeff_ctx = 0;
- const tran_low_t *dqcoeff;
- uint16_t eob;
- const PLANE_TYPE plane_type = PLANE_TYPE_Y;
- uint8_t *recon_4x4 = recon_sub8x8 + (idy_ * 8 + idx_) * 4;
- const int block_raster_idx = (idy + idy_) * 2 + (idx + idx_);
- const int block =
- av1_raster_order_to_block_index(tx_size, block_raster_idx);
- TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
-
- dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
- av1_xform_quant(cm, x, 0, block, idy + idy_, idx + idx_, BLOCK_8X8,
- tx_size, coeff_ctx, AV1_XFORM_QUANT_FP);
- if (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0)
- av1_optimize_b(cm, x, 0, block, tx_size, coeff_ctx);
-
- eob = p->eobs[block];
- av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size,
- recon_4x4, 8, eob);
- }
- }
- }
- }
- // Compute daala-distortion for a 8x8 block
- daala_sse = av1_daala_dist(src, src_stride, pd->dst.buf, dst_stride, 8, 8,
- qm, use_activity_masking, x->qindex)
- << 4;
-
- daala_dist = av1_daala_dist(src, src_stride, recon_8x8, 8, 8, 8, qm,
- use_activity_masking, x->qindex)
- << 4;
-
- bsi->sse = daala_sse;
- bsi->d = daala_dist;
-
- rd1 = RDCOST(x->rdmult, x->rddiv, bsi->r, bsi->d);
- rd2 = RDCOST(x->rdmult, x->rddiv, 0, bsi->sse);
- bsi->segment_rd = AOMMIN(rd1, rd2);
- }
-#endif // CONFIG_DAALA_DIST
-
- if (bsi->segment_rd > best_rd) return INT64_MAX;
- /* set it to the best */
- for (idx = 0; idx < 4; idx++) {
- mode_idx = INTER_OFFSET(bsi->modes[idx]);
- mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int;
- if (has_second_ref(mbmi))
- mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int;
-#if CONFIG_REF_MV
- mi->bmi[idx].pred_mv[0] = bsi->rdstat[idx][mode_idx].pred_mv[0];
- if (has_second_ref(mbmi))
- mi->bmi[idx].pred_mv[1] = bsi->rdstat[idx][mode_idx].pred_mv[1];
-#endif // CONFIG_REF_MV
-#if CONFIG_EXT_INTER
- mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int;
- if (has_second_rf)
- mi->bmi[idx].ref_mv[1].as_int =
- bsi->rdstat[idx][mode_idx].ref_mv[1].as_int;
-#endif // CONFIG_EXT_INTER
- x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs;
- mi->bmi[idx].as_mode = bsi->modes[idx];
- }
-
- /*
- * used to set mbmi->mv.as_int
- */
- *returntotrate = bsi->r;
- *returndistortion = bsi->d;
- *returnyrate = bsi->segment_yrate;
- *skippable = av1_is_skippable_in_plane(x, BLOCK_8X8, 0);
- *psse = bsi->sse;
- mbmi->mode = bsi->modes[3];
-
- return bsi->segment_rd;
-}
-
static void estimate_ref_frame_costs(const AV1_COMMON *cm,
const MACROBLOCKD *xd, int segment_id,
unsigned int *ref_costs_single,
@@ -6808,15 +5652,13 @@ static void setup_buffer_inter(
av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
// Gets an initial list of candidate vectors from neighbours and orders them
- av1_find_mv_refs(
- cm, xd, mi, ref_frame,
-#if CONFIG_REF_MV
- &mbmi_ext->ref_mv_count[ref_frame], mbmi_ext->ref_mv_stack[ref_frame],
+ av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
+ mbmi_ext->ref_mv_stack[ref_frame],
#if CONFIG_EXT_INTER
- mbmi_ext->compound_mode_context,
+ mbmi_ext->compound_mode_context,
#endif // CONFIG_EXT_INTER
-#endif // CONFIG_REF_MV
- candidates, mi_row, mi_col, NULL, NULL, mbmi_ext->mode_context);
+ candidates, mi_row, mi_col, NULL, NULL,
+ mbmi_ext->mode_context);
// Candidate refinement carried out at encoder and decoder
av1_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,
@@ -6882,9 +5724,7 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
av1_set_mv_search_range(&x->mv_limits, &ref_mv);
-#if CONFIG_REF_MV
av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
-#endif // CONFIG_REF_MV
// Work out the size of the first step in the mv step search.
// 0 here is maximum length first step. 1 is AOMMAX >> 1 etc.
@@ -6996,8 +5836,11 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
&cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
- x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, pw, ph,
- 1);
+ x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
+#if CONFIG_EXT_INTER
+ NULL, 0, 0,
+#endif
+ pw, ph, 1);
if (try_second) {
const int minc =
@@ -7021,7 +5864,11 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
&cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
cpi->sf.mv.subpel_iters_per_step,
cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
- &dis, &x->pred_sse[ref], NULL, pw, ph, 1);
+ &dis, &x->pred_sse[ref], NULL,
+#if CONFIG_EXT_INTER
+ NULL, 0, 0,
+#endif
+ pw, ph, 1);
if (this_var < best_mv_var) best_mv = x->best_mv.as_mv;
x->best_mv.as_mv = best_mv;
}
@@ -7034,8 +5881,11 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
x, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
&cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
- x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0,
- 0);
+ x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL,
+#if CONFIG_EXT_INTER
+ NULL, 0, 0,
+#endif
+ 0, 0, 0);
}
#if CONFIG_MOTION_VAR
break;
@@ -7077,131 +5927,287 @@ static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
}
#if CONFIG_EXT_INTER
-#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
-static void do_masked_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
- const uint8_t *mask, int mask_stride,
- BLOCK_SIZE bsize, int mi_row, int mi_col,
- int_mv *tmp_mv, int *rate_mv, int ref_idx) {
+static void build_second_inter_pred(const AV1_COMP *cpi, MACROBLOCK *x,
+ BLOCK_SIZE bsize, const MV *other_mv,
+ int mi_row, int mi_col, const int block,
+ int ref_idx, uint8_t *second_pred) {
+ const AV1_COMMON *const cm = &cpi->common;
+ const int pw = block_size_wide[bsize];
+ const int ph = block_size_high[bsize];
MACROBLOCKD *xd = &x->e_mbd;
- const AV1_COMMON *cm = &cpi->common;
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
- struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
- int bestsme = INT_MAX;
- int step_param;
- int sadpb = x->sadperbit16;
- MV mvp_full;
- int ref = mbmi->ref_frame[ref_idx];
- MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
-
- MvLimits tmp_mv_limits = x->mv_limits;
-
- const YV12_BUFFER_CONFIG *scaled_ref_frame =
- av1_get_scaled_ref_frame(cpi, ref);
- int i;
+ const int other_ref = mbmi->ref_frame[!ref_idx];
+#if CONFIG_DUAL_FILTER
+ InterpFilter interp_filter[2] = {
+ (ref_idx == 0) ? mbmi->interp_filter[2] : mbmi->interp_filter[0],
+ (ref_idx == 0) ? mbmi->interp_filter[3] : mbmi->interp_filter[1]
+ };
+#else
+ const InterpFilter interp_filter = mbmi->interp_filter;
+#endif // CONFIG_DUAL_FILTER
+ struct scale_factors sf;
+#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
+ struct macroblockd_plane *const pd = &xd->plane[0];
+ // ic and ir are the 4x4 coordiantes of the sub8x8 at index "block"
+ const int ic = block & 1;
+ const int ir = (block - ic) >> 1;
+ const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
+ const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
+#if CONFIG_GLOBAL_MOTION
+ WarpedMotionParams *const wm = &xd->global_motion[other_ref];
+ int is_global = is_global_mv_block(xd->mi[0], block, wm->wmtype);
+#endif // CONFIG_GLOBAL_MOTION
+#else
+ (void)block;
+#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
- MV pred_mv[3];
- pred_mv[0] = x->mbmi_ext->ref_mvs[ref][0].as_mv;
- pred_mv[1] = x->mbmi_ext->ref_mvs[ref][1].as_mv;
- pred_mv[2] = x->pred_mv[ref];
+ // This function should only ever be called for compound modes
+ assert(has_second_ref(mbmi));
-#if CONFIG_REF_MV
- av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
-#endif // CONFIG_REF_MV
+ struct buf_2d backup_yv12[MAX_MB_PLANE];
+ const YV12_BUFFER_CONFIG *const scaled_ref_frame =
+ av1_get_scaled_ref_frame(cpi, other_ref);
if (scaled_ref_frame) {
+ int i;
// Swap out the reference frame for a version that's been scaled to
// match the resolution of the current frame, allowing the existing
// motion search code to be used without additional modifications.
for (i = 0; i < MAX_MB_PLANE; i++)
- backup_yv12[i] = xd->plane[i].pre[ref_idx];
-
- av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
+ backup_yv12[i] = xd->plane[i].pre[!ref_idx];
+ av1_setup_pre_planes(xd, !ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
}
- av1_set_mv_search_range(&x->mv_limits, &ref_mv);
+// Since we have scaled the reference frames to match the size of the current
+// frame we must use a unit scaling factor during mode selection.
+#if CONFIG_HIGHBITDEPTH
+ av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
+ cm->height, cm->use_highbitdepth);
+#else
+ av1_setup_scale_factors_for_frame(&sf, cm->width, cm->height, cm->width,
+ cm->height);
+#endif // CONFIG_HIGHBITDEPTH
- // Work out the size of the first step in the mv step search.
- // 0 here is maximum length first step. 1 is MAX >> 1 etc.
- if (cpi->sf.mv.auto_mv_step_size && cm->show_frame) {
- // Take wtd average of the step_params based on the last frame's
- // max mv magnitude and that based on the best ref mvs of the current
- // block for the given reference.
- step_param =
- (av1_init_search_range(x->max_mv_context[ref]) + cpi->mv_step_param) /
- 2;
+ struct buf_2d ref_yv12;
+
+ const int plane = 0;
+ ConvolveParams conv_params = get_conv_params(0, plane);
+#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
+ WarpTypesAllowed warp_types;
+#if CONFIG_GLOBAL_MOTION
+ warp_types.global_warp_allowed = is_global;
+#endif // CONFIG_GLOBAL_MOTION
+#if CONFIG_WARPED_MOTION
+ warp_types.local_warp_allowed = mbmi->motion_mode == WARPED_CAUSAL;
+#endif // CONFIG_WARPED_MOTION
+#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
+
+ // Initialized here because of compiler problem in Visual Studio.
+ ref_yv12 = xd->plane[plane].pre[!ref_idx];
+
+// Get the prediction block from the 'other' reference frame.
+#if CONFIG_HIGHBITDEPTH
+ if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
+ av1_highbd_build_inter_predictor(
+ ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
+ 0, interp_filter,
+#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
+ &warp_types, p_col, p_row,
+#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
+ plane, MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
} else {
- step_param = cpi->mv_step_param;
+#endif // CONFIG_HIGHBITDEPTH
+ av1_build_inter_predictor(
+ ref_yv12.buf, ref_yv12.stride, second_pred, pw, other_mv, &sf, pw, ph,
+ &conv_params, interp_filter,
+#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
+ &warp_types, p_col, p_row, plane, !ref_idx,
+#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
+ MV_PRECISION_Q3, mi_col * MI_SIZE, mi_row * MI_SIZE, xd);
+#if CONFIG_HIGHBITDEPTH
}
+#endif // CONFIG_HIGHBITDEPTH
- // TODO(debargha): is show_frame needed here?
- if (cpi->sf.adaptive_motion_search && bsize < cm->sb_size && cm->show_frame) {
- int boffset =
- 2 * (b_width_log2_lookup[cm->sb_size] -
- AOMMIN(b_height_log2_lookup[bsize], b_width_log2_lookup[bsize]));
- step_param = AOMMAX(step_param, boffset);
+ if (scaled_ref_frame) {
+ // Restore the prediction frame pointers to their unscaled versions.
+ int i;
+ for (i = 0; i < MAX_MB_PLANE; i++)
+ xd->plane[i].pre[!ref_idx] = backup_yv12[i];
}
+}
- if (cpi->sf.adaptive_motion_search) {
- int bwl = b_width_log2_lookup[bsize];
- int bhl = b_height_log2_lookup[bsize];
- int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
+// Search for the best mv for one component of a compound,
+// given that the other component is fixed.
+static void compound_single_motion_search(
+ const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, MV *this_mv,
+ int mi_row, int mi_col, const uint8_t *second_pred, const uint8_t *mask,
+ int mask_stride, int *rate_mv, const int block, int ref_idx) {
+ const int pw = block_size_wide[bsize];
+ const int ph = block_size_high[bsize];
+ MACROBLOCKD *xd = &x->e_mbd;
+ MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
+ const int ref = mbmi->ref_frame[ref_idx];
+ int_mv ref_mv = x->mbmi_ext->ref_mvs[ref][0];
+ struct macroblockd_plane *const pd = &xd->plane[0];
- if (tlevel < 5) step_param += 2;
+ struct buf_2d backup_yv12[MAX_MB_PLANE];
+ const YV12_BUFFER_CONFIG *const scaled_ref_frame =
+ av1_get_scaled_ref_frame(cpi, ref);
- // prev_mv_sad is not setup for dynamically scaled frames.
- if (cpi->oxcf.resize_mode != RESIZE_DYNAMIC) {
- for (i = LAST_FRAME; i <= ALTREF_FRAME && cm->show_frame; ++i) {
- if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
- x->pred_mv[ref].row = 0;
- x->pred_mv[ref].col = 0;
- tmp_mv->as_int = INVALID_MV;
+ // Check that this is either an interinter or an interintra block
+ assert(has_second_ref(mbmi) ||
+ (ref_idx == 0 && mbmi->ref_frame[1] == INTRA_FRAME));
- if (scaled_ref_frame) {
- int j;
- for (j = 0; j < MAX_MB_PLANE; ++j)
- xd->plane[j].pre[ref_idx] = backup_yv12[j];
- }
- return;
- }
- }
- }
+ if (scaled_ref_frame) {
+ int i;
+ // Swap out the reference frame for a version that's been scaled to
+ // match the resolution of the current frame, allowing the existing
+ // motion search code to be used without additional modifications.
+ for (i = 0; i < MAX_MB_PLANE; i++)
+ backup_yv12[i] = xd->plane[i].pre[ref_idx];
+ av1_setup_pre_planes(xd, ref_idx, scaled_ref_frame, mi_row, mi_col, NULL);
}
- mvp_full = pred_mv[x->mv_best_ref_index[ref]];
+ struct buf_2d orig_yv12;
+ int bestsme = INT_MAX;
+ int sadpb = x->sadperbit16;
+ MV *const best_mv = &x->best_mv.as_mv;
+ int search_range = 3;
+
+ MvLimits tmp_mv_limits = x->mv_limits;
- mvp_full.col >>= 3;
- mvp_full.row >>= 3;
+ // Initialized here because of compiler problem in Visual Studio.
+ if (ref_idx) {
+ orig_yv12 = pd->pre[0];
+ pd->pre[0] = pd->pre[ref_idx];
+ }
- bestsme = av1_masked_full_pixel_diamond(
- cpi, x, mask, mask_stride, &mvp_full, step_param, sadpb,
- MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
- &tmp_mv->as_mv, ref_idx);
+ // Do compound motion search on the current reference frame.
+ av1_set_mv_search_range(&x->mv_limits, &ref_mv.as_mv);
+
+ // Use the mv result from the single mode as mv predictor.
+ *best_mv = *this_mv;
+
+ best_mv->col >>= 3;
+ best_mv->row >>= 3;
+
+ av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
+
+ // Small-range full-pixel motion search.
+ bestsme = av1_refining_search_8p_c(x, sadpb, search_range,
+ &cpi->fn_ptr[bsize], mask, mask_stride,
+ ref_idx, &ref_mv.as_mv, second_pred);
+ if (bestsme < INT_MAX) {
+ if (mask)
+ bestsme =
+ av1_get_mvpred_mask_var(x, best_mv, &ref_mv.as_mv, second_pred, mask,
+ mask_stride, ref_idx, &cpi->fn_ptr[bsize], 1);
+ else
+ bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv.as_mv, second_pred,
+ &cpi->fn_ptr[bsize], 1);
+ }
x->mv_limits = tmp_mv_limits;
if (bestsme < INT_MAX) {
int dis; /* TODO: use dis in distortion calculation later. */
- av1_find_best_masked_sub_pixel_tree_up(
- cpi, x, mask, mask_stride, mi_row, mi_col, &tmp_mv->as_mv, &ref_mv,
- cm->allow_high_precision_mv, x->errorperbit, &cpi->fn_ptr[bsize],
- cpi->sf.mv.subpel_force_stop, cpi->sf.mv.subpel_iters_per_step,
- x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], ref_idx,
- cpi->sf.use_upsampled_references);
- }
- *rate_mv = av1_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
- x->mvcost, MV_COST_WEIGHT);
+ unsigned int sse;
+ if (cpi->sf.use_upsampled_references) {
+ // Use up-sampled reference frames.
+ struct buf_2d backup_pred = pd->pre[0];
+ const YV12_BUFFER_CONFIG *upsampled_ref = get_upsampled_ref(cpi, ref);
+
+ // Set pred for Y plane
+ setup_pred_plane(&pd->pre[0], bsize, upsampled_ref->y_buffer,
+ upsampled_ref->y_crop_width,
+ upsampled_ref->y_crop_height, upsampled_ref->y_stride,
+ (mi_row << 3), (mi_col << 3), NULL, pd->subsampling_x,
+ pd->subsampling_y);
+
+// If bsize < BLOCK_8X8, adjust pred pointer for this block
+#if !CONFIG_CB4X4
+ if (bsize < BLOCK_8X8)
+ pd->pre[0].buf =
+ &pd->pre[0].buf[(av1_raster_block_offset(BLOCK_8X8, block,
+ pd->pre[0].stride))
+ << 3];
+#endif // !CONFIG_CB4X4
+
+ bestsme = cpi->find_fractional_mv_step(
+ x, &ref_mv.as_mv, cpi->common.allow_high_precision_mv, x->errorperbit,
+ &cpi->fn_ptr[bsize], 0, cpi->sf.mv.subpel_iters_per_step, NULL,
+ x->nmvjointcost, x->mvcost, &dis, &sse, second_pred, mask,
+ mask_stride, ref_idx, pw, ph, 1);
+
+ // Restore the reference frames.
+ pd->pre[0] = backup_pred;
+ } else {
+ (void)block;
+ bestsme = cpi->find_fractional_mv_step(
+ x, &ref_mv.as_mv, cpi->common.allow_high_precision_mv, x->errorperbit,
+ &cpi->fn_ptr[bsize], 0, cpi->sf.mv.subpel_iters_per_step, NULL,
+ x->nmvjointcost, x->mvcost, &dis, &sse, second_pred, mask,
+ mask_stride, ref_idx, pw, ph, 0);
+ }
+ }
+
+ // Restore the pointer to the first (possibly scaled) prediction buffer.
+ if (ref_idx) pd->pre[0] = orig_yv12;
+
+ if (bestsme < INT_MAX) *this_mv = *best_mv;
- if (cpi->sf.adaptive_motion_search && cm->show_frame)
- x->pred_mv[ref] = tmp_mv->as_mv;
+ *rate_mv = 0;
if (scaled_ref_frame) {
+ // Restore the prediction frame pointers to their unscaled versions.
+ int i;
for (i = 0; i < MAX_MB_PLANE; i++)
xd->plane[i].pre[ref_idx] = backup_yv12[i];
}
+
+ av1_set_mvcost(x, ref, ref_idx, mbmi->ref_mv_idx);
+ *rate_mv += av1_mv_bit_cost(this_mv, &ref_mv.as_mv, x->nmvjointcost,
+ x->mvcost, MV_COST_WEIGHT);
}
+// Wrapper for compound_single_motion_search, for the common case
+// where the second prediction is also an inter mode.
+static void compound_single_motion_search_interinter(
+ const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int_mv *frame_mv,
+ int mi_row, int mi_col, const uint8_t *mask, int mask_stride, int *rate_mv,
+ const int block, int ref_idx) {
+ MACROBLOCKD *xd = &x->e_mbd;
+ MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
+
+ // This function should only ever be called for compound modes
+ assert(has_second_ref(mbmi));
+
+// Prediction buffer from second frame.
+#if CONFIG_HIGHBITDEPTH
+ DECLARE_ALIGNED(16, uint16_t, second_pred_alloc_16[MAX_SB_SQUARE]);
+ uint8_t *second_pred;
+ if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
+ second_pred = CONVERT_TO_BYTEPTR(second_pred_alloc_16);
+ else
+ second_pred = (uint8_t *)second_pred_alloc_16;
+#else
+ DECLARE_ALIGNED(16, uint8_t, second_pred[MAX_SB_SQUARE]);
+#endif // CONFIG_HIGHBITDEPTH
+
+ MV *this_mv = &frame_mv[mbmi->ref_frame[ref_idx]].as_mv;
+ const MV *other_mv = &frame_mv[mbmi->ref_frame[!ref_idx]].as_mv;
+
+ build_second_inter_pred(cpi, x, bsize, other_mv, mi_row, mi_col, block,
+ ref_idx, second_pred);
+
+ compound_single_motion_search(cpi, x, bsize, this_mv, mi_row, mi_col,
+ second_pred, mask, mask_stride, rate_mv, block,
+ ref_idx);
+}
+
+#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
static void do_masked_motion_search_indexed(
- const AV1_COMP *const cpi, MACROBLOCK *x,
+ const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE bsize,
int mi_row, int mi_col, int_mv *tmp_mv, int *rate_mv, int which) {
// NOTE: which values: 0 - 0 only, 1 - 1 only, 2 - both
@@ -7213,23 +6219,22 @@ static void do_masked_motion_search_indexed(
mask = av1_get_compound_type_mask(comp_data, sb_type);
- if (which == 0 || which == 2)
- do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
- &tmp_mv[0], &rate_mv[0], 0);
-
- if (which == 1 || which == 2) {
-// get the negative mask
-#if CONFIG_COMPOUND_SEGMENT
- uint8_t inv_mask_buf[2 * MAX_SB_SQUARE];
- const int h = block_size_high[bsize];
- mask = av1_get_compound_type_mask_inverse(
- comp_data, inv_mask_buf, h, mask_stride, mask_stride, sb_type);
-#else
- mask = av1_get_compound_type_mask_inverse(comp_data, sb_type);
-#endif // CONFIG_COMPOUND_SEGMENT
- do_masked_motion_search(cpi, x, mask, mask_stride, bsize, mi_row, mi_col,
- &tmp_mv[1], &rate_mv[1], 1);
- }
+ int_mv frame_mv[TOTAL_REFS_PER_FRAME];
+ MV_REFERENCE_FRAME rf[2] = { mbmi->ref_frame[0], mbmi->ref_frame[1] };
+ assert(bsize >= BLOCK_8X8 || CONFIG_CB4X4);
+
+ frame_mv[rf[0]].as_int = cur_mv[0].as_int;
+ frame_mv[rf[1]].as_int = cur_mv[1].as_int;
+ if (which == 0 || which == 1) {
+ compound_single_motion_search_interinter(cpi, x, bsize, frame_mv, mi_row,
+ mi_col, mask, mask_stride, rate_mv,
+ 0, which);
+ } else if (which == 2) {
+ joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, mask,
+ mask_stride, rate_mv, 0);
+ }
+ tmp_mv[0].as_int = frame_mv[rf[0]].as_int;
+ tmp_mv[1].as_int = frame_mv[rf[1]].as_int;
}
#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
#endif // CONFIG_EXT_INTER
@@ -7275,7 +6280,7 @@ static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
const int f_index = bsize - BLOCK_8X8;
const int bw = block_size_wide[bsize];
const int bh = block_size_high[bsize];
- uint32_t esq[2][4], var;
+ uint32_t esq[2][4];
int64_t tl, br;
#if CONFIG_HIGHBITDEPTH
@@ -7285,23 +6290,22 @@ static int estimate_wedge_sign(const AV1_COMP *cpi, const MACROBLOCK *x,
}
#endif // CONFIG_HIGHBITDEPTH
- var = cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
- var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2,
- stride0, &esq[0][1]);
- var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
- pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
- var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
- pred0 + bh / 2 * stride0 + bw / 2, stride0,
- &esq[0][3]);
- var = cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
- var = cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2,
- stride1, &esq[1][1]);
- var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
- pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
- var = cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
- pred1 + bh / 2 * stride1 + bw / 2, stride0,
- &esq[1][3]);
- (void)var;
+ cpi->fn_ptr[f_index].vf(src, src_stride, pred0, stride0, &esq[0][0]);
+ cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred0 + bw / 2, stride0,
+ &esq[0][1]);
+ cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
+ pred0 + bh / 2 * stride0, stride0, &esq[0][2]);
+ cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
+ pred0 + bh / 2 * stride0 + bw / 2, stride0,
+ &esq[0][3]);
+ cpi->fn_ptr[f_index].vf(src, src_stride, pred1, stride1, &esq[1][0]);
+ cpi->fn_ptr[f_index].vf(src + bw / 2, src_stride, pred1 + bw / 2, stride1,
+ &esq[1][1]);
+ cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride, src_stride,
+ pred1 + bh / 2 * stride1, stride0, &esq[1][2]);
+ cpi->fn_ptr[f_index].vf(src + bh / 2 * src_stride + bw / 2, src_stride,
+ pred1 + bh / 2 * stride1 + bw / 2, stride0,
+ &esq[1][3]);
tl = (int64_t)(esq[0][0] + esq[0][1] + esq[0][2]) -
(int64_t)(esq[1][0] + esq[1][1] + esq[1][2]);
@@ -7353,16 +6357,6 @@ static InterpFilter predict_interp_filter(
single_filter[NEARESTMV][refs[1]])
best_filter = single_filter[NEARESTMV][refs[0]];
break;
- case NEAREST_NEARMV:
- if (single_filter[NEARESTMV][refs[0]] ==
- single_filter[NEARMV][refs[1]])
- best_filter = single_filter[NEARESTMV][refs[0]];
- break;
- case NEAR_NEARESTMV:
- if (single_filter[NEARMV][refs[0]] ==
- single_filter[NEARESTMV][refs[1]])
- best_filter = single_filter[NEARMV][refs[0]];
- break;
case NEAR_NEARMV:
if (single_filter[NEARMV][refs[0]] == single_filter[NEARMV][refs[1]])
best_filter = single_filter[NEARMV][refs[0]];
@@ -7575,6 +6569,7 @@ static int64_t pick_interinter_wedge(const AV1_COMP *const cpi,
int wedge_sign = 0;
assert(is_interinter_compound_used(COMPOUND_WEDGE, bsize));
+ assert(cpi->common.allow_masked_compound);
if (cpi->sf.fast_wedge_sign_estimate) {
wedge_sign = estimate_wedge_sign(cpi, x, bsize, p0, bw, p1, bw);
@@ -7688,6 +6683,7 @@ static int64_t pick_interintra_wedge(const AV1_COMP *const cpi,
int wedge_index = -1;
assert(is_interintra_wedge_used(bsize));
+ assert(cpi->common.allow_interintra_compound);
rd = pick_wedge_fixed_sign(cpi, x, bsize, p0, p1, 0, &wedge_index);
@@ -7715,15 +6711,13 @@ static int64_t pick_interinter_mask(const AV1_COMP *const cpi, MACROBLOCK *x,
}
}
-static int interinter_compound_motion_search(const AV1_COMP *const cpi,
- MACROBLOCK *x,
- const BLOCK_SIZE bsize,
- const int this_mode, int mi_row,
- int mi_col) {
+static int interinter_compound_motion_search(
+ const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
+ const BLOCK_SIZE bsize, const int this_mode, int mi_row, int mi_col) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
int_mv tmp_mv[2];
- int rate_mvs[2], tmp_rate_mv = 0;
+ int tmp_rate_mv = 0;
const INTERINTER_COMPOUND_DATA compound_data = {
#if CONFIG_WEDGE
mbmi->wedge_index,
@@ -7736,20 +6730,17 @@ static int interinter_compound_motion_search(const AV1_COMP *const cpi,
mbmi->interinter_compound_type
};
if (this_mode == NEW_NEWMV) {
- do_masked_motion_search_indexed(cpi, x, &compound_data, bsize, mi_row,
- mi_col, tmp_mv, rate_mvs, 2);
- tmp_rate_mv = rate_mvs[0] + rate_mvs[1];
+ do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
+ mi_row, mi_col, tmp_mv, &tmp_rate_mv, 2);
mbmi->mv[0].as_int = tmp_mv[0].as_int;
mbmi->mv[1].as_int = tmp_mv[1].as_int;
} else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
- do_masked_motion_search_indexed(cpi, x, &compound_data, bsize, mi_row,
- mi_col, tmp_mv, rate_mvs, 0);
- tmp_rate_mv = rate_mvs[0];
+ do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
+ mi_row, mi_col, tmp_mv, &tmp_rate_mv, 0);
mbmi->mv[0].as_int = tmp_mv[0].as_int;
} else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
- do_masked_motion_search_indexed(cpi, x, &compound_data, bsize, mi_row,
- mi_col, tmp_mv, rate_mvs, 1);
- tmp_rate_mv = rate_mvs[1];
+ do_masked_motion_search_indexed(cpi, x, cur_mv, &compound_data, bsize,
+ mi_row, mi_col, tmp_mv, &tmp_rate_mv, 1);
mbmi->mv[1].as_int = tmp_mv[1].as_int;
}
return tmp_rate_mv;
@@ -7760,6 +6751,7 @@ static int64_t build_and_cost_compound_type(
const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
int *strides, int mi_row, int mi_col) {
+ const AV1_COMMON *const cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
int rate_sum;
@@ -7775,9 +6767,9 @@ static int64_t build_and_cost_compound_type(
if (have_newmv_in_inter_mode(this_mode) &&
use_masked_motion_search(compound_type)) {
- *out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
- mi_row, mi_col);
- av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
+ *out_rate_mv = interinter_compound_motion_search(cpi, x, cur_mv, bsize,
+ this_mode, mi_row, mi_col);
+ av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, ctx, bsize);
model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
&tmp_skip_txfm_sb, &tmp_skip_sse_sb);
rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
@@ -7830,9 +6822,6 @@ typedef struct {
// Pointer to array of motion vectors to use for each ref and their rates
// Should point to first of 2 arrays in 2D array
int *single_newmv_rate;
- // Pointers costs of compound inter-intra and inter-inter predictions
- int *compmode_interintra_cost;
- int *compmode_interinter_cost;
// Pointer to array of predicted rate-distortion
// Should point to first of 2 arrays in 2D array
int64_t (*modelled_rd)[TOTAL_REFS_PER_FRAME];
@@ -7872,14 +6861,12 @@ static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
- joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL,
- rate_mv, 0);
+ joint_motion_search(cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, NULL,
+ 0, rate_mv, 0);
} else {
*rate_mv = 0;
for (i = 0; i < 2; ++i) {
-#if CONFIG_REF_MV
av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
-#endif // CONFIG_REF_MV
*rate_mv += av1_mv_bit_cost(
&frame_mv[refs[i]].as_mv, &mbmi_ext->ref_mvs[refs[i]][0].as_mv,
x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
@@ -7887,21 +6874,31 @@ static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
}
} else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
-#if CONFIG_REF_MV
- av1_set_mvcost(x, refs[1], 1, mbmi->ref_mv_idx);
-#endif // CONFIG_REF_MV
- *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
- &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
- x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
+ if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
+ frame_mv[refs[0]].as_int =
+ mode_mv[compound_ref0_mode(this_mode)][refs[0]].as_int;
+ compound_single_motion_search_interinter(
+ cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, 0, rate_mv, 0, 1);
+ } else {
+ av1_set_mvcost(x, refs[1], 1, mbmi->ref_mv_idx);
+ *rate_mv = av1_mv_bit_cost(&frame_mv[refs[1]].as_mv,
+ &mbmi_ext->ref_mvs[refs[1]][0].as_mv,
+ x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
+ }
} else {
assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
-#if CONFIG_REF_MV
- av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
-#endif // CONFIG_REF_MV
- *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
- &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
- x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
+ if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
+ frame_mv[refs[1]].as_int =
+ mode_mv[compound_ref1_mode(this_mode)][refs[1]].as_int;
+ compound_single_motion_search_interinter(
+ cpi, x, bsize, frame_mv, mi_row, mi_col, NULL, 0, rate_mv, 0, 0);
+ } else {
+ av1_set_mvcost(x, refs[0], 0, mbmi->ref_mv_idx);
+ *rate_mv = av1_mv_bit_cost(&frame_mv[refs[0]].as_mv,
+ &mbmi_ext->ref_mvs[refs[0]][0].as_mv,
+ x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
+ }
}
#else
// Initialize mv using single prediction mode result.
@@ -7913,9 +6910,7 @@ static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
} else {
*rate_mv = 0;
for (i = 0; i < 2; ++i) {
-#if CONFIG_REF_MV
av1_set_mvcost(x, refs[i], i, mbmi->ref_mv_idx);
-#endif // CONFIG_REF_MV
*rate_mv += av1_mv_bit_cost(&frame_mv[refs[i]].as_mv,
&mbmi_ext->ref_mvs[refs[i]][0].as_mv,
x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
@@ -7986,7 +6981,7 @@ int64_t interpolation_filter_search(
set_default_interp_filters(mbmi, assign_filter);
*switchable_rate = av1_get_switchable_rate(cpi, xd);
- av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
+ av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate, &tmp_dist,
skip_txfm_sb, skip_sse_sb);
*rd = RDCOST(x->rdmult, x->rddiv, *switchable_rate + tmp_rate, tmp_dist);
@@ -8022,7 +7017,7 @@ int64_t interpolation_filter_search(
mbmi->interp_filter = (InterpFilter)i;
#endif // CONFIG_DUAL_FILTER
tmp_rs = av1_get_switchable_rate(cpi, xd);
- av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
+ av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
&tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
@@ -8077,6 +7072,7 @@ static int64_t motion_mode_rd(
int mi_col, HandleInterModeArgs *const args, const int64_t ref_best_rd,
const int *refs, int rate_mv,
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
+ int_mv *const single_newmv,
#if CONFIG_EXT_INTER
int rate2_bmc_nocoeff, MB_MODE_INFO *best_bmc_mbmi,
#if CONFIG_MOTION_VAR
@@ -8183,10 +7179,10 @@ static int64_t motion_mode_rd(
if (!has_subpel_mv_component(xd->mi[0], xd, 1))
mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
#endif // CONFIG_DUAL_FILTER
- av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
+ av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
#if CONFIG_EXT_INTER
} else {
- av1_build_inter_predictors_sb(xd, mi_row, mi_col, orig_dst, bsize);
+ av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize);
#endif // CONFIG_EXT_INTER
}
av1_build_obmc_inter_prediction(
@@ -8214,10 +7210,55 @@ static int64_t motion_mode_rd(
: cm->interp_filter;
#endif // CONFIG_DUAL_FILTER
- if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
- mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
- &mbmi->wm_params[0], mi_row, mi_col) == 0) {
- av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
+ if (!find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
+ mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
+ &mbmi->wm_params[0], mi_row, mi_col)) {
+ // Refine MV for NEWMV mode
+ if (!is_comp_pred && have_newmv_in_inter_mode(this_mode)) {
+ int tmp_rate_mv = 0;
+ const int_mv mv0 = mbmi->mv[0];
+ WarpedMotionParams wm_params0 = mbmi->wm_params[0];
+
+ // Refine MV in a small range.
+ av1_refine_warped_mv(cpi, x, bsize, mi_row, mi_col, pts, pts_inref);
+
+ // Keep the refined MV and WM parameters.
+ if (mv0.as_int != mbmi->mv[0].as_int) {
+ const int ref = refs[0];
+ const MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
+
+ tmp_rate_mv =
+ av1_mv_bit_cost(&mbmi->mv[0].as_mv, &ref_mv, x->nmvjointcost,
+ x->mvcost, MV_COST_WEIGHT);
+
+ if (cpi->sf.adaptive_motion_search)
+ x->pred_mv[ref] = mbmi->mv[0].as_mv;
+
+ single_newmv[ref] = mbmi->mv[0];
+
+ if (discount_newmv_test(cpi, this_mode, mbmi->mv[0], mode_mv,
+ refs[0])) {
+ tmp_rate_mv = AOMMAX((tmp_rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
+ }
+#if CONFIG_EXT_INTER
+ tmp_rate2 = rate2_bmc_nocoeff - rate_mv_bmc + tmp_rate_mv;
+#else
+ tmp_rate2 = rate2_nocoeff - rate_mv + tmp_rate_mv;
+#endif // CONFIG_EXT_INTER
+#if CONFIG_DUAL_FILTER
+ if (!has_subpel_mv_component(xd->mi[0], xd, 0))
+ mbmi->interp_filter[0] = EIGHTTAP_REGULAR;
+ if (!has_subpel_mv_component(xd->mi[0], xd, 1))
+ mbmi->interp_filter[1] = EIGHTTAP_REGULAR;
+#endif // CONFIG_DUAL_FILTER
+ } else {
+ // Restore the old MV and WM parameters.
+ mbmi->mv[0] = mv0;
+ mbmi->wm_params[0] = wm_params0;
+ }
+ }
+
+ av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
&tmp_dist, skip_txfm_sb, skip_sse_sb);
} else {
@@ -8446,16 +7487,16 @@ static int64_t handle_inter_mode(
int rate_mv = 0;
#if CONFIG_EXT_INTER
int pred_exists = 1;
+#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
const int bw = block_size_wide[bsize];
+#endif // ONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
int_mv single_newmv[TOTAL_REFS_PER_FRAME];
#if CONFIG_INTERINTRA
const unsigned int *const interintra_mode_cost =
cpi->interintra_mode_cost[size_group_lookup[bsize]];
#endif // CONFIG_INTERINTRA
const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
-#if CONFIG_REF_MV
uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
-#endif // CONFIG_REF_MV
#else
int_mv *const single_newmv = args->single_newmv;
#endif // CONFIG_EXT_INTER
@@ -8484,10 +7525,19 @@ static int64_t handle_inter_mode(
int16_t mode_ctx;
#if CONFIG_EXT_INTER
- *args->compmode_interintra_cost = 0;
+#if CONFIG_INTERINTRA
+ int compmode_interintra_cost = 0;
mbmi->use_wedge_interintra = 0;
- *args->compmode_interinter_cost = 0;
+#endif
+#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
+ int compmode_interinter_cost = 0;
mbmi->interinter_compound_type = COMPOUND_AVERAGE;
+#endif
+
+#if CONFIG_INTERINTRA
+ if (!cm->allow_interintra_compound && is_comp_interintra_pred)
+ return INT64_MAX;
+#endif // CONFIG_INTERINTRA
// is_comp_interintra_pred implies !is_comp_pred
assert(!is_comp_interintra_pred || (!is_comp_pred));
@@ -8495,7 +7545,6 @@ static int64_t handle_inter_mode(
assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
#endif // CONFIG_EXT_INTER
-#if CONFIG_REF_MV
#if CONFIG_EXT_INTER
if (is_comp_pred)
mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
@@ -8503,9 +7552,6 @@ static int64_t handle_inter_mode(
#endif // CONFIG_EXT_INTER
mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
mbmi->ref_frame, bsize, -1);
-#else // CONFIG_REF_MV
- mode_ctx = mbmi_ext->mode_context[refs[0]];
-#endif // CONFIG_REF_MV
#if CONFIG_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
@@ -8545,7 +7591,6 @@ static int64_t handle_inter_mode(
mbmi->mv[i].as_int = cur_mv[i].as_int;
}
-#if CONFIG_REF_MV
#if CONFIG_EXT_INTER
if (this_mode == NEAREST_NEARESTMV)
#else
@@ -8569,7 +7614,7 @@ static int64_t handle_inter_mode(
#if CONFIG_EXT_INTER
if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
- if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
+ if (this_mode == NEAREST_NEWMV) {
cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
@@ -8578,7 +7623,7 @@ static int64_t handle_inter_mode(
mbmi->mv[0].as_int = cur_mv[0].as_int;
}
- if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
+ if (this_mode == NEW_NEARESTMV) {
cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
@@ -8590,8 +7635,7 @@ static int64_t handle_inter_mode(
if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
int ref_mv_idx = mbmi->ref_mv_idx + 1;
- if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV ||
- this_mode == NEAR_NEARMV) {
+ if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARMV) {
cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
@@ -8600,8 +7644,7 @@ static int64_t handle_inter_mode(
mbmi->mv[0].as_int = cur_mv[0].as_int;
}
- if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV ||
- this_mode == NEAR_NEARMV) {
+ if (this_mode == NEW_NEARMV || this_mode == NEAR_NEARMV) {
cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
@@ -8626,7 +7669,6 @@ static int64_t handle_inter_mode(
}
}
#endif // CONFIG_EXT_INTER
-#endif // CONFIG_REF_MV
// do first prediction into the destination buffer. Do the next
// prediction into a temporary buffer. Then keep track of which one
@@ -8659,7 +7701,7 @@ static int64_t handle_inter_mode(
#else
rd_stats->rate += AOMMIN(cost_mv_ref(cpi, this_mode, mode_ctx),
cost_mv_ref(cpi, NEARESTMV, mode_ctx));
-#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
+#endif // CONFIG_EXT_INTER
} else {
rd_stats->rate += cost_mv_ref(cpi, this_mode, mode_ctx);
}
@@ -8688,6 +7730,7 @@ static int64_t handle_inter_mode(
#endif // CONFIG_MOTION_VAR
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
+#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
if (is_comp_pred) {
int rate_sum, rs2;
int64_t dist_sum;
@@ -8705,6 +7748,9 @@ static int64_t handle_inter_mode(
int strides[1] = { bw };
int tmp_rate_mv;
int masked_compound_used = is_any_masked_compound_used(bsize);
+#if CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
+ masked_compound_used = masked_compound_used && cm->allow_masked_compound;
+#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
COMPOUND_TYPE cur_type;
best_mv[0].as_int = cur_mv[0].as_int;
@@ -8714,8 +7760,6 @@ static int64_t handle_inter_mode(
uint8_t tmp_mask_buf[2 * MAX_SB_SQUARE];
best_compound_data.seg_mask = tmp_mask_buf;
#endif // CONFIG_COMPOUND_SEGMENT
- av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
- av1_compound_type_tree);
if (masked_compound_used) {
av1_cost_tokens(compound_type_cost, cm->fc->compound_type_prob[bsize],
@@ -8728,6 +7772,7 @@ static int64_t handle_inter_mode(
}
for (cur_type = COMPOUND_AVERAGE; cur_type < COMPOUND_TYPES; cur_type++) {
+ if (cur_type != COMPOUND_AVERAGE && !masked_compound_used) break;
if (!is_interinter_compound_used(cur_type, bsize)) break;
tmp_rate_mv = rate_mv;
best_rd_cur = INT64_MAX;
@@ -8740,7 +7785,8 @@ static int64_t handle_inter_mode(
switch (cur_type) {
case COMPOUND_AVERAGE:
- av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
+ av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
+ bsize);
av1_subtract_plane(x, bsize, 0);
rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
&tmp_skip_txfm_sb, &tmp_skip_sse_sb,
@@ -8830,13 +7876,14 @@ static int64_t handle_inter_mode(
pred_exists = 0;
- *args->compmode_interinter_cost =
+ compmode_interinter_cost =
av1_cost_literal(get_interinter_compound_type_bits(
bsize, mbmi->interinter_compound_type)) +
(masked_compound_used
? compound_type_cost[mbmi->interinter_compound_type]
: 0);
}
+#endif // CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
#if CONFIG_INTERINTRA
if (is_comp_interintra_pred) {
@@ -8863,7 +7910,7 @@ static int64_t handle_inter_mode(
xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
xd->plane[j].dst.stride = bw;
}
- av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
+ av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst, bsize);
restore_dst_buf(xd, orig_dst);
mbmi->ref_frame[1] = INTRA_FRAME;
mbmi->use_wedge_interintra = 0;
@@ -8876,7 +7923,8 @@ static int64_t handle_inter_mode(
av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
&tmp_skip_txfm_sb, &tmp_skip_sse_sb);
- rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate_mv + rate_sum, dist_sum);
+ rd =
+ RDCOST(x->rdmult, x->rddiv, tmp_rate_mv + rate_sum + rmode, dist_sum);
if (rd < best_interintra_rd) {
best_interintra_rd = rd;
best_interintra_mode = mbmi->interintra_mode;
@@ -8907,7 +7955,7 @@ static int64_t handle_inter_mode(
if (rd != INT64_MAX)
rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_mv + rwedge + rate_sum,
dist_sum);
- best_interintra_rd_nowedge = rd;
+ best_interintra_rd_nowedge = best_interintra_rd;
// Disable wedge search if source variance is small
if (x->source_variance > cpi->sf.disable_wedge_search_var_thresh) {
@@ -8926,17 +7974,18 @@ static int64_t handle_inter_mode(
// get negative of mask
const uint8_t *mask = av1_get_contiguous_soft_mask(
mbmi->interintra_wedge_index, 1, bsize);
- do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
- &tmp_mv, &tmp_rate_mv, 0);
+ tmp_mv.as_int = x->mbmi_ext->ref_mvs[refs[0]][0].as_int;
+ compound_single_motion_search(cpi, x, bsize, &tmp_mv.as_mv, mi_row,
+ mi_col, intrapred, mask, bw,
+ &tmp_rate_mv, 0, 0);
mbmi->mv[0].as_int = tmp_mv.as_int;
- av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
+ av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, &orig_dst,
+ bsize);
model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
&tmp_skip_txfm_sb, &tmp_skip_sse_sb);
rd = RDCOST(x->rdmult, x->rddiv,
rmode + tmp_rate_mv + rwedge + rate_sum, dist_sum);
- if (rd < best_interintra_rd_wedge) {
- best_interintra_rd_wedge = rd;
- } else {
+ if (rd >= best_interintra_rd_wedge) {
tmp_mv.as_int = cur_mv[0].as_int;
tmp_rate_mv = rate_mv;
}
@@ -8956,37 +8005,33 @@ static int64_t handle_inter_mode(
best_interintra_rd_wedge = rd;
if (best_interintra_rd_wedge < best_interintra_rd_nowedge) {
mbmi->use_wedge_interintra = 1;
- best_interintra_rd = best_interintra_rd_wedge;
mbmi->mv[0].as_int = tmp_mv.as_int;
rd_stats->rate += tmp_rate_mv - rate_mv;
rate_mv = tmp_rate_mv;
} else {
mbmi->use_wedge_interintra = 0;
- best_interintra_rd = best_interintra_rd_nowedge;
mbmi->mv[0].as_int = cur_mv[0].as_int;
}
} else {
mbmi->use_wedge_interintra = 0;
- best_interintra_rd = best_interintra_rd_nowedge;
}
}
#endif // CONFIG_WEDGE
pred_exists = 0;
- *args->compmode_interintra_cost =
- av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1);
- *args->compmode_interintra_cost +=
+ compmode_interintra_cost =
+ av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 1) +
interintra_mode_cost[mbmi->interintra_mode];
if (is_interintra_wedge_used(bsize)) {
- *args->compmode_interintra_cost += av1_cost_bit(
+ compmode_interintra_cost += av1_cost_bit(
cm->fc->wedge_interintra_prob[bsize], mbmi->use_wedge_interintra);
if (mbmi->use_wedge_interintra) {
- *args->compmode_interintra_cost +=
+ compmode_interintra_cost +=
av1_cost_literal(get_interintra_wedge_bits(bsize));
}
}
} else if (is_interintra_allowed(mbmi)) {
- *args->compmode_interintra_cost =
+ compmode_interintra_cost =
av1_cost_bit(cm->fc->interintra_prob[size_group_lookup[bsize]], 0);
}
#endif // CONFIG_INTERINTRA
@@ -8994,7 +8039,7 @@ static int64_t handle_inter_mode(
if (pred_exists == 0) {
int tmp_rate;
int64_t tmp_dist;
- av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
+ av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, &orig_dst, bsize);
model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
&tmp_dist, &skip_txfm_sb, &skip_sse_sb);
rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
@@ -9034,10 +8079,23 @@ static int64_t handle_inter_mode(
}
}
+#if CONFIG_EXT_INTER
+#if CONFIG_INTERINTRA
+ rd_stats->rate += compmode_interintra_cost;
+#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
+ rate2_bmc_nocoeff += compmode_interintra_cost;
+#endif
+#endif
+#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
+ rd_stats->rate += compmode_interinter_cost;
+#endif
+#endif
+
ret_val = motion_mode_rd(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
disable_skip, mode_mv, mi_row, mi_col, args,
ref_best_rd, refs, rate_mv,
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
+ single_newmv,
#if CONFIG_EXT_INTER
rate2_bmc_nocoeff, &best_bmc_mbmi,
#if CONFIG_MOTION_VAR
@@ -9060,34 +8118,36 @@ static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
MACROBLOCKD *const xd = &x->e_mbd;
const TileInfo *tile = &xd->tile;
+#if CONFIG_EC_ADAPT
+ FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
+#else
+ FRAME_CONTEXT *const ec_ctx = cm->fc;
+#endif // CONFIG_EC_ADAPT
MODE_INFO *const mi = xd->mi[0];
const int mi_row = -xd->mb_to_top_edge / (8 * MI_SIZE);
const int mi_col = -xd->mb_to_left_edge / (8 * MI_SIZE);
const int w = block_size_wide[bsize];
const int h = block_size_high[bsize];
const int sb_row = mi_row / MAX_MIB_SIZE;
+ const int sb_col = mi_col / MAX_MIB_SIZE;
- int_mv dv_ref;
- av1_find_ref_dv(&dv_ref, mi_row, mi_col);
-
- const MvLimits tmp_mv_limits = x->mv_limits;
+ MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
+ MV_REFERENCE_FRAME ref_frame = INTRA_FRAME;
+ int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
+ av1_find_mv_refs(cm, xd, mi, ref_frame, &mbmi_ext->ref_mv_count[ref_frame],
+ mbmi_ext->ref_mv_stack[ref_frame],
+#if CONFIG_EXT_INTER
+ mbmi_ext->compound_mode_context,
+#endif // CONFIG_EXT_INTER
+ candidates, mi_row, mi_col, NULL, NULL,
+ mbmi_ext->mode_context);
- // TODO(aconverse@google.com): Handle same row DV.
- x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
- x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
- x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
- x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
- assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
- assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
- assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
- assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
- av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
+ int_mv nearestmv, nearmv;
+ av1_find_best_ref_mvs(0, candidates, &nearestmv, &nearmv);
- if (x->mv_limits.col_max < x->mv_limits.col_min ||
- x->mv_limits.row_max < x->mv_limits.row_min) {
- x->mv_limits = tmp_mv_limits;
- return INT64_MAX;
- }
+ int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
+ if (dv_ref.as_int == 0) av1_find_ref_dv(&dv_ref, mi_row, mi_col);
+ mbmi_ext->ref_mvs[INTRA_FRAME][0] = dv_ref;
struct buf_2d yv12_mb[MAX_MB_PLANE];
av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, mi_row, mi_col, NULL, NULL);
@@ -9095,86 +8155,140 @@ static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
xd->plane[i].pre[0] = yv12_mb[i];
}
- int step_param = cpi->mv_step_param;
- MV mvp_full = dv_ref.as_mv;
- mvp_full.col >>= 3;
- mvp_full.row >>= 3;
- int sadpb = x->sadperbit16;
- int cost_list[5];
- int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
- sadpb, cond_cost_list(cpi, cost_list),
- &dv_ref.as_mv, INT_MAX, 1);
+ enum IntrabcMotionDirection {
+ IBC_MOTION_ABOVE,
+ IBC_MOTION_LEFT,
+ IBC_MOTION_DIRECTIONS
+ };
- x->mv_limits = tmp_mv_limits;
- if (bestsme == INT_MAX) return INT64_MAX;
- mvp_full = x->best_mv.as_mv;
- MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
- if (mv_check_bounds(&x->mv_limits, &dv)) return INT64_MAX;
- if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) return INT64_MAX;
MB_MODE_INFO *mbmi = &mi->mbmi;
MB_MODE_INFO best_mbmi = *mbmi;
RD_STATS best_rdcost = *rd_cost;
int best_skip = x->skip;
+
+ for (enum IntrabcMotionDirection dir = IBC_MOTION_ABOVE;
+ dir < IBC_MOTION_DIRECTIONS; ++dir) {
+ const MvLimits tmp_mv_limits = x->mv_limits;
+ switch (dir) {
+ case IBC_MOTION_ABOVE:
+ x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
+ x->mv_limits.col_max = (tile->mi_col_end - mi_col) * MI_SIZE - w;
+ x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
+ x->mv_limits.row_max = (sb_row * MAX_MIB_SIZE - mi_row) * MI_SIZE - h;
+ break;
+ case IBC_MOTION_LEFT:
+ x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
+ x->mv_limits.col_max = (sb_col * MAX_MIB_SIZE - mi_col) * MI_SIZE - w;
+ // TODO(aconverse@google.com): Minimize the overlap between above and
+ // left areas.
+ x->mv_limits.row_min = (tile->mi_row_start - mi_row) * MI_SIZE;
+ int bottom_coded_mi_edge =
+ AOMMIN((sb_row + 1) * MAX_MIB_SIZE, tile->mi_row_end);
+ x->mv_limits.row_max = (bottom_coded_mi_edge - mi_row) * MI_SIZE - h;
+ break;
+ default: assert(0);
+ }
+ assert(x->mv_limits.col_min >= tmp_mv_limits.col_min);
+ assert(x->mv_limits.col_max <= tmp_mv_limits.col_max);
+ assert(x->mv_limits.row_min >= tmp_mv_limits.row_min);
+ assert(x->mv_limits.row_max <= tmp_mv_limits.row_max);
+ av1_set_mv_search_range(&x->mv_limits, &dv_ref.as_mv);
+
+ if (x->mv_limits.col_max < x->mv_limits.col_min ||
+ x->mv_limits.row_max < x->mv_limits.row_min) {
+ x->mv_limits = tmp_mv_limits;
+ continue;
+ }
+
+ int step_param = cpi->mv_step_param;
+ MV mvp_full = dv_ref.as_mv;
+ mvp_full.col >>= 3;
+ mvp_full.row >>= 3;
+ int sadpb = x->sadperbit16;
+ int cost_list[5];
+ int bestsme = av1_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
+ sadpb, cond_cost_list(cpi, cost_list),
+ &dv_ref.as_mv, INT_MAX, 1);
+
+ x->mv_limits = tmp_mv_limits;
+ if (bestsme == INT_MAX) continue;
+ mvp_full = x->best_mv.as_mv;
+ MV dv = {.row = mvp_full.row * 8, .col = mvp_full.col * 8 };
+ if (mv_check_bounds(&x->mv_limits, &dv)) continue;
+ if (!is_dv_valid(dv, tile, mi_row, mi_col, bsize)) continue;
+
#if CONFIG_PALETTE
- memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
+ memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
#endif
- mbmi->use_intrabc = 1;
- mbmi->mode = DC_PRED;
- mbmi->uv_mode = DC_PRED;
- mbmi->mv[0].as_mv = dv;
+ mbmi->use_intrabc = 1;
+ mbmi->mode = DC_PRED;
+ mbmi->uv_mode = DC_PRED;
+ mbmi->mv[0].as_mv = dv;
#if CONFIG_DUAL_FILTER
- for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
+ for (int idx = 0; idx < 4; ++idx) mbmi->interp_filter[idx] = BILINEAR;
#else
- mbmi->interp_filter = BILINEAR;
+ mbmi->interp_filter = BILINEAR;
#endif
- mbmi->skip = 0;
- x->skip = 0;
- av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
-
- int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, x->nmvjointcost, x->mvcost,
- MV_COST_WEIGHT);
- const PREDICTION_MODE A = av1_above_block_mode(mi, xd->above_mi, 0);
- const PREDICTION_MODE L = av1_left_block_mode(mi, xd->left_mi, 0);
- const int rate_mode =
- cpi->y_mode_costs[A][L][DC_PRED] + av1_cost_bit(INTRABC_PROB, 1);
-
- RD_STATS rd_stats, rd_stats_uv;
- av1_subtract_plane(x, bsize, 0);
- super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
- super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
- av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
+ mbmi->skip = 0;
+ x->skip = 0;
+ av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
+
+ int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, x->nmvjointcost,
+ x->mvcost, MV_COST_WEIGHT);
+ const PREDICTION_MODE A = av1_above_block_mode(mi, xd->above_mi, 0);
+ const PREDICTION_MODE L = av1_left_block_mode(mi, xd->left_mi, 0);
+ const int rate_mode = cpi->y_mode_costs[A][L][DC_PRED] +
+ av1_cost_bit(ec_ctx->intrabc_prob, 1);
+
+ RD_STATS rd_stats, rd_stats_uv;
+ av1_subtract_plane(x, bsize, 0);
+ super_block_yrd(cpi, x, &rd_stats, bsize, INT64_MAX);
+ super_block_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
+ av1_merge_rd_stats(&rd_stats, &rd_stats_uv);
#if CONFIG_RD_DEBUG
- mbmi->rd_stats = rd_stats;
+ mbmi->rd_stats = rd_stats;
#endif
- const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
-
- RD_STATS rdc_noskip;
- av1_init_rd_stats(&rdc_noskip);
- rdc_noskip.rate =
- rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
- rdc_noskip.dist = rd_stats.dist;
- rdc_noskip.rdcost =
- RDCOST(x->rdmult, x->rddiv, rdc_noskip.rate, rdc_noskip.dist);
- if (rdc_noskip.rdcost < best_rd) {
- best_rd = rdc_noskip.rdcost;
- best_mbmi = *mbmi;
- best_skip = x->skip;
- best_rdcost = rdc_noskip;
- }
+#if CONFIG_VAR_TX
+ // TODO(aconverse@google.com): Evaluate allowing VAR TX on intrabc blocks
+ const int width = block_size_wide[bsize] >> tx_size_wide_log2[0];
+ const int height = block_size_high[bsize] >> tx_size_high_log2[0];
+ int idx, idy;
+ for (idy = 0; idy < height; ++idy)
+ for (idx = 0; idx < width; ++idx)
+ mbmi->inter_tx_size[idy >> 1][idx >> 1] = mbmi->tx_size;
+ mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
+#endif // CONFIG_VAR_TX
- x->skip = 1;
- mbmi->skip = 1;
- RD_STATS rdc_skip;
- av1_init_rd_stats(&rdc_skip);
- rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
- rdc_skip.dist = rd_stats.sse;
- rdc_skip.rdcost = RDCOST(x->rdmult, x->rddiv, rdc_skip.rate, rdc_skip.dist);
- if (rdc_skip.rdcost < best_rd) {
- best_rd = rdc_skip.rdcost;
- best_mbmi = *mbmi;
- best_skip = x->skip;
- best_rdcost = rdc_skip;
+ const aom_prob skip_prob = av1_get_skip_prob(cm, xd);
+
+ RD_STATS rdc_noskip;
+ av1_init_rd_stats(&rdc_noskip);
+ rdc_noskip.rate =
+ rate_mode + rate_mv + rd_stats.rate + av1_cost_bit(skip_prob, 0);
+ rdc_noskip.dist = rd_stats.dist;
+ rdc_noskip.rdcost =
+ RDCOST(x->rdmult, x->rddiv, rdc_noskip.rate, rdc_noskip.dist);
+ if (rdc_noskip.rdcost < best_rd) {
+ best_rd = rdc_noskip.rdcost;
+ best_mbmi = *mbmi;
+ best_skip = x->skip;
+ best_rdcost = rdc_noskip;
+ }
+
+ x->skip = 1;
+ mbmi->skip = 1;
+ RD_STATS rdc_skip;
+ av1_init_rd_stats(&rdc_skip);
+ rdc_skip.rate = rate_mode + rate_mv + av1_cost_bit(skip_prob, 1);
+ rdc_skip.dist = rd_stats.sse;
+ rdc_skip.rdcost = RDCOST(x->rdmult, x->rddiv, rdc_skip.rate, rdc_skip.dist);
+ if (rdc_skip.rdcost < best_rd) {
+ best_rd = rdc_skip.rdcost;
+ best_mbmi = *mbmi;
+ best_skip = x->skip;
+ best_rdcost = rdc_skip;
+ }
}
*mbmi = best_mbmi;
*rd_cost = best_rdcost;
@@ -9200,6 +8314,7 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
xd->mi[0]->mbmi.ref_frame[1] = NONE_FRAME;
#if CONFIG_INTRABC
xd->mi[0]->mbmi.use_intrabc = 0;
+ xd->mi[0]->mbmi.mv[0].as_int = 0;
#endif // CONFIG_INTRABC
const int64_t intra_yrd =
@@ -9212,11 +8327,8 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
if (intra_yrd < best_rd) {
max_uv_tx_size = uv_txsize_lookup[bsize][xd->mi[0]->mbmi.tx_size]
[pd[1].subsampling_x][pd[1].subsampling_y];
-
+ init_sbuv_mode(&xd->mi[0]->mbmi);
#if CONFIG_CB4X4
-#if !CONFIG_CHROMA_2X2
- max_uv_tx_size = AOMMAX(max_uv_tx_size, TX_4X4);
-#endif // !CONFIG_CHROMA_2X2
if (!x->skip_chroma_rd)
rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly, &dist_uv,
&uv_skip, bsize, max_uv_tx_size);
@@ -9235,6 +8347,9 @@ void av1_rd_pick_intra_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
rd_cost->dist = dist_y + dist_uv;
}
rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
+#if CONFIG_DAALA_DIST && CONFIG_CB4X4
+ rd_cost->dist_y = dist_y;
+#endif
} else {
rd_cost->rate = INT_MAX;
}
@@ -9602,10 +8717,8 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
int64_t best_pred_diff[REFERENCE_MODES];
int64_t best_pred_rd[REFERENCE_MODES];
MB_MODE_INFO best_mbmode;
-#if CONFIG_REF_MV
int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
-#endif // CONFIG_REF_MV
int best_mode_skippable = 0;
int midx, best_mode_index = -1;
unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
@@ -9635,13 +8748,11 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
int best_skip2 = 0;
uint8_t ref_frame_skip_mask[2] = { 0 };
-#if CONFIG_EXT_INTER
uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
+#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
int64_t best_single_inter_rd = INT64_MAX;
-#else
- uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
-#endif // CONFIG_EXT_INTER
+#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
int mode_skip_start = sf->mode_skip_start + 1;
const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
const int *const rd_thresh_freq_fact = tile_data->thresh_freq_fact[bsize];
@@ -9663,8 +8774,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
NULL,
NULL,
NULL,
- NULL,
- NULL,
#else // CONFIG_EXT_INTER
NULL,
#endif // CONFIG_EXT_INTER
@@ -9681,15 +8790,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
const MODE_INFO *left_mi = xd->left_mi;
#endif // CONFIG_PALETTE
#if CONFIG_MOTION_VAR
-#if CONFIG_HIGHBITDEPTH
- DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
- DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
-#else
- DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
- DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
-#endif // CONFIG_HIGHBITDEPTH
- DECLARE_ALIGNED(16, int32_t, weighted_src_buf[MAX_SB_SQUARE]);
- DECLARE_ALIGNED(16, int32_t, mask2d_buf[MAX_SB_SQUARE]);
int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
@@ -9698,22 +8798,24 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
#if CONFIG_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
int len = sizeof(uint16_t);
- args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
- args.above_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
+ args.above_pred_buf[0] = CONVERT_TO_BYTEPTR(x->above_pred_buf);
+ args.above_pred_buf[1] =
+ CONVERT_TO_BYTEPTR(x->above_pred_buf + MAX_SB_SQUARE * len);
args.above_pred_buf[2] =
- CONVERT_TO_BYTEPTR(tmp_buf1 + 2 * MAX_SB_SQUARE * len);
- args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
- args.left_pred_buf[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
+ CONVERT_TO_BYTEPTR(x->above_pred_buf + 2 * MAX_SB_SQUARE * len);
+ args.left_pred_buf[0] = CONVERT_TO_BYTEPTR(x->left_pred_buf);
+ args.left_pred_buf[1] =
+ CONVERT_TO_BYTEPTR(x->left_pred_buf + MAX_SB_SQUARE * len);
args.left_pred_buf[2] =
- CONVERT_TO_BYTEPTR(tmp_buf2 + 2 * MAX_SB_SQUARE * len);
+ CONVERT_TO_BYTEPTR(x->left_pred_buf + 2 * MAX_SB_SQUARE * len);
} else {
#endif // CONFIG_HIGHBITDEPTH
- args.above_pred_buf[0] = tmp_buf1;
- args.above_pred_buf[1] = tmp_buf1 + MAX_SB_SQUARE;
- args.above_pred_buf[2] = tmp_buf1 + 2 * MAX_SB_SQUARE;
- args.left_pred_buf[0] = tmp_buf2;
- args.left_pred_buf[1] = tmp_buf2 + MAX_SB_SQUARE;
- args.left_pred_buf[2] = tmp_buf2 + 2 * MAX_SB_SQUARE;
+ args.above_pred_buf[0] = x->above_pred_buf;
+ args.above_pred_buf[1] = x->above_pred_buf + MAX_SB_SQUARE;
+ args.above_pred_buf[2] = x->above_pred_buf + 2 * MAX_SB_SQUARE;
+ args.left_pred_buf[0] = x->left_pred_buf;
+ args.left_pred_buf[1] = x->left_pred_buf + MAX_SB_SQUARE;
+ args.left_pred_buf[2] = x->left_pred_buf + 2 * MAX_SB_SQUARE;
#if CONFIG_HIGHBITDEPTH
}
#endif // CONFIG_HIGHBITDEPTH
@@ -9731,11 +8833,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
}
#endif // CONFIG_PALETTE
-#if CONFIG_EXT_INTRA
- memset(directional_mode_skip_mask, 0,
- sizeof(directional_mode_skip_mask[0]) * INTRA_MODES);
-#endif // CONFIG_EXT_INTRA
-
estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
&comp_mode_p);
@@ -9756,9 +8853,9 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
x->pred_mv_sad[ref_frame] = INT_MAX;
x->mbmi_ext->mode_context[ref_frame] = 0;
-#if CONFIG_REF_MV && CONFIG_EXT_INTER
+#if CONFIG_EXT_INTER
x->mbmi_ext->compound_mode_context[ref_frame] = 0;
-#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
+#endif // CONFIG_EXT_INTER
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
@@ -9788,7 +8885,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
#endif // CONFIG_EXT_INTER
}
-#if CONFIG_REF_MV
for (; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
MODE_INFO *const mi = xd->mi[0];
int_mv *const candidates = x->mbmi_ext->ref_mvs[ref_frame];
@@ -9813,10 +8909,10 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
}
}
-#endif // CONFIG_REF_MV
#if CONFIG_MOTION_VAR
av1_count_overlappable_neighbors(cm, xd, mi_row, mi_col);
+
if (check_num_overlappable_neighbors(mbmi) &&
is_motion_variation_allowed_bsize(bsize)) {
av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col,
@@ -9827,8 +8923,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
dst_height2, args.left_pred_stride);
av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
mi_col);
- x->mask_buf = mask2d_buf;
- x->wsrc_buf = weighted_src_buf;
calc_target_weighted_pred(cm, x, xd, mi_row, mi_col, args.above_pred_buf[0],
args.above_pred_stride[0], args.left_pred_buf[0],
args.left_pred_stride[0]);
@@ -9904,10 +8998,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
#if CONFIG_EXT_INTER
if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
- if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
- mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
- if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
- mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
#endif // CONFIG_EXT_INTER
@@ -9931,7 +9021,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
if (sf->adaptive_mode_search) {
if (cm->show_frame && !cpi->rc.is_src_frame_alt_ref &&
cpi->rc.frames_since_golden >= 3)
- if (x->pred_mv_sad[GOLDEN_FRAME] > (x->pred_mv_sad[LAST_FRAME] << 1))
+ if ((x->pred_mv_sad[GOLDEN_FRAME] >> 1) > x->pred_mv_sad[LAST_FRAME])
mode_skip_mask[GOLDEN_FRAME] |= INTER_ALL;
}
@@ -9985,18 +9075,16 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
int64_t this_rd = INT64_MAX;
int disable_skip = 0;
int compmode_cost = 0;
-#if CONFIG_EXT_INTER
- int compmode_interintra_cost = 0;
- int compmode_interinter_cost = 0;
-#endif // CONFIG_EXT_INTER
int rate2 = 0, rate_y = 0, rate_uv = 0;
int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
+#if CONFIG_DAALA_DIST && CONFIG_CB4X4
+ int64_t distortion2_y = 0;
+ int64_t total_sse_y = INT64_MAX;
+#endif
int skippable = 0;
int this_skip2 = 0;
int64_t total_sse = INT64_MAX;
-#if CONFIG_REF_MV
uint8_t ref_frame_type;
-#endif // CONFIG_REF_MV
#if CONFIG_PVQ
od_encode_rollback(&x->daala_enc, &pre_buf);
#endif // CONFIG_PVQ
@@ -10004,9 +9092,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
this_mode = av1_mode_order[mode_index].mode;
ref_frame = av1_mode_order[mode_index].ref_frame[0];
second_ref_frame = av1_mode_order[mode_index].ref_frame[1];
-#if CONFIG_REF_MV
mbmi->ref_mv_idx = 0;
-#endif // CONFIG_REF_MV
#if CONFIG_EXT_INTER
if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
@@ -10079,7 +9165,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
// This is only used in motion vector unit test.
if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
-#if CONFIG_LOWDELAY_COMPOUND // Changes LL bitstream
+#if CONFIG_ONE_SIDED_COMPOUND // Changes LL bitstream
#if CONFIG_EXT_REFS
if (cpi->oxcf.pass == 0) {
// Complexity-compression trade-offs
@@ -10144,9 +9230,9 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
#endif // CONFIG_GLOBAL_MOTION
const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
-#if CONFIG_REF_MV && CONFIG_EXT_INTER
+#if CONFIG_EXT_INTER
mbmi_ext->compound_mode_context,
-#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
+#endif // CONFIG_EXT_INTER
frame_mv, this_mode, ref_frames, bsize, -1,
mi_row, mi_col))
continue;
@@ -10181,9 +9267,9 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
}
-#if CONFIG_EXT_INTER
+#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
-#endif // CONFIG_EXT_INTER
+#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
if (ref_frame == INTRA_FRAME) {
RD_STATS rd_stats_y;
@@ -10199,11 +9285,11 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
const uint8_t *src = x->plane[0].src.buf;
#if CONFIG_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
- highbd_angle_estimation(src, src_stride, rows, cols,
+ highbd_angle_estimation(src, src_stride, rows, cols, bsize,
directional_mode_skip_mask);
else
#endif // CONFIG_HIGHBITDEPTH
- angle_estimation(src, src_stride, rows, cols,
+ angle_estimation(src, src_stride, rows, cols, bsize,
directional_mode_skip_mask);
angle_stats_ready = 1;
}
@@ -10336,18 +9422,19 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
rate2 += intra_cost_penalty;
distortion2 = distortion_y + distortion_uv;
+#if CONFIG_DAALA_DIST && CONFIG_CB4X4
+ if (bsize < BLOCK_8X8) distortion2_y = distortion_y;
+#endif
} else {
-#if CONFIG_REF_MV
int_mv backup_ref_mv[2];
#if !SUB8X8_COMP_REF
- if (bsize < BLOCK_8X8 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
+ if (bsize == BLOCK_4X4 && mbmi->ref_frame[1] > INTRA_FRAME) continue;
#endif // !SUB8X8_COMP_REF
backup_ref_mv[0] = mbmi_ext->ref_mvs[ref_frame][0];
if (comp_pred) backup_ref_mv[1] = mbmi_ext->ref_mvs[second_ref_frame][0];
-#endif // CONFIG_REF_MV
-#if CONFIG_EXT_INTER
+#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
if (second_ref_frame == INTRA_FRAME) {
if (best_single_inter_ref != ref_frame) continue;
mbmi->interintra_mode = intra_to_interintra_mode[best_intra_mode];
@@ -10365,8 +9452,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
#endif // CONFIG_FILTER_INTRA
}
-#endif // CONFIG_EXT_INTER
-#if CONFIG_REF_MV
+#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
mbmi->ref_mv_idx = 0;
ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
@@ -10411,7 +9497,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
#if CONFIG_EXT_INTER
}
#endif // CONFIG_EXT_INTER
-#endif // CONFIG_REF_MV
{
RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
av1_init_rd_stats(&rd_stats);
@@ -10421,18 +9506,11 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
args.single_newmv = single_newmv;
#if CONFIG_EXT_INTER
args.single_newmv_rate = single_newmv_rate;
- args.compmode_interintra_cost = &compmode_interintra_cost;
- args.compmode_interinter_cost = &compmode_interinter_cost;
args.modelled_rd = modelled_rd;
#endif // CONFIG_EXT_INTER
this_rd = handle_inter_mode(cpi, x, bsize, &rd_stats, &rd_stats_y,
&rd_stats_uv, &disable_skip, frame_mv,
mi_row, mi_col, &args, best_rd);
-// Prevent pointers from escaping local scope
-#if CONFIG_EXT_INTER
- args.compmode_interintra_cost = NULL;
- args.compmode_interinter_cost = NULL;
-#endif // CONFIG_EXT_INTER
rate2 = rd_stats.rate;
skippable = rd_stats.skip;
@@ -10440,9 +9518,11 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
total_sse = rd_stats.sse;
rate_y = rd_stats_y.rate;
rate_uv = rd_stats_uv.rate;
+#if CONFIG_DAALA_DIST && CONFIG_CB4X4
+ if (bsize < BLOCK_8X8) distortion2_y = rd_stats_y.dist;
+#endif
}
-#if CONFIG_REF_MV
// TODO(jingning): This needs some refactoring to improve code quality
// and reduce redundant steps.
#if CONFIG_EXT_INTER
@@ -10505,10 +9585,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
int ref;
int_mv cur_mv;
RD_STATS tmp_rd_stats, tmp_rd_stats_y, tmp_rd_stats_uv;
-#if CONFIG_EXT_INTER
- int tmp_compmode_interintra_cost = 0;
- int tmp_compmode_interinter_cost = 0;
-#endif // CONFIG_EXT_INTER
av1_invalid_rd_stats(&tmp_rd_stats);
x->skip = 0;
@@ -10586,8 +9662,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
args.single_newmv = dummy_single_newmv;
#if CONFIG_EXT_INTER
args.single_newmv_rate = dummy_single_newmv_rate;
- args.compmode_interintra_cost = &tmp_compmode_interintra_cost;
- args.compmode_interinter_cost = &tmp_compmode_interinter_cost;
args.modelled_rd = NULL;
#endif // CONFIG_EXT_INTER
tmp_alt_rd = handle_inter_mode(
@@ -10597,8 +9671,6 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
args.single_newmv = NULL;
#if CONFIG_EXT_INTER
args.single_newmv_rate = NULL;
- args.compmode_interintra_cost = NULL;
- args.compmode_interinter_cost = NULL;
#endif // CONFIG_EXT_INTER
}
@@ -10658,15 +9730,17 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
tmp_ref_rd = tmp_alt_rd;
backup_mbmi = *mbmi;
backup_skip = x->skip;
+#if CONFIG_DAALA_DIST && CONFIG_CB4X4
+ if (bsize < BLOCK_8X8) {
+ total_sse_y = tmp_rd_stats_y.sse;
+ distortion2_y = tmp_rd_stats_y.dist;
+ }
+#endif
#if CONFIG_VAR_TX
for (i = 0; i < MAX_MB_PLANE; ++i)
memcpy(x->blk_skip_drl[i], x->blk_skip[i],
sizeof(uint8_t) * ctx->num_4x4_blk);
#endif // CONFIG_VAR_TX
-#if CONFIG_EXT_INTER
- compmode_interintra_cost = tmp_compmode_interintra_cost;
- compmode_interinter_cost = tmp_compmode_interinter_cost;
-#endif // CONFIG_EXT_INTER
} else {
*mbmi = backup_mbmi;
x->skip = backup_skip;
@@ -10684,29 +9758,19 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
}
mbmi_ext->ref_mvs[ref_frame][0] = backup_ref_mv[0];
if (comp_pred) mbmi_ext->ref_mvs[second_ref_frame][0] = backup_ref_mv[1];
-#endif // CONFIG_REF_MV
if (this_rd == INT64_MAX) continue;
#if SUB8X8_COMP_REF
compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
#else
- if (mbmi->sb_type >= BLOCK_8X8)
+ if (mbmi->sb_type != BLOCK_4X4)
compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
#endif // SUB8X8_COMP_REF
if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
}
-#if CONFIG_EXT_INTER
- rate2 += compmode_interintra_cost;
- if (cm->reference_mode != SINGLE_REFERENCE && comp_pred)
-#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
- if (mbmi->motion_mode == SIMPLE_TRANSLATION)
-#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
- rate2 += compmode_interinter_cost;
-#endif // CONFIG_EXT_INTER
-
// Estimate the reference frame signaling cost and add it
// to the rolling cost variable.
if (comp_pred) {
@@ -10731,14 +9795,9 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
// Cost the skip mb case
rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
} else if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
-#if CONFIG_REF_MV
if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv + rate_skip0,
distortion2) <
RDCOST(x->rdmult, x->rddiv, rate_skip1, total_sse)) {
-#else
- if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
- RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
-#endif // CONFIG_REF_MV
// Add in the cost of the no skip flag.
rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
} else {
@@ -10750,6 +9809,9 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
this_skip2 = 1;
rate_y = 0;
rate_uv = 0;
+#if CONFIG_DAALA_DIST && CONFIG_CB4X4
+ if (bsize < BLOCK_8X8) distortion2_y = total_sse_y;
+#endif
}
} else {
// Add in the cost of the no skip flag.
@@ -10775,13 +9837,13 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
best_intra_rd = this_rd;
best_intra_mode = mbmi->mode;
}
-#if CONFIG_EXT_INTER
+#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
} else if (second_ref_frame == NONE_FRAME) {
if (this_rd < best_single_inter_rd) {
best_single_inter_rd = this_rd;
best_single_inter_ref = mbmi->ref_frame[0];
}
-#endif // CONFIG_EXT_INTER
+#endif // CONFIG_EXT_INTER && CONFIG_INTERINTRA
}
if (!disable_skip && ref_frame == INTRA_FRAME) {
@@ -10839,7 +9901,9 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
best_rate_y = rate_y + av1_cost_bit(av1_get_skip_prob(cm, xd),
this_skip2 || skippable);
best_rate_uv = rate_uv;
-
+#if CONFIG_DAALA_DIST && CONFIG_CB4X4
+ if (bsize < BLOCK_8X8) rd_cost->dist_y = distortion2_y;
+#endif
#if CONFIG_VAR_TX
for (i = 0; i < MAX_MB_PLANE; ++i)
memcpy(ctx->blk_skip[i], x->blk_skip[i],
@@ -10900,7 +9964,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
}
if (is_inter_mode(mbmi->mode)) {
- av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
+ av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
#if CONFIG_MOTION_VAR
if (mbmi->motion_mode == OBMC_CAUSAL) {
av1_build_obmc_inter_prediction(
@@ -10967,6 +10031,9 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
rd_cost->rate +=
(rd_stats_y.rate + rd_stats_uv.rate - best_rate_y - best_rate_uv);
rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
+#if CONFIG_DAALA_DIST && CONFIG_CB4X4
+ if (bsize < BLOCK_8X8) rd_cost->dist_y = rd_stats_y.dist;
+#endif
rd_cost->rdcost =
RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
best_skip2 = skip_blk;
@@ -11111,9 +10178,7 @@ PALETTE_EXIT:
best_mbmode.ref_frame[1] };
int comp_pred_mode = refs[1] > INTRA_FRAME;
int_mv zeromv[2];
-#if CONFIG_REF_MV
const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
-#endif // CONFIG_REF_MV
#if CONFIG_GLOBAL_MOTION
zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
cm->allow_high_precision_mv, bsize,
@@ -11129,7 +10194,6 @@ PALETTE_EXIT:
zeromv[0].as_int = 0;
zeromv[1].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
-#if CONFIG_REF_MV
if (!comp_pred_mode) {
int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
? AOMMIN(2, mbmi_ext->ref_mv_count[rf_type] - 2)
@@ -11196,17 +10260,9 @@ PALETTE_EXIT:
nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][i + 1].this_mv;
nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][i + 1].comp_mv;
- // Try switching to the NEAR_NEAREST type modes first
- if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
+ // Try switching to the NEAR_NEARMV mode
+ if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
nearmv[1].as_int == best_mbmode.mv[1].as_int) {
- best_mbmode.mode = NEAREST_NEARMV;
- best_mbmode.ref_mv_idx = i;
- } else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
- nearestmv[1].as_int == best_mbmode.mv[1].as_int) {
- best_mbmode.mode = NEAR_NEARESTMV;
- best_mbmode.ref_mv_idx = i;
- } else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
- nearmv[1].as_int == best_mbmode.mv[1].as_int) {
best_mbmode.mode = NEAR_NEARMV;
best_mbmode.ref_mv_idx = i;
}
@@ -11225,72 +10281,8 @@ PALETTE_EXIT:
}
#endif // CONFIG_EXT_INTER
}
-#else
-#if CONFIG_EXT_INTER
- if (!comp_pred_mode) {
-#endif // CONFIG_EXT_INTER
- if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
- ((comp_pred_mode &&
- frame_mv[NEARESTMV][refs[1]].as_int == best_mbmode.mv[1].as_int) ||
- !comp_pred_mode))
- best_mbmode.mode = NEARESTMV;
- else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
- ((comp_pred_mode &&
- frame_mv[NEARMV][refs[1]].as_int ==
- best_mbmode.mv[1].as_int) ||
- !comp_pred_mode))
- best_mbmode.mode = NEARMV;
- else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
- ((comp_pred_mode &&
- best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
- !comp_pred_mode))
- best_mbmode.mode = ZEROMV;
-#if CONFIG_EXT_INTER
- } else {
-#if CONFIG_GLOBAL_MOTION
- zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
- cm->allow_high_precision_mv,
- bsize, mi_col, mi_row, 0)
- .as_int;
- zeromv[1].as_int = comp_pred_mode
- ? gm_get_motion_vector(&cm->global_motion[refs[1]],
- cm->allow_high_precision_mv,
- bsize, mi_col, mi_row, 0)
- .as_int
- : 0;
-#else
- zeromv[0].as_int = 0;
- zeromv[1].as_int = 0;
-#endif // CONFIG_GLOBAL_MOTION
- if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
- best_mbmode.mv[0].as_int &&
- frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
- best_mbmode.mv[1].as_int)
- best_mbmode.mode = NEAREST_NEARESTMV;
- else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
- best_mbmode.mv[0].as_int &&
- frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
- best_mbmode.mv[1].as_int)
- best_mbmode.mode = NEAREST_NEARMV;
- else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
- best_mbmode.mv[0].as_int &&
- frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
- best_mbmode.mv[1].as_int)
- best_mbmode.mode = NEAR_NEARESTMV;
- else if (frame_mv[NEAR_NEARMV][refs[0]].as_int ==
- best_mbmode.mv[0].as_int &&
- frame_mv[NEAR_NEARMV][refs[1]].as_int ==
- best_mbmode.mv[1].as_int)
- best_mbmode.mode = NEAR_NEARMV;
- else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
- best_mbmode.mv[1].as_int == zeromv[1].as_int)
- best_mbmode.mode = ZERO_ZEROMV;
- }
-#endif // CONFIG_EXT_INTER
-#endif // CONFIG_REF_MV
}
-#if CONFIG_REF_MV
// Make sure that the ref_mv_idx is only nonzero when we're
// using a mode which can support ref_mv_idx
if (best_mbmode.ref_mv_idx != 0 &&
@@ -11339,7 +10331,6 @@ PALETTE_EXIT:
}
}
}
-#endif // CONFIG_REF_MV
if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
rd_cost->rate = INT_MAX;
@@ -11412,14 +10403,12 @@ PALETTE_EXIT:
}
#endif // CONFIG_GLOBAL_MOTION
-#if CONFIG_REF_MV
for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
if (mbmi->mode != NEWMV)
mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int;
else
mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[mbmi->ref_frame[i]][0].as_int;
}
-#endif // CONFIG_REF_MV
for (i = 0; i < REFERENCE_MODES; ++i) {
if (best_pred_rd[i] == INT64_MAX)
@@ -11502,10 +10491,8 @@ void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
mbmi->tx_size = max_txsize_lookup[bsize];
x->skip = 1;
-#if CONFIG_REF_MV
mbmi->ref_mv_idx = 0;
mbmi->pred_mv[0].as_int = 0;
-#endif // CONFIG_REF_MV
mbmi->motion_mode = SIMPLE_TRANSLATION;
#if CONFIG_MOTION_VAR
@@ -11566,7 +10553,9 @@ void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
rd_cost->rate = rate2;
rd_cost->dist = distortion2;
rd_cost->rdcost = this_rd;
-
+#if CONFIG_DAALA_DIST && CONFIG_CB4X4
+ if (bsize < BLOCK_8X8) rd_cost->dist_y = distortion2;
+#endif
if (this_rd >= best_rd_so_far) {
rd_cost->rate = INT_MAX;
rd_cost->rdcost = INT64_MAX;
@@ -11589,791 +10578,6 @@ void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
store_coding_context(x, ctx, THR_ZEROMV, best_pred_diff, 0);
}
-void av1_rd_pick_inter_mode_sub8x8(const struct AV1_COMP *cpi,
- TileDataEnc *tile_data, struct macroblock *x,
- int mi_row, int mi_col,
- struct RD_STATS *rd_cost,
-#if CONFIG_SUPERTX
- int *returnrate_nocoef,
-#endif // CONFIG_SUPERTX
- BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
- int64_t best_rd_so_far) {
- const AV1_COMMON *const cm = &cpi->common;
- const RD_OPT *const rd_opt = &cpi->rd;
- const SPEED_FEATURES *const sf = &cpi->sf;
- MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
- const struct segmentation *const seg = &cm->seg;
- MV_REFERENCE_FRAME ref_frame, second_ref_frame;
- unsigned char segment_id = mbmi->segment_id;
- int comp_pred, i;
- int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME];
- struct buf_2d yv12_mb[TOTAL_REFS_PER_FRAME][MAX_MB_PLANE];
- static const int flag_list[TOTAL_REFS_PER_FRAME] = {
- 0,
- AOM_LAST_FLAG,
-#if CONFIG_EXT_REFS
- AOM_LAST2_FLAG,
- AOM_LAST3_FLAG,
-#endif // CONFIG_EXT_REFS
- AOM_GOLD_FLAG,
-#if CONFIG_EXT_REFS
- AOM_BWD_FLAG,
-#endif // CONFIG_EXT_REFS
- AOM_ALT_FLAG
- };
- int64_t best_rd = best_rd_so_far;
- int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
- int64_t best_pred_diff[REFERENCE_MODES];
- int64_t best_pred_rd[REFERENCE_MODES];
- MB_MODE_INFO best_mbmode;
- int ref_index, best_ref_index = 0;
- unsigned int ref_costs_single[TOTAL_REFS_PER_FRAME];
- unsigned int ref_costs_comp[TOTAL_REFS_PER_FRAME];
- aom_prob comp_mode_p;
-#if CONFIG_DUAL_FILTER
- InterpFilter tmp_best_filter[4] = { 0 };
-#else
- InterpFilter tmp_best_filter = SWITCHABLE;
-#endif // CONFIG_DUAL_FILTER
- int rate_uv_intra, rate_uv_tokenonly = INT_MAX;
- int64_t dist_uv = INT64_MAX;
- int skip_uv;
- PREDICTION_MODE mode_uv = DC_PRED;
- const int intra_cost_penalty = av1_get_intra_cost_penalty(
- cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
- int_mv seg_mvs[4][TOTAL_REFS_PER_FRAME];
- b_mode_info best_bmodes[4];
- int best_skip2 = 0;
- int ref_frame_skip_mask[2] = { 0 };
- int internal_active_edge =
- av1_active_edge_sb(cpi, mi_row, mi_col) && av1_internal_image_edge(cpi);
-#if CONFIG_PVQ
- od_rollback_buffer pre_buf;
-
- od_encode_checkpoint(&x->daala_enc, &pre_buf);
-#endif // CONFIG_PVQ
-
-#if CONFIG_SUPERTX
- best_rd_so_far = INT64_MAX;
- best_rd = best_rd_so_far;
- best_yrd = best_rd_so_far;
-#endif // CONFIG_SUPERTX
- av1_zero(best_mbmode);
-
-#if CONFIG_FILTER_INTRA
- mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
- mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
-#endif // CONFIG_FILTER_INTRA
- mbmi->motion_mode = SIMPLE_TRANSLATION;
-#if CONFIG_EXT_INTER
- mbmi->interinter_compound_type = COMPOUND_AVERAGE;
- mbmi->use_wedge_interintra = 0;
-#endif // CONFIG_EXT_INTER
-#if CONFIG_WARPED_MOTION
- mbmi->num_proj_ref[0] = 0;
- mbmi->num_proj_ref[1] = 0;
-#endif // CONFIG_WARPED_MOTION
-
- for (i = 0; i < 4; i++) {
- int j;
- for (j = 0; j < TOTAL_REFS_PER_FRAME; j++)
- seg_mvs[i][j].as_int = INVALID_MV;
- }
-
- estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
- &comp_mode_p);
-
- for (i = 0; i < REFERENCE_MODES; ++i) best_pred_rd[i] = INT64_MAX;
- rate_uv_intra = INT_MAX;
-
- rd_cost->rate = INT_MAX;
-#if CONFIG_SUPERTX
- *returnrate_nocoef = INT_MAX;
-#endif // CONFIG_SUPERTX
-
- for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
- x->mbmi_ext->mode_context[ref_frame] = 0;
-#if CONFIG_REF_MV && CONFIG_EXT_INTER
- x->mbmi_ext->compound_mode_context[ref_frame] = 0;
-#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
- if (cpi->ref_frame_flags & flag_list[ref_frame]) {
- setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
- frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
- } else {
- ref_frame_skip_mask[0] |= (1 << ref_frame);
- ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
- }
- frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
-#if CONFIG_EXT_INTER
-#endif // CONFIG_EXT_INTER
- frame_mv[ZEROMV][ref_frame].as_int = 0;
- }
-
-#if CONFIG_PALETTE
- mbmi->palette_mode_info.palette_size[0] = 0;
- mbmi->palette_mode_info.palette_size[1] = 0;
-#endif // CONFIG_PALETTE
-
- for (ref_index = 0; ref_index < MAX_REFS; ++ref_index) {
- int mode_excluded = 0;
- int64_t this_rd = INT64_MAX;
- int disable_skip = 0;
- int compmode_cost = 0;
- int rate2 = 0, rate_y = 0, rate_uv = 0;
- int64_t distortion2 = 0, distortion_y = 0, distortion_uv = 0;
- int skippable = 0;
- int this_skip2 = 0;
- int64_t total_sse = INT_MAX;
-
-#if CONFIG_PVQ
- od_encode_rollback(&x->daala_enc, &pre_buf);
-#endif // CONFIG_PVQ
-
- ref_frame = av1_ref_order[ref_index].ref_frame[0];
- second_ref_frame = av1_ref_order[ref_index].ref_frame[1];
-
-#if CONFIG_REF_MV
- mbmi->ref_mv_idx = 0;
-#endif // CONFIG_REF_MV
-
- // Look at the reference frame of the best mode so far and set the
- // skip mask to look at a subset of the remaining modes.
- if (ref_index > 2 && sf->mode_skip_start < MAX_MODES) {
- if (ref_index == 3) {
- switch (best_mbmode.ref_frame[0]) {
- case INTRA_FRAME: break;
- case LAST_FRAME:
- ref_frame_skip_mask[0] |= (1 << GOLDEN_FRAME) |
-#if CONFIG_EXT_REFS
- (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
- (1 << BWDREF_FRAME) |
-#endif // CONFIG_EXT_REFS
- (1 << ALTREF_FRAME);
- ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
- break;
-#if CONFIG_EXT_REFS
- case LAST2_FRAME:
- ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST3_FRAME) |
- (1 << GOLDEN_FRAME) |
- (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
- ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
- break;
- case LAST3_FRAME:
- ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
- (1 << GOLDEN_FRAME) |
- (1 << BWDREF_FRAME) | (1 << ALTREF_FRAME);
- ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
- break;
-#endif // CONFIG_EXT_REFS
- case GOLDEN_FRAME:
- ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
-#if CONFIG_EXT_REFS
- (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
- (1 << BWDREF_FRAME) |
-#endif // CONFIG_EXT_REFS
- (1 << ALTREF_FRAME);
- ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK;
- break;
-#if CONFIG_EXT_REFS
- case BWDREF_FRAME:
- ref_frame_skip_mask[0] |= (1 << LAST_FRAME) | (1 << LAST2_FRAME) |
- (1 << LAST3_FRAME) | (1 << GOLDEN_FRAME) |
- (1 << ALTREF_FRAME);
- ref_frame_skip_mask[1] |= (1 << ALTREF_FRAME) | 0x01;
- break;
-#endif // CONFIG_EXT_REFS
- case ALTREF_FRAME:
- ref_frame_skip_mask[0] |= (1 << LAST_FRAME) |
-#if CONFIG_EXT_REFS
- (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
- (1 << BWDREF_FRAME) |
-#endif // CONFIG_EXT_REFS
- (1 << GOLDEN_FRAME);
-#if CONFIG_EXT_REFS
- ref_frame_skip_mask[1] |= (1 << BWDREF_FRAME) | 0x01;
-#endif // CONFIG_EXT_REFS
- break;
- case NONE_FRAME:
- case TOTAL_REFS_PER_FRAME:
- assert(0 && "Invalid Reference frame");
- break;
- }
- }
- }
-
- if ((ref_frame_skip_mask[0] & (1 << ref_frame)) &&
- (ref_frame_skip_mask[1] & (1 << AOMMAX(0, second_ref_frame))))
- continue;
-
- // Test best rd so far against threshold for trying this mode.
- if (!internal_active_edge &&
- rd_less_than_thresh(best_rd,
- rd_opt->threshes[segment_id][bsize][ref_index],
- tile_data->thresh_freq_fact[bsize][ref_index]))
- continue;
-
- // This is only used in motion vector unit test.
- if (cpi->oxcf.motion_vector_unit_test && ref_frame == INTRA_FRAME) continue;
-
-#if CONFIG_LOWDELAY_COMPOUND // Changes LL bitstream
-#if CONFIG_EXT_REFS
- if (cpi->oxcf.pass == 0) {
- // Complexity-compression trade-offs
- // if (ref_frame == ALTREF_FRAME) continue;
- // if (ref_frame == BWDREF_FRAME) continue;
- if (second_ref_frame == ALTREF_FRAME) continue;
- // if (second_ref_frame == BWDREF_FRAME) continue;
- }
-#endif
-#endif
- comp_pred = second_ref_frame > INTRA_FRAME;
- if (comp_pred) {
- if (!cpi->allow_comp_inter_inter) continue;
- if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) continue;
- // Do not allow compound prediction if the segment level reference frame
- // feature is in use as in this case there can only be one reference.
- if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) continue;
-
- if ((sf->mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
- best_mbmode.ref_frame[0] == INTRA_FRAME)
- continue;
- }
-
- // TODO(jingning, jkoleszar): scaling reference frame not supported for
- // sub8x8 blocks.
- if (ref_frame > INTRA_FRAME &&
- av1_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
- continue;
-
- if (second_ref_frame > INTRA_FRAME &&
- av1_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
- continue;
-
- if (comp_pred)
- mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
- else if (ref_frame != INTRA_FRAME)
- mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
-
- // If the segment reference frame feature is enabled....
- // then do nothing if the current ref frame is not allowed..
- if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
- get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
- continue;
- // Disable this drop out case if the ref frame
- // segment level feature is enabled for this segment. This is to
- // prevent the possibility that we end up unable to pick any mode.
- } else if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
- // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
- // unless ARNR filtering is enabled in which case we want
- // an unfiltered alternative. We allow near/nearest as well
- // because they may result in zero-zero MVs but be cheaper.
- if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0))
- continue;
- }
-
- mbmi->tx_size = TX_4X4;
- mbmi->uv_mode = DC_PRED;
- mbmi->ref_frame[0] = ref_frame;
- mbmi->ref_frame[1] = second_ref_frame;
-// Evaluate all sub-pel filters irrespective of whether we can use
-// them for this frame.
-#if CONFIG_DUAL_FILTER
- for (i = 0; i < 4; ++i)
- mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE
- ? EIGHTTAP_REGULAR
- : cm->interp_filter;
-#else
- mbmi->interp_filter =
- cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR : cm->interp_filter;
-#endif // CONFIG_DUAL_FILTER
- x->skip = 0;
- set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
-
- // Select prediction reference frames.
- for (i = 0; i < MAX_MB_PLANE; i++) {
- xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
- if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
- }
-
-#if CONFIG_VAR_TX
- mbmi->inter_tx_size[0][0] = mbmi->tx_size;
- mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
-#endif // CONFIG_VAR_TX
-
- if (ref_frame == INTRA_FRAME) {
- int rate;
- if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y, &distortion_y,
- NULL, best_rd) >= best_rd)
- continue;
- rate2 += rate;
- rate2 += intra_cost_penalty;
- distortion2 += distortion_y;
-
- if (rate_uv_intra == INT_MAX) {
- choose_intra_uv_mode(cpi, x, ctx, bsize, TX_4X4, &rate_uv_intra,
- &rate_uv_tokenonly, &dist_uv, &skip_uv, &mode_uv);
- }
- rate2 += rate_uv_intra;
- rate_uv = rate_uv_tokenonly;
- distortion2 += dist_uv;
- distortion_uv = dist_uv;
- mbmi->uv_mode = mode_uv;
- } else {
- int rate;
- int64_t distortion;
- int64_t this_rd_thresh;
- int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX;
- int tmp_best_rate = INT_MAX, tmp_best_ratey = INT_MAX;
- int64_t tmp_best_distortion = INT_MAX, tmp_best_sse, uv_sse;
- int tmp_best_skippable = 0;
- int switchable_filter_index;
- int_mv *second_ref =
- comp_pred ? &x->mbmi_ext->ref_mvs[second_ref_frame][0] : NULL;
- b_mode_info tmp_best_bmodes[16]; // Should this be 4 ?
- MB_MODE_INFO tmp_best_mbmode;
-#if CONFIG_DUAL_FILTER
- BEST_SEG_INFO bsi[DUAL_FILTER_SET_SIZE];
-#else
- BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
-#endif // CONFIG_DUAL_FILTER
- int pred_exists = 0;
- int uv_skippable;
-#if CONFIG_EXT_INTER
- int_mv compound_seg_newmvs[4][2];
- for (i = 0; i < 4; i++) {
- compound_seg_newmvs[i][0].as_int = INVALID_MV;
- compound_seg_newmvs[i][1].as_int = INVALID_MV;
- }
-#endif // CONFIG_EXT_INTER
-
- this_rd_thresh = (ref_frame == LAST_FRAME)
- ? rd_opt->threshes[segment_id][bsize][THR_LAST]
- : rd_opt->threshes[segment_id][bsize][THR_ALTR];
-#if CONFIG_EXT_REFS
- this_rd_thresh = (ref_frame == LAST2_FRAME)
- ? rd_opt->threshes[segment_id][bsize][THR_LAST2]
- : this_rd_thresh;
- this_rd_thresh = (ref_frame == LAST3_FRAME)
- ? rd_opt->threshes[segment_id][bsize][THR_LAST3]
- : this_rd_thresh;
- this_rd_thresh = (ref_frame == BWDREF_FRAME)
- ? rd_opt->threshes[segment_id][bsize][THR_BWDR]
- : this_rd_thresh;
-#endif // CONFIG_EXT_REFS
- this_rd_thresh = (ref_frame == GOLDEN_FRAME)
- ? rd_opt->threshes[segment_id][bsize][THR_GOLD]
- : this_rd_thresh;
-
- // TODO(any): Add search of the tx_type to improve rd performance at the
- // expense of speed.
- mbmi->tx_type = DCT_DCT;
-
- if (cm->interp_filter != BILINEAR) {
-#if CONFIG_DUAL_FILTER
- tmp_best_filter[0] = EIGHTTAP_REGULAR;
- tmp_best_filter[1] = EIGHTTAP_REGULAR;
- tmp_best_filter[2] = EIGHTTAP_REGULAR;
- tmp_best_filter[3] = EIGHTTAP_REGULAR;
-#else
- tmp_best_filter = EIGHTTAP_REGULAR;
-#endif // CONFIG_DUAL_FILTER
- if (x->source_variance < sf->disable_filter_search_var_thresh) {
-#if CONFIG_DUAL_FILTER
- tmp_best_filter[0] = EIGHTTAP_REGULAR;
-#else
- tmp_best_filter = EIGHTTAP_REGULAR;
-#endif // CONFIG_DUAL_FILTER
- } else if (sf->adaptive_pred_interp_filter == 1 &&
- ctx->pred_interp_filter < SWITCHABLE) {
-#if CONFIG_DUAL_FILTER
- tmp_best_filter[0] = ctx->pred_interp_filter;
-#else
- tmp_best_filter = ctx->pred_interp_filter;
-#endif // CONFIG_DUAL_FILTER
- } else if (sf->adaptive_pred_interp_filter == 2) {
-#if CONFIG_DUAL_FILTER
- tmp_best_filter[0] = ctx->pred_interp_filter < SWITCHABLE
- ? ctx->pred_interp_filter
- : 0;
-#else
- tmp_best_filter = ctx->pred_interp_filter < SWITCHABLE
- ? ctx->pred_interp_filter
- : 0;
-#endif // CONFIG_DUAL_FILTER
- } else {
-#if CONFIG_DUAL_FILTER
- const int filter_set_size = DUAL_FILTER_SET_SIZE;
-#else
- const int filter_set_size = SWITCHABLE_FILTERS;
-#endif // CONFIG_DUAL_FILTER
- for (switchable_filter_index = 0;
- switchable_filter_index < filter_set_size;
- ++switchable_filter_index) {
- int newbest, rs;
- int64_t rs_rd;
- MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
-#if CONFIG_DUAL_FILTER
- mbmi->interp_filter[0] = filter_sets[switchable_filter_index][0];
- mbmi->interp_filter[1] = filter_sets[switchable_filter_index][1];
- mbmi->interp_filter[2] = filter_sets[switchable_filter_index][0];
- mbmi->interp_filter[3] = filter_sets[switchable_filter_index][1];
-#else
- mbmi->interp_filter = switchable_filter_index;
-#endif // CONFIG_DUAL_FILTER
- tmp_rd = rd_pick_inter_best_sub8x8_mode(
- cpi, x, &mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
- &rate, &rate_y, &distortion, &skippable, &total_sse,
- (int)this_rd_thresh, seg_mvs,
-#if CONFIG_EXT_INTER
- compound_seg_newmvs,
-#endif // CONFIG_EXT_INTER
- bsi, switchable_filter_index, mi_row, mi_col);
- if (tmp_rd == INT64_MAX) continue;
- rs = av1_get_switchable_rate(cpi, xd);
- rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
- if (cm->interp_filter == SWITCHABLE) tmp_rd += rs_rd;
-
- newbest = (tmp_rd < tmp_best_rd);
- if (newbest) {
-#if CONFIG_DUAL_FILTER
- tmp_best_filter[0] = mbmi->interp_filter[0];
- tmp_best_filter[1] = mbmi->interp_filter[1];
- tmp_best_filter[2] = mbmi->interp_filter[2];
- tmp_best_filter[3] = mbmi->interp_filter[3];
-#else
- tmp_best_filter = mbmi->interp_filter;
-#endif // CONFIG_DUAL_FILTER
- tmp_best_rd = tmp_rd;
- }
- if ((newbest && cm->interp_filter == SWITCHABLE) ||
- (
-#if CONFIG_DUAL_FILTER
- mbmi->interp_filter[0] == cm->interp_filter
-#else
- mbmi->interp_filter == cm->interp_filter
-#endif // CONFIG_DUAL_FILTER
- && cm->interp_filter != SWITCHABLE)) {
- tmp_best_rdu = tmp_rd;
- tmp_best_rate = rate;
- tmp_best_ratey = rate_y;
- tmp_best_distortion = distortion;
- tmp_best_sse = total_sse;
- tmp_best_skippable = skippable;
- tmp_best_mbmode = *mbmi;
- for (i = 0; i < 4; i++) {
- tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
- }
- pred_exists = 1;
- }
- } // switchable_filter_index loop
- }
- }
-
- if (tmp_best_rdu == INT64_MAX && pred_exists) continue;
-
-#if CONFIG_DUAL_FILTER
- mbmi->interp_filter[0] =
- (cm->interp_filter == SWITCHABLE ? tmp_best_filter[0]
- : cm->interp_filter);
- mbmi->interp_filter[1] =
- (cm->interp_filter == SWITCHABLE ? tmp_best_filter[1]
- : cm->interp_filter);
- mbmi->interp_filter[2] =
- (cm->interp_filter == SWITCHABLE ? tmp_best_filter[2]
- : cm->interp_filter);
- mbmi->interp_filter[3] =
- (cm->interp_filter == SWITCHABLE ? tmp_best_filter[3]
- : cm->interp_filter);
-#else
- mbmi->interp_filter =
- (cm->interp_filter == SWITCHABLE ? tmp_best_filter
- : cm->interp_filter);
-#endif // CONFIG_DUAL_FILTER
-
- if (!pred_exists) {
- // Handles the special case when a filter that is not in the
- // switchable list (bilinear) is indicated at the frame level
- tmp_rd = rd_pick_inter_best_sub8x8_mode(
- cpi, x, &x->mbmi_ext->ref_mvs[ref_frame][0], second_ref, best_yrd,
- &rate, &rate_y, &distortion, &skippable, &total_sse,
- (int)this_rd_thresh, seg_mvs,
-#if CONFIG_EXT_INTER
- compound_seg_newmvs,
-#endif // CONFIG_EXT_INTER
- bsi, 0, mi_row, mi_col);
- if (tmp_rd == INT64_MAX) continue;
- } else {
- total_sse = tmp_best_sse;
- rate = tmp_best_rate;
- rate_y = tmp_best_ratey;
- distortion = tmp_best_distortion;
- skippable = tmp_best_skippable;
- *mbmi = tmp_best_mbmode;
- for (i = 0; i < 4; i++) xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
- }
- // Add in the cost of the transform type
- if (!xd->lossless[mbmi->segment_id]) {
- int rate_tx_type = 0;
-#if CONFIG_EXT_TX
- if (get_ext_tx_types(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used) >
- 1) {
- const int eset =
- get_ext_tx_set(mbmi->tx_size, bsize, 1, cm->reduced_tx_set_used);
- rate_tx_type =
- cpi->inter_tx_type_costs[eset][mbmi->tx_size][mbmi->tx_type];
- }
-#else
- if (mbmi->tx_size < TX_32X32) {
- rate_tx_type = cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
- }
-#endif // CONFIG_EXT_TX
- rate += rate_tx_type;
- rate_y += rate_tx_type;
- }
-
- rate2 += rate;
- distortion2 += distortion;
-
- if (cm->interp_filter == SWITCHABLE)
- rate2 += av1_get_switchable_rate(cpi, xd);
-
- if (!mode_excluded)
- mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
- : cm->reference_mode == COMPOUND_REFERENCE;
-
- compmode_cost = av1_cost_bit(comp_mode_p, comp_pred);
-
- tmp_best_rdu =
- best_rd - AOMMIN(RDCOST(x->rdmult, x->rddiv, rate2, distortion2),
- RDCOST(x->rdmult, x->rddiv, 0, total_sse));
-
- if (tmp_best_rdu > 0) {
- // If even the 'Y' rd value of split is higher than best so far
- // then dont bother looking at UV
- int is_cost_valid_uv;
- RD_STATS rd_stats_uv;
- av1_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, NULL,
- BLOCK_8X8);
-#if CONFIG_VAR_TX
- is_cost_valid_uv =
- inter_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
-#else
- is_cost_valid_uv =
- super_block_uvrd(cpi, x, &rd_stats_uv, BLOCK_8X8, tmp_best_rdu);
-#endif // CONFIG_VAR_TX
- rate_uv = rd_stats_uv.rate;
- distortion_uv = rd_stats_uv.dist;
- uv_skippable = rd_stats_uv.skip;
- uv_sse = rd_stats_uv.sse;
-
- if (!is_cost_valid_uv) continue;
- rate2 += rate_uv;
- distortion2 += distortion_uv;
- skippable = skippable && uv_skippable;
- total_sse += uv_sse;
- } else {
- continue;
- }
- }
-
- if (cm->reference_mode == REFERENCE_MODE_SELECT) rate2 += compmode_cost;
-
- // Estimate the reference frame signaling cost and add it
- // to the rolling cost variable.
- if (second_ref_frame > INTRA_FRAME) {
- rate2 += ref_costs_comp[ref_frame];
-#if CONFIG_EXT_REFS
- rate2 += ref_costs_comp[second_ref_frame];
-#endif // CONFIG_EXT_REFS
- } else {
- rate2 += ref_costs_single[ref_frame];
- }
-
- if (!disable_skip) {
- // Skip is never coded at the segment level for sub8x8 blocks and instead
- // always coded in the bitstream at the mode info level.
-
- if (ref_frame != INTRA_FRAME && !xd->lossless[mbmi->segment_id]) {
- if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
- RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
- // Add in the cost of the no skip flag.
- rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
- } else {
- // FIXME(rbultje) make this work for splitmv also
- rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
- distortion2 = total_sse;
- assert(total_sse >= 0);
- rate2 -= (rate_y + rate_uv);
- rate_y = 0;
- rate_uv = 0;
- this_skip2 = 1;
- }
- } else {
- // Add in the cost of the no skip flag.
- rate2 += av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
- }
-
- // Calculate the final RD estimate for this mode.
- this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
- }
-
- if (!disable_skip && ref_frame == INTRA_FRAME) {
- for (i = 0; i < REFERENCE_MODES; ++i)
- best_pred_rd[i] = AOMMIN(best_pred_rd[i], this_rd);
- }
-
- // Did this mode help.. i.e. is it the new best mode
- if (this_rd < best_rd || x->skip) {
- if (!mode_excluded) {
- // Note index of best mode so far
- best_ref_index = ref_index;
-
- if (ref_frame == INTRA_FRAME) {
- /* required for left and above block mv */
- mbmi->mv[0].as_int = 0;
- }
-
- rd_cost->rate = rate2;
-#if CONFIG_SUPERTX
- *returnrate_nocoef = rate2 - rate_y - rate_uv;
- if (!disable_skip)
- *returnrate_nocoef -=
- av1_cost_bit(av1_get_skip_prob(cm, xd), this_skip2);
- *returnrate_nocoef -= av1_cost_bit(av1_get_intra_inter_prob(cm, xd),
- mbmi->ref_frame[0] != INTRA_FRAME);
- assert(*returnrate_nocoef > 0);
-#endif // CONFIG_SUPERTX
- rd_cost->dist = distortion2;
- rd_cost->rdcost = this_rd;
- best_rd = this_rd;
- best_yrd =
- best_rd - RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
- best_mbmode = *mbmi;
- best_skip2 = this_skip2;
-
-#if CONFIG_VAR_TX
- for (i = 0; i < MAX_MB_PLANE; ++i)
- memset(ctx->blk_skip[i], 0, sizeof(uint8_t) * ctx->num_4x4_blk);
-#endif // CONFIG_VAR_TX
-
- for (i = 0; i < 4; i++) best_bmodes[i] = xd->mi[0]->bmi[i];
- }
- }
-
- /* keep record of best compound/single-only prediction */
- if (!disable_skip && ref_frame != INTRA_FRAME) {
- int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
-
- if (cm->reference_mode == REFERENCE_MODE_SELECT) {
- single_rate = rate2 - compmode_cost;
- hybrid_rate = rate2;
- } else {
- single_rate = rate2;
- hybrid_rate = rate2 + compmode_cost;
- }
-
- single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
- hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
-
- if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE])
- best_pred_rd[SINGLE_REFERENCE] = single_rd;
- else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE])
- best_pred_rd[COMPOUND_REFERENCE] = single_rd;
-
- if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
- best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
- }
-
- if (x->skip && !comp_pred) break;
- }
-
- if (best_rd >= best_rd_so_far) {
- rd_cost->rate = INT_MAX;
- rd_cost->rdcost = INT64_MAX;
-#if CONFIG_SUPERTX
- *returnrate_nocoef = INT_MAX;
-#endif // CONFIG_SUPERTX
- return;
- }
-
- if (best_rd == INT64_MAX) {
- rd_cost->rate = INT_MAX;
- rd_cost->dist = INT64_MAX;
- rd_cost->rdcost = INT64_MAX;
-#if CONFIG_SUPERTX
- *returnrate_nocoef = INT_MAX;
-#endif // CONFIG_SUPERTX
- return;
- }
-
-#if CONFIG_DUAL_FILTER
- assert((cm->interp_filter == SWITCHABLE) ||
- (cm->interp_filter == best_mbmode.interp_filter[0]) ||
- !is_inter_block(&best_mbmode));
-#else
- assert((cm->interp_filter == SWITCHABLE) ||
- (cm->interp_filter == best_mbmode.interp_filter) ||
- !is_inter_block(&best_mbmode));
-#endif // CONFIG_DUAL_FILTER
-
- av1_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
- sf->adaptive_rd_thresh, bsize, best_ref_index);
-
- // macroblock modes
- *mbmi = best_mbmode;
-#if CONFIG_VAR_TX
- mbmi->inter_tx_size[0][0] = mbmi->tx_size;
-#endif // CONFIG_VAR_TX
-
- x->skip |= best_skip2;
- if (!is_inter_block(&best_mbmode)) {
- for (i = 0; i < 4; i++) xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
- } else {
- for (i = 0; i < 4; ++i)
- memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
-
-#if CONFIG_REF_MV
- mbmi->pred_mv[0].as_int = xd->mi[0]->bmi[3].pred_mv[0].as_int;
- mbmi->pred_mv[1].as_int = xd->mi[0]->bmi[3].pred_mv[1].as_int;
-#endif // CONFIG_REF_MV
- mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
- mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
- }
-
-// Note: this section is needed since the mode may have been forced to ZEROMV
-#if CONFIG_GLOBAL_MOTION
- if (mbmi->mode == ZEROMV
-#if CONFIG_EXT_INTER
- || mbmi->mode == ZERO_ZEROMV
-#endif // CONFIG_EXT_INTER
- ) {
- if (is_nontrans_global_motion(xd)) {
-#if CONFIG_DUAL_FILTER
- mbmi->interp_filter[0] = cm->interp_filter == SWITCHABLE
- ? EIGHTTAP_REGULAR
- : cm->interp_filter;
- mbmi->interp_filter[1] = cm->interp_filter == SWITCHABLE
- ? EIGHTTAP_REGULAR
- : cm->interp_filter;
-#else
- mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
- : cm->interp_filter;
-#endif // CONFIG_DUAL_FILTER
- }
- }
-#endif // CONFIG_GLOBAL_MOTION
-
- for (i = 0; i < REFERENCE_MODES; ++i) {
- if (best_pred_rd[i] == INT64_MAX)
- best_pred_diff[i] = INT_MIN;
- else
- best_pred_diff[i] = best_rd - best_pred_rd[i];
- }
-
- store_coding_context(x, ctx, best_ref_index, best_pred_diff, 0);
-}
-
#if CONFIG_MOTION_VAR
// This function has a structure similar to av1_build_obmc_inter_prediction
//
@@ -12454,9 +10658,14 @@ static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
i = 0;
do { // for each mi in the above row
const int mi_col_offset = i;
- const MB_MODE_INFO *const above_mbmi =
+ const MB_MODE_INFO *above_mbmi =
&xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
- const BLOCK_SIZE a_bsize = above_mbmi->sb_type;
+#if CONFIG_CHROMA_SUB8X8
+ if (above_mbmi->sb_type < BLOCK_8X8)
+ above_mbmi =
+ &xd->mi[mi_col_offset + 1 + mi_row_offset * xd->mi_stride]->mbmi;
+#endif
+ const BLOCK_SIZE a_bsize = AOMMAX(above_mbmi->sb_type, BLOCK_8X8);
const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[a_bsize]);
const int neighbor_bw = mi_step * MI_SIZE;
@@ -12528,9 +10737,15 @@ static void calc_target_weighted_pred(const AV1_COMMON *cm, const MACROBLOCK *x,
i = 0;
do { // for each mi in the left column
const int mi_row_offset = i;
- const MB_MODE_INFO *const left_mbmi =
+ MB_MODE_INFO *left_mbmi =
&xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
- const BLOCK_SIZE l_bsize = left_mbmi->sb_type;
+
+#if CONFIG_CHROMA_SUB8X8
+ if (left_mbmi->sb_type < BLOCK_8X8)
+ left_mbmi =
+ &xd->mi[mi_col_offset + (mi_row_offset + 1) * xd->mi_stride]->mbmi;
+#endif
+ const BLOCK_SIZE l_bsize = AOMMAX(left_mbmi->sb_type, BLOCK_8X8);
const int mi_step = AOMMIN(xd->n8_h, mi_size_high[l_bsize]);
const int neighbor_bh = mi_step * MI_SIZE;
@@ -12636,7 +10851,7 @@ void av1_check_ncobmc_rd(const struct AV1_COMP *cpi, struct macroblock *x,
av1_setup_dst_planes(x->e_mbd.plane, bsize,
get_frame_new_buffer(&cpi->common), mi_row, mi_col);
- av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, bsize);
+ av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
av1_subtract_plane(x, bsize, 0);
super_block_yrd(cpi, x, &rd_stats_y, bsize, INT64_MAX);