]> granicus.if.org Git - libvpx/commitdiff
Entropy coding for dynamic ref mv modes
authorJingning Han <jingning@google.com>
Fri, 22 Jan 2016 02:07:31 +0000 (18:07 -0800)
committerJingning Han <jingning@google.com>
Tue, 9 Feb 2016 01:05:24 +0000 (17:05 -0800)
This commit enables entropy coding for dynamic reference motion
vector modes. The probability model is contexted on the ranking
categories of the reference motion vector candidates.

Change-Id: I09b58d98a409d63ec1a407331e29f8945b7ef17d

13 files changed:
vp10/common/entropymode.c
vp10/common/entropymode.h
vp10/common/enums.h
vp10/common/mvref_common.c
vp10/common/mvref_common.h
vp10/common/thread_common.c
vp10/decoder/decodeframe.c
vp10/decoder/decodemv.c
vp10/encoder/bitstream.c
vp10/encoder/encodeframe.c
vp10/encoder/encoder.h
vp10/encoder/rd.c
vp10/encoder/rdopt.c

index 5c2d51b9a78ee0fdf3217a01e4cfcf9f56419cec..4d9f773d6d485b890a932b0daddf011b5ca438bc 100644 (file)
@@ -184,6 +184,10 @@ static const vpx_prob default_refmv_prob[REFMV_MODE_CONTEXTS] = {
     220, 220, 200, 200, 180, 128, 30, 220, 30,
 };
 
+static const vpx_prob default_drl_prob[DRL_MODE_CONTEXTS] = {
+    128, 128, 128,
+};
+
 #if CONFIG_EXT_INTER
 static const vpx_prob default_new2mv_prob = 180;
 #endif
@@ -1292,6 +1296,8 @@ 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);
 #if CONFIG_EXT_INTER
   fc->new2mv_prob = default_new2mv_prob;
 #endif  // CONFIG_EXT_INTER
@@ -1360,6 +1366,13 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
     fc->refmv_prob[i] = mode_mv_merge_probs(pre_fc->refmv_prob[i],
                                             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]);
+
 #if CONFIG_EXT_INTER
   fc->new2mv_prob = mode_mv_merge_probs(pre_fc->new2mv_prob,
                                         counts->new2mv_mode);
index fbadc4e0712790f21db96f05bb56ced58862f622..4b4bdf12f6742e8e1a3a92894103358573034de3 100644 (file)
@@ -68,6 +68,9 @@ 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];
+
 #if CONFIG_EXT_INTER
   vpx_prob new2mv_prob;
 #endif  // CONFIG_EXT_INTER
@@ -121,6 +124,8 @@ 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];
 #if CONFIG_EXT_INTER
   unsigned int new2mv_mode[2];
 #endif  // CONFIG_EXT_INTER
index fdcde99e6b07dfc702650d0a518c2d92f74fbcb3..f41b8d9450954872438c660006589c519ed6982c 100644 (file)
@@ -231,6 +231,7 @@ typedef enum {
 #define NEWMV_MODE_CONTEXTS  7
 #define ZEROMV_MODE_CONTEXTS 2
 #define REFMV_MODE_CONTEXTS  9
+#define DRL_MODE_CONTEXTS    3
 
 #define ZEROMV_OFFSET 3
 #define REFMV_OFFSET  4
@@ -251,6 +252,7 @@ typedef enum {
 #define MAX_MV_REF_CANDIDATES 2
 #if CONFIG_REF_MV
 #define MAX_REF_MV_STACK_SIZE 16
+#define REF_CAT_LEVEL  160
 #endif
 
 #define INTRA_INTER_CONTEXTS 4
index 53394e94d0f054e0f34b40a2e5a4aae31878b8b2..1b7fb7d9fbd535ef547c15f0d950bfb007138a6b 100644 (file)
@@ -329,6 +329,9 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd,
 
   nearest_refmv_count = *refmv_count;
 
+  for (idx = 0; idx < nearest_refmv_count; ++idx)
+    ref_mv_stack[idx].weight += REF_CAT_LEVEL;
+
   if (prev_frame_mvs_base && cm->show_frame && cm->last_show_frame
       && rf[1] == NONE) {
     int ref;
index 3a77147e955e6b33eba93fca3561f275ceda70e1..224c5edfae870a8f84d4035fcc220d4992e7d5f5 100644 (file)
@@ -257,6 +257,24 @@ static INLINE int16_t vp10_mode_context_analyzer(
   else
     return mode_context[rf[0]];
 }
+
+static INLINE uint8_t vp10_drl_ctx(const CANDIDATE_MV *ref_mv_stack,
+                                   int ref_idx) {
+  if (ref_mv_stack[ref_idx + 1].weight > REF_CAT_LEVEL &&
+      ref_mv_stack[ref_idx + 2].weight > REF_CAT_LEVEL)
+    return 0;
+
+  if (ref_mv_stack[ref_idx + 1].weight > REF_CAT_LEVEL &&
+      ref_mv_stack[ref_idx + 2].weight < REF_CAT_LEVEL)
+    return 1;
+
+  if (ref_mv_stack[ref_idx + 1].weight < REF_CAT_LEVEL &&
+      ref_mv_stack[ref_idx + 2].weight < REF_CAT_LEVEL)
+    return 2;
+
+  assert(0);
+  return 0;
+}
 #endif
 
 typedef void (*find_mv_refs_sync)(void *const data, int mi_row);
index bacc534591e96df8735c10ff4fdb329252e3bd33..6e959edbd351df7988c7d7051c3a780d52334436 100644 (file)
@@ -379,6 +379,15 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts,
     for (j = 0; j < 2; ++j)
       cm->counts.refmv_mode[i][j] += counts->refmv_mode[i][j];
 
+
+  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];
+
 #if CONFIG_EXT_INTER
   for (j = 0; j < 2; ++j)
     cm->counts.new2mv_mode[j] += counts->new2mv_mode[j];
index a26f969ccb2db1556d5122151a9f7ce4594745c8..ec1a5fb783491ab56adb2d5529d1d2bfffde249d 100644 (file)
@@ -132,6 +132,10 @@ static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
     vp10_diff_update_prob(r, &fc->zeromv_prob[i]);
   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]);
 #if CONFIG_EXT_INTER
   vp10_diff_update_prob(r, &fc->new2mv_prob);
 #endif  // CONFIG_EXT_INTER
index 8d26c62de697c5704f4c9afc4d6afe68082a1dc5..51bf2b390f0b043923ffca1ae39fc546a186a471 100644 (file)
@@ -147,6 +147,45 @@ static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd,
 #endif
 }
 
+#if CONFIG_REF_MV
+static void read_drl_idx(const VP10_COMMON *cm,
+                         MACROBLOCKD *xd,
+                         MB_MODE_INFO *mbmi,
+                         vpx_reader *r) {
+  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] > 2) {
+    uint8_t drl0_ctx = vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], 0);
+    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], 1);
+        vpx_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx];
+        if (vpx_read(r, drl1_prob)) {
+          mbmi->ref_mv_idx = 2;
+          if (xd->counts)
+            ++xd->counts->drl_mode1[drl1_ctx][1];
+
+          return;
+        }
+
+        if (xd->counts)
+          ++xd->counts->drl_mode1[drl1_ctx][0];
+      }
+      return;
+    }
+
+    if (xd->counts)
+      ++xd->counts->drl_mode0[drl0_ctx][0];
+  }
+}
+#endif
+
 #if CONFIG_EXT_INTER
 static PREDICTION_MODE read_inter_compound_mode(VP10_COMMON *cm,
                                                 MACROBLOCKD *xd,
@@ -1056,17 +1095,8 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
 #endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
                                    r, mode_ctx);
 #if CONFIG_REF_MV
-      if (mbmi->mode == NEARMV) {
-        uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
-        if (xd->ref_mv_count[ref_frame_type] > 2) {
-          if (vpx_read_bit(r)) {
-            mbmi->ref_mv_idx = 1;
-            if (xd->ref_mv_count[ref_frame_type] > 3)
-              if (vpx_read_bit(r))
-                mbmi->ref_mv_idx = 2;
-          }
-        }
-      }
+      if (mbmi->mode == NEARMV)
+        read_drl_idx(cm, xd, mbmi, r);
 #endif
     }
   }
index d4bd12269c9e3d27e2c365649e93e4e7ab0ebcec..a2edade8249b22d576019b9c0e6692493362937b 100644 (file)
@@ -177,6 +177,28 @@ static void write_inter_mode(VP10_COMMON *cm,
 #endif
 }
 
+#if CONFIG_REF_MV
+static void write_drl_idx(const VP10_COMMON *cm,
+                          const MB_MODE_INFO *mbmi,
+                          const MB_MODE_INFO_EXT *mbmi_ext,
+                          vpx_writer *w) {
+  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], 0);
+    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], 1);
+      vpx_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx];
+      vpx_write(w, mbmi->ref_mv_idx != 1, drl1_prob);
+    }
+  }
+}
+#endif
+
 #if CONFIG_EXT_INTER
 static void write_inter_compound_mode(VP10_COMMON *cm, vpx_writer *w,
                                       PREDICTION_MODE mode,
@@ -312,7 +334,12 @@ static void update_inter_mode_probs(VP10_COMMON *cm, vpx_writer *w,
   for (i = 0; i < REFMV_MODE_CONTEXTS; ++i)
     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]);
 #if CONFIG_EXT_INTER
   vp10_cond_prob_diff_update(w, &cm->fc->new2mv_prob, counts->new2mv_mode);
 #endif  // CONFIG_EXT_INTER
@@ -994,15 +1021,8 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
                          mode_ctx);
 
 #if CONFIG_REF_MV
-        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) {
-            vpx_write_bit(w, mbmi->ref_mv_idx != 0);
-            if (mbmi_ext->ref_mv_count[ref_frame_type] > 3 &&
-                mbmi->ref_mv_idx > 0)
-              vpx_write_bit(w, mbmi->ref_mv_idx != 1);
-          }
-        }
+        if (mode == NEARMV)
+          write_drl_idx(cm, mbmi, mbmi_ext, w);
 #endif
       }
     }
index 859ec49c40ffd49998fbfa4a6e5949cd4457dcd9..b758b3bd87b98ed16c805ff72e2f79304b24df7c 100644 (file)
@@ -1822,6 +1822,28 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td
                                 has_second_ref(mbmi),
 #endif  // CONFIG_EXT_INTER
                                 mode_ctx);
+
+        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], 0);
+            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], 1);
+              if (mbmi->ref_mv_idx == 1)
+                ++counts->drl_mode1[drl1_ctx][0];
+              else
+                ++counts->drl_mode1[drl1_ctx][1];
+            }
+          }
+        }
 #if CONFIG_EXT_INTER
         }
 #endif  // CONFIG_EXT_INTER
index 940c9a51acd737ea96924f7b70eb0aa5956af100..f7c60133973d7074e2c67c53f82b92622d7cafeb 100644 (file)
@@ -474,6 +474,8 @@ typedef struct VP10_COMP {
   int newmv_mode_cost[NEWMV_MODE_CONTEXTS][2];
   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
index 1aac71908bc7a27bbc4b843f05c5d73d73de47a5..8498ce9cc70179333ec86b99d0358ace4092d129 100644 (file)
@@ -382,6 +382,16 @@ void vp10_initialize_rd_consts(VP10_COMP *cpi) {
       cpi->refmv_mode_cost[i][0] = vp10_cost_bit(cm->fc->refmv_prob[i], 0);
       cpi->refmv_mode_cost[i][1] = vp10_cost_bit(cm->fc->refmv_prob[i], 1);
     }
+
+    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);
+    }
 #if CONFIG_EXT_INTER
     cpi->new2mv_mode_cost[0] = vp10_cost_bit(cm->fc->new2mv_prob, 0);
     cpi->new2mv_mode_cost[1] = vp10_cost_bit(cm->fc->new2mv_prob, 1);
index af360242f3f2bdce0b9b65ef6e34839934e6cb9c..3f617f81ad6fe60b0a6992e7e4404858c2097dbd 100644 (file)
@@ -6380,7 +6380,9 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
         int ref_idx;
         int ref_set = VPXMIN(2, mbmi_ext->ref_mv_count[ref_frame_type] - 2);
 
-        rate2 += vp10_cost_bit(128, 0);
+        uint8_t drl0_ctx =
+            vp10_drl_ctx(mbmi_ext->ref_mv_stack[ref_frame_type], 0);
+        rate2 += cpi->drl_mode_cost0[drl0_ctx][0];
 
         if (this_rd < INT64_MAX) {
           if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
@@ -6440,9 +6442,13 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
                                            dummy_filter_cache);
           }
 
-          tmp_rate += vp10_cost_bit(128, 1);
-          if (mbmi_ext->ref_mv_count[ref_frame_type] > 3)
-            tmp_rate += vp10_cost_bit(128, ref_idx);
+          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], 1);
+            tmp_rate += cpi->drl_mode_cost1[drl1_ctx][ref_idx];
+          }
 
           if (tmp_alt_rd < INT64_MAX) {
             if (RDCOST(x->rdmult, x->rddiv,