From: Marco Date: Thu, 16 Mar 2017 22:55:33 +0000 (-0700) Subject: vp9: Use sb content measure to bias against golden. X-Git-Tag: v1.7.0~614^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=06c8713e89514ccbed2d68e847adfd7830b53881;p=libvpx vp9: Use sb content measure to bias against golden. For each superblock, keep track of how far from current frame was the last significant content change, and use that (along with GF distance), to turnoff GF search in non-rd pickmode. Only enabled for speed >= 8. avgPNSR on RTC/RTC_derf down by ~0.9/1.2. Speedup on mac: ~3-5%. Speedup on arm: 3.6% for VGA and 4.4% for HD. Change-Id: Ic3f3d6a2af650aca6ba0064d2b1db8d48c035ac7 --- diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h index c86c818aa..071a9b3e3 100644 --- a/vp9/encoder/vp9_block.h +++ b/vp9/encoder/vp9_block.h @@ -170,6 +170,8 @@ struct macroblock { uint8_t skip_low_source_sad; + uint8_t last_sb_high_content; + // 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. diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index df72667d4..e6f4901fd 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1018,6 +1018,7 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile, content_state == kLowSadHighSumdiff) ? 1 : 0; + 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)) { diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 64d6985b5..aba2c115a 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -466,6 +466,9 @@ static void dealloc_compressor_data(VP9_COMP *cpi) { vpx_free(cpi->content_state_sb); cpi->content_state_sb = NULL; + vpx_free(cpi->content_state_sb_fd); + cpi->content_state_sb_fd = NULL; + vp9_cyclic_refresh_free(cpi->cyclic_refresh); cpi->cyclic_refresh = NULL; @@ -3141,10 +3144,14 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size, cpi->svc.current_superframe < 1)) || cpi->resize_pending || cpi->resize_state || cpi->external_resize) { compute_source_sad = 0; - if (cpi->content_state_sb != NULL) + if (cpi->content_state_sb != NULL) { memset(cpi->content_state_sb, 0, (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) * sizeof(*cpi->content_state_sb)); + memset(cpi->content_state_sb_fd, 0, + (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) * + sizeof(*cpi->content_state_sb_fd)); + } } // Avoid scaling last_source unless its needed. diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index ba29cabb1..72c0ba787 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -705,7 +705,12 @@ typedef struct VP9_COMP { uint8_t *copied_frame_cnt; uint8_t max_copied_frame; + // For each superblock: saves the content value (e.g., low/high sad/sumdiff) + // based on source sad, prior to encoding the frame. uint8_t *content_state_sb; + // For each superblock: keeps track of the last time (in frame distance) the + // the superblock did not have low source sad. + uint8_t *content_state_sb_fd; LevelConstraint level_constraint; } VP9_COMP; diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 46fb67a93..ecc9afbad 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -1563,6 +1563,11 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, usable_ref_frame = LAST_FRAME; #endif + if (cpi->oxcf.speed >= 8 && !cpi->use_svc && + ((cpi->rc.frames_since_golden + 1) < x->last_sb_high_content || + x->last_sb_high_content > 40)) + usable_ref_frame = LAST_FRAME; + for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) { if (!skip_ref_find_pred[ref_frame]) { find_predictors(cpi, x, ref_frame, frame_mv, const_motion, diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index b95cd7773..fb41427ea 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -2285,6 +2285,7 @@ void vp9_avg_source_sad(VP9_COMP *cpi) { int sb_cols = (cm->mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; int sb_rows = (cm->mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE; uint64_t avg_source_sad_threshold = 10000; + uint64_t avg_source_sad_threshold2 = 12000; if (cpi->oxcf.lag_in_frames > 0) { src_y = frames[frame]->y_buffer; src_ystride = frames[frame]->y_stride; @@ -2315,6 +2316,13 @@ void vp9_avg_source_sad(VP9_COMP *cpi) { cpi->content_state_sb[num_samples] = ((tmp_sse - tmp_variance) < 25) ? kHighSadLowSumdiff : kHighSadHighSumdiff; + if (tmp_sad < avg_source_sad_threshold2) { + // Cap the increment to 255. + if (cpi->content_state_sb_fd[num_samples] < 255) + cpi->content_state_sb_fd[num_samples]++; + } else { + cpi->content_state_sb_fd[num_samples] = 0; + } } avg_sad += tmp_sad; num_samples++; diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 2ce836f2e..fd589f990 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -518,6 +518,8 @@ static void set_rt_speed_feature_framesize_independent( cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) { cpi->content_state_sb = (uint8_t *)vpx_calloc( (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), sizeof(uint8_t)); + cpi->content_state_sb_fd = (uint8_t *)vpx_calloc( + (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1), sizeof(uint8_t)); } } }