From 340c7a48e6b1f199d93ce7888a961acf5f13d701 Mon Sep 17 00:00:00 2001
From: Paul Wilkins <paulwilkins@google.com>
Date: Fri, 7 Jun 2013 14:59:53 +0100
Subject: [PATCH] Change to segment ref frame feature.

Simplify feature to only support a single reference frame
instead of a mask.

Change-Id: I5dd3a98c7a224aafb35708850ab82e2f220e68fb
---
 vp9/common/vp9_seg_common.c   | 15 ---------------
 vp9/common/vp9_seg_common.h   | 10 ----------
 vp9/decoder/vp9_decodemv.c    | 19 ++++---------------
 vp9/encoder/vp9_bitstream.c   | 14 +++-----------
 vp9/encoder/vp9_encodeframe.c | 30 +++++-------------------------
 vp9/encoder/vp9_onyx_if.c     | 10 +++++-----
 vp9/encoder/vp9_rdopt.c       | 11 +----------
 7 files changed, 18 insertions(+), 91 deletions(-)

diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c
index 890dcce373..e54e6c7cbd 100644
--- a/vp9/common/vp9_seg_common.c
+++ b/vp9/common/vp9_seg_common.c
@@ -70,21 +70,6 @@ int vp9_get_segdata(const MACROBLOCKD *xd, int segment_id,
   return xd->segment_feature_data[segment_id][feature_id];
 }
 
-void vp9_clear_segref(MACROBLOCKD *xd, int segment_id) {
-  xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] = 0;
-}
-
-void vp9_set_segref(MACROBLOCKD *xd, int segment_id,
-                    MV_REFERENCE_FRAME ref_frame) {
-  xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] |= 1 << ref_frame;
-}
-
-int vp9_check_segref(const MACROBLOCKD *xd, int segment_id,
-                     MV_REFERENCE_FRAME ref_frame) {
-  return (xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] &
-         (1 << ref_frame)) ? 1 : 0;
-}
-
 
 const vp9_tree_index vp9_segment_tree[14] = {
   2,  4,  6,  8, 10, 12,
diff --git a/vp9/common/vp9_seg_common.h b/vp9/common/vp9_seg_common.h
index c424a57f4f..74ba03c3e3 100644
--- a/vp9/common/vp9_seg_common.h
+++ b/vp9/common/vp9_seg_common.h
@@ -45,16 +45,6 @@ int vp9_get_segdata(const MACROBLOCKD *xd,
                     int segment_id,
                     SEG_LVL_FEATURES feature_id);
 
-void vp9_clear_segref(MACROBLOCKD *xd, int segment_id);
-
-void vp9_set_segref(MACROBLOCKD *xd,
-                    int segment_id,
-                    MV_REFERENCE_FRAME ref_frame);
-
-int vp9_check_segref(const MACROBLOCKD *xd,
-                     int segment_id,
-                     MV_REFERENCE_FRAME ref_frame);
-
 extern const vp9_tree_index vp9_segment_tree[14];
 
 #endif  // VP9_COMMON_VP9_SEG_COMMON_H_
diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c
index cb16ccdf3c..e0f128f57c 100644
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -241,22 +241,11 @@ static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r,
                            int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
   VP9_COMMON *const cm = &pbi->common;
   MACROBLOCKD *const xd = &pbi->mb;
-  int seg_ref_count = 0;
   const int seg_ref_active = vp9_segfeature_active(xd, segment_id,
                                                    SEG_LVL_REF_FRAME);
-  const int intra = vp9_check_segref(xd, segment_id, INTRA_FRAME);
-  const int last = vp9_check_segref(xd, segment_id, LAST_FRAME);
-  const int golden = vp9_check_segref(xd, segment_id, GOLDEN_FRAME);
-  const int altref = vp9_check_segref(xd, segment_id, ALTREF_FRAME);
-
-  // If segment coding enabled does the segment allow for more than one
-  // possible reference frame
-  if (seg_ref_active)
-    seg_ref_count = intra + last + golden + altref;
-
-  // Segment reference frame features not available or allows for
-  // multiple reference frame options
-  if (!seg_ref_active || seg_ref_count > 1) {
+
+  // Segment reference frame features not available.
+  if (!seg_ref_active) {
     int is_comp;
     int comp_ctx = vp9_get_pred_context(cm, xd, PRED_COMP_INTER_INTER);
 
@@ -291,7 +280,7 @@ static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r,
       }
     }
   } else {
-    ref_frame[0] = last ? LAST_FRAME : golden ? GOLDEN_FRAME : ALTREF_FRAME;
+    ref_frame[0] = vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME);
     ref_frame[1] = NONE;
   }
 }
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 28e107b552..55ed2a4506 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -483,18 +483,9 @@ static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) {
   const int segment_id = mi->segment_id;
   int seg_ref_active = vp9_segfeature_active(xd, segment_id,
                                              SEG_LVL_REF_FRAME);
-  int seg_ref_count = 0;
-
-  if (seg_ref_active) {
-    seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME) +
-                    vp9_check_segref(xd, segment_id, LAST_FRAME) +
-                    vp9_check_segref(xd, segment_id, GOLDEN_FRAME) +
-                    vp9_check_segref(xd, segment_id, ALTREF_FRAME);
-  }
-
   // If segment level coding of this signal is disabled...
   // or the segment allows multiple reference frame options
-  if (!seg_ref_active || (seg_ref_count > 1)) {
+  if (!seg_ref_active) {
     // does the feature use compound prediction or not
     // (if not specified at the frame/segment level)
     if (pc->comp_pred_mode == HYBRID_PREDICTION) {
@@ -517,7 +508,8 @@ static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) {
     }
   } else {
     assert(mi->ref_frame[1] <= INTRA_FRAME);
-    assert(vp9_check_segref(xd, segment_id, mi->ref_frame[0]));
+    assert(vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME) ==
+           mi->ref_frame[0]);
   }
 
   // if using the prediction mdoel we have nothing further to do because
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 8980306042..047bbb5e91 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -575,11 +575,7 @@ static void set_offsets(VP9_COMP *cpi,
 
     if (xd->segmentation_enabled && cpi->seg0_cnt > 0 &&
         !vp9_segfeature_active(xd, 0, SEG_LVL_REF_FRAME) &&
-        vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME) &&
-        vp9_check_segref(xd, 1, INTRA_FRAME)  +
-        vp9_check_segref(xd, 1, LAST_FRAME)   +
-        vp9_check_segref(xd, 1, GOLDEN_FRAME) +
-        vp9_check_segref(xd, 1, ALTREF_FRAME) == 1) {
+        vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME)) {
       cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt;
     } else {
       const int y = mb_row & ~3;
@@ -638,20 +634,13 @@ static void update_stats(VP9_COMP *cpi, int mi_row, int mi_col) {
     cpi->intra_inter_count[vp9_get_pred_context(cm, xd, PRED_INTRA_INTER)]
                           [mbmi->ref_frame[0] > INTRA_FRAME]++;
 
-    // If we have just a single reference frame coded for a segment then
-    // exclude from the reference frame counts used to work out
-    // probabilities. NOTE: At the moment we dont support custom trees
-    // for the reference frame coding for each segment but this is a
-    // possible future action.
+    // If the segment reference feature is enabled we have only a single
+    // reference frame allowed for the segment so exclude it from
+    // the reference frame counts used to work out probabilities.
     segment_id = mbmi->segment_id;
     seg_ref_active = vp9_segfeature_active(xd, segment_id,
                                            SEG_LVL_REF_FRAME);
-    if (mbmi->ref_frame[0] > INTRA_FRAME &&
-        (!seg_ref_active ||
-         ((vp9_check_segref(xd, segment_id, INTRA_FRAME) +
-           vp9_check_segref(xd, segment_id, LAST_FRAME) +
-           vp9_check_segref(xd, segment_id, GOLDEN_FRAME) +
-           vp9_check_segref(xd, segment_id, ALTREF_FRAME)) > 1))) {
+    if ((mbmi->ref_frame[0] > INTRA_FRAME) && !seg_ref_active) {
       if (cm->comp_pred_mode == HYBRID_PREDICTION)
         cpi->comp_inter_count[vp9_get_pred_context(cm, xd,
                                                    PRED_COMP_INTER_INTER)]
@@ -1616,15 +1605,6 @@ static int check_dual_ref_flags(VP9_COMP *cpi) {
   int ref_flags = cpi->ref_frame_flags;
 
   if (vp9_segfeature_active(xd, 1, SEG_LVL_REF_FRAME)) {
-    if ((ref_flags & (VP9_LAST_FLAG | VP9_GOLD_FLAG)) == (VP9_LAST_FLAG | VP9_GOLD_FLAG) &&
-        vp9_check_segref(xd, 1, LAST_FRAME))
-      return 1;
-    if ((ref_flags & (VP9_GOLD_FLAG | VP9_ALT_FLAG)) == (VP9_GOLD_FLAG | VP9_ALT_FLAG) &&
-        vp9_check_segref(xd, 1, GOLDEN_FRAME))
-      return 1;
-    if ((ref_flags & (VP9_ALT_FLAG  | VP9_LAST_FLAG)) == (VP9_ALT_FLAG  | VP9_LAST_FLAG) &&
-        vp9_check_segref(xd, 1, ALTREF_FRAME))
-      return 1;
     return 0;
   } else {
     return (!!(ref_flags & VP9_GOLD_FLAG) +
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 73220dcd9c..5bd4e7857a 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -413,7 +413,7 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
 
         // Segment coding disabled for compred testing
         if (high_q || (cpi->static_mb_pct == 100)) {
-          vp9_set_segref(xd, 1, ALTREF_FRAME);
+          vp9_set_segdata(xd, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
           vp9_enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
           vp9_enable_segfeature(xd, 1, SEG_LVL_SKIP);
         }
@@ -440,10 +440,10 @@ static void configure_static_seg_features(VP9_COMP *cpi) {
       vp9_enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
 
       // All mbs should use ALTREF_FRAME
-      vp9_clear_segref(xd, 0);
-      vp9_set_segref(xd, 0, ALTREF_FRAME);
-      vp9_clear_segref(xd, 1);
-      vp9_set_segref(xd, 1, ALTREF_FRAME);
+      vp9_clear_segdata(xd, 0, SEG_LVL_REF_FRAME);
+      vp9_set_segdata(xd, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
+      vp9_clear_segdata(xd, 1, SEG_LVL_REF_FRAME);
+      vp9_set_segdata(xd, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
 
       // Skip all MBs if high Q (0,0 mv and skip coeffs)
       if (high_q) {
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 0fea2b9319..cb081a316f 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1635,16 +1635,7 @@ static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
   MACROBLOCKD *const xd = &cpi->mb.e_mbd;
   int seg_ref_active = vp9_segfeature_active(xd, segment_id,
                                              SEG_LVL_REF_FRAME);
-  int seg_ref_count = 0;
-
   if (seg_ref_active) {
-    seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME)  +
-                    vp9_check_segref(xd, segment_id, LAST_FRAME)   +
-                    vp9_check_segref(xd, segment_id, GOLDEN_FRAME) +
-                    vp9_check_segref(xd, segment_id, ALTREF_FRAME);
-  }
-
-  if (seg_ref_active && seg_ref_count == 1) {
     vpx_memset(ref_costs_single, 0, MAX_REF_FRAMES * sizeof(*ref_costs_single));
     vpx_memset(ref_costs_comp,   0, MAX_REF_FRAMES * sizeof(*ref_costs_comp));
     *comp_mode_p = 128;
@@ -2685,7 +2676,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
     // If the segment reference frame feature is enabled....
     // then do nothing if the current ref frame is not allowed..
     if (vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME) &&
-        !vp9_check_segref(xd, segment_id, ref_frame)) {
+        vp9_get_segdata(xd, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
       continue;
     // If the segment skip feature is enabled....
     // then do nothing if the current mode is not allowed..
-- 
GitLab