diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index 4989b34af6a3cbf579fa8af7474fa7ff829db8c9..6b0ea61cbeacc2557771c44fe4aeb899c38a9972 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -32,7 +32,7 @@ void vpx_log(const char *format, ...); #define DCPREDCNTTHRESH 3 #define MB_FEATURE_TREE_PROBS 3 -#define SEGMENT_PREDICTION_PROBS 3 +#define PREDICTION_PROBS 3 #define MAX_MB_SEGMENTS 4 @@ -278,9 +278,6 @@ typedef struct MacroBlockD // Probability Tree used to code Segment number vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS]; - // Context probabilities when using predictive coding of segment id - vp8_prob mb_segment_pred_probs[SEGMENT_PREDICTION_PROBS]; - unsigned char temporal_update; // Segment features signed char segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX]; diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h index 0e078ebb880ead29e498b2562c4996fe9c37e0a3..e5c7b912ab598b62a7971801864b88e8850303ea 100644 --- a/vp8/common/onyxc_int.h +++ b/vp8/common/onyxc_int.h @@ -181,6 +181,9 @@ typedef struct VP8Common MODE_INFO *prev_mi; /* 'mi' from last frame (points into prev_mip) */ + // Persistent mb segment id map used in prediction. + unsigned char * last_frame_seg_map; + INTERPOLATIONFILTERTYPE mcomp_filter_type; LOOPFILTERTYPE filter_type; @@ -223,6 +226,10 @@ typedef struct VP8Common #endif vp8_prob i8x8_mode_prob [VP8_UV_MODES-1]; + // Context probabilities when using predictive coding of segment id + vp8_prob segment_pred_probs[PREDICTION_PROBS]; + unsigned char temporal_update; + FRAME_CONTEXT lfc_a; /* last alt ref entropy */ FRAME_CONTEXT lfc; /* last frame entropy */ diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index b33d15f88e0f39b8e1f0a661cb16ace2e9801a6b..5e7d5c09930d3529e63b8a0834fcc3651f65e74d 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -83,12 +83,12 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, MB_PREDICTION_MODE y_mode; // Read the Macroblock segmentation map if it is being updated explicitly - // this frame (reset to 0 above by default). + // this frame (reset to 0 by default). m->mbmi.segment_id = 0; if (pbi->mb.update_mb_segmentation_map) { vp8_read_mb_segid(bc, &m->mbmi, &pbi->mb); - pbi->segmentation_map[map_index] = m->mbmi.segment_id; + pbi->common.last_frame_seg_map[map_index] = m->mbmi.segment_id; } //#if CONFIG_SEGFEATURES @@ -435,6 +435,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, #endif int mb_row, int mb_col) { + VP8_COMMON *const cm = & pbi->common; vp8_reader *const bc = & pbi->bc; MV_CONTEXT *const mvc = pbi->common.fc.mvc; const int mis = pbi->common.mode_info_stride; @@ -473,7 +474,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, if (xd->update_mb_segmentation_map) { // Is temporal coding of the segment id for this mb enabled. - if (xd->temporal_update) + if (cm->temporal_update) { // Work out a context for decoding seg_id_predicted. pred_context = 0; @@ -481,21 +482,21 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, pred_context += (mi-1)->mbmi.seg_id_predicted; if (mb_row != 0) pred_context += - (mi-pbi->common.mode_info_stride)->mbmi.seg_id_predicted; + (mi-cm->mode_info_stride)->mbmi.seg_id_predicted; mbmi->seg_id_predicted = vp8_read(bc, - xd->mb_segment_pred_probs[pred_context]); + cm->segment_pred_probs[pred_context]); if ( mbmi->seg_id_predicted ) { - mbmi->segment_id = pbi->segmentation_map[index]; + 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); - pbi->segmentation_map[index] = mbmi->segment_id; + cm->last_frame_seg_map[index] = mbmi->segment_id; } } @@ -503,7 +504,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, else { vp8_read_mb_segid(bc, &mi->mbmi, xd); - pbi->segmentation_map[index] = mbmi->segment_id; + cm->last_frame_seg_map[index] = mbmi->segment_id; } index++; } diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 6e8284f4684aa72cf124bb2bed8b47d4f9ff0d98..64a5557c0175f416dc25ab7b92ff660f1db2a1dd 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -1063,7 +1063,7 @@ int vp8_decode_frame(VP8D_COMP *pbi) // If so what method will be used. if ( xd->update_mb_segmentation_map ) - xd->temporal_update = (unsigned char)vp8_read_bit(bc); + pc->temporal_update = (unsigned char)vp8_read_bit(bc); // Is the segment data being updated xd->update_mb_segmentation_data = (unsigned char)vp8_read_bit(bc); @@ -1114,8 +1114,8 @@ int vp8_decode_frame(VP8D_COMP *pbi) // Which macro block level features are enabled vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs)); - vpx_memset(xd->mb_segment_pred_probs, 255, - sizeof(xd->mb_segment_pred_probs)); + vpx_memset(pc->segment_pred_probs, 255, + sizeof(pc->segment_pred_probs)); // Read the probs used to decode the segment id for each macro // block. @@ -1130,16 +1130,16 @@ int vp8_decode_frame(VP8D_COMP *pbi) // If predictive coding of segment map is enabled read the // prediction probabilities. - if ( xd->temporal_update ) + if ( pc->temporal_update ) { // Read the prediction probs needed to decode the segment id // when predictive coding enabled - for (i = 0; i < SEGMENT_PREDICTION_PROBS; i++) + for (i = 0; i < PREDICTION_PROBS; i++) { // If not explicitly set value is defaulted to 255 by // memset above if (vp8_read_bit(bc)) - xd->mb_segment_pred_probs[i] = + pc->segment_pred_probs[i] = (vp8_prob)vp8_read_literal(bc, 8); } } @@ -1352,8 +1352,9 @@ int vp8_decode_frame(VP8D_COMP *pbi) vpx_memcpy(&xd->dst, &pc->yv12_fb[pc->new_fb_idx], sizeof(YV12_BUFFER_CONFIG)); // Create the encoder segmentation map and set all entries to 0 - if (!pbi->segmentation_map) - CHECK_MEM_ERROR(pbi->segmentation_map, vpx_calloc((pc->mb_rows * pc->mb_cols), 1)); + if (!pc->last_frame_seg_map) + CHECK_MEM_ERROR(pc->last_frame_seg_map, + vpx_calloc((pc->mb_rows * pc->mb_cols), 1)); /* set up frame new frame for intra coded blocks */ #if CONFIG_MULTITHREAD diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index ed7baac3e32bef7f28bd6831f6405d6e84483e07..391e579d8a520b77196c9124849d6ebedcbd33b8 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -202,8 +202,8 @@ void vp8dx_remove_decompressor(VP8D_PTR ptr) return; // Delete sementation map - if (pbi->segmentation_map != 0) - vpx_free(pbi->segmentation_map); + if (pbi->common.last_frame_seg_map != 0) + vpx_free(pbi->common.last_frame_seg_map); #if CONFIG_MULTITHREAD if (pbi->b_multithreaded_rd) diff --git a/vp8/decoder/onyxd_int.h b/vp8/decoder/onyxd_int.h index cf686380a1d4fb434d3bbe96e3db97834aae17a5..21d223e5dae8447fada08927a77ab64e83364e38 100644 --- a/vp8/decoder/onyxd_int.h +++ b/vp8/decoder/onyxd_int.h @@ -89,7 +89,6 @@ typedef struct VP8Decompressor const unsigned char *partitions[MAX_PARTITIONS]; unsigned int partition_sizes[MAX_PARTITIONS]; unsigned int num_partitions; - unsigned char *segmentation_map; #if CONFIG_MULTITHREAD /* variable for threading */ diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 9ce2bc8a896b488442b980447dcf7c18bb665d54..32f64999fba0da6734d083484db7cfa4c07293a4 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -1066,7 +1066,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) if (cpi->mb.e_mbd.update_mb_segmentation_map) { // Is temporal coding of the segment map enabled - if (xd->temporal_update) + if (pc->temporal_update) { // Look at whether neighbours were successfully predicted // to create a context for the seg_id_predicted flag. @@ -1078,7 +1078,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) // Code the prediction flag for this mb vp8_write( w, m->mbmi.seg_id_predicted, - xd->mb_segment_pred_probs[pred_context]); + pc->segment_pred_probs[pred_context]); // If the mbs segment id was not predicted code explicitly if (!m->mbmi.seg_id_predicted) @@ -1172,7 +1172,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) #endif //#if CONFIG_SEGFEATURES - // Is the segment coding of reference frame enabled + // Is the segment coding of mode enabled if ( !segfeature_active( xd, segment_id, SEG_LVL_MODE ) ) { write_mv_ref(w, mode, mv_ref_p); @@ -2086,7 +2086,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) // 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); + vp8_write_bit(bc, (pc->temporal_update) ? 1:0); vp8_write_bit(bc, (xd->update_mb_segmentation_data) ? 1 : 0); @@ -2162,11 +2162,11 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) // If predictive coding of segment map is enabled send the // prediction probabilities. - if ( xd->temporal_update ) + if ( pc->temporal_update ) { - for (i = 0; i < SEGMENT_PREDICTION_PROBS; i++) + for (i = 0; i < PREDICTION_PROBS; i++) { - int Data = xd->mb_segment_pred_probs[i]; + int Data = pc->segment_pred_probs[i]; if (Data != 255) { @@ -2180,7 +2180,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) } } - // Code to determine whether or not to update the scan order. + // Encode the loop filter level and type vp8_write_bit(bc, pc->filter_type); vp8_write_literal(bc, pc->filter_level, 6); vp8_write_literal(bc, pc->sharpness_level, 3); diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 779577f2d305e5435a7d6216f7acfb65f67aa51d..9969d3f584314e09f5faa58e57a5d046dd49abc1 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -333,8 +333,8 @@ static void dealloc_compressor_data(VP8_COMP *cpi) // Delete sementation map vpx_free(cpi->segmentation_map); cpi->segmentation_map = 0; - vpx_free(cpi->last_segmentation_map); - cpi->last_segmentation_map = 0; + vpx_free(cpi->common.last_frame_seg_map); + cpi->common.last_frame_seg_map = 0; vpx_free(cpi->active_map); cpi->active_map = 0; @@ -2380,7 +2380,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1)); // And a copy "last_segmentation_map" for temporal coding - CHECK_MEM_ERROR(cpi->last_segmentation_map, + CHECK_MEM_ERROR(cm->last_frame_seg_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)); @@ -4866,7 +4866,7 @@ static void encode_frame_to_data_rate choose_segmap_coding_method( cpi ); // Take a copy of the segment map if it changed for future comparison - vpx_memcpy( cpi->last_segmentation_map, + vpx_memcpy( cm->last_frame_seg_map, cpi->segmentation_map, cm->MBs ); } diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 002f30a9788480b19053cf82632aac1a8d5390ec..2ba3423cdd100d05cc54a7a307a0468df41cea4d 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -542,10 +542,7 @@ typedef struct VP8_COMP int y_uv_mode_count[VP8_YMODES][VP8_UV_MODES]; #endif - - unsigned char *segmentation_map; - unsigned char *last_segmentation_map; // 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 9a89bc6e9da22b6c2f42955b5b7661496420504b..9fce482f6fd077d05e9780ed55eee9f3bcc5d3bd 100644 --- a/vp8/encoder/segmentation.c +++ b/vp8/encoder/segmentation.c @@ -191,20 +191,20 @@ void choose_segmap_coding_method( VP8_COMP *cpi ) int segmap_index = 0; unsigned char segment_id; - int temporal_predictor_count[SEGMENT_PREDICTION_PROBS][2]; + int temporal_predictor_count[PREDICTION_PROBS][2]; int no_pred_segcounts[MAX_MB_SEGMENTS]; int t_unpred_seg_counts[MAX_MB_SEGMENTS]; vp8_prob no_pred_tree[MB_FEATURE_TREE_PROBS]; vp8_prob t_pred_tree[MB_FEATURE_TREE_PROBS]; - vp8_prob t_nopred_prob[SEGMENT_PREDICTION_PROBS]; + vp8_prob t_nopred_prob[PREDICTION_PROBS]; // Set default state for the segment tree probabilities and the // temporal coding probabilities vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs)); - vpx_memset(xd->mb_segment_pred_probs, 255, - sizeof(xd->mb_segment_pred_probs)); + vpx_memset(cm->segment_pred_probs, 255, + sizeof(cm->segment_pred_probs)); vpx_memset(no_pred_segcounts, 0, sizeof(no_pred_segcounts)); vpx_memset(t_unpred_seg_counts, 0, sizeof(t_unpred_seg_counts)); @@ -244,7 +244,7 @@ void choose_segmap_coding_method( VP8_COMP *cpi ) // 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 == cpi->last_segmentation_map[segmap_index] ) + 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]++; @@ -284,7 +284,7 @@ void choose_segmap_coding_method( VP8_COMP *cpi ) t_pred_cost = cost_segmap( xd, t_unpred_seg_counts, t_pred_tree ); // Add in the cost of the signalling for each prediction context - for ( i = 0; i < SEGMENT_PREDICTION_PROBS; i++ ) + for ( i = 0; i < PREDICTION_PROBS; i++ ) { tot_count = temporal_predictor_count[i][0] + temporal_predictor_count[i][1]; @@ -314,15 +314,15 @@ void choose_segmap_coding_method( VP8_COMP *cpi ) // Now choose which coding method to use. if ( t_pred_cost < no_pred_cost ) { - xd->temporal_update = 1; + cm->temporal_update = 1; vpx_memcpy( xd->mb_segment_tree_probs, t_pred_tree, sizeof(t_pred_tree) ); - vpx_memcpy( &xd->mb_segment_pred_probs, + vpx_memcpy( &cm->segment_pred_probs, t_nopred_prob, sizeof(t_nopred_prob) ); } else { - xd->temporal_update = 0; + cm->temporal_update = 0; vpx_memcpy( xd->mb_segment_tree_probs, no_pred_tree, sizeof(no_pred_tree) ); }