Merge "Compound inter-intra experiment" into experimental

This commit is contained in:
Deb Mukherjee 2012-11-16 08:30:34 -08:00 коммит произвёл Gerrit Code Review
Родитель 170305dcd3 0c917fc975
Коммит cb2d06ceac
20 изменённых файлов: 982 добавлений и 187 удалений

1
configure поставляемый
Просмотреть файл

@ -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) {

Просмотреть файл

@ -63,7 +63,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;
@ -77,7 +77,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;
@ -85,13 +85,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;
@ -100,7 +100,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);

Просмотреть файл

@ -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
*/

Просмотреть файл

@ -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

Просмотреть файл

@ -532,6 +532,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);
@ -672,7 +678,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);
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);
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) {
@ -972,7 +987,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)) {
best_second_mv.as_int =
@ -982,9 +997,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 */
@ -1020,7 +1056,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;
@ -1091,7 +1127,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,
@ -2017,6 +2053,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);
@ -2046,6 +2091,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)
@ -2090,6 +2138,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);
@ -2112,7 +2168,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);

Просмотреть файл

@ -572,6 +572,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;
@ -1111,7 +1125,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]++;
@ -1390,6 +1404,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);
@ -2089,7 +2107,7 @@ static void encode_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)
@ -2285,7 +2303,7 @@ static void encode_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)

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
@ -1115,6 +1173,12 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->thresh_mult[THR_ZEROG_FILT ] = INT_MAX;
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;
}
@ -1129,6 +1193,12 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->thresh_mult[THR_ZEROA_FILT ] = INT_MAX;
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 */

Просмотреть файл

@ -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

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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},
{ZEROMV, LAST_FRAME, NONE, 0},
{ZEROMV, LAST_FRAME, NONE, 1},
{DC_PRED, INTRA_FRAME, NONE, 0},
{NEARESTMV, LAST_FRAME, 0, 0},
{NEARESTMV, LAST_FRAME, 0, 1},
{NEARMV, LAST_FRAME, 0, 0},
{NEARMV, LAST_FRAME, 0, 1},
{NEARESTMV, LAST_FRAME, NONE, 0},
{NEARESTMV, LAST_FRAME, NONE, 1},
{NEARMV, LAST_FRAME, NONE, 0},
{NEARMV, LAST_FRAME, NONE, 1},
{ZEROMV, GOLDEN_FRAME, 0, 0},
{ZEROMV, GOLDEN_FRAME, 0, 1},
{NEARESTMV, GOLDEN_FRAME, 0, 0},
{NEARESTMV, GOLDEN_FRAME, 0, 1},
{ZEROMV, GOLDEN_FRAME, NONE, 0},
{ZEROMV, GOLDEN_FRAME, NONE, 1},
{NEARESTMV, GOLDEN_FRAME, NONE, 0},
{NEARESTMV, GOLDEN_FRAME, NONE, 1},
{ZEROMV, ALTREF_FRAME, 0, 0},
{ZEROMV, ALTREF_FRAME, 0, 1},
{NEARESTMV, ALTREF_FRAME, 0, 0},
{NEARESTMV, ALTREF_FRAME, 0, 1},
{ZEROMV, ALTREF_FRAME, NONE, 0},
{ZEROMV, ALTREF_FRAME, NONE, 1},
{NEARESTMV, ALTREF_FRAME, NONE, 0},
{NEARESTMV, ALTREF_FRAME, NONE, 1},
{NEARMV, GOLDEN_FRAME, 0, 0},
{NEARMV, GOLDEN_FRAME, 0, 1},
{NEARMV, ALTREF_FRAME, 0, 0},
{NEARMV, ALTREF_FRAME, 0, 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, 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},
{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, 0, 0},
{TM_PRED, INTRA_FRAME, NONE, 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},
{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, 0, 0},
{SPLITMV, GOLDEN_FRAME, 0, 0},
{SPLITMV, ALTREF_FRAME, 0, 0},
{SPLITMV, LAST_FRAME, NONE, 0},
{SPLITMV, GOLDEN_FRAME, NONE, 0},
{SPLITMV, ALTREF_FRAME, NONE, 0},
{B_PRED, INTRA_FRAME, 0, 0},
{I8X8_PRED, INTRA_FRAME, 0, 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
@ -1959,7 +1995,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;
@ -1967,7 +2003,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);
@ -1975,17 +2011,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:
@ -1998,12 +2034,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;
}
@ -2017,12 +2053,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;
}
@ -2050,7 +2086,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);
@ -2100,7 +2136,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);
@ -2281,7 +2317,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;
@ -2367,8 +2403,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 ||
@ -2389,7 +2425,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;
@ -2462,7 +2498,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];
@ -2693,7 +2729,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];
}
@ -2717,14 +2753,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);
@ -3164,7 +3200,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]) {
@ -3231,6 +3267,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,
@ -3242,11 +3281,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;
@ -3367,11 +3410,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,
@ -3439,6 +3501,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],
@ -3446,7 +3517,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 {
@ -3468,12 +3545,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
}
@ -3502,9 +3573,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;
@ -3607,6 +3681,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 };
@ -3644,6 +3721,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..
@ -3683,7 +3764,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];
@ -3871,7 +3952,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;
@ -3920,10 +4001,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);
@ -3931,6 +4027,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;
@ -3995,18 +4096,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) ||
@ -4016,6 +4132,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;
@ -4086,10 +4207,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;
}
@ -4126,6 +4247,9 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
++cpi->pred_filter_on_count;
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 &&
@ -4190,7 +4314,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;
@ -4219,10 +4343,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
@ -4447,6 +4573,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;
@ -4479,6 +4610,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]) {
@ -4488,7 +4622,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
@ -4501,7 +4635,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) {
@ -4521,7 +4656,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;
}
@ -4558,7 +4693,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);
@ -4690,10 +4829,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;
}
@ -4745,7 +4884,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;
@ -4782,7 +4921,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;