From 2ba4729ef80b73187d0f9d9a1fbf7eca60887f67 Mon Sep 17 00:00:00 2001 From: Marco Date: Mon, 15 May 2017 17:14:11 -0700 Subject: [PATCH] vp9: Make copy partition work for SVC and dynamic resize. Only affects speed 8. Make changes to copy partition to fix a bug in setting microblock offset. Avg PSNR shows 0.02% gain on rtc_derf and 0.08% loss on rtc. Change-Id: I61c3e5914dde645331344388e7437e5638acd4f3 --- vp9/encoder/vp9_encodeframe.c | 55 +++++++++++++++++++++++----------------- vp9/encoder/vp9_speed_features.c | 9 ++++--- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 0bd8bdb..f402b57 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -841,7 +841,8 @@ static void set_low_temp_var_flag(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, } } -static void copy_partitioning_helper(VP9_COMP *cpi, BLOCK_SIZE bsize, +static void copy_partitioning_helper(VP9_COMP *cpi, MACROBLOCK *x, + MACROBLOCKD *xd, BLOCK_SIZE bsize, int mi_row, int mi_col) { VP9_COMMON *const cm = &cpi->common; BLOCK_SIZE *prev_part = cpi->prev_partition; @@ -851,49 +852,57 @@ static void copy_partitioning_helper(VP9_COMP *cpi, BLOCK_SIZE bsize, const int bs = (1 << bsl) / 4; BLOCK_SIZE subsize; PARTITION_TYPE partition; - MODE_INFO *mi = NULL; if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; partition = partition_lookup[bsl][prev_part[start_pos]]; subsize = get_subsize(bsize, partition); - mi = cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]; if (subsize < BLOCK_8X8) { - mi->sb_type = bsize; + set_block_size(cpi, x, xd, mi_row, mi_col, bsize); } else { switch (partition) { - case PARTITION_NONE: mi->sb_type = bsize; break; + case PARTITION_NONE: + set_block_size(cpi, x, xd, mi_row, mi_col, bsize); + break; case PARTITION_HORZ: - mi->sb_type = subsize; - if (mi_row + bs < cm->mi_rows) - cm->mi_grid_visible[(mi_row + bs) * cm->mi_stride + mi_col]->sb_type = - subsize; + set_block_size(cpi, x, xd, mi_row, mi_col, subsize); + set_block_size(cpi, x, xd, mi_row + bs, mi_col, subsize); break; case PARTITION_VERT: - mi->sb_type = subsize; - if (mi_col + bs < cm->mi_cols) - cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col + bs]->sb_type = - subsize; + set_block_size(cpi, x, xd, mi_row, mi_col, subsize); + set_block_size(cpi, x, xd, mi_row, mi_col + bs, subsize); break; case PARTITION_SPLIT: - copy_partitioning_helper(cpi, subsize, mi_row, mi_col); - copy_partitioning_helper(cpi, subsize, mi_row + bs, mi_col); - copy_partitioning_helper(cpi, subsize, mi_row, mi_col + bs); - copy_partitioning_helper(cpi, subsize, mi_row + bs, mi_col + bs); + copy_partitioning_helper(cpi, x, xd, subsize, mi_row, mi_col); + copy_partitioning_helper(cpi, x, xd, subsize, mi_row + bs, mi_col); + copy_partitioning_helper(cpi, x, xd, subsize, mi_row, mi_col + bs); + copy_partitioning_helper(cpi, x, xd, subsize, mi_row + bs, mi_col + bs); break; default: assert(0); } } } -static int copy_partitioning(VP9_COMP *cpi, MACROBLOCK *x, int mi_row, - int mi_col, int segment_id, int sb_offset) { - if (cpi->rc.frames_since_key > 1 && segment_id == CR_SEGMENT_ID_BASE && +static int copy_partitioning(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, + int mi_row, int mi_col, int segment_id, + int sb_offset) { + int base_is_key = 0; + int frames_since_key_thresh = 1; + if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) { + int layer = LAYER_IDS_TO_IDX(0, cpi->svc.temporal_layer_id, + cpi->svc.number_temporal_layers); + const LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer]; + if (lc->is_key_frame) base_is_key = 1; + frames_since_key_thresh = cpi->svc.number_spatial_layers << 1; + } + if (cpi->rc.frames_since_key > frames_since_key_thresh && + !cpi->resize_pending && !base_is_key && + segment_id == CR_SEGMENT_ID_BASE && cpi->prev_segment_id[sb_offset] == CR_SEGMENT_ID_BASE && cpi->copied_frame_cnt[sb_offset] < cpi->max_copied_frame) { if (cpi->prev_partition != NULL) { - copy_partitioning_helper(cpi, BLOCK_64X64, mi_row, mi_col); + copy_partitioning_helper(cpi, x, xd, BLOCK_64X64, mi_row, mi_col); cpi->copied_frame_cnt[sb_offset] += 1; memcpy(x->variance_low, &(cpi->prev_variance_low[sb_offset * 25]), sizeof(x->variance_low)); @@ -1081,7 +1090,7 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, x->last_sb_high_content = cpi->content_state_sb_fd[sb_offset2]; // If source_sad is low copy the partition without computing the y_sad. if (x->skip_low_source_sad && cpi->sf.copy_partition_flag && - copy_partitioning(cpi, x, mi_row, mi_col, segment_id, sb_offset)) { + copy_partitioning(cpi, x, xd, mi_row, mi_col, segment_id, sb_offset)) { return 0; } } @@ -1208,7 +1217,7 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, // Stop the copy every cpi->max_copied_frame to refresh the partition. // TODO(jianj) : tune the threshold. if (cpi->sf.copy_partition_flag && y_sad_last < cpi->vbp_threshold_copy && - copy_partitioning(cpi, x, mi_row, mi_col, segment_id, sb_offset)) { + copy_partitioning(cpi, x, xd, mi_row, mi_col, segment_id, sb_offset)) { chroma_check(cpi, x, bsize, y_sad, is_key_frame); return 0; } diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 7917c63..1468830 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -564,10 +564,11 @@ static void set_rt_speed_feature_framesize_independent( if (speed >= 8) { sf->adaptive_rd_thresh = 4; - // Enable partition copy - if (!cpi->last_frame_dropped && !cpi->use_svc && !cpi->resize_pending && - cpi->resize_state == ORIG && !cpi->external_resize && - cpi->oxcf.resize_mode == RESIZE_NONE) { + // Enable partition copy. For SVC, only enabled for top resolution layer, + if (!cpi->last_frame_dropped && cpi->resize_state == ORIG && + !cpi->external_resize && + (!cpi->use_svc || + cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) { sf->copy_partition_flag = 1; cpi->max_copied_frame = 4; } -- 2.7.4