diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 58d556260..b6fadafa3 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -924,7 +924,7 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, const int low_res = (cm->width <= 352 && cm->height <= 288); int variance4x4downsample[16]; int segment_id; - int offset = cm->mi_stride * mi_row + mi_col; + int sb_offset = (cm->mi_stride >> 3) * (mi_row >> 3) + (mi_col >> 3); set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64); segment_id = xd->mi[0]->segment_id; @@ -1035,6 +1035,7 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, if (mi_col + block_width / 2 < cm->mi_cols && mi_row + block_height / 2 < cm->mi_rows) { set_block_size(cpi, x, xd, mi_row, mi_col, BLOCK_64X64); + x->variance_low[0] = 1; chroma_check(cpi, x, bsize, y_sad, is_key_frame); return 0; } @@ -1045,11 +1046,13 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, // TODO(jianj) : tune the threshold. if (cpi->sf.copy_partition_flag && cpi->rc.frames_since_key > 1 && segment_id == CR_SEGMENT_ID_BASE && - cpi->prev_segment_id[offset] == CR_SEGMENT_ID_BASE && + cpi->prev_segment_id[sb_offset] == CR_SEGMENT_ID_BASE && y_sad_last < cpi->vbp_threshold_copy) { if (cpi->prev_partition != NULL) { copy_prev_partition(cpi, BLOCK_64X64, mi_row, mi_col); chroma_check(cpi, x, bsize, y_sad, is_key_frame); + memcpy(x->variance_low, &(cpi->prev_variance_low[sb_offset * 25]), + sizeof(x->variance_low)); return 0; } } @@ -1249,7 +1252,9 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, if (cm->frame_type != KEY_FRAME && cpi->sf.copy_partition_flag) { update_prev_partition(cpi, BLOCK_64X64, mi_row, mi_col); - cpi->prev_segment_id[offset] = segment_id; + cpi->prev_segment_id[sb_offset] = segment_id; + memcpy(&(cpi->prev_variance_low[sb_offset * 25]), x->variance_low, + sizeof(x->variance_low)); } if (cpi->sf.short_circuit_low_temp_var) { diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 3fa7dbbf6..cd3166d0a 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -456,6 +456,9 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { vpx_free(cpi->prev_segment_id); cpi->prev_segment_id = NULL; + vpx_free(cpi->prev_variance_low); + cpi->prev_variance_low = NULL; + vp9_cyclic_refresh_free(cpi->cyclic_refresh); cpi->cyclic_refresh = NULL; diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index c415414f3..6741a24b6 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -633,6 +633,12 @@ typedef struct VP9_COMP { // Previous Partition Info BLOCK_SIZE *prev_partition; int8_t *prev_segment_id; + // Used to save the status of whether a block has a low variance in + // choose_partitioning. 0 for 64x64, 1~2 for 64x32, 3~4 for 32x64, 5~8 for + // 32x32, 9~24 for 16x16. + // This is for the last frame and is copied to the current frame + // when partition copy happens. + uint8_t *prev_variance_low; LevelConstraint level_constraint; } VP9_COMP; diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 088c4d0a9..005f94469 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -507,8 +507,13 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf, int speed, cm->mi_stride * cm->mi_rows, sizeof(BLOCK_SIZE)); } if (cpi->prev_segment_id == NULL) { - cpi->prev_segment_id = - (int8_t *)vpx_calloc(cm->mi_stride * cm->mi_rows, sizeof(int8_t)); + cpi->prev_segment_id = (int8_t *)vpx_calloc( + (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), sizeof(int8_t)); + } + if (cpi->prev_variance_low == NULL) { + cpi->prev_variance_low = (uint8_t *)vpx_calloc( + (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) * 25, + sizeof(uint8_t)); } } sf->mv.subpel_force_stop = (content == VP9E_CONTENT_SCREEN) ? 3 : 2;