shithub: libvpx

Download patch

ref: 61e2eac61d6c10f8ba49edb9c69559dc95ee81eb
parent: 51bc4bf4a05cf2de8b4e6c035e53b8710d0b17d6
parent: 6ff3eb1647c68c9afcd2e57f184eea5f3d369d57
author: Paul Wilkins <paulwilkins@google.com>
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);