ref: 61e2eac61d6c10f8ba49edb9c69559dc95ee81eb
parent: 51bc4bf4a05cf2de8b4e6c035e53b8710d0b17d6
parent: 6ff3eb1647c68c9afcd2e57f184eea5f3d369d57
author: Paul Wilkins <[email protected]>
date: Fri May 17 02:59:09 EDT 2013
Merge "New inter mode context." into experimental
--- a/vp9/common/vp9_modecont.c
+++ b/vp9/common/vp9_modecont.c
@@ -12,11 +12,11 @@
#include "vp9/common/vp9_entropy.h"
const int vp9_default_mode_contexts[INTER_MODE_CONTEXTS][4] = {
- {1, 223, 1, 237}, // 0,0 best: Only candidate
- {87, 166, 26, 219}, // 0,0 best: non zero candidates
- {89, 67, 18, 125}, // 0,0 best: non zero candidates, split
- {16, 141, 69, 226}, // strong nz candidate(s), no split
- {35, 122, 14, 227}, // weak nz candidate(s), no split
- {14, 122, 22, 164}, // strong nz candidate(s), split
- {16, 70, 9, 183}, // weak nz candidate(s), split
+ {2, 173, 34, 229}, // 0 = both zero mv
+ {7, 145, 85, 225}, // 1 = one zero mv + one a predicted mv
+ {7, 166, 63, 231}, // 2 = two predicted mvs
+ {7, 94, 66, 219}, // 3 = one predicted/zero and one new mv
+ {8, 64, 46, 213}, // 4 = two new mvs
+ {17, 81, 31, 231}, // 5 = one intra neighbour + x
+ {25, 29, 30, 246}, // 6 = two intra neighbours
};
--- a/vp9/common/vp9_mvref_common.c
+++ b/vp9/common/vp9_mvref_common.c
@@ -165,6 +165,10 @@
int split_count = 0;
int (*mv_ref_search)[2];
const int mi_col = get_mi_col(xd);
+ int intra_count = 0;
+ int zero_count = 0;
+ int newmv_count = 0;
+
// Blank the reference vector lists and other local structures.
vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
vpx_memset(candidate_scores, 0, sizeof(candidate_scores));
@@ -196,9 +200,24 @@
&refmv_count, c_refmv, 16);
}
split_count += (candidate_mi->mbmi.mode == SPLITMV);
+
+ // Count number of neihgbours coded intra and zeromv
+ intra_count += (candidate_mi->mbmi.mode < NEARESTMV);
+ zero_count += (candidate_mi->mbmi.mode == ZEROMV);
+ newmv_count += (candidate_mi->mbmi.mode >= NEWMV);
}
}
+ // If at this stage wwe have a 0 vector and a non zero vector from the
+ // correct reference frame then make sure that the non zero one is given
+ // precedence as we have other options for coding 0,0
+ /* if (refmv_count == MAX_MV_REF_CANDIDATES) {
+ if (mv_ref_list[1].as_int && !mv_ref_list[0].as_int) {
+ mv_ref_list[0].as_int = mv_ref_list[1].as_int;
+ mv_ref_list[1].as_int = 0;
+ }
+ } */
+
// More distant neigbours
for (i = 2; (i < MVREF_NEIGHBOURS) &&
(refmv_count < MAX_MV_REF_CANDIDATES); ++i) {
@@ -278,24 +297,21 @@
}
}
- // Define inter mode coding context.
- // 0,0 was best
- if (mv_ref_list[0].as_int == 0) {
- // 0,0 is only candidate
- if (refmv_count <= 1) {
- mbmi->mb_mode_context[ref_frame] = 0;
- // non zero candidates candidates available
- } else if (split_count == 0) {
- mbmi->mb_mode_context[ref_frame] = 1;
+ if (!intra_count) {
+ if (!newmv_count) {
+ // 0 = both zero mv
+ // 1 = one zero mv + one a predicted mv
+ // 2 = two predicted mvs
+ mbmi->mb_mode_context[ref_frame] = 2 - zero_count;
} else {
- mbmi->mb_mode_context[ref_frame] = 2;
+ // 3 = one predicted/zero and one new mv
+ // 4 = two new mvs
+ mbmi->mb_mode_context[ref_frame] = 2 + newmv_count;
}
- } else if (split_count == 0) {
- // Non zero best, No Split MV cases
- mbmi->mb_mode_context[ref_frame] = candidate_scores[0] >= 16 ? 3 : 4;
} else {
- // Non zero best, some split mv
- mbmi->mb_mode_context[ref_frame] = candidate_scores[0] >= 16 ? 5 : 6;
+ // 5 = one intra neighbour + x
+ // 6 = two intra neighbours
+ mbmi->mb_mode_context[ref_frame] = 4 + intra_count;
}
// Clamp vectors
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -804,9 +804,9 @@
left_block_mode(m, i) : B_DC_PRED;
const int bm = m->bmi[i].as_mode.first;
-#ifdef ENTROPY_STATS
+/*#ifdef ENTROPY_STATS
++intra_mode_stats [A] [L] [bm];
-#endif
+#endif*/
write_kf_bmode(bc, bm, c->kf_bmode_prob[a][l]);
} while (++i < 4);
}
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -2430,32 +2430,3 @@
}
}
#endif // CONFIG_COMP_INTER_JOINT_SEARCH
-
-#ifdef ENTROPY_STATS
-void print_mode_context(VP9_COMMON *pc) {
- FILE *f = fopen("vp9_modecont.c", "a");
- int i, j;
-
- fprintf(f, "#include \"vp9_entropy.h\"\n");
- fprintf(f, "const int vp9_mode_contexts[INTER_MODE_CONTEXTS][4] =");
- fprintf(f, "{\n");
- for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
- fprintf(f, " {/* %d */ ", j);
- fprintf(f, " ");
- for (i = 0; i < 4; i++) {
- int this_prob;
-
- // context probs
- this_prob = get_binary_prob(pc->fc.mv_ref_ct[j][i][0],
- pc->fc.mv_ref_ct[j][i][1]);
-
- fprintf(f, "%5d, ", this_prob);
- }
- fprintf(f, " },\n");
- }
-
- fprintf(f, "};\n");
- fclose(f);
-}
-
-#endif/* END MV ref count ENTROPY_STATS stats code */
--- a/vp9/encoder/vp9_mcomp.h
+++ b/vp9/encoder/vp9_mcomp.h
@@ -15,10 +15,6 @@
#include "vp9/encoder/vp9_block.h"
#include "vp9/encoder/vp9_variance.h"
-#ifdef ENTROPY_STATS
-void print_mode_context(VP9_COMMON *pc);
-#endif
-
// The maximum number of steps in a step search given the largest
// allowed initial step
#define MAX_MVSEARCH_STEPS 11
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -522,6 +522,66 @@
}
#endif
+#ifdef ENTROPY_STATS
+void vp9_update_mode_context_stats(VP9_COMP *cpi) {
+ VP9_COMMON *cm = &cpi->common;
+ int i, j;
+ unsigned int (*mv_ref_ct)[4][2] = cm->fc.mv_ref_ct;
+ int64_t (*mv_ref_stats)[4][2] = cpi->mv_ref_stats;
+ FILE *f;
+
+ // Read the past stats counters
+ f = fopen("mode_context.bin", "rb");
+ if (!f) {
+ vpx_memset(cpi->mv_ref_stats, 0, sizeof(cpi->mv_ref_stats));
+ } else {
+ fread(cpi->mv_ref_stats, sizeof(cpi->mv_ref_stats), 1, f);
+ fclose(f);
+ }
+
+ // Add in the values for this frame
+ for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
+ for (j = 0; j < 4; j++) {
+ mv_ref_stats[i][j][0] += (int64_t)mv_ref_ct[i][j][0];
+ mv_ref_stats[i][j][1] += (int64_t)mv_ref_ct[i][j][1];
+ }
+ }
+
+ // Write back the accumulated stats
+ f = fopen("mode_context.bin", "wb");
+ fwrite(cpi->mv_ref_stats, sizeof(cpi->mv_ref_stats), 1, f);
+ fclose(f);
+}
+
+void print_mode_context(VP9_COMP *cpi) {
+ FILE *f = fopen("vp9_modecont.c", "a");
+ int i, j;
+
+ fprintf(f, "#include \"vp9_entropy.h\"\n");
+ fprintf(f, "const int vp9_mode_contexts[INTER_MODE_CONTEXTS][4] =");
+ fprintf(f, "{\n");
+ for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
+ fprintf(f, " {/* %d */ ", j);
+ fprintf(f, " ");
+ for (i = 0; i < 4; i++) {
+ int this_prob;
+ int64_t count = cpi->mv_ref_stats[j][i][0] + cpi->mv_ref_stats[j][i][1];
+ if (count)
+ this_prob = ((cpi->mv_ref_stats[j][i][0] * 256) + (count >> 1)) / count;
+ else
+ this_prob = 128;
+
+ // context probs
+ fprintf(f, "%5d, ", this_prob);
+ }
+ fprintf(f, " },\n");
+ }
+
+ fprintf(f, "};\n");
+ fclose(f);
+}
+#endif // ENTROPY_STATS
+
// DEBUG: Print out the segment id of each MB in the current frame.
static void print_seg_map(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
@@ -1630,7 +1690,7 @@
if (cpi->pass != 1) {
print_context_counters();
print_tree_update_probs();
- print_mode_context(&cpi->common);
+ print_mode_context(cpi);
}
#endif
#ifdef NMV_STATS
@@ -3138,6 +3198,10 @@
vp9_adapt_nmv_probs(&cpi->common, cpi->mb.e_mbd.allow_high_precision_mv);
}
}
+
+#ifdef ENTROPY_STATS
+ vp9_update_mode_context_stats(cpi);
+#endif
/* Move storing frame_type out of the above loop since it is also
* needed in motion search besides loopfilter */
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -611,6 +611,10 @@
int this_frame_weight;
int max_arf_level;
#endif
+
+#ifdef ENTROPY_STATS
+ int64_t mv_ref_stats[INTER_MODE_CONTEXTS][4][2];
+#endif
} VP9_COMP;
void vp9_encode_frame(VP9_COMP *cpi);