From 6394ef28d719f74f2757f8aad245e43e5401c9e6 Mon Sep 17 00:00:00 2001
From: Paul Wilkins <paulwilkins@google.com>
Date: Tue, 15 Nov 2011 15:22:26 +0000
Subject: [PATCH] Further clean up of Segmentation experiment code

Changed name and sense of segment_flag to "seg_id_predicted"
Added some additional comments and retested.

I also did some experimentation with a spatial prediction option
using a similar strategy to the temporal mode implemented.
This helps in some cases where temporal prediction is bad but
I suspect there is more overlap here with work on a larger scale
block structure and spatial correlation will likely be better
handled through that mechanism.

Next check in will remove #ifdefs and legacy mode code.

Change-Id: I3b382b65ed2a57bd7775ac0f3a01a9508a209cbc
---
 vp8/common/blockd.h        |  8 +++++---
 vp8/decoder/decodemv.c     | 18 +++++++++++-------
 vp8/encoder/bitstream.c    | 22 ++++++++++++----------
 vp8/encoder/segmentation.c | 21 ++++++++++-----------
 4 files changed, 38 insertions(+), 31 deletions(-)

diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
index c477d2d6d9..9e23f4d7da 100644
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -181,13 +181,15 @@ typedef struct
     MB_PREDICTION_MODE mode, uv_mode;
     MV_REFERENCE_FRAME ref_frame;
     int_mv mv;
-#if CONFIG_SEGMENTATION
-    unsigned char segment_flag;
-#endif
     unsigned char partitioning;
     unsigned char mb_skip_coeff;                                /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */
     unsigned char need_to_clamp_mvs;
     unsigned char segment_id;                  /* Which set of segmentation parameters should be used for this MB */
+#if CONFIG_SEGMENTATION
+    // Flag used when temporal prediction of segment map is enabled.
+    // 1 means it is predicted 0 that it must be coded explicitly
+    unsigned char seg_id_predicted;
+#endif
 
 } MB_MODE_INFO;
 
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 416865cae5..d75469f876 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -459,30 +459,34 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
     if (xd->update_mb_segmentation_map)
             {
 #if CONFIG_SEGMENTATION
+                // Is temporal coding of the segment id for this mb enabled.
                 if (xd->temporal_update)
                 {
+                    // Work out a context for decoding seg_id_predicted.
                     pred_context = 0;
-
                     if (mb_col != 0)
-                        pred_context += (mi-1)->mbmi.segment_flag;
+                        pred_context += (mi-1)->mbmi.seg_id_predicted;
                     if (mb_row != 0)
                         pred_context +=
-                            (mi-pbi->common.mb_cols)->mbmi.segment_flag;
+                            (mi-pbi->common.mb_cols)->mbmi.seg_id_predicted;
+
+                    mbmi->seg_id_predicted =
+                        vp8_read(bc,
+                                 xd->mb_segment_pred_probs[pred_context]);
 
-                    if (vp8_read(bc,
-                                 xd->mb_segment_pred_probs[pred_context]) == 0)
+                    if ( mbmi->seg_id_predicted )
                     {
                         mbmi->segment_id = pbi->segmentation_map[index];
-                        mbmi->segment_flag = 0;
                     }
+                    // If the segment id was not predicted decode it explicitly
                     else
                     {
                         vp8_read_mb_segid(bc, &mi->mbmi, xd);
-                        mbmi->segment_flag = 1;
                         pbi->segmentation_map[index] = mbmi->segment_id;
                     }
 
                 }
+                // Normal unpredicted coding mode
                 else
                 {
                     vp8_read_mb_segid(bc, &mi->mbmi, xd);
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index eda40f375e..cea5a6ce4d 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -1041,26 +1041,28 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
             if (cpi->mb.e_mbd.update_mb_segmentation_map)
             {
 #if CONFIG_SEGMENTATION
+                // Is temporal coding of the segment map enabled
                 if (xd->temporal_update)
                 {
+                    // Look at whether neighbours were successfully predicted
+                    // to create a context for the seg_id_predicted flag.
                     pred_context = 0;
                     if (mb_col != 0)
-                        pred_context +=  (m-1)->mbmi.segment_flag;
+                        pred_context += (m-1)->mbmi.seg_id_predicted;
                     if (mb_row != 0)
-                        pred_context += (m-pc->mb_cols)->mbmi.segment_flag;
+                        pred_context += (m-pc->mb_cols)->mbmi.seg_id_predicted;
 
-                    if (m->mbmi.segment_flag == 0)
-                    {
-                        vp8_write(w,0,xd->mb_segment_pred_probs[pred_context]);
-                    }
-                    else
-                    {
-                        vp8_write(w,1,xd->mb_segment_pred_probs[pred_context]);
+                    // Code the prediction flag for this mb
+                    vp8_write( w, m->mbmi.seg_id_predicted,
+                               xd->mb_segment_pred_probs[pred_context]);
+
+                    // If the mbs segment id was not predicted code explicitly
+                    if (!m->mbmi.seg_id_predicted)
                         write_mb_segid(w, mi, &cpi->mb.e_mbd);
-                    }
                 }
                 else
                 {
+                    // Normal undpredicted coding
                     write_mb_segid(w, mi, &cpi->mb.e_mbd);
                 }
                 index++;
diff --git a/vp8/encoder/segmentation.c b/vp8/encoder/segmentation.c
index 2eb0ce408c..2dc96c61b2 100644
--- a/vp8/encoder/segmentation.c
+++ b/vp8/encoder/segmentation.c
@@ -226,25 +226,26 @@ void choose_segmap_coding_method( VP8_COMP *cpi )
                 pred_context = 0;
                 if (mb_col != 0)
                     pred_context +=
-                        (xd->mode_info_context-1)->mbmi.segment_flag;
+                        (xd->mode_info_context-1)->mbmi.seg_id_predicted;
                 if (mb_row != 0)
+                {
                     pred_context +=
-                        (xd->mode_info_context-cm->mb_cols)->mbmi.segment_flag;
+                        (xd->mode_info_context-cm->mb_cols)->
+                        mbmi.seg_id_predicted;
+                }
 
                 // Test to see if the last frame segment id at the same
-                // locationcorrectly predicts the segment_id for this MB.
+                // location correctly predicts the segment_id for this MB.
                 // Update the prediction flag and count as appropriate;
                 if ( segment_id == cpi->last_segmentation_map[segmap_index] )
                 {
-                    //xd->mode_info_context->mbmi.segment_predicted = 1;
-                    xd->mode_info_context->mbmi.segment_flag = 0;
-                    temporal_predictor_count[pred_context][0]++;
+                    xd->mode_info_context->mbmi.seg_id_predicted = 1;
+                    temporal_predictor_count[pred_context][1]++;
                 }
                 else
                 {
-                    //xd->mode_info_context->mbmi.segment_predicted = 0;
-                    xd->mode_info_context->mbmi.segment_flag = 1;
-                    temporal_predictor_count[pred_context][1]++;
+                    xd->mode_info_context->mbmi.seg_id_predicted = 0;
+                    temporal_predictor_count[pred_context][0]++;
 
                     // Update the "undpredicted" segment count
                     t_unpred_seg_counts[segment_id]++;
@@ -317,8 +318,6 @@ void choose_segmap_coding_method( VP8_COMP *cpi )
          xd->temporal_update = 0;
          vpx_memcpy( xd->mb_segment_tree_probs,
                      no_pred_tree, sizeof(no_pred_tree) );
-         //vpx_memcpy( &xd->mb_segment_pred_probs,
-         //            t_nopred_prob, sizeof(t_nopred_prob) );
     }
 }
 #endif
-- 
GitLab