shithub: libvpx

Download patch

ref: 56904be19de4894c40e3e6325cc7631f61ac88c5
parent: b2f64dff7dd60ae5e0e0ff994b298545dc340846
author: Paul Wilkins <paulwilkins@google.com>
date: Sat Jan 28 05:24:43 EST 2012

Use common prediction interface for segment coding.

This does not change any functionality just modifies the code to
use the common prediction module interface for coding
the segment data.

Change-Id: Ifd43e9153573365619774a4f5572215e44fb5aa3

--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -17,6 +17,7 @@
 
 //#if CONFIG_SEGFEATURES
 #include "vp8/common/seg_common.h"
+#include "vp8/common/pred_common.h"
 
 #if CONFIG_DEBUG
 #include <assert.h>
@@ -437,7 +438,68 @@
     }
 }
 
+// This function either reads the segment id for the current macroblock from
+// the bitstream or if the value is temporally predicted asserts the predicted
+// value
+static void read_mb_segment_id ( VP8D_COMP *pbi,
+                                 int mb_row, int mb_col )
+{
+    vp8_reader *const bc = & pbi->bc;
+    VP8_COMMON *const cm = & pbi->common;
+    MACROBLOCKD *const xd  = & pbi->mb;
+    MODE_INFO *mi = xd->mode_info_context;
+    MB_MODE_INFO *mbmi = &mi->mbmi;
+    int index = mb_row * pbi->common.mb_cols + mb_col;
 
+    if (xd->segmentation_enabled)
+    {
+        if (xd->update_mb_segmentation_map)
+        {
+            // Is temporal coding of the segment id for this mb enabled.
+            if (cm->temporal_update)
+            {
+                // Get the context based probability for reading the
+                // prediction status flag
+                vp8_prob pred_prob =
+                    get_pred_prob( cm, xd, PRED_SEG_ID );
+
+                // Read the prediction status flag
+                unsigned char seg_pred_flag =
+                    (unsigned char)vp8_read(bc, pred_prob );
+
+                // Store the prediction flag.
+                set_pred_flag( xd, PRED_SEG_ID, seg_pred_flag );
+
+                // If the value is flagged as correctly predicted
+                // then use the predicted value
+                if ( seg_pred_flag )
+                {
+                    mbmi->segment_id = get_pred_mb_segid( cm, index );
+                }
+                // Else .... decode it explicitly
+                else
+                {
+                    vp8_read_mb_segid(bc, mbmi, xd );
+                    cm->last_frame_seg_map[index] = mbmi->segment_id;
+                }
+
+            }
+            // Normal unpredicted coding mode
+            else
+            {
+                vp8_read_mb_segid(bc, mbmi, xd);
+                cm->last_frame_seg_map[index] = mbmi->segment_id;
+            }
+        }
+    }
+    else
+    {
+        // The encoder explicitly sets the segment_id to 0
+        // when segmentation is disabled
+        mbmi->segment_id = 0;
+    }
+}
+
 static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
 #if CONFIG_NEWNEAR
                              MODE_INFO *prev_mi,
@@ -477,53 +539,13 @@
     mb_to_right_edge = ((pbi->common.mb_cols - 1 - mb_col) * 16) << 3;
     mb_to_right_edge += RIGHT_BOTTOM_MARGIN;
 
-    /* If required read in new segmentation data for this MB */
-    if (xd->segmentation_enabled)
-    {
-        if (xd->update_mb_segmentation_map)
-        {
-            // Is temporal coding of the segment id for this mb enabled.
-            if (cm->temporal_update)
-            {
-                // Work out a context for decoding seg_id_predicted.
-                pred_context = 0;
-                if (mb_col != 0)
-                    pred_context += (mi-1)->mbmi.seg_id_predicted;
-                if (mb_row != 0)
-                    pred_context +=
-                        (mi-cm->mode_info_stride)->mbmi.seg_id_predicted;
+    // Make sure the MACROBLOCKD mode info pointer is pointed at the
+    // correct entry for the current macroblock.
+    xd->mode_info_context = mi;
 
-                mbmi->seg_id_predicted =
-                    vp8_read(bc,
-                             cm->segment_pred_probs[pred_context]);
+    // Read the macroblock segment id.
+    read_mb_segment_id ( pbi, mb_row, mb_col );
 
-                if ( mbmi->seg_id_predicted )
-                {
-                    mbmi->segment_id = cm->last_frame_seg_map[index];
-                }
-                // If the segment id was not predicted decode it explicitly
-                else
-                {
-                    vp8_read_mb_segid(bc, &mi->mbmi, xd);
-                    cm->last_frame_seg_map[index] = mbmi->segment_id;
-                }
-
-            }
-            // Normal unpredicted coding mode
-            else
-            {
-                vp8_read_mb_segid(bc, &mi->mbmi, xd);
-                cm->last_frame_seg_map[index] = mbmi->segment_id;
-            }
-            index++;
-        }
-    }
-    else
-    {
-        // The encoder explicitly sets the segment_id to 0
-        // when segmentation is disabled
-        mbmi->segment_id = 0;
-    }
 //#if CONFIG_SEGFEATURES
     if ( pbi->common.mb_no_coeff_skip &&
          ( !segfeature_active( xd,
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -1393,6 +1393,9 @@
 
     vpx_memset(pc->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * pc->mb_cols);
 
+    // Resset the macroblock mode info context to the start of the list
+    xd->mode_info_context = pc->mi;
+
 #if CONFIG_MULTITHREAD
     if (pbi->b_multithreaded_rd && pc->multi_token_partition != ONE_PARTITION)
     {
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -27,6 +27,7 @@
 
 //#if CONFIG_SEGFEATURES
 #include "vp8/common/seg_common.h"
+#include "vp8/common/pred_common.h"
 
 #if defined(SECTIONBITS_OUTPUT)
 unsigned __int64 Sectionbits[500];
@@ -944,6 +945,10 @@
     int prob_dual_pred[3];
 #endif /* CONFIG_DUALPRED */
 
+    // Values used in prediction model coding
+    vp8_prob pred_prob;
+    unsigned char prediction_flag;
+
     cpi->mb.partition_info = cpi->mb.pi;
 
     // Calculate the probabilities to be used to code the reference frame
@@ -1053,6 +1058,7 @@
 
             // Make sure the MacroBlockD mode info pointer is set correctly
             xd->mode_info_context = m;
+
 #if CONFIG_NEWNEAR
             xd->prev_mode_info_context = prev_m;
 #endif
@@ -1066,20 +1072,16 @@
                 // Is temporal coding of the segment map enabled
                 if (pc->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.seg_id_predicted;
-                    if (mb_row != 0)
-                        pred_context += (m-pc->mode_info_stride)->mbmi.seg_id_predicted;
+                    prediction_flag =
+                        get_pred_flag( xd, PRED_SEG_ID );
+                    pred_prob =
+                        get_pred_prob( pc, xd, PRED_SEG_ID);
 
-                    // Code the prediction flag for this mb
-                    vp8_write( w, m->mbmi.seg_id_predicted,
-                               pc->segment_pred_probs[pred_context]);
+                    // Code the segment id prediction flag for this mb
+                    vp8_write( w, prediction_flag, pred_prob );
 
                     // If the mbs segment id was not predicted code explicitly
-                    if (!m->mbmi.seg_id_predicted)
+                    if (!prediction_flag)
                         write_mb_segid(w, mi, &cpi->mb.e_mbd);
                 }
                 else
--- a/vp8/encoder/segmentation.c
+++ b/vp8/encoder/segmentation.c
@@ -12,6 +12,7 @@
 #include "limits.h"
 #include "vpx_mem/vpx_mem.h"
 #include "segmentation.h"
+#include "vp8/common/pred_common.h"
 
 void vp8_update_gf_useage_maps(VP8_COMP *cpi, VP8_COMMON *cm, MACROBLOCK *x)
 {
@@ -57,7 +58,7 @@
                 }
 
                 x->gf_active_ptr++;          // Step onto next entry
-                this_mb_mode_info++;           // skip to next mb
+                this_mb_mode_info++;         // skip to next mb
 
             }
 
@@ -229,34 +230,22 @@
             // Temporal prediction not allowed on key frames
             if (cm->frame_type != KEY_FRAME)
             {
-                // Get temporal prediction context
-                pred_context = 0;
-                if (mb_col != 0)
-                    pred_context +=
-                        (xd->mode_info_context-1)->mbmi.seg_id_predicted;
-                if (mb_row != 0)
-                {
-                    pred_context +=
-                        (xd->mode_info_context-cm->mode_info_stride)->
-                        mbmi.seg_id_predicted;
-                }
+                // Test to see if the segment id matches the predicted value.
+                int seg_predicted =
+                    (segment_id == get_pred_mb_segid( cm, segmap_index ));
 
-                // Test to see if the last frame segment id at the same
-                // location correctly predicts the segment_id for this MB.
-                // Update the prediction flag and count as appropriate;
-                if ( segment_id == cm->last_frame_seg_map[segmap_index] )
-                {
-                    xd->mode_info_context->mbmi.seg_id_predicted = 1;
-                    temporal_predictor_count[pred_context][1]++;
-                }
-                else
-                {
-                    xd->mode_info_context->mbmi.seg_id_predicted = 0;
-                    temporal_predictor_count[pred_context][0]++;
+                // Get the segment id prediction context
+                pred_context =
+                    get_pred_context( cm, xd, PRED_SEG_ID );
 
+                // Store the prediction status for this mb and update counts
+                // as appropriate
+                set_pred_flag( xd, PRED_SEG_ID, seg_predicted );
+                temporal_predictor_count[pred_context][seg_predicted]++;
+
+                if ( !seg_predicted )
                     // Update the "undpredicted" segment count
                     t_unpred_seg_counts[segment_id]++;
-                }
             }
 
             // Step on to the next mb