Added update-able mv-ref probabilities.
authorPaul Wilkins <paulwilkins@google.com>
Mon, 10 Dec 2012 12:38:48 +0000 (12:38 +0000)
committerPaul Wilkins <paulwilkins@google.com>
Wed, 2 Jan 2013 14:22:11 +0000 (14:22 +0000)
Part of NEW_MVREF experiment.
Added update-able probabilities.

Change-Id: I5a4fcf4aaed1d0d1dac980f69d535639a3d59401

vp9/common/vp9_blockd.h
vp9/common/vp9_entropymv.h
vp9/decoder/vp9_decodemv.c
vp9/decoder/vp9_decodframe.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_onyx_int.h
vp9/encoder/vp9_ratectrl.c
vp9/encoder/vp9_rdopt.c

index ad5f3b3..c430ea2 100644 (file)
@@ -362,7 +362,7 @@ typedef struct macroblockd {
   vp9_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
 
 #if CONFIG_NEW_MVREF
-  vp9_prob mb_mv_ref_id_probs[MAX_REF_FRAMES][3];
+  vp9_prob mb_mv_ref_probs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES-1];
 #endif
 
   // Segment features
index dcdd0ec..f5cfee9 100644 (file)
@@ -25,6 +25,13 @@ void vp9_adapt_nmv_probs(struct VP9Common *cm, int usehp);
 int vp9_use_nmv_hp(const MV *ref);
 
 #define VP9_NMV_UPDATE_PROB  255
+
+#if CONFIG_NEW_MVREF
+#define VP9_MVREF_UPDATE_PROB 252
+#define VP9_DEFAULT_MV_REF_PROB 192
+#define VP9_MV_REF_UPDATE_COST (14 << 8)
+#endif
+
 //#define MV_GROUP_UPDATE
 
 #define LOW_PRECISION_MV_UPDATE  /* Use 7 bit forward update */
index f36a224..f846117 100644 (file)
@@ -591,11 +591,6 @@ static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *bc) {
     }
 #endif
 
-#if CONFIG_NEW_MVREF
-  // Temp defaults probabilities for ecnoding the MV ref id signal
-  vpx_memset(xd->mb_mv_ref_id_probs, 192, sizeof(xd->mb_mv_ref_id_probs));
-#endif
-
     read_nmvprobs(bc, nmvc, xd->allow_high_precision_mv);
   }
 }
@@ -936,7 +931,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
 
       // Encode the index of the choice.
       best_index =
-        vp9_read_mv_ref_id(bc, xd->mb_mv_ref_id_probs[ref_frame]);
+        vp9_read_mv_ref_id(bc, xd->mb_mv_ref_probs[ref_frame]);
 
       best_mv.as_int = mbmi->ref_mvs[ref_frame][best_index].as_int;
 
@@ -945,7 +940,7 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
 
         // Encode the index of the choice.
         best_index =
-          vp9_read_mv_ref_id(bc, xd->mb_mv_ref_id_probs[ref_frame]);
+          vp9_read_mv_ref_id(bc, xd->mb_mv_ref_probs[ref_frame]);
         best_mv_second.as_int = mbmi->ref_mvs[ref_frame][best_index].as_int;
       }
     }
index c3a17ef..af34582 100644 (file)
@@ -1608,6 +1608,33 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
     }
   }
 
+#if CONFIG_NEW_MVREF
+  // If Key frame reset mv ref id probabilities to defaults
+  if (pc->frame_type == KEY_FRAME) {
+    // Defaults probabilities for encoding the MV ref id signal
+    vpx_memset(xd->mb_mv_ref_probs, VP9_DEFAULT_MV_REF_PROB,
+               sizeof(xd->mb_mv_ref_probs));
+  } else {
+    // Read any mv_ref index probability updates
+    int i, j;
+
+    for (i = 0; i < MAX_REF_FRAMES; ++i) {
+      // Skip the dummy entry for intra ref frame.
+      if (i == INTRA_FRAME) {
+        continue;
+      }
+
+      // Read any updates to probabilities
+      for (j = 0; j < MAX_MV_REF_CANDIDATES - 1; ++j) {
+        if (vp9_read(&header_bc, VP9_MVREF_UPDATE_PROB)) {
+          xd->mb_mv_ref_probs[i][j] =
+            (vp9_prob)vp9_read_literal(&header_bc, 8);
+        }
+      }
+    }
+  }
+#endif
+
   if (0) {
     FILE *z = fopen("decodestats.stt", "a");
     fprintf(z, "%6d F:%d,G:%d,A:%d,L:%d,Q:%d\n",
index 54d44fa..956c16c 100644 (file)
@@ -12,6 +12,7 @@
 #include "vp9/common/vp9_header.h"
 #include "vp9/encoder/vp9_encodemv.h"
 #include "vp9/common/vp9_entropymode.h"
+#include "vp9/common/vp9_entropymv.h"
 #include "vp9/common/vp9_findnearmv.h"
 #include "vp9/encoder/vp9_mcomp.h"
 #include "vp9/common/vp9_systemdependent.h"
@@ -259,6 +260,56 @@ static void update_mode_probs(VP9_COMMON *cm,
     }
   }
 }
+
+#if CONFIG_NEW_MVREF
+static void update_mv_ref_probs(VP9_COMP *cpi,
+                                int mvref_probs[MAX_REF_FRAMES]
+                                               [MAX_MV_REF_CANDIDATES-1]) {
+  MACROBLOCKD *xd = &cpi->mb.e_mbd;
+  int rf;     // Reference frame
+  int ref_c;  // Motion reference candidate
+  int node;   // Probability node index
+
+  for (rf = 0; rf < MAX_REF_FRAMES; ++rf) {
+    int count = 0;
+
+    // Skip the dummy entry for intra ref frame.
+    if (rf == INTRA_FRAME) {
+      continue;
+    }
+
+    // Sum the counts for all candidates
+    for (ref_c = 0; ref_c < MAX_MV_REF_CANDIDATES; ++ref_c) {
+      count += cpi->mb_mv_ref_count[rf][ref_c];
+    }
+
+    // Calculate the tree node probabilities
+    for (node = 0; node < MAX_MV_REF_CANDIDATES-1; ++node) {
+      int new_prob, old_cost, new_cost;
+      unsigned int branch_cnts[2];
+
+      // How many hits on each branch at this node
+      branch_cnts[0] = cpi->mb_mv_ref_count[rf][node];
+      branch_cnts[1] = count - cpi->mb_mv_ref_count[rf][node];
+
+      // Work out cost of coding branches with the old and optimal probability
+      old_cost = cost_branch256(branch_cnts, xd->mb_mv_ref_probs[rf][node]);
+      new_prob = get_prob(branch_cnts[0], count);
+      new_cost = cost_branch256(branch_cnts, new_prob);
+
+      // Take current 0 branch cases out of residual count
+      count -= cpi->mb_mv_ref_count[rf][node];
+
+      if ((new_cost + VP9_MV_REF_UPDATE_COST) <= old_cost) {
+        mvref_probs[rf][node] = new_prob;
+      } else {
+        mvref_probs[rf][node] = xd->mb_mv_ref_probs[rf][node];
+      }
+    }
+  }
+}
+#endif
+
 static void write_ymode(vp9_writer *bc, int m, const vp9_prob *p) {
   write_token(bc, vp9_ymode_tree, p, vp9_ymode_encodings + m);
 }
@@ -912,17 +963,13 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
           if (mode == NEWMV) {
             // Encode the index of the choice.
             vp9_write_mv_ref_id(bc,
-                                xd->mb_mv_ref_id_probs[rf], mi->best_index);
-            cpi->best_ref_index_counts[rf][mi->best_index]++;
+                                xd->mb_mv_ref_probs[rf], mi->best_index);
 
             if (mi->second_ref_frame > 0) {
               // Encode the index of the choice.
               vp9_write_mv_ref_id(
-                bc, xd->mb_mv_ref_id_probs[mi->second_ref_frame],
+                bc, xd->mb_mv_ref_probs[mi->second_ref_frame],
                 mi->best_second_index);
-
-              cpi->best_ref_index_counts[mi->second_ref_frame]
-                                        [mi->best_second_index]++;
             }
           }
 #endif
@@ -1964,7 +2011,7 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
 
   // If appropriate update the inter mode probability context and code the
   // changes in the bitstream.
-  if ((pc->frame_type != KEY_FRAME)) {
+  if (pc->frame_type != KEY_FRAME) {
     int i, j;
     int new_context[INTER_MODE_CONTEXTS][4];
     update_mode_probs(pc, new_context);
@@ -1986,6 +2033,37 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
     }
   }
 
+#if CONFIG_NEW_MVREF
+  if ((pc->frame_type != KEY_FRAME)) {
+    int new_mvref_probs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES-1];
+    int i, j;
+
+    update_mv_ref_probs(cpi, new_mvref_probs);
+
+    for (i = 0; i < MAX_REF_FRAMES; ++i) {
+      // Skip the dummy entry for intra ref frame.
+      if (i == INTRA_FRAME) {
+        continue;
+      }
+
+      // Encode any mandated updates to probabilities
+      for (j = 0; j < MAX_MV_REF_CANDIDATES - 1; ++j) {
+        if (new_mvref_probs[i][j] != xd->mb_mv_ref_probs[i][j]) {
+          vp9_write(&header_bc, 1, VP9_MVREF_UPDATE_PROB);
+          vp9_write_literal(&header_bc, new_mvref_probs[i][j], 8);
+
+          // Only update the persistent copy if this is the "real pack"
+          if (!cpi->dummy_packing) {
+            xd->mb_mv_ref_probs[i][j] = new_mvref_probs[i][j];
+          }
+        } else {
+          vp9_write(&header_bc, 0, VP9_MVREF_UPDATE_PROB);
+        }
+      }
+    }
+  }
+#endif
+
   vp9_clear_system_state();  // __asm emms;
 
   vp9_copy(cpi->common.fc.pre_coef_probs_4x4,
index 63fc1a9..b7a5b80 100644 (file)
@@ -392,7 +392,7 @@ static unsigned int pick_best_mv_ref(MACROBLOCK *x,
   MACROBLOCKD *xd = &x->e_mbd;
   int max_mv = MV_MAX;
 
-  cost = vp9_cost_mv_ref_id(xd->mb_mv_ref_id_probs[ref_frame], 0) +
+  cost = vp9_cost_mv_ref_id(xd->mb_mv_ref_probs[ref_frame], 0) +
          vp9_mv_bit_cost(&target_mv, &mv_ref_list[0], x->nmvjointcost,
                          x->mvcost, 96, xd->allow_high_precision_mv);
 
@@ -413,7 +413,7 @@ static unsigned int pick_best_mv_ref(MACROBLOCK *x,
       continue;
     }
 
-    cost2 = vp9_cost_mv_ref_id(xd->mb_mv_ref_id_probs[ref_frame], i) +
+    cost2 = vp9_cost_mv_ref_id(xd->mb_mv_ref_probs[ref_frame], i) +
             vp9_mv_bit_cost(&target_mv, &mv_ref_list[i], x->nmvjointcost,
                             x->mvcost, 96, xd->allow_high_precision_mv);
 
@@ -422,8 +422,6 @@ static unsigned int pick_best_mv_ref(MACROBLOCK *x,
       best_index = i;
     }
   }
-
-  // best_index = x->mv_best_ref_index[ref_frame];
   best_ref->as_int = mv_ref_list[best_index].as_int;
 
   return best_index;
@@ -555,6 +553,7 @@ static void update_state(VP9_COMP *cpi, MACROBLOCK *x,
         best_index = pick_best_mv_ref(x, rf, mbmi->mv[0],
                                       mbmi->ref_mvs[rf], &best_mv);
         mbmi->best_index = best_index;
+        ++cpi->mb_mv_ref_count[rf][best_index];
 
         if (mbmi->second_ref_frame > 0) {
           unsigned int best_index;
@@ -563,6 +562,7 @@ static void update_state(VP9_COMP *cpi, MACROBLOCK *x,
                                mbmi->ref_mvs[sec_ref_frame],
                                &best_second_mv);
           mbmi->best_second_index = best_index;
+          ++cpi->mb_mv_ref_count[sec_ref_frame][best_index];
         }
 #endif
       }
@@ -1443,11 +1443,6 @@ static void encode_frame_internal(VP9_COMP *cpi) {
   // this frame which may be updated with each iteration of the recode loop.
   vp9_compute_mod_refprobs(cm);
 
-#if CONFIG_NEW_MVREF
-  // temp stats reset
-  vp9_zero( cpi->best_ref_index_counts );
-#endif
-
 // debug output
 #if DBG_PRNT_SEGMAP
   {
@@ -1496,6 +1491,9 @@ static void encode_frame_internal(VP9_COMP *cpi) {
 #if CONFIG_TX32X32 && CONFIG_SUPERBLOCKS
   vp9_zero(cpi->coef_counts_32x32);
 #endif
+#if CONFIG_NEW_MVREF
+  vp9_zero(cpi->mb_mv_ref_count);
+#endif
 
   vp9_frame_init_quantizer(cpi);
 
index 9e43673..5043bc4 100644 (file)
@@ -2992,11 +2992,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
   // Set default state for segment based loop filter update flags
   xd->mode_ref_lf_delta_update = 0;
 
-#if CONFIG_NEW_MVREF
-  // Temp defaults probabilities for ecnoding the MV ref id signal
-  vpx_memset(xd->mb_mv_ref_id_probs, 192,
-             sizeof(xd->mb_mv_ref_id_probs));
-#endif
 
   // Set various flags etc to special state if it is a key frame
   if (cm->frame_type == KEY_FRAME) {
@@ -3789,19 +3784,6 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
   // in this frame.
   update_base_skip_probs(cpi);
 
-#if 0 //CONFIG_NEW_MVREF && CONFIG_INTERNAL_STATS
-  {
-    FILE *f = fopen("mv_ref_dist.stt", "a");
-    unsigned int i;
-    for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
-      fprintf(f, "%10d", cpi->best_ref_index_counts[0][i]);
-    }
-    fprintf(f, "\n" );
-
-    fclose(f);
-  }
-#endif
-
 #if 0// 1 && CONFIG_INTERNAL_STATS
   {
     FILE *f = fopen("tmp.stt", "a");
index 0c2b8cc..6452be3 100644 (file)
@@ -800,7 +800,7 @@ typedef struct VP9_COMP {
   unsigned int switchable_interp_count[VP9_SWITCHABLE_FILTERS + 1]
                                       [VP9_SWITCHABLE_FILTERS];
 #if CONFIG_NEW_MVREF
-  unsigned int best_ref_index_counts[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
+  unsigned int mb_mv_ref_count[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
 #endif
 
 } VP9_COMP;
index 540a680..08ad54b 100644 (file)
@@ -277,6 +277,16 @@ void vp9_setup_key_frame(VP9_COMP *cpi) {
 
   vp9_update_mode_info_border(cm, cm->mip);
   vp9_update_mode_info_in_image(cm, cm->mi);
+
+#if CONFIG_NEW_MVREF
+  if (1) {
+    MACROBLOCKD *xd = &cpi->mb.e_mbd;
+
+    // Defaults probabilities for encoding the MV ref id signal
+    vpx_memset(xd->mb_mv_ref_probs, VP9_DEFAULT_MV_REF_PROB,
+               sizeof(xd->mb_mv_ref_probs));
+  }
+#endif
 }
 
 void vp9_setup_inter_frame(VP9_COMP *cpi) {
index 69bc892..0d4c2b6 100644 (file)
@@ -3256,11 +3256,6 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
   mv_pred(cpi, x, y_buffer[frame_type], yv12->y_stride,
           frame_type, block_size);
 
-#if CONFIG_NEW_MVREF
-  // TODO(paulwilkins): Final choice of which of the best 4 candidates from
-  // above gives lowest error score when used in isolation. This stage encoder
-  // and sets the reference MV
-#endif
 }
 
 static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
@@ -3300,8 +3295,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
     case NEWMV:
       ref_mv[0] = mbmi->ref_mvs[refs[0]][0];
       ref_mv[1] = mbmi->ref_mvs[refs[1]][0];
-      // ref_mv[0] = mbmi->ref_mvs[refs[0]][x->mv_best_ref_index[refs[0]]];
-      // ref_mv[1] = mbmi->ref_mvs[refs[1]][x->mv_best_ref_index[refs[1]]];
+
       if (is_comp_pred) {
         if (frame_mv[NEWMV][refs[0]].as_int == INVALID_MV ||
             frame_mv[NEWMV][refs[1]].as_int == INVALID_MV)
@@ -3328,8 +3322,10 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
 
         vp9_clamp_mv_min_max(x, &ref_mv[0]);
 
+        // mvp_full.as_int = ref_mv[0].as_int;
         mvp_full.as_int =
-          mbmi->ref_mvs[refs[0]][x->mv_best_ref_index[refs[0]]].as_int;
+         mbmi->ref_mvs[refs[0]][x->mv_best_ref_index[refs[0]]].as_int;
+
         mvp_full.as_mv.col >>= 3;
         mvp_full.as_mv.row >>= 3;
         if (mvp_full.as_int != mvp_full.as_int) {