Commit 0c917fc9 authored by Deb Mukherjee's avatar Deb Mukherjee

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
parent 16e26866
......@@ -246,6 +246,7 @@ EXPERIMENT_LIST="
new_mvref
implicit_segmentation
newbintramodes
comp_interintra_pred
"
CONFIG_LIST="
external_build
......
......@@ -214,6 +214,7 @@ union b_mode_info {
};
typedef enum {
NONE = -1,
INTRA_FRAME = 0,
LAST_FRAME = 1,
GOLDEN_FRAME = 2,
......@@ -225,6 +226,9 @@ typedef struct {
MB_PREDICTION_MODE mode, uv_mode;
#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;
......
......@@ -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
}
......@@ -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];
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 )
......
......@@ -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);
......
This diff is collapsed.
......@@ -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
......@@ -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;
......
......@@ -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);
......
......@@ -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,