Commit e9630de8 authored by Jingning Han's avatar Jingning Han

Unify the entropy coding system for dynamic motion vector referencing

This commit unifies the probability models for the dynamic motion
vector referencing system.

Change-Id: I2b8a5e3da9824b52779a6b8ef43b7a588eade93a
parent cbeab1c7
......@@ -245,7 +245,7 @@ static const aom_prob default_refmv_prob[REFMV_MODE_CONTEXTS] = {
};
static const aom_prob default_drl_prob[DRL_MODE_CONTEXTS] = {
128, 128, 128,
128, 160, 180, 128, 160
};
#endif
......@@ -373,8 +373,7 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->newmv_prob, default_newmv_prob);
av1_copy(fc->zeromv_prob, default_zeromv_prob);
av1_copy(fc->refmv_prob, default_refmv_prob);
av1_copy(fc->drl_prob0, default_drl_prob);
av1_copy(fc->drl_prob1, default_drl_prob);
av1_copy(fc->drl_prob, default_drl_prob);
#endif
av1_copy(fc->inter_mode_probs, default_inter_mode_probs);
#if CONFIG_MISC_FIXES
......@@ -419,11 +418,8 @@ void av1_adapt_inter_frame_probs(AV1_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]);
fc->drl_prob[i] = mode_mv_merge_probs(pre_fc->drl_prob[i],
counts->drl_mode[i]);
#else
for (i = 0; i < INTER_MODE_CONTEXTS; i++)
aom_tree_merge_probs(av1_inter_mode_tree, pre_fc->inter_mode_probs[i],
......
......@@ -62,8 +62,7 @@ typedef struct frame_contexts {
aom_prob newmv_prob[NEWMV_MODE_CONTEXTS];
aom_prob zeromv_prob[ZEROMV_MODE_CONTEXTS];
aom_prob refmv_prob[REFMV_MODE_CONTEXTS];
aom_prob drl_prob0[DRL_MODE_CONTEXTS];
aom_prob drl_prob1[DRL_MODE_CONTEXTS];
aom_prob drl_prob[DRL_MODE_CONTEXTS];
#endif
aom_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1];
......@@ -101,8 +100,7 @@ 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];
unsigned int drl_mode[DRL_MODE_CONTEXTS][2];
#endif
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES];
......
......@@ -137,7 +137,7 @@ typedef uint8_t PREDICTION_MODE;
#define NEWMV_MODE_CONTEXTS 7
#define ZEROMV_MODE_CONTEXTS 2
#define REFMV_MODE_CONTEXTS 9
#define DRL_MODE_CONTEXTS 3
#define DRL_MODE_CONTEXTS 5
#define ZEROMV_OFFSET 3
#define REFMV_OFFSET 4
......
......@@ -378,16 +378,24 @@ static int16_t av1_mode_context_analyzer(const int16_t *const mode_context,
static INLINE uint8_t av1_drl_ctx(const CANDIDATE_MV *ref_mv_stack,
int ref_idx) {
if (ref_mv_stack[ref_idx].weight >= REF_CAT_LEVEL &&
ref_mv_stack[ref_idx + 1].weight >= REF_CAT_LEVEL)
return 0;
ref_mv_stack[ref_idx + 1].weight >= REF_CAT_LEVEL) {
if (ref_mv_stack[ref_idx].weight == ref_mv_stack[ref_idx + 1].weight)
return 0;
else
return 1;
}
if (ref_mv_stack[ref_idx].weight >= REF_CAT_LEVEL &&
ref_mv_stack[ref_idx + 1].weight < REF_CAT_LEVEL)
return 1;
return 2;
if (ref_mv_stack[ref_idx].weight < REF_CAT_LEVEL &&
ref_mv_stack[ref_idx + 1].weight < REF_CAT_LEVEL)
return 2;
ref_mv_stack[ref_idx + 1].weight < REF_CAT_LEVEL) {
if (ref_mv_stack[ref_idx].weight == ref_mv_stack[ref_idx + 1].weight)
return 3;
else
return 4;
}
assert(0);
return 0;
......
......@@ -374,11 +374,7 @@ void av1_accumulate_frame_counts(AV1_COMMON *cm, FRAME_COUNTS *counts,
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];
cm->counts.drl_mode[i][j] += counts->drl_mode[i][j];
#endif
for (i = 0; i < INTER_MODE_CONTEXTS; i++)
......
......@@ -134,9 +134,7 @@ static void read_inter_mode_probs(FRAME_CONTEXT *fc, aom_reader *r) {
for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
av1_diff_update_prob(r, &fc->refmv_prob[i]);
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
av1_diff_update_prob(r, &fc->drl_prob0[i]);
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
av1_diff_update_prob(r, &fc->drl_prob1[i]);
av1_diff_update_prob(r, &fc->drl_prob[i]);
#else
int j;
for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
......
......@@ -117,55 +117,45 @@ static void read_drl_idx(const AV1_COMMON *cm,
uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
mbmi->ref_mv_idx = 0;
if (xd->ref_mv_count[ref_frame_type] > 1 && mbmi->mode == NEWMV) {
uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], 0);
aom_prob drl_prob = cm->fc->drl_prob0[drl_ctx];
if (!aom_read(r, drl_prob)) {
mbmi->ref_mv_idx = 0;
return;
}
mbmi->ref_mv_idx = 1;
if (xd->ref_mv_count[ref_frame_type] > 2) {
drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], 1);
drl_prob = cm->fc->drl_prob0[drl_ctx];
if (!aom_read(r, drl_prob)) {
mbmi->ref_mv_idx = 1;
return;
if (mbmi->mode == NEWMV) {
int idx;
for (idx = 0; idx < 2; ++idx) {
if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
if (!aom_read(r, drl_prob)) {
mbmi->ref_mv_idx = idx;
if (xd->counts)
++xd->counts->drl_mode[drl_ctx][0];
return;
}
mbmi->ref_mv_idx = idx + 1;
if (xd->counts)
++xd->counts->drl_mode[drl_ctx][1];
}
mbmi->ref_mv_idx = 2;
}
return;
}
if (xd->ref_mv_count[ref_frame_type] > 2 && mbmi->mode == NEARMV) {
uint8_t drl0_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], 1);
aom_prob drl0_prob = cm->fc->drl_prob0[drl0_ctx];
if (aom_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 =
av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], 2);
aom_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx];
if (aom_read(r, drl1_prob)) {
mbmi->ref_mv_idx = 2;
if (mbmi->mode == NEARMV) {
int idx;
// Offset the NEARESTMV mode.
// TODO(jingning): Unify the two syntax decoding loops after the NEARESTMV
// mode is factored in.
for (idx = 1; idx < 3; ++idx) {
if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
if (!aom_read(r, drl_prob)) {
mbmi->ref_mv_idx = idx - 1;
if (xd->counts)
++xd->counts->drl_mode1[drl1_ctx][1];
++xd->counts->drl_mode[drl_ctx][0];
return;
}
mbmi->ref_mv_idx = idx;
if (xd->counts)
++xd->counts->drl_mode1[drl1_ctx][0];
++xd->counts->drl_mode[drl_ctx][1];
}
return;
}
if (xd->counts)
++xd->counts->drl_mode0[drl0_ctx][0];
}
}
#endif
......
......@@ -118,39 +118,37 @@ static void write_drl_idx(const AV1_COMMON *cm,
assert(mbmi->ref_mv_idx < 3);
if (mbmi_ext->ref_mv_count[ref_frame_type] > 1 && mbmi->mode == NEWMV) {
uint8_t drl_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 0);
aom_prob drl_prob = cm->fc->drl_prob0[drl_ctx];
aom_write(w, mbmi->ref_mv_idx != 0, drl_prob);
if (mbmi->ref_mv_idx == 0)
return;
if (mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
drl_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
drl_prob = cm->fc->drl_prob0[drl_ctx];
aom_write(w, mbmi->ref_mv_idx != 1, drl_prob);
if (mbmi->mode == NEWMV) {
int idx;
for (idx = 0; idx < 2; ++idx) {
if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
uint8_t drl_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
aom_write(w, mbmi->ref_mv_idx != idx, drl_prob);
if (mbmi->ref_mv_idx == idx)
return;
}
}
if (mbmi->ref_mv_idx == 1)
return;
assert(mbmi->ref_mv_idx == 2);
return;
}
if (mbmi_ext->ref_mv_count[ref_frame_type] > 2 && mbmi->mode == NEARMV) {
uint8_t drl0_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
aom_prob drl0_prob = cm->fc->drl_prob0[drl0_ctx];
aom_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 =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 2);
aom_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx];
aom_write(w, mbmi->ref_mv_idx != 1, drl1_prob);
if (mbmi->mode == NEARMV) {
int idx;
// TODO(jingning): Temporary solution to compensate the NEARESTMV offset.
for (idx = 1; idx < 3; ++idx) {
if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
uint8_t drl_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
aom_write(w, mbmi->ref_mv_idx != (idx - 1), drl_prob);
if (mbmi->ref_mv_idx == (idx - 1))
return;
}
}
return;
}
}
#endif
......@@ -221,11 +219,8 @@ static void update_inter_mode_probs(AV1_COMMON *cm, aom_writer *w,
av1_cond_prob_diff_update(w, &cm->fc->refmv_prob[i],
counts->refmv_mode[i]);
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
av1_cond_prob_diff_update(w, &cm->fc->drl_prob0[i],
counts->drl_mode0[i]);
for (i = 0; i < DRL_MODE_CONTEXTS; ++i)
av1_cond_prob_diff_update(w, &cm->fc->drl_prob1[i],
counts->drl_mode1[i]);
av1_cond_prob_diff_update(w, &cm->fc->drl_prob[i],
counts->drl_mode[i]);
}
#endif
......
......@@ -1261,24 +1261,34 @@ static void update_stats(AV1_COMMON *cm, ThreadData *td) {
mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
mbmi->ref_frame, bsize, -1);
update_inter_mode_stats(counts, mode, mode_ctx);
if (mode == NEWMV) {
uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
int idx;
for (idx = 0; idx < 2; ++idx) {
if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
uint8_t drl_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx];
if (mbmi->ref_mv_idx == idx)
break;
}
}
}
if (mode == NEARMV) {
uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
if (mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
uint8_t drl0_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
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 =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 2);
if (mbmi->ref_mv_idx == 1)
++counts->drl_mode1[drl1_ctx][0];
else
++counts->drl_mode1[drl1_ctx][1];
int idx;
for (idx = 1; idx < 3; ++idx) {
if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
uint8_t drl_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx);
++counts->drl_mode[drl_ctx][mbmi->ref_mv_idx != idx - 1];
if (mbmi->ref_mv_idx == idx - 1)
break;
}
}
}
......
......@@ -465,8 +465,7 @@ typedef struct AV1_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];
int drl_mode_cost[DRL_MODE_CONTEXTS][2];
#endif
int mbmode_cost[INTRA_MODES];
......
......@@ -338,13 +338,8 @@ void av1_initialize_rd_consts(AV1_COMP *cpi) {
cpi->refmv_mode_cost[i][1] = av1_cost_bit(cm->fc->refmv_prob[i], 1);
}
for (i = 0; i < DRL_MODE_CONTEXTS; ++i) {
cpi->drl_mode_cost0[i][0] = av1_cost_bit(cm->fc->drl_prob0[i], 0);
cpi->drl_mode_cost0[i][1] = av1_cost_bit(cm->fc->drl_prob0[i], 1);
}
for (i = 0; i < DRL_MODE_CONTEXTS; ++i) {
cpi->drl_mode_cost1[i][0] = av1_cost_bit(cm->fc->drl_prob1[i], 0);
cpi->drl_mode_cost1[i][1] = av1_cost_bit(cm->fc->drl_prob1[i], 1);
cpi->drl_mode_cost[i][0] = av1_cost_bit(cm->fc->drl_prob[i], 0);
cpi->drl_mode_cost[i][1] = av1_cost_bit(cm->fc->drl_prob[i], 1);
}
#else
for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
......
......@@ -3321,15 +3321,12 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
uint8_t backup_zcoeff_blk[256];
int64_t tmp_ref_rd = this_rd;
int ref_idx;
// TODO(jingning): This should be deprecated shortly.
int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0;
int ref_set =
AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 1 - idx_offset);
uint8_t drl0_ctx = 0;
uint8_t drl_ctx = 0;
uint8_t drl_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
idx_offset);
// Dummy
int_mv backup_fmv[2];
......@@ -3340,13 +3337,7 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
memcpy(backup_zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
sizeof(backup_zcoeff_blk[0]) * ctx->num_4x4_blk);
if (mbmi->mode == NEARMV) {
drl0_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
rate2 += cpi->drl_mode_cost0[drl0_ctx][0];
} else {
drl_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 0);
rate2 += cpi->drl_mode_cost0[drl_ctx][0];
}
rate2 += cpi->drl_mode_cost[drl_ctx][0];
if (this_rd < INT64_MAX) {
if (RDCOST(x->rdmult, x->rddiv,
......@@ -3408,23 +3399,20 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
dummy_filter_cache);
}
if (this_mode == NEARMV) {
tmp_rate += cpi->drl_mode_cost0[drl0_ctx][1];
if (mbmi_ext->ref_mv_count[ref_frame_type] > 3) {
uint8_t drl1_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 2);
tmp_rate += cpi->drl_mode_cost1[drl1_ctx][ref_idx];
}
for (i = 0; i < mbmi->ref_mv_idx; ++i) {
uint8_t drl1_ctx = 0;
drl1_ctx = av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
i + idx_offset);
tmp_rate += cpi->drl_mode_cost[drl1_ctx][1];
}
if (this_mode == NEWMV) {
tmp_rate += cpi->drl_mode_cost0[drl_ctx][1];
if (mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
uint8_t this_drl_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1);
tmp_rate += cpi->drl_mode_cost0[this_drl_ctx][ref_idx];
}
if (mbmi_ext->ref_mv_count[ref_frame_type] >
mbmi->ref_mv_idx + idx_offset + 1 &&
ref_idx < ref_set - 1) {
uint8_t drl1_ctx =
av1_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type],
mbmi->ref_mv_idx + idx_offset);
tmp_rate += cpi->drl_mode_cost[drl1_ctx][0];
}
if (tmp_alt_rd < INT64_MAX) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment