Adjust gop decision for realtime lookahead mode For the realtime with lookahead encoding mode: constrain the gop length on scene cuts, and allow for disabling the arf frame for high motion content. Change-Id: I63b02871058d9286735aeda7d49fc888d23c5ae0
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c index 0dec565..06905b3 100644 --- a/av1/encoder/pass2_strategy.c +++ b/av1/encoder/pass2_strategy.c
@@ -2216,10 +2216,15 @@ // Rare case when the look-ahead is less than the target GOP length, can't // generate ARF frame. + // Also disable ARF frame if the motion content (source_sad) is high in + // lookahead buffer. + const uint64_t thresh_sad = 8 * 64 * 64; if (p_rc->baseline_gf_interval > gf_cfg->lag_in_frames || !is_altref_enabled(gf_cfg->lag_in_frames, gf_cfg->enable_auto_arf) || - p_rc->baseline_gf_interval < rc->min_gf_interval) + p_rc->baseline_gf_interval < rc->min_gf_interval || + rc->frame_source_sad_lag[0] > thresh_sad) { gf_group->max_layer_depth_allowed = 0; + } // Set up the structure of this Group-Of-Pictures (same as GF_GROUP) av1_gop_setup_structure(cpi, is_final_pass); @@ -3812,6 +3817,10 @@ max_gop_length = AOMMIN(max_gop_length, rc->frames_to_key); // Go through source frames in lookahead buffer and compute source metrics: // scene change, frame average source sad, etc. + int num_frames = 1; + int scene_change_gop_frame_index = 0; + rc->frame_source_sad_lag[0] = 0; + rc->avg_source_sad = 0; for (int i = 1; i < max_gop_length; i++) { EncodeFrameInput frame_input; memset(&frame_input, 0, sizeof(frame_input)); @@ -3824,22 +3833,30 @@ frame_input.last_source = &e_prev->img; rc->high_source_sad_lag[i] = -1; rc->frame_source_sad_lag[i] = 0; - rc->avg_source_sad = 0; av1_rc_scene_detection_onepass_rt(cpi, &frame_input); rc->high_source_sad_lag[i] = rc->high_source_sad; rc->frame_source_sad_lag[i] = rc->frame_source_sad; - // Use rc->high_source_sad_lag[i] and frame_source_sad_lag[i] to - // adjust/adapt the gop parameters. Reset the parameters for the - // encoding. - rc->high_source_sad = 0; - rc->frame_source_sad = UINT64_MAX; + if (rc->high_source_sad_lag[i] == 1 && i > 1) { + // Scene change, so exit and constrain the gop to this frame. + scene_change_gop_frame_index = i; + break; + } + num_frames++; + rc->frame_source_sad_lag[0] += rc->frame_source_sad_lag[i]; } } + if (scene_change_gop_frame_index > 0) + max_gop_length = AOMMIN(max_gop_length, scene_change_gop_frame_index); + rc->frame_source_sad_lag[0] = rc->frame_source_sad_lag[0] / num_frames; calculate_gf_length(cpi, max_gop_length, MAX_NUM_GF_INTERVALS); define_gf_group(cpi, frame_params, 0); rc->frames_till_gf_update_due = p_rc->baseline_gf_interval; frame_params->frame_type = gf_group->frame_type[cpi->gf_frame_index]; av1_setup_target_rate(cpi); + // Reset the source_sad parameters for the encoding. + rc->high_source_sad = 0; + rc->frame_source_sad = UINT64_MAX; + rc->avg_source_sad = 0; } }