Port interintra experiment from nextgen.
The interintra experiment, which combines an inter prediction and an
inter prediction have been ported from the nextgen branch. The
experiment is merged into ext_inter, so there is no separate configure
option to enable it.
Change-Id: I0cc20cefd29e9b77ab7bbbb709abc11512320325
diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c
index 7134672..6385f2f 100644
--- a/vp10/encoder/bitstream.c
+++ b/vp10/encoder/bitstream.c
@@ -1028,7 +1028,7 @@
#endif // CONFIG_EXT_INTER
write_inter_mode(cm, w, mode,
#if CONFIG_REF_MV && CONFIG_EXT_INTER
- has_second_ref(mbmi),
+ is_compound,
#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
mode_ctx);
@@ -1163,6 +1163,22 @@
}
}
+#if CONFIG_EXT_INTER
+ if (cpi->common.reference_mode != COMPOUND_REFERENCE &&
+#if CONFIG_SUPERTX
+ !supertx_enabled &&
+#endif // CONFIG_SUPERTX
+ is_interintra_allowed(mbmi)) {
+ const int interintra = mbmi->ref_frame[1] == INTRA_FRAME;
+ vpx_write(w, interintra, cm->fc->interintra_prob[bsize]);
+ if (interintra) {
+ write_intra_mode(w, mbmi->interintra_mode,
+ cm->fc->y_mode_prob[size_group_lookup[bsize]]);
+ assert(mbmi->interintra_mode == mbmi->interintra_uv_mode);
+ }
+ }
+#endif // CONFIG_EXT_INTER
+
#if CONFIG_EXT_INTERP
write_switchable_interp_filter(cpi, xd, w);
#endif // CONFIG_EXT_INTERP
@@ -2444,6 +2460,16 @@
#if CONFIG_EXT_INTER
update_inter_compound_mode_probs(cm, &header_bc);
+
+ if (cm->reference_mode != COMPOUND_REFERENCE) {
+ for (i = 0; i < BLOCK_SIZES; i++) {
+ if (is_interintra_allowed_bsize(i)) {
+ vp10_cond_prob_diff_update(&header_bc,
+ &fc->interintra_prob[i],
+ cm->counts.interintra[i]);
+ }
+ }
+ }
#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c
index ea08415..7548456 100644
--- a/vp10/encoder/encodeframe.c
+++ b/vp10/encoder/encodeframe.c
@@ -1810,6 +1810,22 @@
#endif // CONFIG_OBMC
}
}
+
+#if CONFIG_EXT_INTER
+ if (cm->reference_mode != COMPOUND_REFERENCE &&
+#if CONFIG_SUPERTX
+ !supertx_enabled &&
+#endif
+ is_interintra_allowed(mbmi)) {
+ if (mbmi->ref_frame[1] == INTRA_FRAME) {
+ counts->y_mode[size_group_lookup[bsize]][mbmi->interintra_mode]++;
+ counts->interintra[bsize][1]++;
+ } else {
+ counts->interintra[bsize][0]++;
+ }
+ }
+#endif // CONFIG_EXT_INTER
+
if (inter_block &&
!segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
int16_t mode_ctx = mbmi_ext->mode_context[mbmi->ref_frame[0]];
@@ -4573,7 +4589,13 @@
#if CONFIG_SUPERTX
static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
- return !is_inter_mode((&ctx->mic)->mbmi.mode);
+ if (!is_inter_mode((&ctx->mic)->mbmi.mode))
+ return 1;
+#if CONFIG_EXT_INTER
+ if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME)
+ return 1;
+#endif // CONFIG_EXT_INTER
+ return 0;
}
static int check_intra_sb(VP10_COMP *cpi, const TileInfo *const tile,
diff --git a/vp10/encoder/mbgraph.c b/vp10/encoder/mbgraph.c
index ab1e60f..2d3a33e 100644
--- a/vp10/encoder/mbgraph.c
+++ b/vp10/encoder/mbgraph.c
@@ -73,7 +73,11 @@
else
#endif // CONFIG_EXT_INTER
xd->mi[0]->mbmi.mode = NEWMV;
+
xd->mi[0]->mbmi.mv[0].as_mv = *dst_mv;
+#if CONFIG_EXT_INTER
+ xd->mi[0]->mbmi.ref_frame[1] = NONE;
+#endif // CONFIG_EXT_INTER
vp10_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16);
diff --git a/vp10/encoder/rd.c b/vp10/encoder/rd.c
index 044ced1..3f60a1b 100644
--- a/vp10/encoder/rd.c
+++ b/vp10/encoder/rd.c
@@ -859,6 +859,44 @@
rd->thresh_mult[THR_D153_PRED] += 2500;
rd->thresh_mult[THR_D207_PRED] += 2500;
rd->thresh_mult[THR_D63_PRED] += 2500;
+
+#if CONFIG_EXT_INTER
+ rd->thresh_mult[THR_COMP_INTERINTRA_ZEROL ] += 1500;
+#if CONFIG_EXT_REFS
+ rd->thresh_mult[THR_COMP_INTERINTRA_ZEROL2 ] += 1500;
+ rd->thresh_mult[THR_COMP_INTERINTRA_ZEROL3 ] += 1500;
+ rd->thresh_mult[THR_COMP_INTERINTRA_ZEROL4 ] += 1500;
+#endif // CONFIG_EXT_REFS
+ rd->thresh_mult[THR_COMP_INTERINTRA_ZEROG ] += 1500;
+ rd->thresh_mult[THR_COMP_INTERINTRA_ZEROA ] += 1500;
+
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARESTL] += 1500;
+#if CONFIG_EXT_REFS
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARESTL2] += 1500;
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARESTL3] += 1500;
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARESTL4] += 1500;
+#endif // CONFIG_EXT_REFS
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARESTG] += 1500;
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARESTA] += 1500;
+
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARL ] += 1500;
+#if CONFIG_EXT_REFS
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARL2 ] += 1500;
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARL3 ] += 1500;
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARL4 ] += 1500;
+#endif // CONFIG_EXT_REFS
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARG ] += 1500;
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEARA ] += 1500;
+
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEWL ] += 2000;
+#if CONFIG_EXT_REFS
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEWL2 ] += 2000;
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEWL3 ] += 2000;
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEWL4 ] += 2000;
+#endif // CONFIG_EXT_REFS
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEWG ] += 2000;
+ rd->thresh_mult[THR_COMP_INTERINTRA_NEWA ] += 2000;
+#endif // CONFIG_EXT_INTER
}
void vp10_set_rd_speed_thresholds_sub8x8(VP10_COMP *cpi) {
diff --git a/vp10/encoder/rd.h b/vp10/encoder/rd.h
index fdbe431..5a6a44a 100644
--- a/vp10/encoder/rd.h
+++ b/vp10/encoder/rd.h
@@ -42,13 +42,13 @@
#if CONFIG_EXT_REFS
#if CONFIG_EXT_INTER
-#define MAX_MODES 85
+#define MAX_MODES 109
#else
#define MAX_MODES 54
#endif // CONFIG_EXT_INTER
#else
#if CONFIG_EXT_INTER
-#define MAX_MODES 43
+#define MAX_MODES 55
#else
#define MAX_MODES 30
#endif // CONFIG_EXT_INTER
@@ -212,6 +212,40 @@
THR_D63_PRED,
THR_D117_PRED,
THR_D45_PRED,
+
+#if CONFIG_EXT_INTER
+ THR_COMP_INTERINTRA_ZEROL,
+ THR_COMP_INTERINTRA_NEARESTL,
+ THR_COMP_INTERINTRA_NEARL,
+ THR_COMP_INTERINTRA_NEWL,
+
+#if CONFIG_EXT_REFS
+ THR_COMP_INTERINTRA_ZEROL2,
+ THR_COMP_INTERINTRA_NEARESTL2,
+ THR_COMP_INTERINTRA_NEARL2,
+ THR_COMP_INTERINTRA_NEWL2,
+
+ THR_COMP_INTERINTRA_ZEROL3,
+ THR_COMP_INTERINTRA_NEARESTL3,
+ THR_COMP_INTERINTRA_NEARL3,
+ THR_COMP_INTERINTRA_NEWL3,
+
+ THR_COMP_INTERINTRA_ZEROL4,
+ THR_COMP_INTERINTRA_NEARESTL4,
+ THR_COMP_INTERINTRA_NEARL4,
+ THR_COMP_INTERINTRA_NEWL4,
+#endif // CONFIG_EXT_REFS
+
+ THR_COMP_INTERINTRA_ZEROG,
+ THR_COMP_INTERINTRA_NEARESTG,
+ THR_COMP_INTERINTRA_NEARG,
+ THR_COMP_INTERINTRA_NEWG,
+
+ THR_COMP_INTERINTRA_ZEROA,
+ THR_COMP_INTERINTRA_NEARESTA,
+ THR_COMP_INTERINTRA_NEARA,
+ THR_COMP_INTERINTRA_NEWA,
+#endif // CONFIG_EXT_INTER
} THR_MODES;
typedef enum {
diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c
index 416c11c..ff07489 100644
--- a/vp10/encoder/rdopt.c
+++ b/vp10/encoder/rdopt.c
@@ -44,6 +44,10 @@
#include "vp10/encoder/rdopt.h"
#include "vp10/encoder/aq_variance.h"
+// TODO(geza.lore) Update this when the extended coding unit size experiment
+// have been ported.
+#define CU_SIZE 64
+
#if CONFIG_EXT_REFS
#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \
@@ -260,6 +264,40 @@
{D63_PRED, {INTRA_FRAME, NONE}},
{D117_PRED, {INTRA_FRAME, NONE}},
{D45_PRED, {INTRA_FRAME, NONE}},
+
+#if CONFIG_EXT_INTER
+ {ZEROMV, {LAST_FRAME, INTRA_FRAME}},
+ {NEARESTMV, {LAST_FRAME, INTRA_FRAME}},
+ {NEARMV, {LAST_FRAME, INTRA_FRAME}},
+ {NEWMV, {LAST_FRAME, INTRA_FRAME}},
+
+#if CONFIG_EXT_REFS
+ {ZEROMV, {LAST2_FRAME, INTRA_FRAME}},
+ {NEARESTMV, {LAST2_FRAME, INTRA_FRAME}},
+ {NEARMV, {LAST2_FRAME, INTRA_FRAME}},
+ {NEWMV, {LAST2_FRAME, INTRA_FRAME}},
+
+ {ZEROMV, {LAST3_FRAME, INTRA_FRAME}},
+ {NEARESTMV, {LAST3_FRAME, INTRA_FRAME}},
+ {NEARMV, {LAST3_FRAME, INTRA_FRAME}},
+ {NEWMV, {LAST3_FRAME, INTRA_FRAME}},
+
+ {ZEROMV, {LAST4_FRAME, INTRA_FRAME}},
+ {NEARESTMV, {LAST4_FRAME, INTRA_FRAME}},
+ {NEARMV, {LAST4_FRAME, INTRA_FRAME}},
+ {NEWMV, {LAST4_FRAME, INTRA_FRAME}},
+#endif // CONFIG_EXT_REFS
+
+ {ZEROMV, {GOLDEN_FRAME, INTRA_FRAME}},
+ {NEARESTMV, {GOLDEN_FRAME, INTRA_FRAME}},
+ {NEARMV, {GOLDEN_FRAME, INTRA_FRAME}},
+ {NEWMV, {GOLDEN_FRAME, INTRA_FRAME}},
+
+ {ZEROMV, {ALTREF_FRAME, INTRA_FRAME}},
+ {NEARESTMV, {ALTREF_FRAME, INTRA_FRAME}},
+ {NEARMV, {ALTREF_FRAME, INTRA_FRAME}},
+ {NEWMV, {ALTREF_FRAME, INTRA_FRAME}},
+#endif // CONFIG_EXT_INTER
};
static const REF_DEFINITION vp10_ref_order[MAX_REFS] = {
@@ -1056,33 +1094,6 @@
rate, distortion, skip,
sse, ref_best_rd, 0, bs,
mbmi->tx_size, cpi->sf.use_fast_coef_costing);
-
-#if CONFIG_EXT_TX
- if (get_ext_tx_types(mbmi->tx_size, bs, is_inter) > 1 &&
- !xd->lossless[mbmi->segment_id] && *rate != INT_MAX) {
- int ext_tx_set = get_ext_tx_set(mbmi->tx_size, bs, is_inter);
- if (is_inter) {
- if (ext_tx_set > 0)
- *rate += cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size]
- [mbmi->tx_type];
- } else {
- if (ext_tx_set > 0 && ALLOW_INTRA_EXT_TX)
- *rate +=
- cpi->intra_tx_type_costs[ext_tx_set][mbmi->tx_size]
- [mbmi->mode][mbmi->tx_type];
- }
- }
-#else
- if (mbmi->tx_size < TX_32X32 && !xd->lossless[mbmi->segment_id] &&
- *rate != INT_MAX) {
- if (is_inter)
- *rate += cpi->inter_tx_type_costs[mbmi->tx_size][mbmi->tx_type];
- else
- *rate += cpi->intra_tx_type_costs[mbmi->tx_size]
- [intra_mode_to_tx_type_context[mbmi->mode]]
- [mbmi->tx_type];
- }
-#endif // CONFIG_EXT_TX
}
static void choose_smallest_tx_size(VP10_COMP *cpi, MACROBLOCK *x,
@@ -3818,9 +3829,14 @@
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
const MV_REFERENCE_FRAME ref_frames[2],
const BLOCK_SIZE bsize, int block) {
+
+#if !CONFIG_EXT_INTER
+ assert(ref_frames[1] != INTRA_FRAME); // Just sanity check
+#endif
+
if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
- (ref_frames[1] == NONE ||
+ (ref_frames[1] <= INTRA_FRAME ||
frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
#if CONFIG_REF_MV
int16_t rfc = vp10_mode_context_analyzer(mode_context,
@@ -3849,7 +3865,7 @@
if (c2 > c3) return 0;
} else {
assert(this_mode == ZEROMV);
- if (ref_frames[1] == NONE) {
+ if (ref_frames[1] <= INTRA_FRAME) {
if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frames[0]].as_int == 0) ||
(c3 >= c1 && frame_mv[NEARMV][ref_frames[0]].as_int == 0))
return 0;
@@ -3889,26 +3905,16 @@
if (c4 > c3) return 0;
} else {
assert(this_mode == ZERO_ZEROMV);
- if (ref_frames[1] == NONE) {
- if ((c3 >= c2 &&
- frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0) ||
- (c3 >= c1 &&
- frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0) ||
- (c3 >= c4 &&
- frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0))
- return 0;
- } else {
- 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 >= c4 &&
- frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
- frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
- return 0;
- }
+ 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 >= c4 &&
+ frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
+ frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
+ return 0;
}
}
#endif // CONFIG_EXT_INTER
@@ -5160,6 +5166,8 @@
#endif // CONFIG_OBMC
#if CONFIG_EXT_INTER
int_mv single_newmvs[2][MAX_REF_FRAMES],
+ int single_newmvs_rate[2][MAX_REF_FRAMES],
+ int *compmode_interintra_cost,
#else
int_mv single_newmv[MAX_REF_FRAMES],
#endif // CONFIG_EXT_INTER
@@ -5183,6 +5191,9 @@
#if CONFIG_EXT_INTER
int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
int_mv single_newmv[MAX_REF_FRAMES];
+ const int * const intra_mode_cost =
+ cpi->mbmode_cost[size_group_lookup[bsize]];
+ const int is_comp_interintra_pred = (mbmi->ref_frame[1] == INTRA_FRAME);
#if CONFIG_REF_MV
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
#endif
@@ -5193,6 +5204,9 @@
#else
DECLARE_ALIGNED(16, uint8_t, tmp_buf[MAX_MB_PLANE * 64 * 64]);
#endif // CONFIG_VP9_HIGHBITDEPTH
+#if CONFIG_EXT_INTER
+ const int tmp_buf_sz = CU_SIZE * CU_SIZE;
+#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
int allow_obmc = is_obmc_allowed(mbmi);
int best_obmc_flag = 0;
@@ -5243,6 +5257,15 @@
int64_t distortion_y = 0, distortion_uv = 0;
int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
+#if CONFIG_EXT_INTER
+ *compmode_interintra_cost = 0;
+
+ // is_comp_interintra_pred implies !is_comp_pred
+ assert(!is_comp_interintra_pred || (!is_comp_pred));
+ // is_comp_interintra_pred implies is_interintra_allowed(mbmi->sb_type)
+ assert(!is_comp_interintra_pred || is_interintra_allowed(mbmi));
+#endif // CONFIG_EXT_INTER
+
#if CONFIG_OBMC
tmp_rd = 0;
#endif // CONFIG_OBMC
@@ -5345,35 +5368,39 @@
x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
}
#endif // CONFIG_EXT_INTER
- *rate2 += rate_mv;
} else {
int_mv tmp_mv;
- single_motion_search(cpi, x, bsize, mi_row, mi_col,
+
#if CONFIG_EXT_INTER
- 0, mv_idx,
+ if (is_comp_interintra_pred) {
+ tmp_mv = single_newmvs[mv_idx][refs[0]];
+ rate_mv = single_newmvs_rate[mv_idx][refs[0]];
+ } else {
+ single_motion_search(cpi, x, bsize, mi_row, mi_col,
+ 0, mv_idx, &tmp_mv, &rate_mv);
+ single_newmvs[mv_idx][refs[0]] = tmp_mv;
+ single_newmvs_rate[mv_idx][refs[0]] = rate_mv;
+ }
+#else
+ single_motion_search(cpi, x, bsize, mi_row, mi_col, &tmp_mv, &rate_mv);
+ single_newmv[refs[0]] = tmp_mv;
#endif // CONFIG_EXT_INTER
- &tmp_mv, &rate_mv);
+
if (tmp_mv.as_int == INVALID_MV)
return INT64_MAX;
- frame_mv[refs[0]].as_int =
- xd->mi[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
-#if CONFIG_EXT_INTER
- single_newmvs[mv_idx][refs[0]].as_int = tmp_mv.as_int;
-#else
- single_newmv[refs[0]].as_int = tmp_mv.as_int;
-#endif // CONFIG_EXT_INTER
+ frame_mv[refs[0]] = tmp_mv;
+ xd->mi[0]->bmi[0].as_mv[0] = tmp_mv;
// Estimate the rate implications of a new mv but discount this
// under certain circumstances where we want to help initiate a weak
// motion field, where the distortion gain for a single block may not
// be enough to overcome the cost of a new mv.
if (discount_newmv_test(cpi, this_mode, tmp_mv, mode_mv, refs[0])) {
- *rate2 += VPXMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
- } else {
- *rate2 += rate_mv;
+ rate_mv = VPXMAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1);
}
}
+ *rate2 += rate_mv;
}
for (i = 0; i < is_comp_pred + 1; ++i) {
@@ -5586,6 +5613,9 @@
if ((cm->interp_filter == SWITCHABLE &&
(!i || best_needs_copy)) ||
+#if CONFIG_EXT_INTER
+ is_comp_interintra_pred ||
+#endif // CONFIG_EXT_INTER
(cm->interp_filter != SWITCHABLE &&
(cm->interp_filter == mbmi->interp_filter ||
(i == 0 && intpel_mv && IsInterpolatingFilter(i))))) {
@@ -5714,6 +5744,63 @@
mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
cm->interp_filter : best_filter;
rs = cm->interp_filter == SWITCHABLE ? vp10_get_switchable_rate(cpi, xd) : 0;
+
+#if CONFIG_EXT_INTER
+ if (is_comp_interintra_pred) {
+ PREDICTION_MODE interintra_mode, best_interintra_mode = DC_PRED;
+ int64_t best_interintra_rd = INT64_MAX;
+ int rmode, rate_sum;
+ int64_t dist_sum;
+ int j;
+ mbmi->ref_frame[1] = NONE;
+ for (j = 0; j < MAX_MB_PLANE; j++) {
+ xd->plane[j].dst.buf = tmp_buf + j * tmp_buf_sz;
+ xd->plane[j].dst.stride = CU_SIZE;
+ }
+ vp10_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
+ restore_dst_buf(xd, orig_dst, orig_dst_stride);
+ mbmi->ref_frame[1] = INTRA_FRAME;
+
+ for (interintra_mode = DC_PRED; interintra_mode <= TM_PRED;
+ ++interintra_mode) {
+ mbmi->interintra_mode = interintra_mode;
+ mbmi->interintra_uv_mode = interintra_mode;
+ rmode = intra_mode_cost[mbmi->interintra_mode];
+ vp10_build_interintra_predictors(xd,
+ tmp_buf,
+ tmp_buf + tmp_buf_sz,
+ tmp_buf + 2 * tmp_buf_sz,
+ CU_SIZE,
+ CU_SIZE,
+ CU_SIZE,
+ bsize);
+ model_rd_for_sb(cpi, bsize, x, xd, &rate_sum, &dist_sum,
+ &skip_txfm_sb, &skip_sse_sb);
+ rd = RDCOST(x->rdmult, x->rddiv, rmode + rate_sum, dist_sum);
+ if (rd < best_interintra_rd) {
+ best_interintra_rd = rd;
+ best_interintra_mode = interintra_mode;
+ }
+ }
+ mbmi->interintra_mode = best_interintra_mode;
+ mbmi->interintra_uv_mode = best_interintra_mode;
+ if (ref_best_rd < INT64_MAX &&
+ best_interintra_rd / 2 > ref_best_rd) {
+ return INT64_MAX;
+ }
+
+ pred_exists = 0;
+ tmp_rd = best_interintra_rd;
+
+ *compmode_interintra_cost =
+ vp10_cost_bit(cm->fc->interintra_prob[bsize], 1);
+ *compmode_interintra_cost += intra_mode_cost[mbmi->interintra_mode];
+ } else if (is_interintra_allowed(mbmi)) {
+ *compmode_interintra_cost =
+ vp10_cost_bit(cm->fc->interintra_prob[bsize], 0);
+ }
+#endif // CONFIG_EXT_INTER
+
#if CONFIG_OBMC
if (allow_obmc)
mbmi->obmc = best_obmc_flag;
@@ -6303,6 +6390,7 @@
struct buf_2d yv12_mb[MAX_REF_FRAMES][MAX_MB_PLANE];
#if CONFIG_EXT_INTER
int_mv single_newmvs[2][MAX_REF_FRAMES] = { { { 0 } }, { { 0 } } };
+ int single_newmvs_rate[2][MAX_REF_FRAMES] = { { 0 }, { 0 } };
#else
int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
#endif // CONFIG_EXT_INTER
@@ -6325,9 +6413,6 @@
int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
MB_MODE_INFO best_mbmode;
-#if CONFIG_REF_MV
- uint8_t best_ref_mv_idx[MODE_CTX_REF_FRAMES] = { 0 };
-#endif
int best_mode_skippable = 0;
int midx, best_mode_index = -1;
unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
@@ -6594,6 +6679,9 @@
int64_t this_rd = INT64_MAX;
int disable_skip = 0;
int compmode_cost = 0;
+#if CONFIG_EXT_INTER
+ int compmode_interintra_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;
int skippable = 0;
@@ -6609,6 +6697,14 @@
second_ref_frame = vp10_mode_order[mode_index].ref_frame[1];
#if CONFIG_EXT_INTER
+ if (ref_frame > INTRA_FRAME && second_ref_frame == INTRA_FRAME) {
+ // Mode must by compatible
+ assert(is_interintra_allowed_mode(this_mode));
+
+ if (!is_interintra_allowed_bsize(bsize))
+ continue;
+ }
+
if (this_mode == NEAREST_NEARESTMV) {
frame_mv[NEAREST_NEARESTMV][ref_frame].as_int =
frame_mv[NEARESTMV][ref_frame].as_int;
@@ -6792,6 +6888,11 @@
xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
}
+#if CONFIG_EXT_INTER
+ mbmi->interintra_mode = (PREDICTION_MODE)(DC_PRED - 1);
+ mbmi->interintra_uv_mode = (PREDICTION_MODE)(DC_PRED - 1);
+#endif // CONFIG_EXT_INTER
+
if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
struct macroblockd_plane *const pd = &xd->plane[1];
@@ -6936,6 +7037,21 @@
rate2 += intra_cost_penalty;
distortion2 = distortion_y + distortion_uv;
} else {
+#if CONFIG_EXT_INTER
+ if (second_ref_frame == INTRA_FRAME) {
+ mbmi->interintra_mode = best_intra_mode;
+ mbmi->interintra_uv_mode = best_intra_mode;
+#if CONFIG_EXT_INTRA
+ // TODO(debargha|geza.lore):
+ // Should we use ext_intra modes for interintra?
+ mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
+ mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
+ mbmi->angle_delta[0] = 0;
+ mbmi->angle_delta[1] = 0;
+ mbmi->intra_filter = INTRA_FILTER_LINEAR;
+#endif // CONFIG_EXT_INTRA
+ }
+#endif // CONFIG_EXT_INTER
#if CONFIG_REF_MV
mbmi->ref_mv_idx = 0;
ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
@@ -6951,11 +7067,14 @@
#endif // CONFIG_OBMC
#if CONFIG_EXT_INTER
single_newmvs,
+ single_newmvs_rate,
+ &compmode_interintra_cost,
#else
single_newmv,
#endif // CONFIG_EXT_INTER
single_inter_filter,
- single_skippable, &total_sse, best_rd,
+ single_skippable,
+ &total_sse, best_rd,
&mask_filter, filter_cache);
#if CONFIG_REF_MV
@@ -7008,6 +7127,9 @@
#if CONFIG_EXT_INTER
int_mv dummy_single_newmvs[2][MAX_REF_FRAMES] =
{ { { 0 } }, { { 0 } } };
+ int dummy_single_newmvs_rate[2][MAX_REF_FRAMES] =
+ { { 0 }, { 0 } };
+ int dummy_compmode_interintra_cost = 0;
#else
int_mv dummy_single_newmv[MAX_REF_FRAMES] = { { 0 } };
#endif
@@ -7027,6 +7149,8 @@
#endif // CONFIG_OBMC
#if CONFIG_EXT_INTER
dummy_single_newmvs,
+ dummy_single_newmvs_rate,
+ &dummy_compmode_interintra_cost,
#else
dummy_single_newmv,
#endif
@@ -7071,8 +7195,6 @@
rate_uv = tmp_rate_uv;
total_sse = tmp_sse;
this_rd = tmp_alt_rd;
- // Indicator of the effective nearmv reference motion vector.
- best_ref_mv_idx[ref_frame_type] = 1 + ref_idx;
tmp_ref_rd = tmp_alt_rd;
backup_mbmi = *mbmi;
} else {
@@ -7082,7 +7204,7 @@
frame_mv[NEARMV][ref_frame] = backup_mv;
}
-#endif
+#endif // CONFIG_REF_MV
if (this_rd == INT64_MAX)
continue;
@@ -7093,6 +7215,10 @@
rate2 += compmode_cost;
}
+#if CONFIG_EXT_INTER
+ rate2 += compmode_interintra_cost;
+#endif // CONFIG_EXT_INTER
+
// Estimate the reference frame signaling cost and add it
// to the rolling cost variable.
if (comp_pred) {
@@ -7308,12 +7434,11 @@
best_mbmode.ref_frame[1]};
int comp_pred_mode = refs[1] > INTRA_FRAME;
#if CONFIG_REF_MV
+ const uint8_t rf_type = vp10_ref_frame_type(best_mbmode.ref_frame);
if (!comp_pred_mode) {
- if (best_ref_mv_idx[best_mbmode.ref_frame[0]] > 0 &&
- best_mbmode.ref_frame[1] == NONE) {
- int idx = best_ref_mv_idx[best_mbmode.ref_frame[0]] + 1;
- int_mv cur_mv =
- mbmi_ext->ref_mv_stack[best_mbmode.ref_frame[0]][idx].this_mv;
+ if (best_mbmode.ref_mv_idx > 0 && refs[1] == NONE) {
+ int idx = best_mbmode.ref_mv_idx + 1;
+ int_mv cur_mv = mbmi_ext->ref_mv_stack[refs[0]][idx].this_mv;
lower_mv_precision(&cur_mv.as_mv, cm->allow_high_precision_mv);
frame_mv[NEARMV][refs[0]] = cur_mv;
}
@@ -7325,7 +7450,6 @@
else if (best_mbmode.mv[0].as_int == 0)
best_mbmode.mode = ZEROMV;
} else {
- uint8_t rf_type = vp10_ref_frame_type(best_mbmode.ref_frame);
int i;
const int allow_hp = cm->allow_high_precision_mv;
int_mv nearestmv[2] = { frame_mv[NEARESTMV][refs[0]],
@@ -7340,7 +7464,7 @@
}
if (mbmi_ext->ref_mv_count[rf_type] > 1) {
- int ref_mv_idx = best_ref_mv_idx[rf_type] + 1;
+ int ref_mv_idx = best_mbmode.ref_mv_idx + 1;
nearmv[0] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].this_mv;
nearmv[1] = mbmi_ext->ref_mv_stack[rf_type][ref_mv_idx].comp_mv;
}
@@ -7417,10 +7541,11 @@
if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
best_mbmode.mv[0].as_int == 0 &&
#if CONFIG_EXT_INTER
- best_mbmode.ref_frame[1] == NONE) {
+ (best_mbmode.ref_frame[1] <= INTRA_FRAME)
#else
- (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)) {
+ (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
#endif // CONFIG_EXT_INTER
+ ) {
int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
#if !CONFIG_EXT_INTER
if (best_mbmode.ref_frame[1] > NONE)
@@ -7430,11 +7555,6 @@
if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET))
best_mbmode.mode = ZEROMV;
}
-
- if (best_mbmode.mode == NEARMV) {
- uint8_t ref_frame_type = vp10_ref_frame_type(best_mbmode.ref_frame);
- best_mbmode.ref_mv_idx = best_ref_mv_idx[ref_frame_type];
- }
#endif
if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
diff --git a/vp10/encoder/speed_features.c b/vp10/encoder/speed_features.c
index 4257f93..1f70dcb 100644
--- a/vp10/encoder/speed_features.c
+++ b/vp10/encoder/speed_features.c
@@ -168,7 +168,6 @@
if (speed >= 2) {
sf->tx_size_search_method = frame_is_boosted(cpi) ? USE_FULL_RD
: USE_LARGESTALL;
-
sf->mode_search_skip_flags = (cm->frame_type == KEY_FRAME) ? 0 :
FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |