Commit 6ef805eb authored by Ronald S. Bultje's avatar Ronald S. Bultje

Change ref frame coding.

Code intra/inter, then comp/single, then the ref frame selection.
Use contextualization for all steps. Don't code two past frames
in comp pred mode.

Change-Id: I4639a78cd5cccb283023265dbcc07898c3e7cf95
parent 9062b92b
...@@ -24,11 +24,8 @@ ...@@ -24,11 +24,8 @@
#define BLOCK_SIZE_GROUPS 4 #define BLOCK_SIZE_GROUPS 4
#define MAX_MB_SEGMENTS 8 #define MAX_MB_SEGMENTS 8
#define MB_SEG_TREE_PROBS (MAX_MB_SEGMENTS-1) #define MB_SEG_TREE_PROBS (MAX_MB_SEGMENTS-1)
#define PREDICTION_PROBS 3
#define DEFAULT_PRED_PROB_0 120 #define PREDICTION_PROBS 3
#define DEFAULT_PRED_PROB_1 80
#define DEFAULT_PRED_PROB_2 40
#define MBSKIP_CONTEXTS 3 #define MBSKIP_CONTEXTS 3
...@@ -40,6 +37,10 @@ ...@@ -40,6 +37,10 @@
#define SEGMENT_ABSDATA 1 #define SEGMENT_ABSDATA 1
#define MAX_MV_REF_CANDIDATES 2 #define MAX_MV_REF_CANDIDATES 2
#define INTRA_INTER_CONTEXTS 4
#define COMP_INTER_CONTEXTS 5
#define REF_CONTEXTS 5
typedef enum { typedef enum {
PLANE_TYPE_Y_WITH_DC, PLANE_TYPE_Y_WITH_DC,
PLANE_TYPE_UV, PLANE_TYPE_UV,
...@@ -200,7 +201,7 @@ static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) { ...@@ -200,7 +201,7 @@ static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) {
typedef struct { typedef struct {
MB_PREDICTION_MODE mode, uv_mode; MB_PREDICTION_MODE mode, uv_mode;
MV_REFERENCE_FRAME ref_frame, second_ref_frame; MV_REFERENCE_FRAME ref_frame[2];
TX_SIZE txfm_size; TX_SIZE txfm_size;
int_mv mv[2]; // for each reference frame used int_mv mv[2]; // for each reference frame used
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES]; int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
...@@ -215,7 +216,6 @@ typedef struct { ...@@ -215,7 +216,6 @@ typedef struct {
// Flags used for prediction status of various bistream signals // Flags used for prediction status of various bistream signals
unsigned char seg_id_predicted; unsigned char seg_id_predicted;
unsigned char ref_predicted;
// Indicates if the mb is part of the image (1) vs border (0) // Indicates if the mb is part of the image (1) vs border (0)
// This can be useful in determining whether the MB provides // This can be useful in determining whether the MB provides
...@@ -526,7 +526,7 @@ static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, int ib) { ...@@ -526,7 +526,7 @@ static TX_TYPE get_tx_type_4x4(const MACROBLOCKD *xd, int ib) {
TX_TYPE tx_type; TX_TYPE tx_type;
MODE_INFO *mi = xd->mode_info_context; MODE_INFO *mi = xd->mode_info_context;
MB_MODE_INFO *const mbmi = &mi->mbmi; MB_MODE_INFO *const mbmi = &mi->mbmi;
if (xd->lossless || mbmi->ref_frame != INTRA_FRAME) if (xd->lossless || mbmi->ref_frame[0] != INTRA_FRAME)
return DCT_DCT; return DCT_DCT;
if (mbmi->sb_type < BLOCK_SIZE_SB8X8) { if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
tx_type = txfm_map(mi->bmi[ib].as_mode.first); tx_type = txfm_map(mi->bmi[ib].as_mode.first);
......
...@@ -129,6 +129,26 @@ struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_INTER_MODES]; ...@@ -129,6 +129,26 @@ struct vp9_token vp9_sb_mv_ref_encoding_array[VP9_INTER_MODES];
struct vp9_token vp9_partition_encodings[PARTITION_TYPES]; struct vp9_token vp9_partition_encodings[PARTITION_TYPES];
static const vp9_prob default_intra_inter_p[INTRA_INTER_CONTEXTS] = {
6, 87, 165, 213
};
static const vp9_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
25, 66, 106, 142, 183
};
static const vp9_prob default_comp_ref_p[REF_CONTEXTS] = {
36, 93, 136, 205, 236
};
static const vp9_prob default_single_ref_p[REF_CONTEXTS][2] = {
{ 30, 17 },
{ 80, 66 },
{ 142, 129 },
{ 192, 178 },
{ 235, 248 },
};
void vp9_init_mbmode_probs(VP9_COMMON *x) { void vp9_init_mbmode_probs(VP9_COMMON *x) {
vpx_memcpy(x->fc.uv_mode_prob, default_if_uv_probs, vpx_memcpy(x->fc.uv_mode_prob, default_if_uv_probs,
sizeof(default_if_uv_probs)); sizeof(default_if_uv_probs));
...@@ -143,9 +163,14 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) { ...@@ -143,9 +163,14 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) {
vpx_memcpy(x->fc.partition_prob, vp9_partition_probs, vpx_memcpy(x->fc.partition_prob, vp9_partition_probs,
sizeof(vp9_partition_probs)); sizeof(vp9_partition_probs));
x->ref_pred_probs[0] = DEFAULT_PRED_PROB_0; vpx_memcpy(x->fc.intra_inter_prob, default_intra_inter_p,
x->ref_pred_probs[1] = DEFAULT_PRED_PROB_1; sizeof(default_intra_inter_p));
x->ref_pred_probs[2] = DEFAULT_PRED_PROB_2; vpx_memcpy(x->fc.comp_inter_prob, default_comp_inter_p,
sizeof(default_comp_inter_p));
vpx_memcpy(x->fc.comp_ref_prob, default_comp_ref_p,
sizeof(default_comp_ref_p));
vpx_memcpy(x->fc.single_ref_prob, default_single_ref_p,
sizeof(default_single_ref_p));
} }
#if VP9_SWITCHABLE_FILTERS == 3 #if VP9_SWITCHABLE_FILTERS == 3
...@@ -246,6 +271,14 @@ void vp9_adapt_mode_context(VP9_COMMON *pc) { ...@@ -246,6 +271,14 @@ void vp9_adapt_mode_context(VP9_COMMON *pc) {
#define MODE_COUNT_SAT 20 #define MODE_COUNT_SAT 20
#define MODE_MAX_UPDATE_FACTOR 144 #define MODE_MAX_UPDATE_FACTOR 144
static int update_mode_ct(int pre_prob, int prob,
unsigned int branch_ct[2]) {
int factor, count = branch_ct[0] + branch_ct[1];
count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count;
factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
return weighted_prob(pre_prob, prob, factor);
}
static void update_mode_probs(int n_modes, static void update_mode_probs(int n_modes,
const vp9_tree_index *tree, unsigned int *cnt, const vp9_tree_index *tree, unsigned int *cnt,
vp9_prob *pre_probs, vp9_prob *dst_probs, vp9_prob *pre_probs, vp9_prob *dst_probs,
...@@ -253,21 +286,22 @@ static void update_mode_probs(int n_modes, ...@@ -253,21 +286,22 @@ static void update_mode_probs(int n_modes,
#define MAX_PROBS 32 #define MAX_PROBS 32
vp9_prob probs[MAX_PROBS]; vp9_prob probs[MAX_PROBS];
unsigned int branch_ct[MAX_PROBS][2]; unsigned int branch_ct[MAX_PROBS][2];
int t, count, factor; int t;
assert(n_modes - 1 < MAX_PROBS); assert(n_modes - 1 < MAX_PROBS);
vp9_tree_probs_from_distribution(tree, probs, branch_ct, cnt, tok0_offset); vp9_tree_probs_from_distribution(tree, probs, branch_ct, cnt, tok0_offset);
for (t = 0; t < n_modes - 1; ++t) { for (t = 0; t < n_modes - 1; ++t)
count = branch_ct[t][0] + branch_ct[t][1]; dst_probs[t] = update_mode_ct(pre_probs[t], probs[t], branch_ct[t]);
count = count > MODE_COUNT_SAT ? MODE_COUNT_SAT : count; }
factor = (MODE_MAX_UPDATE_FACTOR * count / MODE_COUNT_SAT);
dst_probs[t] = weighted_prob(pre_probs[t], probs[t], factor); static int update_mode_ct2(int pre_prob, unsigned int branch_ct[2]) {
} return update_mode_ct(pre_prob, get_binary_prob(branch_ct[0],
branch_ct[1]), branch_ct);
} }
// #define MODE_COUNT_TESTING // #define MODE_COUNT_TESTING
void vp9_adapt_mode_probs(VP9_COMMON *cm) { void vp9_adapt_mode_probs(VP9_COMMON *cm) {
int i; int i, j;
FRAME_CONTEXT *fc = &cm->fc; FRAME_CONTEXT *fc = &cm->fc;
#ifdef MODE_COUNT_TESTING #ifdef MODE_COUNT_TESTING
int t; int t;
...@@ -303,6 +337,20 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) { ...@@ -303,6 +337,20 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
printf("};\n"); printf("};\n");
#endif #endif
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
fc->intra_inter_prob[i] = update_mode_ct2(fc->pre_intra_inter_prob[i],
fc->intra_inter_count[i]);
for (i = 0; i < COMP_INTER_CONTEXTS; i++)
fc->comp_inter_prob[i] = update_mode_ct2(fc->pre_comp_inter_prob[i],
fc->comp_inter_count[i]);
for (i = 0; i < REF_CONTEXTS; i++)
fc->comp_ref_prob[i] = update_mode_ct2(fc->pre_comp_ref_prob[i],
fc->comp_ref_count[i]);
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < 2; j++)
fc->single_ref_prob[i][j] = update_mode_ct2(fc->pre_single_ref_prob[i][j],
fc->single_ref_count[i][j]);
for (i = 0; i < BLOCK_SIZE_GROUPS; i++) for (i = 0; i < BLOCK_SIZE_GROUPS; i++)
update_mode_probs(VP9_INTRA_MODES, vp9_intra_mode_tree, update_mode_probs(VP9_INTRA_MODES, vp9_intra_mode_tree,
fc->y_mode_counts[i], fc->pre_y_mode_prob[i], fc->y_mode_counts[i], fc->pre_y_mode_prob[i],
......
...@@ -59,7 +59,7 @@ void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, ...@@ -59,7 +59,7 @@ void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
vp9_find_mv_refs_idx(cm, xd, xd->mode_info_context, vp9_find_mv_refs_idx(cm, xd, xd->mode_info_context,
xd->prev_mode_info_context, xd->prev_mode_info_context,
ref_idx ? mbmi->second_ref_frame : mbmi->ref_frame, mbmi->ref_frame[ref_idx],
mv_list, cm->ref_frame_sign_bias, block_idx); mv_list, cm->ref_frame_sign_bias, block_idx);
dst_list[1].as_int = 0; dst_list[1].as_int = 0;
......
...@@ -87,7 +87,7 @@ static MB_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b) { ...@@ -87,7 +87,7 @@ static MB_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b) {
/* On L edge, get from MB to left of us */ /* On L edge, get from MB to left of us */
--cur_mb; --cur_mb;
if (cur_mb->mbmi.ref_frame != INTRA_FRAME) { if (cur_mb->mbmi.ref_frame[0] != INTRA_FRAME) {
return DC_PRED; return DC_PRED;
} else if (cur_mb->mbmi.sb_type < BLOCK_SIZE_SB8X8) { } else if (cur_mb->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
return ((cur_mb->bmi + 1 + b)->as_mode.first); return ((cur_mb->bmi + 1 + b)->as_mode.first);
...@@ -105,7 +105,7 @@ static MB_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mb, ...@@ -105,7 +105,7 @@ static MB_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mb,
/* On top edge, get from MB above us */ /* On top edge, get from MB above us */
cur_mb -= mi_stride; cur_mb -= mi_stride;
if (cur_mb->mbmi.ref_frame != INTRA_FRAME) { if (cur_mb->mbmi.ref_frame[0] != INTRA_FRAME) {
return DC_PRED; return DC_PRED;
} else if (cur_mb->mbmi.sb_type < BLOCK_SIZE_SB8X8) { } else if (cur_mb->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
return ((cur_mb->bmi + 2 + b)->as_mode.first); return ((cur_mb->bmi + 2 + b)->as_mode.first);
......
...@@ -140,11 +140,11 @@ void segment_via_mode_info(VP9_COMMON *oci, int how) { ...@@ -140,11 +140,11 @@ void segment_via_mode_info(VP9_COMMON *oci, int how) {
break; break;
case SEGMENT_MV: case SEGMENT_MV:
n = mi[mb_index].mbmi.mv[0].as_int; n = mi[mb_index].mbmi.mv[0].as_int;
if (mi[mb_index].mbmi.ref_frame == INTRA_FRAME) if (mi[mb_index].mbmi.ref_frame[0] == INTRA_FRAME)
n = -9999999; n = -9999999;
break; break;
case SEGMENT_REFFRAME: case SEGMENT_REFFRAME:
n = mi[mb_index].mbmi.ref_frame; n = mi[mb_index].mbmi.ref_frame[0];
break; break;
case SEGMENT_SKIPPED: case SEGMENT_SKIPPED:
n = mi[mb_index].mbmi.mb_skip_coeff; n = mi[mb_index].mbmi.mb_skip_coeff;
......
...@@ -177,8 +177,8 @@ static int sb_mb_lf_skip(const MODE_INFO *const mip0, ...@@ -177,8 +177,8 @@ static int sb_mb_lf_skip(const MODE_INFO *const mip0,
const MB_MODE_INFO *mbmi0 = &mip0->mbmi; const MB_MODE_INFO *mbmi0 = &mip0->mbmi;
const MB_MODE_INFO *mbmi1 = &mip1->mbmi; const MB_MODE_INFO *mbmi1 = &mip1->mbmi;
return mb_lf_skip(mbmi0) && mb_lf_skip(mbmi1) && return mb_lf_skip(mbmi0) && mb_lf_skip(mbmi1) &&
mbmi0->ref_frame != INTRA_FRAME && mbmi0->ref_frame[0] != INTRA_FRAME &&
mbmi1->ref_frame != INTRA_FRAME; mbmi1->ref_frame[0] != INTRA_FRAME;
} }
static void lpf_mb(VP9_COMMON *cm, const MODE_INFO *mi, static void lpf_mb(VP9_COMMON *cm, const MODE_INFO *mi,
...@@ -191,7 +191,7 @@ static void lpf_mb(VP9_COMMON *cm, const MODE_INFO *mi, ...@@ -191,7 +191,7 @@ static void lpf_mb(VP9_COMMON *cm, const MODE_INFO *mi,
int mode = mi->mbmi.mode; int mode = mi->mbmi.mode;
int mode_index = lfi_n->mode_lf_lut[mode]; int mode_index = lfi_n->mode_lf_lut[mode];
int seg = mi->mbmi.segment_id; int seg = mi->mbmi.segment_id;
int ref_frame = mi->mbmi.ref_frame; MV_REFERENCE_FRAME ref_frame = mi->mbmi.ref_frame[0];
int filter_level = lfi_n->lvl[seg][ref_frame][mode_index]; int filter_level = lfi_n->lvl[seg][ref_frame][mode_index];
if (filter_level) { if (filter_level) {
......
...@@ -47,12 +47,12 @@ static void clamp_mv_ref(const MACROBLOCKD *xd, int_mv *mv) { ...@@ -47,12 +47,12 @@ static void clamp_mv_ref(const MACROBLOCKD *xd, int_mv *mv) {
static int get_matching_candidate(const MODE_INFO *candidate_mi, static int get_matching_candidate(const MODE_INFO *candidate_mi,
MV_REFERENCE_FRAME ref_frame, MV_REFERENCE_FRAME ref_frame,
int_mv *c_mv, int block_idx) { int_mv *c_mv, int block_idx) {
if (ref_frame == candidate_mi->mbmi.ref_frame) { if (ref_frame == candidate_mi->mbmi.ref_frame[0]) {
if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8) if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8)
c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[0].as_int; c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[0].as_int;
else else
c_mv->as_int = candidate_mi->mbmi.mv[0].as_int; c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
} else if (ref_frame == candidate_mi->mbmi.second_ref_frame) { } else if (ref_frame == candidate_mi->mbmi.ref_frame[1]) {
if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8) if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8)
c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[1].as_int; c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[1].as_int;
else else
...@@ -79,18 +79,18 @@ static void get_non_matching_candidates(const MODE_INFO *candidate_mi, ...@@ -79,18 +79,18 @@ static void get_non_matching_candidates(const MODE_INFO *candidate_mi,
*c2_ref_frame = INTRA_FRAME; *c2_ref_frame = INTRA_FRAME;
// If first candidate not valid neither will be. // If first candidate not valid neither will be.
if (candidate_mi->mbmi.ref_frame > INTRA_FRAME) { if (candidate_mi->mbmi.ref_frame[0] > INTRA_FRAME) {
// First candidate // First candidate
if (candidate_mi->mbmi.ref_frame != ref_frame) { if (candidate_mi->mbmi.ref_frame[0] != ref_frame) {
*c_ref_frame = candidate_mi->mbmi.ref_frame; *c_ref_frame = candidate_mi->mbmi.ref_frame[0];
c_mv->as_int = candidate_mi->mbmi.mv[0].as_int; c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
} }
// Second candidate // Second candidate
if ((candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) && if ((candidate_mi->mbmi.ref_frame[1] > INTRA_FRAME) &&
(candidate_mi->mbmi.second_ref_frame != ref_frame) && (candidate_mi->mbmi.ref_frame[1] != ref_frame) &&
(candidate_mi->mbmi.mv[1].as_int != candidate_mi->mbmi.mv[0].as_int)) { (candidate_mi->mbmi.mv[1].as_int != candidate_mi->mbmi.mv[0].as_int)) {
*c2_ref_frame = candidate_mi->mbmi.second_ref_frame; *c2_ref_frame = candidate_mi->mbmi.ref_frame[1];
c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int; c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
} }
} }
...@@ -226,7 +226,7 @@ void vp9_find_mv_refs_idx(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here, ...@@ -226,7 +226,7 @@ void vp9_find_mv_refs_idx(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here,
&refmv_count, c_refmv, 16); &refmv_count, c_refmv, 16);
} }
split_count += (candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8 && split_count += (candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8 &&
candidate_mi->mbmi.ref_frame != INTRA_FRAME); candidate_mi->mbmi.ref_frame[0] != INTRA_FRAME);
// Count number of neihgbours coded intra and zeromv // Count number of neihgbours coded intra and zeromv
intra_count += (candidate_mi->mbmi.mode < NEARESTMV); intra_count += (candidate_mi->mbmi.mode < NEARESTMV);
......
...@@ -40,8 +40,6 @@ ...@@ -40,8 +40,6 @@
#define NUM_FRAME_CONTEXTS_LG2 2 #define NUM_FRAME_CONTEXTS_LG2 2
#define NUM_FRAME_CONTEXTS (1 << NUM_FRAME_CONTEXTS_LG2) #define NUM_FRAME_CONTEXTS (1 << NUM_FRAME_CONTEXTS_LG2)
#define COMP_PRED_CONTEXTS 2
#define MAX_LAG_BUFFERS 25 #define MAX_LAG_BUFFERS 25
typedef struct frame_contexts { typedef struct frame_contexts {
...@@ -78,6 +76,19 @@ typedef struct frame_contexts { ...@@ -78,6 +76,19 @@ typedef struct frame_contexts {
vp9_prob inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1]; vp9_prob inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1];
vp9_prob pre_inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1]; vp9_prob pre_inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1];
unsigned int inter_mode_counts[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1][2]; unsigned int inter_mode_counts[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1][2];
vp9_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
vp9_prob comp_inter_prob[COMP_INTER_CONTEXTS];
vp9_prob single_ref_prob[REF_CONTEXTS][2];
vp9_prob comp_ref_prob[REF_CONTEXTS];
vp9_prob pre_intra_inter_prob[INTRA_INTER_CONTEXTS];
vp9_prob pre_comp_inter_prob[COMP_INTER_CONTEXTS];
vp9_prob pre_single_ref_prob[REF_CONTEXTS][2];
vp9_prob pre_comp_ref_prob[REF_CONTEXTS];
unsigned int intra_inter_count[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter_count[COMP_INTER_CONTEXTS][2];
unsigned int single_ref_count[REF_CONTEXTS][2][2];
unsigned int comp_ref_count[REF_CONTEXTS][2];
} FRAME_CONTEXT; } FRAME_CONTEXT;
typedef enum { typedef enum {
...@@ -162,7 +173,6 @@ typedef struct VP9Common { ...@@ -162,7 +173,6 @@ typedef struct VP9Common {
/* profile settings */ /* profile settings */
int experimental; int experimental;
TXFM_MODE txfm_mode; TXFM_MODE txfm_mode;
COMPPREDMODE_TYPE comp_pred_mode;
int no_lpf; int no_lpf;
int use_bilinear_mc_filter; int use_bilinear_mc_filter;
...@@ -219,20 +229,15 @@ typedef struct VP9Common { ...@@ -219,20 +229,15 @@ typedef struct VP9Common {
[VP9_INTRA_MODES - 1]; [VP9_INTRA_MODES - 1];
vp9_prob kf_uv_mode_prob[VP9_INTRA_MODES] [VP9_INTRA_MODES - 1]; vp9_prob kf_uv_mode_prob[VP9_INTRA_MODES] [VP9_INTRA_MODES - 1];
vp9_prob prob_intra_coded;
vp9_prob prob_last_coded;
vp9_prob prob_gf_coded;
// Context probabilities when using predictive coding of segment id // Context probabilities when using predictive coding of segment id
vp9_prob segment_pred_probs[PREDICTION_PROBS]; vp9_prob segment_pred_probs[PREDICTION_PROBS];
unsigned char temporal_update; unsigned char temporal_update;
// Context probabilities for reference frame prediction // Context probabilities for reference frame prediction
unsigned char ref_scores[MAX_REF_FRAMES]; int allow_comp_inter_inter;
vp9_prob ref_pred_probs[PREDICTION_PROBS]; MV_REFERENCE_FRAME comp_fixed_ref;
vp9_prob mod_refprobs[MAX_REF_FRAMES][PREDICTION_PROBS]; MV_REFERENCE_FRAME comp_var_ref[2];
COMPPREDMODE_TYPE comp_pred_mode;
vp9_prob prob_comppred[COMP_PRED_CONTEXTS];
// FIXME contextualize // FIXME contextualize
vp9_prob prob_tx[TX_SIZE_MAX_SB - 1]; vp9_prob prob_tx[TX_SIZE_MAX_SB - 1];
......
This diff is collapsed.
...@@ -17,10 +17,13 @@ ...@@ -17,10 +17,13 @@
// Predicted items // Predicted items
typedef enum { typedef enum {
PRED_SEG_ID = 0, // Segment identifier PRED_SEG_ID = 0, // Segment identifier
PRED_REF = 1, PRED_MBSKIP = 1,
PRED_COMP = 2, PRED_SWITCHABLE_INTERP = 2,
PRED_MBSKIP = 3, PRED_INTRA_INTER = 3,
PRED_SWITCHABLE_INTERP = 4 PRED_COMP_INTER_INTER = 4,
PRED_SINGLE_REF_P1 = 5,
PRED_SINGLE_REF_P2 = 6,
PRED_COMP_REF_P = 7,
} PRED_ID; } PRED_ID;
unsigned char vp9_get_pred_context(const VP9_COMMON *const cm, unsigned char vp9_get_pred_context(const VP9_COMMON *const cm,
...@@ -46,9 +49,4 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd, ...@@ -46,9 +49,4 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd,
int vp9_get_pred_mi_segid(VP9_COMMON *cm, BLOCK_SIZE_TYPE sb_type, int vp9_get_pred_mi_segid(VP9_COMMON *cm, BLOCK_SIZE_TYPE sb_type,
int mi_row, int mi_col); int mi_row, int mi_col);
MV_REFERENCE_FRAME vp9_get_pred_ref(const VP9_COMMON *const cm,
const MACROBLOCKD *const xd);
void vp9_compute_mod_refprobs(VP9_COMMON *const cm);
#endif // VP9_COMMON_VP9_PRED_COMMON_H_ #endif // VP9_COMMON_VP9_PRED_COMMON_H_
...@@ -171,8 +171,8 @@ void vp9_setup_interp_filters(MACROBLOCKD *xd, ...@@ -171,8 +171,8 @@ void vp9_setup_interp_filters(MACROBLOCKD *xd,
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi; MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
set_scale_factors(xd, set_scale_factors(xd,
mbmi->ref_frame - 1, mbmi->ref_frame[0] - 1,
mbmi->second_ref_frame - 1, mbmi->ref_frame[1] - 1,
cm->active_ref_scale); cm->active_ref_scale);
} }
...@@ -386,7 +386,7 @@ static void build_inter_predictors(int plane, int block, ...@@ -386,7 +386,7 @@ static void build_inter_predictors(int plane, int block,
const int bhl = b_height_log2(bsize) - xd->plane[plane].subsampling_y; const int bhl = b_height_log2(bsize) - xd->plane[plane].subsampling_y;
const int bh = 4 << bhl, bw = 4 << bwl; const int bh = 4 << bhl, bw = 4 << bwl;
const int x = 4 * (block & ((1 << bwl) - 1)), y = 4 * (block >> bwl); const int x = 4 * (block & ((1 << bwl) - 1)), y = 4 * (block >> bwl);
const int use_second_ref = xd->mode_info_context->mbmi.second_ref_frame > 0; const int use_second_ref = xd->mode_info_context->mbmi.ref_frame[1] > 0;
int which_mv; int which_mv;
assert(x < bw); assert(x < bw);
......
...@@ -81,7 +81,6 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m, ...@@ -81,7 +81,6 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
VP9_COMMON *const cm = &pbi->common; VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb; MACROBLOCKD *const xd = &pbi->mb;
const int mis = cm->mode_info_stride; const int mis = cm->mode_info_stride;
m->mbmi.ref_frame = INTRA_FRAME;
// Read segmentation map if it is being updated explicitly this frame // Read segmentation map if it is being updated explicitly this frame
m->mbmi.segment_id = 0; m->mbmi.segment_id = 0;
...@@ -114,7 +113,7 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m, ...@@ -114,7 +113,7 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
} }
// luma mode // luma mode
m->mbmi.ref_frame = INTRA_FRAME; m->mbmi.ref_frame[0] = INTRA_FRAME;
if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) { if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
const MB_PREDICTION_MODE A = above_block_mode(m, 0, mis); const MB_PREDICTION_MODE A = above_block_mode(m, 0, mis);
const MB_PREDICTION_MODE L = xd->left_available ? const MB_PREDICTION_MODE L = xd->left_available ?
...@@ -232,17 +231,13 @@ static void read_nmvprobs(vp9_reader *r, nmv_context *mvctx, ...@@ -232,17 +231,13 @@ static void read_nmvprobs(vp9_reader *r, nmv_context *mvctx,
} }
// Read the referncence frame // Read the referncence frame
static MV_REFERENCE_FRAME read_ref_frame(VP9D_COMP *pbi, static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r,
vp9_reader *r, int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
int segment_id) {
MV_REFERENCE_FRAME ref_frame;
VP9_COMMON *const cm = &pbi->common; VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb; MACROBLOCKD *const xd = &pbi->mb;
int seg_ref_count = 0; int seg_ref_count = 0;
const int seg_ref_active = vp9_segfeature_active(xd, segment_id, const int seg_ref_active = vp9_segfeature_active(xd, segment_id,
SEG_LVL_REF_FRAME); SEG_LVL_REF_FRAME);
const int intra = vp9_check_segref(xd, segment_id, INTRA_FRAME); const int intra = vp9_check_segref(xd, segment_id, INTRA_FRAME);
const int last = vp9_check_segref(xd, segment_id, LAST_FRAME); const int last = vp9_check_segref(xd, segment_id, LAST_FRAME);
const int golden = vp9_check_segref(xd, segment_id, GOLDEN_FRAME); const int golden = vp9_check_segref(xd, segment_id, GOLDEN_FRAME);
...@@ -256,79 +251,43 @@ static MV_REFERENCE_FRAME read_ref_frame(VP9D_COMP *pbi, ...@@ -256,79 +251,43 @@ static MV_REFERENCE_FRAME read_ref_frame(VP9D_COMP *pbi,
// Segment reference frame features not available or allows for // Segment reference frame features not available or allows for
// multiple reference frame options // multiple reference frame options
if (!seg_ref_active || seg_ref_count > 1) { if (!seg_ref_active || seg_ref_count > 1) {
// Values used in prediction model coding int is_comp;
MV_REFERENCE_FRAME pred_ref; int comp_ctx = vp9_get_pred_context(cm, xd, PRED_COMP_INTER_INTER);
// Get the context probability the prediction flag
vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF);
// Read the prediction status flag if (cm->comp_pred_mode == HYBRID_PREDICTION) {
unsigned char prediction_flag = vp9_read(r, pred_prob); is_comp = vp9_read(r, cm->fc.comp_inter_prob[comp_ctx]);
cm->fc.comp_inter_count[comp_ctx][is_comp]++;
// Store the prediction flag. } else {
vp9_set_pred_flag(xd, PRED_REF, prediction_flag); is_comp = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
}
// Get the predicted reference frame. // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
pred_ref = vp9_get_pred_ref(cm, xd); if (is_comp) {
int b, fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
int ref_ctx = vp9_get_pred_context(cm, xd, PRED_COMP_REF_P);
// If correctly predicted then use the predicted value ref_frame[fix_ref_idx] = cm->comp_fixed_ref;
if (prediction_flag) { b = vp9_read(r, cm->fc.comp_ref_prob[ref_ctx]);
ref_frame = pred_ref;