summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/encoder/firstpass.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/aom/av1/encoder/firstpass.c')
-rw-r--r--third_party/aom/av1/encoder/firstpass.c493
1 files changed, 462 insertions, 31 deletions
diff --git a/third_party/aom/av1/encoder/firstpass.c b/third_party/aom/av1/encoder/firstpass.c
index 113c068c1..ef0800c79 100644
--- a/third_party/aom/av1/encoder/firstpass.c
+++ b/third_party/aom/av1/encoder/firstpass.c
@@ -486,6 +486,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
int mb_row, mb_col;
MACROBLOCK *const x = &cpi->td.mb;
AV1_COMMON *const cm = &cpi->common;
+ const SequenceHeader *const seq_params = &cm->seq_params;
const int num_planes = av1_num_planes(cm);
MACROBLOCKD *const xd = &x->e_mbd;
TileInfo tile;
@@ -524,7 +525,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
double intra_factor;
double brightness_factor;
BufferPool *const pool = cm->buffer_pool;
- const int qindex = find_fp_qindex(cm->bit_depth);
+ const int qindex = find_fp_qindex(seq_params->bit_depth);
const int mb_scale = mi_size_wide[BLOCK_16X16];
int *raw_motion_err_list;
@@ -555,11 +556,11 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
set_first_pass_params(cpi);
av1_set_quantizer(cm, qindex);
- av1_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y,
- num_planes);
+ av1_setup_block_planes(&x->e_mbd, seq_params->subsampling_x,
+ seq_params->subsampling_y, num_planes);
av1_setup_src_planes(x, cpi->source, 0, 0, num_planes);
- av1_setup_dst_planes(xd->plane, cm->seq_params.sb_size, new_yv12, 0, 0, 0,
+ av1_setup_dst_planes(xd->plane, seq_params->sb_size, new_yv12, 0, 0, 0,
num_planes);
if (!frame_is_intra_only(cm)) {
@@ -654,14 +655,14 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
image_data_start_row = mb_row;
}
- if (cm->use_highbitdepth) {
- switch (cm->bit_depth) {
+ if (seq_params->use_highbitdepth) {
+ switch (seq_params->bit_depth) {
case AOM_BITS_8: break;
case AOM_BITS_10: this_error >>= 4; break;
case AOM_BITS_12: this_error >>= 8; break;
default:
assert(0 &&
- "cm->bit_depth should be AOM_BITS_8, "
+ "seq_params->bit_depth should be AOM_BITS_8, "
"AOM_BITS_10 or AOM_BITS_12");
return;
}
@@ -674,7 +675,7 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
else
intra_factor += 1.0;
- if (cm->use_highbitdepth)
+ if (seq_params->use_highbitdepth)
level_sample = CONVERT_TO_SHORTPTR(x->plane[0].src.buf)[0];
else
level_sample = x->plane[0].src.buf[0];
@@ -1156,10 +1157,10 @@ static int get_twopass_worst_quality(const AV1_COMP *cpi,
for (q = rc->best_quality; q < rc->worst_quality; ++q) {
const double factor = calc_correction_factor(
av_err_per_mb, ERR_DIVISOR - ediv_size_correction, FACTOR_PT_LOW,
- FACTOR_PT_HIGH, q, cpi->common.bit_depth);
+ FACTOR_PT_HIGH, q, cpi->common.seq_params.bit_depth);
const int bits_per_mb = av1_rc_bits_per_mb(
INTER_FRAME, q, factor * speed_term * group_weight_factor,
- cpi->common.bit_depth);
+ cpi->common.seq_params.bit_depth);
if (bits_per_mb <= target_norm_bits_per_mb) break;
}
@@ -1377,7 +1378,7 @@ static double calc_frame_boost(AV1_COMP *cpi, const FIRSTPASS_STATS *this_frame,
double this_frame_mv_in_out, double max_boost) {
double frame_boost;
const double lq = av1_convert_qindex_to_q(
- cpi->rc.avg_frame_qindex[INTER_FRAME], cpi->common.bit_depth);
+ cpi->rc.avg_frame_qindex[INTER_FRAME], cpi->common.seq_params.bit_depth);
const double boost_q_correction = AOMMIN((0.5 + (lq * 0.015)), 1.5);
int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) ? cpi->initial_mbs
: cpi->common.MBs;
@@ -2130,6 +2131,319 @@ static void define_gf_group_structure_16(AV1_COMP *cpi) {
}
#endif // USE_GF16_MULTI_LAYER
+#if USE_SYMM_MULTI_LAYER
+void check_frame_params(GF_GROUP *const gf_group, int gf_interval,
+ int frame_nums) {
+ static const char *update_type_strings[] = {
+ "KF_UPDATE", "LF_UPDATE", "GF_UPDATE",
+ "ARF_UPDATE", "OVERLAY_UPDATE", "BRF_UPDATE",
+ "LAST_BIPRED_UPDATE", "BIPRED_UPDATE", "INTNL_OVERLAY_UPDATE",
+ "INTNL_ARF_UPDATE"
+ };
+ FILE *fid = fopen("GF_PARAMS.txt", "a");
+
+ fprintf(fid, "\n{%d}\n", gf_interval);
+ for (int i = 0; i <= frame_nums; ++i) {
+ fprintf(fid, "%s %d %d %d %d\n",
+ update_type_strings[gf_group->update_type[i]],
+ gf_group->arf_src_offset[i], gf_group->arf_pos_in_gf[i],
+ gf_group->arf_update_idx[i], gf_group->pyramid_level[i]);
+ }
+ fclose(fid);
+}
+
+static int update_type_2_rf_level(FRAME_UPDATE_TYPE update_type) {
+ // Derive rf_level from update_type
+ switch (update_type) {
+ case LF_UPDATE: return INTER_NORMAL;
+ case ARF_UPDATE: return GF_ARF_STD;
+ case OVERLAY_UPDATE: return INTER_NORMAL;
+ case BRF_UPDATE: return GF_ARF_LOW;
+ case LAST_BIPRED_UPDATE: return INTER_NORMAL;
+ case BIPRED_UPDATE: return INTER_NORMAL;
+ case INTNL_ARF_UPDATE: return GF_ARF_LOW;
+ case INTNL_OVERLAY_UPDATE: return INTER_NORMAL;
+ default: return INTER_NORMAL;
+ }
+}
+
+static void set_multi_layer_params(GF_GROUP *const gf_group, int l, int r,
+ int *frame_ind, int arf_ind, int level) {
+ if (r - l == 2) {
+ // leaf node, not a look-ahead frame
+ gf_group->update_type[*frame_ind] = LF_UPDATE;
+ gf_group->arf_src_offset[*frame_ind] = 0;
+ gf_group->arf_pos_in_gf[*frame_ind] = 0;
+ gf_group->arf_update_idx[*frame_ind] = arf_ind;
+ gf_group->pyramid_level[*frame_ind] = level;
+ ++(*frame_ind);
+ } else {
+ int m = (l + r) / 2;
+ int arf_pos_in_gf = *frame_ind;
+
+ gf_group->update_type[*frame_ind] = INTNL_ARF_UPDATE;
+ gf_group->arf_src_offset[*frame_ind] = m - l - 1;
+ gf_group->arf_pos_in_gf[*frame_ind] = 0;
+ gf_group->arf_update_idx[*frame_ind] = 1; // mark all internal ARF 1
+ gf_group->pyramid_level[*frame_ind] = level;
+ ++(*frame_ind);
+
+ // set parameters for frames displayed before this frame
+ set_multi_layer_params(gf_group, l, m, frame_ind, 1, level - 1);
+
+ // for overlay frames, we need to record the position of its corresponding
+ // arf frames for bit allocation
+ gf_group->update_type[*frame_ind] = INTNL_OVERLAY_UPDATE;
+ gf_group->arf_src_offset[*frame_ind] = 0;
+ gf_group->arf_pos_in_gf[*frame_ind] = arf_pos_in_gf;
+ gf_group->arf_update_idx[*frame_ind] = 1;
+ gf_group->pyramid_level[*frame_ind] = 0;
+ ++(*frame_ind);
+
+ // set parameters for frames displayed after this frame
+ set_multi_layer_params(gf_group, m, r, frame_ind, arf_ind, level - 1);
+ }
+}
+
+static INLINE unsigned char get_pyramid_height(int pyramid_width) {
+ assert(pyramid_width <= 16 && pyramid_width >= 4 &&
+ "invalid gf interval for pyramid structure");
+
+ return pyramid_width == 16 ? 4 : (pyramid_width >= 8 ? 3 : 2);
+}
+
+static int construct_multi_layer_gf_structure(GF_GROUP *const gf_group,
+ const int gf_interval) {
+ int frame_index = 0;
+ gf_group->pyramid_height = get_pyramid_height(gf_interval);
+
+ // At the beginning of each GF group it will be a key or overlay frame,
+ gf_group->update_type[frame_index] = OVERLAY_UPDATE;
+ gf_group->arf_src_offset[frame_index] = 0;
+ gf_group->arf_pos_in_gf[frame_index] = 0;
+ gf_group->arf_update_idx[frame_index] = 0;
+ gf_group->pyramid_level[frame_index] = 0;
+ ++frame_index;
+
+ // ALT0
+ gf_group->update_type[frame_index] = ARF_UPDATE;
+ gf_group->arf_src_offset[frame_index] = gf_interval - 1;
+ gf_group->arf_pos_in_gf[frame_index] = 0;
+ gf_group->arf_update_idx[frame_index] = 0;
+ gf_group->pyramid_level[frame_index] = gf_group->pyramid_height;
+ ++frame_index;
+
+ // set parameters for the rest of the frames
+ set_multi_layer_params(gf_group, 0, gf_interval, &frame_index, 0,
+ gf_group->pyramid_height - 1);
+
+ // check_frame_params(gf_group, gf_interval, frame_index);
+
+ return frame_index;
+}
+
+void define_customized_gf_group_structure(AV1_COMP *cpi) {
+ RATE_CONTROL *const rc = &cpi->rc;
+ TWO_PASS *const twopass = &cpi->twopass;
+ GF_GROUP *const gf_group = &twopass->gf_group;
+ const int key_frame = cpi->common.frame_type == KEY_FRAME;
+
+ assert(rc->baseline_gf_interval == 4 || rc->baseline_gf_interval == 8 ||
+ rc->baseline_gf_interval == 16);
+
+ const int gf_update_frames =
+ construct_multi_layer_gf_structure(gf_group, rc->baseline_gf_interval);
+ int frame_index;
+
+ cpi->num_extra_arfs = 0;
+
+ for (frame_index = 0; frame_index < gf_update_frames; ++frame_index) {
+ // Set unused variables to default values
+ gf_group->bidir_pred_enabled[frame_index] = 0;
+ gf_group->brf_src_offset[frame_index] = 0;
+
+ // Special handle for the first frame for assigning update_type
+ if (frame_index == 0) {
+ // For key frames the frame target rate is already set and it
+ // is also the golden frame.
+ if (key_frame) {
+ gf_group->update_type[frame_index] = KF_UPDATE;
+ continue;
+ }
+
+ if (rc->source_alt_ref_active) {
+ gf_group->update_type[frame_index] = OVERLAY_UPDATE;
+ } else {
+ gf_group->update_type[frame_index] = GF_UPDATE;
+ }
+ } else {
+ if (gf_group->update_type[frame_index] == INTNL_ARF_UPDATE)
+ ++cpi->num_extra_arfs;
+ }
+
+ // Assign rf level based on update type
+ gf_group->rf_level[frame_index] =
+ update_type_2_rf_level(gf_group->update_type[frame_index]);
+ }
+
+ // NOTE: We need to configure the frame at the end of the sequence + 1 that
+ // will be the start frame for the next group. Otherwise prior to the
+ // call to av1_rc_get_second_pass_params() the data will be undefined.
+ if (rc->source_alt_ref_pending) {
+ gf_group->update_type[frame_index] = OVERLAY_UPDATE;
+ gf_group->rf_level[frame_index] = INTER_NORMAL;
+ } else {
+ gf_group->update_type[frame_index] = GF_UPDATE;
+ gf_group->rf_level[frame_index] = GF_ARF_STD;
+ }
+
+ gf_group->bidir_pred_enabled[frame_index] = 0;
+ gf_group->brf_src_offset[frame_index] = 0;
+ gf_group->arf_update_idx[frame_index] = 0;
+ // This value is only used for INTNL_OVERLAY_UPDATE
+ gf_group->arf_pos_in_gf[frame_index] = 0;
+
+ // This parameter is useless?
+ gf_group->arf_ref_idx[frame_index] = 0;
+
+ check_frame_params(gf_group, rc->baseline_gf_interval, gf_update_frames);
+}
+
+// It is an example of how to define a GF stucture manually. The function will
+// result in exactly the same GF group structure as
+// define_customized_gf_group_structure() when rc->baseline_gf_interval == 4
+#if USE_MANUAL_GF4_STRUCT
+#define GF_INTERVAL_4 4
+static const unsigned char gf4_multi_layer_params[][GF_FRAME_PARAMS] = {
+ {
+ // gf_group->index == 0 (Frame 0)
+ // It can also be KEY frame. Will assign the proper value
+ // in define_gf_group_structure
+ OVERLAY_UPDATE, // update_type (default value)
+ 0, // arf_src_offset
+ 0, // arf_pos_in_gf
+ 0 // arf_update_idx
+ },
+ {
+ // gf_group->index == 1 (Frame 4)
+ ARF_UPDATE, // update_type
+ GF_INTERVAL_4 - 1, // arf_src_offset
+ 0, // arf_pos_in_gf
+ 0 // arf_update_idx
+ },
+ {
+ // gf_group->index == 2 (Frame 2)
+ INTNL_ARF_UPDATE, // update_type
+ (GF_INTERVAL_4 >> 1) - 1, // arf_src_offset
+ 0, // arf_pos_in_gf
+ 0 // arf_update_idx
+ },
+ {
+ // gf_group->index == 3 (Frame 1)
+ LAST_BIPRED_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // arf_pos_in_gf
+ 0 // arf_update_idx
+ },
+
+ {
+ // gf_group->index == 4 (Frame 2 - OVERLAY)
+ INTNL_OVERLAY_UPDATE, // update_type
+ 0, // arf_src_offset
+ 2, // arf_pos_in_gf
+ 0 // arf_update_idx
+ },
+ {
+ // gf_group->index == 5 (Frame 3)
+ LF_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // arf_pos_in_gf
+ 1 // arf_update_idx
+ }
+};
+
+static int define_gf_group_structure_4(AV1_COMP *cpi) {
+ RATE_CONTROL *const rc = &cpi->rc;
+ TWO_PASS *const twopass = &cpi->twopass;
+ GF_GROUP *const gf_group = &twopass->gf_group;
+ const int key_frame = cpi->common.frame_type == KEY_FRAME;
+
+ assert(rc->baseline_gf_interval == GF_INTERVAL_4);
+
+ const int gf_update_frames = rc->baseline_gf_interval + 2;
+ int frame_index;
+
+ for (frame_index = 0; frame_index < gf_update_frames; ++frame_index) {
+ int param_idx = 0;
+
+ gf_group->bidir_pred_enabled[frame_index] = 0;
+
+ if (frame_index == 0) {
+ // gf_group->arf_src_offset[frame_index] = 0;
+ gf_group->brf_src_offset[frame_index] = 0;
+ gf_group->bidir_pred_enabled[frame_index] = 0;
+
+ // For key frames the frame target rate is already set and it
+ // is also the golden frame.
+ if (key_frame) continue;
+
+ gf_group->update_type[frame_index] =
+ gf4_multi_layer_params[frame_index][param_idx++];
+
+ if (rc->source_alt_ref_active) {
+ gf_group->update_type[frame_index] = OVERLAY_UPDATE;
+ } else {
+ gf_group->update_type[frame_index] = GF_UPDATE;
+ }
+ param_idx++;
+ } else {
+ gf_group->update_type[frame_index] =
+ gf4_multi_layer_params[frame_index][param_idx++];
+ }
+
+ // setup other parameters
+ gf_group->rf_level[frame_index] =
+ update_type_2_rf_level(gf_group->update_type[frame_index]);
+
+ // == arf_src_offset ==
+ gf_group->arf_src_offset[frame_index] =
+ gf4_multi_layer_params[frame_index][param_idx++];
+
+ // == arf_pos_in_gf ==
+ gf_group->arf_pos_in_gf[frame_index] =
+ gf4_multi_layer_params[frame_index][param_idx++];
+
+ // == arf_update_idx ==
+ gf_group->brf_src_offset[frame_index] =
+ gf4_multi_layer_params[frame_index][param_idx];
+ }
+
+ // NOTE: We need to configure the frame at the end of the sequence + 1 that
+ // will be the start frame for the next group. Otherwise prior to the
+ // call to av1_rc_get_second_pass_params() the data will be undefined.
+ gf_group->arf_update_idx[frame_index] = 0;
+ gf_group->arf_ref_idx[frame_index] = 0;
+
+ if (rc->source_alt_ref_pending) {
+ gf_group->update_type[frame_index] = OVERLAY_UPDATE;
+ gf_group->rf_level[frame_index] = INTER_NORMAL;
+
+ } else {
+ gf_group->update_type[frame_index] = GF_UPDATE;
+ gf_group->rf_level[frame_index] = GF_ARF_STD;
+ }
+
+ gf_group->bidir_pred_enabled[frame_index] = 0;
+ gf_group->brf_src_offset[frame_index] = 0;
+
+ // This value is only used for INTNL_OVERLAY_UPDATE
+ gf_group->arf_pos_in_gf[frame_index] = 0;
+
+ return gf_update_frames;
+}
+#endif // USE_MANUAL_GF4_STRUCT
+#endif // USE_SYMM_MULTI_LAYER
+
static void define_gf_group_structure(AV1_COMP *cpi) {
RATE_CONTROL *const rc = &cpi->rc;
@@ -2139,6 +2453,25 @@ static void define_gf_group_structure(AV1_COMP *cpi) {
return;
}
#endif // USE_GF16_MULTI_LAYER
+#if USE_SYMM_MULTI_LAYER
+ const int valid_customized_gf_length = rc->baseline_gf_interval == 4 ||
+ rc->baseline_gf_interval == 8 ||
+ rc->baseline_gf_interval == 16;
+ // used the new structure only if extra_arf is allowed
+ if (valid_customized_gf_length && rc->source_alt_ref_pending &&
+ cpi->extra_arf_allowed > 0) {
+#if USE_MANUAL_GF4_STRUCT
+ if (rc->baseline_gf_interval == 4)
+ define_gf_group_structure_4(cpi);
+ else
+#endif
+ define_customized_gf_group_structure(cpi);
+ cpi->new_bwdref_update_rule = 1;
+ return;
+ } else {
+ cpi->new_bwdref_update_rule = 0;
+ }
+#endif
TWO_PASS *const twopass = &cpi->twopass;
GF_GROUP *const gf_group = &twopass->gf_group;
@@ -2322,9 +2655,8 @@ static void define_gf_group_structure(AV1_COMP *cpi) {
}
// NOTE: We need to configure the frame at the end of the sequence + 1 that
- // will
- // be the start frame for the next group. Otherwise prior to the call to
- // av1_rc_get_second_pass_params() the data will be undefined.
+ // will be the start frame for the next group. Otherwise prior to the
+ // call to av1_rc_get_second_pass_params() the data will be undefined.
gf_group->arf_update_idx[frame_index] = 0;
gf_group->arf_ref_idx[frame_index] = 0;
@@ -2438,6 +2770,17 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
// TODO(zoeliu): To investigate whether the allocated bits on
// BIPRED_UPDATE frames need to be further adjusted.
gf_group->bit_allocation[frame_index] = target_frame_size;
+#if USE_SYMM_MULTI_LAYER
+ } else if (cpi->new_bwdref_update_rule == 1 &&
+ gf_group->update_type[frame_index] == INTNL_OVERLAY_UPDATE) {
+ int arf_pos = gf_group->arf_pos_in_gf[frame_index];
+ gf_group->bit_allocation[frame_index] = 0;
+
+ // Tried boosting up the allocated bits on backward reference frame
+ // by (target_frame_size >> 2) as in the original setting. However it
+ // does not bring gains for pyramid structure with GF length = 16.
+ gf_group->bit_allocation[arf_pos] = target_frame_size;
+#endif
} else {
assert(gf_group->update_type[frame_index] == LF_UPDATE ||
gf_group->update_type[frame_index] == INTNL_OVERLAY_UPDATE);
@@ -2453,10 +2796,11 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
}
}
- // NOTE: We need to configure the frame at the end of the sequence + 1 that
- // will be the start frame for the next group. Otherwise prior to the
- // call to av1_rc_get_second_pass_params() the data will be undefined.
+#if USE_SYMM_MULTI_LAYER
+ if (cpi->new_bwdref_update_rule == 0 && rc->source_alt_ref_pending) {
+#else
if (rc->source_alt_ref_pending) {
+#endif
if (cpi->num_extra_arfs) {
// NOTE: For bit allocation, move the allocated bits associated with
// INTNL_OVERLAY_UPDATE to the corresponding INTNL_ARF_UPDATE.
@@ -2489,7 +2833,10 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
int i;
double boost_score = 0.0;
+#if !FIX_GF_INTERVAL_LENGTH
double old_boost_score = 0.0;
+ double mv_ratio_accumulator_thresh;
+#endif
double gf_group_err = 0.0;
#if GROUP_ADAPTIVE_MAXQ
double gf_group_raw_error = 0.0;
@@ -2509,7 +2856,7 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
double this_frame_mv_in_out = 0.0;
double mv_in_out_accumulator = 0.0;
double abs_mv_in_out_accumulator = 0.0;
- double mv_ratio_accumulator_thresh;
+
unsigned int allow_alt_ref = is_altref_enabled(cpi);
int f_boost = 0;
@@ -2551,18 +2898,18 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
gf_group_skip_pct -= this_frame->intra_skip_pct;
gf_group_inactive_zone_rows -= this_frame->inactive_zone_rows;
}
-
+#if !FIX_GF_INTERVAL_LENGTH
// Motion breakout threshold for loop below depends on image size.
mv_ratio_accumulator_thresh =
(cpi->initial_height + cpi->initial_width) / 4.0;
-
+#endif
// Set a maximum and minimum interval for the GF group.
// If the image appears almost completely static we can extend beyond this.
{
- int int_max_q = (int)(av1_convert_qindex_to_q(twopass->active_worst_quality,
- cpi->common.bit_depth));
- int int_lbq = (int)(av1_convert_qindex_to_q(rc->last_boosted_qindex,
- cpi->common.bit_depth));
+ int int_max_q = (int)(av1_convert_qindex_to_q(
+ twopass->active_worst_quality, cpi->common.seq_params.bit_depth));
+ int int_lbq = (int)(av1_convert_qindex_to_q(
+ rc->last_boosted_qindex, cpi->common.seq_params.bit_depth));
active_min_gf_interval = rc->min_gf_interval + AOMMIN(2, int_max_q / 200);
if (active_min_gf_interval > rc->max_gf_interval)
@@ -2643,7 +2990,10 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
boost_score +=
decay_accumulator *
calc_frame_boost(cpi, &next_frame, this_frame_mv_in_out, GF_MAX_BOOST);
-
+#if FIX_GF_INTERVAL_LENGTH
+ if (i == (FIXED_GF_LENGTH + 1)) break;
+#else
+ // Skip breaking condition for FIX_GF_INTERVAL_LENGTH
// Break out conditions.
if (
// Break at active_max_gf_interval unless almost totally static.
@@ -2666,9 +3016,9 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
break;
}
}
-
- *this_frame = next_frame;
old_boost_score = boost_score;
+#endif // FIX_GF_INTERVAL_LENGTH
+ *this_frame = next_frame;
}
twopass->gf_zeromotion_pct = (int)(zero_motion_accumulator * 1000.0);
@@ -2693,7 +3043,18 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
}
// Set the interval until the next gf.
- rc->baseline_gf_interval = i - (is_key_frame || rc->source_alt_ref_pending);
+ if (cpi->oxcf.fwd_kf_enabled) {
+ // Ensure the gf group before the next keyframe will contain an altref
+ if ((rc->frames_to_key - i < rc->min_gf_interval) &&
+ (rc->frames_to_key != i)) {
+ rc->baseline_gf_interval = AOMMIN(rc->frames_to_key - rc->min_gf_interval,
+ rc->static_scene_max_gf_interval);
+ } else {
+ rc->baseline_gf_interval = i;
+ }
+ } else {
+ rc->baseline_gf_interval = i - (is_key_frame || rc->source_alt_ref_pending);
+ }
if (non_zero_stdev_count) avg_raw_err_stdev /= non_zero_stdev_count;
// Disable extra altrefs and backward refs for "still" gf group:
@@ -2711,12 +3072,23 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
if (!cpi->extra_arf_allowed) {
cpi->num_extra_arfs = 0;
} else {
+#if USE_SYMM_MULTI_LAYER
+ if (rc->baseline_gf_interval == 4 && rc->source_alt_ref_pending)
+ cpi->num_extra_arfs = 1;
+ else
+ cpi->num_extra_arfs = get_number_of_extra_arfs(
+ rc->baseline_gf_interval, rc->source_alt_ref_pending);
+#else
// Compute how many extra alt_refs we can have
cpi->num_extra_arfs = get_number_of_extra_arfs(rc->baseline_gf_interval,
rc->source_alt_ref_pending);
+#endif // USE_SYMM_MULTI_LAYER
}
+
+#if !USE_SYMM_MULTI_LAYER
// Currently at maximum two extra ARFs' are allowed
assert(cpi->num_extra_arfs <= MAX_EXT_ARFS);
+#endif
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
@@ -3393,12 +3765,66 @@ static void configure_buffer_updates(AV1_COMP *cpi) {
case INTNL_ARF_UPDATE:
cpi->refresh_last_frame = 0;
cpi->refresh_golden_frame = 0;
+#if USE_SYMM_MULTI_LAYER
+ if (cpi->new_bwdref_update_rule == 1) {
+ cpi->refresh_bwd_ref_frame = 1;
+ cpi->refresh_alt2_ref_frame = 0;
+ } else {
+#endif
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 1;
+#if USE_SYMM_MULTI_LAYER
+ }
+#endif
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+
+ default: assert(0); break;
+ }
+}
+
+void av1_configure_buffer_updates_firstpass(AV1_COMP *cpi,
+ FRAME_UPDATE_TYPE update_type) {
+ RATE_CONTROL *rc = &cpi->rc;
+
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
+ cpi->refresh_alt_ref_frame = 0;
+
+ rc->is_bwd_ref_frame = 0;
+
+ switch (update_type) {
+ case ARF_UPDATE:
+ cpi->refresh_alt_ref_frame = 1;
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
+
+ rc->is_src_frame_alt_ref = 0;
+ break;
+ case INTNL_ARF_UPDATE:
cpi->refresh_alt2_ref_frame = 1;
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_bwd_ref_frame = 0;
cpi->refresh_alt_ref_frame = 0;
+ rc->is_src_frame_alt_ref = 0;
+ rc->is_src_frame_ext_arf = 0;
+
break;
+ case BIPRED_UPDATE:
+ cpi->refresh_bwd_ref_frame = 1;
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
+ cpi->refresh_alt_ref_frame = 0;
- default: assert(0); break;
+ rc->is_bwd_ref_frame = 1;
+ break;
+ default: break;
}
}
@@ -3444,7 +3870,12 @@ void av1_rc_get_second_pass_params(AV1_COMP *cpi) {
target_rate = av1_rc_clamp_pframe_target_size(cpi, target_rate);
rc->base_frame_target = target_rate;
- cm->frame_type = INTER_FRAME;
+ if (cpi->no_show_kf) {
+ assert(gf_group->update_type[gf_group->index] == ARF_UPDATE);
+ cm->frame_type = KEY_FRAME;
+ } else {
+ cm->frame_type = INTER_FRAME;
+ }
// Do the firstpass stats indicate that this frame is skippable for the
// partition search?
@@ -3479,7 +3910,7 @@ void av1_rc_get_second_pass_params(AV1_COMP *cpi) {
twopass->baseline_active_worst_quality = tmp_q;
rc->ni_av_qi = tmp_q;
rc->last_q[INTER_FRAME] = tmp_q;
- rc->avg_q = av1_convert_qindex_to_q(tmp_q, cm->bit_depth);
+ rc->avg_q = av1_convert_qindex_to_q(tmp_q, cm->seq_params.bit_depth);
rc->avg_frame_qindex[INTER_FRAME] = tmp_q;
rc->last_q[KEY_FRAME] = (tmp_q + cpi->oxcf.best_allowed_q) / 2;
rc->avg_frame_qindex[KEY_FRAME] = rc->last_q[KEY_FRAME];