ref: 8dc15230576f8900327f38c667dda1cab41e3894
parent: d642dd43110f93fafa9c88e86cf2fc6464340663
parent: 06c8713e89514ccbed2d68e847adfd7830b53881
author: Marco Paniconi <marpan@google.com>
date: Mon Mar 20 17:35:11 EDT 2017
Merge "vp9: Use sb content measure to bias against golden."
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -170,6 +170,8 @@
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.
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1018,6 +1018,7 @@
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)) {
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -466,6 +466,9 @@
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 @@
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.
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -705,7 +705,12 @@
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;
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1563,6 +1563,11 @@
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,
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -2285,6 +2285,7 @@
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 @@
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++;
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -518,6 +518,8 @@
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));
}
}
}