ref: c9130bdbbcf833595d9f3efd9bbcdb51575245d9
parent: bf25d4ad7f5f9c7b11894be140783da8ee640494
author: Paul Wilkins <paulwilkins@google.com>
date: Fri Nov 11 13:08:06 EST 2011
Segmentation experiment: Added last_segmentation_map[] structure to keep track of what we had before when doing temporal prediction. With this change the existing code does once again appear to be giving a decodable bitstream for both temporal and standard prediction modes. However, it is still somewhat messy and confused and there is no option to take advantage of spatial prediction so it could do with further work. Some housekeeping / clean out. Change-Id: I368258243f82127b81d8dffa7ada615208513b47
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -28,10 +28,6 @@
//#if CONFIG_SEGFEATURES
#include "vp8/common/seg_common.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,
@@ -837,30 +833,18 @@
case 0:
vp8_write(w, 0, x->mb_segment_tree_probs[0]);
vp8_write(w, 0, x->mb_segment_tree_probs[1]);
-#if CONFIG_SEGMENTATION
- segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]);
-#endif
break;
case 1:
vp8_write(w, 0, x->mb_segment_tree_probs[0]);
vp8_write(w, 1, x->mb_segment_tree_probs[1]);
-#if CONFIG_SEGMENTATION
- segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[1]);
-#endif
break;
case 2:
vp8_write(w, 1, x->mb_segment_tree_probs[0]);
vp8_write(w, 0, x->mb_segment_tree_probs[2]);
-#if CONFIG_SEGMENTATION
- segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[2]);
-#endif
break;
case 3:
vp8_write(w, 1, x->mb_segment_tree_probs[0]);
vp8_write(w, 1, x->mb_segment_tree_probs[2]);
-#if CONFIG_SEGMENTATION
- segment_cost += vp8_cost_one(x->mb_segment_tree_probs[0]) + vp8_cost_one(x->mb_segment_tree_probs[2]);
-#endif
break;
// TRAP.. This should not happen
@@ -867,9 +851,6 @@
default:
vp8_write(w, 0, x->mb_segment_tree_probs[0]);
vp8_write(w, 0, x->mb_segment_tree_probs[1]);
-#if CONFIG_SEGMENTATION
- segment_cost += vp8_cost_zero(x->mb_segment_tree_probs[0]) + vp8_cost_zero(x->mb_segment_tree_probs[1]);
-#endif
break;
}
}
@@ -963,7 +944,6 @@
const MV_CONTEXT *mvc = pc->fc.mvc;
MACROBLOCKD *xd = &cpi->mb.e_mbd;
#if CONFIG_SEGMENTATION
- int left_id, above_id;
int i;
int sum;
int index = 0;
@@ -1058,10 +1038,6 @@
// Make sure the MacroBlockD mode info pointer is set correctly
xd->mode_info_context = m;
-#if CONFIG_SEGMENTATION
- xd->up_available = (mb_row != 0);
- xd->left_available = (mb_col != 0);
-#endif
#ifdef ENTROPY_STATS
active_section = 9;
#endif
@@ -1085,12 +1061,10 @@
if (m->mbmi.segment_flag == 0)
{
vp8_write(w,0,xd->mb_segment_tree_probs[3+sum]);
- segment_cost += vp8_cost_zero(xd->mb_segment_tree_probs[3+sum]);
}
else
{
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_segid(w, mi, &cpi->mb.e_mbd);
cpi->segmentation_map[index] = segment_id;
}
@@ -1248,7 +1222,6 @@
/* const */
MODE_INFO *m = c->mi;
#if CONFIG_SEGMENTATION
- int left_id, above_id;
int i;
int index = 0;
#endif
@@ -1295,11 +1268,6 @@
const int ym = m->mbmi.mode;
int segment_id = m->mbmi.segment_id;
-#if CONFIG_SEGMENTATION
- MACROBLOCKD *xd = &cpi->mb.e_mbd;
- xd->up_available = (mb_row != 0);
- xd->left_available = (mb_col != 0);
-#endif
#ifdef MODE_STATS
#if CONFIG_SEGMENTATION
segment_modes_intra[segment_id]++;
@@ -1309,7 +1277,6 @@
if (cpi->mb.e_mbd.update_mb_segmentation_map)
{
#if CONFIG_SEGMENTATION
-
write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd);
cpi->segmentation_map[index] = segment_id;
index++;
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -579,7 +579,6 @@
int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
int map_index = (mb_row * cpi->common.mb_cols);
#if CONFIG_SEGMENTATION
- int left_id, above_id;
int sum;
#endif
#if CONFIG_MULTITHREAD
@@ -783,8 +782,11 @@
if (mb_row != 0)
sum += (xd->mode_info_context-cm->mb_cols)->mbmi.segment_flag;
- if (xd->mode_info_context->mbmi.segment_id == cpi->segmentation_map[(mb_row*cm->mb_cols) + mb_col])
+ if ( xd->mode_info_context->mbmi.segment_id ==
+ cpi->last_segmentation_map[(mb_row*cm->mb_cols) + mb_col] )
+ {
xd->mode_info_context->mbmi.segment_flag = 0;
+ }
else
xd->mode_info_context->mbmi.segment_flag = 1;
@@ -1129,8 +1131,9 @@
}
- // Work out the segment probabilites if segmentation is enabled
- if (xd->segmentation_enabled)
+ // Work out the segment probabilites if segmentation is enabled and
+ // the map is due to be updated
+ if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
{
int tot_count;
int i;
@@ -1137,7 +1140,7 @@
int count1,count2,count3,count4;
// Set to defaults
- vpx_memset(xd->mb_segment_tree_probs, 255 , sizeof(xd->mb_segment_tree_probs));
+ vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs));
#if CONFIG_SEGMENTATION
// Select the coding strategy for the segment map (temporal or spatial)
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -367,6 +367,9 @@
// Delete sementation map
vpx_free(cpi->segmentation_map);
+#if CONFIG_SEGMENTATION
+ vpx_free(cpi->last_segmentation_map);
+#endif
cpi->segmentation_map = 0;
vpx_free(cpi->active_map);
@@ -2124,6 +2127,13 @@
// 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));
+
+#if CONFIG_SEGMENTATION
+ // And a copy "last_segmentation_map" for temporal coding
+ CHECK_MEM_ERROR(cpi->last_segmentation_map,
+ vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
+#endif
+
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;
@@ -4798,6 +4808,16 @@
cpi->last_frame_percent_intra = cpi->this_frame_percent_intra;
}
+
+ // Take a copy of the segment map if it changed for future comparison
+#if CONFIG_SEGMENTATION
+ if ( cpi->mb.e_mbd.segmentation_enabled &&
+ cpi->mb.e_mbd.update_mb_segmentation_map )
+ {
+ vpx_memcpy( cpi->last_segmentation_map,
+ cpi->segmentation_map, cm->MBs );
+ }
+#endif
// Clear the one shot update flags for segmentation map and mode/ref loop filter deltas.
cpi->mb.e_mbd.update_mb_segmentation_map = 0;
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -516,6 +516,9 @@
#endif
unsigned char *segmentation_map;
+#if CONFIG_SEGMENTATION
+ unsigned char *last_segmentation_map;
+#endif
// segment threashold for encode breakout
int segment_encode_breakout[MAX_MB_SEGMENTS];
--- a/vp8/encoder/segmentation.c
+++ b/vp8/encoder/segmentation.c
@@ -234,9 +234,5 @@
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