Commit 8a13bbe8 authored by Jingning Han's avatar Jingning Han
Browse files

Enable entropy coding of the dynamic motion vector referencing syntax

This commit enables entropy coding of the syntax elements used in
the dynamic motion vector referencing system.

Change-Id: If876c7df6402caf4b6daa3d511328da522e95233
parent c443f820
......@@ -243,6 +243,10 @@ static const aom_prob default_zeromv_prob[ZEROMV_MODE_CONTEXTS] = {
static const aom_prob default_refmv_prob[REFMV_MODE_CONTEXTS] = {
220, 220, 200, 200, 180, 128, 30, 220, 30,
};
static const aom_prob default_drl_prob[DRL_MODE_CONTEXTS] = {
128, 128, 128,
};
#endif
static const aom_prob
......@@ -369,6 +373,8 @@ 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);
#endif
av1_copy(fc->inter_mode_probs, default_inter_mode_probs);
#if CONFIG_MISC_FIXES
......@@ -412,6 +418,12 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
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]);
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]);
#else
for (i = 0; i < INTER_MODE_CONTEXTS; i++)
aom_tree_merge_probs(av1_inter_mode_tree, pre_fc->inter_mode_probs[i],
......
......@@ -62,6 +62,8 @@ 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];
#endif
aom_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1];
......@@ -95,6 +97,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];
#endif
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES];
......
......@@ -135,6 +135,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 ZEROMV_OFFSET 3
#define REFMV_OFFSET 4
......@@ -156,6 +157,7 @@ typedef uint8_t PREDICTION_MODE;
#if CONFIG_REF_MV
#define MAX_REF_MV_STACK_SIZE 16
#define REF_CAT_LEVEL 160
#endif
#define INTRA_INTER_CONTEXTS 4
......
......@@ -318,6 +318,9 @@ static void setup_ref_mv_list(const AV1_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;
......
......@@ -351,6 +351,24 @@ static int16_t av1_mode_context_analyzer(const int16_t *const mode_context,
else
return mode_context[rf[0]];
}
static INLINE uint8_t av1_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);
......
......@@ -371,6 +371,14 @@ void av1_accumulate_frame_counts(AV1_COMMON *cm, FRAME_COUNTS *counts,
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];
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];
#endif
for (i = 0; i < INTER_MODE_CONTEXTS; i++)
......
......@@ -133,6 +133,10 @@ static void read_inter_mode_probs(FRAME_CONTEXT *fc, aom_reader *r) {
av1_diff_update_prob(r, &fc->zeromv_prob[i]);
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]);
#else
int j;
for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
......
......@@ -109,6 +109,45 @@ static PREDICTION_MODE read_inter_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
#endif
}
#if CONFIG_REF_MV
static void read_drl_idx(const AV1_COMMON *cm,
MACROBLOCKD *xd,
MB_MODE_INFO *mbmi,
aom_reader *r) {
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] > 2) {
uint8_t drl0_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], 0);
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], 1);
aom_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx];
if (aom_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
static int read_segment_id(aom_reader *r,
const struct segmentation_probs *segp) {
return aom_read_tree(r, av1_segment_tree, segp->tree_probs);
......@@ -613,17 +652,8 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
if (bsize >= BLOCK_8X8) {
mbmi->mode = read_inter_mode(cm, xd, r, mode_ctx);
#if CONFIG_REF_MV
if (mbmi->mode == NEARMV) {
uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
if (xd->ref_mv_count[ref_frame_type] > 2) {
if (aom_read_bit(r)) {
mbmi->ref_mv_idx = 1;
if (xd->ref_mv_count[ref_frame_type] > 3)
if (aom_read_bit(r))
mbmi->ref_mv_idx = 2;
}
}
}
if (mbmi->mode == NEARMV)
read_drl_idx(cm, xd, mbmi, r);
#endif
}
}
......
......@@ -109,6 +109,28 @@ static void write_inter_mode(AV1_COMMON *cm,
#endif
}
#if CONFIG_REF_MV
static void write_drl_idx(const AV1_COMMON *cm,
const MB_MODE_INFO *mbmi,
const MB_MODE_INFO_EXT *mbmi_ext,
aom_writer *w) {
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], 0);
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], 1);
aom_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx];
aom_write(w, mbmi->ref_mv_idx != 1, drl1_prob);
}
}
}
#endif
static void encode_unsigned_max(struct aom_write_bit_buffer *wb, int data,
int max) {
aom_wb_write_literal(wb, data, get_unsigned_bits(max));
......@@ -174,6 +196,12 @@ static void update_inter_mode_probs(AV1_COMMON *cm, aom_writer *w,
for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
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]);
}
#endif
......@@ -444,15 +472,8 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const MODE_INFO *mi,
if (bsize >= BLOCK_8X8) {
write_inter_mode(cm, w, mode, mode_ctx);
#if CONFIG_REF_MV
if (mode == NEARMV) {
const uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
if (mbmi_ext->ref_mv_count[ref_frame_type] > 2) {
aom_write_bit(w, mbmi->ref_mv_idx != 0);
if (mbmi_ext->ref_mv_count[ref_frame_type] > 3 &&
mbmi->ref_mv_idx > 0)
aom_write_bit(w, mbmi->ref_mv_idx != 1);
}
}
if (mode == NEARMV)
write_drl_idx(cm, mbmi, mbmi_ext, w);
#endif
}
}
......
......@@ -1241,6 +1241,27 @@ 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 == 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], 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 =
av1_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];
}
}
}
#else
++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
#endif
......
......@@ -454,6 +454,8 @@ 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];
#endif
int mbmode_cost[INTRA_MODES];
......
......@@ -310,6 +310,15 @@ void av1_initialize_rd_consts(AV1_COMP *cpi) {
cpi->refmv_mode_cost[i][0] = av1_cost_bit(cm->fc->refmv_prob[i], 0);
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);
}
#else
for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
av1_cost_tokens((int *)cpi->inter_mode_cost[i],
......
......@@ -3265,7 +3265,10 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
int64_t tmp_ref_rd = this_rd;
int ref_idx;
int ref_set = AOMMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 2);
rate2 += av1_cost_bit(128, 0);
uint8_t drl0_ctx =
av1_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,
......@@ -3313,9 +3316,13 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
dummy_filter_cache);
}
tmp_rate += av1_cost_bit(128, 1);
if (mbmi_ext->ref_mv_count[ref_frame_type] > 3)
tmp_rate += av1_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 =
av1_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,
......
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