Entropy coding for dynamic ref mv modes
This commit enables entropy coding for dynamic reference motion vector modes. The probability model is contexted on the ranking categories of the reference motion vector candidates. Change-Id: I09b58d98a409d63ec1a407331e29f8945b7ef17d
This commit is contained in:
@@ -184,6 +184,10 @@ static const vpx_prob default_refmv_prob[REFMV_MODE_CONTEXTS] = {
|
||||
220, 220, 200, 200, 180, 128, 30, 220, 30,
|
||||
};
|
||||
|
||||
static const vpx_prob default_drl_prob[DRL_MODE_CONTEXTS] = {
|
||||
128, 128, 128,
|
||||
};
|
||||
|
||||
#if CONFIG_EXT_INTER
|
||||
static const vpx_prob default_new2mv_prob = 180;
|
||||
#endif
|
||||
@@ -1292,6 +1296,8 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
|
||||
vp10_copy(fc->newmv_prob, default_newmv_prob);
|
||||
vp10_copy(fc->zeromv_prob, default_zeromv_prob);
|
||||
vp10_copy(fc->refmv_prob, default_refmv_prob);
|
||||
vp10_copy(fc->drl_prob0, default_drl_prob);
|
||||
vp10_copy(fc->drl_prob1, default_drl_prob);
|
||||
#if CONFIG_EXT_INTER
|
||||
fc->new2mv_prob = default_new2mv_prob;
|
||||
#endif // CONFIG_EXT_INTER
|
||||
@@ -1360,6 +1366,13 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
|
||||
fc->refmv_prob[i] = mode_mv_merge_probs(pre_fc->refmv_prob[i],
|
||||
counts->refmv_mode[i]);
|
||||
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
|
||||
fc->drl_prob0[i] = mode_mv_merge_probs(pre_fc->drl_prob0[i],
|
||||
counts->drl_mode0[i]);
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
|
||||
fc->drl_prob1[i] = mode_mv_merge_probs(pre_fc->drl_prob1[i],
|
||||
counts->drl_mode1[i]);
|
||||
|
||||
#if CONFIG_EXT_INTER
|
||||
fc->new2mv_prob = mode_mv_merge_probs(pre_fc->new2mv_prob,
|
||||
counts->new2mv_mode);
|
||||
|
||||
@@ -68,6 +68,9 @@ typedef struct frame_contexts {
|
||||
vpx_prob newmv_prob[NEWMV_MODE_CONTEXTS];
|
||||
vpx_prob zeromv_prob[ZEROMV_MODE_CONTEXTS];
|
||||
vpx_prob refmv_prob[REFMV_MODE_CONTEXTS];
|
||||
vpx_prob drl_prob0[DRL_MODE_CONTEXTS];
|
||||
vpx_prob drl_prob1[DRL_MODE_CONTEXTS];
|
||||
|
||||
#if CONFIG_EXT_INTER
|
||||
vpx_prob new2mv_prob;
|
||||
#endif // CONFIG_EXT_INTER
|
||||
@@ -121,6 +124,8 @@ typedef struct FRAME_COUNTS {
|
||||
unsigned int newmv_mode[NEWMV_MODE_CONTEXTS][2];
|
||||
unsigned int zeromv_mode[ZEROMV_MODE_CONTEXTS][2];
|
||||
unsigned int refmv_mode[REFMV_MODE_CONTEXTS][2];
|
||||
unsigned int drl_mode0[DRL_MODE_CONTEXTS][2];
|
||||
unsigned int drl_mode1[DRL_MODE_CONTEXTS][2];
|
||||
#if CONFIG_EXT_INTER
|
||||
unsigned int new2mv_mode[2];
|
||||
#endif // CONFIG_EXT_INTER
|
||||
|
||||
@@ -231,6 +231,7 @@ typedef enum {
|
||||
#define NEWMV_MODE_CONTEXTS 7
|
||||
#define ZEROMV_MODE_CONTEXTS 2
|
||||
#define REFMV_MODE_CONTEXTS 9
|
||||
#define DRL_MODE_CONTEXTS 3
|
||||
|
||||
#define ZEROMV_OFFSET 3
|
||||
#define REFMV_OFFSET 4
|
||||
@@ -251,6 +252,7 @@ typedef enum {
|
||||
#define MAX_MV_REF_CANDIDATES 2
|
||||
#if CONFIG_REF_MV
|
||||
#define MAX_REF_MV_STACK_SIZE 16
|
||||
#define REF_CAT_LEVEL 160
|
||||
#endif
|
||||
|
||||
#define INTRA_INTER_CONTEXTS 4
|
||||
|
||||
@@ -329,6 +329,9 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd,
|
||||
|
||||
nearest_refmv_count = *refmv_count;
|
||||
|
||||
for (idx = 0; idx < nearest_refmv_count; ++idx)
|
||||
ref_mv_stack[idx].weight += REF_CAT_LEVEL;
|
||||
|
||||
if (prev_frame_mvs_base && cm->show_frame && cm->last_show_frame
|
||||
&& rf[1] == NONE) {
|
||||
int ref;
|
||||
|
||||
@@ -257,6 +257,24 @@ static INLINE int16_t vp10_mode_context_analyzer(
|
||||
else
|
||||
return mode_context[rf[0]];
|
||||
}
|
||||
|
||||
static INLINE uint8_t vp10_drl_ctx(const CANDIDATE_MV *ref_mv_stack,
|
||||
int ref_idx) {
|
||||
if (ref_mv_stack[ref_idx + 1].weight > REF_CAT_LEVEL &&
|
||||
ref_mv_stack[ref_idx + 2].weight > REF_CAT_LEVEL)
|
||||
return 0;
|
||||
|
||||
if (ref_mv_stack[ref_idx + 1].weight > REF_CAT_LEVEL &&
|
||||
ref_mv_stack[ref_idx + 2].weight < REF_CAT_LEVEL)
|
||||
return 1;
|
||||
|
||||
if (ref_mv_stack[ref_idx + 1].weight < REF_CAT_LEVEL &&
|
||||
ref_mv_stack[ref_idx + 2].weight < REF_CAT_LEVEL)
|
||||
return 2;
|
||||
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef void (*find_mv_refs_sync)(void *const data, int mi_row);
|
||||
|
||||
@@ -379,6 +379,15 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts,
|
||||
for (j = 0; j < 2; ++j)
|
||||
cm->counts.refmv_mode[i][j] += counts->refmv_mode[i][j];
|
||||
|
||||
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
|
||||
for (j = 0; j < 2; ++j)
|
||||
cm->counts.drl_mode0[i][j] += counts->drl_mode0[i][j];
|
||||
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
|
||||
for (j = 0; j < 2; ++j)
|
||||
cm->counts.drl_mode1[i][j] += counts->drl_mode1[i][j];
|
||||
|
||||
#if CONFIG_EXT_INTER
|
||||
for (j = 0; j < 2; ++j)
|
||||
cm->counts.new2mv_mode[j] += counts->new2mv_mode[j];
|
||||
|
||||
@@ -132,6 +132,10 @@ static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
|
||||
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]);
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
|
||||
vp10_diff_update_prob(r, &fc->drl_prob0[i]);
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
|
||||
vp10_diff_update_prob(r, &fc->drl_prob1[i]);
|
||||
#if CONFIG_EXT_INTER
|
||||
vp10_diff_update_prob(r, &fc->new2mv_prob);
|
||||
#endif // CONFIG_EXT_INTER
|
||||
|
||||
@@ -147,6 +147,45 @@ static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd,
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_REF_MV
|
||||
static void read_drl_idx(const VP10_COMMON *cm,
|
||||
MACROBLOCKD *xd,
|
||||
MB_MODE_INFO *mbmi,
|
||||
vpx_reader *r) {
|
||||
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
|
||||
mbmi->ref_mv_idx = 0;
|
||||
|
||||
if (xd->ref_mv_count[ref_frame_type] > 2) {
|
||||
uint8_t drl0_ctx = vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], 0);
|
||||
vpx_prob drl0_prob = cm->fc->drl_prob0[drl0_ctx];
|
||||
if (vpx_read(r, drl0_prob)) {
|
||||
mbmi->ref_mv_idx = 1;
|
||||
if (xd->counts)
|
||||
++xd->counts->drl_mode0[drl0_ctx][1];
|
||||
if (xd->ref_mv_count[ref_frame_type] > 3) {
|
||||
uint8_t drl1_ctx =
|
||||
vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], 1);
|
||||
vpx_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx];
|
||||
if (vpx_read(r, drl1_prob)) {
|
||||
mbmi->ref_mv_idx = 2;
|
||||
if (xd->counts)
|
||||
++xd->counts->drl_mode1[drl1_ctx][1];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (xd->counts)
|
||||
++xd->counts->drl_mode1[drl1_ctx][0];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (xd->counts)
|
||||
++xd->counts->drl_mode0[drl0_ctx][0];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_INTER
|
||||
static PREDICTION_MODE read_inter_compound_mode(VP10_COMMON *cm,
|
||||
MACROBLOCKD *xd,
|
||||
@@ -1056,17 +1095,8 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
|
||||
#endif // CONFIG_REF_MV && CONFIG_EXT_INTER
|
||||
r, mode_ctx);
|
||||
#if CONFIG_REF_MV
|
||||
if (mbmi->mode == NEARMV) {
|
||||
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
|
||||
if (xd->ref_mv_count[ref_frame_type] > 2) {
|
||||
if (vpx_read_bit(r)) {
|
||||
mbmi->ref_mv_idx = 1;
|
||||
if (xd->ref_mv_count[ref_frame_type] > 3)
|
||||
if (vpx_read_bit(r))
|
||||
mbmi->ref_mv_idx = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mbmi->mode == NEARMV)
|
||||
read_drl_idx(cm, xd, mbmi, r);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,6 +177,28 @@ static void write_inter_mode(VP10_COMMON *cm,
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_REF_MV
|
||||
static void write_drl_idx(const VP10_COMMON *cm,
|
||||
const MB_MODE_INFO *mbmi,
|
||||
const MB_MODE_INFO_EXT *mbmi_ext,
|
||||
vpx_writer *w) {
|
||||
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
|
||||
if (mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
|
||||
uint8_t drl0_ctx =
|
||||
vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 0);
|
||||
vpx_prob drl0_prob = cm->fc->drl_prob0[drl0_ctx];
|
||||
vpx_write(w, mbmi->ref_mv_idx != 0, drl0_prob);
|
||||
if (mbmi_ext->ref_mv_count[ref_frame_type] > 3 &&
|
||||
mbmi->ref_mv_idx > 0) {
|
||||
uint8_t drl1_ctx =
|
||||
vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
|
||||
vpx_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx];
|
||||
vpx_write(w, mbmi->ref_mv_idx != 1, drl1_prob);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_INTER
|
||||
static void write_inter_compound_mode(VP10_COMMON *cm, vpx_writer *w,
|
||||
PREDICTION_MODE mode,
|
||||
@@ -312,7 +334,12 @@ static void update_inter_mode_probs(VP10_COMMON *cm, vpx_writer *w,
|
||||
for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
|
||||
vp10_cond_prob_diff_update(w, &cm->fc->refmv_prob[i],
|
||||
counts->refmv_mode[i]);
|
||||
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
|
||||
vp10_cond_prob_diff_update(w, &cm->fc->drl_prob0[i],
|
||||
counts->drl_mode0[i]);
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
|
||||
vp10_cond_prob_diff_update(w, &cm->fc->drl_prob1[i],
|
||||
counts->drl_mode1[i]);
|
||||
#if CONFIG_EXT_INTER
|
||||
vp10_cond_prob_diff_update(w, &cm->fc->new2mv_prob, counts->new2mv_mode);
|
||||
#endif // CONFIG_EXT_INTER
|
||||
@@ -994,15 +1021,8 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
|
||||
mode_ctx);
|
||||
|
||||
#if CONFIG_REF_MV
|
||||
if (mode == NEARMV) {
|
||||
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
|
||||
if (mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
|
||||
vpx_write_bit(w, mbmi->ref_mv_idx != 0);
|
||||
if (mbmi_ext->ref_mv_count[ref_frame_type] > 3 &&
|
||||
mbmi->ref_mv_idx > 0)
|
||||
vpx_write_bit(w, mbmi->ref_mv_idx != 1);
|
||||
}
|
||||
}
|
||||
if (mode == NEARMV)
|
||||
write_drl_idx(cm, mbmi, mbmi_ext, w);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1822,6 +1822,28 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td
|
||||
has_second_ref(mbmi),
|
||||
#endif // CONFIG_EXT_INTER
|
||||
mode_ctx);
|
||||
|
||||
if (mode == NEARMV) {
|
||||
uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
|
||||
if (mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
|
||||
uint8_t drl0_ctx =
|
||||
vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 0);
|
||||
if (mbmi->ref_mv_idx == 0)
|
||||
++counts->drl_mode0[drl0_ctx][0];
|
||||
else
|
||||
++counts->drl_mode0[drl0_ctx][1];
|
||||
|
||||
if (mbmi_ext->ref_mv_count[ref_frame_type] > 3 &&
|
||||
mbmi->ref_mv_idx > 0) {
|
||||
uint8_t drl1_ctx =
|
||||
vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
|
||||
if (mbmi->ref_mv_idx == 1)
|
||||
++counts->drl_mode1[drl1_ctx][0];
|
||||
else
|
||||
++counts->drl_mode1[drl1_ctx][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
#if CONFIG_EXT_INTER
|
||||
}
|
||||
#endif // CONFIG_EXT_INTER
|
||||
|
||||
@@ -474,6 +474,8 @@ typedef struct VP10_COMP {
|
||||
int newmv_mode_cost[NEWMV_MODE_CONTEXTS][2];
|
||||
int zeromv_mode_cost[ZEROMV_MODE_CONTEXTS][2];
|
||||
int refmv_mode_cost[REFMV_MODE_CONTEXTS][2];
|
||||
int drl_mode_cost0[DRL_MODE_CONTEXTS][2];
|
||||
int drl_mode_cost1[DRL_MODE_CONTEXTS][2];
|
||||
#if CONFIG_EXT_INTER
|
||||
int new2mv_mode_cost[2];
|
||||
#endif // CONFIG_EXT_INTER
|
||||
|
||||
@@ -382,6 +382,16 @@ void vp10_initialize_rd_consts(VP10_COMP *cpi) {
|
||||
cpi->refmv_mode_cost[i][0] = vp10_cost_bit(cm->fc->refmv_prob[i], 0);
|
||||
cpi->refmv_mode_cost[i][1] = vp10_cost_bit(cm->fc->refmv_prob[i], 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i) {
|
||||
cpi->drl_mode_cost0[i][0] = vp10_cost_bit(cm->fc->drl_prob0[i], 0);
|
||||
cpi->drl_mode_cost0[i][1] = vp10_cost_bit(cm->fc->drl_prob0[i], 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < DRL_MODE_CONTEXTS; ++i) {
|
||||
cpi->drl_mode_cost1[i][0] = vp10_cost_bit(cm->fc->drl_prob1[i], 0);
|
||||
cpi->drl_mode_cost1[i][1] = vp10_cost_bit(cm->fc->drl_prob1[i], 1);
|
||||
}
|
||||
#if CONFIG_EXT_INTER
|
||||
cpi->new2mv_mode_cost[0] = vp10_cost_bit(cm->fc->new2mv_prob, 0);
|
||||
cpi->new2mv_mode_cost[1] = vp10_cost_bit(cm->fc->new2mv_prob, 1);
|
||||
|
||||
@@ -6380,7 +6380,9 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
|
||||
int ref_idx;
|
||||
int ref_set = VPXMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 2);
|
||||
|
||||
rate2 += vp10_cost_bit(128, 0);
|
||||
uint8_t drl0_ctx =
|
||||
vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 0);
|
||||
rate2 += cpi->drl_mode_cost0[drl0_ctx][0];
|
||||
|
||||
if (this_rd < INT64_MAX) {
|
||||
if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
|
||||
@@ -6440,9 +6442,13 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
|
||||
dummy_filter_cache);
|
||||
}
|
||||
|
||||
tmp_rate += vp10_cost_bit(128, 1);
|
||||
if (mbmi_ext->ref_mv_count[ref_frame_type] > 3)
|
||||
tmp_rate += vp10_cost_bit(128, ref_idx);
|
||||
tmp_rate += cpi->drl_mode_cost0[drl0_ctx][1];
|
||||
|
||||
if (mbmi_ext->ref_mv_count[ref_frame_type] > 3) {
|
||||
uint8_t drl1_ctx =
|
||||
vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
|
||||
tmp_rate += cpi->drl_mode_cost1[drl1_ctx][ref_idx];
|
||||
}
|
||||
|
||||
if (tmp_alt_rd < INT64_MAX) {
|
||||
if (RDCOST(x->rdmult, x->rddiv,
|
||||
|
||||
Reference in New Issue
Block a user