From: Paul Wilkins Date: Fri, 11 Nov 2011 18:08:06 +0000 (+0000) Subject: Segmentation experiment: X-Git-Tag: v1.3.0~1217^2~380^2~157 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c9130bdbbcf833595d9f3efd9bbcdb51575245d9;p=libvpx 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 --- diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 19ec6d622..ff8fb8a48 100644 --- 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,39 +833,24 @@ static void write_mb_segid(vp8_writer *w, 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 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 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) 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 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) // 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 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) 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 @@ static void write_kfmodes(VP8_COMP *cpi) /* const */ MODE_INFO *m = c->mi; #if CONFIG_SEGMENTATION - int left_id, above_id; int i; int index = 0; #endif @@ -1295,11 +1268,6 @@ static void write_kfmodes(VP8_COMP *cpi) 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 @@ static void write_kfmodes(VP8_COMP *cpi) 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++; diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 28ef7c6b9..b48a5f687 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -579,7 +579,6 @@ void encode_mb_row(VP8_COMP *cpi, 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 @@ void encode_mb_row(VP8_COMP *cpi, 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,15 +1131,16 @@ void vp8_encode_frame(VP8_COMP *cpi) } - // 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; 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) diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index c98c98059..8dbb0059b 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -367,6 +367,9 @@ static void dealloc_compressor_data(VP8_COMP *cpi) // 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 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) // 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; @@ -4799,6 +4809,16 @@ static void encode_frame_to_data_rate 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; cpi->mb.e_mbd.update_mb_segmentation_data = 0; diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 817aaafea..8bcf65acc 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -516,6 +516,9 @@ typedef struct VP8_COMP #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]; diff --git a/vp8/encoder/segmentation.c b/vp8/encoder/segmentation.c index ac8611ef6..16dd74f04 100644 --- a/vp8/encoder/segmentation.c +++ b/vp8/encoder/segmentation.c @@ -234,9 +234,5 @@ void choose_segmap_coding_method( VP8_COMP *cpi, 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