]> granicus.if.org Git - libvpx/commitdiff
SEGMENTATION experiment:
authorPaul Wilkins <paulwilkins@google.com>
Fri, 11 Nov 2011 10:10:06 +0000 (10:10 +0000)
committerPaul Wilkins <paulwilkins@google.com>
Fri, 11 Nov 2011 18:31:21 +0000 (18:31 +0000)
Some initial cleanup to aid testing and debug.

Pull code to choose temporal or spatial encoding
out of encodeframe.c into a dedicated function
in segmentation.c.

For now disable broken temporal mode.

Move the coding of "temporal_update" flag and
only transmit if segment map update is indicated.

Rename the functions read_mb_features() and
write_mb_features() to read_mb_segid() and
read_mb_segid() as they only read and write
the macroblock segment id not any of the
features.

Change-Id: Ib75118520b1144c24d35fdfc6ce46106803cabcf

vp8/decoder/decodemv.c
vp8/decoder/decodframe.c
vp8/encoder/bitstream.c
vp8/encoder/encodeframe.c
vp8/encoder/onyx_int.h
vp8/encoder/segmentation.c
vp8/encoder/segmentation.h

index d279ebaec0c7a48de9dc35c16e6a3b4d5cf2b729..e13fd6f09a642ce5faa838f0ff6d6ac266a761cb 100644 (file)
@@ -63,7 +63,9 @@ static int vp8_read_uv_mode(vp8_reader *bc, const vp8_prob *p)
     return i;
 }
 
-static void vp8_read_mb_features(vp8_reader *r, MB_MODE_INFO *mi, MACROBLOCKD *x)
+// This function reads the current macro block's segnment id to from bitstream
+// It should only be called if a segment map update is indicated.
+static void vp8_read_mb_segid(vp8_reader *r, MB_MODE_INFO *mi, MACROBLOCKD *x)
 {
     /* Is segmentation enabled */
     if (x->segmentation_enabled && x->update_mb_segmentation_map)
@@ -90,7 +92,7 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, MODE_INFO *m, int mb_row, int mb_co
             m->mbmi.segment_id = 0;
 
             if (pbi->mb.update_mb_segmentation_map)
-                vp8_read_mb_features(bc, &m->mbmi, &pbi->mb);
+                vp8_read_mb_segid(bc, &m->mbmi, &pbi->mb);
 
 //#if CONFIG_SEGFEATURES
             if ( pbi->common.mb_no_coeff_skip &&
@@ -419,9 +421,6 @@ static void mb_mode_mv_init(VP8D_COMP *pbi)
         }
 
         read_mvcontexts(bc, mvc);
-#if CONFIG_SEGMENTATION
-    xd->temporal_update = vp8_read_bit(bc);
-#endif
     }
 }
 
@@ -480,7 +479,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
                     }
                     else
                     {
-                        vp8_read_mb_features(bc, &mi->mbmi, xd);
+                        vp8_read_mb_segid(bc, &mi->mbmi, xd);
                         mbmi->segment_flag = 1;
                         pbi->segmentation_map[index] = mbmi->segment_id;
                     }
@@ -488,12 +487,12 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
                 }
                 else
                 {
-                    vp8_read_mb_features(bc, &mi->mbmi, xd);
+                    vp8_read_mb_segid(bc, &mi->mbmi, xd);
                     pbi->segmentation_map[index] = mbmi->segment_id;
                 }
                 index++;
 #else
-                vp8_read_mb_features(bc, &mi->mbmi, xd);
+                vp8_read_mb_segid(bc, &mi->mbmi, xd);
 #endif
             }
 
index 963939cf05e8ecca100281c5086f58f0a7d9474e..5ba49915515a4d2ff8167bf627382b6528333b9e 100644 (file)
@@ -1004,8 +1004,17 @@ int vp8_decode_frame(VP8D_COMP *pbi)
     xd->segmentation_enabled = (unsigned char)vp8_read_bit(bc);
     if (xd->segmentation_enabled)
     {
-        /* Signal whether or not the segmentation map is being explicitly updated this frame. */
+        // Read whether or not the segmentation map is being explicitly
+        // updated this frame.
         xd->update_mb_segmentation_map = (unsigned char)vp8_read_bit(bc);
+
+#if CONFIG_SEGMENTATION
+        // If so what method will be used.
+        if ( xd->update_mb_segmentation_map )
+            xd->temporal_update = (unsigned char)vp8_read_bit(bc);
+#endif
+
+        // Is the segment data being updated
         xd->update_mb_segmentation_data = (unsigned char)vp8_read_bit(bc);
 
         if (xd->update_mb_segmentation_data)
index 40e845fda7874f431ec5ecfb95986963193ad165..19ec6d6228bff207a57a85da031ca08be1764da2 100644 (file)
@@ -824,7 +824,10 @@ static void write_mv
     vp8_encode_motion_vector(w, &e, mvc);
 }
 
-static void write_mb_features(vp8_writer *w, const MB_MODE_INFO *mi, const MACROBLOCKD *x)
+// This function writes the current macro block's segnment id to the bitstream
+// It should only be called if a segment map update is indicated.
+static void write_mb_segid(vp8_writer *w,
+                           const MB_MODE_INFO *mi, const MACROBLOCKD *x)
 {
     // Encode the MB segment id.
     if (x->segmentation_enabled && x->update_mb_segmentation_map)
@@ -1033,9 +1036,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
     update_mbintra_mode_probs(cpi);
 
     vp8_write_mvprobs(cpi);
-#if CONFIG_SEGMENTATION
-    vp8_write_bit(w, (xd->temporal_update) ? 1:0);
-#endif
+
     while (++mb_row < pc->mb_rows)
     {
         int mb_col = -1;
@@ -1090,18 +1091,18 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
                     {
                         vp8_write(w,1,xd->mb_segment_tree_probs[3+sum]);
                         segment_cost += vp8_cost_one(xd->mb_segment_tree_probs[3+sum]);
-                        write_mb_features(w, mi, &cpi->mb.e_mbd);
+                        write_mb_segid(w, mi, &cpi->mb.e_mbd);
                         cpi->segmentation_map[index] = segment_id;
                     }
                 }
                 else
                 {
-                    write_mb_features(w, mi, &cpi->mb.e_mbd);
+                    write_mb_segid(w, mi, &cpi->mb.e_mbd);
                     cpi->segmentation_map[index] = segment_id;
                 }
                 index++;
 #else
-                write_mb_features(w, mi, &cpi->mb.e_mbd);
+                write_mb_segid(w, mi, &cpi->mb.e_mbd);
 #endif
             }
 
@@ -1309,11 +1310,11 @@ static void write_kfmodes(VP8_COMP *cpi)
             {
 #if CONFIG_SEGMENTATION
 
-                write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
+                write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd);
                 cpi->segmentation_map[index] = segment_id;
                 index++;
 #else
-                write_mb_features(bc, &m->mbmi, &cpi->mb.e_mbd);
+                write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd);
 #endif
             }
 
@@ -2020,8 +2021,13 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
     // Indicate which features are enabled
     if (xd->segmentation_enabled)
     {
-        // Signal whether or not the segmentation map is being updated.
+        // Indicate whether or not the segmentation map is being updated.
         vp8_write_bit(bc, (xd->update_mb_segmentation_map) ? 1 : 0);
+#if CONFIG_SEGMENTATION
+        // If it is, then indicate the method that will be used.
+        if ( xd->update_mb_segmentation_map )
+            vp8_write_bit(bc, (xd->temporal_update) ? 1:0);
+#endif
         vp8_write_bit(bc, (xd->update_mb_segmentation_data) ? 1 : 0);
 
         if (xd->update_mb_segmentation_data)
index b24b39633a9ce1da49087c989173abc9fcf1e047..28ef7c6b92c049eb13665837aa2f8b7025dd8d81 100644 (file)
 #define IF_RTCD(x)  NULL
 #endif
 
-#if CONFIG_SEGMENTATION
-#define SEEK_SEGID 12
-#define SEEK_SAMEID 4
-#define SEEK_DIFFID 7
-#endif
-
 #ifdef ENC_DEBUG
 int enc_debug=0;
 int mb_row_debug, mb_col_debug;
@@ -955,8 +949,6 @@ void vp8_encode_frame(VP8_COMP *cpi)
 
 #if CONFIG_SEGMENTATION
     int segment_counts[MAX_MB_SEGMENTS + SEEK_SEGID];
-    int prob[3];
-    int new_cost, original_cost;
 #else
     int segment_counts[MAX_MB_SEGMENTS];
 #endif
@@ -1098,14 +1090,10 @@ void vp8_encode_frame(VP8_COMP *cpi)
             {
                 int i, j;
 
-                if (xd->segmentation_enabled)
+                for (i = 0; i < cpi->encoding_thread_count; i++)
                 {
-
-                    for (i = 0; i < cpi->encoding_thread_count; i++)
-                    {
-                        for (j = 0; j < 4; j++)
-                            segment_counts[j] += cpi->mb_row_ei[i].segment_counts[j];
-                    }
+                    for (j = 0; j < 4; j++)
+                        segment_counts[j] += cpi->mb_row_ei[i].segment_counts[j];
                 }
             }
 
@@ -1150,92 +1138,10 @@ void vp8_encode_frame(VP8_COMP *cpi)
 
         // Set to defaults
         vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs));
-#if CONFIG_SEGMENTATION
-
-        tot_count = segment_counts[12] + segment_counts[13] + segment_counts[14] + segment_counts[15];
-        count1 = segment_counts[12] + segment_counts[13];
-        count2 = segment_counts[14] + segment_counts[15];
-
-        if (tot_count)
-            prob[0] = (count1 * 255) / tot_count;
-
-        if (count1 > 0)
-            prob[1] = (segment_counts[12] * 255) /count1;
-
-        if (count2 > 0)
-            prob[2] = (segment_counts[14] * 255) /count2;
-
-        if (cm->frame_type != KEY_FRAME)
-        {
-            tot_count = segment_counts[4] + segment_counts[7];
-            if (tot_count)
-                xd->mb_segment_tree_probs[3] = (segment_counts[4] * 255)/tot_count;
-
-            tot_count = segment_counts[5] + segment_counts[8];
-            if (tot_count)
-                xd->mb_segment_tree_probs[4] = (segment_counts[5] * 255)/tot_count;
-
-            tot_count = segment_counts[6] + segment_counts[9];
-            if (tot_count)
-                xd->mb_segment_tree_probs[5] = (segment_counts[6] * 255)/tot_count;
-        }
-
-        tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
-        count3 = segment_counts[0] + segment_counts[1];
-        count4 = segment_counts[2] + segment_counts[3];
-
-        if (tot_count)
-            xd->mb_segment_tree_probs[0] = (count3 * 255) / tot_count;
 
-        if (count3 > 0)
-            xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count3;
-
-        if (count4 > 0)
-            xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count4;
-
-        for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
-        {
-            if (xd->mb_segment_tree_probs[i] == 0)
-                xd->mb_segment_tree_probs[i] = 1;
-        }
-
-        original_cost = count1 * vp8_cost_zero(prob[0]) + count2 * vp8_cost_one(prob[0]);
-
-        if (count1 > 0)
-            original_cost += segment_counts[12] * vp8_cost_zero(prob[1]) + segment_counts[13] * vp8_cost_one(prob[1]);
-
-        if (count2 > 0)
-            original_cost += segment_counts[14] * vp8_cost_zero(prob[2]) + segment_counts[15] * vp8_cost_one(prob[2]) ;
-
-        new_cost = 0;
-
-        if (cm->frame_type != KEY_FRAME)
-        {
-            new_cost = segment_counts[4] * vp8_cost_zero(xd->mb_segment_tree_probs[3]) + segment_counts[7] *  vp8_cost_one(xd->mb_segment_tree_probs[3]);
-
-            new_cost += segment_counts[5] * vp8_cost_zero(xd->mb_segment_tree_probs[4]) + segment_counts[8] * vp8_cost_one(xd->mb_segment_tree_probs[4]);
-
-            new_cost += segment_counts[6] * vp8_cost_zero(xd->mb_segment_tree_probs[5]) + segment_counts[9] * vp8_cost_one (xd->mb_segment_tree_probs[5]);
-        }
-
-        if (tot_count > 0)
-            new_cost += count3 * vp8_cost_zero(xd->mb_segment_tree_probs[0]) + count4 * vp8_cost_one(xd->mb_segment_tree_probs[0]);
-
-        if (count3 > 0)
-            new_cost += segment_counts[0] * vp8_cost_zero(xd->mb_segment_tree_probs[1]) + segment_counts[1] * vp8_cost_one(xd->mb_segment_tree_probs[1]);
-
-        if (count4 > 0)
-            new_cost += segment_counts[2] * vp8_cost_zero(xd->mb_segment_tree_probs[2]) + segment_counts[3] * vp8_cost_one(xd->mb_segment_tree_probs[2]) ;
-
-        if (new_cost < original_cost)
-            xd->temporal_update = 1;
-        else
-        {
-            xd->temporal_update = 0;
-            xd->mb_segment_tree_probs[0] = prob[0];
-            xd->mb_segment_tree_probs[1] = prob[1];
-            xd->mb_segment_tree_probs[2] = prob[2];
-        }
+#if CONFIG_SEGMENTATION
+        // Select the coding strategy for the segment map (temporal or spatial)
+        choose_segmap_coding_method( cpi, segment_counts );
 #else
         tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
         count1 = segment_counts[0] + segment_counts[1];
index f2bff98c57bb22469c4971970ef83ee7b64c7818..817aaafea13bb3b65c21d83ff9b0039c55746367 100644 (file)
 #define VP8_TEMPORAL_ALT_REF 1
 #endif
 
+#if CONFIG_SEGMENTATION
+#define SEEK_SEGID 12
+#define SEEK_SAMEID 4
+#define SEEK_DIFFID 7
+#endif
+
 typedef struct
 {
     int kf_indicated;
index 752053dd9f6bb3d7fc28ca8848761fff2c634d4f..ac8611ef64239608eb086e7cef65e1f338dd8007 100644 (file)
@@ -114,3 +114,129 @@ void vp8_set_segment_data(VP8_PTR ptr,
     // vpx_memcpy(cpi->mb.e_mbd.segment_feature_mask, 0,
     //            sizeof(cpi->mb.e_mbd.segment_feature_mask));
 }
+
+#if CONFIG_SEGMENTATION
+void choose_segmap_coding_method( VP8_COMP *cpi,
+                                  int * segment_counts )
+{
+    VP8_COMMON *const cm = & cpi->common;
+    MACROBLOCKD *const xd = & cpi->mb.e_mbd;
+
+    int tot_count;
+    int i;
+    int count1,count2,count3,count4;
+    int prob[3];
+    int new_cost, original_cost;
+
+    // Select the coding strategy for the segment map (temporal or spatial)
+    tot_count = segment_counts[12] + segment_counts[13] +
+                segment_counts[14] + segment_counts[15];
+    count1 = segment_counts[12] + segment_counts[13];
+    count2 = segment_counts[14] + segment_counts[15];
+
+    if (tot_count)
+        prob[0] = (count1 * 255) / tot_count;
+
+    if (count1 > 0)
+        prob[1] = (segment_counts[12] * 255) /count1;
+
+    if (count2 > 0)
+        prob[2] = (segment_counts[14] * 255) /count2;
+
+    if (cm->frame_type != KEY_FRAME)
+    {
+        tot_count = segment_counts[4] + segment_counts[7];
+        if (tot_count)
+            xd->mb_segment_tree_probs[3] = (segment_counts[4] * 255)/tot_count;
+
+        tot_count = segment_counts[5] + segment_counts[8];
+        if (tot_count)
+            xd->mb_segment_tree_probs[4] = (segment_counts[5] * 255)/tot_count;
+
+        tot_count = segment_counts[6] + segment_counts[9];
+        if (tot_count)
+            xd->mb_segment_tree_probs[5] = (segment_counts[6] * 255)/tot_count;
+    }
+
+    tot_count = segment_counts[0] + segment_counts[1] +
+                segment_counts[2] + segment_counts[3];
+    count3 = segment_counts[0] + segment_counts[1];
+    count4 = segment_counts[2] + segment_counts[3];
+
+    if (tot_count)
+        xd->mb_segment_tree_probs[0] = (count3 * 255) / tot_count;
+
+    if (count3 > 0)
+        xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count3;
+
+    if (count4 > 0)
+        xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count4;
+
+    for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
+    {
+        if (xd->mb_segment_tree_probs[i] == 0)
+            xd->mb_segment_tree_probs[i] = 1;
+    }
+
+    original_cost = count1 * vp8_cost_zero(prob[0]) +
+                    count2 * vp8_cost_one(prob[0]);
+
+    if (count1 > 0)
+        original_cost += segment_counts[12] * vp8_cost_zero(prob[1]) +
+                         segment_counts[13] * vp8_cost_one(prob[1]);
+
+    if (count2 > 0)
+        original_cost += segment_counts[14] * vp8_cost_zero(prob[2]) +
+                         segment_counts[15] * vp8_cost_one(prob[2]) ;
+
+    new_cost = 0;
+
+    if (cm->frame_type != KEY_FRAME)
+    {
+        new_cost = segment_counts[4] *
+                        vp8_cost_zero(xd->mb_segment_tree_probs[3]) +
+                   segment_counts[7] *
+                        vp8_cost_one(xd->mb_segment_tree_probs[3]);
+
+        new_cost += segment_counts[5] *
+                        vp8_cost_zero(xd->mb_segment_tree_probs[4]) +
+                    segment_counts[8] *
+                        vp8_cost_one(xd->mb_segment_tree_probs[4]);
+
+        new_cost += segment_counts[6] *
+                        vp8_cost_zero(xd->mb_segment_tree_probs[5]) +
+                    segment_counts[9] *
+                        vp8_cost_one (xd->mb_segment_tree_probs[5]);
+    }
+
+    if (tot_count > 0)
+        new_cost += count3 * vp8_cost_zero(xd->mb_segment_tree_probs[0]) +
+                    count4 * vp8_cost_one(xd->mb_segment_tree_probs[0]);
+
+    if (count3 > 0)
+        new_cost += segment_counts[0] *
+                        vp8_cost_zero(xd->mb_segment_tree_probs[1]) +
+                    segment_counts[1] *
+                        vp8_cost_one(xd->mb_segment_tree_probs[1]);
+
+    if (count4 > 0)
+        new_cost += segment_counts[2] *
+                        vp8_cost_zero(xd->mb_segment_tree_probs[2]) +
+                    segment_counts[3] *
+                        vp8_cost_one(xd->mb_segment_tree_probs[2]) ;
+
+    if (new_cost < original_cost)
+        xd->temporal_update = 1;
+    else
+    {
+        xd->temporal_update = 0;
+        xd->mb_segment_tree_probs[0] = prob[0];
+        xd->mb_segment_tree_probs[1] = prob[1];
+        xd->mb_segment_tree_probs[2] = prob[2];
+    }
+
+    // ***** TODO
+    // PGW temp test code fix value as spatial
+    xd->temporal_update = 0;
+}
+#endif
index 6c1683c17414ae9ff90aec87bf1b9453a79340b2..b6394fd095af9c04204e3f81f230397d7679d43c 100644 (file)
@@ -38,4 +38,9 @@ extern void vp8_set_segmentation_map(VP8_PTR ptr, unsigned char *segmentation_ma
 //
 extern void vp8_set_segment_data(VP8_PTR ptr, signed char *feature_data, unsigned char abs_delta);
 
+#if CONFIG_SEGMENTATION
+extern void choose_segmap_coding_method( VP8_COMP *cpi,
+                                         int * segment_counts );
+#endif
+
 #endif /* __INC_SEGMENTATION_H__ */