From af6d8456a337db0361aae0952447490200d0d3b9 Mon Sep 17 00:00:00 2001 From: Marco Paniconi Date: Tue, 24 Jul 2018 11:34:42 -0700 Subject: [PATCH] vp9: Modify logic for flat blocks in nonrd-pickmode. For real-time screen content mode: when slide change is detected, for spatially flat blocks (source_variance = 0) on the re-encoded frame, skip inter modes (so force intra) if non-zero temporal variance is detected for the coding block. Add flag to keep track of re-encoded frame at max Q. Reduces artifacts on slide change. Change-Id: I28151f412aba6ab8cb03f30087c7ce16d443654b --- vp9/encoder/vp9_encoder.c | 1 + vp9/encoder/vp9_pickmode.c | 4 +++- vp9/encoder/vp9_ratectrl.c | 2 ++ vp9/encoder/vp9_ratectrl.h | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index de5519dce..ed2c17702 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -3985,6 +3985,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size, // (need to check encoding time cost for doing this for speed 8). cpi->rc.high_source_sad = 0; cpi->rc.hybrid_intra_scene_change = 0; + cpi->rc.re_encode_maxq_scene_change = 0; if (cm->show_frame && cpi->oxcf.mode == REALTIME && (cpi->oxcf.rc_mode == VPX_VBR || cpi->oxcf.content == VP9E_CONTENT_SCREEN || diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 8248d12e6..fa7cf8c26 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -1827,7 +1827,9 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, if (!(cpi->ref_frame_flags & flag_list[ref_frame])) continue; if (sf->short_circuit_flat_blocks && x->source_variance == 0 && - frame_mv[this_mode][ref_frame].as_int != 0) { + (frame_mv[this_mode][ref_frame].as_int != 0 || + (svc->spatial_layer_id == 0 && cpi->rc.re_encode_maxq_scene_change && + !x->zero_temp_sad_source))) { continue; } diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 22ae7266b..9bf845890 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -364,6 +364,7 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) { rc->reset_high_source_sad = 0; rc->high_source_sad_lagindex = -1; rc->hybrid_intra_scene_change = 0; + rc->re_encode_maxq_scene_change = 0; rc->alt_ref_gf_group = 0; rc->last_frame_is_src_altref = 0; rc->fac_active_worst_inter = 150; @@ -2813,6 +2814,7 @@ int vp9_encodedframe_overshoot(VP9_COMP *cpi, int frame_size, int *q) { // Force a re-encode, and for now use max-QP. *q = cpi->rc.worst_quality; cpi->cyclic_refresh->counter_encode_maxq_scene_change = 0; + cpi->rc.re_encode_maxq_scene_change = 1; // If the frame_size is much larger than the threshold (big content change) // and the encoded frame used alot of Intra modes, then force hybrid_intra // encoding for the re-encode on this scene change. hybrid_intra will diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h index 373c6a3aa..cf37117f9 100644 --- a/vp9/encoder/vp9_ratectrl.h +++ b/vp9/encoder/vp9_ratectrl.h @@ -190,6 +190,7 @@ typedef struct { int high_source_sad; int count_last_scene_change; int hybrid_intra_scene_change; + int re_encode_maxq_scene_change; int avg_frame_low_motion; int af_ratio_onepass_vbr; int force_qpmin; -- 2.40.0