diff options
Diffstat (limited to 'vp8/encoder/encodeframe.c')
-rw-r--r-- | vp8/encoder/encodeframe.c | 180 |
1 files changed, 159 insertions, 21 deletions
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 0ced6e7b0..5dbe1975f 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -30,6 +30,7 @@ #include "vp8/common/subpixel.h" #include "vpx_ports/vpx_timer.h" + #if CONFIG_RUNTIME_CPU_DETECT #define RTCD(x) &cpi->common.rtcd.x #define IF_RTCD(x) (x) @@ -37,6 +38,13 @@ #define RTCD(x) NULL #define IF_RTCD(x) NULL #endif + +#if CONFIG_SEGMENTATION +#define SEEK_SEGID 12 +#define SEEK_SAMEID 4 +#define SEEK_DIFFID 7 +#endif + extern void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ; extern void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex); @@ -479,7 +487,10 @@ void encode_mb_row(VP8_COMP *cpi, int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride; int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride; int seg_map_index = (mb_row * cpi->common.mb_cols); - +#if CONFIG_SEGMENTATION + int left_id, above_id; + int sum; +#endif #if CONFIG_MULTITHREAD const int nsync = cpi->mt_sync_range; const int rightmost_col = cm->mb_cols - 1; @@ -490,7 +501,6 @@ void encode_mb_row(VP8_COMP *cpi, else last_row_current_mb_col = &rightmost_col; #endif - // reset above block coeffs xd->above_context = cm->above_context; @@ -564,6 +574,7 @@ void encode_mb_row(VP8_COMP *cpi, xd->mode_info_context->mbmi.segment_id = 0; vp8cx_mb_init_quantizer(cpi, x); + } else xd->mode_info_context->mbmi.segment_id = 0; // Set to Segment 0 by default @@ -627,6 +638,11 @@ void encode_mb_row(VP8_COMP *cpi, x->gf_active_ptr++; // Increment pointer into gf useage flags structure for next mb + if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)) + xd->mode_info_context->mbmi.segment_id = 0; + else + xd->mode_info_context->mbmi.segment_id = 1; + for (i = 0; i < 16; i++) vpx_memcpy(&xd->mode_info_context->bmi[i], &xd->block[i].bmi, sizeof(xd->block[i].bmi)); @@ -638,9 +654,42 @@ void encode_mb_row(VP8_COMP *cpi, recon_yoffset += 16; recon_uvoffset += 8; - // Keep track of segment useage - segment_counts[xd->mode_info_context->mbmi.segment_id] ++; +#if CONFIG_SEGMENTATION + //cpi->segmentation_map[mb_row * cm->mb_cols + mb_col] = xd->mbmi.segment_id; + if (cm->frame_type == KEY_FRAME) + { + segment_counts[xd->mode_info_context->mbmi.segment_id] ++; + } + else + { + sum = 0; + if (mb_col != 0) + sum += (xd->mode_info_context-1)->mbmi.segment_flag; + 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]) + xd->mode_info_context->mbmi.segment_flag = 0; + else + xd->mode_info_context->mbmi.segment_flag = 1; + if (xd->mode_info_context->mbmi.segment_flag == 0) + { + segment_counts[SEEK_SAMEID + sum]++; + segment_counts[10]++; + } + else + { + segment_counts[SEEK_DIFFID + sum]++; + segment_counts[11]++; + //calculate individual segment ids + segment_counts[xd->mode_info_context->mbmi.segment_id] ++; + } + } + segment_counts[SEEK_SEGID + xd->mode_info_context->mbmi.segment_id] ++; +#else + segment_counts[xd->mode_info_context->mbmi.segment_id] ++; +#endif // skip to next mb xd->mode_info_context++; x->partition_info++; @@ -665,7 +714,6 @@ void encode_mb_row(VP8_COMP *cpi, xd->mode_info_context++; x->partition_info++; x->activity_sum += activity_sum; - #if CONFIG_MULTITHREAD if ((cpi->b_multi_threaded != 0) && (mb_row == cm->mb_rows - 1)) { @@ -673,7 +721,6 @@ void encode_mb_row(VP8_COMP *cpi, } #endif } - void vp8_encode_frame(VP8_COMP *cpi) { int mb_row; @@ -682,7 +729,13 @@ void vp8_encode_frame(VP8_COMP *cpi) MACROBLOCKD *const xd = & x->e_mbd; TOKENEXTRA *tp = cpi->tok; +#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 int totalrate; // Functions setup for all frame types so we can use MC in AltRef @@ -762,7 +815,7 @@ void vp8_encode_frame(VP8_COMP *cpi) vp8_auto_select_speed(cpi); } - vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q)); + vp8_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q); vp8cx_initialize_me_consts(cpi, cm->base_qindex); // Copy data over into macro block data sturctures. @@ -894,41 +947,126 @@ void vp8_encode_frame(VP8_COMP *cpi) } - // Work out the segment probabilites if segmentation is enabled if (xd->segmentation_enabled) { int tot_count; - int i; + int i,j; + int count1,count2,count3,count4; // 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++) { - xd->mb_segment_tree_probs[0] = ((segment_counts[0] + segment_counts[1]) * 255) / tot_count; + if (xd->mb_segment_tree_probs[i] == 0) + xd->mb_segment_tree_probs[i] = 1; + } - tot_count = segment_counts[0] + segment_counts[1]; + original_cost = count1 * vp8_cost_zero(prob[0]) + count2 * vp8_cost_one(prob[0]); - if (tot_count > 0) - { - xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) / tot_count; - } + 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]) ; - tot_count = segment_counts[2] + segment_counts[3]; + new_cost = 0; - if (tot_count > 0) - xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) / tot_count; + 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]); + } - // Zero probabilities not allowed - for (i = 0; i < MB_FEATURE_TREE_PROBS; i ++) + 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]; + } +#else + tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3]; + count1 = segment_counts[0] + segment_counts[1]; + count2 = segment_counts[2] + segment_counts[3]; + + if (tot_count) + xd->mb_segment_tree_probs[0] = (count1 * 255) / tot_count; + + if (count1 > 0) + xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count1; + + if (count2 > 0) + xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count2; + +#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 |