shithub: libvpx

Download patch

ref: be7e4e854c82bd9e8b5db0586873ea19156cfeef
parent: f4020e2338a1786b1db0f67075ceb7d9c01be6a3
author: Suman Sunkara <sunkaras@google.com>
date: Tue Aug 31 16:43:14 EDT 2010

Delta updates to segmentation map using left and above contexts.

-Updates by making use of spatial correlation.
-Checks if the segment_id is same as above or left context and encodes only the update to the map instead of updating individual segment_ids.

Change-Id: Ib861df97e8aa2b37516219eeddcdbaf552b6a249

--- a/configure
+++ b/configure
@@ -204,6 +204,7 @@
     sys_mman_h
 "
 EXPERIMENT_LIST="
+    segmentation
 "
 CONFIG_LIST="
     external_build
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -31,8 +31,8 @@
 #define UCONTEXT 1
 #define VCONTEXT 2
 #define Y2CONTEXT 3
-
 #define MB_FEATURE_TREE_PROBS   3
+
 #define MAX_MB_SEGMENTS         4
 
 #define MAX_REF_LF_DELTAS       4
@@ -255,8 +255,11 @@
 
     // Per frame flags that define which MB level features (such as quantizer or loop filter level)
     // are enabled and when enabled the proabilities used to decode the per MB flags in MB_MODE_INFO
-    vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];         // Probability Tree used to code Segment number
-
+#if CONFIG_SEGMENTATION
+    vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS + 3];         // Probability Tree used to code Segment number
+#else
+    vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
+#endif
     signed char segment_feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];            // Segment parameters
 
     // mode_based Loop filter adjustment
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -120,7 +120,10 @@
     MV_CONTEXT *const mvc = pc->fc.mvc;
 
     int mb_row = -1;
-
+#if CONFIG_SEGMENTATION
+    int left_id, above_id;
+    int i;
+#endif
     vp8_prob prob_intra;
     vp8_prob prob_last;
     vp8_prob prob_gf;
@@ -171,7 +174,6 @@
             MACROBLOCKD *xd = &pbi->mb;
 
             vp8dx_bool_decoder_fill(bc);
-
             // Distance of Mb to the various image edges.
             // These specified to 8th pel as they are always compared to MV values that are in 1/8th pel units
             xd->mb_to_left_edge = -((mb_col * 16) << 3);
@@ -181,7 +183,44 @@
 
             // If required read in new segmentation data for this MB
             if (pbi->mb.update_mb_segmentation_map)
-                vp8_read_mb_features(bc, mbmi, &pbi->mb);
+            {
+#if CONFIG_SEGMENTATION
+                xd->up_available = (mb_row != 0);
+                xd->left_available = (mb_col != 0);
+
+                if(xd->left_available)
+                    left_id = (mi-1)->mbmi.segment_id;
+                else
+                    left_id = 0;
+
+                if(xd->up_available)
+                    above_id = (mi-pc->mb_cols)->mbmi.segment_id;
+                else
+                    above_id = 0;
+
+                if (vp8_read(bc, xd->mb_segment_tree_probs[0]))
+                {
+                    for(i = 0; i < MAX_MB_SEGMENTS; i++)
+                    {
+                        if((left_id != i) && (above_id != i))
+                        {
+                            if (vp8_read(bc, xd->mb_segment_tree_probs[2+i]) == 0)
+                              mbmi->segment_id = i;
+                        }
+                    }
+                }
+                else
+                {
+                    if (vp8_read(bc, xd->mb_segment_tree_probs[1]))
+                        mbmi->segment_id = above_id;
+                    else
+                        mbmi->segment_id = left_id;
+
+                }
+#else
+                vp8_read_mb_features(bc, &mi->mbmi, &pbi->mb);
+#endif
+            }
 
             // Read the macroblock coeff skip flag if this feature is in use, else default to 0
             if (pc->mb_no_coeff_skip)
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -545,7 +545,7 @@
         }
     }
 
-    xd->left_context = pc->left_context;
+    xd->left_context = &pc->left_context;
     xd->mode_info_context = pc->mi;
     xd->frame_type = pc->frame_type;
     xd->mbmi.mode = DC_PRED;
@@ -560,7 +560,6 @@
     const unsigned char *data = (const unsigned char *)pbi->Source;
     const unsigned char *const data_end = data + pbi->source_sz;
     int first_partition_length_in_bytes;
-
     int mb_row;
     int i, j, k, l;
     const int *const mb_feature_data_bits = vp8_mb_feature_data_bits;
@@ -669,9 +668,12 @@
         {
             // Which macro block level features are enabled
             vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs));
-
+#if CONFIG_SEGMENTATION
             // Read the probs used to decode the segment id for each macro block.
+            for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
+#else
             for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+#endif
             {
                 // If not explicitly set value is defaulted to 255 by memset above
                 if (vp8_read_bit(bc))
--- a/vp8/decoder/demode.c
+++ b/vp8/decoder/demode.c
@@ -64,7 +64,10 @@
 
     MODE_INFO *m = cp->mi;
     const int ms = cp->mode_info_stride;
-
+#if CONFIG_SEGMENTATION
+    int left_id,above_id;
+    int i;
+#endif
     int mb_row = -1;
     vp8_prob prob_skip_false = 0;
 
@@ -78,16 +81,57 @@
         while (++mb_col < cp->mb_cols)
         {
             MB_PREDICTION_MODE y_mode;
-
             vp8dx_bool_decoder_fill(bc);
+
             // Read the Macroblock segmentation map if it is being updated explicitly this frame (reset to 0 above by default)
             // By default on a key frame reset all MBs to segment 0
             m->mbmi.segment_id = 0;
 
             if (pbi->mb.update_mb_segmentation_map)
+            {
+
+#if CONFIG_SEGMENTATION
+                MACROBLOCKD *xd = &pbi->mb;
+                xd->up_available = (mb_row != 0);
+                xd->left_available = (mb_col != 0);
+
+                if(xd->left_available)
+                    left_id = (m-1)->mbmi.segment_id;
+                else
+                    left_id = 0;
+
+                if(xd->up_available)
+                    above_id = (m-cp->mb_cols)->mbmi.segment_id;
+                else
+                    above_id = 0;
+
+                if (vp8_read(bc, xd->mb_segment_tree_probs[0]))
+                {
+                    for(i = 0; i < MAX_MB_SEGMENTS; i++)
+                    {
+                        if((left_id != i) && (above_id != i))
+                        {
+                            if (vp8_read(bc, xd->mb_segment_tree_probs[2+i]) == 0)
+                            {
+                                m->mbmi.segment_id = i;
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    if (vp8_read(bc, xd->mb_segment_tree_probs[1]))
+                        m->mbmi.segment_id = above_id;
+                    else
+                        m->mbmi.segment_id = left_id;
+
+                }
+#else
                 vp8_read_mb_features(bc, &m->mbmi, &pbi->mb);
+#endif
+            }
 
-            // Read the macroblock coeff skip flag if this feature is in use, else default to 0
+        // Read the macroblock coeff skip flag if this feature is in use, else default to 0
             if (cp->mb_no_coeff_skip)
                 m->mbmi.mb_skip_coeff = vp8_read(bc, prob_skip_false);
             else
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -85,7 +85,6 @@
     }
 }
 
-
 VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
 {
     VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
@@ -132,7 +131,6 @@
     return (VP8D_PTR) pbi;
 }
 
-
 void vp8dx_remove_decompressor(VP8D_PTR ptr)
 {
     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
@@ -306,9 +304,11 @@
 
     vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
 
-#if 0
+
     // DEBUG code
-    //vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
+#if 0
+    vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
+
     if (cm->current_video_frame <= 5)
         write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
 #endif
--- a/vp8/decoder/onyxd_int.h
+++ b/vp8/decoder/onyxd_int.h
@@ -94,7 +94,6 @@
     int current_mb_col_main;
     int decoding_thread_count;
     int allocated_decoding_thread_count;
-
     // variable for threading
     DECLARE_ALIGNED(16, MACROBLOCKD, lpfmb);
 #if CONFIG_MULTITHREAD
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -19,7 +19,9 @@
 #include "pragmas.h"
 #include "vpx_mem/vpx_mem.h"
 #include "bitstream.h"
-
+#if CONFIG_SEGMENTATION
+static int segment_cost = 0;
+#endif
 const int vp8cx_base_skip_false_prob[128] =
 {
     255, 255, 255, 255, 255, 255, 255, 255,
@@ -826,18 +828,22 @@
         case 0:
             vp8_write(w, 0, x->mb_segment_tree_probs[0]);
             vp8_write(w, 0, x->mb_segment_tree_probs[1]);
+            segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]);
             break;
         case 1:
             vp8_write(w, 0, x->mb_segment_tree_probs[0]);
             vp8_write(w, 1, x->mb_segment_tree_probs[1]);
+            segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[1]);
             break;
         case 2:
             vp8_write(w, 1, x->mb_segment_tree_probs[0]);
             vp8_write(w, 0, x->mb_segment_tree_probs[2]);
+            segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[2]);
             break;
         case 3:
             vp8_write(w, 1, x->mb_segment_tree_probs[0]);
             vp8_write(w, 1, x->mb_segment_tree_probs[2]);
+            segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[2]);
             break;
 
             // TRAP.. This should not happen
@@ -844,6 +850,7 @@
         default:
             vp8_write(w, 0, x->mb_segment_tree_probs[0]);
             vp8_write(w, 0, x->mb_segment_tree_probs[1]);
+            segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]);
             break;
         }
     }
@@ -855,7 +862,10 @@
     VP8_COMMON *const pc = & cpi->common;
     vp8_writer *const w = & cpi->bc;
     const MV_CONTEXT *mvc = pc->fc.mvc;
-
+#if CONFIG_SEGMENTATION
+    int left_id, above_id;
+    int i;
+#endif
     const int *const rfct = cpi->count_mb_ref_frame_usage;
     const int rf_intra = rfct[INTRA_FRAME];
     const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
@@ -929,13 +939,74 @@
             xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
             xd->mb_to_top_edge = -((mb_row * 16)) << 3;
             xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
-
+            xd->up_available = (mb_row != 0);
+            xd->left_available = (mb_col != 0);
 #ifdef ENTROPY_STATS
             active_section = 9;
 #endif
 
             if (cpi->mb.e_mbd.update_mb_segmentation_map)
+            {
+#if CONFIG_SEGMENTATION
+                if(xd->left_available)
+                    left_id = (m-1)->mbmi.segment_id;
+                else
+                    left_id = 0;
+
+                if(xd->up_available)
+                    above_id = (m-pc->mb_cols)->mbmi.segment_id;
+                else
+                    above_id = 0;
+
+                if ((m->mbmi.segment_id == left_id) || (m->mbmi.segment_id == above_id))
+                {
+                    vp8_write(w, 0, xd->mb_segment_tree_probs[0]);
+                    segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[0]);
+
+                    if  (left_id != above_id)
+                    {
+                        if(m->mbmi.segment_id == left_id)
+                        {
+                            vp8_write(w, 0, xd->mb_segment_tree_probs[1]);
+                            segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[1]);
+                        }
+                        else
+                        {
+                            vp8_write(w, 1, xd->mb_segment_tree_probs[1]);
+                            segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[1]);
+                        }
+                    }
+                    else
+                    {
+                        vp8_write(w, 0, xd->mb_segment_tree_probs[1]);
+                        segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[1]);
+                    }
+                }
+                else
+                {
+                    vp8_write(w, 1, xd->mb_segment_tree_probs[0]);
+                    segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[0]);
+                    for(i = 0; i < MAX_MB_SEGMENTS; i++)
+                    {
+                        if((left_id != i) && (above_id != i))
+                        {
+                            if(m->mbmi.segment_id == i)
+                            {
+                                vp8_write(w, 0, xd->mb_segment_tree_probs[2+i]);
+                                segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[2+i]);
+                            }
+                            else
+                            {
+                                vp8_write(w, 1, xd->mb_segment_tree_probs[2+i]);
+                                segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[2+i]);
+                            }
+                        }
+                    }
+                }
+#else
                 write_mb_features(w, mi, &cpi->mb.e_mbd);
+#endif
+                }
 
             if (pc->mb_no_coeff_skip)
                 vp8_encode_bool(w, m->mbmi.mb_skip_coeff, prob_skip_false);
@@ -1061,7 +1132,10 @@
     const VP8_COMMON *const c = & cpi->common;
     /* const */
     MODE_INFO *m = c->mi;
-
+#if CONFIG_SEGMENTATION
+    int left_id, above_id;
+    int i;
+#endif
     int mb_row = -1;
     int prob_skip_false = 0;
 
@@ -1086,10 +1160,75 @@
         while (++mb_col < c->mb_cols)
         {
             const int ym = m->mbmi.mode;
-
+#if CONFIG_SEGMENTATION
+            MACROBLOCKD *xd = &cpi->mb.e_mbd;
+            xd->up_available = (mb_row != 0);
+            xd->left_available = (mb_col != 0);
+#endif
             if (cpi->mb.e_mbd.update_mb_segmentation_map)
-                write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
+            {
+#if CONFIG_SEGMENTATION
+                if(xd->left_available)
+                    left_id = (m-1)->mbmi.segment_id;
+                else
+                    left_id = 0;
 
+                if(xd->up_available)
+                    above_id = (m-c->mb_cols)->mbmi.segment_id;
+                else
+                    above_id = 0;
+
+                if ((m->mbmi.segment_id == left_id) || (m->mbmi.segment_id == above_id))
+                {
+                    vp8_write(bc, 0, xd->mb_segment_tree_probs[0]);
+                    segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[0]);
+                    if  (left_id != above_id)
+                    {
+                        if(m->mbmi.segment_id == left_id)
+                        {
+                            vp8_write(bc, 0, xd->mb_segment_tree_probs[1]);
+                            segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[1]);
+                        }
+                        else
+                        {
+                            vp8_write(bc, 1, xd->mb_segment_tree_probs[1]);
+                            segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[1]);
+                        }
+                    }
+                    else
+                    {
+                        vp8_write(bc, 0, xd->mb_segment_tree_probs[1]);
+                        segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[1]);
+                    }
+                }
+                else
+                {
+                    vp8_write(bc, 1, xd->mb_segment_tree_probs[0]);
+                    segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[0]);
+
+                    for(i = 0; i < MAX_MB_SEGMENTS; i++)
+                    {
+                        if((left_id != i) && (above_id != i))
+                        {
+                            if(m->mbmi.segment_id == i)
+                            {
+                                vp8_write(bc, 0, xd->mb_segment_tree_probs[2+i]);
+                                segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[2+i]);
+                            }
+                            else
+                            {
+                                vp8_write(bc, 1, xd->mb_segment_tree_probs[2+i]);
+                                segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[2+i]);
+                            }
+                            
+                        }
+                    }
+                }
+#else
+            write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
+#endif
+            }
+
             if (c->mb_no_coeff_skip)
                 vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
 
@@ -1405,8 +1544,10 @@
     }
     else
         vp8_start_encode(bc, cx_data);
-
-
+//#if CONFIG_SEGMENTATION
+     //xd->segmentation_enabled =1;
+     xd->update_mb_segmentation_map = 1;
+//#endif
     // Signal whether or not Segmentation is enabled
     vp8_write_bit(bc, (xd->segmentation_enabled) ? 1 : 0);
 
@@ -1456,8 +1597,12 @@
 
         if (xd->update_mb_segmentation_map)
         {
+ #if CONFIG_SEGMENTATION
             // Write the probs used to decode the segment id for each macro block.
+            for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
+#else
             for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+#endif
             {
                 int Data = xd->mb_segment_tree_probs[i];
 
@@ -1621,7 +1766,9 @@
         active_section = 1;
 #endif
     }
-
+#if CONFIG_SEGMENTATION
+    //printf("\nseg_cost is %d\n",segment_cost);
+#endif
     vp8_stop_encode(bc);
 
 
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -258,8 +258,9 @@
     int recon_y_stride = cm->last_frame.y_stride;
     int recon_uv_stride = cm->last_frame.uv_stride;
     int seg_map_index = (mb_row * cpi->common.mb_cols);
-
-
+#if CONFIG_SEGMENTATION
+    int left_id, above_id;
+#endif
     // reset above block coeffs
     xd->above_context[Y1CONTEXT] = cm->above_context[Y1CONTEXT];
     xd->above_context[UCONTEXT ] = cm->above_context[UCONTEXT ];
@@ -305,6 +306,7 @@
                 xd->mbmi.segment_id = 0;
 
             vp8cx_mb_init_quantizer(cpi, x);
+
         }
         else
             xd->mbmi.segment_id = 0;         // Set to Segment 0 by default
@@ -382,9 +384,48 @@
         recon_yoffset += 16;
         recon_uvoffset += 8;
 
-        // Keep track of segment useage
-        segment_counts[xd->mbmi.segment_id] ++;
+#if CONFIG_SEGMENTATION
+    if(xd->left_available)
+        left_id = cpi->segmentation_map[seg_map_index+mb_col-1];
+    else
+        left_id = 0;
 
+    if(xd->up_available)
+        above_id = cpi->segmentation_map[seg_map_index+mb_col-cpi->common.mb_cols];
+    else
+        above_id = 0;
+
+    if ((xd->mbmi.segment_id == left_id) || (xd->mbmi.segment_id == above_id))
+    {
+        segment_counts[8]++;
+        if  (left_id != above_id)
+        {
+            if(xd->mbmi.segment_id == left_id)
+                segment_counts[10]++;
+            else
+                segment_counts[11]++;
+        }
+        else
+            segment_counts[10]++;
+    }
+    else
+    {
+        segment_counts[9]++;
+        for(i = 0; i < MAX_MB_SEGMENTS; i++)
+        {
+            if((left_id != i) && (above_id != i))
+            {
+                if(xd->mbmi.segment_id == i)
+                    segment_counts[i]++;
+                else
+                    segment_counts[MAX_MB_SEGMENTS + i]++;
+            }
+        }
+    }
+
+#else
+    segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
+#endif
         // skip to next mb
         xd->mode_info_context++;
 
@@ -406,10 +447,6 @@
     xd->mode_info_context++;
 }
 
-
-
-
-
 void vp8_encode_frame(VP8_COMP *cpi)
 {
     int mb_row;
@@ -419,7 +456,11 @@
 
     int i;
     TOKENEXTRA *tp = cpi->tok;
+#if CONFIG_SEGMENTATION
+    int segment_counts[MAX_MB_SEGMENTS + 8];
+#else
     int segment_counts[MAX_MB_SEGMENTS];
+#endif
     int totalrate;
 
     if (cm->frame_type != KEY_FRAME)
@@ -447,7 +488,6 @@
     //cpi->prob_intra_coded = 255;
     //}
 
-
     xd->gf_active_ptr = (signed char *)cm->gf_active_flags;     // Point to base of GF active flags data structure
 
     x->vector_range = 32;
@@ -467,7 +507,7 @@
 
 #if 0
     // Experimental code
-    cpi->frame_distortion = 0;     
+    cpi->frame_distortion = 0;
     cpi->last_mb_distortion = 0;
 #endif
 
@@ -687,32 +727,64 @@
 
         // Set to defaults
         vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs));
+#if CONFIG_SEGMENTATION
+        tot_count = segment_counts[8] + segment_counts[9];
 
+        if (tot_count)
+            xd->mb_segment_tree_probs[0] = (segment_counts[8] * 255) / tot_count;
+
+        tot_count = segment_counts[10] + segment_counts[11];
+
+        if (tot_count > 0)
+            xd->mb_segment_tree_probs[1] = (segment_counts[10] * 255) / tot_count;
+
+        tot_count = segment_counts[0] + segment_counts[4] ;
+
+        if (tot_count > 0)
+            xd->mb_segment_tree_probs[2] = (segment_counts[0]  * 255) / tot_count;
+
+        tot_count = segment_counts[1] + segment_counts[5];
+
+        if (tot_count > 0)
+            xd->mb_segment_tree_probs[3] = (segment_counts[1] * 255) / tot_count;
+
+        tot_count = segment_counts[2] + segment_counts[6];
+
+        if (tot_count > 0)
+            xd->mb_segment_tree_probs[4] = (segment_counts[2] * 255) / tot_count;
+
+        tot_count = segment_counts[3] + segment_counts[7];
+
+        if (tot_count > 0)
+            xd->mb_segment_tree_probs[5] = (segment_counts[3] * 255) / tot_count;
+
+#else
         tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
 
         if (tot_count)
-        {
             xd->mb_segment_tree_probs[0] = ((segment_counts[0] + segment_counts[1]) * 255) / tot_count;
 
-            tot_count = segment_counts[0] + segment_counts[1];
+        tot_count = segment_counts[0] + segment_counts[1];
 
-            if (tot_count > 0)
-            {
-                xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count;
-            }
+        if (tot_count > 0)
+            xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count;
 
-            tot_count = segment_counts[2] + segment_counts[3];
+        tot_count = segment_counts[2] + segment_counts[3];
 
-            if (tot_count > 0)
-                xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count;
+        if (tot_count > 0)
+            xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count;
 
-            // Zero probabilities not allowed
-            for (i = 0; i < MB_FEATURE_TREE_PROBS; i ++)
+#endif
+        // Zero probabilities not allowed
+#if CONFIG_SEGMENTATION
+            for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
+#else
+            for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
+#endif
             {
                 if (xd->mb_segment_tree_probs[i] == 0)
                     xd->mb_segment_tree_probs[i] = 1;
             }
-        }
     }
 
     // 256 rate units to the bit
--- a/vp8/encoder/ethreading.c
+++ b/vp8/encoder/ethreading.c
@@ -86,7 +86,7 @@
                     for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
                     {
                         int seg_map_index = (mb_row * cm->mb_cols);
-
+   
                         while (mb_col > (*last_row_current_mb_col - 1) && *last_row_current_mb_col != cm->mb_cols - 1)
                         {
                             x86_pause_hint();
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -252,7 +252,6 @@
 
     // Copy in the new segmentation map
     vpx_memcpy(cpi->segmentation_map, segmentation_map, (cpi->common.mb_rows * cpi->common.mb_cols));
-
     // Signal that the map should be updated.
     cpi->mb.e_mbd.update_mb_segmentation_map = 1;
     cpi->mb.e_mbd.update_mb_segmentation_data = 1;
@@ -278,13 +277,28 @@
 static void segmentation_test_function(VP8_PTR ptr)
 {
     VP8_COMP *cpi = (VP8_COMP *)(ptr);
-
+#if CONFIG_SEGMENTATION
+    int i,j;
+#endif
     unsigned char *seg_map;
     signed char feature_data[MB_LVL_MAX][MAX_MB_SEGMENTS];
-
+    CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
     // Create a temporary map for segmentation data.
-    CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+#if CONFIG_SEGMENTATION
+    // MB loop to set local segmentation map
+    for (i = 0; i < cpi->common.mb_rows; i++ )
+    {
+        for (j = 0; j < cpi->common.mb_cols; j++ )
+        {
+            if (j >= cpi->common.mb_cols/4 && j < (cpi->common.mb_cols*3)/4 )
+                seg_map[(i*cpi->common.mb_cols) + j] = 2;
+            else
+                seg_map[(i*cpi->common.mb_cols) + j] = 0;
+        }
+    }
 
+#endif
+
     // MB loop to set local segmentation map
     /*for ( i = 0; i < cpi->common.mb_rows; i++ )
     {
@@ -344,7 +358,7 @@
     int mbs_in_frame = cpi->common.mb_rows * cpi->common.mb_cols;
 
     // Create a temporary map for segmentation data.
-    CHECK_MEM_ERROR(seg_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+    CHECK_MEM_ERROR(seg_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
 
     cpi->cyclic_refresh_q = Q;
 
@@ -1924,7 +1938,7 @@
         VP8_COMP *cpi;
         VP8_PTR   ptr;
     } ctx;
-    
+
     VP8_COMP *cpi;
     VP8_COMMON *cm;
 
@@ -1987,7 +2001,7 @@
 
 
     // Create the encoder segmentation map and set all entries to 0
-    CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
+    CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
     CHECK_MEM_ERROR(cpi->active_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
     vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols));
     cpi->active_map_enabled = 0;
@@ -2026,13 +2040,12 @@
     cpi->cyclic_refresh_q = 32;
 
     if (cpi->cyclic_refresh_mode_enabled)
-    {
         CHECK_MEM_ERROR(cpi->cyclic_refresh_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
-    }
     else
         cpi->cyclic_refresh_map = (signed char *) NULL;
 
     // Test function for segmentation
+
     //segmentation_test_function((VP8_PTR) cpi);
 
     // Loop filter mode / ref deltas test function
@@ -3529,11 +3542,16 @@
     int drop_mark75 = drop_mark * 2 / 3;
     int drop_mark50 = drop_mark / 4;
     int drop_mark25 = drop_mark / 8;
-
+#if CONFIG_SEGMENTATION
+   int i;
+#endif
     // Clear down mmx registers to allow floating point in what follows
     vp8_clear_system_state();
 
     // Test code for segmentation of gf/arf (0,0)
+#if CONFIG_SEGMENTATION
+    segmentation_test_function((VP8_PTR) cpi);
+#endif
     //segmentation_test_function((VP8_PTR) cpi);
 
     // For an alt ref frame in 2 pass we skip the call to the second pass function that sets the target bandwidth
@@ -4039,7 +4057,28 @@
             vp8_setup_key_frame(cpi);
 
         // transform / motion compensation build reconstruction frame
-
+#if CONFIG_SEGMENTATION
+   // MB loop to set local segmentation map
+    for (i = 0; i < cpi->common.mb_rows; i++ )
+    {
+        int j = (cpi->common.mb_cols/4);
+        int k = (cpi->common.mb_cols*3)/4;
+        if((cm->current_video_frame%2 == 0 && i<cpi->common.mb_rows/2)||(cm->current_video_frame%2 == 1 && i>cpi->common.mb_rows/2))
+        {
+            cpi->segmentation_map[(i*cpi->common.mb_cols) + j] = 2;
+            cpi->segmentation_map[(i*cpi->common.mb_cols) + j-1] = 2;
+            cpi->segmentation_map[(i*cpi->common.mb_cols) + k] = 2;
+            cpi->segmentation_map[(i*cpi->common.mb_cols) + k+1] = 2;
+        }
+        else if((cm->current_video_frame%2 == 1 && i<cpi->common.mb_rows/2)||(cm->current_video_frame%2 == 0 && i>cpi->common.mb_rows/2))
+        {
+            cpi->segmentation_map[(i*cpi->common.mb_cols) + j] = 0;
+            cpi->segmentation_map[(i*cpi->common.mb_cols) + j-1] = 0;
+            cpi->segmentation_map[(i*cpi->common.mb_cols) + k] = 0;
+            cpi->segmentation_map[(i*cpi->common.mb_cols) + k+1] = 0;
+        }
+    }
+#endif
         vp8_encode_frame(cpi);
         cpi->projected_frame_size -= vp8_estimate_entropy_savings(cpi);
         cpi->projected_frame_size = (cpi->projected_frame_size > 0) ? cpi->projected_frame_size : 0;
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -187,7 +187,11 @@
     MACROBLOCK  mb;
     int mb_row;
     TOKENEXTRA *tp;
+#if CONFIG_SEGMENTATION
+    int segment_counts[MAX_MB_SEGMENTS + 8];
+#else
     int segment_counts[MAX_MB_SEGMENTS];
+#endif
     int totalrate;
     int current_mb_col;
 } MB_ROW_COMP;