diff --git a/vp10/common/entropymode.c b/vp10/common/entropymode.c index d48679e0628a292dc09bc9185142e951c69ac1cb..d758548d412c527b462522684e6f6bde6a13a54f 100644 --- a/vp10/common/entropymode.c +++ b/vp10/common/entropymode.c @@ -186,7 +186,7 @@ static const vpx_prob default_refmv_prob[REFMV_MODE_CONTEXTS] = { }; static const vpx_prob default_drl_prob[DRL_MODE_CONTEXTS] = { - 128, 128, 128, + 128, 160, 180, 128, 160 }; #if CONFIG_EXT_INTER @@ -1323,8 +1323,7 @@ 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); + vp10_copy(fc->drl_prob, default_drl_prob); #if CONFIG_EXT_INTER fc->new2mv_prob = default_new2mv_prob; #endif // CONFIG_EXT_INTER @@ -1408,12 +1407,8 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) { 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]); #if CONFIG_EXT_INTER fc->new2mv_prob = mode_mv_merge_probs(pre_fc->new2mv_prob, counts->new2mv_mode); diff --git a/vp10/common/entropymode.h b/vp10/common/entropymode.h index 2443d60f81149f948af928d6aebe769e2baa05fb..ba93ea7e1743ecb50209bcc8b61600986bcf8af1 100644 --- a/vp10/common/entropymode.h +++ b/vp10/common/entropymode.h @@ -55,8 +55,7 @@ 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]; + vpx_prob drl_prob[DRL_MODE_CONTEXTS]; #if CONFIG_EXT_INTER vpx_prob new2mv_prob; @@ -121,8 +120,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]; #if CONFIG_EXT_INTER unsigned int new2mv_mode[2]; #endif // CONFIG_EXT_INTER diff --git a/vp10/common/enums.h b/vp10/common/enums.h index 87bcc8a71cce5934dd9d0ff3418d6b70d68f576e..3a0038153c188d1175fcac64644a5d8ed23b5a90 100644 --- a/vp10/common/enums.h +++ b/vp10/common/enums.h @@ -247,7 +247,7 @@ typedef enum { #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 diff --git a/vp10/common/mvref_common.h b/vp10/common/mvref_common.h index bc6d824326cc966e2c3b41c1b3b719a03d8a2f9b..4834866dc41c2b46ec8c6c89d2435c0b04bb2182 100644 --- a/vp10/common/mvref_common.h +++ b/vp10/common/mvref_common.h @@ -289,16 +289,24 @@ static INLINE int16_t vp10_mode_context_analyzer( static INLINE uint8_t vp10_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; diff --git a/vp10/common/thread_common.c b/vp10/common/thread_common.c index f8bfc899f080f3a9ffe791c1eb507dbbc16fcb42..66e788b0d3bdd56b51359c2caa70c95effd08d58 100644 --- a/vp10/common/thread_common.c +++ b/vp10/common/thread_common.c @@ -387,11 +387,7 @@ void vp10_accumulate_frame_counts(VP10_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]; #if CONFIG_EXT_INTER for (j = 0; j < 2; ++j) diff --git a/vp10/decoder/decodeframe.c b/vp10/decoder/decodeframe.c index 84b01e0b2bc469cb32165a618cba71a38295ee06..a253689f3704a0108d10ab3aa514f9fc491f229f 100644 --- a/vp10/decoder/decodeframe.c +++ b/vp10/decoder/decodeframe.c @@ -117,9 +117,7 @@ static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) { 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]); + vp10_diff_update_prob(r, &fc->drl_prob[i]); #if CONFIG_EXT_INTER vp10_diff_update_prob(r, &fc->new2mv_prob); #endif // CONFIG_EXT_INTER diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c index f52fae4706da35414d928ece508e69a357ad1984..456451232dc73aa7980747ea39c0f4c22466f84b 100644 --- a/vp10/decoder/decodemv.c +++ b/vp10/decoder/decodemv.c @@ -155,55 +155,45 @@ static void read_drl_idx(const VP10_COMMON *cm, 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] > 1 && mbmi->mode == NEWMV) { - uint8_t drl_ctx = vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], 0); - vpx_prob drl_prob = cm->fc->drl_prob0[drl_ctx]; - - if (!vpx_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 = vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], 1); - drl_prob = cm->fc->drl_prob0[drl_ctx]; - if (!vpx_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 = vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx); + vpx_prob drl_prob = cm->fc->drl_prob[drl_ctx]; + if (!vpx_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 = vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], 1); - 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], 2); - vpx_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx]; - if (vpx_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 = vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx); + vpx_prob drl_prob = cm->fc->drl_prob[drl_ctx]; + if (!vpx_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 diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index 386a17e877de772eac3e8a5a4a52a14111ba152a..40840a56586e84a2fb0c3423760c134ede030751 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -196,39 +196,37 @@ static void write_drl_idx(const VP10_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 = - vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 0); - vpx_prob drl_prob = cm->fc->drl_prob0[drl_ctx]; - - vpx_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 = vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1); - drl_prob = cm->fc->drl_prob0[drl_ctx]; - vpx_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 = + vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx); + vpx_prob drl_prob = cm->fc->drl_prob[drl_ctx]; + + vpx_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 = - vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1); - 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], 2); - vpx_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx]; - vpx_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 = + vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], idx); + vpx_prob drl_prob = cm->fc->drl_prob[drl_ctx]; + + vpx_write(w, mbmi->ref_mv_idx != (idx - 1), drl_prob); + if (mbmi->ref_mv_idx == (idx - 1)) + return; + } } + return; } } #endif @@ -368,11 +366,8 @@ static void update_inter_mode_probs(VP10_COMMON *cm, vpx_writer *w, 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]); + vp10_cond_prob_diff_update(w, &cm->fc->drl_prob[i], + counts->drl_mode[i]); #if CONFIG_EXT_INTER vp10_cond_prob_diff_update(w, &cm->fc->new2mv_prob, counts->new2mv_mode); #endif // CONFIG_EXT_INTER diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c index 2c47be9b52355775c3cc7ca46b2634aed34714bd..dafa0723651d93f8b5e4a72d3994d96bc4b9626e 100644 --- a/vp10/encoder/encodeframe.c +++ b/vp10/encoder/encodeframe.c @@ -1909,24 +1909,34 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td #endif // CONFIG_EXT_INTER mode_ctx); + if (mode == NEWMV) { + uint8_t ref_frame_type = vp10_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 = + vp10_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 = 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], 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 = - vp10_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 = + vp10_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; } } } diff --git a/vp10/encoder/encoder.h b/vp10/encoder/encoder.h index a319901e22e1cdce3cfb953b91fce51a143bbf8b..e02bf6c535ca859d63de62b0b3c862284e358d8b 100644 --- a/vp10/encoder/encoder.h +++ b/vp10/encoder/encoder.h @@ -487,7 +487,6 @@ typedef struct VP10_COMP { 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 diff --git a/vp10/encoder/rd.c b/vp10/encoder/rd.c index 78e8e9a36de5b7d37a30e7deacb3e9673cb48be1..8d55ab4b35183dd2d0e538a8ae7dac9a4aade98d 100644 --- a/vp10/encoder/rd.c +++ b/vp10/encoder/rd.c @@ -418,13 +418,8 @@ void vp10_initialize_rd_consts(VP10_COMP *cpi) { } 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); + cpi->drl_mode_cost0[i][0] = vp10_cost_bit(cm->fc->drl_prob[i], 0); + cpi->drl_mode_cost0[i][1] = vp10_cost_bit(cm->fc->drl_prob[i], 1); } #if CONFIG_EXT_INTER cpi->new2mv_mode_cost[0] = vp10_cost_bit(cm->fc->new2mv_prob, 0); diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c index 3d925919644cee62f61052c10fc1e51d12dad7e3..c631d708b196aea82dc3885e4cfbae27401a857a 100644 --- a/vp10/encoder/rdopt.c +++ b/vp10/encoder/rdopt.c @@ -8059,26 +8059,18 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi, // TODO(jingning): This should be deprecated shortly. int idx_offset = (mbmi->mode == NEARMV) ? 1 : 0; - int ref_set = VPXMIN(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 = vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], + idx_offset); // Dummy int_mv backup_fmv[2]; backup_fmv[0] = frame_mv[NEWMV][ref_frame]; if (comp_pred) backup_fmv[1] = frame_mv[NEWMV][second_ref_frame]; - if (mbmi->mode == NEARMV) { - drl0_ctx = vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 1); - rate2 += cpi->drl_mode_cost0[drl0_ctx][0]; - } else { - drl_ctx = vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 0); - rate2 += cpi->drl_mode_cost0[drl_ctx][0]; - } + rate2 += cpi->drl_mode_cost0[drl_ctx][0]; if (this_rd < INT64_MAX) { if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) < @@ -8164,23 +8156,20 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi, &tmp_sse, best_rd); } - 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 = - vp10_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 = vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], + i + idx_offset); + tmp_rate += cpi->drl_mode_cost0[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 = - vp10_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 = + vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], + mbmi->ref_mv_idx + idx_offset); + tmp_rate += cpi->drl_mode_cost0[drl1_ctx][0]; } if (tmp_alt_rd < INT64_MAX) {