Commit 1dc18077 authored by Jingning Han's avatar Jingning Han
Browse files

Re-design motion compensated prediction mode entropy coding system

This commit re-works the entropy coding scheme of the motion
compensated prediction modes. It allows more flexible hyperplane
partition for precise classification.

Change-Id: Iba5035c76691946cf1386b6c495e399c3d9c8fc5
parent 9fbc3940
...@@ -133,8 +133,8 @@ typedef struct { ...@@ -133,8 +133,8 @@ typedef struct {
int8_t angle_delta[2]; int8_t angle_delta[2];
#endif // CONFIG_EXT_INTRA #endif // CONFIG_EXT_INTRA
// TODO(slavarnway): Delete and use bmi[3].as_mv[] instead.
int_mv mv[2]; int_mv mv[2];
int_mv pred_mv[2];
} MB_MODE_INFO; } MB_MODE_INFO;
typedef struct MODE_INFO { typedef struct MODE_INFO {
......
...@@ -171,6 +171,20 @@ static const vpx_prob default_partition_probs[PARTITION_CONTEXTS] ...@@ -171,6 +171,20 @@ static const vpx_prob default_partition_probs[PARTITION_CONTEXTS]
{ 10, 7, 6 }, // a/l both split { 10, 7, 6 }, // a/l both split
}; };
#if CONFIG_REF_MV
static const vpx_prob default_newmv_prob[NEWMV_MODE_CONTEXTS] = {
230, 190, 150, 110, 70, 30,
};
static const vpx_prob default_zeromv_prob[ZEROMV_MODE_CONTEXTS] = {
192, 64,
};
static const vpx_prob default_refmv_prob[REFMV_MODE_CONTEXTS] = {
180, 230, 128
};
#endif
static const vpx_prob default_inter_mode_probs[INTER_MODE_CONTEXTS] static const vpx_prob default_inter_mode_probs[INTER_MODE_CONTEXTS]
[INTER_MODES - 1] = { [INTER_MODES - 1] = {
{2, 173, 34}, // 0 = both zero mv {2, 173, 34}, // 0 = both zero mv
...@@ -1184,6 +1198,11 @@ static void init_mode_probs(FRAME_CONTEXT *fc) { ...@@ -1184,6 +1198,11 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
vp10_copy(fc->txfm_partition_prob, default_txfm_partition_probs); vp10_copy(fc->txfm_partition_prob, default_txfm_partition_probs);
#endif #endif
vp10_copy(fc->skip_probs, default_skip_probs); vp10_copy(fc->skip_probs, default_skip_probs);
#if CONFIG_REF_MV
vp10_copy(fc->newmv_prob, default_newmv_prob);
vp10_copy(fc->zeromv_prob, default_zeromv_prob);
vp10_copy(fc->refmv_prob, default_refmv_prob);
#endif
vp10_copy(fc->inter_mode_probs, default_inter_mode_probs); vp10_copy(fc->inter_mode_probs, default_inter_mode_probs);
#if CONFIG_EXT_TX #if CONFIG_EXT_TX
vp10_copy(fc->inter_ext_tx_prob, default_inter_ext_tx_prob); vp10_copy(fc->inter_ext_tx_prob, default_inter_ext_tx_prob);
...@@ -1232,9 +1251,21 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) { ...@@ -1232,9 +1251,21 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
fc->single_ref_prob[i][j] = mode_mv_merge_probs( fc->single_ref_prob[i][j] = mode_mv_merge_probs(
pre_fc->single_ref_prob[i][j], counts->single_ref[i][j]); pre_fc->single_ref_prob[i][j], counts->single_ref[i][j]);
#if CONFIG_REF_MV
for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
fc->newmv_prob[i] = mode_mv_merge_probs(pre_fc->newmv_prob[i],
counts->newmv_mode[i]);
for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
fc->zeromv_prob[i] = mode_mv_merge_probs(pre_fc->zeromv_prob[i],
counts->zeromv_mode[i]);
for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
fc->refmv_prob[i] = mode_mv_merge_probs(pre_fc->refmv_prob[i],
counts->refmv_mode[i]);
#else
for (i = 0; i < INTER_MODE_CONTEXTS; i++) for (i = 0; i < INTER_MODE_CONTEXTS; i++)
vpx_tree_merge_probs(vp10_inter_mode_tree, pre_fc->inter_mode_probs[i], vpx_tree_merge_probs(vp10_inter_mode_tree, pre_fc->inter_mode_probs[i],
counts->inter_mode[i], fc->inter_mode_probs[i]); counts->inter_mode[i], fc->inter_mode_probs[i]);
#endif
for (i = 0; i < BLOCK_SIZE_GROUPS; i++) for (i = 0; i < BLOCK_SIZE_GROUPS; i++)
vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->y_mode_prob[i], vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->y_mode_prob[i],
......
...@@ -60,6 +60,13 @@ typedef struct frame_contexts { ...@@ -60,6 +60,13 @@ typedef struct frame_contexts {
vp10_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES]; vp10_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES];
vpx_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS] vpx_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS]
[SWITCHABLE_FILTERS - 1]; [SWITCHABLE_FILTERS - 1];
#if CONFIG_REF_MV
vpx_prob newmv_prob[NEWMV_MODE_CONTEXTS];
vpx_prob zeromv_prob[ZEROMV_MODE_CONTEXTS];
vpx_prob refmv_prob[REFMV_MODE_CONTEXTS];
#endif
vpx_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1]; vpx_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1];
vpx_prob intra_inter_prob[INTRA_INTER_CONTEXTS]; vpx_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS]; vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS];
...@@ -93,6 +100,12 @@ typedef struct FRAME_COUNTS { ...@@ -93,6 +100,12 @@ typedef struct FRAME_COUNTS {
[COEF_BANDS][COEFF_CONTEXTS]; [COEF_BANDS][COEFF_CONTEXTS];
unsigned int switchable_interp[SWITCHABLE_FILTER_CONTEXTS] unsigned int switchable_interp[SWITCHABLE_FILTER_CONTEXTS]
[SWITCHABLE_FILTERS]; [SWITCHABLE_FILTERS];
#if CONFIG_REF_MV
unsigned int newmv_mode[NEWMV_MODE_CONTEXTS][2];
unsigned int zeromv_mode[ZEROMV_MODE_CONTEXTS][2];
unsigned int refmv_mode[REFMV_MODE_CONTEXTS][2];
#endif
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES]; unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES];
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2]; unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2]; unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
......
...@@ -202,6 +202,19 @@ typedef enum { ...@@ -202,6 +202,19 @@ typedef enum {
#define INTER_MODES (1 + NEWMV - NEARESTMV) #define INTER_MODES (1 + NEWMV - NEARESTMV)
#define SKIP_CONTEXTS 3 #define SKIP_CONTEXTS 3
#if CONFIG_REF_MV
#define NEWMV_MODE_CONTEXTS 6
#define ZEROMV_MODE_CONTEXTS 2
#define REFMV_MODE_CONTEXTS 3
#define ZEROMV_OFFSET 3
#define REFMV_OFFSET 4
#define NEWMV_CTX_MASK ((1 << ZEROMV_OFFSET) - 1)
#define ZEROMV_CTX_MASK ((1 << (REFMV_OFFSET - ZEROMV_OFFSET)) - 1)
#endif
#define INTER_MODE_CONTEXTS 7 #define INTER_MODE_CONTEXTS 7
/* Segment Feature Masks */ /* Segment Feature Masks */
......
...@@ -12,14 +12,15 @@ ...@@ -12,14 +12,15 @@
#include "vp10/common/mvref_common.h" #include "vp10/common/mvref_common.h"
#if CONFIG_REF_MV #if CONFIG_REF_MV
static void scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, static uint8_t scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, const int mi_col, int block, const int mi_row, const int mi_col, int block,
const MV_REFERENCE_FRAME ref_frame, const MV_REFERENCE_FRAME ref_frame,
int row_offset, int row_offset,
CANDIDATE_MV *ref_mv_stack, CANDIDATE_MV *ref_mv_stack,
uint8_t *refmv_count) { uint8_t *refmv_count) {
const TileInfo *const tile = &xd->tile; const TileInfo *const tile = &xd->tile;
int i; int i;
uint8_t newmv_count = 0;
for (i = 0; i < xd->n8_w && *refmv_count < MAX_REF_MV_STACK_SIZE;) { for (i = 0; i < xd->n8_w && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
POSITION mi_pos; POSITION mi_pos;
...@@ -51,6 +52,9 @@ static void scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, ...@@ -51,6 +52,9 @@ static void scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
ref_mv_stack[index].this_mv = this_refmv; ref_mv_stack[index].this_mv = this_refmv;
ref_mv_stack[index].weight = weight; ref_mv_stack[index].weight = weight;
++(*refmv_count); ++(*refmv_count);
if (candidate->mode == NEWMV)
++newmv_count;
} }
} }
} }
...@@ -59,16 +63,19 @@ static void scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, ...@@ -59,16 +63,19 @@ static void scan_row_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
++i; ++i;
} }
} }
return newmv_count;
} }
static void scan_col_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, static uint8_t scan_col_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, const int mi_col, int block, const int mi_row, const int mi_col, int block,
const MV_REFERENCE_FRAME ref_frame, const MV_REFERENCE_FRAME ref_frame,
int col_offset, int col_offset,
CANDIDATE_MV *ref_mv_stack, CANDIDATE_MV *ref_mv_stack,
uint8_t *refmv_count) { uint8_t *refmv_count) {
const TileInfo *const tile = &xd->tile; const TileInfo *const tile = &xd->tile;
int i; int i;
uint8_t newmv_count = 0;
for (i = 0; i < xd->n8_h && *refmv_count < MAX_REF_MV_STACK_SIZE;) { for (i = 0; i < xd->n8_h && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
POSITION mi_pos; POSITION mi_pos;
...@@ -99,25 +106,30 @@ static void scan_col_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, ...@@ -99,25 +106,30 @@ static void scan_col_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
ref_mv_stack[index].this_mv = this_refmv; ref_mv_stack[index].this_mv = this_refmv;
ref_mv_stack[index].weight = weight; ref_mv_stack[index].weight = weight;
++(*refmv_count); ++(*refmv_count);
if (candidate->mode == NEWMV)
++newmv_count;
} }
} }
} }
i += len; i += len;
} else { } else {
++i; ++i;
} }
} }
return newmv_count;
} }
static void scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, static uint8_t scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
const int mi_row, const int mi_col, int block, const int mi_row, const int mi_col, int block,
const MV_REFERENCE_FRAME ref_frame, const MV_REFERENCE_FRAME ref_frame,
int row_offset, int col_offset, int row_offset, int col_offset,
CANDIDATE_MV *ref_mv_stack, CANDIDATE_MV *ref_mv_stack,
uint8_t *refmv_count) { uint8_t *refmv_count) {
const TileInfo *const tile = &xd->tile; const TileInfo *const tile = &xd->tile;
POSITION mi_pos; POSITION mi_pos;
uint8_t newmv_count = 0;
mi_pos.row = row_offset; mi_pos.row = row_offset;
mi_pos.col = col_offset; mi_pos.col = col_offset;
...@@ -146,6 +158,9 @@ static void scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, ...@@ -146,6 +158,9 @@ static void scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
ref_mv_stack[index].this_mv = this_refmv; ref_mv_stack[index].this_mv = this_refmv;
ref_mv_stack[index].weight = weight; ref_mv_stack[index].weight = weight;
++(*refmv_count); ++(*refmv_count);
if (candidate->mode == NEWMV)
++newmv_count;
} }
if (candidate_mi->mbmi.sb_type < BLOCK_8X8 && block >= 0) { if (candidate_mi->mbmi.sb_type < BLOCK_8X8 && block >= 0) {
...@@ -169,6 +184,7 @@ static void scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd, ...@@ -169,6 +184,7 @@ static void scan_blk_mbmi(const VP10_COMMON *cm, const MACROBLOCKD *xd,
} }
} }
} // Analyze a single 8x8 block motion information. } // Analyze a single 8x8 block motion information.
return newmv_count;
} }
static int has_top_right(const MACROBLOCKD *xd, static int has_top_right(const MACROBLOCKD *xd,
...@@ -215,55 +231,102 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd, ...@@ -215,55 +231,102 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd,
int block, int mi_row, int mi_col, int block, int mi_row, int mi_col,
uint8_t *mode_context) { uint8_t *mode_context) {
int idx, nearest_refmv_count = 0; int idx, nearest_refmv_count = 0;
uint8_t newmv_count = 0;
CANDIDATE_MV tmp_mv; CANDIDATE_MV tmp_mv;
int len, nr_len; int len, nr_len;
const MV_REF *const prev_frame_mvs = cm->use_prev_frame_mvs ? const MV_REF *const prev_frame_mvs_base = cm->use_prev_frame_mvs ?
cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col : NULL; cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col : NULL;
int bs = VPXMAX(xd->n8_w, xd->n8_h); int bs = VPXMAX(xd->n8_w, xd->n8_h);
int has_tr = has_top_right(xd, mi_row, mi_col, bs); int has_tr = has_top_right(xd, mi_row, mi_col, bs);
(void) mode_context;
*refmv_count = 0; *refmv_count = 0;
// Scan the first above row mode info. // Scan the first above row mode info.
scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, newmv_count = scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-1, ref_mv_stack, refmv_count); -1, ref_mv_stack, refmv_count);
// Scan the first left column mode info. // Scan the first left column mode info.
scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, newmv_count += scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-1, ref_mv_stack, refmv_count); -1, ref_mv_stack, refmv_count);
// Check top-right boundary // Check top-right boundary
if (has_tr) if (has_tr)
scan_blk_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, newmv_count += scan_blk_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-1, 1, ref_mv_stack, refmv_count); -1, 1, ref_mv_stack, refmv_count);
nearest_refmv_count = *refmv_count; nearest_refmv_count = *refmv_count;
if (prev_frame_mvs && cm->show_frame && cm->last_show_frame) { mode_context[ref_frame] = 0;
int ref; switch (nearest_refmv_count) {
for (ref = 0; ref < 2; ++ref) { case 0:
if (prev_frame_mvs->ref_frame[ref] == ref_frame) { mode_context[ref_frame] = 0;
for (idx = 0; idx < nearest_refmv_count; ++idx) break;
if (prev_frame_mvs->mv[ref].as_int ==
ref_mv_stack[idx].this_mv.as_int)
break;
if (idx == nearest_refmv_count && case 1:
nearest_refmv_count < MAX_REF_MV_STACK_SIZE) { mode_context[ref_frame] = (newmv_count > 0) ? 1 : 2;
ref_mv_stack[idx].this_mv.as_int = prev_frame_mvs->mv[ref].as_int; mode_context[ref_frame] += (1 << REFMV_OFFSET);
ref_mv_stack[idx].weight = 1; break;
++(*refmv_count);
++nearest_refmv_count; case 2:
default:
if (newmv_count >= 2)
mode_context[ref_frame] = 3;
else if (newmv_count == 1)
mode_context[ref_frame] = 4;
else
mode_context[ref_frame] = 5;
mode_context[ref_frame] += (2 << REFMV_OFFSET);
break;
}
if (prev_frame_mvs_base && cm->show_frame && cm->last_show_frame) {
int ref;
int blk_row, blk_col;
for (blk_row = 0; blk_row < xd->n8_h; ++blk_row) {
for (blk_col = 0; blk_col < xd->n8_w; ++blk_col) {
const MV_REF *prev_frame_mvs =
prev_frame_mvs_base + blk_row * cm->mi_cols + blk_col;
POSITION mi_pos;
mi_pos.row = blk_row;
mi_pos.col = blk_col;
if (!is_inside(&xd->tile, mi_col, mi_row, cm->mi_rows, &mi_pos))
continue;
for (ref = 0; ref < 2; ++ref) {
if (prev_frame_mvs->ref_frame[ref] == ref_frame) {
for (idx = 0; idx < *refmv_count; ++idx)
if (prev_frame_mvs->mv[ref].as_int ==
ref_mv_stack[idx].this_mv.as_int)
break;
if (idx < *refmv_count)
ref_mv_stack[idx].weight += 1;
if (idx == *refmv_count &&
*refmv_count < MAX_REF_MV_STACK_SIZE) {
ref_mv_stack[idx].this_mv.as_int = prev_frame_mvs->mv[ref].as_int;
ref_mv_stack[idx].weight = 1;
++(*refmv_count);
if (abs(ref_mv_stack[idx].this_mv.as_mv.row) >= 8 ||
abs(ref_mv_stack[idx].this_mv.as_mv.col) >= 8)
mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
}
}
} }
} }
} }
} }
if (*refmv_count == nearest_refmv_count)
mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
// Analyze the top-left corner block mode info. // Analyze the top-left corner block mode info.
// scan_blk_mbmi(cm, xd, mi_row, mi_col, block, ref_frame, // scan_blk_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
// -1, -1, ref_mv_stack, refmv_count); // -1, -1, ref_mv_stack, refmv_count);
...@@ -519,7 +582,6 @@ void vp10_append_sub8x8_mvs_for_idx(VP10_COMMON *cm, MACROBLOCKD *xd, ...@@ -519,7 +582,6 @@ void vp10_append_sub8x8_mvs_for_idx(VP10_COMMON *cm, MACROBLOCKD *xd,
find_mv_refs_idx(cm, xd, mi, mi->mbmi.ref_frame[ref], mv_list, block, find_mv_refs_idx(cm, xd, mi, mi->mbmi.ref_frame[ref], mv_list, block,
mi_row, mi_col, NULL, NULL, NULL); mi_row, mi_col, NULL, NULL, NULL);
#if CONFIG_REF_MV #if CONFIG_REF_MV
scan_blk_mbmi(cm, xd, mi_row, mi_col, block, mi->mbmi.ref_frame[ref], scan_blk_mbmi(cm, xd, mi_row, mi_col, block, mi->mbmi.ref_frame[ref],
-1, 0, ref_mv_stack, &ref_mv_count); -1, 0, ref_mv_stack, &ref_mv_count);
......
...@@ -366,6 +366,20 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts, ...@@ -366,6 +366,20 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts,
for (j = 0; j < SWITCHABLE_FILTERS; j++) for (j = 0; j < SWITCHABLE_FILTERS; j++)
cm->counts.switchable_interp[i][j] += counts->switchable_interp[i][j]; cm->counts.switchable_interp[i][j] += counts->switchable_interp[i][j];
#if CONFIG_REF_MV
for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
for (j = 0; j < 2; ++j)
cm->counts.newmv_mode[i][j] += counts->newmv_mode[i][j];
for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
for (j = 0; j < 2; ++j)
cm->counts.zeromv_mode[i][j] += counts->zeromv_mode[i][j];
for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
for (j = 0; j < 2; ++j)
cm->counts.refmv_mode[i][j] += counts->refmv_mode[i][j];
#endif
for (i = 0; i < INTER_MODE_CONTEXTS; i++) for (i = 0; i < INTER_MODE_CONTEXTS; i++)
for (j = 0; j < INTER_MODES; j++) for (j = 0; j < INTER_MODES; j++)
cm->counts.inter_mode[i][j] += counts->inter_mode[i][j]; cm->counts.inter_mode[i][j] += counts->inter_mode[i][j];
......
...@@ -124,10 +124,20 @@ static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vpx_reader *r) { ...@@ -124,10 +124,20 @@ static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
} }
static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) { static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
int i, j; int i;
#if CONFIG_REF_MV
for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
vp10_diff_update_prob(r, &fc->newmv_prob[i]);
for (i = 0; i < ZEROMV_MODE_CONTEXTS; ++i)
vp10_diff_update_prob(r, &fc->zeromv_prob[i]);
for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
vp10_diff_update_prob(r, &fc->refmv_prob[i]);
#else
int j;
for (i = 0; i < INTER_MODE_CONTEXTS; ++i) for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
for (j = 0; j < INTER_MODES - 1; ++j) for (j = 0; j < INTER_MODES - 1; ++j)
vp10_diff_update_prob(r, &fc->inter_mode_probs[i][j]); vp10_diff_update_prob(r, &fc->inter_mode_probs[i][j]);
#endif
} }
static REFERENCE_MODE read_frame_reference_mode(const VP10_COMMON *cm, static REFERENCE_MODE read_frame_reference_mode(const VP10_COMMON *cm,
......
...@@ -63,7 +63,49 @@ static PREDICTION_MODE read_intra_mode_uv(VP10_COMMON *cm, MACROBLOCKD *xd, ...@@ -63,7 +63,49 @@ static PREDICTION_MODE read_intra_mode_uv(VP10_COMMON *cm, MACROBLOCKD *xd,
} }
static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd, static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd,
vpx_reader *r, int ctx) { vpx_reader *r, uint8_t ctx) {
#if CONFIG_REF_MV
FRAME_COUNTS *counts = xd->counts;
uint8_t mode_ctx = ctx & NEWMV_CTX_MASK;
vpx_prob mode_prob = cm->fc->newmv_prob[mode_ctx];
if (vpx_read(r, mode_prob) == 0) {
if (counts)
++counts->newmv_mode[mode_ctx][0];
return NEWMV;
}
if (counts)
++counts->newmv_mode[mode_ctx][1];
mode_ctx = (ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
if (mode_ctx > 1)
assert(0);
mode_prob = cm->fc->zeromv_prob[mode_ctx];
if (vpx_read(r, mode_prob) == 0) {
if (counts)
++counts->zeromv_mode[mode_ctx][0];
return ZEROMV;
}
if (counts)
++counts->zeromv_mode[mode_ctx][1];
mode_ctx = (ctx >> REFMV_OFFSET);
mode_prob = cm->fc->refmv_prob[mode_ctx];
if (vpx_read(r, mode_prob) == 0) {
if (counts)
++counts->refmv_mode[mode_ctx][0];
return NEARESTMV;
} else {
if (counts)
++counts->refmv_mode[mode_ctx][1];
return NEARMV;
}
// Invalid prediction mode.
assert(0);
#else
const int mode = vpx_read_tree(r, vp10_inter_mode_tree, const int mode = vpx_read_tree(r, vp10_inter_mode_tree,
cm->fc->inter_mode_probs[ctx]); cm->fc->inter_mode_probs[ctx]);
FRAME_COUNTS *counts = xd->counts; FRAME_COUNTS *counts = xd->counts;
...@@ -71,6 +113,7 @@ static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd, ...@@ -71,6 +113,7 @@ static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd,
++counts->inter_mode[ctx][mode]; ++counts->inter_mode[ctx][mode];
return NEARESTMV + mode; return NEARESTMV + mode;
#endif
} }
static int read_segment_id(vpx_reader *r, static int read_segment_id(vpx_reader *r,
......
...@@ -47,8 +47,10 @@ static const struct vp10_token switchable_interp_encodings[SWITCHABLE_FILTERS] = ...@@ -47,8 +47,10 @@ static const struct vp10_token switchable_interp_encodings[SWITCHABLE_FILTERS] =
#endif // CONFIG_EXT_INTERP && SWITCHABLE_FILTERS == 4 #endif // CONFIG_EXT_INTERP && SWITCHABLE_FILTERS == 4
static const struct vp10_token partition_encodings[PARTITION_TYPES] = static const struct vp10_token partition_encodings[PARTITION_TYPES] =
{{0, 1}, {2, 2}, {6, 3}, {7, 3}}; {{0, 1}, {2, 2}, {6, 3}, {7, 3}};
#if !CONFIG_REF_MV
static const struct vp10_token inter_mode_encodings[INTER_MODES] = static const struct vp10_token inter_mode_encodings[INTER_MODES] =
{{2, 2}, {6, 3}, {0, 1}, {7, 3}}; {{2, 2}, {6, 3}, {0, 1}, {7, 3}};