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 @@
#define BLOCK_SIZE_GROUPS 4
#define MAX_MB_SEGMENTS 8
#define MB_SEG_TREE_PROBS (MAX_MB_SEGMENTS-1)
#define PREDICTION_PROBS 3
#define DEFAULT_PRED_PROB_0 120
#define DEFAULT_PRED_PROB_1 80
#define DEFAULT_PRED_PROB_2 40
#define PREDICTION_PROBS 3
#define MBSKIP_CONTEXTS 3
......@@ -40,6 +37,10 @@
#define SEGMENT_ABSDATA 1
#define MAX_MV_REF_CANDIDATES 2
#define INTRA_INTER_CONTEXTS 4
#define COMP_INTER_CONTEXTS 5
#define REF_CONTEXTS 5
typedef enum {
PLANE_TYPE_Y_WITH_DC,
PLANE_TYPE_UV,
......@@ -200,7 +201,7 @@ static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) {
typedef struct {
MB_PREDICTION_MODE mode, uv_mode;
MV_REFERENCE_FRAME ref_frame, second_ref_frame;
MV_REFERENCE_FRAME ref_frame[2];
TX_SIZE txfm_size;
int_mv mv[2]; // for each reference frame used
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
......@@ -215,7 +216,6 @@ typedef struct {
// Flags used for prediction status of various bistream signals
unsigned char seg_id_predicted;
unsigned char ref_predicted;
// Indicates if the mb is part of the image (1) vs border (0)
// 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) {
TX_TYPE tx_type;
MODE_INFO *mi = xd->mode_info_context;
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;
if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
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];
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) {
vpx_memcpy(x->fc.uv_mode_prob, default_if_uv_probs,
sizeof(default_if_uv_probs));
......@@ -143,9 +163,14 @@ void vp9_init_mbmode_probs(VP9_COMMON *x) {
vpx_memcpy(x->fc.partition_prob, vp9_partition_probs,
sizeof(vp9_partition_probs));
x->ref_pred_probs[0] = DEFAULT_PRED_PROB_0;
x->ref_pred_probs[1] = DEFAULT_PRED_PROB_1;
x->ref_pred_probs[2] = DEFAULT_PRED_PROB_2;
vpx_memcpy(x->fc.intra_inter_prob, default_intra_inter_p,
sizeof(default_intra_inter_p));
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
......@@ -246,6 +271,14 @@ void vp9_adapt_mode_context(VP9_COMMON *pc) {
#define MODE_COUNT_SAT 20
#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,
const vp9_tree_index *tree, unsigned int *cnt,
vp9_prob *pre_probs, vp9_prob *dst_probs,
......@@ -253,21 +286,22 @@ static void update_mode_probs(int n_modes,
#define MAX_PROBS 32
vp9_prob probs[MAX_PROBS];
unsigned int branch_ct[MAX_PROBS][2];
int t, count, factor;
int t;
assert(n_modes - 1 < MAX_PROBS);
vp9_tree_probs_from_distribution(tree, probs, branch_ct, cnt, tok0_offset);
for (t = 0; t < n_modes - 1; ++t) {
count = branch_ct[t][0] + branch_ct[t][1];
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);
}
for (t = 0; t < n_modes - 1; ++t)
dst_probs[t] = update_mode_ct(pre_probs[t], probs[t], branch_ct[t]);
}
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
void vp9_adapt_mode_probs(VP9_COMMON *cm) {
int i;
int i, j;
FRAME_CONTEXT *fc = &cm->fc;
#ifdef MODE_COUNT_TESTING
int t;
......@@ -303,6 +337,20 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
printf("};\n");
#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++)
update_mode_probs(VP9_INTRA_MODES, vp9_intra_mode_tree,
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,
vp9_find_mv_refs_idx(cm, xd, xd->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);
dst_list[1].as_int = 0;
......
......@@ -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 */
--cur_mb;
if (cur_mb->mbmi.ref_frame != INTRA_FRAME) {
if (cur_mb->mbmi.ref_frame[0] != INTRA_FRAME) {
return DC_PRED;
} else if (cur_mb->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
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,
/* On top edge, get from MB above us */
cur_mb -= mi_stride;
if (cur_mb->mbmi.ref_frame != INTRA_FRAME) {
if (cur_mb->mbmi.ref_frame[0] != INTRA_FRAME) {
return DC_PRED;
} else if (cur_mb->mbmi.sb_type < BLOCK_SIZE_SB8X8) {
return ((cur_mb->bmi + 2 + b)->as_mode.first);
......
......@@ -140,11 +140,11 @@ void segment_via_mode_info(VP9_COMMON *oci, int how) {
break;
case SEGMENT_MV:
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;
break;
case SEGMENT_REFFRAME:
n = mi[mb_index].mbmi.ref_frame;
n = mi[mb_index].mbmi.ref_frame[0];
break;
case SEGMENT_SKIPPED:
n = mi[mb_index].mbmi.mb_skip_coeff;
......
......@@ -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 *mbmi1 = &mip1->mbmi;
return mb_lf_skip(mbmi0) && mb_lf_skip(mbmi1) &&
mbmi0->ref_frame != INTRA_FRAME &&
mbmi1->ref_frame != INTRA_FRAME;
mbmi0->ref_frame[0] != INTRA_FRAME &&
mbmi1->ref_frame[0] != INTRA_FRAME;
}
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_index = lfi_n->mode_lf_lut[mode];
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];
if (filter_level) {
......
......@@ -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,
MV_REFERENCE_FRAME ref_frame,
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)
c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[0].as_int;
else
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)
c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[1].as_int;
else
......@@ -79,18 +79,18 @@ static void get_non_matching_candidates(const MODE_INFO *candidate_mi,
*c2_ref_frame = INTRA_FRAME;
// 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
if (candidate_mi->mbmi.ref_frame != ref_frame) {
*c_ref_frame = candidate_mi->mbmi.ref_frame;
if (candidate_mi->mbmi.ref_frame[0] != ref_frame) {
*c_ref_frame = candidate_mi->mbmi.ref_frame[0];
c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
}
// Second candidate
if ((candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) &&
(candidate_mi->mbmi.second_ref_frame != ref_frame) &&
if ((candidate_mi->mbmi.ref_frame[1] > INTRA_FRAME) &&
(candidate_mi->mbmi.ref_frame[1] != ref_frame) &&
(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;
}
}
......@@ -226,7 +226,7 @@ void vp9_find_mv_refs_idx(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here,
&refmv_count, c_refmv, 16);
}
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
intra_count += (candidate_mi->mbmi.mode < NEARESTMV);
......
......@@ -40,8 +40,6 @@
#define NUM_FRAME_CONTEXTS_LG2 2
#define NUM_FRAME_CONTEXTS (1 << NUM_FRAME_CONTEXTS_LG2)
#define COMP_PRED_CONTEXTS 2
#define MAX_LAG_BUFFERS 25
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 pre_inter_mode_probs[INTER_MODE_CONTEXTS][VP9_INTER_MODES - 1];
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;
typedef enum {
......@@ -162,7 +173,6 @@ typedef struct VP9Common {
/* profile settings */
int experimental;
TXFM_MODE txfm_mode;
COMPPREDMODE_TYPE comp_pred_mode;
int no_lpf;
int use_bilinear_mc_filter;
......@@ -219,20 +229,15 @@ typedef struct VP9Common {
[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
vp9_prob segment_pred_probs[PREDICTION_PROBS];
unsigned char temporal_update;
// Context probabilities for reference frame prediction
unsigned char ref_scores[MAX_REF_FRAMES];
vp9_prob ref_pred_probs[PREDICTION_PROBS];
vp9_prob mod_refprobs[MAX_REF_FRAMES][PREDICTION_PROBS];
vp9_prob prob_comppred[COMP_PRED_CONTEXTS];
int allow_comp_inter_inter;
MV_REFERENCE_FRAME comp_fixed_ref;
MV_REFERENCE_FRAME comp_var_ref[2];
COMPPREDMODE_TYPE comp_pred_mode;
// FIXME contextualize
vp9_prob prob_tx[TX_SIZE_MAX_SB - 1];
......
This diff is collapsed.
......@@ -17,10 +17,13 @@
// Predicted items
typedef enum {
PRED_SEG_ID = 0, // Segment identifier
PRED_REF = 1,
PRED_COMP = 2,
PRED_MBSKIP = 3,
PRED_SWITCHABLE_INTERP = 4
PRED_MBSKIP = 1,
PRED_SWITCHABLE_INTERP = 2,
PRED_INTRA_INTER = 3,
PRED_COMP_INTER_INTER = 4,
PRED_SINGLE_REF_P1 = 5,
PRED_SINGLE_REF_P2 = 6,
PRED_COMP_REF_P = 7,
} PRED_ID;
unsigned char vp9_get_pred_context(const VP9_COMMON *const cm,
......@@ -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 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_
......@@ -171,8 +171,8 @@ void vp9_setup_interp_filters(MACROBLOCKD *xd,
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
set_scale_factors(xd,
mbmi->ref_frame - 1,
mbmi->second_ref_frame - 1,
mbmi->ref_frame[0] - 1,
mbmi->ref_frame[1] - 1,
cm->active_ref_scale);
}
......@@ -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 bh = 4 << bhl, bw = 4 << 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;
assert(x < bw);
......
......@@ -81,7 +81,6 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
const int mis = cm->mode_info_stride;
m->mbmi.ref_frame = INTRA_FRAME;
// Read segmentation map if it is being updated explicitly this frame
m->mbmi.segment_id = 0;
......@@ -114,7 +113,7 @@ static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
}
// luma mode
m->mbmi.ref_frame = INTRA_FRAME;
m->mbmi.ref_frame[0] = INTRA_FRAME;
if (m->mbmi.sb_type >= BLOCK_SIZE_SB8X8) {
const MB_PREDICTION_MODE A = above_block_mode(m, 0, mis);
const MB_PREDICTION_MODE L = xd->left_available ?
......@@ -232,17 +231,13 @@ static void read_nmvprobs(vp9_reader *r, nmv_context *mvctx,
}
// Read the referncence frame
static MV_REFERENCE_FRAME read_ref_frame(VP9D_COMP *pbi,
vp9_reader *r,
int segment_id) {
MV_REFERENCE_FRAME ref_frame;
static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r,
int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
VP9_COMMON *const cm = &pbi->common;
MACROBLOCKD *const xd = &pbi->mb;
int seg_ref_count = 0;
const int seg_ref_active = vp9_segfeature_active(xd, segment_id,
SEG_LVL_REF_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 golden = vp9_check_segref(xd, segment_id, GOLDEN_FRAME);
......@@ -256,79 +251,43 @@ static MV_REFERENCE_FRAME read_ref_frame(VP9D_COMP *pbi,
// Segment reference frame features not available or allows for
// multiple reference frame options
if (!seg_ref_active || seg_ref_count > 1) {
// Values used in prediction model coding
MV_REFERENCE_FRAME pred_ref;
// Get the context probability the prediction flag
vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF);
int is_comp;
int comp_ctx = vp9_get_pred_context(cm, xd, PRED_COMP_INTER_INTER);
// Read the prediction status flag
unsigned char prediction_flag = vp9_read(r, pred_prob);
// Store the prediction flag.
vp9_set_pred_flag(xd, PRED_REF, prediction_flag);
if (cm->comp_pred_mode == HYBRID_PREDICTION) {
is_comp = vp9_read(r, cm->fc.comp_inter_prob[comp_ctx]);
cm->fc.comp_inter_count[comp_ctx][is_comp]++;
} else {
is_comp = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
}
// Get the predicted reference frame.
pred_ref = vp9_get_pred_ref(cm, xd);
// FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
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
if (prediction_flag) {
ref_frame = pred_ref;
ref_frame[fix_ref_idx] = cm->comp_fixed_ref;
b = vp9_read(r, cm->fc.comp_ref_prob[ref_ctx]);
cm->fc.comp_ref_count[ref_ctx][b]++;
ref_frame[!fix_ref_idx] = cm->comp_var_ref[b];
} else {
// decode the explicitly coded value
vp9_prob mod_refprobs[PREDICTION_PROBS];
vpx_memcpy(mod_refprobs, cm->mod_refprobs[pred_ref],
sizeof(mod_refprobs));
// If segment coding enabled blank out options that cant occur by
// setting the branch probability to 0.
if (seg_ref_active) {
mod_refprobs[INTRA_FRAME] *= intra;
mod_refprobs[LAST_FRAME] *= last;
mod_refprobs[GOLDEN_FRAME] *= golden * altref;
}
// Default to INTRA_FRAME (value 0)
ref_frame = INTRA_FRAME;
// Do we need to decode the Intra/Inter branch
if (mod_refprobs[0])
ref_frame = vp9_read(r, mod_refprobs[0]);
else
ref_frame++;
if (ref_frame) {
// Do we need to decode the Last/Gf_Arf branch
if (mod_refprobs[1])
ref_frame += vp9_read(r, mod_refprobs[1]);
else
ref_frame++;
if (ref_frame > 1) {
// Do we need to decode the GF/Arf branch
if (mod_refprobs[2]) {
ref_frame += vp9_read(r, mod_refprobs[2]);
int ref1_ctx = vp9_get_pred_context(cm, xd, PRED_SINGLE_REF_P1);
ref_frame[1] = NONE;
if (vp9_read(r, cm->fc.single_ref_prob[ref1_ctx][0])) {
int ref2_ctx = vp9_get_pred_context(cm, xd, PRED_SINGLE_REF_P2);
int b2 = vp9_read(r, cm->fc.single_ref_prob[ref2_ctx][1]);
ref_frame[0] = b2 ? ALTREF_FRAME : GOLDEN_FRAME;
cm->fc.single_ref_count[ref1_ctx][0][1]++;
cm->fc.single_ref_count[ref2_ctx][1][b2]++;
} else {
if (seg_ref_active)
ref_frame = pred_ref == GOLDEN_FRAME || !golden ? ALTREF_FRAME
: GOLDEN_FRAME;
else
ref_frame = pred_ref == GOLDEN_FRAME ? ALTREF_FRAME
: GOLDEN_FRAME;
}
}
ref_frame[0] = LAST_FRAME;
cm->fc.single_ref_count[ref1_ctx][0][0]++;
}
}
} else {
// Segment reference frame features are enabled
// The reference frame for the mb is considered as correclty predicted
// if it is signaled at the segment level for the purposes of the
// common prediction model
vp9_set_pred_flag(xd, PRED_REF, 1);
ref_frame = vp9_get_pred_ref(cm, xd);
ref_frame[0] = last ? LAST_FRAME : golden ? GOLDEN_FRAME : ALTREF_FRAME;
ref_frame[1] = NONE;
}
return ref_frame;
}
static MB_PREDICTION_MODE read_sb_mv_ref(vp9_reader *r, const vp9_prob *p) {
......@@ -389,19 +348,38 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) {
if (cm->mcomp_filter_type == SWITCHABLE)
read_switchable_interp_probs(cm, r);
// Baseline probabilities for decoding reference frame
cm->prob_intra_coded = vp9_read_prob(r);
cm->prob_last_coded = vp9_read_prob(r);
cm->prob_gf_coded = vp9_read_prob(r);
// Computes a modified set of probabilities for use when reference
// frame prediction fails.
vp9_compute_mod_refprobs(cm);
for (i = 0; i < INTRA_INTER_CONTEXTS; i++) {
if (vp9_read(r, VP9_DEF_UPDATE_PROB))
cm->fc.intra_inter_prob[i] =
vp9_read_prob_diff_update(r, cm->fc.intra_inter_prob[i]);
}
if (cm->allow_comp_inter_inter) {
cm->comp_pred_mode = read_comp_pred_mode(r);
if (cm->comp_pred_mode == HYBRID_PREDICTION)
for (i = 0; i < COMP_PRED_CONTEXTS; i++)
cm->prob_comppred[i] = vp9_read_prob(r);
for (i = 0; i < COMP_INTER_CONTEXTS; i++)
if (vp9_read(r, VP9_DEF_UPDATE_PROB))
cm->fc.comp_inter_prob[i] =
vp9_read_prob_diff_update(r, cm->fc.comp_inter_prob[i]);
} else {
cm->comp_pred_mode = SINGLE_PREDICTION_ONLY;
}
if (cm->comp_pred_mode != COMP_PREDICTION_ONLY)
for (i = 0; i < REF_CONTEXTS; i++) {
if (vp9_read(r, VP9_DEF_UPDATE_PROB))
cm->fc.single_ref_prob[i][0] =
vp9_read_prob_diff_update(r, cm->fc.single_ref_prob[i][0]);
if (vp9_read(r, VP9_DEF_UPDATE_PROB))
cm->fc.single_ref_prob[i][1] =
vp9_read_prob_diff_update(r, cm->fc.single_ref_prob[i][1]);
}
if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY)
for (i = 0; i < REF_CONTEXTS; i++)
if (vp9_read(r, VP9_DEF_UPDATE_PROB))
cm->fc.comp_ref_prob[i] =
vp9_read_prob_diff_update(r, cm->fc.comp_ref_prob[i]);
// VP9_INTRA_MODES
for (j = 0; j < BLOCK_SIZE_GROUPS; j++) {
......@@ -526,7 +504,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mbmi->need_to_clamp_mvs = 0;
mbmi->need_to_clamp_secondmv = 0;
mbmi->second_ref_frame = NONE;
mbmi->ref_frame[1] = NONE;
// Make sure the MACROBLOCKD mode info pointer is pointed at the
// correct entry for the current macroblock.
......@@ -552,10 +530,12 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
mbmi->mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
// Read the reference frame
mbmi->ref_frame = read_ref_frame(pbi, r, mbmi->segment_id);
mbmi->ref_frame[0] = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_INTRA_INTER));
cm->fc.intra_inter_count[vp9_get_pred_context(cm, xd, PRED_INTRA_INTER)]
[mbmi->ref_frame[0] != INTRA_FRAME]++;
if (cm->txfm_mode == TX_MODE_SELECT &&
(mbmi->mb_skip_coeff == 0 || mbmi->ref_frame == INTRA_FRAME) &&
(mbmi->mb_skip_coeff == 0 || mbmi->ref_frame[0] == INTRA_FRAME) &&
bsize >= BLOCK_SIZE_SB8X8) {
const int allow_16x16 = bsize >= BLOCK_SIZE_MB16X16;
const int allow_32x32 = bsize >= BLOCK_SIZE_SB32X32;
......@@ -573,11 +553,12 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
}
// If reference frame is an Inter frame
if (mbmi->ref_frame) {
if (mbmi->ref_frame[0] != INTRA_FRAME) {
int_mv nearest, nearby, best_mv;
int_mv nearest_second, nearby_second, best_mv_second;
vp9_prob mv_ref_p[VP9_INTER_MODES - 1];
const MV_REFERENCE_FRAME ref_frame = mbmi->ref_frame;
read_ref_frame(pbi, r, mbmi->segment_id, mbmi->ref_frame);
{
#ifdef DEC_DEBUG
......@@ -585,25 +566,27 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
printf("%d %d\n", xd->mode_info_context->mbmi.mv[0].as_mv.row,
xd->mode_info_context->mbmi.mv[0].as_mv.col);
#endif
vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context, ref_frame,
mbmi->ref_mvs[ref_frame], cm->ref_frame_sign_bias);
vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
mbmi->ref_frame[0], mbmi->ref_mvs[mbmi->ref_frame[0]],
cm->ref_frame_sign_bias);