]> granicus.if.org Git - libvpx/commitdiff
Enable context analyzer for inter mode entropy coding
authorJingning Han <jingning@google.com>
Wed, 9 Dec 2015 17:07:39 +0000 (09:07 -0800)
committerJingning Han <jingning@google.com>
Fri, 8 Jan 2016 18:27:27 +0000 (10:27 -0800)
It allows the codec to account for certain corner cases when
processing inter prediction mode entropy coding.

Change-Id: Ied451f4fff26ba579f6556554b8381ff2ccd0003

vp10/common/entropymode.c
vp10/common/enums.h
vp10/common/mvref_common.c
vp10/common/mvref_common.h
vp10/decoder/decodemv.c
vp10/encoder/bitstream.c
vp10/encoder/encodeframe.c
vp10/encoder/encoder.c
vp10/encoder/rdopt.c

index 02287ec7a6f514bed4c56b824b660edf836680f3..0048c7ca4a63bbc1c64ba4a968e3edeb92cf97fa 100644 (file)
@@ -181,7 +181,7 @@ static const vpx_prob default_zeromv_prob[ZEROMV_MODE_CONTEXTS] = {
 };
 
 static const vpx_prob default_refmv_prob[REFMV_MODE_CONTEXTS] = {
-    220, 220, 200, 200, 180, 128, 1, 250,
+    220, 220, 200, 200, 180, 128, 30, 220, 30,
 };
 #endif
 
index c283222ea7cbb2860c6b5f91f2542dc5867e8bf8..44de0a2270f1eaa848902b4d2470f1b4e53e4c74 100644 (file)
@@ -207,7 +207,7 @@ typedef enum {
 #if CONFIG_REF_MV
 #define NEWMV_MODE_CONTEXTS  7
 #define ZEROMV_MODE_CONTEXTS 2
-#define REFMV_MODE_CONTEXTS  8
+#define REFMV_MODE_CONTEXTS  9
 
 #define ZEROMV_OFFSET 3
 #define REFMV_OFFSET  4
@@ -219,6 +219,7 @@ typedef enum {
 #define ALL_ZERO_FLAG_OFFSET   8
 #define SKIP_NEARESTMV_OFFSET  9
 #define SKIP_NEARMV_OFFSET    10
+#define SKIP_NEARESTMV_SUB8X8_OFFSET 11
 #endif
 
 #define INTER_MODE_CONTEXTS 7
index c62e8acc0db5d7e2537d7e143e343e7de2f5c24e..319ef4a7eb42fd3271cab54f3df1292907fcd1c1 100644 (file)
@@ -216,7 +216,7 @@ static int has_top_right(const MACROBLOCKD *xd,
 }
 
 static void handle_sec_rect_block(const MB_MODE_INFO * const candidate,
-                                  uint8_t *refmv_count,
+                                  uint8_t refmv_count,
                                   CANDIDATE_MV *ref_mv_stack,
                                   MV_REFERENCE_FRAME ref_frame,
                                   int16_t *mode_context) {
@@ -224,7 +224,7 @@ static void handle_sec_rect_block(const MB_MODE_INFO * const candidate,
 
   for (rf = 0; rf < 2; ++rf) {
     if (candidate->ref_frame[rf] == ref_frame) {
-      const int list_range = VPXMIN(*refmv_count, MAX_MV_REF_CANDIDATES);
+      const int list_range = VPXMIN(refmv_count, MAX_MV_REF_CANDIDATES);
 
       const int_mv pred_mv = candidate->mv[rf];
       for (idx = 0; idx < list_range; ++idx)
@@ -232,15 +232,10 @@ static void handle_sec_rect_block(const MB_MODE_INFO * const candidate,
           break;
 
       if (idx < list_range) {
-        mode_context[ref_frame] &= ~(0x0f << REFMV_OFFSET);
-
-        if (idx == 0) {
+        if (idx == 0)
           mode_context[ref_frame] |= (1 << SKIP_NEARESTMV_OFFSET);
-          mode_context[ref_frame] |= (6 << REFMV_OFFSET);
-        } else if (idx == 1) {
+        else if (idx == 1)
           mode_context[ref_frame] |= (1 << SKIP_NEARMV_OFFSET);
-          mode_context[ref_frame] |= (7 << REFMV_OFFSET);
-        }
       }
     }
   }
@@ -417,14 +412,14 @@ static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd,
     if (xd->n8_w < xd->n8_h) {
       const MODE_INFO *const candidate_mi = xd->mi[-1];
       const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
-      handle_sec_rect_block(candidate, refmv_count, ref_mv_stack,
+      handle_sec_rect_block(candidate, nearest_refmv_count, ref_mv_stack,
                             ref_frame, mode_context);
     }
 
     if (xd->n8_w > xd->n8_h) {
       const MODE_INFO *const candidate_mi = xd->mi[-xd->mi_stride];
       const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
-      handle_sec_rect_block(candidate, refmv_count, ref_mv_stack,
+      handle_sec_rect_block(candidate, nearest_refmv_count, ref_mv_stack,
                             ref_frame, mode_context);
     }
   }
index c5b40c3134f6204bef737533705415423b34ddd0..39684690642186759ddfaa9feaf00ac64fc6fe83 100644 (file)
@@ -195,6 +195,29 @@ static INLINE int is_inside(const TileInfo *const tile,
            mi_col + mi_pos->col >= tile->mi_col_end);
 }
 
+#if CONFIG_REF_MV
+static int16_t vp10_mode_context_analyzer(const int16_t *const mode_context,
+                                          const MV_REFERENCE_FRAME *const rf,
+                                          BLOCK_SIZE bsize, int block) {
+  int16_t mode_ctx = 0;
+  if (block >= 0) {
+    mode_ctx = mode_context[rf[0]] & 0x00ff;
+
+    if (block > 0 && bsize < BLOCK_8X8 && bsize > BLOCK_4X4)
+      mode_ctx |= (1 << SKIP_NEARESTMV_SUB8X8_OFFSET);
+
+    return mode_ctx;
+  }
+
+  if (rf[1] > INTRA_FRAME)
+    return mode_context[rf[0]] & (mode_context[rf[1]] | 0x00ff);
+  else if (rf[0] != ALTREF_FRAME)
+    return mode_context[rf[0]] & ~(mode_context[ALTREF_FRAME] & 0xfe00);
+  else
+    return mode_context[rf[0]];
+}
+#endif
+
 typedef void (*find_mv_refs_sync)(void *const data, int mi_row);
 void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
                        MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
index f41085a3dd2b31057ccc2ffd3331e478dcf791c1..f4386e488f5fb8e05eff0a1b0de2758333ed5b03 100644 (file)
@@ -92,6 +92,14 @@ static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd,
     ++counts->zeromv_mode[mode_ctx][1];
 
   mode_ctx = (ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
+
+  if (ctx & (1 << SKIP_NEARESTMV_OFFSET))
+    mode_ctx = 6;
+  if (ctx & (1 << SKIP_NEARMV_OFFSET))
+    mode_ctx = 7;
+  if (ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
+    mode_ctx = 8;
+
   mode_prob = cm->fc->refmv_prob[mode_ctx];
 
   if (vpx_read(r, mode_prob) == 0) {
@@ -820,12 +828,13 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
   int ref, is_compound;
   int16_t inter_mode_ctx[MAX_REF_FRAMES];
   int16_t mode_ctx = 0;
+  MV_REFERENCE_FRAME ref_frame;
 
   read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
   is_compound = has_second_ref(mbmi);
 
   for (ref = 0; ref < 1 + is_compound; ++ref) {
-    const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
+    MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
     RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];
 
     xd->block_refs[ref] = ref_buf;
@@ -834,22 +843,23 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
                          "Reference frame has invalid dimensions");
     vp10_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col,
                          &ref_buf->sf);
-    vp10_find_mv_refs(cm, xd, mi, frame,
+  }
+
+  for (ref_frame = LAST_FRAME; ref_frame < MAX_REF_FRAMES; ++ref_frame) {
+    vp10_find_mv_refs(cm, xd, mi, ref_frame,
 #if CONFIG_REF_MV
-                      &xd->ref_mv_count[frame],
-                      xd->ref_mv_stack[frame],
+                      &xd->ref_mv_count[ref_frame],
+                      xd->ref_mv_stack[ref_frame],
 #endif
-                      ref_mvs[frame],
+                      ref_mvs[ref_frame],
                       mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
   }
 
   mode_ctx = inter_mode_ctx[mbmi->ref_frame[0]];
 
 #if CONFIG_REF_MV
-  if (mbmi->ref_frame[1] > NONE)
-    mode_ctx &= (inter_mode_ctx[mbmi->ref_frame[1]] | 0x00ff);
-  if (bsize < BLOCK_8X8)
-    mode_ctx &= 0x00ff;
+  mode_ctx = vp10_mode_context_analyzer(inter_mode_ctx,
+                                        mbmi->ref_frame, bsize, -1);
 #endif
 
   if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
@@ -887,6 +897,10 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
       for (idx = 0; idx < 2; idx += num_4x4_w) {
         int_mv block[2];
         const int j = idy * 2 + idx;
+#if CONFIG_REF_MV
+        mode_ctx = vp10_mode_context_analyzer(inter_mode_ctx,  mbmi->ref_frame,
+                                              bsize, j);
+#endif
         b_mode = read_inter_mode(cm, xd, r, mode_ctx);
 
         if (b_mode == NEARESTMV || b_mode == NEARMV) {
index 11fa8548065f8aee1c0f610ddc34cf74c245a2df..4c0c6af22bfd9503d25cfd55431a66acc4432ae8 100644 (file)
@@ -131,8 +131,17 @@ static void write_inter_mode(VP10_COMMON *cm,
     vpx_write(w, mode != ZEROMV, zeromv_prob);
 
     if (mode != ZEROMV) {
-      const int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
-      const vpx_prob refmv_prob = cm->fc->refmv_prob[refmv_ctx];
+      int16_t refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
+      vpx_prob refmv_prob;
+
+      if (mode_ctx & (1 << SKIP_NEARESTMV_OFFSET))
+        refmv_ctx = 6;
+      if (mode_ctx & (1 << SKIP_NEARMV_OFFSET))
+        refmv_ctx = 7;
+      if (mode_ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
+        refmv_ctx = 8;
+
+      refmv_prob = cm->fc->refmv_prob[refmv_ctx];
       vpx_write(w, mode != NEARESTMV, refmv_prob);
     }
   }
@@ -776,10 +785,8 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
     write_ref_frames(cm, xd, w);
 
 #if CONFIG_REF_MV
-    if (mbmi->ref_frame[1] > NONE)
-      mode_ctx &= (mbmi_ext->mode_context[mbmi->ref_frame[1]] | 0x00ff);
-    if (bsize < BLOCK_8X8)
-      mode_ctx &= 0x00ff;
+    mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+                                          mbmi->ref_frame, bsize, -1);
 #endif
 
     // If segment skip is not enabled code the mode.
@@ -801,6 +808,10 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
         for (idx = 0; idx < 2; idx += num_4x4_w) {
           const int j = idy * 2 + idx;
           const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
+#if CONFIG_REF_MV
+          mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+                                                mbmi->ref_frame, bsize, j);
+#endif
           write_inter_mode(cm, w, b_mode, mode_ctx);
           if (b_mode == NEWMV) {
             for (ref = 0; ref < 1 + is_compound; ++ref)
index 1e4ed4b410353b88befb7d240c691da176ba5639..e516a5f9fe48295b5cd64fa7d4769f025255a998 100644 (file)
@@ -1687,6 +1687,14 @@ static void update_inter_mode_stats(FRAME_COUNTS *counts,
     } else {
       ++counts->zeromv_mode[mode_ctx][1];
       mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
+
+      if (mode_context & (1 << SKIP_NEARESTMV_OFFSET))
+        mode_ctx = 6;
+      if (mode_context & (1 << SKIP_NEARMV_OFFSET))
+        mode_ctx = 7;
+      if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
+        mode_ctx = 8;
+
       ++counts->refmv_mode[mode_ctx][mode != NEARESTMV];
     }
   }
@@ -1779,8 +1787,8 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td
       if (bsize >= BLOCK_8X8) {
         const PREDICTION_MODE mode = mbmi->mode;
 #if CONFIG_REF_MV
-        if (mbmi->ref_frame[1] > NONE)
-          mode_ctx &= (mbmi_ext->mode_context[mbmi->ref_frame[1]] | 0x00ff);
+        mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+                                              mbmi->ref_frame, bsize, -1);
         update_inter_mode_stats(counts, mode, mode_ctx);
 #else
         ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
@@ -1794,7 +1802,8 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td
             const int j = idy * 2 + idx;
             const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
 #if CONFIG_REF_MV
-            mode_ctx &= 0x00ff;
+            mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+                                                  mbmi->ref_frame, bsize, j);
             update_inter_mode_stats(counts, b_mode, mode_ctx);
 #else
             ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
index a3982e3cef5281fc8030c2ceaacec70519560eba..6d0fd197f3a53f33cafb3ac8cb44d53a1dc91564 100644 (file)
@@ -3340,7 +3340,6 @@ static void encode_with_recode_loop(VP10_COMP *cpi,
     // update_base_skip_probs(cpi);
 
     vpx_clear_system_state();
-
     // Dummy pack of the bitstream using up to date stats to get an
     // accurate estimate of output frame size to determine if we need
     // to recode.
index bd7be7f38d7cc04b24881017dbe4c78db1456132..d457199cca59a551f5618e36f0c6193059dfa834 100644 (file)
@@ -3099,6 +3099,14 @@ static int cost_mv_ref(const VP10_COMP *cpi, PREDICTION_MODE mode,
     } else {
       mode_cost += cpi->zeromv_mode_cost[mode_ctx][1];
       mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
+
+      if (mode_context & (1 << SKIP_NEARESTMV_OFFSET))
+        mode_ctx = 6;
+      if (mode_context & (1 << SKIP_NEARMV_OFFSET))
+        mode_ctx = 7;
+      if (mode_context & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET))
+        mode_ctx = 8;
+
       mode_cost += cpi->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
       return mode_cost;
     }
@@ -3163,7 +3171,8 @@ static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
       memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
 
 #if CONFIG_REF_MV
-  mode_ctx &= 0x00ff;
+  mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+                                        mbmi->ref_frame, mbmi->sb_type, i);
 #endif
   return cost_mv_ref(cpi, mode, mode_ctx) + thismvcost;
 }
@@ -3348,14 +3357,15 @@ static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
 static int check_best_zero_mv(
     const VP10_COMP *cpi, const int16_t mode_context[MAX_REF_FRAMES],
     int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
-    const MV_REFERENCE_FRAME ref_frames[2]) {
+    const MV_REFERENCE_FRAME ref_frames[2],
+    const BLOCK_SIZE bsize, int block) {
   if ((this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
       frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
       (ref_frames[1] == NONE ||
        frame_mv[this_mode][ref_frames[1]].as_int == 0)) {
 #if CONFIG_REF_MV
-    int16_t rfc = (ref_frames[1] == NONE) ? mode_context[ref_frames[0]] :
-        mode_context[ref_frames[0]] & (mode_context[ref_frames[1]] | 0x00ff);
+    int16_t rfc = vp10_mode_context_analyzer(mode_context,
+                                             ref_frames, bsize, block);
 #else
     int16_t rfc = mode_context[ref_frames[0]];
 #endif
@@ -3363,6 +3373,11 @@ static int check_best_zero_mv(
     int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
     int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
 
+#if !CONFIG_REF_MV
+    (void)bsize;
+    (void)block;
+#endif
+
     if (this_mode == NEARMV) {
       if (c1 > c3) return 0;
     } else if (this_mode == NEARESTMV) {
@@ -3656,7 +3671,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
           continue;
 
         if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv,
-                                this_mode, mbmi->ref_frame))
+                                this_mode, mbmi->ref_frame, bsize, i))
           continue;
 
         memcpy(orig_pre, pd->pre, sizeof(orig_pre));
@@ -4261,8 +4276,6 @@ static void single_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
   }
 }
 
-
-
 static INLINE void restore_dst_buf(MACROBLOCKD *xd,
                                    uint8_t *orig_dst[MAX_MB_PLANE],
                                    int orig_dst_stride[MAX_MB_PLANE]) {
@@ -4360,8 +4373,8 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
   int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
 
 #if CONFIG_REF_MV
-  if (refs[1] > NONE)
-    mode_ctx &= (mbmi_ext->mode_context[refs[1]] | 0x00ff);
+  mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
+                                        mbmi->ref_frame, bsize, -1);
 #endif
 
 #if CONFIG_VP9_HIGHBITDEPTH
@@ -5012,6 +5025,7 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
 
   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
     x->pred_mv_sad[ref_frame] = INT_MAX;
+    x->mbmi_ext->mode_context[ref_frame] = 0;
     if (cpi->ref_frame_flags & flag_list[ref_frame]) {
       assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
       setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
@@ -5243,7 +5257,7 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
     } else {
       const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
       if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv,
-                              this_mode, ref_frames))
+                              this_mode, ref_frames, bsize, -1))
         continue;
     }
 
@@ -5923,6 +5937,7 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
 #endif
 
   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
+    x->mbmi_ext->mode_context[ref_frame] = 0;
     if (cpi->ref_frame_flags & flag_list[ref_frame]) {
       setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
                          frame_mv[NEARESTMV], frame_mv[NEARMV],