From 939791a129819951bbdd187ba022d456efbc21d6 Mon Sep 17 00:00:00 2001 From: Yunqing Wang Date: Thu, 5 Sep 2013 17:10:58 -0700 Subject: [PATCH] Modify encode breakout for static frames Thank Paul for the suggestions. While turning on static-thresh for static-image videos, a big jump on bitrate was seen. In this patch, we detected static frames in the video using first-pass stats. For different cases, disable encode breakout or reduce encode breakout threshold to limit the skipping. More modification need be done to break incorrect partition picking pattern for static frames while skipping happens. Change-Id: Ia25f47041af0f04e229c70a0185e12b0ffa6047f --- vp9/encoder/vp9_firstpass.c | 13 +++++++++++++ vp9/encoder/vp9_onyx_if.c | 4 ++++ vp9/encoder/vp9_onyx_int.h | 3 +++ vp9/encoder/vp9_rdopt.c | 15 ++++++++++----- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 0cbe3abb8..c5b348582 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -1717,6 +1717,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { old_boost_score = boost_score; } + cpi->gf_zeromotion_pct = (int)(zero_motion_accumulator * 1000.0); + // Don't allow a gf too near the next kf if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL) { while (i < cpi->twopass.frames_to_key) { @@ -2162,6 +2164,8 @@ void vp9_second_pass(VP9_COMP *cpi) { // Define next gf group and assign bits to it this_frame_copy = this_frame; + cpi->gf_zeromotion_pct = 0; + #if CONFIG_MULTIPLE_ARF if (cpi->multi_arf_enabled) { define_fixed_arf_period(cpi); @@ -2172,6 +2176,15 @@ void vp9_second_pass(VP9_COMP *cpi) { } #endif + if (cpi->gf_zeromotion_pct > 995) { + // As long as max_thresh for encode breakout is small enough, it is ok + // to enable it for no-show frame, i.e. set enable_encode_breakout to 2. + if (!cpi->common.show_frame) + cpi->enable_encode_breakout = 0; + else + cpi->enable_encode_breakout = 2; + } + // If we are going to code an altref frame at the end of the group // and the current frame is not a key frame.... // If the previous group used an arf this frame has already benefited diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 94ac89d48..d53d2f26f 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -1590,6 +1590,8 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) { cpi->output_pkt_list = oxcf->output_pkt_list; + cpi->enable_encode_breakout = 1; + if (cpi->pass == 1) { vp9_init_first_pass(cpi); } else if (cpi->pass == 2) { @@ -3619,6 +3621,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, static void Pass2Encode(VP9_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags) { + cpi->enable_encode_breakout = 1; + if (!cpi->refresh_alt_ref_frame) vp9_second_pass(cpi); diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 334a23c05..d83c3f7e0 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -495,6 +495,7 @@ typedef struct VP9_COMP { int last_boost; int kf_boost; int kf_zeromotion_pct; + int gf_zeromotion_pct; int64_t target_bandwidth; struct vpx_codec_pkt_list *output_pkt_list; @@ -656,6 +657,8 @@ typedef struct VP9_COMP { int initial_height; int number_spatial_layers; + int enable_encode_breakout; // Default value is 1. From first pass stats, + // encode_breakout may be disabled. #if CONFIG_MULTIPLE_ARF // ARF tracking variables. diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 53a064c39..07850d4f6 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -2861,7 +2861,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, if (cpi->common.mcomp_filter_type == SWITCHABLE) *rate2 += get_switchable_rate(x); - if (!is_comp_pred) { + if (!is_comp_pred && cpi->enable_encode_breakout) { if (cpi->active_map_enabled && x->active_ptr[0] == 0) x->skip = 1; else if (x->encode_breakout) { @@ -2872,18 +2872,23 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, unsigned int thresh_ac; // The encode_breakout input unsigned int encode_breakout = x->encode_breakout << 4; + int max_thresh = 36000; + + // Use extreme low threshold for static frames to limit skipping. + if (cpi->enable_encode_breakout == 2) + max_thresh = 128; // Calculate threshold according to dequant value. thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9; - // Set a maximum for threshold to avoid big PSNR loss in low bitrate case. - if (thresh_ac > 36000) - thresh_ac = 36000; - // Use encode_breakout input if it is bigger than internal threshold. if (thresh_ac < encode_breakout) thresh_ac = encode_breakout; + // Set a maximum for threshold to avoid big PSNR loss in low bitrate case. + if (thresh_ac > max_thresh) + thresh_ac = max_thresh; + var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].dst.buf, xd->plane[0].dst.stride, &sse); -- 2.40.0