summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeb Mukherjee <debargha@google.com>2012-11-07 06:50:25 -0800
committerDeb Mukherjee <debargha@google.com>2012-11-16 06:56:29 -0800
commit0c917fc9755108887901bc0ea44e1952de8a2c65 (patch)
tree9a402304bdfc0dbc0e08c158e282a28d8690639f
parent16e268668204566d7f4b2d4fc6775f996773d74d (diff)
downloadlibvpx-0c917fc9755108887901bc0ea44e1952de8a2c65.tar
libvpx-0c917fc9755108887901bc0ea44e1952de8a2c65.tar.gz
libvpx-0c917fc9755108887901bc0ea44e1952de8a2c65.tar.bz2
libvpx-0c917fc9755108887901bc0ea44e1952de8a2c65.zip
Compound inter-intra experiment
A patch on compound inter-intra prediction. In compound inter-intra prediction, a new predictor for 16x16 inter coded MBs are obtained by combining a single inter predictor with a 16x16 intra predictor, in a manner that the weight varies with distance from the top/left boundary. The current search strategy is to combine the best inter mode with the best intra mode obtained independently. Results so far: derf +0.31% yt +0.32% std-hd +0.35% hd +0.42% It is conceivable that the results would improve somewhat with a more thorough search strategy where all intra modes are searched given the best mv, or even a joint search for the best mv and the best intra mode. Change-Id: I7951f1ed0d6eb31ca32ac24d120f1585bcd8d79b
-rwxr-xr-xconfigure1
-rw-r--r--vp9/common/blockd.h4
-rw-r--r--vp9/common/entropymode.c29
-rw-r--r--vp9/common/entropymode.h7
-rw-r--r--vp9/common/findnearmv.h14
-rw-r--r--vp9/common/mvref_common.c10
-rw-r--r--vp9/common/onyxc_int.h8
-rw-r--r--vp9/common/pred_common.c4
-rw-r--r--vp9/common/reconinter.c30
-rw-r--r--vp9/common/reconintra.c302
-rw-r--r--vp9/common/reconintra.h15
-rw-r--r--vp9/decoder/decodemv.c60
-rw-r--r--vp9/decoder/decodframe.c52
-rw-r--r--vp9/encoder/bitstream.c65
-rw-r--r--vp9/encoder/encodeframe.c24
-rw-r--r--vp9/encoder/encodemv.c8
-rw-r--r--vp9/encoder/onyx_if.c104
-rw-r--r--vp9/encoder/onyx_int.h50
-rw-r--r--vp9/encoder/ratectrl.c6
-rw-r--r--vp9/encoder/rdopt.c396
20 files changed, 992 insertions, 197 deletions
diff --git a/configure b/configure
index c1ee96dda..d1d25b3d5 100755
--- a/configure
+++ b/configure
@@ -246,6 +246,7 @@ EXPERIMENT_LIST="
new_mvref
implicit_segmentation
newbintramodes
+ comp_interintra_pred
"
CONFIG_LIST="
external_build
diff --git a/vp9/common/blockd.h b/vp9/common/blockd.h
index b3c8ff33c..412d2bc93 100644
--- a/vp9/common/blockd.h
+++ b/vp9/common/blockd.h
@@ -214,6 +214,7 @@ union b_mode_info {
};
typedef enum {
+ NONE = -1,
INTRA_FRAME = 0,
LAST_FRAME = 1,
GOLDEN_FRAME = 2,
@@ -226,6 +227,9 @@ typedef struct {
#if CONFIG_COMP_INTRA_PRED
MB_PREDICTION_MODE second_mode, second_uv_mode;
#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+ MB_PREDICTION_MODE interintra_mode, interintra_uv_mode;
+#endif
MV_REFERENCE_FRAME ref_frame, second_ref_frame;
TX_SIZE txfm_size;
int_mv mv[2]; // for each reference frame used
diff --git a/vp9/common/entropymode.c b/vp9/common/entropymode.c
index d0e83ecb2..83ba21c55 100644
--- a/vp9/common/entropymode.c
+++ b/vp9/common/entropymode.c
@@ -345,6 +345,9 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) {
vpx_memcpy(x->fc.mbsplit_prob, vp9_mbsplit_probs, sizeof(vp9_mbsplit_probs));
vpx_memcpy(x->fc.switchable_interp_prob, vp9_switchable_interp_prob,
sizeof(vp9_switchable_interp_prob));
+#if CONFIG_COMP_INTERINTRA_PRED
+ x->fc.interintra_prob = VP9_DEF_INTERINTRA_PROB;
+#endif
}
@@ -547,6 +550,9 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
vp9_prob i8x8_mode_probs[VP9_I8X8_MODES - 1];
vp9_prob sub_mv_ref_probs[VP9_SUBMVREFS - 1];
vp9_prob mbsplit_probs[VP9_NUMMBSPLITS - 1];
+#if CONFIG_COMP_INTERINTRA_PRED
+ vp9_prob interintra_prob;
+#endif
#ifdef MODE_COUNT_TESTING
printf("static const unsigned int\nymode_counts"
"[VP9_YMODES] = {\n");
@@ -581,6 +587,12 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
"[VP9_NUMMBSPLITS] = {\n");
for (t = 0; t < VP9_NUMMBSPLITS; ++t) printf("%d, ", cm->fc.mbsplit_counts[t]);
printf("};\n");
+#if CONFIG_COMP_INTERINTRA_PRED
+ printf("static const unsigned int\ninterintra_counts"
+ "[2] = {\n");
+ for (t = 0; t < 2; ++t) printf("%d, ", cm->fc.interintra_counts[t]);
+ printf("};\n");
+#endif
#endif
vp9_tree_probs_from_distribution(
VP9_YMODES, vp9_ymode_encodings, vp9_ymode_tree,
@@ -673,4 +685,21 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
else if (prob > 255) cm->fc.mbsplit_prob[t] = 255;
else cm->fc.mbsplit_prob[t] = prob;
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (cm->use_interintra) {
+ int prob;
+ interintra_prob = vp9_bin_prob_from_distribution(cm->fc.interintra_counts);
+ count = cm->fc.interintra_counts[0] + cm->fc.interintra_counts[1];
+ count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
+ factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
+ prob = ((int)cm->fc.pre_interintra_prob * (256 - factor) +
+ (int)interintra_prob * factor + 128) >> 8;
+ if (prob <= 0)
+ cm->fc.interintra_prob = 1;
+ else if (prob > 255)
+ cm->fc.interintra_prob = 255;
+ else
+ cm->fc.interintra_prob = prob;
+ }
+#endif
}
diff --git a/vp9/common/entropymode.h b/vp9/common/entropymode.h
index 34a2bea03..790f5597b 100644
--- a/vp9/common/entropymode.h
+++ b/vp9/common/entropymode.h
@@ -21,6 +21,13 @@
#define DEFAULT_COMP_INTRA_PROB 32
#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+#define VP9_DEF_INTERINTRA_PROB 248
+#define VP9_UPD_INTERINTRA_PROB 192
+// whether to use a separate uv mode (1) or use the same as the y mode (0)
+#define SEPARATE_INTERINTRA_UV 0
+#endif
+
typedef const int vp9_mbsplit[16];
extern vp9_mbsplit vp9_mbsplits[VP9_NUMMBSPLITS];
diff --git a/vp9/common/findnearmv.h b/vp9/common/findnearmv.h
index 64233ec23..256745261 100644
--- a/vp9/common/findnearmv.h
+++ b/vp9/common/findnearmv.h
@@ -104,11 +104,14 @@ static int left_block_second_mv(const MODE_INFO *cur_mb, int b) {
--cur_mb;
if (cur_mb->mbmi.mode != SPLITMV)
- return cur_mb->mbmi.second_ref_frame ? cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
+ return cur_mb->mbmi.second_ref_frame > 0 ?
+ cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
b += 4;
}
- return cur_mb->mbmi.second_ref_frame ? (cur_mb->bmi + b - 1)->as_mv.second.as_int : (cur_mb->bmi + b - 1)->as_mv.first.as_int;
+ return cur_mb->mbmi.second_ref_frame > 0 ?
+ (cur_mb->bmi + b - 1)->as_mv.second.as_int :
+ (cur_mb->bmi + b - 1)->as_mv.first.as_int;
}
static int above_block_mv(const MODE_INFO *cur_mb, int b, int mi_stride) {
@@ -130,11 +133,14 @@ static int above_block_second_mv(const MODE_INFO *cur_mb, int b, int mi_stride)
cur_mb -= mi_stride;
if (cur_mb->mbmi.mode != SPLITMV)
- return cur_mb->mbmi.second_ref_frame ? cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
+ return cur_mb->mbmi.second_ref_frame > 0 ?
+ cur_mb->mbmi.mv[1].as_int : cur_mb->mbmi.mv[0].as_int;
b += 16;
}
- return cur_mb->mbmi.second_ref_frame ? (cur_mb->bmi + b - 4)->as_mv.second.as_int : (cur_mb->bmi + b - 4)->as_mv.first.as_int;
+ return cur_mb->mbmi.second_ref_frame > 0 ?
+ (cur_mb->bmi + b - 4)->as_mv.second.as_int :
+ (cur_mb->bmi + b - 4)->as_mv.first.as_int;
}
static B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b) {
diff --git a/vp9/common/mvref_common.c b/vp9/common/mvref_common.c
index a412a6c8a..0f5673697 100644
--- a/vp9/common/mvref_common.c
+++ b/vp9/common/mvref_common.c
@@ -54,7 +54,7 @@ static int get_candidate_mvref(
ret_val = TRUE;
// Is there a second non zero vector we can use.
- if ((candidate_mi->mbmi.second_ref_frame != INTRA_FRAME) &&
+ if ((candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) &&
(candidate_mi->mbmi.mv[1].as_int != 0) &&
(candidate_mi->mbmi.mv[1].as_int != c_mv->as_int)) {
c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
@@ -68,7 +68,7 @@ static int get_candidate_mvref(
ret_val = TRUE;
// Is there a second non zero vector we can use.
- if ((candidate_mi->mbmi.ref_frame != INTRA_FRAME) &&
+ if ((candidate_mi->mbmi.ref_frame > INTRA_FRAME) &&
(candidate_mi->mbmi.mv[0].as_int != 0) &&
(candidate_mi->mbmi.mv[0].as_int != c_mv->as_int)) {
c2_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
@@ -76,13 +76,13 @@ static int get_candidate_mvref(
}
// No ref frame matches so use first ref mv as first choice
- } else if (candidate_mi->mbmi.ref_frame != INTRA_FRAME) {
+ } else if (candidate_mi->mbmi.ref_frame > INTRA_FRAME) {
c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
*c_ref_frame = candidate_mi->mbmi.ref_frame;
ret_val = TRUE;
// Is there a second non zero vector we can use.
- if ((candidate_mi->mbmi.second_ref_frame != INTRA_FRAME) &&
+ if ((candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) &&
(candidate_mi->mbmi.mv[1].as_int != 0) &&
(candidate_mi->mbmi.mv[1].as_int != c_mv->as_int)) {
c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
@@ -91,7 +91,7 @@ static int get_candidate_mvref(
// If only the second ref mv is valid:- (Should not trigger in current code
// base given current possible compound prediction options).
- } else if (candidate_mi->mbmi.second_ref_frame != INTRA_FRAME) {
+ } else if (candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) {
c_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
*c_ref_frame = candidate_mi->mbmi.second_ref_frame;
ret_val = TRUE;
diff --git a/vp9/common/onyxc_int.h b/vp9/common/onyxc_int.h
index 516bea3cc..f51cfd529 100644
--- a/vp9/common/onyxc_int.h
+++ b/vp9/common/onyxc_int.h
@@ -106,6 +106,11 @@ typedef struct frame_contexts {
nmv_context_counts NMVcount;
vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
[VP9_SWITCHABLE_FILTERS - 1];
+#if CONFIG_COMP_INTERINTRA_PRED
+ unsigned int interintra_counts[2];
+ vp9_prob interintra_prob;
+ vp9_prob pre_interintra_prob;
+#endif
int mode_context[INTER_MODE_CONTEXTS][4];
int mode_context_a[INTER_MODE_CONTEXTS][4];
@@ -311,6 +316,9 @@ typedef struct VP9Common {
// 2=specified per MB (1=filtered, 0=non-filtered)
vp9_prob prob_pred_filter_off;
#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+ int use_interintra;
+#endif
} VP9_COMMON;
diff --git a/vp9/common/pred_common.c b/vp9/common/pred_common.c
index bac7a0962..d779c641d 100644
--- a/vp9/common/pred_common.c
+++ b/vp9/common/pred_common.c
@@ -40,8 +40,8 @@ unsigned char vp9_get_pred_context(const VP9_COMMON *const cm,
case PRED_COMP:
// Context based on use of comp pred flag by neighbours
// pred_context =
- // ((m - 1)->mbmi.second_ref_frame != INTRA_FRAME) +
- // ((m - cm->mode_info_stride)->mbmi.second_ref_frame != INTRA_FRAME);
+ // ((m - 1)->mbmi.second_ref_frame > INTRA_FRAME) +
+ // ((m - cm->mode_info_stride)->mbmi.second_ref_frame > INTRA_FRAME);
// Context based on mode and reference frame
// if ( m->mbmi.ref_frame == LAST_FRAME )
diff --git a/vp9/common/reconinter.c b/vp9/common/reconinter.c
index 8b81b28c7..b67cec798 100644
--- a/vp9/common/reconinter.c
+++ b/vp9/common/reconinter.c
@@ -14,6 +14,7 @@
#include "subpixel.h"
#include "blockd.h"
#include "reconinter.h"
+#include "vp9/common/reconintra.h"
#if CONFIG_RUNTIME_CPU_DETECT
#include "onyxc_int.h"
#endif
@@ -511,7 +512,7 @@ void vp9_build_inter4x4_predictors_mbuv(MACROBLOCKD *xd) {
blockd[voffset].bmi.as_mv.first.as_mv.col =
blockd[uoffset].bmi.as_mv.first.as_mv.col;
- if (xd->mode_info_context->mbmi.second_ref_frame) {
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
temp = blockd[yoffset ].bmi.as_mv.second.as_mv.row
+ blockd[yoffset + 1].bmi.as_mv.second.as_mv.row
+ blockd[yoffset + 4].bmi.as_mv.second.as_mv.row
@@ -559,7 +560,7 @@ void vp9_build_inter4x4_predictors_mbuv(MACROBLOCKD *xd) {
vp9_build_inter_predictors_b(d1, 8, xd->subpixel_predict);
}
- if (xd->mode_info_context->mbmi.second_ref_frame) {
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
vp9_build_2nd_inter_predictors_b(d0, 8, xd->subpixel_predict_avg);
vp9_build_2nd_inter_predictors_b(d1, 8, xd->subpixel_predict_avg);
}
@@ -777,7 +778,7 @@ void vp9_build_inter32x32_predictors_sb(MACROBLOCKD *x,
dst_u + y_idx * 8 * dst_uvstride + x_idx * 8,
dst_v + y_idx * 8 * dst_uvstride + x_idx * 8,
dst_ystride, dst_uvstride);
- if (x->mode_info_context->mbmi.second_ref_frame) {
+ if (x->mode_info_context->mbmi.second_ref_frame > 0) {
x->second_pre.y_buffer = y2 + y_idx * 16 * x->pre.y_stride + x_idx * 16;
x->second_pre.u_buffer = u2 + y_idx * 8 * x->pre.uv_stride + x_idx * 8;
x->second_pre.v_buffer = v2 + y_idx * 8 * x->pre.uv_stride + x_idx * 8;
@@ -799,7 +800,7 @@ void vp9_build_inter32x32_predictors_sb(MACROBLOCKD *x,
x->pre.u_buffer = u1;
x->pre.v_buffer = v1;
- if (x->mode_info_context->mbmi.second_ref_frame) {
+ if (x->mode_info_context->mbmi.second_ref_frame > 0) {
x->second_pre.y_buffer = y2;
x->second_pre.u_buffer = u2;
x->second_pre.v_buffer = v2;
@@ -979,7 +980,7 @@ static void build_inter4x4_predictors_mb(MACROBLOCKD *xd) {
clamp_mv_to_umv_border(&blockd[ 2].bmi.as_mv.first.as_mv, xd);
clamp_mv_to_umv_border(&blockd[ 8].bmi.as_mv.first.as_mv, xd);
clamp_mv_to_umv_border(&blockd[10].bmi.as_mv.first.as_mv, xd);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
clamp_mv_to_umv_border(&blockd[ 0].bmi.as_mv.second.as_mv, xd);
clamp_mv_to_umv_border(&blockd[ 2].bmi.as_mv.second.as_mv, xd);
clamp_mv_to_umv_border(&blockd[ 8].bmi.as_mv.second.as_mv, xd);
@@ -993,7 +994,7 @@ static void build_inter4x4_predictors_mb(MACROBLOCKD *xd) {
vp9_build_inter_predictors4b(xd, &blockd[ 8], 16);
vp9_build_inter_predictors4b(xd, &blockd[10], 16);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
vp9_build_2nd_inter_predictors4b(xd, &blockd[ 0], 16);
vp9_build_2nd_inter_predictors4b(xd, &blockd[ 2], 16);
vp9_build_2nd_inter_predictors4b(xd, &blockd[ 8], 16);
@@ -1010,7 +1011,7 @@ static void build_inter4x4_predictors_mb(MACROBLOCKD *xd) {
if (mbmi->need_to_clamp_mvs) {
clamp_mv_to_umv_border(&blockd[i + 0].bmi.as_mv.first.as_mv, xd);
clamp_mv_to_umv_border(&blockd[i + 1].bmi.as_mv.first.as_mv, xd);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
clamp_mv_to_umv_border(&blockd[i + 0].bmi.as_mv.second.as_mv, xd);
clamp_mv_to_umv_border(&blockd[i + 1].bmi.as_mv.second.as_mv, xd);
}
@@ -1023,7 +1024,7 @@ static void build_inter4x4_predictors_mb(MACROBLOCKD *xd) {
vp9_build_inter_predictors_b(d1, 16, xd->subpixel_predict);
}
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
vp9_build_2nd_inter_predictors_b(d0, 16, xd->subpixel_predict_avg);
vp9_build_2nd_inter_predictors_b(d1, 16, xd->subpixel_predict_avg);
}
@@ -1041,7 +1042,7 @@ static void build_inter4x4_predictors_mb(MACROBLOCKD *xd) {
vp9_build_inter_predictors_b(d1, 8, xd->subpixel_predict);
}
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
vp9_build_2nd_inter_predictors_b(d0, 8, xd->subpixel_predict_avg);
vp9_build_2nd_inter_predictors_b(d1, 8, xd->subpixel_predict_avg);
}
@@ -1094,7 +1095,7 @@ void build_4x4uvmvs(MACROBLOCKD *xd) {
blockd[voffset].bmi.as_mv.first.as_mv.col =
blockd[uoffset].bmi.as_mv.first.as_mv.col;
- if (xd->mode_info_context->mbmi.second_ref_frame) {
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
temp = xd->mode_info_context->bmi[yoffset + 0].as_mv.second.as_mv.row
+ xd->mode_info_context->bmi[yoffset + 1].as_mv.second.as_mv.row
+ xd->mode_info_context->bmi[yoffset + 4].as_mv.second.as_mv.row
@@ -1146,7 +1147,7 @@ void vp9_build_inter_predictors_mb(MACROBLOCKD *xd) {
&xd->predictor[256],
&xd->predictor[320], 16, 8);
- if (xd->mode_info_context->mbmi.second_ref_frame) {
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
/* 256 = offset of U plane in Y+U+V buffer;
* 320 = offset of V plane in Y+U+V buffer.
* (256=16x16, 320=16x16+8x8). */
@@ -1154,6 +1155,13 @@ void vp9_build_inter_predictors_mb(MACROBLOCKD *xd) {
&xd->predictor[256],
&xd->predictor[320], 16, 8);
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ else if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) {
+ vp9_build_interintra_16x16_predictors_mb(xd, xd->predictor,
+ &xd->predictor[256],
+ &xd->predictor[320], 16, 8);
+ }
+#endif
} else {
build_4x4uvmvs(xd);
build_inter4x4_predictors_mb(xd);
diff --git a/vp9/common/reconintra.c b/vp9/common/reconintra.c
index c9b8bd052..2964ff462 100644
--- a/vp9/common/reconintra.c
+++ b/vp9/common/reconintra.c
@@ -372,6 +372,294 @@ void vp9_build_intra_predictors_internal(unsigned char *src, int src_stride,
}
}
+#if CONFIG_COMP_INTERINTRA_PRED
+static void combine_interintra(MB_PREDICTION_MODE mode,
+ unsigned char *interpred,
+ int interstride,
+ unsigned char *intrapred,
+ int intrastride,
+ int size) {
+ // TODO(debargha): Explore different ways of combining predictors
+ // or designing the tables below
+ static const int scale_bits = 8;
+ static const int scale_max = 1 << scale_bits;
+ static const int scale_round = (1 << scale_bits) - 1;
+ // This table is a function A + B*exp(-kx), where x is hor. index
+ static const int weights1d[32] = {
+ 128, 122, 116, 111, 107, 103, 99, 96,
+ 93, 90, 88, 85, 83, 81, 80, 78,
+ 77, 76, 75, 74, 73, 72, 71, 70,
+ 70, 69, 69, 68, 68, 68, 67, 67,
+ };
+ // This table is a function A + B*exp(-k.sqrt(xy)), where x, y are
+ // hor. and vert. indices
+ static const int weights2d[1024] = {
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 122, 120, 118, 116, 115, 114, 113,
+ 112, 111, 111, 110, 109, 109, 108, 107,
+ 107, 106, 106, 105, 105, 104, 104, 104,
+ 103, 103, 102, 102, 102, 101, 101, 101,
+ 128, 120, 116, 114, 112, 111, 109, 108,
+ 107, 106, 105, 104, 103, 102, 102, 101,
+ 100, 100, 99, 99, 98, 97, 97, 96,
+ 96, 96, 95, 95, 94, 94, 93, 93,
+ 128, 118, 114, 111, 109, 107, 106, 104,
+ 103, 102, 101, 100, 99, 98, 97, 97,
+ 96, 95, 95, 94, 93, 93, 92, 92,
+ 91, 91, 90, 90, 90, 89, 89, 88,
+ 128, 116, 112, 109, 107, 105, 103, 102,
+ 100, 99, 98, 97, 96, 95, 94, 93,
+ 93, 92, 91, 91, 90, 90, 89, 89,
+ 88, 88, 87, 87, 86, 86, 85, 85,
+ 128, 115, 111, 107, 105, 103, 101, 99,
+ 98, 97, 96, 94, 93, 93, 92, 91,
+ 90, 89, 89, 88, 88, 87, 86, 86,
+ 85, 85, 84, 84, 84, 83, 83, 82,
+ 128, 114, 109, 106, 103, 101, 99, 97,
+ 96, 95, 93, 92, 91, 90, 90, 89,
+ 88, 87, 87, 86, 85, 85, 84, 84,
+ 83, 83, 82, 82, 82, 81, 81, 80,
+ 128, 113, 108, 104, 102, 99, 97, 96,
+ 94, 93, 92, 91, 90, 89, 88, 87,
+ 86, 85, 85, 84, 84, 83, 83, 82,
+ 82, 81, 81, 80, 80, 79, 79, 79,
+ 128, 112, 107, 103, 100, 98, 96, 94,
+ 93, 91, 90, 89, 88, 87, 86, 85,
+ 85, 84, 83, 83, 82, 82, 81, 80,
+ 80, 80, 79, 79, 78, 78, 78, 77,
+ 128, 111, 106, 102, 99, 97, 95, 93,
+ 91, 90, 89, 88, 87, 86, 85, 84,
+ 83, 83, 82, 81, 81, 80, 80, 79,
+ 79, 78, 78, 77, 77, 77, 76, 76,
+ 128, 111, 105, 101, 98, 96, 93, 92,
+ 90, 89, 88, 86, 85, 84, 84, 83,
+ 82, 81, 81, 80, 80, 79, 79, 78,
+ 78, 77, 77, 76, 76, 76, 75, 75,
+ 128, 110, 104, 100, 97, 94, 92, 91,
+ 89, 88, 86, 85, 84, 83, 83, 82,
+ 81, 80, 80, 79, 79, 78, 78, 77,
+ 77, 76, 76, 75, 75, 75, 74, 74,
+ 128, 109, 103, 99, 96, 93, 91, 90,
+ 88, 87, 85, 84, 83, 82, 82, 81,
+ 80, 79, 79, 78, 78, 77, 77, 76,
+ 76, 75, 75, 75, 74, 74, 74, 73,
+ 128, 109, 102, 98, 95, 93, 90, 89,
+ 87, 86, 84, 83, 82, 81, 81, 80,
+ 79, 78, 78, 77, 77, 76, 76, 75,
+ 75, 75, 74, 74, 73, 73, 73, 73,
+ 128, 108, 102, 97, 94, 92, 90, 88,
+ 86, 85, 84, 83, 82, 81, 80, 79,
+ 78, 78, 77, 77, 76, 76, 75, 75,
+ 74, 74, 73, 73, 73, 73, 72, 72,
+ 128, 107, 101, 97, 93, 91, 89, 87,
+ 85, 84, 83, 82, 81, 80, 79, 78,
+ 78, 77, 76, 76, 75, 75, 74, 74,
+ 74, 73, 73, 73, 72, 72, 72, 71,
+ 128, 107, 100, 96, 93, 90, 88, 86,
+ 85, 83, 82, 81, 80, 79, 78, 78,
+ 77, 76, 76, 75, 75, 74, 74, 73,
+ 73, 73, 72, 72, 72, 71, 71, 71,
+ 128, 106, 100, 95, 92, 89, 87, 85,
+ 84, 83, 81, 80, 79, 78, 78, 77,
+ 76, 76, 75, 75, 74, 74, 73, 73,
+ 72, 72, 72, 72, 71, 71, 71, 70,
+ 128, 106, 99, 95, 91, 89, 87, 85,
+ 83, 82, 81, 80, 79, 78, 77, 76,
+ 76, 75, 75, 74, 74, 73, 73, 72,
+ 72, 72, 71, 71, 71, 71, 70, 70,
+ 128, 105, 99, 94, 91, 88, 86, 84,
+ 83, 81, 80, 79, 78, 77, 77, 76,
+ 75, 75, 74, 74, 73, 73, 72, 72,
+ 72, 71, 71, 71, 70, 70, 70, 70,
+ 128, 105, 98, 93, 90, 88, 85, 84,
+ 82, 81, 80, 79, 78, 77, 76, 75,
+ 75, 74, 74, 73, 73, 72, 72, 71,
+ 71, 71, 71, 70, 70, 70, 70, 69,
+ 128, 104, 97, 93, 90, 87, 85, 83,
+ 82, 80, 79, 78, 77, 76, 76, 75,
+ 74, 74, 73, 73, 72, 72, 71, 71,
+ 71, 70, 70, 70, 70, 69, 69, 69,
+ 128, 104, 97, 92, 89, 86, 84, 83,
+ 81, 80, 79, 78, 77, 76, 75, 74,
+ 74, 73, 73, 72, 72, 71, 71, 71,
+ 70, 70, 70, 70, 69, 69, 69, 69,
+ 128, 104, 96, 92, 89, 86, 84, 82,
+ 80, 79, 78, 77, 76, 75, 75, 74,
+ 73, 73, 72, 72, 71, 71, 71, 70,
+ 70, 70, 70, 69, 69, 69, 69, 68,
+ 128, 103, 96, 91, 88, 85, 83, 82,
+ 80, 79, 78, 77, 76, 75, 74, 74,
+ 73, 72, 72, 72, 71, 71, 70, 70,
+ 70, 70, 69, 69, 69, 69, 68, 68,
+ 128, 103, 96, 91, 88, 85, 83, 81,
+ 80, 78, 77, 76, 75, 75, 74, 73,
+ 73, 72, 72, 71, 71, 70, 70, 70,
+ 70, 69, 69, 69, 69, 68, 68, 68,
+ 128, 102, 95, 90, 87, 84, 82, 81,
+ 79, 78, 77, 76, 75, 74, 73, 73,
+ 72, 72, 71, 71, 71, 70, 70, 70,
+ 69, 69, 69, 69, 68, 68, 68, 68,
+ 128, 102, 95, 90, 87, 84, 82, 80,
+ 79, 77, 76, 75, 75, 74, 73, 73,
+ 72, 72, 71, 71, 70, 70, 70, 69,
+ 69, 69, 69, 68, 68, 68, 68, 68,
+ 128, 102, 94, 90, 86, 84, 82, 80,
+ 78, 77, 76, 75, 74, 73, 73, 72,
+ 72, 71, 71, 70, 70, 70, 69, 69,
+ 69, 69, 68, 68, 68, 68, 68, 67,
+ 128, 101, 94, 89, 86, 83, 81, 79,
+ 78, 77, 76, 75, 74, 73, 73, 72,
+ 71, 71, 71, 70, 70, 69, 69, 69,
+ 69, 68, 68, 68, 68, 68, 67, 67,
+ 128, 101, 93, 89, 85, 83, 81, 79,
+ 78, 76, 75, 74, 74, 73, 72, 72,
+ 71, 71, 70, 70, 70, 69, 69, 69,
+ 68, 68, 68, 68, 68, 67, 67, 67,
+ 128, 101, 93, 88, 85, 82, 80, 79,
+ 77, 76, 75, 74, 73, 73, 72, 71,
+ 71, 70, 70, 70, 69, 69, 69, 68,
+ 68, 68, 68, 68, 67, 67, 67, 67,
+ };
+ int size_scale = (size == 32 ? 1 :
+ size == 16 ? 2 :
+ size == 8 ? 4 : 8);
+ int i, j;
+ switch (mode) {
+ case V_PRED:
+ for (i = 0; i < size; ++i) {
+ for (j = 0; j < size; ++j) {
+ int k = i * interstride + j;
+ int scale = weights1d[i * size_scale];
+ interpred[k] =
+ ((scale_max - scale) * interpred[k] +
+ scale * intrapred[i * intrastride + j] + scale_round)
+ >> scale_bits;
+ }
+ }
+ break;
+
+ case H_PRED:
+ for (i = 0; i < size; ++i) {
+ for (j = 0; j < size; ++j) {
+ int k = i * interstride + j;
+ int scale = weights1d[j * size_scale];
+ interpred[k] =
+ ((scale_max - scale) * interpred[k] +
+ scale * intrapred[i * intrastride + j] + scale_round)
+ >> scale_bits;
+ }
+ }
+ break;
+
+ case D63_PRED:
+ case D117_PRED:
+ for (i = 0; i < size; ++i) {
+ for (j = 0; j < size; ++j) {
+ int k = i * interstride + j;
+ int scale = (weights2d[i * size_scale * 32 + j * size_scale] +
+ weights1d[i * size_scale]) >> 1;
+ interpred[k] =
+ ((scale_max - scale) * interpred[k] +
+ scale * intrapred[i * intrastride + j] + scale_round)
+ >> scale_bits;
+ }
+ }
+ break;
+
+ case D27_PRED:
+ case D153_PRED:
+ for (i = 0; i < size; ++i) {
+ for (j = 0; j < size; ++j) {
+ int k = i * interstride + j;
+ int scale = (weights2d[i * size_scale * 32 + j * size_scale] +
+ weights1d[j * size_scale]) >> 1;
+ interpred[k] =
+ ((scale_max - scale) * interpred[k] +
+ scale * intrapred[i * intrastride + j] + scale_round)
+ >> scale_bits;
+ }
+ }
+ break;
+
+ case D135_PRED:
+ for (i = 0; i < size; ++i) {
+ for (j = 0; j < size; ++j) {
+ int k = i * interstride + j;
+ int scale = weights2d[i * size_scale * 32 + j * size_scale];
+ interpred[k] =
+ ((scale_max - scale) * interpred[k] +
+ scale * intrapred[i * intrastride + j] + scale_round)
+ >> scale_bits;
+ }
+ }
+ break;
+
+ case D45_PRED:
+ case DC_PRED:
+ case TM_PRED:
+ default:
+ // simple average
+ for (i = 0; i < size; ++i) {
+ for (j = 0; j < size; ++j) {
+ int k = i * interstride + j;
+ interpred[k] = (interpred[k] + intrapred[i * intrastride + j]) >> 1;
+ }
+ }
+ break;
+ }
+}
+
+void vp9_build_interintra_16x16_predictors_mb(MACROBLOCKD *xd,
+ unsigned char *ypred,
+ unsigned char *upred,
+ unsigned char *vpred,
+ int ystride, int uvstride) {
+ vp9_build_interintra_16x16_predictors_mby(xd, ypred, ystride);
+ vp9_build_interintra_16x16_predictors_mbuv(xd, upred, vpred, uvstride);
+}
+
+void vp9_build_interintra_16x16_predictors_mby(MACROBLOCKD *xd,
+ unsigned char *ypred,
+ int ystride) {
+ static const int scale_bits = 6;
+ unsigned char intrapredictor[256];
+ int i, j;
+ vp9_build_intra_predictors_internal(
+ xd->dst.y_buffer, xd->dst.y_stride,
+ intrapredictor, 16,
+ xd->mode_info_context->mbmi.interintra_mode, 16,
+ xd->up_available, xd->left_available);
+ combine_interintra(xd->mode_info_context->mbmi.interintra_mode,
+ ypred, ystride, intrapredictor, 16, 16);
+}
+
+void vp9_build_interintra_16x16_predictors_mbuv(MACROBLOCKD *xd,
+ unsigned char *upred,
+ unsigned char *vpred,
+ int uvstride) {
+ int i, j;
+ unsigned char uintrapredictor[64];
+ unsigned char vintrapredictor[64];
+ vp9_build_intra_predictors_internal(
+ xd->dst.u_buffer, xd->dst.uv_stride,
+ uintrapredictor, 8,
+ xd->mode_info_context->mbmi.interintra_uv_mode, 8,
+ xd->up_available, xd->left_available);
+ vp9_build_intra_predictors_internal(
+ xd->dst.v_buffer, xd->dst.uv_stride,
+ vintrapredictor, 8,
+ xd->mode_info_context->mbmi.interintra_uv_mode, 8,
+ xd->up_available, xd->left_available);
+ combine_interintra(xd->mode_info_context->mbmi.interintra_uv_mode,
+ upred, uvstride, uintrapredictor, 8, 8);
+ combine_interintra(xd->mode_info_context->mbmi.interintra_uv_mode,
+ vpred, uvstride, vintrapredictor, 8, 8);
+}
+#endif
+
void vp9_build_intra_predictors_mby(MACROBLOCKD *xd) {
vp9_build_intra_predictors_internal(xd->dst.y_buffer, xd->dst.y_stride,
xd->predictor, 16,
@@ -460,11 +748,11 @@ void vp9_build_comp_intra_predictors_mbuv(MACROBLOCKD *xd) {
int i;
vp9_build_intra_predictors_mbuv_internal(
- xd, predictor[0][0], predictor[1][0], 8,
- xd->mode_info_context->mbmi.uv_mode, 8);
+ xd, predictor[0][0], predictor[1][0], 8,
+ xd->mode_info_context->mbmi.uv_mode, 8);
vp9_build_intra_predictors_mbuv_internal(
- xd, predictor[0][1], predictor[1][1], 8,
- xd->mode_info_context->mbmi.second_uv_mode, 8);
+ xd, predictor[0][1], predictor[1][1], 8,
+ xd->mode_info_context->mbmi.second_uv_mode, 8);
for (i = 0; i < 64; i++) {
xd->predictor[256 + i] = (predictor[0][0][i] + predictor[0][1][i] + 1) >> 1;
xd->predictor[256 + 64 + i] = (predictor[1][0][i] +
@@ -526,6 +814,6 @@ void vp9_comp_intra_uv4x4_predict(BLOCKD *xd,
#endif
/* TODO: try different ways of use Y-UV mode correlation
- Current code assumes that a uv 4x4 block use same mode
- as corresponding Y 8x8 area
- */
+ Current code assumes that a uv 4x4 block use same mode
+ as corresponding Y 8x8 area
+ */
diff --git a/vp9/common/reconintra.h b/vp9/common/reconintra.h
index 35a839db3..c72e8e912 100644
--- a/vp9/common/reconintra.h
+++ b/vp9/common/reconintra.h
@@ -17,5 +17,20 @@ extern void vp9_recon_intra_mbuv(MACROBLOCKD *xd);
extern B_PREDICTION_MODE vp9_find_dominant_direction(unsigned char *ptr,
int stride, int n);
extern B_PREDICTION_MODE vp9_find_bpred_context(BLOCKD *x);
+#if CONFIG_COMP_INTERINTRA_PRED
+extern void vp9_build_interintra_16x16_predictors_mb(MACROBLOCKD *xd,
+ unsigned char *ypred,
+ unsigned char *upred,
+ unsigned char *vpred,
+ int ystride,
+ int uvstride);
+extern void vp9_build_interintra_16x16_predictors_mby(MACROBLOCKD *xd,
+ unsigned char *ypred,
+ int ystride);
+extern void vp9_build_interintra_16x16_predictors_mbuv(MACROBLOCKD *xd,
+ unsigned char *upred,
+ unsigned char *vpred,
+ int uvstride);
+#endif
#endif // __INC_RECONINTRA_H
diff --git a/vp9/decoder/decodemv.c b/vp9/decoder/decodemv.c
index e7560765a..467a2958d 100644
--- a/vp9/decoder/decodemv.c
+++ b/vp9/decoder/decodemv.c
@@ -531,6 +531,12 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *bc) {
#endif
if (cm->mcomp_filter_type == SWITCHABLE)
read_switchable_interp_probs(pbi, bc);
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (cm->use_interintra) {
+ if (vp9_read(bc, VP9_UPD_INTERINTRA_PROB))
+ cm->fc.interintra_prob = (vp9_prob)vp9_read_literal(bc, 8);
+ }
+#endif
// Decode the baseline probabilities for decoding reference frame
cm->prob_intra_coded = (vp9_prob)vp9_read_literal(bc, 8);
cm->prob_last_coded = (vp9_prob)vp9_read_literal(bc, 8);
@@ -671,7 +677,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN;
mbmi->need_to_clamp_mvs = 0;
mbmi->need_to_clamp_secondmv = 0;
- mbmi->second_ref_frame = 0;
+ mbmi->second_ref_frame = NONE;
/* Distance of Mb to the various image edges.
* These specified to 8th pel as they are always compared to MV values that are in 1/8th pel units
*/
@@ -819,7 +825,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mbmi->second_ref_frame = mbmi->ref_frame + 1;
if (mbmi->second_ref_frame == 4)
mbmi->second_ref_frame = 1;
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
int second_ref_fb_idx;
/* Select the appropriate reference frame for this MB */
if (mbmi->second_ref_frame == LAST_FRAME)
@@ -852,7 +858,33 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
}
} else {
- mbmi->second_ref_frame = 0;
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (pbi->common.use_interintra &&
+ mbmi->mode >= NEARESTMV && mbmi->mode < SPLITMV &&
+ mbmi->second_ref_frame == NONE) {
+ mbmi->second_ref_frame = (vp9_read(bc, pbi->common.fc.interintra_prob) ?
+ INTRA_FRAME : NONE);
+ // printf("-- %d (%d)\n", mbmi->second_ref_frame == INTRA_FRAME,
+ // pbi->common.fc.interintra_prob);
+ pbi->common.fc.interintra_counts[
+ mbmi->second_ref_frame == INTRA_FRAME]++;
+ if (mbmi->second_ref_frame == INTRA_FRAME) {
+ mbmi->interintra_mode = (MB_PREDICTION_MODE)read_ymode(
+ bc, pbi->common.fc.ymode_prob);
+ pbi->common.fc.ymode_counts[mbmi->interintra_mode]++;
+#if SEPARATE_INTERINTRA_UV
+ mbmi->interintra_uv_mode = (MB_PREDICTION_MODE)read_uv_mode(
+ bc, pbi->common.fc.uv_mode_prob[mbmi->interintra_mode]);
+ pbi->common.fc.uv_mode_counts[mbmi->interintra_mode]
+ [mbmi->interintra_uv_mode]++;
+#else
+ mbmi->interintra_uv_mode = mbmi->interintra_mode;
+#endif
+ // printf("** %d %d\n",
+ // mbmi->interintra_mode, mbmi->interintra_uv_mode);
+ }
+ }
+#endif
}
mbmi->uv_mode = DC_PRED;
@@ -876,7 +908,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
leftmv.as_int = left_block_mv(mi, k);
abovemv.as_int = above_block_mv(mi, k, mis);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
second_leftmv.as_int = left_block_second_mv(mi, k);
second_abovemv.as_int = above_block_second_mv(mi, k, mis);
}
@@ -894,7 +926,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
blockmv.as_mv.row += best_mv.as_mv.row;
blockmv.as_mv.col += best_mv.as_mv.col;
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
read_nmv(bc, &secondmv.as_mv, &best_mv_second.as_mv, nmvc);
read_nmv_fp(bc, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
xd->allow_high_precision_mv);
@@ -909,7 +941,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
break;
case LEFT4X4:
blockmv.as_int = leftmv.as_int;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
secondmv.as_int = second_leftmv.as_int;
#ifdef VPX_MODE_COUNT
vp9_mv_cont_count[mv_contz][0]++;
@@ -917,7 +949,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
break;
case ABOVE4X4:
blockmv.as_int = abovemv.as_int;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
secondmv.as_int = second_abovemv.as_int;
#ifdef VPX_MODE_COUNT
vp9_mv_cont_count[mv_contz][1]++;
@@ -925,7 +957,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
break;
case ZERO4X4:
blockmv.as_int = 0;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
secondmv.as_int = 0;
#ifdef VPX_MODE_COUNT
vp9_mv_cont_count[mv_contz][2]++;
@@ -940,7 +972,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mb_to_right_edge,
mb_to_top_edge,
mb_to_bottom_edge);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
mbmi->need_to_clamp_mvs |= check_mv_bounds(&secondmv,
mb_to_left_edge,
mb_to_right_edge,
@@ -959,7 +991,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
do {
mi->bmi[ *fill_offset].as_mv.first.as_int = blockmv.as_int;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
mi->bmi[ *fill_offset].as_mv.second.as_int = secondmv.as_int;
fill_offset++;
} while (--fill_count);
@@ -978,7 +1010,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
/* Clip "next_nearest" so that it does not extend to far out of image */
clamp_mv(mv, mb_to_left_edge, mb_to_right_edge,
mb_to_top_edge, mb_to_bottom_edge);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
mbmi->mv[1].as_int = nearby_second.as_int;
clamp_mv(&mbmi->mv[1], mb_to_left_edge, mb_to_right_edge,
mb_to_top_edge, mb_to_bottom_edge);
@@ -990,7 +1022,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
/* Clip "next_nearest" so that it does not extend to far out of image */
clamp_mv(mv, mb_to_left_edge, mb_to_right_edge,
mb_to_top_edge, mb_to_bottom_edge);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
mbmi->mv[1].as_int = nearest_second.as_int;
clamp_mv(&mbmi->mv[1], mb_to_left_edge, mb_to_right_edge,
mb_to_top_edge, mb_to_bottom_edge);
@@ -999,7 +1031,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
case ZEROMV:
mv->as_int = 0;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
mbmi->mv[1].as_int = 0;
break;
@@ -1038,7 +1070,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mb_to_top_edge,
mb_to_bottom_edge);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
#if CONFIG_NEW_MVREF
{
int best_index;
diff --git a/vp9/decoder/decodframe.c b/vp9/decoder/decodframe.c
index 5b56b158a..d9413b7ab 100644
--- a/vp9/decoder/decodframe.c
+++ b/vp9/decoder/decodframe.c
@@ -185,20 +185,39 @@ static void skip_recon_mb(VP9D_COMP *pbi, MACROBLOCKD *xd) {
} else {
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
- vp9_build_inter32x32_predictors_sb(xd, xd->dst.y_buffer,
- xd->dst.u_buffer, xd->dst.v_buffer,
- xd->dst.y_stride, xd->dst.uv_stride);
+ vp9_build_inter32x32_predictors_sb(xd,
+ xd->dst.y_buffer,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.y_stride,
+ xd->dst.uv_stride);
} else {
#endif
- vp9_build_1st_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
- xd->dst.u_buffer, xd->dst.v_buffer,
- xd->dst.y_stride, xd->dst.uv_stride);
-
- if (xd->mode_info_context->mbmi.second_ref_frame) {
- vp9_build_2nd_inter16x16_predictors_mb(xd, xd->dst.y_buffer,
- xd->dst.u_buffer, xd->dst.v_buffer,
- xd->dst.y_stride, xd->dst.uv_stride);
+ vp9_build_1st_inter16x16_predictors_mb(xd,
+ xd->dst.y_buffer,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.y_stride,
+ xd->dst.uv_stride);
+
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
+ vp9_build_2nd_inter16x16_predictors_mb(xd,
+ xd->dst.y_buffer,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.y_stride,
+ xd->dst.uv_stride);
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ else if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) {
+ vp9_build_interintra_16x16_predictors_mb(xd,
+ xd->dst.y_buffer,
+ xd->dst.u_buffer,
+ xd->dst.v_buffer,
+ xd->dst.y_stride,
+ xd->dst.uv_stride);
+ }
+#endif
#if CONFIG_SUPERBLOCKS
}
#endif
@@ -707,7 +726,7 @@ decode_sb_row(VP9D_COMP *pbi, VP9_COMMON *pc, int mbrow, MACROBLOCKD *xd,
xd->pre.u_buffer = pc->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
xd->pre.v_buffer = pc->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
- if (xd->mode_info_context->mbmi.second_ref_frame) {
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
int second_ref_fb_idx;
/* Select the appropriate reference frame for this MB */
@@ -1281,6 +1300,9 @@ int vp9_decode_frame(VP9D_COMP *pbi) {
} else {
pc->mcomp_filter_type = vp9_read_literal(&header_bc, 2);
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ pc->use_interintra = vp9_read_bit(&header_bc);
+#endif
/* To enable choice of different interploation filters */
vp9_setup_interp_filters(xd, pc->mcomp_filter_type, pc);
}
@@ -1323,6 +1345,9 @@ int vp9_decode_frame(VP9D_COMP *pbi) {
vp9_copy(pbi->common.fc.pre_i8x8_mode_prob, pbi->common.fc.i8x8_mode_prob);
vp9_copy(pbi->common.fc.pre_sub_mv_ref_prob, pbi->common.fc.sub_mv_ref_prob);
vp9_copy(pbi->common.fc.pre_mbsplit_prob, pbi->common.fc.mbsplit_prob);
+#if CONFIG_COMP_INTERINTRA_PRED
+ pbi->common.fc.pre_interintra_prob = pbi->common.fc.interintra_prob;
+#endif
pbi->common.fc.pre_nmvc = pbi->common.fc.nmvc;
vp9_zero(pbi->common.fc.coef_counts);
vp9_zero(pbi->common.fc.hybrid_coef_counts);
@@ -1339,6 +1364,9 @@ int vp9_decode_frame(VP9D_COMP *pbi) {
vp9_zero(pbi->common.fc.NMVcount);
vp9_zero(pbi->common.fc.mv_ref_ct);
vp9_zero(pbi->common.fc.mv_ref_ct_a);
+#if CONFIG_COMP_INTERINTRA_PRED
+ vp9_zero(pbi->common.fc.interintra_counts);
+#endif
read_coef_probs(pbi, &header_bc);
diff --git a/vp9/encoder/bitstream.c b/vp9/encoder/bitstream.c
index 65614a176..a71472df3 100644
--- a/vp9/encoder/bitstream.c
+++ b/vp9/encoder/bitstream.c
@@ -338,6 +338,21 @@ static int prob_diff_update_savings_search(const unsigned int *ct,
return bestsavings;
}
+static void vp9_cond_prob_update(vp9_writer *bc, vp9_prob *oldp, vp9_prob upd,
+ unsigned int *ct) {
+ vp9_prob newp;
+ int savings;
+ newp = get_binary_prob(ct[0], ct[1]);
+ savings = prob_update_savings(ct, *oldp, newp, upd);
+ if (savings > 0) {
+ vp9_write(bc, 1, upd);
+ vp9_write_literal(bc, newp, 8);
+ *oldp = newp;
+ } else {
+ vp9_write(bc, 0, upd);
+ }
+}
+
static void pack_mb_tokens(vp9_writer* const bc,
TOKENEXTRA **tp,
const TOKENEXTRA *const stop) {
@@ -975,7 +990,7 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
}
}
- if (mi->second_ref_frame &&
+ if (mi->second_ref_frame > 0 &&
(mode == NEWMV || mode == SPLITMV)) {
int_mv n1, n2;
@@ -986,9 +1001,30 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
// does the feature use compound prediction or not
// (if not specified at the frame/segment level)
if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
- vp9_write(bc, mi->second_ref_frame != INTRA_FRAME,
+ vp9_write(bc, mi->second_ref_frame > INTRA_FRAME,
vp9_get_pred_prob(pc, xd, PRED_COMP));
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (cpi->common.use_interintra &&
+ mode >= NEARESTMV && mode < SPLITMV &&
+ mi->second_ref_frame <= INTRA_FRAME) {
+ vp9_write(bc, mi->second_ref_frame == INTRA_FRAME,
+ pc->fc.interintra_prob);
+ // if (!cpi->dummy_packing)
+ // printf("-- %d (%d)\n", mi->second_ref_frame == INTRA_FRAME,
+ // pc->fc.interintra_prob);
+ if (mi->second_ref_frame == INTRA_FRAME) {
+ // if (!cpi->dummy_packing)
+ // printf("** %d %d\n", mi->interintra_mode,
+ // mi->interintra_uv_mode);
+ write_ymode(bc, mi->interintra_mode, pc->fc.ymode_prob);
+#if SEPARATE_INTERINTRA_UV
+ write_uv_mode(bc, mi->interintra_uv_mode,
+ pc->fc.uv_mode_prob[mi->interintra_mode]);
+#endif
+ }
+ }
+#endif
{
switch (mode) { /* new, split require MVs */
@@ -1024,7 +1060,7 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
(const nmv_context*) nmvc,
xd->allow_high_precision_mv);
- if (mi->second_ref_frame) {
+ if (mi->second_ref_frame > 0) {
#if CONFIG_NEW_MVREF
unsigned int best_index;
sec_ref_frame = mi->second_ref_frame;
@@ -1095,7 +1131,7 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
(const nmv_context*) nmvc,
xd->allow_high_precision_mv);
- if (mi->second_ref_frame) {
+ if (mi->second_ref_frame > 0) {
write_nmv(bc,
&cpi->mb.partition_info->bmi[j].second_mv.as_mv,
&best_second_mv,
@@ -2021,6 +2057,15 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
vp9_write_bit(&header_bc, (pc->mcomp_filter_type == SWITCHABLE));
if (pc->mcomp_filter_type != SWITCHABLE)
vp9_write_literal(&header_bc, (pc->mcomp_filter_type), 2);
+#if CONFIG_COMP_INTERINTRA_PRED
+ // printf("Counts: %d %d\n", cpi->interintra_count[0],
+ // cpi->interintra_count[1]);
+ if (!cpi->dummy_packing && pc->use_interintra)
+ pc->use_interintra = (cpi->interintra_count[1] > 0);
+ vp9_write_bit(&header_bc, pc->use_interintra);
+ if (!pc->use_interintra)
+ vp9_zero(cpi->interintra_count);
+#endif
}
vp9_write_bit(&header_bc, pc->refresh_entropy_probs);
@@ -2050,6 +2095,9 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
vp9_copy(cpi->common.fc.pre_mbsplit_prob, cpi->common.fc.mbsplit_prob);
vp9_copy(cpi->common.fc.pre_i8x8_mode_prob, cpi->common.fc.i8x8_mode_prob);
cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc;
+#if CONFIG_COMP_INTERINTRA_PRED
+ cpi->common.fc.pre_interintra_prob = cpi->common.fc.interintra_prob;
+#endif
vp9_zero(cpi->sub_mv_ref_count);
vp9_zero(cpi->mbsplit_count);
vp9_zero(cpi->common.fc.mv_ref_ct)
@@ -2094,6 +2142,14 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
#endif
if (pc->mcomp_filter_type == SWITCHABLE)
update_switchable_interp_probs(cpi, &header_bc);
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (pc->use_interintra) {
+ vp9_cond_prob_update(&header_bc,
+ &pc->fc.interintra_prob,
+ VP9_UPD_INTERINTRA_PROB,
+ cpi->interintra_count);
+ }
+#endif
vp9_write_literal(&header_bc, pc->prob_intra_coded, 8);
vp9_write_literal(&header_bc, pc->prob_last_coded, 8);
@@ -2116,7 +2172,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
}
}
}
-
update_mbintra_mode_probs(cpi, &header_bc);
vp9_write_nmv_probs(cpi, xd->allow_high_precision_mv, &header_bc);
diff --git a/vp9/encoder/encodeframe.c b/vp9/encoder/encodeframe.c
index 98e03d6f7..b91cd04a2 100644
--- a/vp9/encoder/encodeframe.c
+++ b/vp9/encoder/encodeframe.c
@@ -578,6 +578,20 @@ static void update_state(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->best_second_mv.as_int = best_second_mv.as_int;
vp9_update_nmv_count(cpi, x, &best_mv, &best_second_mv);
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (mbmi->mode >= NEARESTMV && mbmi->mode < SPLITMV &&
+ mbmi->second_ref_frame <= INTRA_FRAME) {
+ if (mbmi->second_ref_frame == INTRA_FRAME) {
+ ++cpi->interintra_count[1];
+ ++cpi->ymode_count[mbmi->interintra_mode];
+#if SEPARATE_INTERINTRA_UV
+ ++cpi->y_uv_mode_count[mbmi->interintra_mode][mbmi->interintra_uv_mode];
+#endif
+ } else {
+ ++cpi->interintra_count[0];
+ }
+ }
+#endif
cpi->prediction_error += ctx->distortion;
cpi->intra_error += ctx->intra_error;
@@ -1114,7 +1128,7 @@ static void encode_sb(VP9_COMP *cpi,
pred_context = vp9_get_pred_context(cm, xd, PRED_COMP);
- if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME)
+ if (xd->mode_info_context->mbmi.second_ref_frame <= INTRA_FRAME)
cpi->single_pred_count[pred_context]++;
else
cpi->comp_pred_count[pred_context]++;
@@ -1393,6 +1407,10 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
vp9_zero(cpi->sb_ymode_count)
cpi->sb_count = 0;
#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+ vp9_zero(cpi->interintra_count);
+ vp9_zero(cpi->interintra_select_count);
+#endif
vpx_memset(cm->above_context, 0,
sizeof(ENTROPY_CONTEXT_PLANES) * cm->mb_cols);
@@ -2219,7 +2237,7 @@ static void encode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
xd->pre.u_buffer = cpi->common.yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
xd->pre.v_buffer = cpi->common.yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
int second_ref_fb_idx;
if (mbmi->second_ref_frame == LAST_FRAME)
@@ -2406,7 +2424,7 @@ static void encode_inter_superblock(VP9_COMP *cpi, MACROBLOCK *x,
xd->pre.u_buffer = cpi->common.yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
xd->pre.v_buffer = cpi->common.yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;
- if (xd->mode_info_context->mbmi.second_ref_frame) {
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0) {
int second_ref_fb_idx;
if (xd->mode_info_context->mbmi.second_ref_frame == LAST_FRAME)
diff --git a/vp9/encoder/encodemv.c b/vp9/encoder/encodemv.c
index 04aa95d03..8b9c170a1 100644
--- a/vp9/encoder/encodemv.c
+++ b/vp9/encoder/encodemv.c
@@ -610,7 +610,7 @@ void vp9_update_nmv_count(VP9_COMP *cpi, MACROBLOCK *x,
mv.col = (x->partition_info->bmi[i].mv.as_mv.col
- best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 1);
- if (x->e_mbd.mode_info_context->mbmi.second_ref_frame) {
+ if (x->e_mbd.mode_info_context->mbmi.second_ref_frame > 0) {
mv.row = (x->partition_info->bmi[i].second_mv.as_mv.row
- second_best_ref_mv->as_mv.row);
mv.col = (x->partition_info->bmi[i].second_mv.as_mv.col
@@ -624,7 +624,7 @@ void vp9_update_nmv_count(VP9_COMP *cpi, MACROBLOCK *x,
mv.col = (x->partition_info->bmi[i].mv.as_mv.col
- best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 0);
- if (x->e_mbd.mode_info_context->mbmi.second_ref_frame) {
+ if (x->e_mbd.mode_info_context->mbmi.second_ref_frame > 0) {
mv.row = (x->partition_info->bmi[i].second_mv.as_mv.row
- second_best_ref_mv->as_mv.row);
mv.col = (x->partition_info->bmi[i].second_mv.as_mv.col
@@ -640,7 +640,7 @@ void vp9_update_nmv_count(VP9_COMP *cpi, MACROBLOCK *x,
mv.row = (mbmi->mv[0].as_mv.row - best_ref_mv->as_mv.row);
mv.col = (mbmi->mv[0].as_mv.col - best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 1);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
mv.row = (mbmi->mv[1].as_mv.row - second_best_ref_mv->as_mv.row);
mv.col = (mbmi->mv[1].as_mv.col - second_best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &second_best_ref_mv->as_mv, &cpi->NMVcount, 1);
@@ -649,7 +649,7 @@ void vp9_update_nmv_count(VP9_COMP *cpi, MACROBLOCK *x,
mv.row = (mbmi->mv[0].as_mv.row - best_ref_mv->as_mv.row);
mv.col = (mbmi->mv[0].as_mv.col - best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, 0);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
mv.row = (mbmi->mv[1].as_mv.row - second_best_ref_mv->as_mv.row);
mv.col = (mbmi->mv[1].as_mv.col - second_best_ref_mv->as_mv.col);
vp9_increment_nmv(&mv, &second_best_ref_mv->as_mv, &cpi->NMVcount, 0);
diff --git a/vp9/encoder/onyx_if.c b/vp9/encoder/onyx_if.c
index 249572d04..215436134 100644
--- a/vp9/encoder/onyx_if.c
+++ b/vp9/encoder/onyx_if.c
@@ -224,6 +224,7 @@ static void init_minq_luts(void) {
}
}
+
static void set_mvcost(MACROBLOCK *mb) {
if (mb->e_mbd.allow_high_precision_mv) {
mb->mvcost = mb->nmvcost_hp;
@@ -788,6 +789,21 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->thresh_mult[THR_COMP_SPLITGA ] = 5000;
sf->thresh_mult[THR_COMP_SPLITLG ] = 5000;
+#if CONFIG_COMP_INTERINTRA_PRED
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTL] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTG] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROA ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTA] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARA ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWA ] = 0;
+#endif
+
sf->first_step = 0;
sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
sf->search_best_filter = SEARCH_BEST_FILTER;
@@ -912,6 +928,20 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->thresh_mult[THR_COMP_SPLITLA ] = 1700;
sf->thresh_mult[THR_COMP_SPLITGA ] = 4500;
sf->thresh_mult[THR_COMP_SPLITLG ] = 4500;
+#if CONFIG_COMP_INTERINTRA_PRED
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTL] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTG] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROA ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTA] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARA ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWA ] = 0;
+#endif
if (Speed > 0) {
/* Disable coefficient optimization above speed 0 */
@@ -1002,6 +1032,20 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->thresh_mult[THR_COMP_NEWLG ] = 2000;
sf->thresh_mult[THR_COMP_NEWLA ] = 2000;
sf->thresh_mult[THR_COMP_NEWGA ] = 2000;
+#if CONFIG_COMP_INTERINTRA_PRED
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTL] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTG] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROA ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTA] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARA ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWA ] = 0;
+#endif
}
if (Speed > 2) {
@@ -1077,6 +1121,20 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->thresh_mult[THR_COMP_NEWLG ] = 2500;
sf->thresh_mult[THR_COMP_NEWLA ] = 2500;
sf->thresh_mult[THR_COMP_NEWGA ] = 2500;
+#if CONFIG_COMP_INTERINTRA_PRED
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTL] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWL ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTG] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWG ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROA ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTA] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARA ] = 0;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWA ] = 0;
+#endif
sf->improved_dct = 0;
@@ -1116,6 +1174,12 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->thresh_mult[THR_NEARG_FILT ] = INT_MAX;
sf->thresh_mult[THR_NEWG_FILT ] = INT_MAX;
#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROG ] = INT_MAX;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTG] = INT_MAX;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARG ] = INT_MAX;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWG ] = INT_MAX;
+#endif
sf->thresh_mult[THR_SPLITG ] = INT_MAX;
}
@@ -1130,6 +1194,12 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->thresh_mult[THR_NEARA_FILT ] = INT_MAX;
sf->thresh_mult[THR_NEWA_FILT ] = INT_MAX;
#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROA ] = INT_MAX;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTA] = INT_MAX;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARA ] = INT_MAX;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWA ] = INT_MAX;
+#endif
sf->thresh_mult[THR_SPLITA ] = INT_MAX;
}
@@ -1156,6 +1226,14 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->thresh_mult[THR_COMP_NEWGA ] = INT_MAX;
sf->thresh_mult[THR_COMP_SPLITGA ] = INT_MAX;
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ if ((cpi->ref_frame_flags & VP9_LAST_FLAG) != VP9_LAST_FLAG) {
+ sf->thresh_mult[THR_COMP_INTERINTRA_ZEROL ] = INT_MAX;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARESTL] = INT_MAX;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEARL ] = INT_MAX;
+ sf->thresh_mult[THR_COMP_INTERINTRA_NEWL ] = INT_MAX;
+ }
+#endif
// Slow quant, dct and trellis not worthwhile for first pass
// so make sure they are always turned off.
@@ -2850,6 +2928,19 @@ void update_pred_filt_prob(VP9_COMP *cpi) {
*/
}
#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+static void select_interintra_mode(VP9_COMP *cpi) {
+ static const double threshold = 0.01;
+ VP9_COMMON *cm = &cpi->common;
+ // FIXME(debargha): Make this RD based
+ int sum = cpi->interintra_select_count[1] + cpi->interintra_select_count[0];
+ if (sum) {
+ double fraction = (double) cpi->interintra_select_count[1] / sum;
+ // printf("fraction: %f\n", fraction);
+ cm->use_interintra = (fraction > threshold);
+ }
+}
+#endif
static void encode_frame_to_data_rate
(
@@ -3144,6 +3235,12 @@ static void encode_frame_to_data_rate
set_mvcost(&cpi->mb);
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (cm->current_video_frame == 0) {
+ cm->use_interintra = 1;
+ }
+#endif
+
#if CONFIG_POSTPROC
if (cpi->oxcf.noise_sensitivity > 0) {
@@ -3634,6 +3731,9 @@ static void encode_frame_to_data_rate
vp9_copy(cpi->common.fc.i8x8_mode_counts, cpi->i8x8_mode_count);
vp9_copy(cpi->common.fc.sub_mv_ref_counts, cpi->sub_mv_ref_count);
vp9_copy(cpi->common.fc.mbsplit_counts, cpi->mbsplit_count);
+#if CONFIG_COMP_INTERINTRA_PRED
+ vp9_copy(cpi->common.fc.interintra_counts, cpi->interintra_count);
+#endif
vp9_adapt_mode_probs(&cpi->common);
cpi->common.fc.NMVcount = cpi->NMVcount;
@@ -3644,6 +3744,10 @@ static void encode_frame_to_data_rate
vp9_adapt_nmv_probs(&cpi->common, cpi->mb.e_mbd.allow_high_precision_mv);
vp9_update_mode_context(&cpi->common);
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (cm->frame_type != KEY_FRAME)
+ select_interintra_mode(cpi);
+#endif
/* Move storing frame_type out of the above loop since it is also
* needed in motion search besides loopfilter */
diff --git a/vp9/encoder/onyx_int.h b/vp9/encoder/onyx_int.h
index 2a9fd68b1..e1ddd45fb 100644
--- a/vp9/encoder/onyx_int.h
+++ b/vp9/encoder/onyx_int.h
@@ -43,9 +43,17 @@
#define ARF_DECAY_THRESH 12
#if CONFIG_PRED_FILTER
+#if CONFIG_COMP_INTERINTRA_PRED
+#define MAX_MODES 66
+#else
#define MAX_MODES 54
+#endif
#else // CONFIG_PRED_FILTER
+#if CONFIG_COMP_INTERINTRA_PRED
+#define MAX_MODES 54
+#else
#define MAX_MODES 42
+#endif
#endif // CONFIG_PRED_FILTER
#define MIN_THRESHMULT 32
@@ -111,6 +119,9 @@ typedef struct {
vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
[VP9_SWITCHABLE_FILTERS - 1];
+#if CONFIG_COMP_INTERINTRA_PRED
+ vp9_prob interintra_prob;
+#endif
int mv_ref_ct[6][4][2];
int mode_context[6][4];
@@ -238,6 +249,22 @@ typedef enum {
THR_COMP_SPLITLG,
THR_COMP_SPLITLA,
THR_COMP_SPLITGA,
+#if CONFIG_COMP_INTERINTRA_PRED
+ THR_COMP_INTERINTRA_ZEROL,
+ THR_COMP_INTERINTRA_NEARESTL,
+ THR_COMP_INTERINTRA_NEARL,
+ THR_COMP_INTERINTRA_NEWL,
+
+ 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
}
THR_MODES;
#else
@@ -296,7 +323,23 @@ typedef enum {
THR_COMP_SPLITLG,
THR_COMP_SPLITLA,
- THR_COMP_SPLITGA
+ THR_COMP_SPLITGA,
+#if CONFIG_COMP_INTERINTRA_PRED
+ THR_COMP_INTERINTRA_ZEROL,
+ THR_COMP_INTERINTRA_NEARESTL,
+ THR_COMP_INTERINTRA_NEARL,
+ THR_COMP_INTERINTRA_NEWL,
+
+ 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
}
THR_MODES;
#endif
@@ -539,6 +582,10 @@ typedef struct VP9_COMP {
int sub_mv_ref_count[SUBMVREF_COUNT][VP9_SUBMVREFS];
int mbsplit_count[VP9_NUMMBSPLITS];
int y_uv_mode_count[VP9_YMODES][VP9_UV_MODES];
+#if CONFIG_COMP_INTERINTRA_PRED
+ int interintra_count[2];
+ int interintra_select_count[2];
+#endif
nmv_context_counts NMVcount;
@@ -751,7 +798,6 @@ typedef struct VP9_COMP {
#endif
unsigned int switchable_interp_count[VP9_SWITCHABLE_FILTERS + 1]
[VP9_SWITCHABLE_FILTERS];
-
#if CONFIG_NEW_MVREF
unsigned int best_ref_index_counts[MAX_REF_FRAMES][MAX_MV_REFS];
#endif
diff --git a/vp9/encoder/ratectrl.c b/vp9/encoder/ratectrl.c
index b499f1df0..097a54d5a 100644
--- a/vp9/encoder/ratectrl.c
+++ b/vp9/encoder/ratectrl.c
@@ -175,6 +175,9 @@ void vp9_save_coding_context(VP9_COMP *cpi) {
vp9_copy(cc->coef_probs_16x16, cm->fc.coef_probs_16x16);
vp9_copy(cc->hybrid_coef_probs_16x16, cm->fc.hybrid_coef_probs_16x16);
vp9_copy(cc->switchable_interp_prob, cm->fc.switchable_interp_prob);
+#if CONFIG_COMP_INTERINTRA_PRED
+ cc->interintra_prob = cm->fc.interintra_prob;
+#endif
}
void vp9_restore_coding_context(VP9_COMP *cpi) {
@@ -231,6 +234,9 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
vp9_copy(cm->fc.coef_probs_16x16, cc->coef_probs_16x16);
vp9_copy(cm->fc.hybrid_coef_probs_16x16, cc->hybrid_coef_probs_16x16);
vp9_copy(cm->fc.switchable_interp_prob, cc->switchable_interp_prob);
+#if CONFIG_COMP_INTERINTRA_PRED
+ cm->fc.interintra_prob = cc->interintra_prob;
+#endif
}
diff --git a/vp9/encoder/rdopt.c b/vp9/encoder/rdopt.c
index 2a08ae8a1..1054e432f 100644
--- a/vp9/encoder/rdopt.c
+++ b/vp9/encoder/rdopt.c
@@ -78,54 +78,54 @@ static const int auto_speed_thresh[17] = {
#if CONFIG_PRED_FILTER
const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
- {ZEROMV, LAST_FRAME, 0, 0},
- {ZEROMV, LAST_FRAME, 0, 1},
- {DC_PRED, INTRA_FRAME, 0, 0},
-
- {NEARESTMV, LAST_FRAME, 0, 0},
- {NEARESTMV, LAST_FRAME, 0, 1},
- {NEARMV, LAST_FRAME, 0, 0},
- {NEARMV, LAST_FRAME, 0, 1},
-
- {ZEROMV, GOLDEN_FRAME, 0, 0},
- {ZEROMV, GOLDEN_FRAME, 0, 1},
- {NEARESTMV, GOLDEN_FRAME, 0, 0},
- {NEARESTMV, GOLDEN_FRAME, 0, 1},
-
- {ZEROMV, ALTREF_FRAME, 0, 0},
- {ZEROMV, ALTREF_FRAME, 0, 1},
- {NEARESTMV, ALTREF_FRAME, 0, 0},
- {NEARESTMV, ALTREF_FRAME, 0, 1},
-
- {NEARMV, GOLDEN_FRAME, 0, 0},
- {NEARMV, GOLDEN_FRAME, 0, 1},
- {NEARMV, ALTREF_FRAME, 0, 0},
- {NEARMV, ALTREF_FRAME, 0, 1},
-
- {V_PRED, INTRA_FRAME, 0, 0},
- {H_PRED, INTRA_FRAME, 0, 0},
- {D45_PRED, INTRA_FRAME, 0, 0},
- {D135_PRED, INTRA_FRAME, 0, 0},
- {D117_PRED, INTRA_FRAME, 0, 0},
- {D153_PRED, INTRA_FRAME, 0, 0},
- {D27_PRED, INTRA_FRAME, 0, 0},
- {D63_PRED, INTRA_FRAME, 0, 0},
-
- {TM_PRED, INTRA_FRAME, 0, 0},
-
- {NEWMV, LAST_FRAME, 0, 0},
- {NEWMV, LAST_FRAME, 0, 1},
- {NEWMV, GOLDEN_FRAME, 0, 0},
- {NEWMV, GOLDEN_FRAME, 0, 1},
- {NEWMV, ALTREF_FRAME, 0, 0},
- {NEWMV, ALTREF_FRAME, 0, 1},
-
- {SPLITMV, LAST_FRAME, 0, 0},
- {SPLITMV, GOLDEN_FRAME, 0, 0},
- {SPLITMV, ALTREF_FRAME, 0, 0},
-
- {B_PRED, INTRA_FRAME, 0, 0},
- {I8X8_PRED, INTRA_FRAME, 0, 0},
+ {ZEROMV, LAST_FRAME, NONE, 0},
+ {ZEROMV, LAST_FRAME, NONE, 1},
+ {DC_PRED, INTRA_FRAME, NONE, 0},
+
+ {NEARESTMV, LAST_FRAME, NONE, 0},
+ {NEARESTMV, LAST_FRAME, NONE, 1},
+ {NEARMV, LAST_FRAME, NONE, 0},
+ {NEARMV, LAST_FRAME, NONE, 1},
+
+ {ZEROMV, GOLDEN_FRAME, NONE, 0},
+ {ZEROMV, GOLDEN_FRAME, NONE, 1},
+ {NEARESTMV, GOLDEN_FRAME, NONE, 0},
+ {NEARESTMV, GOLDEN_FRAME, NONE, 1},
+
+ {ZEROMV, ALTREF_FRAME, NONE, 0},
+ {ZEROMV, ALTREF_FRAME, NONE, 1},
+ {NEARESTMV, ALTREF_FRAME, NONE, 0},
+ {NEARESTMV, ALTREF_FRAME, NONE, 1},
+
+ {NEARMV, GOLDEN_FRAME, NONE, 0},
+ {NEARMV, GOLDEN_FRAME, NONE, 1},
+ {NEARMV, ALTREF_FRAME, NONE, 0},
+ {NEARMV, ALTREF_FRAME, NONE, 1},
+
+ {V_PRED, INTRA_FRAME, NONE, 0},
+ {H_PRED, INTRA_FRAME, NONE, 0},
+ {D45_PRED, INTRA_FRAME, NONE, 0},
+ {D135_PRED, INTRA_FRAME, NONE, 0},
+ {D117_PRED, INTRA_FRAME, NONE, 0},
+ {D153_PRED, INTRA_FRAME, NONE, 0},
+ {D27_PRED, INTRA_FRAME, NONE, 0},
+ {D63_PRED, INTRA_FRAME, NONE, 0},
+
+ {TM_PRED, INTRA_FRAME, NONE, 0},
+
+ {NEWMV, LAST_FRAME, NONE, 0},
+ {NEWMV, LAST_FRAME, NONE, 1},
+ {NEWMV, GOLDEN_FRAME, NONE, 0},
+ {NEWMV, GOLDEN_FRAME, NONE, 1},
+ {NEWMV, ALTREF_FRAME, NONE, 0},
+ {NEWMV, ALTREF_FRAME, NONE, 1},
+
+ {SPLITMV, LAST_FRAME, NONE, 0},
+ {SPLITMV, GOLDEN_FRAME, NONE, 0},
+ {SPLITMV, ALTREF_FRAME, NONE, 0},
+
+ {B_PRED, INTRA_FRAME, NONE, 0},
+ {I8X8_PRED, INTRA_FRAME, NONE, 0},
/* compound prediction modes */
{ZEROMV, LAST_FRAME, GOLDEN_FRAME, 0},
@@ -146,46 +146,64 @@ const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
{SPLITMV, LAST_FRAME, GOLDEN_FRAME, 0},
{SPLITMV, ALTREF_FRAME, LAST_FRAME, 0},
- {SPLITMV, GOLDEN_FRAME, ALTREF_FRAME, 0}
+ {SPLITMV, GOLDEN_FRAME, ALTREF_FRAME, 0},
+
+#if CONFIG_COMP_INTERINTRA_PRED
+ /* compound inter-intra prediction */
+ {ZEROMV, LAST_FRAME, INTRA_FRAME, 0},
+ {NEARESTMV, LAST_FRAME, INTRA_FRAME, 0},
+ {NEARMV, LAST_FRAME, INTRA_FRAME, 0},
+ {NEWMV, LAST_FRAME, INTRA_FRAME, 0},
+
+ {ZEROMV, GOLDEN_FRAME, INTRA_FRAME, 0},
+ {NEARESTMV, GOLDEN_FRAME, INTRA_FRAME, 0},
+ {NEARMV, GOLDEN_FRAME, INTRA_FRAME, 0},
+ {NEWMV, GOLDEN_FRAME, INTRA_FRAME, 0},
+
+ {ZEROMV, ALTREF_FRAME, INTRA_FRAME, 0},
+ {NEARESTMV, ALTREF_FRAME, INTRA_FRAME, 0},
+ {NEARMV, ALTREF_FRAME, INTRA_FRAME, 0},
+ {NEWMV, ALTREF_FRAME, INTRA_FRAME, 0},
+#endif
};
#else
const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
- {ZEROMV, LAST_FRAME, 0},
- {DC_PRED, INTRA_FRAME, 0},
+ {ZEROMV, LAST_FRAME, NONE},
+ {DC_PRED, INTRA_FRAME, NONE},
- {NEARESTMV, LAST_FRAME, 0},
- {NEARMV, LAST_FRAME, 0},
+ {NEARESTMV, LAST_FRAME, NONE},
+ {NEARMV, LAST_FRAME, NONE},
- {ZEROMV, GOLDEN_FRAME, 0},
- {NEARESTMV, GOLDEN_FRAME, 0},
+ {ZEROMV, GOLDEN_FRAME, NONE},
+ {NEARESTMV, GOLDEN_FRAME, NONE},
- {ZEROMV, ALTREF_FRAME, 0},
- {NEARESTMV, ALTREF_FRAME, 0},
+ {ZEROMV, ALTREF_FRAME, NONE},
+ {NEARESTMV, ALTREF_FRAME, NONE},
- {NEARMV, GOLDEN_FRAME, 0},
- {NEARMV, ALTREF_FRAME, 0},
+ {NEARMV, GOLDEN_FRAME, NONE},
+ {NEARMV, ALTREF_FRAME, NONE},
- {V_PRED, INTRA_FRAME, 0},
- {H_PRED, INTRA_FRAME, 0},
- {D45_PRED, INTRA_FRAME, 0},
- {D135_PRED, INTRA_FRAME, 0},
- {D117_PRED, INTRA_FRAME, 0},
- {D153_PRED, INTRA_FRAME, 0},
- {D27_PRED, INTRA_FRAME, 0},
- {D63_PRED, INTRA_FRAME, 0},
+ {V_PRED, INTRA_FRAME, NONE},
+ {H_PRED, INTRA_FRAME, NONE},
+ {D45_PRED, INTRA_FRAME, NONE},
+ {D135_PRED, INTRA_FRAME, NONE},
+ {D117_PRED, INTRA_FRAME, NONE},
+ {D153_PRED, INTRA_FRAME, NONE},
+ {D27_PRED, INTRA_FRAME, NONE},
+ {D63_PRED, INTRA_FRAME, NONE},
- {TM_PRED, INTRA_FRAME, 0},
+ {TM_PRED, INTRA_FRAME, NONE},
- {NEWMV, LAST_FRAME, 0},
- {NEWMV, GOLDEN_FRAME, 0},
- {NEWMV, ALTREF_FRAME, 0},
+ {NEWMV, LAST_FRAME, NONE},
+ {NEWMV, GOLDEN_FRAME, NONE},
+ {NEWMV, ALTREF_FRAME, NONE},
- {SPLITMV, LAST_FRAME, 0},
- {SPLITMV, GOLDEN_FRAME, 0},
- {SPLITMV, ALTREF_FRAME, 0},
+ {SPLITMV, LAST_FRAME, NONE},
+ {SPLITMV, GOLDEN_FRAME, NONE},
+ {SPLITMV, ALTREF_FRAME, NONE},
- {B_PRED, INTRA_FRAME, 0},
- {I8X8_PRED, INTRA_FRAME, 0},
+ {B_PRED, INTRA_FRAME, NONE},
+ {I8X8_PRED, INTRA_FRAME, NONE},
/* compound prediction modes */
{ZEROMV, LAST_FRAME, GOLDEN_FRAME},
@@ -206,7 +224,25 @@ const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
{SPLITMV, LAST_FRAME, GOLDEN_FRAME},
{SPLITMV, ALTREF_FRAME, LAST_FRAME },
- {SPLITMV, GOLDEN_FRAME, ALTREF_FRAME}
+ {SPLITMV, GOLDEN_FRAME, ALTREF_FRAME},
+
+#if CONFIG_COMP_INTERINTRA_PRED
+ /* compound inter-intra prediction */
+ {ZEROMV, LAST_FRAME, INTRA_FRAME},
+ {NEARESTMV, LAST_FRAME, INTRA_FRAME},
+ {NEARMV, LAST_FRAME, INTRA_FRAME},
+ {NEWMV, LAST_FRAME, INTRA_FRAME},
+
+ {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
};
#endif
@@ -1960,7 +1996,7 @@ static int labels2mode(
// is when we are on a new label (jbb May 08, 2007)
switch (m = this_mode) {
case NEW4X4 :
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
this_mv->as_int = seg_mvs[mbmi->ref_frame - 1].as_int;
this_second_mv->as_int =
seg_mvs[mbmi->second_ref_frame - 1].as_int;
@@ -1968,7 +2004,7 @@ static int labels2mode(
thismvcost = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost,
102, xd->allow_high_precision_mv);
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv,
mvjcost, mvcost, 102,
xd->allow_high_precision_mv);
@@ -1976,17 +2012,17 @@ static int labels2mode(
break;
case LEFT4X4:
this_mv->as_int = col ? d[-1].bmi.as_mv.first.as_int : left_block_mv(mic, i);
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
this_second_mv->as_int = col ? d[-1].bmi.as_mv.second.as_int : left_block_second_mv(mic, i);
break;
case ABOVE4X4:
this_mv->as_int = row ? d[-4].bmi.as_mv.first.as_int : above_block_mv(mic, i, mis);
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
this_second_mv->as_int = row ? d[-4].bmi.as_mv.second.as_int : above_block_second_mv(mic, i, mis);
break;
case ZERO4X4:
this_mv->as_int = 0;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
this_second_mv->as_int = 0;
break;
default:
@@ -1999,12 +2035,12 @@ static int labels2mode(
left_second_mv.as_int = 0;
left_mv.as_int = col ? d[-1].bmi.as_mv.first.as_int :
left_block_mv(mic, i);
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
left_second_mv.as_int = col ? d[-1].bmi.as_mv.second.as_int :
left_block_second_mv(mic, i);
if (left_mv.as_int == this_mv->as_int &&
- (!mbmi->second_ref_frame ||
+ (mbmi->second_ref_frame <= 0 ||
left_second_mv.as_int == this_second_mv->as_int))
m = LEFT4X4;
}
@@ -2018,12 +2054,12 @@ static int labels2mode(
}
d->bmi.as_mv.first.as_int = this_mv->as_int;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
d->bmi.as_mv.second.as_int = this_second_mv->as_int;
x->partition_info->bmi[i].mode = m;
x->partition_info->bmi[i].mv.as_int = this_mv->as_int;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
x->partition_info->bmi[i].second_mv.as_int = this_second_mv->as_int;
}
@@ -2051,7 +2087,7 @@ static int64_t encode_inter_mb_segment(MACROBLOCK *x,
int thisdistortion;
vp9_build_inter_predictors_b(bd, 16, xd->subpixel_predict);
- if (xd->mode_info_context->mbmi.second_ref_frame)
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0)
vp9_build_2nd_inter_predictors_b(bd, 16, xd->subpixel_predict_avg);
vp9_subtract_b(be, bd, 16);
x->vp9_short_fdct4x4(be->src_diff, be->coeff, 32);
@@ -2101,7 +2137,7 @@ static int64_t encode_inter_mb_segment_8x8(MACROBLOCK *x,
int thisdistortion;
vp9_build_inter_predictors4b(xd, bd, 16);
- if (xd->mode_info_context->mbmi.second_ref_frame)
+ if (xd->mode_info_context->mbmi.second_ref_frame > 0)
vp9_build_2nd_inter_predictors4b(xd, bd, 16);
vp9_subtract_4b_c(be, bd, 16);
@@ -2282,7 +2318,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
tl_s = (ENTROPY_CONTEXT *)&t_left_s;
// motion search for newmv (single predictor case only)
- if (!mbmi->second_ref_frame && this_mode == NEW4X4) {
+ if (mbmi->second_ref_frame <= 0 && this_mode == NEW4X4) {
int sseshift, n;
int step_param = 0;
int further_steps;
@@ -2368,8 +2404,8 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
// safe motion search result for use in compound prediction
seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEW4X4].as_int;
}
- } /* NEW4X4 */
- else if (mbmi->second_ref_frame && this_mode == NEW4X4) {
+ } else if (mbmi->second_ref_frame > 0 && this_mode == NEW4X4) {
+ /* NEW4X4 */
/* motion search not completed? Then skip newmv for this block with
* comppred */
if (seg_mvs[i][mbmi->second_ref_frame - 1].as_int == INVALID_MV ||
@@ -2390,7 +2426,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) {
continue;
}
- if (mbmi->second_ref_frame &&
+ if (mbmi->second_ref_frame > 0 &&
mv_check_bounds(x, &second_mode_mv[this_mode]))
continue;
@@ -2463,7 +2499,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
// store everything needed to come back to this!!
for (i = 0; i < 16; i++) {
bsi->mvs[i].as_mv = x->partition_info->bmi[i].mv.as_mv;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
bsi->second_mvs[i].as_mv = x->partition_info->bmi[i].second_mv.as_mv;
bsi->modes[i] = x->partition_info->bmi[i].mode;
bsi->eobs[i] = best_eobs[i];
@@ -2694,7 +2730,7 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
BLOCKD *bd = &x->e_mbd.block[i];
bd->bmi.as_mv.first.as_int = bsi.mvs[i].as_int;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
bd->bmi.as_mv.second.as_int = bsi.second_mvs[i].as_int;
bd->eob = bsi.eobs[i];
}
@@ -2718,14 +2754,14 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
x->partition_info->bmi[i].mode = bsi.modes[j];
x->partition_info->bmi[i].mv.as_mv = bsi.mvs[j].as_mv;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
x->partition_info->bmi[i].second_mv.as_mv = bsi.second_mvs[j].as_mv;
}
/*
* used to set mbmi->mv.as_int
*/
x->partition_info->bmi[15].mv.as_int = bsi.mvs[15].as_int;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
x->partition_info->bmi[15].second_mv.as_int = bsi.second_mvs[15].as_int;
return (int)(bsi.segment_rd);
@@ -3165,7 +3201,7 @@ static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
memcpy(ctx->txfm_rd_diff, txfm_size_diff, sizeof(ctx->txfm_rd_diff));
}
-static void inter_mode_cost(VP9_COMP *cpi, MACROBLOCK *x, int this_mode,
+static void inter_mode_cost(VP9_COMP *cpi, MACROBLOCK *x,
int *rate2, int *distortion2, int *rate_y,
int *distortion, int* rate_uv, int *distortion_uv,
int *skippable, int64_t txfm_cache[NB_TXFM_MODES]) {
@@ -3232,6 +3268,9 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int mdcounts[4], int64_t txfm_cache[],
int *rate2, int *distortion, int *skippable,
int *compmode_cost,
+#if CONFIG_COMP_INTERINTRA_PRED
+ int *compmode_interintra_cost,
+#endif
int *rate_y, int *distortion_y,
int *rate_uv, int *distortion_uv,
int *mode_excluded, int *disable_skip,
@@ -3243,11 +3282,15 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
BLOCK *b = &x->block[0];
BLOCKD *d = &xd->block[0];
- const int is_comp_pred = (mbmi->second_ref_frame != 0);
+ const int is_comp_pred = (mbmi->second_ref_frame > 0);
+#if CONFIG_COMP_INTERINTRA_PRED
+ const int is_comp_interintra_pred = (mbmi->second_ref_frame == INTRA_FRAME);
+#endif
const int num_refs = is_comp_pred ? 2 : 1;
const int this_mode = mbmi->mode;
int i;
- int refs[2] = { mbmi->ref_frame, mbmi->second_ref_frame };
+ int refs[2] = { mbmi->ref_frame,
+ (mbmi->second_ref_frame < 0 ? 0 : mbmi->second_ref_frame) };
int_mv cur_mv[2];
int_mv mvp;
int64_t this_rd = 0;
@@ -3368,11 +3411,30 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
is_comp_pred);
*rate2 += vp9_cost_mv_ref(cpi, this_mode,
mbmi->mb_mode_context[mbmi->ref_frame]);
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (!is_comp_pred) {
+ *compmode_interintra_cost = vp9_cost_bit(cm->fc.interintra_prob,
+ is_comp_interintra_pred);
+ if (is_comp_interintra_pred) {
+ *compmode_interintra_cost +=
+ x->mbmode_cost[xd->frame_type][mbmi->interintra_mode];
+#if SEPARATE_INTERINTRA_UV
+ *compmode_interintra_cost +=
+ x->intra_uv_mode_cost[xd->frame_type][mbmi->interintra_uv_mode];
+#endif
+ }
+ }
+#endif
if (block_size == BLOCK_16X16) {
vp9_build_1st_inter16x16_predictors_mby(xd, xd->predictor, 16, 0);
if (is_comp_pred)
vp9_build_2nd_inter16x16_predictors_mby(xd, xd->predictor, 16);
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (is_comp_interintra_pred) {
+ vp9_build_interintra_16x16_predictors_mby(xd, xd->predictor, 16);
+ }
+#endif
} else {
#if CONFIG_SUPERBLOCKS
vp9_build_inter32x32_predictors_sb(xd,
@@ -3440,6 +3502,15 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
}
}
+ if (is_comp_pred) {
+ *mode_excluded = (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY);
+ } else {
+ *mode_excluded = (cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY);
+ }
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (is_comp_interintra_pred && !cm->use_interintra) *mode_excluded = 1;
+#endif
+
if (!x->skip) {
if (block_size == BLOCK_16X16) {
vp9_build_1st_inter16x16_predictors_mbuv(xd, &xd->predictor[256],
@@ -3447,7 +3518,13 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (is_comp_pred)
vp9_build_2nd_inter16x16_predictors_mbuv(xd, &xd->predictor[256],
&xd->predictor[320], 8);
- inter_mode_cost(cpi, x, this_mode, rate2, distortion,
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (is_comp_interintra_pred) {
+ vp9_build_interintra_16x16_predictors_mbuv(xd, &xd->predictor[256],
+ &xd->predictor[320], 8);
+ }
+#endif
+ inter_mode_cost(cpi, x, rate2, distortion,
rate_y, distortion_y, rate_uv, distortion_uv,
skippable, txfm_cache);
} else {
@@ -3469,12 +3546,6 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
#endif
}
}
- if (is_comp_pred) {
- *mode_excluded = (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY);
- } else {
- *mode_excluded = (cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY);
- }
-
return this_rd; // if 0, this will be re-calculated by caller
}
@@ -3503,9 +3574,12 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int64_t best_pred_diff[NB_PREDICTION_TYPES];
int64_t best_pred_rd[NB_PREDICTION_TYPES];
int64_t best_rd = INT64_MAX, best_intra_rd = INT64_MAX;
-#if CONFIG_PRED_FILTER
- int64_t best_overall_rd = INT64_MAX;
+#if CONFIG_COMP_INTERINTRA_PRED
+ int is_best_interintra = 0;
+ int64_t best_intra16_rd = INT64_MAX;
+ int best_intra16_mode = DC_PRED, best_intra16_uv_mode = DC_PRED;
#endif
+ int64_t best_overall_rd = INT64_MAX;
int uv_intra_rate, uv_intra_distortion, uv_intra_rate_tokenonly;
int uv_intra_skippable = 0;
int uv_intra_rate_8x8 = 0, uv_intra_distortion_8x8 = 0, uv_intra_rate_tokenonly_8x8 = 0;
@@ -3608,6 +3682,9 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int disable_skip = 0, skippable = 0;
int other_cost = 0;
int compmode_cost = 0;
+#if CONFIG_COMP_INTERINTRA_PRED
+ int compmode_interintra_cost = 0;
+#endif
int mode_excluded = 0;
int64_t txfm_cache[NB_TXFM_MODES] = { 0 };
@@ -3645,6 +3722,10 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
mbmi->second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+ mbmi->interintra_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
+ mbmi->interintra_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
+#endif
// If the segment reference frame feature is enabled....
// then do nothing if the current ref frame is not allowed..
@@ -3684,7 +3765,7 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
vpx_memcpy(mdcounts, frame_mdcounts[ref], sizeof(mdcounts));
}
- if (mbmi->second_ref_frame) {
+ if (mbmi->second_ref_frame > 0) {
int ref = mbmi->second_ref_frame;
xd->second_pre.y_buffer = y_buffer[ref];
@@ -3872,7 +3953,7 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
// Split MV. The code is very different from the other inter modes so
// special case it.
else if (this_mode == SPLITMV) {
- const int is_comp_pred = mbmi->second_ref_frame != 0;
+ const int is_comp_pred = mbmi->second_ref_frame > 0;
int64_t tmp_rd, this_rd_thresh;
int_mv *second_ref = is_comp_pred ? &second_best_ref_mv : NULL;
@@ -3921,10 +4002,25 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->mode = this_mode;
}
else {
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (mbmi->second_ref_frame == INTRA_FRAME) {
+ if (best_intra16_mode == DC_PRED - 1) continue;
+ mbmi->interintra_mode = best_intra16_mode;
+#if SEPARATE_INTERINTRA_UV
+ mbmi->interintra_uv_mode = best_intra16_uv_mode;
+#else
+ mbmi->interintra_uv_mode = best_intra16_mode;
+#endif
+ }
+#endif
this_rd = handle_inter_mode(cpi, x, BLOCK_16X16,
&saddone, near_sadidx, mdcounts, txfm_cache,
&rate2, &distortion2, &skippable,
- &compmode_cost, &rate_y, &distortion,
+ &compmode_cost,
+#if CONFIG_COMP_INTERINTRA_PRED
+ &compmode_interintra_cost,
+#endif
+ &rate_y, &distortion,
&rate_uv, &distortion_uv,
&mode_excluded, &disable_skip, recon_yoffset,
mode_index, frame_mv, frame_best_ref_mv);
@@ -3932,6 +4028,11 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
continue;
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ if (cpi->common.use_interintra)
+ rate2 += compmode_interintra_cost;
+#endif
+
if (cpi->common.comp_pred_mode == HYBRID_PREDICTION)
rate2 += compmode_cost;
@@ -3996,18 +4097,33 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
best_intra_rd = this_rd;
*returnintra = distortion2;
}
+#if CONFIG_COMP_INTERINTRA_PRED
+ if ((mbmi->ref_frame == INTRA_FRAME) &&
+ (this_mode >= DC_PRED && this_mode <= TM_PRED) &&
+ (this_rd < best_intra16_rd)) {
+ best_intra16_rd = this_rd;
+ best_intra16_mode = this_mode;
+ best_intra16_uv_mode = (mbmi->txfm_size != TX_4X4 ?
+ uv_intra_mode_8x8 : uv_intra_mode);
+ }
+#endif
+
if (!disable_skip && mbmi->ref_frame == INTRA_FRAME)
for (i = 0; i < NB_PREDICTION_TYPES; ++i)
best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
-#if CONFIG_PRED_FILTER
- // Keep track of the best mode irrespective of prediction filter state
if (this_rd < best_overall_rd) {
best_overall_rd = this_rd;
+#if CONFIG_PRED_FILTER
best_filter_state = mbmi->pred_filter_enabled;
+#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+ is_best_interintra = (mbmi->second_ref_frame == INTRA_FRAME);
+#endif
}
+#if CONFIG_PRED_FILTER
// Ignore modes where the prediction filter state doesn't
// match the state signaled at the frame level
if ((cm->pred_filter_mode == 2) ||
@@ -4017,6 +4133,11 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
// Did this mode help.. i.e. is it the new best mode
if (this_rd < best_rd || x->skip) {
if (!mode_excluded) {
+ /*
+ if (mbmi->second_ref_frame == INTRA_FRAME) {
+ printf("rd %d best %d bestintra16 %d\n", this_rd, best_rd, best_intra16_rd);
+ }
+ */
// Note index of best mode so far
best_mode_index = mode_index;
@@ -4087,10 +4208,10 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
- if (mbmi->second_ref_frame == INTRA_FRAME &&
+ if (mbmi->second_ref_frame <= INTRA_FRAME &&
single_rd < best_pred_rd[SINGLE_PREDICTION_ONLY]) {
best_pred_rd[SINGLE_PREDICTION_ONLY] = single_rd;
- } else if (mbmi->second_ref_frame != INTRA_FRAME &&
+ } else if (mbmi->second_ref_frame > INTRA_FRAME &&
single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) {
best_pred_rd[COMP_PREDICTION_ONLY] = single_rd;
}
@@ -4128,6 +4249,9 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
else
++cpi->pred_filter_off_count;
#endif
+#if CONFIG_COMP_INTERINTRA_PRED
+ ++cpi->interintra_select_count[is_best_interintra];
+#endif
if (cpi->common.mcomp_filter_type == SWITCHABLE &&
best_mbmode.mode >= NEARESTMV &&
best_mbmode.mode <= SPLITMV) {
@@ -4191,7 +4315,7 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (best_mbmode.mode == SPLITMV) {
for (i = 0; i < 16; i++)
xd->mode_info_context->bmi[i].as_mv.first.as_int = best_bmodes[i].as_mv.first.as_int;
- if (mbmi->second_ref_frame)
+ if (mbmi->second_ref_frame > 0)
for (i = 0; i < 16; i++)
xd->mode_info_context->bmi[i].as_mv.second.as_int = best_bmodes[i].as_mv.second.as_int;
@@ -4220,10 +4344,12 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
}
end:
- store_coding_context(x, &x->mb_context[xd->mb_index], best_mode_index,
- &best_partition, &frame_best_ref_mv[mbmi->ref_frame],
- &frame_best_ref_mv[mbmi->second_ref_frame],
- best_pred_diff, best_txfm_diff);
+ store_coding_context(
+ x, &x->mb_context[xd->mb_index], best_mode_index, &best_partition,
+ &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame],
+ &frame_best_ref_mv[xd->mode_info_context->mbmi.second_ref_frame < 0 ?
+ 0 : xd->mode_info_context->mbmi.second_ref_frame],
+ best_pred_diff, best_txfm_diff);
}
#if CONFIG_SUPERBLOCKS
@@ -4448,6 +4574,11 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
MB_MODE_INFO best_mbmode;
int mode_index, best_mode_index;
unsigned int ref_costs[MAX_REF_FRAMES];
+#if CONFIG_COMP_INTERINTRA_PRED
+ int is_best_interintra = 0;
+ int64_t best_intra16_rd = INT64_MAX;
+ int best_intra16_mode = DC_PRED, best_intra16_uv_mode = DC_PRED;
+#endif
x->skip = 0;
xd->mode_info_context->mbmi.segment_id = segment_id;
@@ -4480,6 +4611,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int distortion2 = 0, distortion_y = 0, distortion_uv = 0;
int skippable;
int64_t txfm_cache[NB_TXFM_MODES];
+#if CONFIG_COMP_INTERINTRA_PRED
+ int compmode_interintra_cost = 0;
+#endif
// Test best rd so far against threshold for trying this mode.
if (best_rd <= cpi->rd_threshes[mode_index]) {
@@ -4489,7 +4623,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
this_mode = vp9_mode_order[mode_index].mode;
ref_frame = vp9_mode_order[mode_index].ref_frame;
mbmi->ref_frame = ref_frame;
- comp_pred = vp9_mode_order[mode_index].second_ref_frame != INTRA_FRAME;
+ comp_pred = vp9_mode_order[mode_index].second_ref_frame > INTRA_FRAME;
mbmi->mode = this_mode;
mbmi->uv_mode = DC_PRED;
#if CONFIG_COMP_INTRA_PRED
@@ -4502,7 +4636,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
// not yet supported or not superblocky
// TODO(rbultje): support intra coding
- if (ref_frame == INTRA_FRAME || this_mode == SPLITMV)
+ if (ref_frame == INTRA_FRAME || this_mode == SPLITMV ||
+ vp9_mode_order[mode_index].second_ref_frame == INTRA_FRAME)
continue;
if (comp_pred) {
@@ -4522,7 +4657,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
xd->second_pre.v_buffer = v_buffer[second_ref];
mode_excluded = cm->comp_pred_mode == SINGLE_PREDICTION_ONLY;
} else {
- mbmi->second_ref_frame = INTRA_FRAME;
+ mbmi->second_ref_frame = NONE;
mode_excluded = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
}
@@ -4559,7 +4694,11 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
this_rd = handle_inter_mode(cpi, x, BLOCK_32X32,
&saddone, near_sadidx, mdcounts, txfm_cache,
&rate2, &distortion2, &skippable,
- &compmode_cost, &rate_y, &distortion_y,
+ &compmode_cost,
+#if CONFIG_COMP_INTERINTRA_PRED
+ &compmode_interintra_cost,
+#endif
+ &rate_y, &distortion_y,
&rate_uv, &distortion_uv,
&mode_excluded, &disable_skip, recon_yoffset,
mode_index, frame_mv, frame_best_ref_mv);
@@ -4691,10 +4830,10 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
- if (mbmi->second_ref_frame == INTRA_FRAME &&
+ if (mbmi->second_ref_frame <= INTRA_FRAME &&
single_rd < best_pred_rd[SINGLE_PREDICTION_ONLY]) {
best_pred_rd[SINGLE_PREDICTION_ONLY] = single_rd;
- } else if (mbmi->second_ref_frame != INTRA_FRAME &&
+ } else if (mbmi->second_ref_frame > INTRA_FRAME &&
single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) {
best_pred_rd[COMP_PREDICTION_ONLY] = single_rd;
}
@@ -4746,7 +4885,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
(best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME)) {
mbmi->mode = ZEROMV;
mbmi->ref_frame = ALTREF_FRAME;
- mbmi->second_ref_frame = 0;
+ mbmi->second_ref_frame = INTRA_FRAME;
mbmi->mv[0].as_int = 0;
mbmi->uv_mode = DC_PRED;
mbmi->mb_skip_coeff = (cpi->common.mb_no_coeff_skip) ? 1 : 0;
@@ -4783,7 +4922,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
end:
store_coding_context(x, &x->sb_context[0], best_mode_index, NULL,
&frame_best_ref_mv[mbmi->ref_frame],
- &frame_best_ref_mv[mbmi->second_ref_frame],
+ &frame_best_ref_mv[mbmi->second_ref_frame < 0 ?
+ 0 : mbmi->second_ref_frame],
best_pred_diff, best_txfm_diff);
return best_rd;