Remove av1_configure_buffer_updates_firstpass()
In pass0/pass1, the cpi->refresh_*_frame flags are initially set by
av1_configure_buffer_updates_firstpass(). This is similar to
av1_configure_buffer_updates() except with a more limited set of
reference types.
In this patch I remove av1_configure_buffer_updates_firstpass(). I
change av1_configure_buffer_updates() to take frame_update_type as an
argument instead of using gf_group.update_type. I change all calls to
av1_configure_buffer_updates_firstpass() to use
av1_configure_buffer_updates() instead.
Note that what av1_configure_buffer_updates_firstpass() called a
BIPRED_UPDATE appears to actually have been a BRF_UPDATE.
This forms part of wider restructuring and refactoring in order to
achieve a clean API separation at the entry to the low-level encoder and
to make the high-level encoding strategy easier to modify.
BUG=aomedia:2244
Change-Id: I3d8883c2ce94cf43ce13640896b6467a814670ec
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 18f1eb7..cc93348 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -31,6 +31,125 @@
#include "av1/encoder/temporal_filter.h"
#include "av1/encoder/tpl_model.h"
+// Define the reference buffers that will be updated post encode.
+void av1_configure_buffer_updates(AV1_COMP *cpi, const FRAME_UPDATE_TYPE type) {
+ // NOTE(weitinglin): Should we define another function to take care of
+ // cpi->rc.is_$Source_Type to make this function as it is in the comment?
+
+ // show_existing_frame is a flag left set from the end of encoding the
+ // previous frame. Alongside it, is_src_frame_alt_ref may also be left
+ // set so shouldn't be cleared in this case.
+ if (!cpi->common.show_existing_frame) cpi->rc.is_src_frame_alt_ref = 0;
+
+ cpi->rc.is_bwd_ref_frame = 0;
+ cpi->rc.is_last_bipred_frame = 0;
+ cpi->rc.is_bipred_frame = 0;
+ cpi->rc.is_src_frame_ext_arf = 0;
+
+ switch (type) {
+ case KF_UPDATE:
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_bwd_ref_frame = 1;
+ cpi->refresh_alt2_ref_frame = 1;
+ cpi->refresh_alt_ref_frame = 1;
+ break;
+
+ case LF_UPDATE:
+ 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;
+ break;
+
+ case GF_UPDATE:
+ // TODO(zoeliu): To further investigate whether 'refresh_last_frame' is
+ // needed.
+ cpi->refresh_last_frame = 1;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+
+ case OVERLAY_UPDATE:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 1;
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
+ cpi->refresh_alt_ref_frame = 0;
+
+ cpi->rc.is_src_frame_alt_ref = 1;
+ break;
+
+ case ARF_UPDATE:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ // NOTE: BWDREF does not get updated along with ALTREF_FRAME.
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
+ cpi->refresh_alt_ref_frame = 1;
+ break;
+
+ case BRF_UPDATE:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_bwd_ref_frame = 1;
+ cpi->refresh_alt2_ref_frame = 0;
+ cpi->refresh_alt_ref_frame = 0;
+
+ cpi->rc.is_bwd_ref_frame = 1;
+ break;
+
+ case LAST_BIPRED_UPDATE:
+ 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;
+
+ cpi->rc.is_last_bipred_frame = 1;
+ break;
+
+ case BIPRED_UPDATE:
+ 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;
+
+ cpi->rc.is_bipred_frame = 1;
+ break;
+
+ case INTNL_OVERLAY_UPDATE:
+ 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;
+
+ cpi->rc.is_src_frame_alt_ref = 1;
+ cpi->rc.is_src_frame_ext_arf = 1;
+ break;
+
+ case INTNL_ARF_UPDATE:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ if (cpi->new_bwdref_update_rule == 1 && cpi->oxcf.pass == 2) {
+ cpi->refresh_bwd_ref_frame = 1;
+ cpi->refresh_alt2_ref_frame = 0;
+ } else {
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 1;
+ }
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+
+ default: assert(0); break;
+ }
+}
+
static void set_additional_frame_flags(const AV1_COMMON *const cm,
unsigned int *const frame_flags) {
if (frame_is_intra_only(cm)) *frame_flags |= FRAMEFLAGS_INTRAONLY;
@@ -247,6 +366,8 @@
// We choose the reference "type" of this frame from the flags which indicate
// which reference frames will be refreshed by it. More than one of these
// flags may be set, so the order here implies an order of precedence.
+ // This is just used to choose the primary_ref_frame (as the most recent
+ // reference buffer of the same reference-type as the current frame)
const int intra_only = frame_params->frame_type == KEY_FRAME ||
frame_params->frame_type == INTRA_ONLY_FRAME;
@@ -516,11 +637,7 @@
if (oxcf->pass < 2) {
// In second pass, the buffer updates configure will be set
// in the function av1_rc_get_second_pass_params
- if (!arf2) {
- av1_configure_buffer_updates_firstpass(cpi, ARF_UPDATE);
- } else {
- av1_configure_buffer_updates_firstpass(cpi, INTNL_ARF_UPDATE);
- }
+ av1_configure_buffer_updates(cpi, arf2 ? INTNL_ARF_UPDATE : ARF_UPDATE);
}
}
rc->source_alt_ref_pending = 0;
@@ -593,7 +710,7 @@
if (cpi->oxcf.pass < 2) {
// In second pass, the buffer updates configure will be set
// in the function av1_rc_get_second_pass_params
- av1_configure_buffer_updates_firstpass(cpi, BIPRED_UPDATE);
+ av1_configure_buffer_updates(cpi, BRF_UPDATE);
}
}
}
diff --git a/av1/encoder/encode_strategy.h b/av1/encoder/encode_strategy.h
index f96202f..1671473 100644
--- a/av1/encoder/encode_strategy.h
+++ b/av1/encoder/encode_strategy.h
@@ -21,6 +21,7 @@
#include "aom/aom_encoder.h"
#include "av1/encoder/encoder.h"
+#include "av1/encoder/firstpass.h"
// This function will implement high-level encode strategy, choosing frame type,
// frame placement, etc. It populates an EncodeFrameParams struct with the
@@ -30,6 +31,10 @@
int64_t *const time_stamp, int64_t *const time_end,
const aom_rational_t *const timebase, int flush);
+// Set individual buffer update flags based on frame reference type
+void av1_configure_buffer_updates(AV1_COMP *const cpi,
+ const FRAME_UPDATE_TYPE type);
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index b1a681d..b94bb39 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3226,15 +3226,6 @@
return 0;
}
-void av1_update_reference(AV1_COMP *cpi, int ref_frame_upd_flags) {
- cpi->ext_refresh_last_frame = (ref_frame_upd_flags & AOM_LAST_FLAG) != 0;
- cpi->ext_refresh_golden_frame = (ref_frame_upd_flags & AOM_GOLD_FLAG) != 0;
- cpi->ext_refresh_alt_ref_frame = (ref_frame_upd_flags & AOM_ALT_FLAG) != 0;
- cpi->ext_refresh_bwd_ref_frame = (ref_frame_upd_flags & AOM_BWD_FLAG) != 0;
- cpi->ext_refresh_alt2_ref_frame = (ref_frame_upd_flags & AOM_ALT2_FLAG) != 0;
- cpi->ext_refresh_frame_flags_pending = 1;
-}
-
int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd) {
AV1_COMMON *const cm = &cpi->common;
const int num_planes = av1_num_planes(cm);
@@ -5742,7 +5733,7 @@
cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_DISABLED;
// default reference buffers update config
- av1_configure_buffer_updates_firstpass(cpi, LF_UPDATE);
+ av1_configure_buffer_updates(cpi, LF_UPDATE);
// Initialize fields related to forward keyframes
cpi->no_show_kf = 0;
@@ -5962,7 +5953,12 @@
upd ^= AOM_ALT2_FLAG;
}
- av1_update_reference(cpi, upd);
+ cpi->ext_refresh_last_frame = (upd & AOM_LAST_FLAG) != 0;
+ cpi->ext_refresh_golden_frame = (upd & AOM_GOLD_FLAG) != 0;
+ cpi->ext_refresh_alt_ref_frame = (upd & AOM_ALT_FLAG) != 0;
+ cpi->ext_refresh_bwd_ref_frame = (upd & AOM_BWD_FLAG) != 0;
+ cpi->ext_refresh_alt2_ref_frame = (upd & AOM_ALT2_FLAG) != 0;
+ cpi->ext_refresh_frame_flags_pending = 1;
}
cpi->ext_use_ref_frame_mvs = cpi->oxcf.allow_ref_frame_mvs &
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 6cd3a08..7b4c02a 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -950,8 +950,6 @@
int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags);
-void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags);
-
int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 3f50204..8b9513b 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -36,6 +36,7 @@
#include "av1/encoder/encodemb.h"
#include "av1/encoder/encodemv.h"
#include "av1/encoder/encoder.h"
+#include "av1/encoder/encode_strategy.h"
#include "av1/encoder/extend.h"
#include "av1/encoder/firstpass.h"
#include "av1/encoder/mcomp.h"
@@ -2934,51 +2935,6 @@
twopass->modified_error_left -= kf_group_err;
}
-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;
-
- rc->is_bwd_ref_frame = 1;
- break;
- default: break;
- }
-}
-
static int is_skippable_frame(const AV1_COMP *cpi) {
// If the current frame does not have non-zero motion vector detected in the
// first pass, and so do its previous and forward frames, then this frame
@@ -3018,7 +2974,7 @@
// advance the input pointer as we already have what we need.
if (gf_group->update_type[gf_group->index] == ARF_UPDATE ||
gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE) {
- av1_configure_buffer_updates(cpi);
+ av1_configure_buffer_updates(cpi, gf_group->update_type[gf_group->index]);
target_rate = gf_group->bit_allocation[gf_group->index];
target_rate = av1_rc_clamp_pframe_target_size(cpi, target_rate);
rc->base_frame_target = target_rate;
@@ -3110,7 +3066,7 @@
#endif
}
- av1_configure_buffer_updates(cpi);
+ av1_configure_buffer_updates(cpi, gf_group->update_type[gf_group->index]);
// Do the firstpass stats indicate that this frame is skippable for the
// partition search?
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index b61116f..be1101a 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -181,8 +181,6 @@
void av1_init_second_pass(struct AV1_COMP *cpi);
void av1_rc_get_second_pass_params(
struct AV1_COMP *cpi, struct EncodeFrameParams *const frame_params);
-void av1_configure_buffer_updates_firstpass(struct AV1_COMP *cpi,
- FRAME_UPDATE_TYPE update_type);
// Post encode update of the rate control parameters for 2-pass
void av1_twopass_postencode_update(struct AV1_COMP *cpi);
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index e34349a..6a76371 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -29,6 +29,7 @@
#include "av1/common/seg_common.h"
#include "av1/encoder/encodemv.h"
+#include "av1/encoder/encode_strategy.h"
#include "av1/encoder/random.h"
#include "av1/encoder/ratectrl.h"
@@ -1304,123 +1305,6 @@
}
}
-// Define the reference buffers that will be updated post encode.
-void av1_configure_buffer_updates(AV1_COMP *cpi) {
- TWO_PASS *const twopass = &cpi->twopass;
-
- // NOTE(weitinglin): Should we define another function to take care of
- // cpi->rc.is_$Source_Type to make this function as it is in the comment?
-
- cpi->rc.is_src_frame_alt_ref = 0;
- cpi->rc.is_bwd_ref_frame = 0;
- cpi->rc.is_last_bipred_frame = 0;
- cpi->rc.is_bipred_frame = 0;
- cpi->rc.is_src_frame_ext_arf = 0;
-
- switch (twopass->gf_group.update_type[twopass->gf_group.index]) {
- case KF_UPDATE:
- cpi->refresh_last_frame = 1;
- cpi->refresh_golden_frame = 1;
- cpi->refresh_bwd_ref_frame = 1;
- cpi->refresh_alt2_ref_frame = 1;
- cpi->refresh_alt_ref_frame = 1;
- break;
-
- case LF_UPDATE:
- 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;
- break;
-
- case GF_UPDATE:
- // TODO(zoeliu): To further investigate whether 'refresh_last_frame' is
- // needed.
- cpi->refresh_last_frame = 1;
- cpi->refresh_golden_frame = 1;
- cpi->refresh_bwd_ref_frame = 0;
- cpi->refresh_alt2_ref_frame = 0;
- cpi->refresh_alt_ref_frame = 0;
- break;
-
- case OVERLAY_UPDATE:
- cpi->refresh_last_frame = 0;
- cpi->refresh_golden_frame = 1;
- cpi->refresh_bwd_ref_frame = 0;
- cpi->refresh_alt2_ref_frame = 0;
- cpi->refresh_alt_ref_frame = 0;
-
- cpi->rc.is_src_frame_alt_ref = 1;
- break;
-
- case ARF_UPDATE:
- cpi->refresh_last_frame = 0;
- cpi->refresh_golden_frame = 0;
- // NOTE: BWDREF does not get updated along with ALTREF_FRAME.
- cpi->refresh_bwd_ref_frame = 0;
- cpi->refresh_alt2_ref_frame = 0;
- cpi->refresh_alt_ref_frame = 1;
- break;
-
- case BRF_UPDATE:
- cpi->refresh_last_frame = 0;
- cpi->refresh_golden_frame = 0;
- cpi->refresh_bwd_ref_frame = 1;
- cpi->refresh_alt2_ref_frame = 0;
- cpi->refresh_alt_ref_frame = 0;
-
- cpi->rc.is_bwd_ref_frame = 1;
- break;
-
- case LAST_BIPRED_UPDATE:
- 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;
-
- cpi->rc.is_last_bipred_frame = 1;
- break;
-
- case BIPRED_UPDATE:
- 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;
-
- cpi->rc.is_bipred_frame = 1;
- break;
-
- case INTNL_OVERLAY_UPDATE:
- 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;
-
- cpi->rc.is_src_frame_alt_ref = 1;
- cpi->rc.is_src_frame_ext_arf = 1;
- break;
-
- case INTNL_ARF_UPDATE:
- cpi->refresh_last_frame = 0;
- cpi->refresh_golden_frame = 0;
- if (cpi->new_bwdref_update_rule == 1) {
- cpi->refresh_bwd_ref_frame = 1;
- cpi->refresh_alt2_ref_frame = 0;
- } else {
- cpi->refresh_bwd_ref_frame = 0;
- cpi->refresh_alt2_ref_frame = 1;
- }
- cpi->refresh_alt_ref_frame = 0;
- break;
-
- default: assert(0); break;
- }
-}
-
void av1_estimate_qp_gop(AV1_COMP *cpi) {
AV1_COMMON *const cm = &cpi->common;
int gop_length = cpi->rc.baseline_gf_interval;
@@ -1435,14 +1319,16 @@
cpi->twopass.gf_group.index = idx;
rc_set_frame_target(cpi, target_rate, cm->width, cm->height);
- av1_configure_buffer_updates(cpi);
+ av1_configure_buffer_updates(
+ cpi, cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index]);
tpl_frame->base_qindex = rc_pick_q_and_bounds_two_pass(
cpi, cm->width, cm->height, &bottom_index, &top_index, &arf_q);
tpl_frame->base_qindex = AOMMAX(tpl_frame->base_qindex, 1);
}
// Reset the actual index and frame update
cpi->twopass.gf_group.index = gf_index;
- av1_configure_buffer_updates(cpi);
+ av1_configure_buffer_updates(
+ cpi, cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index]);
}
void av1_rc_postencode_update(AV1_COMP *cpi, uint64_t bytes_used) {
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 78c23cf..36c738c 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -267,8 +267,6 @@
int av1_resize_one_pass_cbr(struct AV1_COMP *cpi);
-void av1_configure_buffer_updates(struct AV1_COMP *cpi);
-
void av1_estimate_qp_gop(struct AV1_COMP *cpi);
#ifdef __cplusplus