From: Ronald S. Bultje Date: Thu, 6 Jun 2013 20:44:34 +0000 (-0700) Subject: Change ref frame coding. X-Git-Tag: v1.3.0~1104^2~66 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6ef805eb9d084eec2ca52ff5740cbd30972fbf78;p=platform%2Fupstream%2Flibvpx.git 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 --- diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index d7419e4..b8822a6 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -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); diff --git a/vp9/common/vp9_entropymode.c b/vp9/common/vp9_entropymode.c index 411388a..bed4edf 100644 --- a/vp9/common/vp9_entropymode.c +++ b/vp9/common/vp9_entropymode.c @@ -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], diff --git a/vp9/common/vp9_findnearmv.c b/vp9/common/vp9_findnearmv.c index e3a46f2..d781711 100644 --- a/vp9/common/vp9_findnearmv.c +++ b/vp9/common/vp9_findnearmv.c @@ -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; diff --git a/vp9/common/vp9_findnearmv.h b/vp9/common/vp9_findnearmv.h index a75d6a0..91736fe 100644 --- a/vp9/common/vp9_findnearmv.h +++ b/vp9/common/vp9_findnearmv.h @@ -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); diff --git a/vp9/common/vp9_implicit_segmentation.c b/vp9/common/vp9_implicit_segmentation.c index a72c1c7..2a1d35f 100644 --- a/vp9/common/vp9_implicit_segmentation.c +++ b/vp9/common/vp9_implicit_segmentation.c @@ -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; diff --git a/vp9/common/vp9_loopfilter.c b/vp9/common/vp9_loopfilter.c index eb7d01c..fbd9101 100644 --- a/vp9/common/vp9_loopfilter.c +++ b/vp9/common/vp9_loopfilter.c @@ -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) { diff --git a/vp9/common/vp9_mvref_common.c b/vp9/common/vp9_mvref_common.c index 224151d..f225c02 100644 --- a/vp9/common/vp9_mvref_common.c +++ b/vp9/common/vp9_mvref_common.c @@ -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); diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index 68a8052..e73d88c 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -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]; diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c index 459e9d5..73c7278 100644 --- a/vp9/common/vp9_pred_common.c +++ b/vp9/common/vp9_pred_common.c @@ -26,6 +26,8 @@ unsigned char vp9_get_pred_context(const VP9_COMMON *const cm, const MODE_INFO *const mi = xd->mode_info_context; const MODE_INFO *const above_mi = mi - cm->mode_info_stride; const MODE_INFO *const left_mi = mi - 1; + const int left_in_image = xd->left_available && left_mi->mbmi.mb_in_image; + const int above_in_image = xd->up_available && above_mi->mbmi.mb_in_image; // Note: // The mode info data structure has a one element border above and to the // left of the entries correpsonding to real macroblocks. @@ -37,19 +39,6 @@ unsigned char vp9_get_pred_context(const VP9_COMMON *const cm, pred_context += left_mi->mbmi.seg_id_predicted; break; - case PRED_REF: - pred_context = above_mi->mbmi.ref_predicted; - if (xd->left_available) - pred_context += left_mi->mbmi.ref_predicted; - break; - - case PRED_COMP: - if (mi->mbmi.ref_frame == LAST_FRAME) - pred_context = 0; - else - pred_context = 1; - break; - case PRED_MBSKIP: pred_context = above_mi->mbmi.mb_skip_coeff; if (xd->left_available) @@ -58,14 +47,12 @@ unsigned char vp9_get_pred_context(const VP9_COMMON *const cm, case PRED_SWITCHABLE_INTERP: { // left - const int left_in_image = xd->left_available && left_mi->mbmi.mb_in_image; const int left_mv_pred = is_inter_mode(left_mi->mbmi.mode); const int left_interp = left_in_image && left_mv_pred ? vp9_switchable_interp_map[left_mi->mbmi.interp_filter] : VP9_SWITCHABLE_FILTERS; // above - const int above_in_image = xd->up_available && above_mi->mbmi.mb_in_image; const int above_mv_pred = is_inter_mode(above_mi->mbmi.mode); const int above_interp = above_in_image && above_mv_pred ? vp9_switchable_interp_map[above_mi->mbmi.interp_filter] : @@ -88,7 +75,281 @@ unsigned char vp9_get_pred_context(const VP9_COMMON *const cm, break; } + case PRED_INTRA_INTER: { + if (above_in_image && left_in_image) { // both edges available + if (left_mi->mbmi.ref_frame[0] == INTRA_FRAME && + above_mi->mbmi.ref_frame[0] == INTRA_FRAME) { // intra/intra (3) + pred_context = 3; + } else { // intra/inter (1) or inter/inter (0) + pred_context = left_mi->mbmi.ref_frame[0] == INTRA_FRAME || + above_mi->mbmi.ref_frame[0] == INTRA_FRAME; + } + } else if (above_in_image || left_in_image) { // one edge available + const MODE_INFO *edge = above_in_image ? above_mi : left_mi; + + // inter: 0, intra: 2 + pred_context = 2 * (edge->mbmi.ref_frame[0] == INTRA_FRAME); + } else { + pred_context = 0; + } + assert(pred_context >= 0 && pred_context < INTRA_INTER_CONTEXTS); + break; + } + + case PRED_COMP_INTER_INTER: { + if (above_in_image && left_in_image) { // both edges available + if (above_mi->mbmi.ref_frame[1] <= INTRA_FRAME && + left_mi->mbmi.ref_frame[1] <= INTRA_FRAME) { + // neither edge uses comp pred (0/1) + pred_context = ((above_mi->mbmi.ref_frame[0] == cm->comp_fixed_ref) ^ + (left_mi->mbmi.ref_frame[0] == cm->comp_fixed_ref)); + } else if (above_mi->mbmi.ref_frame[1] <= INTRA_FRAME) { + // one of two edges uses comp pred (2/3) + pred_context = 2 + + (above_mi->mbmi.ref_frame[0] == cm->comp_fixed_ref || + above_mi->mbmi.ref_frame[0] == INTRA_FRAME); + } else if (left_mi->mbmi.ref_frame[1] <= INTRA_FRAME) { + // one of two edges uses comp pred (2/3) + pred_context = 2 + + (left_mi->mbmi.ref_frame[0] == cm->comp_fixed_ref || + left_mi->mbmi.ref_frame[0] == INTRA_FRAME); + } else { // both edges use comp pred (4) + pred_context = 4; + } + } else if (above_in_image || left_in_image) { // one edge available + const MODE_INFO *edge = above_in_image ? above_mi : left_mi; + + if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) { + // edge does not use comp pred (0/1) + pred_context = edge->mbmi.ref_frame[0] == cm->comp_fixed_ref; + } else { // edge uses comp pred (3) + pred_context = 3; + } + } else { // no edges available (1) + pred_context = 1; + } + assert(pred_context >= 0 && pred_context < COMP_INTER_CONTEXTS); + break; + } + + case PRED_COMP_REF_P: { + const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref]; + const int var_ref_idx = !fix_ref_idx; + + if (above_in_image && left_in_image) { // both edges available + if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME && + left_mi->mbmi.ref_frame[0] == INTRA_FRAME) { // intra/intra (2) + pred_context = 2; + } else if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME || + left_mi->mbmi.ref_frame[0] == INTRA_FRAME) { // intra/inter + const MODE_INFO *edge = above_mi->mbmi.ref_frame[0] == INTRA_FRAME ? + left_mi : above_mi; + + if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) { // single pred (1/3) + pred_context = 1 + + 2 * edge->mbmi.ref_frame[0] != cm->comp_var_ref[1]; + } else { // comp pred (1/3) + pred_context = 1 + + 2 * edge->mbmi.ref_frame[var_ref_idx] != cm->comp_var_ref[1]; + } + } else { // inter/inter + int l_sg = left_mi->mbmi.ref_frame[1] <= INTRA_FRAME; + int a_sg = above_mi->mbmi.ref_frame[1] <= INTRA_FRAME; + MV_REFERENCE_FRAME vrfa = a_sg ? above_mi->mbmi.ref_frame[0] : + above_mi->mbmi.ref_frame[var_ref_idx]; + MV_REFERENCE_FRAME vrfl = l_sg ? left_mi->mbmi.ref_frame[0] : + left_mi->mbmi.ref_frame[var_ref_idx]; + + if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) { + pred_context = 0; + } else if (l_sg && a_sg) { // single/single + if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) || + (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0])) { + pred_context = 4; + } else if (vrfa == vrfl) { + pred_context = 3; + } else { + pred_context = 1; + } + } else if (l_sg || a_sg) { // single/comp + MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl; + MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl; + + if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1]) { + pred_context = 1; + } else if (rfs == cm->comp_var_ref[1] && + vrfc != cm->comp_var_ref[1]) { + pred_context = 2; + } else { + pred_context = 4; + } + } else if (vrfa == vrfl) { // comp/comp + pred_context = 4; + } else { + pred_context = 2; + } + } + } else if (above_in_image || left_in_image) { // one edge available + const MODE_INFO *edge = above_in_image ? above_mi : left_mi; + + if (edge->mbmi.ref_frame[0] == INTRA_FRAME) { + pred_context = 2; + } else if (edge->mbmi.ref_frame[1] > INTRA_FRAME) { + pred_context = + 4 * edge->mbmi.ref_frame[var_ref_idx] != cm->comp_var_ref[1]; + } else { + pred_context = 3 * edge->mbmi.ref_frame[0] != cm->comp_var_ref[1]; + } + } else { // no edges available (2) + pred_context = 2; + } + assert(pred_context >= 0 && pred_context < REF_CONTEXTS); + break; + } + + case PRED_SINGLE_REF_P1: { + if (above_in_image && left_in_image) { // both edges available + if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME && + left_mi->mbmi.ref_frame[0] == INTRA_FRAME) { + pred_context = 2; + } else if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME || + left_mi->mbmi.ref_frame[0] == INTRA_FRAME) { + const MODE_INFO *edge = above_mi->mbmi.ref_frame[0] == INTRA_FRAME ? + left_mi : above_mi; + + if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) { + pred_context = 4 * (edge->mbmi.ref_frame[0] == LAST_FRAME); + } else { + pred_context = 1 + (edge->mbmi.ref_frame[0] == LAST_FRAME || + edge->mbmi.ref_frame[1] == LAST_FRAME); + } + } else if (above_mi->mbmi.ref_frame[1] <= INTRA_FRAME && + left_mi->mbmi.ref_frame[1] <= INTRA_FRAME) { + pred_context = 2 * (above_mi->mbmi.ref_frame[0] == LAST_FRAME) + + 2 * (left_mi->mbmi.ref_frame[0] == LAST_FRAME); + } else if (above_mi->mbmi.ref_frame[1] > INTRA_FRAME && + left_mi->mbmi.ref_frame[1] > INTRA_FRAME) { + pred_context = 1 + (above_mi->mbmi.ref_frame[0] == LAST_FRAME || + above_mi->mbmi.ref_frame[1] == LAST_FRAME || + left_mi->mbmi.ref_frame[0] == LAST_FRAME || + left_mi->mbmi.ref_frame[1] == LAST_FRAME); + } else { + MV_REFERENCE_FRAME rfs = above_mi->mbmi.ref_frame[1] <= INTRA_FRAME ? + above_mi->mbmi.ref_frame[0] : left_mi->mbmi.ref_frame[0]; + MV_REFERENCE_FRAME crf1 = above_mi->mbmi.ref_frame[1] > INTRA_FRAME ? + above_mi->mbmi.ref_frame[0] : left_mi->mbmi.ref_frame[0]; + MV_REFERENCE_FRAME crf2 = above_mi->mbmi.ref_frame[1] > INTRA_FRAME ? + above_mi->mbmi.ref_frame[1] : left_mi->mbmi.ref_frame[1]; + + if (rfs == LAST_FRAME) { + pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME); + } else { + pred_context = crf1 == LAST_FRAME || crf2 == LAST_FRAME; + } + } + } else if (above_in_image || left_in_image) { // one edge available + const MODE_INFO *edge = above_in_image ? above_mi : left_mi; + + if (edge->mbmi.ref_frame[0] == INTRA_FRAME) { + pred_context = 2; + } else if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) { + pred_context = 4 * (edge->mbmi.ref_frame[0] == LAST_FRAME); + } else { + pred_context = 1 + (edge->mbmi.ref_frame[0] == LAST_FRAME || + edge->mbmi.ref_frame[1] == LAST_FRAME); + } + } else { // no edges available (2) + pred_context = 2; + } + assert(pred_context >= 0 && pred_context < REF_CONTEXTS); + break; + } + + case PRED_SINGLE_REF_P2: { + if (above_in_image && left_in_image) { // both edges available + if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME && + left_mi->mbmi.ref_frame[0] == INTRA_FRAME) { + pred_context = 2; + } else if (above_mi->mbmi.ref_frame[0] == INTRA_FRAME || + left_mi->mbmi.ref_frame[0] == INTRA_FRAME) { + const MODE_INFO *edge = above_mi->mbmi.ref_frame[0] == INTRA_FRAME ? + left_mi : above_mi; + + if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) { + if (edge->mbmi.ref_frame[0] == LAST_FRAME) { + pred_context = 3; + } else { + pred_context = 4 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME); + } + } else { + pred_context = 1 + 2 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME || + edge->mbmi.ref_frame[1] == GOLDEN_FRAME); + } + } else if (above_mi->mbmi.ref_frame[1] <= INTRA_FRAME && + left_mi->mbmi.ref_frame[1] <= INTRA_FRAME) { + if (above_mi->mbmi.ref_frame[0] == LAST_FRAME && + left_mi->mbmi.ref_frame[0] == LAST_FRAME) { + pred_context = 3; + } else if (above_mi->mbmi.ref_frame[0] == LAST_FRAME || + left_mi->mbmi.ref_frame[0] == LAST_FRAME) { + const MODE_INFO *edge = above_mi->mbmi.ref_frame[0] == LAST_FRAME ? + left_mi : above_mi; + + pred_context = 4 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME); + } else { + pred_context = 2 * (above_mi->mbmi.ref_frame[0] == GOLDEN_FRAME) + + 2 * (left_mi->mbmi.ref_frame[0] == GOLDEN_FRAME); + } + } else if (above_mi->mbmi.ref_frame[1] > INTRA_FRAME && + left_mi->mbmi.ref_frame[1] > INTRA_FRAME) { + if (above_mi->mbmi.ref_frame[0] == left_mi->mbmi.ref_frame[0] && + above_mi->mbmi.ref_frame[1] == left_mi->mbmi.ref_frame[1]) { + pred_context = 3 * (above_mi->mbmi.ref_frame[0] == GOLDEN_FRAME || + above_mi->mbmi.ref_frame[1] == GOLDEN_FRAME || + left_mi->mbmi.ref_frame[0] == GOLDEN_FRAME || + left_mi->mbmi.ref_frame[1] == GOLDEN_FRAME); + } else { + pred_context = 2; + } + } else { + MV_REFERENCE_FRAME rfs = above_mi->mbmi.ref_frame[1] <= INTRA_FRAME ? + above_mi->mbmi.ref_frame[0] : left_mi->mbmi.ref_frame[0]; + MV_REFERENCE_FRAME crf1 = above_mi->mbmi.ref_frame[1] > INTRA_FRAME ? + above_mi->mbmi.ref_frame[0] : left_mi->mbmi.ref_frame[0]; + MV_REFERENCE_FRAME crf2 = above_mi->mbmi.ref_frame[1] > INTRA_FRAME ? + above_mi->mbmi.ref_frame[1] : left_mi->mbmi.ref_frame[1]; + + if (rfs == GOLDEN_FRAME) { + pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME); + } else if (rfs == ALTREF_FRAME) { + pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME; + } else { + pred_context = + 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME); + } + } + } else if (above_in_image || left_in_image) { // one edge available + const MODE_INFO *edge = above_in_image ? above_mi : left_mi; + + if (edge->mbmi.ref_frame[0] == INTRA_FRAME || + (edge->mbmi.ref_frame[0] == LAST_FRAME && + edge->mbmi.ref_frame[1] <= INTRA_FRAME)) { + pred_context = 2; + } else if (edge->mbmi.ref_frame[1] <= INTRA_FRAME) { + pred_context = 4 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME); + } else { + pred_context = 3 * (edge->mbmi.ref_frame[0] == GOLDEN_FRAME || + edge->mbmi.ref_frame[1] == GOLDEN_FRAME); + } + } else { // no edges available (2) + pred_context = 2; + } + assert(pred_context >= 0 && pred_context < REF_CONTEXTS); + break; + } + default: + assert(0); pred_context = 0; // *** add error trap code. break; } @@ -106,16 +367,20 @@ vp9_prob vp9_get_pred_prob(const VP9_COMMON *const cm, switch (pred_id) { case PRED_SEG_ID: return cm->segment_pred_probs[pred_context]; - case PRED_REF: - return cm->ref_pred_probs[pred_context]; - case PRED_COMP: - // In keeping with convention elsewhre the probability returned is - // the probability of a "0" outcome which in this case means the - // probability of comp pred off. - return cm->prob_comppred[pred_context]; case PRED_MBSKIP: return cm->mbskip_pred_probs[pred_context]; + case PRED_INTRA_INTER: + return cm->fc.intra_inter_prob[pred_context]; + case PRED_COMP_INTER_INTER: + return cm->fc.comp_inter_prob[pred_context]; + case PRED_COMP_REF_P: + return cm->fc.comp_ref_prob[pred_context]; + case PRED_SINGLE_REF_P1: + return cm->fc.single_ref_prob[pred_context][0]; + case PRED_SINGLE_REF_P2: + return cm->fc.single_ref_prob[pred_context][1]; default: + assert(0); return 128; // *** add error trap code. } } @@ -128,20 +393,10 @@ const vp9_prob *vp9_get_pred_probs(const VP9_COMMON *const cm, const int pred_context = vp9_get_pred_context(cm, xd, pred_id); switch (pred_id) { - case PRED_SEG_ID: - return &cm->segment_pred_probs[pred_context]; - case PRED_REF: - return &cm->ref_pred_probs[pred_context]; - case PRED_COMP: - // In keeping with convention elsewhre the probability returned is - // the probability of a "0" outcome which in this case means the - // probability of comp pred off. - return &cm->prob_comppred[pred_context]; - case PRED_MBSKIP: - return &cm->mbskip_pred_probs[pred_context]; case PRED_SWITCHABLE_INTERP: return &cm->fc.switchable_interp_prob[pred_context][0]; default: + assert(0); return NULL; // *** add error trap code. } } @@ -153,11 +408,10 @@ unsigned char vp9_get_pred_flag(const MACROBLOCKD *const xd, switch (pred_id) { case PRED_SEG_ID: return xd->mode_info_context->mbmi.seg_id_predicted; - case PRED_REF: - return xd->mode_info_context->mbmi.ref_predicted; case PRED_MBSKIP: return xd->mode_info_context->mbmi.mb_skip_coeff; default: + assert(0); return 0; // *** add error trap code. } } @@ -186,14 +440,6 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd, } break; - case PRED_REF: - for (y = 0; y < y_mis; y++) { - for (x = 0; x < x_mis; x++) { - xd->mode_info_context[y * mis + x].mbmi.ref_predicted = pred_flag; - } - } - break; - case PRED_MBSKIP: for (y = 0; y < y_mis; y++) { for (x = 0; x < x_mis; x++) { @@ -203,6 +449,7 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd, break; default: + assert(0); // *** add error trap code. break; } @@ -231,138 +478,3 @@ int vp9_get_pred_mi_segid(VP9_COMMON *cm, BLOCK_SIZE_TYPE sb_type, } return segment_id; } - -MV_REFERENCE_FRAME vp9_get_pred_ref(const VP9_COMMON *const cm, - const MACROBLOCKD *const xd) { - MODE_INFO *m = xd->mode_info_context; - - MV_REFERENCE_FRAME left; - MV_REFERENCE_FRAME above; - MV_REFERENCE_FRAME above_left; - MV_REFERENCE_FRAME pred_ref = LAST_FRAME; - - int segment_id = xd->mode_info_context->mbmi.segment_id; - int i; - - unsigned char frame_allowed[MAX_REF_FRAMES] = {1, 1, 1, 1}; - unsigned char ref_score[MAX_REF_FRAMES]; - unsigned char best_score = 0; - unsigned char left_in_image; - unsigned char above_in_image; - unsigned char above_left_in_image; - - // Is segment coding ennabled - int seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME); - - // Special case treatment if segment coding is enabled. - // Dont allow prediction of a reference frame that the segment - // does not allow - if (seg_ref_active) { - for (i = 0; i < MAX_REF_FRAMES; i++) { - frame_allowed[i] = - vp9_check_segref(xd, segment_id, i); - - // Score set to 0 if ref frame not allowed - ref_score[i] = cm->ref_scores[i] * frame_allowed[i]; - } - } else - vpx_memcpy(ref_score, cm->ref_scores, sizeof(ref_score)); - - // Reference frames used by neighbours - left = (m - 1)->mbmi.ref_frame; - above = (m - cm->mode_info_stride)->mbmi.ref_frame; - above_left = (m - 1 - cm->mode_info_stride)->mbmi.ref_frame; - - // Are neighbours in image - left_in_image = (m - 1)->mbmi.mb_in_image && xd->left_available; - above_in_image = (m - cm->mode_info_stride)->mbmi.mb_in_image; - above_left_in_image = (m - 1 - cm->mode_info_stride)->mbmi.mb_in_image && - xd->left_available; - - // Adjust scores for candidate reference frames based on neigbours - if (frame_allowed[left] && left_in_image) { - ref_score[left] += 16; - if (above_left_in_image && (left == above_left)) - ref_score[left] += 4; - } - if (frame_allowed[above] && above_in_image) { - ref_score[above] += 16; - if (above_left_in_image && (above == above_left)) - ref_score[above] += 4; - } - - // Now choose the candidate with the highest score - for (i = 0; i < MAX_REF_FRAMES; i++) { - if (ref_score[i] > best_score) { - pred_ref = i; - best_score = ref_score[i]; - } - } - - return pred_ref; -} - -// Functions to computes a set of modified reference frame probabilities -// to use when the prediction of the reference frame value fails -void vp9_calc_ref_probs(int *count, vp9_prob *probs) { - int tot_count = count[0] + count[1] + count[2] + count[3]; - probs[0] = get_prob(count[0], tot_count); - - tot_count -= count[0]; - probs[1] = get_prob(count[1], tot_count); - - tot_count -= count[1]; - probs[2] = get_prob(count[2], tot_count); -} - -// Computes a set of modified conditional probabilities for the reference frame -// Values willbe set to 0 for reference frame options that are not possible -// because wither they were predicted and prediction has failed or because -// they are not allowed for a given segment. -void vp9_compute_mod_refprobs(VP9_COMMON *const cm) { - int norm_cnt[MAX_REF_FRAMES]; - const int intra_count = cm->prob_intra_coded; - const int inter_count = (255 - intra_count); - const int last_count = (inter_count * cm->prob_last_coded) / 255; - const int gfarf_count = inter_count - last_count; - const int gf_count = (gfarf_count * cm->prob_gf_coded) / 255; - const int arf_count = gfarf_count - gf_count; - - // Work out modified reference frame probabilities to use where prediction - // of the reference frame fails - norm_cnt[0] = 0; - norm_cnt[1] = last_count; - norm_cnt[2] = gf_count; - norm_cnt[3] = arf_count; - vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[INTRA_FRAME]); - cm->mod_refprobs[INTRA_FRAME][0] = 0; // This branch implicit - - norm_cnt[0] = intra_count; - norm_cnt[1] = 0; - norm_cnt[2] = gf_count; - norm_cnt[3] = arf_count; - vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[LAST_FRAME]); - cm->mod_refprobs[LAST_FRAME][1] = 0; // This branch implicit - - norm_cnt[0] = intra_count; - norm_cnt[1] = last_count; - norm_cnt[2] = 0; - norm_cnt[3] = arf_count; - vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[GOLDEN_FRAME]); - cm->mod_refprobs[GOLDEN_FRAME][2] = 0; // This branch implicit - - norm_cnt[0] = intra_count; - norm_cnt[1] = last_count; - norm_cnt[2] = gf_count; - norm_cnt[3] = 0; - vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[ALTREF_FRAME]); - cm->mod_refprobs[ALTREF_FRAME][2] = 0; // This branch implicit - - // Score the reference frames based on overal frequency. - // These scores contribute to the prediction choices. - // Max score 17 min 1 - cm->ref_scores[INTRA_FRAME] = 1 + (intra_count * 16 / 255); - cm->ref_scores[LAST_FRAME] = 1 + (last_count * 16 / 255); - cm->ref_scores[GOLDEN_FRAME] = 1 + (gf_count * 16 / 255); - cm->ref_scores[ALTREF_FRAME] = 1 + (arf_count * 16 / 255); -} diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h index afb0bfe..6d52997 100644 --- a/vp9/common/vp9_pred_common.h +++ b/vp9/common/vp9_pred_common.h @@ -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_ diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index 679cc7d..93faa8c 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -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); diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index c5ec820..69adb8c 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -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]); - } 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; - } - } + 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 { + 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); + 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]); + } - // Computes a modified set of probabilities for use when reference - // frame prediction fails. - vp9_compute_mod_refprobs(cm); + 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_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]); + } - 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); + 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); - vp9_mv_ref_probs(cm, mv_ref_p, mbmi->mb_mode_context[ref_frame]); + vp9_mv_ref_probs(cm, mv_ref_p, mbmi->mb_mode_context[mbmi->ref_frame[0]]); // If the segment level skip mode enabled if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) { mbmi->mode = ZEROMV; } else if (bsize >= BLOCK_SIZE_SB8X8) { mbmi->mode = read_sb_mv_ref(r, mv_ref_p); - vp9_accum_mv_refs(cm, mbmi->mode, mbmi->mb_mode_context[ref_frame]); + vp9_accum_mv_refs(cm, mbmi->mode, + mbmi->mb_mode_context[mbmi->ref_frame[0]]); } if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) { vp9_find_best_ref_mvs(xd, - mbmi->ref_mvs[ref_frame], + mbmi->ref_mvs[mbmi->ref_frame[0]], &nearest, &nearby); - best_mv.as_int = mbmi->ref_mvs[ref_frame][0].as_int; + best_mv.as_int = mbmi->ref_mvs[mbmi->ref_frame[0]][0].as_int; } #ifdef DEC_DEBUG @@ -618,33 +601,18 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, ? read_switchable_filter_type(pbi, r) : cm->mcomp_filter_type; - if (cm->comp_pred_mode == COMP_PREDICTION_ONLY || - (cm->comp_pred_mode == HYBRID_PREDICTION && - vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_COMP)))) { - /* Since we have 3 reference frames, we can only have 3 unique - * combinations of combinations of 2 different reference frames - * (A-G, G-L or A-L). In the bitstream, we use this to simply - * derive the second reference frame from the first reference - * frame, by saying it's the next one in the enumerator, and - * if that's > n_refs, then the second reference frame is the - * first one in the enumerator. */ - mbmi->second_ref_frame = mbmi->ref_frame + 1; - if (mbmi->second_ref_frame == 4) - mbmi->second_ref_frame = 1; - if (mbmi->second_ref_frame > 0) { - const MV_REFERENCE_FRAME second_ref_frame = mbmi->second_ref_frame; - - vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context, - second_ref_frame, mbmi->ref_mvs[second_ref_frame], - cm->ref_frame_sign_bias); - - if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) { - vp9_find_best_ref_mvs(xd, - mbmi->ref_mvs[second_ref_frame], - &nearest_second, - &nearby_second); - best_mv_second.as_int = mbmi->ref_mvs[second_ref_frame][0].as_int; - } + if (mbmi->ref_frame[1] > INTRA_FRAME) { + vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context, + mbmi->ref_frame[1], + mbmi->ref_mvs[mbmi->ref_frame[1]], + cm->ref_frame_sign_bias); + + if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) { + vp9_find_best_ref_mvs(xd, + mbmi->ref_mvs[mbmi->ref_frame[1]], + &nearest_second, + &nearby_second); + best_mv_second.as_int = mbmi->ref_mvs[mbmi->ref_frame[1]][0].as_int; } } @@ -659,9 +627,10 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, j = idy * 2 + idx; blockmode = read_sb_mv_ref(r, mv_ref_p); - vp9_accum_mv_refs(cm, blockmode, mbmi->mb_mode_context[ref_frame]); + vp9_accum_mv_refs(cm, blockmode, + mbmi->mb_mode_context[mbmi->ref_frame[0]]); if (blockmode == NEARESTMV || blockmode == NEARMV) { - MV_REFERENCE_FRAME rf2 = mbmi->second_ref_frame; + MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1]; vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest, &nearby, j, 0); if (rf2 > 0) { vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest_second, @@ -674,7 +643,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, decode_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc, &cm->fc.NMVcount, xd->allow_high_precision_mv); - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) decode_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc, &cm->fc.NMVcount, xd->allow_high_precision_mv); @@ -684,7 +653,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, break; case NEARESTMV: blockmv.as_int = nearest.as_int; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) secondmv.as_int = nearest_second.as_int; #ifdef VPX_MODE_COUNT vp9_mv_cont_count[mv_contz][0]++; @@ -692,7 +661,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, break; case NEARMV: blockmv.as_int = nearby.as_int; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) secondmv.as_int = nearby_second.as_int; #ifdef VPX_MODE_COUNT vp9_mv_cont_count[mv_contz][1]++; @@ -700,7 +669,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, break; case ZEROMV: blockmv.as_int = 0; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) secondmv.as_int = 0; #ifdef VPX_MODE_COUNT vp9_mv_cont_count[mv_contz][2]++; @@ -710,7 +679,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, break; } mi->bmi[j].as_mv[0].as_int = blockmv.as_int; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) mi->bmi[j].as_mv[1].as_int = secondmv.as_int; for (i = 1; i < bh; ++i) @@ -731,7 +700,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 > 0) + if (mbmi->ref_frame[1] > 0) assign_and_clamp_mv(mv1, &nearby_second, mb_to_left_edge, mb_to_right_edge, mb_to_top_edge, @@ -744,7 +713,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 > 0) + if (mbmi->ref_frame[1] > 0) assign_and_clamp_mv(mv1, &nearest_second, mb_to_left_edge, mb_to_right_edge, mb_to_top_edge, @@ -753,7 +722,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, case ZEROMV: mv0->as_int = 0; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) mv1->as_int = 0; break; @@ -766,7 +735,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 > 0) { + if (mbmi->ref_frame[1] > 0) { decode_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc, &cm->fc.NMVcount, xd->allow_high_precision_mv); mbmi->need_to_clamp_secondmv = check_mv_bounds(mv1, diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 31f6c79..0961ab7 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -281,7 +281,7 @@ static void decode_atom(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r, BLOCK_SIZE_TYPE bsize) { MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi; - assert(mbmi->ref_frame != INTRA_FRAME); + assert(mbmi->ref_frame[0] != INTRA_FRAME); if (pbi->common.frame_type != KEY_FRAME) vp9_setup_interp_filters(xd, mbmi->interp_filter, &pbi->common); @@ -334,7 +334,7 @@ static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col, const int mis = pc->mode_info_stride; assert(mbmi->sb_type == bsize); - assert(mbmi->ref_frame != INTRA_FRAME); + assert(mbmi->ref_frame[0] != INTRA_FRAME); if (pbi->common.frame_type != KEY_FRAME) vp9_setup_interp_filters(xd, mbmi->interp_filter, pc); @@ -401,22 +401,22 @@ static void set_refs(VP9D_COMP *pbi, int mi_row, int mi_col) { MACROBLOCKD *const xd = &pbi->mb; MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi; - if (mbmi->ref_frame > INTRA_FRAME) { + if (mbmi->ref_frame[0] > INTRA_FRAME) { // Select the appropriate reference frame for this MB - const int fb_idx = cm->active_ref_idx[mbmi->ref_frame - 1]; + const int fb_idx = cm->active_ref_idx[mbmi->ref_frame[0] - 1]; const YV12_BUFFER_CONFIG *cfg = &cm->yv12_fb[fb_idx]; - xd->scale_factor[0] = cm->active_ref_scale[mbmi->ref_frame - 1]; - xd->scale_factor_uv[0] = cm->active_ref_scale[mbmi->ref_frame - 1]; + xd->scale_factor[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1]; + xd->scale_factor_uv[0] = cm->active_ref_scale[mbmi->ref_frame[0] - 1]; setup_pre_planes(xd, cfg, NULL, mi_row, mi_col, xd->scale_factor, xd->scale_factor_uv); xd->corrupted |= cfg->corrupted; - if (mbmi->second_ref_frame > INTRA_FRAME) { + if (mbmi->ref_frame[1] > INTRA_FRAME) { // Select the appropriate reference frame for this MB - const int second_fb_idx = cm->active_ref_idx[mbmi->second_ref_frame - 1]; + const int second_fb_idx = cm->active_ref_idx[mbmi->ref_frame[1] - 1]; const YV12_BUFFER_CONFIG *second_cfg = &cm->yv12_fb[second_fb_idx]; - xd->scale_factor[1] = cm->active_ref_scale[mbmi->second_ref_frame - 1]; - xd->scale_factor_uv[1] = cm->active_ref_scale[mbmi->second_ref_frame - 1]; + xd->scale_factor[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1]; + xd->scale_factor_uv[1] = cm->active_ref_scale[mbmi->ref_frame[1] - 1]; setup_pre_planes(xd, NULL, second_cfg, mi_row, mi_col, xd->scale_factor, xd->scale_factor_uv); xd->corrupted |= second_cfg->corrupted; @@ -435,7 +435,7 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col, vp9_decode_mb_mode_mv(pbi, xd, mi_row, mi_col, r); set_refs(pbi, mi_row, mi_col); - if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) + if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) decode_sb_intra(pbi, xd, mi_row, mi_col, r, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); else if (bsize < BLOCK_SIZE_SB8X8) @@ -772,6 +772,10 @@ static void update_frame_context(FRAME_CONTEXT *fc) { vp9_copy(fc->pre_y_mode_prob, fc->y_mode_prob); vp9_copy(fc->pre_uv_mode_prob, fc->uv_mode_prob); vp9_copy(fc->pre_partition_prob, fc->partition_prob[1]); + vp9_copy(fc->pre_intra_inter_prob, fc->intra_inter_prob); + vp9_copy(fc->pre_comp_inter_prob, fc->comp_inter_prob); + vp9_copy(fc->pre_single_ref_prob, fc->single_ref_prob); + vp9_copy(fc->pre_comp_ref_prob, fc->comp_ref_prob); fc->pre_nmvc = fc->nmvc; vp9_copy(fc->pre_switchable_interp_prob, fc->switchable_interp_prob); vp9_copy(fc->pre_inter_mode_probs, fc->inter_mode_probs); @@ -784,6 +788,10 @@ static void update_frame_context(FRAME_CONTEXT *fc) { vp9_zero(fc->inter_mode_counts); vp9_zero(fc->partition_counts); vp9_zero(fc->switchable_interp_count); + vp9_zero(fc->intra_inter_count); + vp9_zero(fc->comp_inter_count); + vp9_zero(fc->single_ref_count); + vp9_zero(fc->comp_ref_count); } static void decode_tile(VP9D_COMP *pbi, vp9_reader *r) { @@ -942,10 +950,6 @@ size_t read_uncompressed_header(VP9D_COMP *pbi, for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) cm->active_ref_idx[i] = cm->new_fb_idx; - - cm->ref_pred_probs[0] = DEFAULT_PRED_PROB_0; - cm->ref_pred_probs[1] = DEFAULT_PRED_PROB_1; - cm->ref_pred_probs[2] = DEFAULT_PRED_PROB_2; } else { if (cm->error_resilient_mode) vp9_setup_past_independence(cm, xd); @@ -958,12 +962,31 @@ size_t read_uncompressed_header(VP9D_COMP *pbi, vp9_setup_scale_factors(cm, i); } - for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) + // Read the sign bias for each reference frame buffer. + cm->allow_comp_inter_inter = 0; + for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) { cm->ref_frame_sign_bias[i + 1] = vp9_rb_read_bit(rb); - - for (i = 0; i < PREDICTION_PROBS; ++i) - if (vp9_rb_read_bit(rb)) - cm->ref_pred_probs[i] = vp9_rb_read_literal(rb, 8); + cm->allow_comp_inter_inter |= i > 0 && + cm->ref_frame_sign_bias[i + 1] != cm->ref_frame_sign_bias[1]; + } + if (cm->allow_comp_inter_inter) { + // which one is always-on in comp inter-inter? + if (cm->ref_frame_sign_bias[LAST_FRAME] == + cm->ref_frame_sign_bias[GOLDEN_FRAME]) { + cm->comp_fixed_ref = ALTREF_FRAME; + cm->comp_var_ref[0] = LAST_FRAME; + cm->comp_var_ref[1] = GOLDEN_FRAME; + } else if (cm->ref_frame_sign_bias[LAST_FRAME] == + cm->ref_frame_sign_bias[ALTREF_FRAME]) { + cm->comp_fixed_ref = GOLDEN_FRAME; + cm->comp_var_ref[0] = LAST_FRAME; + cm->comp_var_ref[1] = ALTREF_FRAME; + } else { + cm->comp_fixed_ref = LAST_FRAME; + cm->comp_var_ref[0] = GOLDEN_FRAME; + cm->comp_var_ref[1] = ALTREF_FRAME; + } + } xd->allow_high_precision_mv = vp9_rb_read_bit(rb); cm->mcomp_filter_type = read_interp_filter_type(rb); diff --git a/vp9/decoder/vp9_detokenize.c b/vp9/decoder/vp9_detokenize.c index c91c4fc..655c358 100644 --- a/vp9/decoder/vp9_detokenize.c +++ b/vp9/decoder/vp9_detokenize.c @@ -111,7 +111,7 @@ static int decode_coefs(VP9D_COMP *dx, const MACROBLOCKD *xd, vp9_prob *prob; vp9_coeff_count_model *coef_counts; - const int ref = xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME; + const int ref = xd->mode_info_context->mbmi.ref_frame[0] != INTRA_FRAME; TX_TYPE tx_type = DCT_DCT; const int *scan, *nb; uint8_t token_cache[1024]; diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index 62b8547..844a1c1 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -343,41 +343,6 @@ void vp9_update_skip_probs(VP9_COMP *cpi) { cpi->skip_true_count[k]); } -// This function updates the reference frame prediction stats -static void update_refpred_stats(VP9_COMP *cpi) { - VP9_COMMON *const cm = &cpi->common; - int i; - vp9_prob new_pred_probs[PREDICTION_PROBS]; - int old_cost, new_cost; - - // Set the prediction probability structures to defaults - if (cm->frame_type != KEY_FRAME) { - // From the prediction counts set the probabilities for each context - for (i = 0; i < PREDICTION_PROBS; i++) { - const int c0 = cpi->ref_pred_count[i][0]; - const int c1 = cpi->ref_pred_count[i][1]; - - new_pred_probs[i] = get_binary_prob(c0, c1); - - // Decide whether or not to update the reference frame probs. - // Returned costs are in 1/256 bit units. - old_cost = c0 * vp9_cost_zero(cm->ref_pred_probs[i]) + - c1 * vp9_cost_one(cm->ref_pred_probs[i]); - - new_cost = c0 * vp9_cost_zero(new_pred_probs[i]) + - c1 * vp9_cost_one(new_pred_probs[i]); - - // Cost saving must be >= 8 bits (2048 in these units) - if ((old_cost - new_cost) >= 2048) { - cpi->ref_pred_probs_update[i] = 1; - cm->ref_pred_probs[i] = new_pred_probs[i]; - } else { - cpi->ref_pred_probs_update[i] = 0; - } - } - } -} - static void write_intra_mode(vp9_writer *bc, int m, const vp9_prob *p) { write_token(bc, vp9_intra_mode_tree, p, vp9_intra_mode_encodings + m); } @@ -510,16 +475,15 @@ static void write_mb_segid(vp9_writer *bc, } // This function encodes the reference frame -static void encode_ref_frame(vp9_writer *const bc, - VP9_COMMON *const cm, - MACROBLOCKD *xd, - int segment_id, - MV_REFERENCE_FRAME rf) { - int seg_ref_active; +static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) { + VP9_COMMON *const pc = &cpi->common; + MACROBLOCK *const x = &cpi->mb; + MACROBLOCKD *const xd = &x->e_mbd; + MB_MODE_INFO *mi = &xd->mode_info_context->mbmi; + const int segment_id = mi->segment_id; + int seg_ref_active = vp9_segfeature_active(xd, segment_id, + SEG_LVL_REF_FRAME); int seg_ref_count = 0; - seg_ref_active = vp9_segfeature_active(xd, - segment_id, - SEG_LVL_REF_FRAME); if (seg_ref_active) { seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME) + @@ -531,84 +495,35 @@ static void encode_ref_frame(vp9_writer *const bc, // If segment level coding of this signal is disabled... // or the segment allows multiple reference frame options if (!seg_ref_active || (seg_ref_count > 1)) { - // Values used in prediction model coding - unsigned char prediction_flag; - vp9_prob pred_prob; - MV_REFERENCE_FRAME pred_rf; - - // Get the context probability the prediction flag - pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF); - - // Get the predicted value. - pred_rf = vp9_get_pred_ref(cm, xd); - - // Did the chosen reference frame match its predicted value. - prediction_flag = - (xd->mode_info_context->mbmi.ref_frame == pred_rf); - - vp9_set_pred_flag(xd, PRED_REF, prediction_flag); - vp9_write(bc, prediction_flag, pred_prob); - - // If not predicted correctly then code value explicitly - if (!prediction_flag) { - vp9_prob mod_refprobs[PREDICTION_PROBS]; - - vpx_memcpy(mod_refprobs, - cm->mod_refprobs[pred_rf], 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] *= - vp9_check_segref(xd, segment_id, INTRA_FRAME); - mod_refprobs[LAST_FRAME] *= - vp9_check_segref(xd, segment_id, LAST_FRAME); - mod_refprobs[GOLDEN_FRAME] *= - (vp9_check_segref(xd, segment_id, GOLDEN_FRAME) * - vp9_check_segref(xd, segment_id, ALTREF_FRAME)); - } - - if (mod_refprobs[0]) { - vp9_write(bc, (rf != INTRA_FRAME), mod_refprobs[0]); - } - - // Inter coded - if (rf != INTRA_FRAME) { - if (mod_refprobs[1]) { - vp9_write(bc, (rf != LAST_FRAME), mod_refprobs[1]); - } + // does the feature use compound prediction or not + // (if not specified at the frame/segment level) + if (pc->comp_pred_mode == HYBRID_PREDICTION) { + vp9_write(bc, mi->ref_frame[1] > INTRA_FRAME, + vp9_get_pred_prob(pc, xd, PRED_COMP_INTER_INTER)); + } else { + assert((mi->ref_frame[1] <= INTRA_FRAME) == + (pc->comp_pred_mode == SINGLE_PREDICTION_ONLY)); + } - if (rf != LAST_FRAME) { - if (mod_refprobs[2]) { - vp9_write(bc, (rf != GOLDEN_FRAME), mod_refprobs[2]); - } - } - } + if (mi->ref_frame[1] > INTRA_FRAME) { + vp9_write(bc, mi->ref_frame[0] == GOLDEN_FRAME, + vp9_get_pred_prob(pc, xd, PRED_COMP_REF_P)); + } else { + vp9_write(bc, mi->ref_frame[0] != LAST_FRAME, + vp9_get_pred_prob(pc, xd, PRED_SINGLE_REF_P1)); + if (mi->ref_frame[0] != LAST_FRAME) + vp9_write(bc, mi->ref_frame[0] != GOLDEN_FRAME, + vp9_get_pred_prob(pc, xd, PRED_SINGLE_REF_P2)); } + } else { + assert(mi->ref_frame[1] <= INTRA_FRAME); + assert(vp9_check_segref(xd, segment_id, mi->ref_frame[0])); } // if using the prediction mdoel we have nothing further to do because // the reference frame is fully coded by the segment } -// Update the probabilities used to encode reference frame data -static void update_ref_probs(VP9_COMP *const cpi) { - VP9_COMMON *const cm = &cpi->common; - - const int *const rfct = cpi->count_mb_ref_frame_usage; - const int rf_intra = rfct[INTRA_FRAME]; - const int rf_inter = rfct[LAST_FRAME] + - rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]; - - cm->prob_intra_coded = get_binary_prob(rf_intra, rf_inter); - cm->prob_last_coded = get_prob(rfct[LAST_FRAME], rf_inter); - cm->prob_gf_coded = get_binary_prob(rfct[GOLDEN_FRAME], rfct[ALTREF_FRAME]); - - // Compute a modified set of probabilities to use when prediction of the - // reference frame fails - vp9_compute_mod_refprobs(cm); -} - static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_writer *bc, int mi_row, int mi_col) { VP9_COMMON *const pc = &cpi->common; @@ -616,7 +531,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mi = &m->mbmi; - const MV_REFERENCE_FRAME rf = mi->ref_frame; + const MV_REFERENCE_FRAME rf = mi->ref_frame[0]; const MB_PREDICTION_MODE mode = mi->mode; const int segment_id = mi->segment_id; int skip_coeff; @@ -654,8 +569,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_get_pred_prob(pc, xd, PRED_MBSKIP)); } - // Encode the reference frame. - encode_ref_frame(bc, pc, xd, segment_id, rf); + vp9_write(bc, rf != INTRA_FRAME, vp9_get_pred_prob(pc, xd, PRED_INTRA_INTER)); if (mi->sb_type >= BLOCK_SIZE_SB8X8 && pc->txfm_mode == TX_MODE_SELECT && !(rf != INTRA_FRAME && @@ -695,6 +609,8 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, } else { vp9_prob mv_ref_p[VP9_INTER_MODES - 1]; + encode_ref_frame(cpi, bc); + vp9_mv_ref_probs(&cpi->common, mv_ref_p, mi->mb_mode_context[rf]); #ifdef ENTROPY_STATS @@ -719,13 +635,6 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, assert(mi->interp_filter == cpi->common.mcomp_filter_type); } - // 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_get_pred_prob(pc, xd, PRED_COMP)); - } - if (xd->mode_info_context->mbmi.sb_type < BLOCK_SIZE_SB8X8) { int j; MB_PREDICTION_MODE blockmode; @@ -747,7 +656,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, vp9_encode_mv(bc, &blockmv.as_mv, &mi->best_mv.as_mv, nmvc, xd->allow_high_precision_mv); - if (mi->second_ref_frame > 0) + if (mi->ref_frame[1] > INTRA_FRAME) vp9_encode_mv(bc, &cpi->mb.partition_info->bmi[j].second_mv.as_mv, &mi->best_second_mv.as_mv, @@ -767,7 +676,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, MODE_INFO *m, &mi->mv[0].as_mv, &mi->best_mv.as_mv, nmvc, xd->allow_high_precision_mv); - if (mi->second_ref_frame > 0) + if (mi->ref_frame[1] > INTRA_FRAME) vp9_encode_mv(bc, &mi->mv[1].as_mv, &mi->best_second_mv.as_mv, nmvc, xd->allow_high_precision_mv); @@ -1175,25 +1084,6 @@ static void update_coef_probs(VP9_COMP* const cpi, vp9_writer* const bc) { update_coef_probs_common(bc, cpi, TX_32X32); } -static void segment_reference_frames(VP9_COMP *cpi) { - VP9_COMMON *oci = &cpi->common; - MODE_INFO *mi = oci->mi; - int ref[MAX_MB_SEGMENTS] = {0}; - int i, j; - int mb_index = 0; - MACROBLOCKD *const xd = &cpi->mb.e_mbd; - - for (i = 0; i < oci->mb_rows; i++) { - for (j = 0; j < oci->mb_cols; j++, mb_index++) - ref[mi[mb_index].mbmi.segment_id] |= (1 << mi[mb_index].mbmi.ref_frame); - mb_index++; - } - for (i = 0; i < MAX_MB_SEGMENTS; i++) { - vp9_enable_segfeature(xd, i, SEG_LVL_REF_FRAME); - vp9_set_segdata(xd, i, SEG_LVL_REF_FRAME, ref[i]); - } -} - static void encode_loopfilter(VP9_COMMON *pc, MACROBLOCKD *xd, struct vp9_write_bit_buffer *wb) { int i; @@ -1303,7 +1193,6 @@ static void encode_segmentation(VP9_COMP *cpi, // Segmentation data vp9_wb_write_bit(wb, xd->update_mb_segmentation_data); - // segment_reference_frames(cpi); if (xd->update_mb_segmentation_data) { vp9_wb_write_bit(wb, xd->mb_segment_abs_delta); @@ -1502,16 +1391,6 @@ void write_uncompressed_header(VP9_COMP *cpi, for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) vp9_wb_write_bit(wb, cm->ref_frame_sign_bias[LAST_FRAME + i]); - // Encode the common prediction model status flag probability updates for - // the reference frame - update_refpred_stats(cpi); - for (i = 0; i < PREDICTION_PROBS; i++) { - const int update = cpi->ref_pred_probs_update[i]; - vp9_wb_write_bit(wb, update); - if (update) - vp9_wb_write_literal(wb, cm->ref_pred_probs[i], 8); - } - // Signal whether to allow high MV precision vp9_wb_write_bit(wb, xd->allow_high_precision_mv); @@ -1576,6 +1455,11 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { pc->fc.pre_nmvc = pc->fc.nmvc; vp9_copy(pc->fc.pre_switchable_interp_prob, pc->fc.switchable_interp_prob); vp9_copy(pc->fc.pre_inter_mode_probs, pc->fc.inter_mode_probs); + vp9_copy(pc->fc.pre_intra_inter_prob, pc->fc.intra_inter_prob); + vp9_copy(pc->fc.pre_comp_inter_prob, pc->fc.comp_inter_prob); + vp9_copy(pc->fc.pre_comp_ref_prob, pc->fc.comp_ref_prob); + vp9_copy(pc->fc.pre_single_ref_prob, pc->fc.single_ref_prob); + cpi->common.fc.pre_nmvc = cpi->common.fc.nmvc; update_coef_probs(cpi, &header_bc); @@ -1588,7 +1472,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { vp9_write_prob(&header_bc, pc->mbskip_pred_probs[i]); if (pc->frame_type != KEY_FRAME) { - #ifdef ENTROPY_STATS active_section = 1; #endif @@ -1599,14 +1482,11 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { if (pc->mcomp_filter_type == SWITCHABLE) update_switchable_interp_probs(pc, &header_bc); - // Update the probabilities used to encode reference frame data - update_ref_probs(cpi); - - vp9_write_prob(&header_bc, pc->prob_intra_coded); - vp9_write_prob(&header_bc, pc->prob_last_coded); - vp9_write_prob(&header_bc, pc->prob_gf_coded); + for (i = 0; i < INTRA_INTER_CONTEXTS; i++) + vp9_cond_prob_diff_update(&header_bc, &pc->fc.intra_inter_prob[i], + VP9_DEF_UPDATE_PROB, cpi->intra_inter_count[i]); - { + if (pc->allow_comp_inter_inter) { const int comp_pred_mode = cpi->common.comp_pred_mode; const int use_compound_pred = (comp_pred_mode != SINGLE_PREDICTION_ONLY); const int use_hybrid_pred = (comp_pred_mode == HYBRID_PREDICTION); @@ -1615,14 +1495,32 @@ void vp9_pack_bitstream(VP9_COMP *cpi, uint8_t *dest, unsigned long *size) { if (use_compound_pred) { vp9_write_bit(&header_bc, use_hybrid_pred); if (use_hybrid_pred) { - for (i = 0; i < COMP_PRED_CONTEXTS; i++) { - pc->prob_comppred[i] = get_binary_prob(cpi->single_pred_count[i], - cpi->comp_pred_count[i]); - vp9_write_prob(&header_bc, pc->prob_comppred[i]); - } + for (i = 0; i < COMP_INTER_CONTEXTS; i++) + vp9_cond_prob_diff_update(&header_bc, &pc->fc.comp_inter_prob[i], + VP9_DEF_UPDATE_PROB, + cpi->comp_inter_count[i]); } } } + + if (pc->comp_pred_mode != COMP_PREDICTION_ONLY) { + for (i = 0; i < REF_CONTEXTS; i++) { + vp9_cond_prob_diff_update(&header_bc, &pc->fc.single_ref_prob[i][0], + VP9_DEF_UPDATE_PROB, + cpi->single_ref_count[i][0]); + vp9_cond_prob_diff_update(&header_bc, &pc->fc.single_ref_prob[i][1], + VP9_DEF_UPDATE_PROB, + cpi->single_ref_count[i][1]); + } + } + + if (pc->comp_pred_mode != SINGLE_PREDICTION_ONLY) { + for (i = 0; i < REF_CONTEXTS; i++) + vp9_cond_prob_diff_update(&header_bc, &pc->fc.comp_ref_prob[i], + VP9_DEF_UPDATE_PROB, + cpi->comp_ref_count[i]); + } + update_mbintra_mode_probs(cpi, &header_bc); for (i = 0; i < NUM_PARTITION_CONTEXTS; ++i) { diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 084e7b3..26ec57e 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -330,7 +330,6 @@ static void update_state(VP9_COMP *cpi, BLOCK_SIZE_TYPE bsize, int output_enabled) { int i, x_idx, y; - VP9_COMMON *const cm = &cpi->common; MACROBLOCK *const x = &cpi->mb; MACROBLOCKD *const xd = &x->e_mbd; MODE_INFO *mi = &ctx->mic; @@ -345,7 +344,8 @@ static void update_state(VP9_COMP *cpi, #if CONFIG_DEBUG assert(mb_mode < MB_MODE_COUNT); assert(mb_mode_index < MAX_MODES); - assert(mi->mbmi.ref_frame < MAX_REF_FRAMES); + assert(mi->mbmi.ref_frame[0] < MAX_REF_FRAMES); + assert(mi->mbmi.ref_frame[1] < MAX_REF_FRAMES); #endif assert(mi->mbmi.sb_type == bsize); @@ -366,7 +366,7 @@ static void update_state(VP9_COMP *cpi, ctx->txfm_rd_diff[ALLOW_32X32] = ctx->txfm_rd_diff[ALLOW_16X16]; } - if (mbmi->ref_frame != INTRA_FRAME && mbmi->sb_type < BLOCK_SIZE_SB8X8) { + if (mbmi->ref_frame[0] != INTRA_FRAME && mbmi->sb_type < BLOCK_SIZE_SB8X8) { *x->partition_info = ctx->partition_info; mbmi->mv[0].as_int = x->partition_info->bmi[3].mv.as_int; mbmi->mv[1].as_int = x->partition_info->bmi[3].second_mv.as_int; @@ -376,29 +376,9 @@ static void update_state(VP9_COMP *cpi, if (!output_enabled) return; - { - int segment_id = mbmi->segment_id, ref_pred_flag; - if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)) { - for (i = 0; i < NB_TXFM_MODES; i++) { - cpi->rd_tx_select_diff[i] += ctx->txfm_rd_diff[i]; - } - } - - // Did the chosen reference frame match its predicted value. - ref_pred_flag = ((xd->mode_info_context->mbmi.ref_frame == - vp9_get_pred_ref(cm, xd))); - vp9_set_pred_flag(xd, PRED_REF, ref_pred_flag); - if (!xd->segmentation_enabled || - !vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME) || - vp9_check_segref(xd, segment_id, INTRA_FRAME) + - vp9_check_segref(xd, segment_id, LAST_FRAME) + - vp9_check_segref(xd, segment_id, GOLDEN_FRAME) + - vp9_check_segref(xd, segment_id, ALTREF_FRAME) > 1) { - // Get the prediction context and status - int pred_context = vp9_get_pred_context(cm, xd, PRED_REF); - - // Count prediction success - cpi->ref_pred_count[pred_context][ref_pred_flag]++; + if (!vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) { + for (i = 0; i < NB_TXFM_MODES; i++) { + cpi->rd_tx_select_diff[i] += ctx->txfm_rd_diff[i]; } } @@ -448,15 +428,16 @@ static void update_state(VP9_COMP *cpi, */ // Note how often each mode chosen as best cpi->mode_chosen_counts[mb_mode_index]++; - if (mbmi->ref_frame != INTRA_FRAME && + if (mbmi->ref_frame[0] != INTRA_FRAME && (mbmi->sb_type < BLOCK_SIZE_SB8X8 || mbmi->mode == NEWMV)) { int_mv best_mv, best_second_mv; - MV_REFERENCE_FRAME rf = mbmi->ref_frame; + const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0]; + const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1]; best_mv.as_int = ctx->best_ref_mv.as_int; best_second_mv.as_int = ctx->second_best_ref_mv.as_int; if (mbmi->mode == NEWMV) { - best_mv.as_int = mbmi->ref_mvs[rf][0].as_int; - best_second_mv.as_int = mbmi->ref_mvs[mbmi->second_ref_frame][0].as_int; + best_mv.as_int = mbmi->ref_mvs[rf1][0].as_int; + best_second_mv.as_int = mbmi->ref_mvs[rf2][0].as_int; } mbmi->best_mv.as_int = best_mv.as_int; mbmi->best_second_mv.as_int = best_second_mv.as_int; @@ -654,14 +635,8 @@ static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) { if (cm->frame_type != KEY_FRAME) { int segment_id, seg_ref_active; - if (mbmi->ref_frame) { - int pred_context = vp9_get_pred_context(cm, xd, PRED_COMP); - - if (mbmi->second_ref_frame <= INTRA_FRAME) - cpi->single_pred_count[pred_context]++; - else - cpi->comp_pred_count[pred_context]++; - } + cpi->intra_inter_count[vp9_get_pred_context(cm, xd, PRED_INTRA_INTER)] + [mbmi->ref_frame[0] > INTRA_FRAME]++; // If we have just a single reference frame coded for a segment then // exclude from the reference frame counts used to work out @@ -671,15 +646,31 @@ static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) { segment_id = mbmi->segment_id; seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME); - if (!seg_ref_active || - ((vp9_check_segref(xd, segment_id, INTRA_FRAME) + - vp9_check_segref(xd, segment_id, LAST_FRAME) + - vp9_check_segref(xd, segment_id, GOLDEN_FRAME) + - vp9_check_segref(xd, segment_id, ALTREF_FRAME)) > 1)) { - cpi->count_mb_ref_frame_usage[mbmi->ref_frame]++; + if (mbmi->ref_frame[0] > INTRA_FRAME && + (!seg_ref_active || + ((vp9_check_segref(xd, segment_id, INTRA_FRAME) + + vp9_check_segref(xd, segment_id, LAST_FRAME) + + vp9_check_segref(xd, segment_id, GOLDEN_FRAME) + + vp9_check_segref(xd, segment_id, ALTREF_FRAME)) > 1))) { + if (cm->comp_pred_mode == HYBRID_PREDICTION) + cpi->comp_inter_count[vp9_get_pred_context(cm, xd, + PRED_COMP_INTER_INTER)] + [mbmi->ref_frame[1] > INTRA_FRAME]++; + + if (mbmi->ref_frame[1] > INTRA_FRAME) { + cpi->comp_ref_count[vp9_get_pred_context(cm, xd, PRED_COMP_REF_P)] + [mbmi->ref_frame[0] == GOLDEN_FRAME]++; + } else { + cpi->single_ref_count[vp9_get_pred_context(cm, xd, PRED_SINGLE_REF_P1)] + [0][mbmi->ref_frame[0] != LAST_FRAME]++; + if (mbmi->ref_frame[0] != LAST_FRAME) + cpi->single_ref_count[vp9_get_pred_context(cm, xd, + PRED_SINGLE_REF_P2)] + [1][mbmi->ref_frame[0] != GOLDEN_FRAME]++; + } } // Count of last ref frame 0,0 usage - if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame == LAST_FRAME)) + if ((mbmi->mode == ZEROMV) && (mbmi->ref_frame[0] == LAST_FRAME)) cpi->inter_zz_count++; } } @@ -1445,7 +1436,6 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) { x->act_zbin_adj = 0; cpi->seg0_idx = 0; - vpx_memset(cpi->ref_pred_count, 0, sizeof(cpi->ref_pred_count)); xd->mode_info_stride = cm->mode_info_stride; xd->frame_type = cm->frame_type; @@ -1472,11 +1462,14 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) { xd->mode_info_context->mbmi.mode = DC_PRED; xd->mode_info_context->mbmi.uv_mode = DC_PRED; - vp9_zero(cpi->count_mb_ref_frame_usage) vp9_zero(cpi->y_mode_count) vp9_zero(cpi->y_uv_mode_count) vp9_zero(cpi->common.fc.inter_mode_counts) vp9_zero(cpi->partition_count); + vp9_zero(cpi->intra_inter_count); + vp9_zero(cpi->comp_inter_count); + vp9_zero(cpi->single_ref_count); + vp9_zero(cpi->comp_ref_count); // Note: this memset assumes above_context[0], [1] and [2] // are allocated as part of the same buffer. @@ -1516,11 +1509,6 @@ static void encode_frame_internal(VP9_COMP *cpi) { // cpi->common.current_video_frame, cpi->common.show_frame, // cm->frame_type); - // Compute a modified set of reference frame probabilities to use when - // prediction fails. These are based on the current general estimates for - // this frame which may be updated with each iteration of the recode loop. - vp9_compute_mod_refprobs(cm); - // debug output #if DBG_PRNT_SEGMAP { @@ -1572,8 +1560,6 @@ static void encode_frame_internal(VP9_COMP *cpi) { init_encode_frame_mb_context(cpi); vpx_memset(cpi->rd_comp_pred_diff, 0, sizeof(cpi->rd_comp_pred_diff)); - vpx_memset(cpi->single_pred_count, 0, sizeof(cpi->single_pred_count)); - vpx_memset(cpi->comp_pred_count, 0, sizeof(cpi->comp_pred_count)); vpx_memset(cpi->txfm_count_32x32p, 0, sizeof(cpi->txfm_count_32x32p)); vpx_memset(cpi->txfm_count_16x16p, 0, sizeof(cpi->txfm_count_16x16p)); vpx_memset(cpi->txfm_count_8x8p, 0, sizeof(cpi->txfm_count_8x8p)); @@ -1764,6 +1750,20 @@ static void reset_skip_txfm_size(VP9_COMP *cpi, TX_SIZE txfm_max) { } void vp9_encode_frame(VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + + if (cm->ref_frame_sign_bias[LAST_FRAME] == + cm->ref_frame_sign_bias[GOLDEN_FRAME] && + cm->ref_frame_sign_bias[LAST_FRAME] == + cm->ref_frame_sign_bias[ALTREF_FRAME]) { + cm->allow_comp_inter_inter = 0; + } else { + cm->allow_comp_inter_inter = 1; + cm->comp_fixed_ref = ALTREF_FRAME; + cm->comp_var_ref[0] = LAST_FRAME; + cm->comp_var_ref[1] = GOLDEN_FRAME; + } + if (cpi->sf.RD) { int i, frame_type, pred_type; TXFM_MODE txfm_type; @@ -1787,7 +1787,7 @@ void vp9_encode_frame(VP9_COMP *cpi) { frame_type = 2; /* prediction (compound, single or hybrid) mode selection */ - if (frame_type == 3) + if (frame_type == 3 || !cm->allow_comp_inter_inter) pred_type = SINGLE_PREDICTION_ONLY; else if (cpi->rd_prediction_type_threshes[frame_type][1] > cpi->rd_prediction_type_threshes[frame_type][0] && @@ -1870,15 +1870,17 @@ void vp9_encode_frame(VP9_COMP *cpi) { int single_count_zero = 0; int comp_count_zero = 0; - for (i = 0; i < COMP_PRED_CONTEXTS; i++) { - single_count_zero += cpi->single_pred_count[i]; - comp_count_zero += cpi->comp_pred_count[i]; + for (i = 0; i < COMP_INTER_CONTEXTS; i++) { + single_count_zero += cpi->comp_inter_count[i][0]; + comp_count_zero += cpi->comp_inter_count[i][1]; } if (comp_count_zero == 0) { cpi->common.comp_pred_mode = SINGLE_PREDICTION_ONLY; + vp9_zero(cpi->comp_inter_count); } else if (single_count_zero == 0) { cpi->common.comp_pred_mode = COMP_PREDICTION_ONLY; + vp9_zero(cpi->comp_inter_count); } } @@ -1997,9 +1999,9 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, // Increase zbin size to suppress noise cpi->zbin_mode_boost = 0; if (cpi->zbin_mode_boost_enabled) { - if (mbmi->ref_frame != INTRA_FRAME) { + if (mbmi->ref_frame[0] != INTRA_FRAME) { if (mbmi->mode == ZEROMV) { - if (mbmi->ref_frame != LAST_FRAME) + if (mbmi->ref_frame[0] != LAST_FRAME) cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST; else cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST; @@ -2016,7 +2018,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, vp9_update_zbin_extra(cpi, x); } - if (mbmi->ref_frame == INTRA_FRAME) { + if (mbmi->ref_frame[0] == INTRA_FRAME) { vp9_encode_intra_block_y(cm, x, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); vp9_encode_intra_block_uv(cm, x, (bsize < BLOCK_SIZE_SB8X8) ? @@ -2024,11 +2026,11 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, if (output_enabled) sum_intra_stats(cpi, x); } else { - int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame)]; + int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame[0])]; YV12_BUFFER_CONFIG *ref_fb = &cm->yv12_fb[idx]; YV12_BUFFER_CONFIG *second_ref_fb = NULL; - if (mbmi->second_ref_frame > 0) { - idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->second_ref_frame)]; + if (mbmi->ref_frame[1] > 0) { + idx = cm->ref_frame_map[get_ref_frame_idx(cpi, mbmi->ref_frame[1])]; second_ref_fb = &cm->yv12_fb[idx]; } @@ -2042,7 +2044,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, : bsize); } - if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) { + if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) { vp9_tokenize_sb(cpi, xd, t, !output_enabled, (bsize < BLOCK_SIZE_SB8X8) ? BLOCK_SIZE_SB8X8 : bsize); } else if (!x->skip) { @@ -2072,7 +2074,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, if (output_enabled) { if (cm->txfm_mode == TX_MODE_SELECT && mbmi->sb_type >= BLOCK_SIZE_SB8X8 && - !(mbmi->ref_frame != INTRA_FRAME && (mbmi->mb_skip_coeff || + !(mbmi->ref_frame[0] != INTRA_FRAME && (mbmi->mb_skip_coeff || vp9_segfeature_active(xd, segment_id, SEG_LVL_SKIP)))) { if (bsize >= BLOCK_SIZE_SB32X32) { cpi->txfm_count_32x32p[mbmi->txfm_size]++; @@ -2085,7 +2087,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int x, y; TX_SIZE sz = (cm->txfm_mode == TX_MODE_SELECT) ? TX_32X32 : cm->txfm_mode; // The new intra coding scheme requires no change of transform size - if (mi->mbmi.ref_frame != INTRA_FRAME) { + if (mi->mbmi.ref_frame[0] != INTRA_FRAME) { if (sz == TX_32X32 && bsize < BLOCK_SIZE_SB32X32) sz = TX_16X16; if (sz == TX_16X16 && bsize < BLOCK_SIZE_MB16X16) diff --git a/vp9/encoder/vp9_encodeintra.c b/vp9/encoder/vp9_encodeintra.c index 57041a9..c78882a 100644 --- a/vp9/encoder/vp9_encodeintra.c +++ b/vp9/encoder/vp9_encodeintra.c @@ -20,7 +20,7 @@ int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) { MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi; (void) cpi; mbmi->mode = DC_PRED; - mbmi->ref_frame = INTRA_FRAME; + mbmi->ref_frame[0] = INTRA_FRAME; if (use_16x16_pred) { mbmi->txfm_size = TX_16X16; vp9_encode_intra_block_y(&cpi->common, x, BLOCK_SIZE_MB16X16); diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c index b65b261..aa9cf8d 100644 --- a/vp9/encoder/vp9_encodemb.c +++ b/vp9/encoder/vp9_encodemb.c @@ -118,7 +118,7 @@ static void optimize_b(VP9_COMMON *const cm, MACROBLOCK *mb, int plane, int block, BLOCK_SIZE_TYPE bsize, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, TX_SIZE tx_size) { - const int ref = mb->e_mbd.mode_info_context->mbmi.ref_frame != INTRA_FRAME; + const int ref = mb->e_mbd.mode_info_context->mbmi.ref_frame[0] != INTRA_FRAME; MACROBLOCKD *const xd = &mb->e_mbd; vp9_token_state tokens[1025][2]; unsigned best_index[1025][2]; @@ -179,7 +179,7 @@ static void optimize_b(VP9_COMMON *const cm, MACROBLOCK *mb, /* Now set up a Viterbi trellis to evaluate alternative roundings. */ rdmult = mb->rdmult * err_mult; - if (mb->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) + if (mb->e_mbd.mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) rdmult = (rdmult * 9) >> 4; rddiv = mb->rddiv; memset(best_index, 0, sizeof(best_index)); @@ -622,7 +622,7 @@ static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize, mode = plane == 0? mbmi->mode: mbmi->uv_mode; if (plane == 0 && mbmi->sb_type < BLOCK_SIZE_SB8X8 && - mbmi->ref_frame == INTRA_FRAME) + mbmi->ref_frame[0] == INTRA_FRAME) b_mode = xd->mode_info_context->bmi[ib].as_mode.first; else b_mode = mode; diff --git a/vp9/encoder/vp9_encodemv.c b/vp9/encoder/vp9_encodemv.c index 2b6dfba..a582d18 100644 --- a/vp9/encoder/vp9_encodemv.c +++ b/vp9/encoder/vp9_encodemv.c @@ -584,7 +584,7 @@ void vp9_update_nmv_count(VP9_COMP *cpi, MACROBLOCK *x, mv.col = (pi->bmi[i].mv.as_mv.col - best_ref_mv->as_mv.col); vp9_increment_nmv(&mv, &best_ref_mv->as_mv, &cpi->NMVcount, x->e_mbd.allow_high_precision_mv); - if (x->e_mbd.mode_info_context->mbmi.second_ref_frame > 0) { + if (x->e_mbd.mode_info_context->mbmi.ref_frame[1] > INTRA_FRAME) { mv.row = pi->bmi[i].second_mv.as_mv.row - second_best_ref_mv->as_mv.row; mv.col = pi->bmi[i].second_mv.as_mv.col - @@ -600,7 +600,7 @@ void vp9_update_nmv_count(VP9_COMP *cpi, MACROBLOCK *x, 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, x->e_mbd.allow_high_precision_mv); - if (mbmi->second_ref_frame > 0) { + if (mbmi->ref_frame[1] > INTRA_FRAME) { 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, diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index b07e37d..001129d 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -523,7 +523,7 @@ void vp9_first_pass(VP9_COMP *cpi) { xd->left_available = (mb_col != 0); xd->mode_info_context->mbmi.sb_type = BLOCK_SIZE_MB16X16; - xd->mode_info_context->mbmi.ref_frame = INTRA_FRAME; + xd->mode_info_context->mbmi.ref_frame[0] = INTRA_FRAME; // do intra 16x16 prediction this_error = vp9_encode_intra(cpi, x, use_dc_pred); @@ -620,7 +620,8 @@ void vp9_first_pass(VP9_COMP *cpi) { this_error = motion_error; vp9_set_mbmode_and_mvs(x, NEWMV, &mv); xd->mode_info_context->mbmi.txfm_size = TX_4X4; - xd->mode_info_context->mbmi.ref_frame = LAST_FRAME; + xd->mode_info_context->mbmi.ref_frame[0] = LAST_FRAME; + xd->mode_info_context->mbmi.ref_frame[1] = NONE; vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, BLOCK_SIZE_MB16X16); diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index a0e7b37..4ca5ef3 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -623,25 +623,20 @@ static void set_rd_speed_thresholds(VP9_COMP *cpi, int mode, int speed) { sf->thresh_mult[THR_SPLITG ] += speed_multiplier * 2500; sf->thresh_mult[THR_SPLITA ] += speed_multiplier * 2500; - sf->thresh_mult[THR_COMP_ZEROLG ] += speed_multiplier * 1500; sf->thresh_mult[THR_COMP_ZEROLA ] += speed_multiplier * 1500; sf->thresh_mult[THR_COMP_ZEROGA ] += speed_multiplier * 1500; - sf->thresh_mult[THR_COMP_NEARESTLG] += speed_multiplier * 1500; sf->thresh_mult[THR_COMP_NEARESTLA] += speed_multiplier * 1500; sf->thresh_mult[THR_COMP_NEARESTGA] += speed_multiplier * 1500; - sf->thresh_mult[THR_COMP_NEARLG ] += speed_multiplier * 1500; sf->thresh_mult[THR_COMP_NEARLA ] += speed_multiplier * 1500; sf->thresh_mult[THR_COMP_NEARGA ] += speed_multiplier * 1500; - sf->thresh_mult[THR_COMP_NEWLG ] += speed_multiplier * 2000; sf->thresh_mult[THR_COMP_NEWLA ] += speed_multiplier * 2000; sf->thresh_mult[THR_COMP_NEWGA ] += speed_multiplier * 2000; sf->thresh_mult[THR_COMP_SPLITLA ] += speed_multiplier * 4500; sf->thresh_mult[THR_COMP_SPLITGA ] += speed_multiplier * 4500; - sf->thresh_mult[THR_COMP_SPLITLG ] += speed_multiplier * 4500; if (speed > 4) { for (i = 0; i < MAX_MODES; ++i) @@ -685,14 +680,6 @@ static void set_rd_speed_thresholds(VP9_COMP *cpi, int mode, int speed) { sf->thresh_mult[THR_SPLITA ] = INT_MAX; } - if ((cpi->ref_frame_flags & (VP9_LAST_FLAG | VP9_GOLD_FLAG)) != - (VP9_LAST_FLAG | VP9_GOLD_FLAG)) { - sf->thresh_mult[THR_COMP_ZEROLG ] = INT_MAX; - sf->thresh_mult[THR_COMP_NEARESTLG] = INT_MAX; - sf->thresh_mult[THR_COMP_NEARLG ] = INT_MAX; - sf->thresh_mult[THR_COMP_NEWLG ] = INT_MAX; - sf->thresh_mult[THR_COMP_SPLITLG ] = INT_MAX; - } if ((cpi->ref_frame_flags & (VP9_LAST_FLAG | VP9_ALT_FLAG)) != (VP9_LAST_FLAG | VP9_ALT_FLAG)) { sf->thresh_mult[THR_COMP_ZEROLA ] = INT_MAX; @@ -1311,21 +1298,9 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) { cpi->frames_till_gf_update_due = 0; cpi->gf_overspend_bits = 0; cpi->non_gf_bitrate_adjustment = 0; - cm->prob_last_coded = 128; - cm->prob_gf_coded = 128; - cm->prob_intra_coded = 63; - for (i = 0; i < COMP_PRED_CONTEXTS; i++) - cm->prob_comppred[i] = 128; for (i = 0; i < TX_SIZE_MAX_SB - 1; i++) cm->prob_tx[i] = 128; - // Prime the recent reference frame usage counters. - // Hereafter they will be maintained as a sort of moving average - cpi->recent_ref_frame_usage[INTRA_FRAME] = 1; - cpi->recent_ref_frame_usage[LAST_FRAME] = 1; - cpi->recent_ref_frame_usage[GOLDEN_FRAME] = 1; - cpi->recent_ref_frame_usage[ALTREF_FRAME] = 1; - // Set reference frame sign bias for ALTREF frame to 1 (for now) cpi->common.ref_frame_sign_bias[ALTREF_FRAME] = 1; @@ -2083,22 +2058,6 @@ static void update_golden_frame_stats(VP9_COMP *cpi) { cpi->refresh_golden_frame = 0; cpi->common.frames_since_golden = 0; - // if ( cm->frame_type == KEY_FRAME ) - // { - cpi->recent_ref_frame_usage[INTRA_FRAME] = 1; - cpi->recent_ref_frame_usage[LAST_FRAME] = 1; - cpi->recent_ref_frame_usage[GOLDEN_FRAME] = 1; - cpi->recent_ref_frame_usage[ALTREF_FRAME] = 1; - // } - // else - // { - // // Carry a portion of count over to beginning of next gf sequence - // cpi->recent_ref_frame_usage[INTRA_FRAME] >>= 5; - // cpi->recent_ref_frame_usage[LAST_FRAME] >>= 5; - // cpi->recent_ref_frame_usage[GOLDEN_FRAME] >>= 5; - // cpi->recent_ref_frame_usage[ALTREF_FRAME] >>= 5; - // } - // ******** Fixed Q test code only ************ // If we are going to use the ALT reference for the next group of frames set a flag to say so. if (cpi->oxcf.fixed_q >= 0 && @@ -2123,13 +2082,6 @@ static void update_golden_frame_stats(VP9_COMP *cpi) { cpi->common.frames_till_alt_ref_frame--; cpi->common.frames_since_golden++; - - if (cpi->common.frames_since_golden > 1) { - cpi->recent_ref_frame_usage[INTRA_FRAME] += cpi->count_mb_ref_frame_usage[INTRA_FRAME]; - cpi->recent_ref_frame_usage[LAST_FRAME] += cpi->count_mb_ref_frame_usage[LAST_FRAME]; - cpi->recent_ref_frame_usage[GOLDEN_FRAME] += cpi->count_mb_ref_frame_usage[GOLDEN_FRAME]; - cpi->recent_ref_frame_usage[ALTREF_FRAME] += cpi->count_mb_ref_frame_usage[ALTREF_FRAME]; - } } } @@ -3113,6 +3065,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, vp9_copy(cpi->common.fc.y_mode_counts, cpi->y_mode_count); vp9_copy(cpi->common.fc.uv_mode_counts, cpi->y_uv_mode_count); vp9_copy(cpi->common.fc.partition_counts, cpi->partition_count); + vp9_copy(cm->fc.intra_inter_count, cpi->intra_inter_count); + vp9_copy(cm->fc.comp_inter_count, cpi->comp_inter_count); + vp9_copy(cm->fc.single_ref_count, cpi->single_ref_count); + vp9_copy(cm->fc.comp_ref_count, cpi->comp_ref_count); cpi->common.fc.NMVcount = cpi->NMVcount; if (!cpi->common.error_resilient_mode && !cpi->common.frame_parallel_decoding_mode) { diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 1f102e8..79a57ee 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -47,7 +47,7 @@ #define KEY_FRAME_CONTEXT 5 -#define MAX_MODES 41 +#define MAX_MODES 36 #define MIN_THRESHMULT 32 #define MAX_THRESHMULT 512 @@ -65,9 +65,10 @@ typedef struct { int nmvcosts_hp[2][MV_VALS]; vp9_prob segment_pred_probs[PREDICTION_PROBS]; - unsigned char ref_pred_probs_update[PREDICTION_PROBS]; - vp9_prob ref_pred_probs[PREDICTION_PROBS]; - vp9_prob prob_comppred[COMP_PRED_CONTEXTS]; + 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]; unsigned char *last_frame_seg_map_copy; @@ -174,10 +175,6 @@ typedef enum { THR_B_PRED, - THR_COMP_ZEROLG, - THR_COMP_NEARESTLG, - THR_COMP_NEARLG, - THR_COMP_ZEROLA, THR_COMP_NEARESTLA, THR_COMP_NEARLA, @@ -186,11 +183,9 @@ typedef enum { THR_COMP_NEARESTGA, THR_COMP_NEARGA, - THR_COMP_NEWLG, THR_COMP_NEWLA, THR_COMP_NEWGA, - THR_COMP_SPLITLG, THR_COMP_SPLITLA, THR_COMP_SPLITGA, } THR_MODES; @@ -325,8 +320,11 @@ typedef struct VP9_COMP { int64_t rd_comp_pred_diff[NB_PREDICTION_TYPES]; int rd_prediction_type_threshes[4][NB_PREDICTION_TYPES]; - int comp_pred_count[COMP_PRED_CONTEXTS]; - int single_pred_count[COMP_PRED_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]; + // FIXME contextualize int txfm_count_32x32p[TX_SIZE_MAX_SB]; int txfm_count_16x16p[TX_SIZE_MAX_SB - 1]; @@ -433,7 +431,6 @@ typedef struct VP9_COMP { int mbgraph_n_frames; // number of frames filled in the above int static_mb_pct; // % forced skip mbs by segmentation int seg0_progress, seg0_idx, seg0_cnt; - int ref_pred_count[3][2]; int decimation_factor; int decimation_count; @@ -454,12 +451,8 @@ typedef struct VP9_COMP { vp9_prob last_skip_false_probs[3][MBSKIP_CONTEXTS]; int last_skip_probs_q[3]; - int recent_ref_frame_usage[MAX_REF_FRAMES]; - int count_mb_ref_frame_usage[MAX_REF_FRAMES]; int ref_frame_flags; - unsigned char ref_pred_probs_update[PREDICTION_PROBS]; - SPEED_FEATURES sf; int error_bins[1024]; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 82f0306..9515ea4 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -129,9 +129,11 @@ void vp9_save_coding_context(VP9_COMP *cpi) { vp9_copy(cc->partition_prob, cm->fc.partition_prob); vp9_copy(cc->segment_pred_probs, cm->segment_pred_probs); - vp9_copy(cc->ref_pred_probs_update, cpi->ref_pred_probs_update); - vp9_copy(cc->ref_pred_probs, cm->ref_pred_probs); - vp9_copy(cc->prob_comppred, cm->prob_comppred); + + vp9_copy(cc->intra_inter_prob, cm->fc.intra_inter_prob); + vp9_copy(cc->comp_inter_prob, cm->fc.comp_inter_prob); + vp9_copy(cc->single_ref_prob, cm->fc.single_ref_prob); + vp9_copy(cc->comp_ref_prob, cm->fc.comp_ref_prob); vpx_memcpy(cpi->coding_context.last_frame_seg_map_copy, cm->last_frame_seg_map, (cm->mi_rows * cm->mi_cols)); @@ -163,9 +165,11 @@ void vp9_restore_coding_context(VP9_COMP *cpi) { vp9_copy(cm->fc.partition_prob, cc->partition_prob); vp9_copy(cm->segment_pred_probs, cc->segment_pred_probs); - vp9_copy(cpi->ref_pred_probs_update, cc->ref_pred_probs_update); - vp9_copy(cm->ref_pred_probs, cc->ref_pred_probs); - vp9_copy(cm->prob_comppred, cc->prob_comppred); + + vp9_copy(cm->fc.intra_inter_prob, cc->intra_inter_prob); + vp9_copy(cm->fc.comp_inter_prob, cc->comp_inter_prob); + vp9_copy(cm->fc.single_ref_prob, cc->single_ref_prob); + vp9_copy(cm->fc.comp_ref_prob, cc->comp_ref_prob); vpx_memcpy(cm->last_frame_seg_map, cpi->coding_context.last_frame_seg_map_copy, diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index f785c32..8eedfc1 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -90,24 +90,18 @@ const MODE_DEFINITION vp9_mode_order[MAX_MODES] = { {I4X4_PRED, INTRA_FRAME, NONE}, /* compound prediction modes */ - {ZEROMV, LAST_FRAME, GOLDEN_FRAME}, - {NEARESTMV, LAST_FRAME, GOLDEN_FRAME}, - {NEARMV, LAST_FRAME, GOLDEN_FRAME}, - - {ZEROMV, ALTREF_FRAME, LAST_FRAME}, - {NEARESTMV, ALTREF_FRAME, LAST_FRAME}, - {NEARMV, ALTREF_FRAME, LAST_FRAME}, + {ZEROMV, LAST_FRAME, ALTREF_FRAME}, + {NEARESTMV, LAST_FRAME, ALTREF_FRAME}, + {NEARMV, LAST_FRAME, ALTREF_FRAME}, {ZEROMV, GOLDEN_FRAME, ALTREF_FRAME}, {NEARESTMV, GOLDEN_FRAME, ALTREF_FRAME}, {NEARMV, GOLDEN_FRAME, ALTREF_FRAME}, - {NEWMV, LAST_FRAME, GOLDEN_FRAME}, - {NEWMV, ALTREF_FRAME, LAST_FRAME }, + {NEWMV, LAST_FRAME, ALTREF_FRAME}, {NEWMV, GOLDEN_FRAME, ALTREF_FRAME}, - {SPLITMV, LAST_FRAME, GOLDEN_FRAME}, - {SPLITMV, ALTREF_FRAME, LAST_FRAME }, + {SPLITMV, LAST_FRAME, ALTREF_FRAME}, {SPLITMV, GOLDEN_FRAME, ALTREF_FRAME}, }; @@ -306,7 +300,7 @@ static INLINE int cost_coeffs(VP9_COMMON *const cm, MACROBLOCK *mb, const int eob = xd->plane[plane].eobs[block]; const int16_t *qcoeff_ptr = BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16); - const int ref = mbmi->ref_frame != INTRA_FRAME; + const int ref = mbmi->ref_frame[0] != INTRA_FRAME; unsigned int (*token_costs)[PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS] = mb->token_costs[tx_size][type][ref]; ENTROPY_CONTEXT above_ec, left_ec; @@ -595,7 +589,7 @@ static void super_block_yrd_for_txfm(VP9_COMMON *const cm, MACROBLOCK *x, MACROBLOCKD *const xd = &x->e_mbd; xd->mode_info_context->mbmi.txfm_size = tx_size; - if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) + if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) vp9_encode_intra_block_y(cm, x, bsize); else vp9_xform_quant_sby(cm, x, bsize); @@ -614,7 +608,7 @@ static void super_block_yrd(VP9_COMP *cpi, MACROBLOCKD *xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi; - if (mbmi->ref_frame > INTRA_FRAME) + if (mbmi->ref_frame[0] > INTRA_FRAME) vp9_subtract_sby(x, bs); if (cpi->speed > 4) { @@ -918,7 +912,7 @@ static void super_block_uvrd_for_txfm(VP9_COMMON *const cm, MACROBLOCK *x, int *skippable, BLOCK_SIZE_TYPE bsize, TX_SIZE uv_tx_size) { MACROBLOCKD *const xd = &x->e_mbd; - if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) + if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) vp9_encode_intra_block_uv(cm, x, bsize); else vp9_xform_quant_sbuv(cm, x, bsize); @@ -934,7 +928,7 @@ static void super_block_uvrd(VP9_COMMON *const cm, MACROBLOCK *x, MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi; - if (mbmi->ref_frame > INTRA_FRAME) + if (mbmi->ref_frame[0] > INTRA_FRAME) vp9_subtract_sbuv(x, bsize); if (mbmi->txfm_size >= TX_32X32 && bsize >= BLOCK_SIZE_SB64X64) { @@ -1034,31 +1028,31 @@ static int labels2mode(MACROBLOCK *x, int i, // is when we are on a new label (jbb May 08, 2007) switch (m = this_mode) { case NEWMV: - this_mv->as_int = seg_mvs[mbmi->ref_frame].as_int; + this_mv->as_int = seg_mvs[mbmi->ref_frame[0]].as_int; thismvcost = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost, 102, xd->allow_high_precision_mv); - if (mbmi->second_ref_frame > 0) { - this_second_mv->as_int = seg_mvs[mbmi->second_ref_frame].as_int; + if (mbmi->ref_frame[1] > 0) { + this_second_mv->as_int = seg_mvs[mbmi->ref_frame[1]].as_int; thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv, mvjcost, mvcost, 102, xd->allow_high_precision_mv); } break; case NEARESTMV: - this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame].as_int; - if (mbmi->second_ref_frame > 0) + this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int; + if (mbmi->ref_frame[1] > 0) this_second_mv->as_int = - frame_mv[NEARESTMV][mbmi->second_ref_frame].as_int; + frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int; break; case NEARMV: - this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame].as_int; - if (mbmi->second_ref_frame > 0) + this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int; + if (mbmi->ref_frame[1] > 0) this_second_mv->as_int = - frame_mv[NEARMV][mbmi->second_ref_frame].as_int; + frame_mv[NEARMV][mbmi->ref_frame[1]].as_int; break; case ZEROMV: this_mv->as_int = 0; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) this_second_mv->as_int = 0; break; default: @@ -1066,15 +1060,15 @@ static int labels2mode(MACROBLOCK *x, int i, } cost = vp9_cost_mv_ref(cpi, this_mode, - mbmi->mb_mode_context[mbmi->ref_frame]); + mbmi->mb_mode_context[mbmi->ref_frame[0]]); mic->bmi[i].as_mv[0].as_int = this_mv->as_int; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) mic->bmi[i].as_mv[1].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 > 0) + if (mbmi->ref_frame[1] > 0) x->partition_info->bmi[i].second_mv.as_int = this_second_mv->as_int; for (idy = 0; idy < bh; ++idy) { for (idx = 0; idx < bw; ++idx) { @@ -1136,7 +1130,7 @@ static int64_t encode_inter_mb_segment(VP9_COMMON *const cm, // TODO(debargha): Make this work properly with the // implicit-compoundinter-weight experiment when implicit // weighting for splitmv modes is turned on. - if (xd->mode_info_context->mbmi.second_ref_frame > 0) { + if (xd->mode_info_context->mbmi.ref_frame[1] > 0) { uint8_t* const second_pre = raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, i, xd->plane[0].pre[1].buf, @@ -1254,7 +1248,7 @@ static INLINE void mi_buf_shift(MACROBLOCK *x, int i) { raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i, x->e_mbd.plane[0].pre[0].buf, x->e_mbd.plane[0].pre[0].stride); - if (mbmi->second_ref_frame) + if (mbmi->ref_frame[1]) x->e_mbd.plane[0].pre[1].buf = raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i, x->e_mbd.plane[0].pre[1].buf, @@ -1266,7 +1260,7 @@ static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src, MB_MODE_INFO *mbmi = &x->e_mbd.mode_info_context->mbmi; x->plane[0].src = orig_src; x->e_mbd.plane[0].pre[0] = orig_pre[0]; - if (mbmi->second_ref_frame) + if (mbmi->ref_frame[1]) x->e_mbd.plane[0].pre[1] = orig_pre[1]; } @@ -1326,16 +1320,16 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, int bestlabelyrate = 0; i = idy * 2 + idx; - frame_mv[ZEROMV][mbmi->ref_frame].as_int = 0; - frame_mv[ZEROMV][mbmi->second_ref_frame].as_int = 0; + frame_mv[ZEROMV][mbmi->ref_frame[0]].as_int = 0; + frame_mv[ZEROMV][mbmi->ref_frame[1]].as_int = 0; vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, - &frame_mv[NEARESTMV][mbmi->ref_frame], - &frame_mv[NEARMV][mbmi->ref_frame], + &frame_mv[NEARESTMV][mbmi->ref_frame[0]], + &frame_mv[NEARMV][mbmi->ref_frame[0]], i, 0); - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) vp9_append_sub8x8_mvs_for_idx(&cpi->common, &x->e_mbd, - &frame_mv[NEARESTMV][mbmi->second_ref_frame], - &frame_mv[NEARMV][mbmi->second_ref_frame], + &frame_mv[NEARESTMV][mbmi->ref_frame[1]], + &frame_mv[NEARMV][mbmi->ref_frame[1]], i, 1); // search for the best motion vector on this segment @@ -1353,7 +1347,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, vpx_memcpy(t_left_s, t_left, sizeof(t_left_s)); // motion search for newmv (single predictor case only) - if (mbmi->second_ref_frame <= 0 && this_mode == NEWMV) { + if (mbmi->ref_frame[1] <= 0 && this_mode == NEWMV) { int step_param = 0; int further_steps; int thissme, bestsme = INT_MAX; @@ -1420,14 +1414,14 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, &distortion, &sse); // safe motion search result for use in compound prediction - seg_mvs[i][mbmi->ref_frame].as_int = mode_mv[NEWMV].as_int; + seg_mvs[i][mbmi->ref_frame[0]].as_int = mode_mv[NEWMV].as_int; } // restore src pointers mi_buf_restore(x, orig_src, orig_pre); - } else if (mbmi->second_ref_frame > 0 && this_mode == NEWMV) { - if (seg_mvs[i][mbmi->second_ref_frame].as_int == INVALID_MV || - seg_mvs[i][mbmi->ref_frame ].as_int == INVALID_MV) + } else if (mbmi->ref_frame[1] > 0 && this_mode == NEWMV) { + if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV || + seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) continue; // adjust src pointers @@ -1436,10 +1430,10 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, iterative_motion_search(cpi, x, bsize, frame_mv[this_mode], scaled_ref_frame, mi_row, mi_col, seg_mvs[i]); - seg_mvs[i][mbmi->ref_frame].as_int = - frame_mv[this_mode][mbmi->ref_frame].as_int; - seg_mvs[i][mbmi->second_ref_frame].as_int = - frame_mv[this_mode][mbmi->second_ref_frame].as_int; + seg_mvs[i][mbmi->ref_frame[0]].as_int = + frame_mv[this_mode][mbmi->ref_frame[0]].as_int; + seg_mvs[i][mbmi->ref_frame[1]].as_int = + frame_mv[this_mode][mbmi->ref_frame[1]].as_int; } // restore src pointers mi_buf_restore(x, orig_src, orig_pre); @@ -1457,7 +1451,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 > 0 && + if (mbmi->ref_frame[1] > 0 && mv_check_bounds(x, &second_mode_mv[this_mode])) continue; @@ -1513,7 +1507,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, // store everything needed to come back to this!! for (i = 0; i < 4; i++) { bsi->mvs[i].as_mv = x->partition_info->bmi[i].mv.as_mv; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 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]; @@ -1551,7 +1545,7 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, /* set it to the best */ for (i = 0; i < 4; i++) { x->e_mbd.mode_info_context->bmi[i].as_mv[0].as_int = bsi.mvs[i].as_int; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) x->e_mbd.mode_info_context->bmi[i].as_mv[1].as_int = bsi.second_mvs[i].as_int; x->e_mbd.plane[0].eobs[i] = bsi.eobs[i]; @@ -1563,14 +1557,14 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, for (i = 0; i < x->partition_info->count; i++) { x->partition_info->bmi[i].mode = bsi.modes[i]; x->partition_info->bmi[i].mv.as_mv = bsi.mvs[i].as_mv; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) x->partition_info->bmi[i].second_mv.as_mv = bsi.second_mvs[i].as_mv; } /* * used to set mbmi->mv.as_int */ x->partition_info->bmi[3].mv.as_int = bsi.mvs[3].as_int; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) x->partition_info->bmi[3].second_mv.as_int = bsi.second_mvs[3].as_int; *returntotrate = bsi.r; @@ -1627,77 +1621,15 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, x->mv_best_ref_index[ref_frame] = best_index; } -extern void vp9_calc_ref_probs(int *count, vp9_prob *probs); -static void estimate_curframe_refprobs(VP9_COMP *cpi, - vp9_prob mod_refprobs[3], - int pred_ref) { - int norm_cnt[MAX_REF_FRAMES]; - const int *const rfct = cpi->count_mb_ref_frame_usage; - int intra_count = rfct[INTRA_FRAME]; - int last_count = rfct[LAST_FRAME]; - int gf_count = rfct[GOLDEN_FRAME]; - int arf_count = rfct[ALTREF_FRAME]; - - // Work out modified reference frame probabilities to use where prediction - // of the reference frame fails - if (pred_ref == INTRA_FRAME) { - norm_cnt[0] = 0; - norm_cnt[1] = last_count; - norm_cnt[2] = gf_count; - norm_cnt[3] = arf_count; - vp9_calc_ref_probs(norm_cnt, mod_refprobs); - mod_refprobs[0] = 0; // This branch implicit - } else if (pred_ref == LAST_FRAME) { - norm_cnt[0] = intra_count; - norm_cnt[1] = 0; - norm_cnt[2] = gf_count; - norm_cnt[3] = arf_count; - vp9_calc_ref_probs(norm_cnt, mod_refprobs); - mod_refprobs[1] = 0; // This branch implicit - } else if (pred_ref == GOLDEN_FRAME) { - norm_cnt[0] = intra_count; - norm_cnt[1] = last_count; - norm_cnt[2] = 0; - norm_cnt[3] = arf_count; - vp9_calc_ref_probs(norm_cnt, mod_refprobs); - mod_refprobs[2] = 0; // This branch implicit - } else { - norm_cnt[0] = intra_count; - norm_cnt[1] = last_count; - norm_cnt[2] = gf_count; - norm_cnt[3] = 0; - vp9_calc_ref_probs(norm_cnt, mod_refprobs); - mod_refprobs[2] = 0; // This branch implicit - } -} - -static INLINE unsigned weighted_cost(vp9_prob *tab0, vp9_prob *tab1, - int idx, int val, int weight) { - unsigned cost0 = tab0[idx] ? vp9_cost_bit(tab0[idx], val) : 0; - unsigned cost1 = tab1[idx] ? vp9_cost_bit(tab1[idx], val) : 0; - // weight is 16-bit fixed point, so this basically calculates: - // 0.5 + weight * cost1 + (1.0 - weight) * cost0 - return (0x8000 + weight * cost1 + (0x10000 - weight) * cost0) >> 16; -} - static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id, - unsigned int *ref_costs) { - VP9_COMMON *cm = &cpi->common; - MACROBLOCKD *xd = &cpi->mb.e_mbd; - vp9_prob *mod_refprobs; - - unsigned int cost; - int pred_ref; - int pred_flag; - int pred_ctx; - int i; - - vp9_prob pred_prob, new_pred_prob; - int seg_ref_active; + unsigned int *ref_costs_single, + unsigned int *ref_costs_comp, + vp9_prob *comp_mode_p) { + VP9_COMMON *const cm = &cpi->common; + MACROBLOCKD *const xd = &cpi->mb.e_mbd; + int seg_ref_active = vp9_segfeature_active(xd, segment_id, + SEG_LVL_REF_FRAME); int seg_ref_count = 0; - seg_ref_active = vp9_segfeature_active(xd, - segment_id, - SEG_LVL_REF_FRAME); if (seg_ref_active) { seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME) + @@ -1706,56 +1638,56 @@ static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id, vp9_check_segref(xd, segment_id, ALTREF_FRAME); } - // Get the predicted reference for this mb - pred_ref = vp9_get_pred_ref(cm, xd); - - // Get the context probability for the prediction flag (based on last frame) - pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF); - - // Predict probability for current frame based on stats so far - pred_ctx = vp9_get_pred_context(cm, xd, PRED_REF); - new_pred_prob = get_binary_prob(cpi->ref_pred_count[pred_ctx][0], - cpi->ref_pred_count[pred_ctx][1]); - - // Get the set of probabilities to use if prediction fails - mod_refprobs = cm->mod_refprobs[pred_ref]; + if (seg_ref_active && seg_ref_count == 1) { + vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single)); + vpx_memset(ref_costs_comp, 0, MAX_REF_FRAMES * sizeof(*ref_costs_comp)); + *comp_mode_p = 128; + } else { + vp9_prob intra_inter_p = vp9_get_pred_prob(cm, xd, PRED_INTRA_INTER); + vp9_prob comp_inter_p = 128; - // For each possible selected reference frame work out a cost. - for (i = 0; i < MAX_REF_FRAMES; i++) { - if (seg_ref_active && seg_ref_count == 1) { - cost = 0; + if (cm->comp_pred_mode == HYBRID_PREDICTION) { + comp_inter_p = vp9_get_pred_prob(cm, xd, PRED_COMP_INTER_INTER); + *comp_mode_p = comp_inter_p; } else { - pred_flag = (i == pred_ref); + *comp_mode_p = 128; + } - // Get the prediction for the current mb - cost = weighted_cost(&pred_prob, &new_pred_prob, 0, - pred_flag, cpi->seg0_progress); - if (cost > 1024) cost = 768; // i.e. account for 4 bits max. + ref_costs_single[INTRA_FRAME] = vp9_cost_bit(intra_inter_p, 0); - // for incorrectly predicted cases - if (!pred_flag) { - vp9_prob curframe_mod_refprobs[3]; + if (cm->comp_pred_mode != COMP_PREDICTION_ONLY) { + vp9_prob ref_single_p1 = vp9_get_pred_prob(cm, xd, PRED_SINGLE_REF_P1); + vp9_prob ref_single_p2 = vp9_get_pred_prob(cm, xd, PRED_SINGLE_REF_P2); + unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1); - if (cpi->seg0_progress) { - estimate_curframe_refprobs(cpi, curframe_mod_refprobs, pred_ref); - } else { - vpx_memset(curframe_mod_refprobs, 0, sizeof(curframe_mod_refprobs)); - } + if (cm->comp_pred_mode == HYBRID_PREDICTION) + base_cost += vp9_cost_bit(comp_inter_p, 0); - cost += weighted_cost(mod_refprobs, curframe_mod_refprobs, 0, - (i != INTRA_FRAME), cpi->seg0_progress); - if (i != INTRA_FRAME) { - cost += weighted_cost(mod_refprobs, curframe_mod_refprobs, 1, - (i != LAST_FRAME), cpi->seg0_progress); - if (i != LAST_FRAME) { - cost += weighted_cost(mod_refprobs, curframe_mod_refprobs, 2, - (i != GOLDEN_FRAME), cpi->seg0_progress); - } - } - } + ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] = + ref_costs_single[ALTREF_FRAME] = base_cost; + ref_costs_single[LAST_FRAME] += vp9_cost_bit(ref_single_p1, 0); + ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p1, 1); + ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p1, 1); + ref_costs_single[GOLDEN_FRAME] += vp9_cost_bit(ref_single_p2, 0); + ref_costs_single[ALTREF_FRAME] += vp9_cost_bit(ref_single_p2, 1); + } else { + ref_costs_single[LAST_FRAME] = 512; + ref_costs_single[GOLDEN_FRAME] = 512; + ref_costs_single[ALTREF_FRAME] = 512; } + if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY) { + vp9_prob ref_comp_p = vp9_get_pred_prob(cm, xd, PRED_COMP_REF_P); + unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1); - ref_costs[i] = cost; + if (cm->comp_pred_mode == HYBRID_PREDICTION) + base_cost += vp9_cost_bit(comp_inter_p, 1); + + ref_costs_comp[LAST_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 0); + ref_costs_comp[GOLDEN_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 1); + } else { + ref_costs_comp[LAST_FRAME] = 512; + ref_costs_comp[GOLDEN_FRAME] = 512; + } } } @@ -1959,8 +1891,8 @@ static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x, int pw = 4 << b_width_log2(bsize), ph = 4 << b_height_log2(bsize); MACROBLOCKD *xd = &x->e_mbd; MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi; - int refs[2] = { mbmi->ref_frame, - (mbmi->second_ref_frame < 0 ? 0 : mbmi->second_ref_frame) }; + int refs[2] = { mbmi->ref_frame[0], + (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) }; int_mv ref_mv[2]; const enum BlockSize block_size = get_plane_block_size(bsize, &xd->plane[0]); int ite; @@ -2102,7 +2034,6 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE_TYPE bsize, int64_t txfm_cache[], int *rate2, int *distortion, int *skippable, - int *compmode_cost, int *rate_y, int *distortion_y, int *rate_uv, int *distortion_uv, int *mode_excluded, int *disable_skip, @@ -2119,12 +2050,12 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, const enum BlockSize uv_block_size = get_plane_block_size(bsize, &xd->plane[1]); MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi; - const int is_comp_pred = (mbmi->second_ref_frame > 0); + const int is_comp_pred = (mbmi->ref_frame[1] > 0); 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 < 0 ? 0 : mbmi->second_ref_frame) }; + int refs[2] = { mbmi->ref_frame[0], + (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) }; int_mv cur_mv[2]; int_mv ref_mv[2]; int64_t this_rd = 0; @@ -2263,10 +2194,8 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other * words if you present them in that order, the second one is always known * if the first is known */ - *compmode_cost = vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP), - is_comp_pred); *rate2 += vp9_cost_mv_ref(cpi, this_mode, - mbmi->mb_mode_context[mbmi->ref_frame]); + mbmi->mb_mode_context[mbmi->ref_frame[0]]); pred_exists = 0; interpolating_intpel_seen = 0; @@ -2460,7 +2389,7 @@ void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, vpx_memset(&txfm_cache,0,sizeof(txfm_cache)); ctx->skip = 0; xd->mode_info_context->mbmi.mode = DC_PRED; - xd->mode_info_context->mbmi.ref_frame = INTRA_FRAME; + xd->mode_info_context->mbmi.ref_frame[0] = INTRA_FRAME; err = rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y, &y_skip, bsize, txfm_cache); mode = xd->mode_info_context->mbmi.mode; @@ -2513,7 +2442,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, const enum BlockSize block_size = get_plane_block_size(bsize, &xd->plane[0]); MB_PREDICTION_MODE this_mode; MB_PREDICTION_MODE best_mode = DC_PRED; - MV_REFERENCE_FRAME ref_frame, second_ref = INTRA_FRAME; + MV_REFERENCE_FRAME ref_frame; unsigned char segment_id = xd->mode_info_context->mbmi.segment_id; int comp_pred, i; int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; @@ -2533,7 +2462,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, MB_MODE_INFO best_mbmode; int j; int mode_index, best_mode_index = 0; - unsigned int ref_costs[MAX_REF_FRAMES]; + unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES]; + vp9_prob comp_mode_p; int64_t best_overall_rd = INT64_MAX; INTERPOLATIONFILTERTYPE best_filter = SWITCHABLE; INTERPOLATIONFILTERTYPE tmp_best_filter = SWITCHABLE; @@ -2566,7 +2496,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, ctx->modes_with_high_error = 0; xd->mode_info_context->mbmi.segment_id = segment_id; - estimate_ref_frame_costs(cpi, segment_id, ref_costs); + estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp, + &comp_mode_p); vpx_memset(&best_mbmode, 0, sizeof(best_mbmode)); vpx_memset(&single_newmv, 0, sizeof(single_newmv)); @@ -2619,7 +2550,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, if (cpi->speed == 0 || (cpi->speed > 0 && (ref_frame_mask & (1 << INTRA_FRAME)))) { mbmi->mode = DC_PRED; - mbmi->ref_frame = INTRA_FRAME; + mbmi->ref_frame[0] = INTRA_FRAME; for (i = 0; i <= (bsize < BLOCK_SIZE_MB16X16 ? TX_4X4 : (bsize < BLOCK_SIZE_SB32X32 ? TX_8X8 : (bsize < BLOCK_SIZE_SB64X64 ? TX_16X16 : TX_32X32))); @@ -2637,7 +2568,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, int mode_excluded = 0; int64_t this_rd = INT64_MAX; int disable_skip = 0; - int other_cost = 0; int compmode_cost = 0; int rate2 = 0, rate_y = 0, rate_uv = 0; int distortion2 = 0, distortion_y = 0, distortion_uv = 0; @@ -2672,39 +2602,39 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } } - mbmi->ref_frame = ref_frame; - mbmi->second_ref_frame = vp9_mode_order[mode_index].second_ref_frame; + mbmi->ref_frame[0] = ref_frame; + mbmi->ref_frame[1] = vp9_mode_order[mode_index].second_ref_frame; if (!(ref_frame == INTRA_FRAME || (cpi->ref_frame_flags & flag_list[ref_frame]))) { continue; } - if (!(mbmi->second_ref_frame == NONE - || (cpi->ref_frame_flags & flag_list[mbmi->second_ref_frame]))) { + if (!(mbmi->ref_frame[1] == NONE + || (cpi->ref_frame_flags & flag_list[mbmi->ref_frame[1]]))) { continue; } // TODO(jingning, jkoleszar): scaling reference frame not supported for // SPLITMV. - if (mbmi->ref_frame > 0 && - (scale_factor[mbmi->ref_frame].x_num != - scale_factor[mbmi->ref_frame].x_den || - scale_factor[mbmi->ref_frame].y_num != - scale_factor[mbmi->ref_frame].y_den) && + if (mbmi->ref_frame[0] > 0 && + (scale_factor[mbmi->ref_frame[0]].x_num != + scale_factor[mbmi->ref_frame[0]].x_den || + scale_factor[mbmi->ref_frame[0]].y_num != + scale_factor[mbmi->ref_frame[0]].y_den) && this_mode == SPLITMV) continue; - if (mbmi->second_ref_frame > 0 && - (scale_factor[mbmi->second_ref_frame].x_num != - scale_factor[mbmi->second_ref_frame].x_den || - scale_factor[mbmi->second_ref_frame].y_num != - scale_factor[mbmi->second_ref_frame].y_den) && + if (mbmi->ref_frame[1] > 0 && + (scale_factor[mbmi->ref_frame[1]].x_num != + scale_factor[mbmi->ref_frame[1]].x_den || + scale_factor[mbmi->ref_frame[1]].y_num != + scale_factor[mbmi->ref_frame[1]].y_den) && this_mode == SPLITMV) continue; - set_scale_factors(xd, mbmi->ref_frame, mbmi->second_ref_frame, + set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1], scale_factor); - comp_pred = mbmi->second_ref_frame > INTRA_FRAME; + comp_pred = mbmi->ref_frame[1] > INTRA_FRAME; mbmi->mode = this_mode; mbmi->uv_mode = DC_PRED; @@ -2721,24 +2651,18 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, continue; if (comp_pred) { - if (ref_frame == ALTREF_FRAME) { - second_ref = LAST_FRAME; - } else { - second_ref = ref_frame + 1; - } - if (!(cpi->ref_frame_flags & flag_list[second_ref])) + if (!(cpi->ref_frame_flags & flag_list[mbmi->ref_frame[1]])) continue; - mbmi->second_ref_frame = second_ref; - set_scale_factors(xd, mbmi->ref_frame, mbmi->second_ref_frame, + set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1], scale_factor); mode_excluded = mode_excluded ? mode_excluded : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY; } else { - // mbmi->second_ref_frame = vp9_mode_order[mode_index].second_ref_frame; + // mbmi->ref_frame[1] = vp9_mode_order[mode_index].ref_frame[1]; if (ref_frame != INTRA_FRAME) { - if (mbmi->second_ref_frame != INTRA_FRAME) + if (mbmi->ref_frame[1] != INTRA_FRAME) mode_excluded = mode_excluded ? mode_excluded : cm->comp_pred_mode == COMP_PREDICTION_ONLY; @@ -2749,7 +2673,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, for (i = 0; i < MAX_MB_PLANE; i++) { xd->plane[i].pre[0] = yv12_mb[ref_frame][i]; if (comp_pred) - xd->plane[i].pre[1] = yv12_mb[second_ref][i]; + xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i]; } // If the segment reference frame feature is enabled.... @@ -2826,7 +2750,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, rate2 += intra_cost_penalty; distortion2 = distortion_y + distortion_uv; } else if (this_mode == SPLITMV) { - const int is_comp_pred = mbmi->second_ref_frame > 0; + const int is_comp_pred = mbmi->ref_frame[1] > 0; int rate, distortion; int64_t this_rd_thresh; int64_t tmp_rd, tmp_best_rd = INT64_MAX, tmp_best_rdu = INT64_MAX; @@ -2834,17 +2758,17 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, int tmp_best_distortion = INT_MAX, tmp_best_skippable = 0; int switchable_filter_index; int_mv *second_ref = is_comp_pred ? - &mbmi->ref_mvs[mbmi->second_ref_frame][0] : NULL; + &mbmi->ref_mvs[mbmi->ref_frame[1]][0] : NULL; union b_mode_info tmp_best_bmodes[16]; MB_MODE_INFO tmp_best_mbmode; PARTITION_INFO tmp_best_partition; int pred_exists = 0; int uv_skippable; - this_rd_thresh = (mbmi->ref_frame == LAST_FRAME) ? + this_rd_thresh = (mbmi->ref_frame[0] == LAST_FRAME) ? cpi->rd_threshes[bsize][THR_NEWMV] : cpi->rd_threshes[bsize][THR_NEWA]; - this_rd_thresh = (mbmi->ref_frame == GOLDEN_FRAME) ? + this_rd_thresh = (mbmi->ref_frame[0] == GOLDEN_FRAME) ? cpi->rd_threshes[bsize][THR_NEWG] : this_rd_thresh; xd->mode_info_context->mbmi.txfm_size = TX_4X4; @@ -2857,12 +2781,12 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, vp9_setup_interp_filters(xd, mbmi->interp_filter, &cpi->common); tmp_rd = rd_pick_best_mbsegmentation(cpi, x, - &mbmi->ref_mvs[mbmi->ref_frame][0], - second_ref, INT64_MAX, - &rate, &rate_y, &distortion, - &skippable, - (int)this_rd_thresh, seg_mvs, - mi_row, mi_col); + &mbmi->ref_mvs[mbmi->ref_frame[0]][0], + second_ref, INT64_MAX, + &rate, &rate_y, &distortion, + &skippable, + (int)this_rd_thresh, seg_mvs, + mi_row, mi_col); if (cpi->common.mcomp_filter_type == SWITCHABLE) { const int rs = get_switchable_rate(cm, x); tmp_rd += RDCOST(x->rdmult, x->rddiv, rs, 0); @@ -2895,12 +2819,12 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // Handles the special case when a filter that is not in the // switchable list (bilinear, 6-tap) is indicated at the frame level tmp_rd = rd_pick_best_mbsegmentation(cpi, x, - &mbmi->ref_mvs[mbmi->ref_frame][0], - second_ref, INT64_MAX, - &rate, &rate_y, &distortion, - &skippable, - (int)this_rd_thresh, seg_mvs, - mi_row, mi_col); + &mbmi->ref_mvs[mbmi->ref_frame[0]][0], + second_ref, INT64_MAX, + &rate, &rate_y, &distortion, + &skippable, + (int)this_rd_thresh, seg_mvs, + mi_row, mi_col); } else { if (cpi->common.mcomp_filter_type == SWITCHABLE) { int rs = get_switchable_rate(cm, x); @@ -2945,24 +2869,24 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY; } - compmode_cost = - vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP), is_comp_pred); + compmode_cost = vp9_cost_bit(comp_mode_p, is_comp_pred); } else { YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL}; - int fb = get_ref_frame_idx(cpi, mbmi->ref_frame); + int fb = get_ref_frame_idx(cpi, mbmi->ref_frame[0]); if (cpi->scaled_ref_idx[fb] != cm->ref_frame_map[fb]) scaled_ref_frame[0] = &cm->yv12_fb[cpi->scaled_ref_idx[fb]]; if (comp_pred) { - fb = get_ref_frame_idx(cpi, mbmi->second_ref_frame); + fb = get_ref_frame_idx(cpi, mbmi->ref_frame[1]); if (cpi->scaled_ref_idx[fb] != cm->ref_frame_map[fb]) scaled_ref_frame[1] = &cm->yv12_fb[cpi->scaled_ref_idx[fb]]; } + compmode_cost = vp9_cost_bit(comp_mode_p, + mbmi->ref_frame[1] > INTRA_FRAME); this_rd = handle_inter_mode(cpi, x, bsize, txfm_cache, &rate2, &distortion2, &skippable, - &compmode_cost, &rate_y, &distortion_y, &rate_uv, &distortion_uv, &mode_excluded, &disable_skip, @@ -2979,7 +2903,11 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // Estimate the reference frame signaling cost and add it // to the rolling cost variable. - rate2 += ref_costs[xd->mode_info_context->mbmi.ref_frame]; + if (mbmi->ref_frame[1] > INTRA_FRAME) { + rate2 += ref_costs_comp[mbmi->ref_frame[0]]; + } else { + rate2 += ref_costs_single[mbmi->ref_frame[0]]; + } if (!disable_skip) { // Test for the condition where skip block will be activated @@ -3007,7 +2935,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, if (skip_prob) { prob_skip_cost = vp9_cost_bit(skip_prob, 1); rate2 += prob_skip_cost; - other_cost += prob_skip_cost; } } } else if (mb_skip_allowed) { @@ -3015,7 +2942,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob(cm, xd, PRED_MBSKIP), 0); rate2 += prob_skip_cost; - other_cost += prob_skip_cost; } // Calculate the final RD estimate for this mode. @@ -3024,14 +2950,14 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, #if 0 // Keep record of best intra distortion - if ((xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) && + if ((xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME) && (this_rd < best_intra_rd)) { best_intra_rd = this_rd; *returnintra = distortion2; } #endif - if (!disable_skip && mbmi->ref_frame == INTRA_FRAME) + if (!disable_skip && mbmi->ref_frame[0] == INTRA_FRAME) for (i = 0; i < NB_PREDICTION_TYPES; ++i) best_pred_rd[i] = MIN(best_pred_rd[i], this_rd); @@ -3047,9 +2973,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, || distortion2 < mode_distortions[this_mode]) { mode_distortions[this_mode] = distortion2; } - if (frame_distortions[mbmi->ref_frame] == -1 - || distortion2 < frame_distortions[mbmi->ref_frame]) { - frame_distortions[mbmi->ref_frame] = distortion2; + if (frame_distortions[mbmi->ref_frame[0]] == -1 + || distortion2 < frame_distortions[mbmi->ref_frame[0]]) { + frame_distortions[mbmi->ref_frame[0]] = distortion2; } } @@ -3064,7 +2990,6 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, mbmi->mv[0].as_int = 0; } - other_cost += ref_costs[xd->mode_info_context->mbmi.ref_frame]; *returnrate = rate2; *returndistortion = distortion2; best_rd = this_rd; @@ -3101,7 +3026,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } /* keep record of best compound/single-only prediction */ - if (!disable_skip && mbmi->ref_frame != INTRA_FRAME) { + if (!disable_skip && mbmi->ref_frame[0] != INTRA_FRAME) { int single_rd, hybrid_rd, single_rate, hybrid_rate; if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) { @@ -3115,10 +3040,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->ref_frame[1] <= 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->ref_frame[1] > INTRA_FRAME && single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) { best_pred_rd[COMP_PREDICTION_ONLY] = single_rd; } @@ -3179,7 +3104,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, assert((cm->mcomp_filter_type == SWITCHABLE) || (cm->mcomp_filter_type == best_mbmode.interp_filter) || - (best_mbmode.ref_frame == INTRA_FRAME)); + (best_mbmode.ref_frame[0] == INTRA_FRAME)); // Accumulate filter usage stats // TODO(agrange): Use RD criteria to select interpolation filter mode. @@ -3227,11 +3152,11 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, if (!vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME) && cpi->is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0) && - (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME) + (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame[0] != ALTREF_FRAME) && bsize >= BLOCK_SIZE_SB8X8) { mbmi->mode = ZEROMV; - mbmi->ref_frame = ALTREF_FRAME; - mbmi->second_ref_frame = NONE; + mbmi->ref_frame[0] = ALTREF_FRAME; + mbmi->ref_frame[1] = NONE; mbmi->mv[0].as_int = 0; mbmi->uv_mode = DC_PRED; mbmi->mb_skip_coeff = 1; @@ -3251,19 +3176,19 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // macroblock modes *mbmi = best_mbmode; - if (best_mbmode.ref_frame == INTRA_FRAME && + if (best_mbmode.ref_frame[0] == INTRA_FRAME && best_mbmode.sb_type < BLOCK_SIZE_SB8X8) { for (i = 0; i < 4; i++) xd->mode_info_context->bmi[i].as_mode = best_bmodes[i].as_mode; } - if (best_mbmode.ref_frame != INTRA_FRAME && + if (best_mbmode.ref_frame[0] != INTRA_FRAME && best_mbmode.sb_type < BLOCK_SIZE_SB8X8) { for (i = 0; i < 4; i++) xd->mode_info_context->bmi[i].as_mv[0].as_int = best_bmodes[i].as_mv[0].as_int; - if (mbmi->second_ref_frame > 0) + if (mbmi->ref_frame[1] > 0) for (i = 0; i < 4; i++) xd->mode_info_context->bmi[i].as_mv[1].as_int = best_bmodes[i].as_mv[1].as_int; @@ -3293,13 +3218,13 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } end: - set_scale_factors(xd, mbmi->ref_frame, mbmi->second_ref_frame, + set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1], scale_factor); store_coding_context(x, ctx, best_mode_index, &best_partition, - &mbmi->ref_mvs[mbmi->ref_frame][0], - &mbmi->ref_mvs[mbmi->second_ref_frame < 0 ? 0 : - mbmi->second_ref_frame][0], + &mbmi->ref_mvs[mbmi->ref_frame[0]][0], + &mbmi->ref_mvs[mbmi->ref_frame[1] < 0 ? 0 : + mbmi->ref_frame[1]][0], best_pred_diff, best_txfm_diff); return best_rd; diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c index b307c54..cb05219 100644 --- a/vp9/encoder/vp9_tokenize.c +++ b/vp9/encoder/vp9_tokenize.c @@ -130,7 +130,7 @@ static void tokenize_b(int plane, int block, BLOCK_SIZE_TYPE bsize, const int *scan, *nb; vp9_coeff_count *counts; vp9_coeff_probs_model *coef_probs; - const int ref = mbmi->ref_frame != INTRA_FRAME; + const int ref = mbmi->ref_frame[0] != INTRA_FRAME; ENTROPY_CONTEXT above_ec, left_ec; uint8_t token_cache[1024]; TX_TYPE tx_type = DCT_DCT;