summaryrefslogtreecommitdiff
path: root/vp9/common
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2012-11-12 15:09:25 +0000
committerPaul Wilkins <paulwilkins@google.com>2012-11-12 15:50:02 +0000
commit2669f42b0d50bcff236176584caf623585e487b7 (patch)
tree5a17fb6160809e0577698226d26d621674a4eb76 /vp9/common
parent6fb8953c190430bbc324b57efa0297f6a612d7c7 (diff)
downloadlibvpx-2669f42b0d50bcff236176584caf623585e487b7.tar
libvpx-2669f42b0d50bcff236176584caf623585e487b7.tar.gz
libvpx-2669f42b0d50bcff236176584caf623585e487b7.tar.bz2
libvpx-2669f42b0d50bcff236176584caf623585e487b7.zip
New inter mode context
This change is a fix / extension of the newbestrefmv experiment. As such it is presented without IFDEF. The change creates a new context for coding inter modes in vp9_find_mv_refs(). This replaces the context that was previously calculated in vp9_find_near_mvs(). The new context is unoptimized and not necessarily any better at this stage (results pending), but eliminates the need for a legacy call to vp9_find_near_mvs(). Based on numbers from Scott, this could help decode speed by several %. In a later patch I will add support for forward update of context (assuming this helps) and refine the context as necessary. Change-Id: I1cd991b82c8df86cc02237a34185e6d67510698a
Diffstat (limited to 'vp9/common')
-rw-r--r--vp9/common/blockd.h2
-rw-r--r--vp9/common/entropymode.c20
-rw-r--r--vp9/common/entropymode.h2
-rw-r--r--vp9/common/findnearmv.c139
-rw-r--r--vp9/common/findnearmv.h10
-rw-r--r--vp9/common/modecont.c61
-rw-r--r--vp9/common/mvref_common.c26
-rw-r--r--vp9/common/onyxc_int.h11
8 files changed, 65 insertions, 206 deletions
diff --git a/vp9/common/blockd.h b/vp9/common/blockd.h
index 300c01f96..0cfa9dcff 100644
--- a/vp9/common/blockd.h
+++ b/vp9/common/blockd.h
@@ -231,6 +231,8 @@ typedef struct {
int_mv mv[2]; // for each reference frame used
int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REFS];
+ int mb_mode_context[MAX_REF_FRAMES];
+
SPLITMV_PARTITIONING_TYPE partitioning;
unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */
unsigned char need_to_clamp_mvs;
diff --git a/vp9/common/entropymode.c b/vp9/common/entropymode.c
index 37d09db9e..d0e83ecb2 100644
--- a/vp9/common/entropymode.c
+++ b/vp9/common/entropymode.c
@@ -451,7 +451,7 @@ void vp9_init_mode_contexts(VP9_COMMON *pc) {
void vp9_accum_mv_refs(VP9_COMMON *pc,
MB_PREDICTION_MODE m,
- const int ct[4]) {
+ const int context) {
int (*mv_ref_ct)[4][2];
if (pc->refresh_alt_ref_frame)
@@ -460,21 +460,21 @@ void vp9_accum_mv_refs(VP9_COMMON *pc,
mv_ref_ct = pc->fc.mv_ref_ct;
if (m == ZEROMV) {
- ++mv_ref_ct [ct[0]] [0] [0];
+ ++mv_ref_ct[context][0][0];
} else {
- ++mv_ref_ct [ct[0]] [0] [1];
+ ++mv_ref_ct[context][0][1];
if (m == NEARESTMV) {
- ++mv_ref_ct [ct[1]] [1] [0];
+ ++mv_ref_ct[context][1][0];
} else {
- ++mv_ref_ct [ct[1]] [1] [1];
+ ++mv_ref_ct[context][1][1];
if (m == NEARMV) {
- ++mv_ref_ct [ct[2]] [2] [0];
+ ++mv_ref_ct[context][2][0];
} else {
- ++mv_ref_ct [ct[2]] [2] [1];
+ ++mv_ref_ct[context][2][1];
if (m == NEWMV) {
- ++mv_ref_ct [ct[3]] [3] [0];
+ ++mv_ref_ct[context][3][0];
} else {
- ++mv_ref_ct [ct[3]] [3] [1];
+ ++mv_ref_ct[context][3][1];
}
}
}
@@ -496,7 +496,7 @@ void vp9_update_mode_context(VP9_COMMON *pc) {
mode_context = pc->fc.mode_context;
}
- for (j = 0; j < 6; j++) {
+ for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
for (i = 0; i < 4; i++) {
int this_prob;
int count = mv_ref_ct[j][i][0] + mv_ref_ct[j][i][1];
diff --git a/vp9/common/entropymode.h b/vp9/common/entropymode.h
index 02975918e..34a2bea03 100644
--- a/vp9/common/entropymode.h
+++ b/vp9/common/entropymode.h
@@ -79,7 +79,7 @@ extern void vp9_update_mode_context(struct VP9Common *pc);
extern void vp9_accum_mv_refs(struct VP9Common *pc,
MB_PREDICTION_MODE m,
- const int ct[4]);
+ const int context);
void vp9_default_bmode_probs(vp9_prob dest[VP9_NKF_BINTRAMODES - 1]);
diff --git a/vp9/common/findnearmv.c b/vp9/common/findnearmv.c
index 84a377e75..8cc0474a7 100644
--- a/vp9/common/findnearmv.c
+++ b/vp9/common/findnearmv.c
@@ -31,140 +31,13 @@ static void lower_mv_precision(int_mv *mv, int usehp)
}
}
-/* Predict motion vectors using those from already-decoded nearby blocks.
- Note that we only consider one 4x4 subblock from each candidate 16x16
- macroblock. */
-
-void vp9_find_near_mvs
-(
- MACROBLOCKD *xd,
- const MODE_INFO *here,
- const MODE_INFO *lf_here,
- int_mv *nearest,
- int_mv *nearby,
- int_mv *best_mv,
- int cnt[4],
- int refframe,
- int *ref_frame_sign_bias) {
- const MODE_INFO *above = here - xd->mode_info_stride;
- const MODE_INFO *left = here - 1;
- const MODE_INFO *aboveleft = above - 1;
- const MODE_INFO *third = NULL;
- int_mv near_mvs[4];
- int_mv *mv = near_mvs;
- int *cntx = cnt;
- enum {CNT_INTRA, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV};
-
- /* Zero accumulators */
- mv[0].as_int = mv[1].as_int = mv[2].as_int = 0;
- cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
-
- /* Process above */
- if (above->mbmi.ref_frame != INTRA_FRAME) {
- if (above->mbmi.mv[0].as_int) {
- ++ mv;
- mv->as_int = above->mbmi.mv[0].as_int;
- mv_bias(ref_frame_sign_bias[above->mbmi.ref_frame],
- refframe, mv, ref_frame_sign_bias);
- ++cntx;
- }
- *cntx += 2;
- }
-
- /* Process left */
- if (left->mbmi.ref_frame != INTRA_FRAME) {
- if (left->mbmi.mv[0].as_int) {
- int_mv this_mv;
- this_mv.as_int = left->mbmi.mv[0].as_int;
- mv_bias(ref_frame_sign_bias[left->mbmi.ref_frame],
- refframe, &this_mv, ref_frame_sign_bias);
-
- if (this_mv.as_int != mv->as_int) {
- ++ mv;
- mv->as_int = this_mv.as_int;
- ++ cntx;
- }
- *cntx += 2;
- } else
- cnt[CNT_INTRA] += 2;
- }
- /* Process above left or the one from last frame */
- if (aboveleft->mbmi.ref_frame != INTRA_FRAME ||
- (lf_here->mbmi.ref_frame == LAST_FRAME && refframe == LAST_FRAME)) {
- if (aboveleft->mbmi.mv[0].as_int) {
- third = aboveleft;
- } else if (lf_here->mbmi.mv[0].as_int) {
- third = lf_here;
- }
- if (third) {
- int_mv this_mv;
- this_mv.as_int = third->mbmi.mv[0].as_int;
- mv_bias(ref_frame_sign_bias[third->mbmi.ref_frame],
- refframe, &this_mv, ref_frame_sign_bias);
-
- if (this_mv.as_int != mv->as_int) {
- ++ mv;
- mv->as_int = this_mv.as_int;
- ++ cntx;
- }
- *cntx += 1;
- } else
- cnt[CNT_INTRA] += 1;
- }
-
- /* If we have three distinct MV's ... */
- if (cnt[CNT_SPLITMV]) {
- /* See if the third MV can be merged with NEAREST */
- if (mv->as_int == near_mvs[CNT_NEAREST].as_int)
- cnt[CNT_NEAREST] += 1;
- }
-
- cnt[CNT_SPLITMV] = ((above->mbmi.mode == SPLITMV)
- + (left->mbmi.mode == SPLITMV)) * 2
- + (
- lf_here->mbmi.mode == SPLITMV ||
- aboveleft->mbmi.mode == SPLITMV);
-
- /* Swap near and nearest if necessary */
- if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
- int tmp;
- tmp = cnt[CNT_NEAREST];
- cnt[CNT_NEAREST] = cnt[CNT_NEAR];
- cnt[CNT_NEAR] = tmp;
- tmp = near_mvs[CNT_NEAREST].as_int;
- near_mvs[CNT_NEAREST].as_int = near_mvs[CNT_NEAR].as_int;
- near_mvs[CNT_NEAR].as_int = tmp;
- }
-
- /* Use near_mvs[0] to store the "best" MV */
- if (cnt[CNT_NEAREST] >= cnt[CNT_INTRA])
- near_mvs[CNT_INTRA] = near_mvs[CNT_NEAREST];
-
- /* Set up return values */
- best_mv->as_int = near_mvs[0].as_int;
- nearest->as_int = near_mvs[CNT_NEAREST].as_int;
- nearby->as_int = near_mvs[CNT_NEAR].as_int;
-
- /* Make sure that the 1/8th bits of the Mvs are zero if high_precision
- * is not being used, by truncating the last bit towards 0
- */
- lower_mv_precision(best_mv, xd->allow_high_precision_mv);
- lower_mv_precision(nearest, xd->allow_high_precision_mv);
- lower_mv_precision(nearby, xd->allow_high_precision_mv);
-
- // TODO: move clamp outside findnearmv
- clamp_mv2(nearest, xd);
- clamp_mv2(nearby, xd);
- clamp_mv2(best_mv, xd);
-}
-
vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc,
- vp9_prob p[VP9_MVREFS - 1],
- const int near_mv_ref_ct[4]) {
- p[0] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[0]][0];
- p[1] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[1]][1];
- p[2] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[2]][2];
- p[3] = pc->fc.vp9_mode_contexts[near_mv_ref_ct[3]][3];
+ vp9_prob p[4], const int context
+ ) {
+ p[0] = pc->fc.vp9_mode_contexts[context][0];
+ p[1] = pc->fc.vp9_mode_contexts[context][1];
+ p[2] = pc->fc.vp9_mode_contexts[context][2];
+ p[3] = pc->fc.vp9_mode_contexts[context][3];
return p;
}
diff --git a/vp9/common/findnearmv.h b/vp9/common/findnearmv.h
index c53575ea9..64233ec23 100644
--- a/vp9/common/findnearmv.h
+++ b/vp9/common/findnearmv.h
@@ -79,17 +79,9 @@ static unsigned int check_mv_bounds(int_mv *mv,
(mv->as_mv.row > mb_to_bottom_edge);
}
-void vp9_find_near_mvs(MACROBLOCKD *xd,
- const MODE_INFO *here,
- const MODE_INFO *lfhere,
- int_mv *nearest, int_mv *nearby, int_mv *best,
- int near_mv_ref_cts[4],
- int refframe,
- int *ref_frame_sign_bias);
-
vp9_prob *vp9_mv_ref_probs(VP9_COMMON *pc,
vp9_prob p[VP9_MVREFS - 1],
- const int near_mv_ref_ct[4]);
+ const int context);
extern const unsigned char vp9_mbsplit_offset[4][16];
diff --git a/vp9/common/modecont.c b/vp9/common/modecont.c
index 023d201f1..ac6719a1b 100644
--- a/vp9/common/modecont.c
+++ b/vp9/common/modecont.c
@@ -10,55 +10,20 @@
#include "entropy.h"
+
const int vp9_default_mode_contexts[6][4] = {
- {
- /* 0 */
- 7, 1, 1, 183
- },
- {
- /* 1 */
- 14, 18, 14, 147
- },
- {
- /* 2 */
- 135, 64, 57, 68
- },
- {
- /* 3 */
- 60, 56, 128, 65
- },
- {
- /* 4 */
- 159, 134, 128, 34
- },
- {
- /* 5 */
- 234, 188, 128, 28
- },
+ {117, 1, 1, 141},
+ {234, 1, 1, 213},
+ {128, 90, 22, 145},
+ {30, 104, 61, 159},
+ {13, 169, 18, 206},
+ {15, 76, 24, 166}
};
const int vp9_default_mode_contexts_a[6][4] = {
- {
- /* 0 */
- 4, 1, 1, 143
- },
- {
- /* 1 */
- 7, 9, 7, 107
- },
- {
- /* 2 */
- 95, 34, 57, 68
- },
- {
- /* 3 */
- 95, 56, 128, 65
- },
- {
- /* 4 */
- 159, 67, 128, 34
- },
- {
- /* 5 */
- 234, 94, 128, 28
- },
+ {117, 1, 1, 141},
+ {234, 1, 1, 213},
+ {128, 90, 22, 145},
+ {30, 104, 61, 159},
+ {13, 169, 18, 206},
+ {15, 76, 24, 166}
};
diff --git a/vp9/common/mvref_common.c b/vp9/common/mvref_common.c
index 67f2fb0fb..a412a6c8a 100644
--- a/vp9/common/mvref_common.c
+++ b/vp9/common/mvref_common.c
@@ -214,6 +214,7 @@ void vp9_find_mv_refs(
int i;
MODE_INFO *candidate_mi;
+ MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
int_mv candidate_mvs[MAX_MV_REFS];
int_mv c_refmv;
MV_REFERENCE_FRAME c_ref_frame;
@@ -328,6 +329,31 @@ void vp9_find_mv_refs(
index = (MAX_MV_REFS - 1);
}
+ if (candidate_mvs[0].as_int == 0) {
+ // 0,0 was best
+ if (index == 0) {
+ // No reference candidates
+ mbmi->mb_mode_context[ref_frame] = 0;
+ } else if (index == 1) {
+ // 0,0 was only candidate
+ mbmi->mb_mode_context[ref_frame] = 1;
+ } else {
+ // Other candidates available
+ mbmi->mb_mode_context[ref_frame] = 2;
+ }
+ } else if (candidate_scores[0] >= 32) {
+ if (candidate_scores[1] >= 16) {
+ // Strong primary and strong or moderate secondary candidate
+ mbmi->mb_mode_context[ref_frame] = 3;
+ } else {
+ // Strong primary but weak secondary candidate
+ mbmi->mb_mode_context[ref_frame] = 4;
+ }
+ } else {
+ // Weak or moderate candidates
+ mbmi->mb_mode_context[ref_frame] = 5;
+ }
+
// 0,0 is always a valid reference.
for (i = 0; i < index; ++i)
if (candidate_mvs[i].as_int == 0)
diff --git a/vp9/common/onyxc_int.h b/vp9/common/onyxc_int.h
index de814705b..516bea3cc 100644
--- a/vp9/common/onyxc_int.h
+++ b/vp9/common/onyxc_int.h
@@ -42,6 +42,7 @@ void vp9_initialize_common(void);
#define NUM_YV12_BUFFERS 4
#define COMP_PRED_CONTEXTS 2
+#define INTER_MODE_CONTEXTS 6
typedef struct frame_contexts {
vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1];
@@ -106,11 +107,11 @@ typedef struct frame_contexts {
vp9_prob switchable_interp_prob[VP9_SWITCHABLE_FILTERS + 1]
[VP9_SWITCHABLE_FILTERS - 1];
- int mode_context[6][4];
- int mode_context_a[6][4];
- int vp9_mode_contexts[6][4];
- int mv_ref_ct[6][4][2];
- int mv_ref_ct_a[6][4][2];
+ int mode_context[INTER_MODE_CONTEXTS][4];
+ int mode_context_a[INTER_MODE_CONTEXTS][4];
+ int vp9_mode_contexts[INTER_MODE_CONTEXTS][4];
+ int mv_ref_ct[INTER_MODE_CONTEXTS][4][2];
+ int mv_ref_ct_a[INTER_MODE_CONTEXTS][4][2];
} FRAME_CONTEXT;
typedef enum {