summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/encoder/firstpass.c
diff options
context:
space:
mode:
authortrav90 <travawine@palemoon.org>2018-10-18 21:53:44 -0500
committertrav90 <travawine@palemoon.org>2018-10-18 21:53:44 -0500
commitec910d81405c736a4490383a250299a7837c2e64 (patch)
tree4f27cc226f93a863121aef6c56313e4153a69b3e /third_party/aom/av1/encoder/firstpass.c
parent01eb57073ba97b2d6cbf20f745dfcc508197adc3 (diff)
downloadUXP-ec910d81405c736a4490383a250299a7837c2e64.tar
UXP-ec910d81405c736a4490383a250299a7837c2e64.tar.gz
UXP-ec910d81405c736a4490383a250299a7837c2e64.tar.lz
UXP-ec910d81405c736a4490383a250299a7837c2e64.tar.xz
UXP-ec910d81405c736a4490383a250299a7837c2e64.zip
Update aom to commit id e87fb2378f01103d5d6e477a4ef6892dc714e614
Diffstat (limited to 'third_party/aom/av1/encoder/firstpass.c')
-rw-r--r--third_party/aom/av1/encoder/firstpass.c1269
1 files changed, 1075 insertions, 194 deletions
diff --git a/third_party/aom/av1/encoder/firstpass.c b/third_party/aom/av1/encoder/firstpass.c
index e7d78d83e..2a4200887 100644
--- a/third_party/aom/av1/encoder/firstpass.c
+++ b/third_party/aom/av1/encoder/firstpass.c
@@ -27,8 +27,11 @@
#include "av1/common/entropymv.h"
#include "av1/common/quant_common.h"
#include "av1/common/reconinter.h" // av1_setup_dst_planes()
-#include "av1/encoder/av1_quantize.h"
+#if CONFIG_LV_MAP
+#include "av1/common/txb_common.h"
+#endif
#include "av1/encoder/aq_variance.h"
+#include "av1/encoder/av1_quantize.h"
#include "av1/encoder/block.h"
#include "av1/encoder/encodeframe.h"
#include "av1/encoder/encodemb.h"
@@ -112,7 +115,7 @@ static void output_stats(FIRSTPASS_STATS *stats,
fprintf(fpfile,
"%12.0lf %12.4lf %12.0lf %12.0lf %12.0lf %12.4lf %12.4lf"
"%12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf"
- "%12.4lf %12.4lf %12.0lf %12.0lf %12.0lf %12.4lf\n",
+ "%12.4lf %12.4lf %12.0lf %12.0lf %12.0lf %12.4lf %12.4lf\n",
stats->frame, stats->weight, stats->intra_error, stats->coded_error,
stats->sr_coded_error, stats->pcnt_inter, stats->pcnt_motion,
stats->pcnt_second_ref, stats->pcnt_neutral, stats->intra_skip_pct,
@@ -456,7 +459,7 @@ static void set_first_pass_params(AV1_COMP *cpi) {
cpi->rc.frames_to_key = INT_MAX;
}
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
static double raw_motion_error_stdev(int *raw_motion_err_list,
int raw_motion_err_counts) {
int64_t sum_raw_err = 0;
@@ -468,7 +471,7 @@ static double raw_motion_error_stdev(int *raw_motion_err_list,
for (i = 0; i < raw_motion_err_counts; i++) {
sum_raw_err += raw_motion_err_list[i];
}
- raw_err_avg = sum_raw_err / raw_motion_err_counts;
+ raw_err_avg = (double)sum_raw_err / raw_motion_err_counts;
for (i = 0; i < raw_motion_err_counts; i++) {
raw_err_stdev += (raw_motion_err_list[i] - raw_err_avg) *
(raw_motion_err_list[i] - raw_err_avg);
@@ -479,7 +482,7 @@ static double raw_motion_error_stdev(int *raw_motion_err_list,
raw_err_stdev = sqrt(raw_err_stdev / raw_motion_err_counts);
return raw_err_stdev;
}
-#endif // CONFIG_FLEX_REFS
+#endif // CONFIG_EXT_REFS
#define UL_INTRA_THRESH 50
#define INVALID_ROW -1
@@ -531,13 +534,13 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
od_adapt_ctx pvq_context;
#endif
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
int *raw_motion_err_list;
int raw_motion_err_counts = 0;
CHECK_MEM_ERROR(
cm, raw_motion_err_list,
aom_calloc(cm->mb_rows * cm->mb_cols, sizeof(*raw_motion_err_list)));
-#endif // CONFIG_FLEX_REFS
+#endif // CONFIG_EXT_REFS
// First pass code requires valid last and new frame buffers.
assert(new_yv12 != NULL);
assert(frame_is_intra_only(cm) || (lst_yv12 != NULL));
@@ -575,8 +578,8 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
#if CONFIG_CFL
// Don't store luma on the fist pass since chroma is not computed
- x->cfl_store_y = 0;
-#endif
+ xd->cfl->store_y = 0;
+#endif // CONFIG_CFL
av1_frame_init_quantizer(cpi);
#if CONFIG_PVQ
@@ -623,6 +626,9 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
}
av1_init_mv_probs(cm);
+#if CONFIG_LV_MAP
+ av1_init_lv_map(cm);
+#endif
#if CONFIG_ADAPT_SCAN
av1_init_scan_order(cm);
av1_deliver_eob_threshold(cm, xd);
@@ -1000,9 +1006,9 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
}
}
}
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
raw_motion_err_list[raw_motion_err_counts++] = raw_motion_error;
-#endif // CONFIG_FLEX_REFS
+#endif // CONFIG_EXT_REFS
} else {
sr_coded_error += (int64_t)this_error;
}
@@ -1025,10 +1031,12 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
aom_clear_system_state();
}
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
const double raw_err_stdev =
raw_motion_error_stdev(raw_motion_err_list, raw_motion_err_counts);
-#endif // CONFIG_FLEX_REFS
+ aom_free(raw_motion_err_list);
+#endif // CONFIG_EXT_REFS
+
#if CONFIG_PVQ
#if !CONFIG_ANS
od_ec_enc_clear(&x->daala_enc.w.ec);
@@ -1082,9 +1090,9 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
fps.intra_skip_pct = (double)intra_skip_count / num_mbs;
fps.inactive_zone_rows = (double)image_data_start_row;
fps.inactive_zone_cols = (double)0; // TODO(paulwilkins): fix
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
fps.raw_error_stdev = raw_err_stdev;
-#endif // CONFIG_FLEX_REFS
+#endif // CONFIG_EXT_REFS
if (mvcount > 0) {
fps.MVr = (double)sum_mvr / mvcount;
@@ -1666,47 +1674,618 @@ static void get_arf_buffer_indices(unsigned char *arf_buffer_indices) {
arf_buffer_indices[0] = ARF_SLOT1;
arf_buffer_indices[1] = ARF_SLOT2;
}
-#endif
+#endif // !CONFIG_EXT_REFS
-static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
- double group_error, int gf_arf_bits) {
+#if CONFIG_EXT_REFS
+#if USE_GF16_MULTI_LAYER
+// === GF Group of 16 ===
+#define GF_INTERVAL_16 16
+#define GF_FRAME_PARAMS (REF_FRAMES + 5)
+
+// GF Group of 16: multi-layer hierarchical coding structure
+// 1st Layer: Frame 0 and Frame 16 (ALTREF)
+// 2nd Layer: Frame 8 (ALTREF2)
+// 3rd Layer: Frame 4 and 12 (ALTREF2)
+// 4th Layer: Frame 2, 6, 10, and 14 (BWDREF)
+// 5th Layer: Frame 1, 3, 5, 7, 9, 11, 13, and 15
+static const unsigned char gf16_multi_layer_params[][GF_FRAME_PARAMS] = {
+ // gf_group->index: coding order
+ // (Frame #) : display order
+ {
+ // gf_group->index == 0 (Frame 0)
+ OVERLAY_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // References (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ ALTREF_FRAME, // Index (current) of reference to get updated
+ GOLDEN_FRAME // cpi->refresh_golden_frame = 1
+ },
+ {
+ // gf_group->index == 1 (Frame 16)
+ ARF_UPDATE, // update_type
+ GF_INTERVAL_16 - 1, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ ALTREF_FRAME, // cpi->alt_fb_idx ===> cpi->gld_fb_idx (GOLDEN_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ GOLDEN_FRAME, // cpi->gld_fb_idx ===> cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ ALTREF_FRAME, // Index (current) of reference to get updated
+ ALTREF_FRAME // cpi->refresh_alt_ref_frame = 1
+ },
+ {
+ // gf_group->index == 2 (Frame 8)
+ INTNL_ARF_UPDATE, // update_type
+ (GF_INTERVAL_16 >> 1) - 1, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ ALTREF2_FRAME, // Index (current) of reference to get updated
+ ALTREF2_FRAME // cpi->refresh_alt2_ref_frame = 1
+ },
+ {
+ // gf_group->index == 3 (Frame 4)
+ INTNL_ARF_UPDATE, // update_type
+ (GF_INTERVAL_16 >> 2) - 1, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx ===> cpi->bwd_fb_idx
+ // (BWDREF_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->alt2_fb_idx
+ // (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ ALTREF2_FRAME, // Index (current) of reference to get updated
+ ALTREF2_FRAME // cpi->refresh_alt2_ref_frame = 1
+ },
+ {
+ // gf_group->index == 4 (Frame 2)
+ BRF_UPDATE, // update_type
+ 0, // arf_src_offset
+ 1, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx ===> cpi->bwd_fb_idx
+ // (BWDREF_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->alt2_fb_idx
+ // (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ REF_FRAMES, // Index (current) of reference to get updated
+ BWDREF_FRAME // cpi->refresh_bwd_ref_frame = 1
+ },
+ {
+ // gf_group->index == 5 (Frame 1)
+ LAST_BIPRED_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx ===> cpi->bwd_fb_idx (BWDREF_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx ===> cpi->alt_fb_idx (ALTREF_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx ===> cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ LAST3_FRAME, // Index (current) of reference to get updated
+ LAST_FRAME // cpi->refresh_last_frame = 1
+ },
+ {
+ // gf_group->index == 6 (Frame 3)
+ LF_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->lst_fb_idxes[LAST_FRAME -
+ // LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx ===> cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx ===> cpi->alt2_fb_idx (ALTREF2_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx ===> cpi->alt_fb_idx (ALTREF_FRAME)
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ LAST3_FRAME, // Index (current) of reference to get updated
+ LAST_FRAME // cpi->refresh_last_frame = 1
+ },
+ {
+ // gf_group->index == 7 (Frame 4 - OVERLAY)
+ INTNL_OVERLAY_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ BWDREF_FRAME, // Index (current) of reference to get updated
+ ALTREF2_FRAME // cpi->refresh_alt2_ref_frame = 1
+ },
+ {
+ // gf_group->index == 8 (Frame 6)
+ BRF_UPDATE, // update_type
+ 0, // arf_src_offset
+ 1, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->lst_fb_idxes[LAST_FRAME -
+ // LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx -> cpi->bwd_fb_idx (BWDREF_FRAME)
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ ALTREF2_FRAME, // Index (current) of reference to get updated
+ BWDREF_FRAME // cpi->refresh_bwd_frame = 1
+ },
+ {
+ // gf_group->index == 9 (Frame 5)
+ LAST_BIPRED_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx ===> cpi->bwd_fb_idx (BWDREF_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ LAST3_FRAME, // Index (current) of reference to get updated
+ LAST_FRAME // cpi->refresh_last_frame = 1
+ },
+ {
+ // gf_group->index == 10 (Frame 7)
+ LF_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->lst_fb_idxes[LAST_FRAME -
+ // LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx ===> cpi->bwd_fb_idx (BWDREF_FRAME)
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ LAST3_FRAME, // Index (current) of reference to get updated
+ LAST_FRAME // cpi->refresh_last_frame = 1
+ },
+ {
+ // gf_group->index == 11 (Frame 8 - OVERLAY)
+ INTNL_OVERLAY_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ BWDREF_FRAME, // Index (current) of reference to get updated
+ ALTREF2_FRAME // cpi->refresh_alt2_ref_frame = 1
+ },
+ {
+ // gf_group->index == 12 (Frame 12)
+ INTNL_ARF_UPDATE, // update_type
+ (GF_INTERVAL_16 >> 2) - 1, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->lst_fb_idxes[LAST_FRAME -
+ // LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ ALTREF2_FRAME, // Index (current) of reference to get updated
+ ALTREF2_FRAME // cpi->refresh_alt2_ref_frame = 1
+ },
+ {
+ // gf_group->index == 13 (Frame 10)
+ BRF_UPDATE, // update_type
+ 0, // arf_src_offset
+ 1, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx ===> cpi->bwd_fb_idx (BWDREF_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ ALTREF2_FRAME, // Index (current) of reference to get updated
+ BWDREF_FRAME // cpi->refresh_bwd_frame = 1
+ },
+ {
+ // gf_group->index == 14 (Frame 9)
+ LAST_BIPRED_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx ===> cpi->bwd_fb_idx (BWDREF_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ LAST3_FRAME, // Index (current) of reference to get updated
+ LAST_FRAME // cpi->refresh_last_frame = 1
+ },
+ {
+ // gf_group->index == 15 (Frame 11)
+ LF_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->lst_fb_idxes[LAST_FRAME -
+ // LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx ===> cpi->bwd_fb_idx (BWDREF_FRAME)
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ LAST3_FRAME, // Index (current) of reference to get updated
+ LAST_FRAME // cpi->refresh_last_frame = 1
+ },
+ {
+ // gf_group->index == 16 (Frame 12 - OVERLAY)
+ INTNL_OVERLAY_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ BWDREF_FRAME, // Index (current) of reference to get updated
+ ALTREF2_FRAME // cpi->refresh_alt2_ref_frame = 1
+ },
+ {
+ // gf_group->index == 17 (Frame 14)
+ BRF_UPDATE, // update_type
+ 0, // arf_src_offset
+ 1, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->lst_fb_idxes[LAST_FRAME -
+ // LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ BWDREF_FRAME, // Index (current) of reference to get updated
+ BWDREF_FRAME // cpi->refresh_bwd_frame = 1
+ },
+ {
+ // gf_group->index == 18 (Frame 13)
+ LAST_BIPRED_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ LAST3_FRAME, // Index (current) of reference to get updated
+ LAST_FRAME // cpi->refresh_last_frame = 1
+ },
+ {
+ // gf_group->index == 19 (Frame 15)
+ LF_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ BWDREF_FRAME, // cpi->bwd_fb_idx ===> cpi->lst_fb_idxes[LAST_FRAME -
+ // LAST_FRAME]
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ LAST3_FRAME, // Index (current) of reference to get updated
+ LAST_FRAME // cpi->refresh_last_frame = 1
+ },
+ {
+ // gf_group->index == 20 (Frame 16 - OVERLAY: Belonging to the next GF
+ // group)
+ OVERLAY_UPDATE, // update_type
+ 0, // arf_src_offset
+ 0, // brf_src_offset
+ // Reference frame indexes (previous ===> current)
+ LAST3_FRAME, // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME]
+ LAST_FRAME, // cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME]
+ LAST2_FRAME, // cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] ===>
+ // cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME]
+ GOLDEN_FRAME, // cpi->gld_fb_idx (GOLDEN_FRAME)
+ BWDREF_FRAME, // cpi->bwd_fb_idx (BWDREF_FRAME)
+ ALTREF2_FRAME, // cpi->alt2_fb_idx (ALTREF2_FRAME)
+ ALTREF_FRAME, // cpi->alt_fb_idx (ALTREF_FRAME)
+ REF_FRAMES, // cpi->ext_fb_idx (extra ref frame)
+ // Refreshment (index, flag)
+ ALTREF_FRAME, // Index (current) of reference to get updated
+ GOLDEN_FRAME // cpi->refresh_golden_frame = 1
+ }
+};
+
+// === GF Group of 16 ===
+static void define_gf_group_structure_16(AV1_COMP *cpi) {
RATE_CONTROL *const rc = &cpi->rc;
- const AV1EncoderConfig *const oxcf = &cpi->oxcf;
TWO_PASS *const twopass = &cpi->twopass;
GF_GROUP *const gf_group = &twopass->gf_group;
- FIRSTPASS_STATS frame_stats;
+ const int key_frame = cpi->common.frame_type == KEY_FRAME;
+
+ assert(rc->baseline_gf_interval == GF_INTERVAL_16);
+
+ // Total number of frames to consider for GF group of 16:
+ // = GF group interval + number of OVERLAY's
+ // = rc->baseline_gf_interval + MAX_EXT_ARFS + 1 + 1
+ // NOTE: The OVERLAY frame for the next GF group also needs to consider to
+ // prepare for the reference frame index mapping.
+
+ const int gf_update_frames = rc->baseline_gf_interval + MAX_EXT_ARFS + 2;
+
+ for (int frame_index = 0; frame_index < gf_update_frames; ++frame_index) {
+ int param_idx = 0;
+
+ // Treat KEY_FRAME differently
+ if (frame_index == 0 && key_frame) {
+ gf_group->update_type[frame_index] = KF_UPDATE;
+
+ gf_group->rf_level[frame_index] = KF_STD;
+ 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 (int ref_idx = 0; ref_idx < REF_FRAMES; ++ref_idx)
+ gf_group->ref_fb_idx_map[frame_index][ref_idx] = ref_idx;
+ gf_group->refresh_idx[frame_index] =
+ cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME];
+ gf_group->refresh_flag[frame_index] =
+ cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME];
+
+ continue;
+ }
+
+ // == update_type ==
+ gf_group->update_type[frame_index] =
+ gf16_multi_layer_params[frame_index][param_idx++];
+
+ // == rf_level ==
+ // Derive rf_level from update_type
+ switch (gf_group->update_type[frame_index]) {
+ case LF_UPDATE: gf_group->rf_level[frame_index] = INTER_NORMAL; break;
+ case ARF_UPDATE: gf_group->rf_level[frame_index] = GF_ARF_LOW; break;
+ case OVERLAY_UPDATE:
+ gf_group->rf_level[frame_index] = INTER_NORMAL;
+ break;
+ case BRF_UPDATE: gf_group->rf_level[frame_index] = GF_ARF_LOW; break;
+ case LAST_BIPRED_UPDATE:
+ gf_group->rf_level[frame_index] = INTER_NORMAL;
+ break;
+ case BIPRED_UPDATE: gf_group->rf_level[frame_index] = INTER_NORMAL; break;
+ case INTNL_ARF_UPDATE:
+ gf_group->rf_level[frame_index] = GF_ARF_LOW;
+ break;
+ case INTNL_OVERLAY_UPDATE:
+ gf_group->rf_level[frame_index] = INTER_NORMAL;
+ break;
+ default: gf_group->rf_level[frame_index] = INTER_NORMAL; break;
+ }
+
+ // == arf_src_offset ==
+ gf_group->arf_src_offset[frame_index] =
+ gf16_multi_layer_params[frame_index][param_idx++];
+
+ // == brf_src_offset ==
+ gf_group->brf_src_offset[frame_index] =
+ gf16_multi_layer_params[frame_index][param_idx++];
+
+ // == bidir_pred_enabled ==
+ // Derive bidir_pred_enabled from bidir_src_offset
+ gf_group->bidir_pred_enabled[frame_index] =
+ gf_group->brf_src_offset[frame_index] ? 1 : 0;
+
+ // == ref_fb_idx_map ==
+ for (int ref_idx = 0; ref_idx < REF_FRAMES; ++ref_idx)
+ gf_group->ref_fb_idx_map[frame_index][ref_idx] =
+ gf16_multi_layer_params[frame_index][param_idx++];
+
+ // == refresh_idx ==
+ gf_group->refresh_idx[frame_index] =
+ gf16_multi_layer_params[frame_index][param_idx++];
+
+ // == refresh_flag ==
+ gf_group->refresh_flag[frame_index] =
+ gf16_multi_layer_params[frame_index][param_idx];
+ }
+
+ // Mark the ARF_UPDATE / INTNL_ARF_UPDATE and OVERLAY_UPDATE /
+ // INTNL_OVERLAY_UPDATE for rate allocation
+ // NOTE: Indexes are designed in the display order backward:
+ // ALT[3] .. ALT[2] .. ALT[1] .. ALT[0],
+ // but their coding order is as follows:
+ // ALT0-ALT2-ALT3 .. OVERLAY3 .. OVERLAY2-ALT1 .. OVERLAY1 .. OVERLAY0
+
+ const int num_arfs_in_gf = cpi->num_extra_arfs + 1;
+ const int sub_arf_interval = rc->baseline_gf_interval / num_arfs_in_gf;
+
+ // == arf_pos_for_ovrly ==: Position for OVERLAY
+ for (int arf_idx = 0; arf_idx < num_arfs_in_gf; arf_idx++) {
+ const int prior_num_arfs =
+ (arf_idx <= 1) ? num_arfs_in_gf : (num_arfs_in_gf - 1);
+ cpi->arf_pos_for_ovrly[arf_idx] =
+ sub_arf_interval * (num_arfs_in_gf - arf_idx) + prior_num_arfs;
+ }
+
+ // == arf_pos_in_gf ==: Position for ALTREF
+ cpi->arf_pos_in_gf[0] = 1;
+ cpi->arf_pos_in_gf[1] = cpi->arf_pos_for_ovrly[2] + 1;
+ cpi->arf_pos_in_gf[2] = 2;
+ cpi->arf_pos_in_gf[3] = 3;
+
+ // == arf_update_idx ==
+ // == arf_ref_idx ==
+ // NOTE: Due to the hierarchical nature of GF16, these two parameters only
+ // relect the index to the nearest future overlay.
+ int start_frame_index = 0;
+ for (int arf_idx = (num_arfs_in_gf - 1); arf_idx >= 0; --arf_idx) {
+ const int end_frame_index = cpi->arf_pos_for_ovrly[arf_idx];
+ for (int frame_index = start_frame_index; frame_index <= end_frame_index;
+ ++frame_index) {
+ gf_group->arf_update_idx[frame_index] = arf_idx;
+ gf_group->arf_ref_idx[frame_index] = arf_idx;
+ }
+ start_frame_index = end_frame_index + 1;
+ }
+}
+#endif // USE_GF16_MULTI_LAYER
+#endif // CONFIG_EXT_REFS
+
+static void define_gf_group_structure(AV1_COMP *cpi) {
+ RATE_CONTROL *const rc = &cpi->rc;
+
+#if CONFIG_EXT_REFS
+#if USE_GF16_MULTI_LAYER
+ if (rc->baseline_gf_interval == 16) {
+ define_gf_group_structure_16(cpi);
+ return;
+ }
+#endif // USE_GF16_MULTI_LAYER
+#endif // CONFIG_EXT_REFS
+
+ TWO_PASS *const twopass = &cpi->twopass;
+ GF_GROUP *const gf_group = &twopass->gf_group;
int i;
int frame_index = 0;
- int target_frame_size;
- int key_frame;
- const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
- int64_t total_group_bits = gf_group_bits;
- double modified_err = 0.0;
- double err_fraction;
- int mid_boost_bits = 0;
+ const int key_frame = cpi->common.frame_type == KEY_FRAME;
+
#if CONFIG_EXT_REFS
// The use of bi-predictive frames are only enabled when following 3
// conditions are met:
- // (1) Alt-ref is enabled;
+ // (1) ALTREF is enabled;
// (2) The bi-predictive group interval is at least 2; and
// (3) The bi-predictive group interval is strictly smaller than the
// golden group interval.
const int is_bipred_enabled =
-#if CONFIG_FLEX_REFS
- cpi->bwd_ref_allowed &&
-#endif
- rc->source_alt_ref_pending && rc->bipred_group_interval &&
+ cpi->bwd_ref_allowed && rc->source_alt_ref_pending &&
+ rc->bipred_group_interval &&
rc->bipred_group_interval <=
(rc->baseline_gf_interval - rc->source_alt_ref_pending);
int bipred_group_end = 0;
int bipred_frame_index = 0;
- int arf_pos[MAX_EXT_ARFS + 1];
const unsigned char ext_arf_interval =
(unsigned char)(rc->baseline_gf_interval / (cpi->num_extra_arfs + 1) - 1);
int which_arf = cpi->num_extra_arfs;
int subgroup_interval[MAX_EXT_ARFS + 1];
- int ext_arf_boost[MAX_EXT_ARFS];
int is_sg_bipred_enabled = is_bipred_enabled;
int accumulative_subgroup_interval = 0;
#else
@@ -1714,27 +2293,20 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
unsigned char arf_buffer_indices[MAX_ACTIVE_ARFS];
#endif // CONFIG_EXT_REFS
-#if CONFIG_EXT_REFS
- av1_zero_array(ext_arf_boost, MAX_EXT_ARFS);
-#endif // CONFIG_EXT_REFS
-
- key_frame = cpi->common.frame_type == KEY_FRAME;
-
#if !CONFIG_EXT_REFS
get_arf_buffer_indices(arf_buffer_indices);
#endif // !CONFIG_EXT_REFS
// For key frames the frame target rate is already set and it
// is also the golden frame.
+ // === [frame_index == 0] ===
if (!key_frame) {
if (rc->source_alt_ref_active) {
gf_group->update_type[frame_index] = OVERLAY_UPDATE;
gf_group->rf_level[frame_index] = INTER_NORMAL;
- gf_group->bit_allocation[frame_index] = 0;
} else {
gf_group->update_type[frame_index] = GF_UPDATE;
gf_group->rf_level[frame_index] = GF_ARF_STD;
- gf_group->bit_allocation[frame_index] = gf_arf_bits;
}
#if CONFIG_EXT_REFS
gf_group->arf_update_idx[frame_index] = 0;
@@ -1743,8 +2315,6 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
gf_group->arf_update_idx[frame_index] = arf_buffer_indices[0];
gf_group->arf_ref_idx[frame_index] = arf_buffer_indices[0];
#endif // CONFIG_EXT_REFS
- // Step over the golden frame / overlay frame
- if (EOF == input_stats(twopass, &frame_stats)) return;
}
#if CONFIG_EXT_REFS
@@ -1752,22 +2322,16 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
gf_group->brf_src_offset[frame_index] = 0;
#endif // CONFIG_EXT_REFS
- // Deduct the boost bits for arf (or gf if it is not a key frame)
- // from the group total.
- if (rc->source_alt_ref_pending || !key_frame) total_group_bits -= gf_arf_bits;
-
frame_index++;
#if CONFIG_EXT_REFS
bipred_frame_index++;
#endif // CONFIG_EXT_REFS
- // Store the bits to spend on the ARF if there is one.
+ // === [frame_index == 1] ===
if (rc->source_alt_ref_pending) {
gf_group->update_type[frame_index] = ARF_UPDATE;
gf_group->rf_level[frame_index] = GF_ARF_STD;
- gf_group->bit_allocation[frame_index] = gf_arf_bits;
-
gf_group->arf_src_offset[frame_index] =
(unsigned char)(rc->baseline_gf_interval - 1);
@@ -1792,34 +2356,38 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
// We index ALTREF's as: KEY ----- ALT2 ----- ALT1 ----- ALT0
// but code them in the following order:
// KEY-ALT0-ALT2 ----- OVERLAY2-ALT1 ----- OVERLAY1 ----- OVERLAY0
- arf_pos[0] =
- frame_index + cpi->num_extra_arfs + gf_group->arf_src_offset[1] + 1;
+ //
+ // arf_pos_for_ovrly[]: Position for OVERLAY
+ // arf_pos_in_gf[]: Position for ALTREF
+ cpi->arf_pos_for_ovrly[0] = frame_index + cpi->num_extra_arfs +
+ gf_group->arf_src_offset[frame_index] + 1;
for (i = 0; i < cpi->num_extra_arfs; ++i) {
- arf_pos[i + 1] =
+ cpi->arf_pos_for_ovrly[i + 1] =
frame_index + (cpi->num_extra_arfs - i) * (ext_arf_interval + 2);
- subgroup_interval[i] = arf_pos[i] - arf_pos[i + 1] - (i == 0 ? 1 : 2);
+ subgroup_interval[i] = cpi->arf_pos_for_ovrly[i] -
+ cpi->arf_pos_for_ovrly[i + 1] - (i == 0 ? 1 : 2);
}
- subgroup_interval[cpi->num_extra_arfs] = arf_pos[cpi->num_extra_arfs] -
- frame_index -
- (cpi->num_extra_arfs == 0 ? 1 : 2);
+ subgroup_interval[cpi->num_extra_arfs] =
+ cpi->arf_pos_for_ovrly[cpi->num_extra_arfs] - frame_index -
+ (cpi->num_extra_arfs == 0 ? 1 : 2);
#endif // CONFIG_EXT_REFS
++frame_index;
#if CONFIG_EXT_REFS
// Insert an extra ARF
+ // === [frame_index == 2] ===
if (cpi->num_extra_arfs) {
- gf_group->update_type[frame_index] = ARF_UPDATE;
- // Note (weitinglin): GF_ARF_LOW is also used as an identifier
- // for internal ALT_REF's:
+ gf_group->update_type[frame_index] = INTNL_ARF_UPDATE;
gf_group->rf_level[frame_index] = GF_ARF_LOW;
gf_group->arf_src_offset[frame_index] = ext_arf_interval;
+
gf_group->arf_update_idx[frame_index] = which_arf;
gf_group->arf_ref_idx[frame_index] = 0;
++frame_index;
}
accumulative_subgroup_interval += subgroup_interval[cpi->num_extra_arfs];
-#else
+#else // !CONFIG_EXT_ARFS
if (cpi->multi_arf_enabled) {
// Set aside a slot for a level 1 arf.
gf_group->update_type[frame_index] = ARF_UPDATE;
@@ -1838,30 +2406,14 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
mid_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
#endif // !CONFIG_EXT_REFS
- // Allocate bits to the other frames in the group.
for (i = 0; i < rc->baseline_gf_interval - rc->source_alt_ref_pending; ++i) {
#if !CONFIG_EXT_REFS
int arf_idx = 0;
-#endif // !CONFIG_EXT_REFS
-
- if (EOF == input_stats(twopass, &frame_stats)) break;
-
- modified_err = calculate_modified_err(cpi, twopass, oxcf, &frame_stats);
-
- if (group_error > 0)
- err_fraction = modified_err / DOUBLE_DIVIDE_CHECK(group_error);
- else
- err_fraction = 0.0;
-
- target_frame_size = (int)((double)total_group_bits * err_fraction);
if (rc->source_alt_ref_pending && cpi->multi_arf_enabled) {
- mid_boost_bits += (target_frame_size >> 4);
- target_frame_size -= (target_frame_size >> 4);
-#if !CONFIG_EXT_REFS
if (frame_index <= mid_frame_idx) arf_idx = 1;
-#endif // !CONFIG_EXT_REFS
}
+#endif // !CONFIG_EXT_REFS
#if CONFIG_EXT_REFS
gf_group->arf_update_idx[frame_index] = which_arf;
@@ -1871,12 +2423,12 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
gf_group->arf_ref_idx[frame_index] = arf_buffer_indices[arf_idx];
#endif // CONFIG_EXT_REFS
- target_frame_size =
- clamp(target_frame_size, 0, AOMMIN(max_bits, (int)total_group_bits));
-
#if CONFIG_EXT_REFS
- // If we are going to have ARFs, check if we can have BWDREF in this
- // subgroup.
+ // If we are going to have ARFs, check whether we can have BWDREF in this
+ // subgroup, and further, whether we can have ARF subgroup which contains
+ // the BWDREF subgroup but contained within the GF group:
+ //
+ // GF group --> ARF subgroup --> BWDREF subgroup
if (rc->source_alt_ref_pending) {
is_sg_bipred_enabled =
is_bipred_enabled &&
@@ -1890,24 +2442,26 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
if (is_sg_bipred_enabled && !bipred_group_end) {
const int cur_brf_src_offset = rc->bipred_group_interval - 1;
- // --- BRF_UPDATE ---
if (bipred_frame_index == 1) {
+ // --- BRF_UPDATE ---
gf_group->update_type[frame_index] = BRF_UPDATE;
- gf_group->bidir_pred_enabled[frame_index] = 1;
+ gf_group->rf_level[frame_index] = GF_ARF_LOW;
gf_group->brf_src_offset[frame_index] = cur_brf_src_offset;
- // --- LAST_BIPRED_UPDATE ---
} else if (bipred_frame_index == rc->bipred_group_interval) {
+ // --- LAST_BIPRED_UPDATE ---
gf_group->update_type[frame_index] = LAST_BIPRED_UPDATE;
- gf_group->bidir_pred_enabled[frame_index] = 1;
+ gf_group->rf_level[frame_index] = INTER_NORMAL;
gf_group->brf_src_offset[frame_index] = 0;
+
// Reset the bi-predictive frame index.
bipred_frame_index = 0;
- // --- BIPRED_UPDATE ---
} else {
+ // --- BIPRED_UPDATE ---
gf_group->update_type[frame_index] = BIPRED_UPDATE;
- gf_group->bidir_pred_enabled[frame_index] = 1;
+ gf_group->rf_level[frame_index] = INTER_NORMAL;
gf_group->brf_src_offset[frame_index] = 0;
}
+ gf_group->bidir_pred_enabled[frame_index] = 1;
bipred_frame_index++;
// Check whether the next bi-predictive frame group would entirely be
@@ -1920,51 +2474,30 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
} else {
#endif // CONFIG_EXT_REFS
gf_group->update_type[frame_index] = LF_UPDATE;
+ gf_group->rf_level[frame_index] = INTER_NORMAL;
#if CONFIG_EXT_REFS
gf_group->bidir_pred_enabled[frame_index] = 0;
gf_group->brf_src_offset[frame_index] = 0;
}
#endif // CONFIG_EXT_REFS
-#if CONFIG_EXT_REFS
- if (gf_group->update_type[frame_index] == BRF_UPDATE) {
- // Boost up the allocated bits on BWDREF_FRAME
- gf_group->rf_level[frame_index] = GF_ARF_LOW;
- gf_group->bit_allocation[frame_index] =
- target_frame_size + (target_frame_size >> 2);
- } else if (gf_group->update_type[frame_index] == LAST_BIPRED_UPDATE) {
- // Press down the allocated bits on LAST_BIPRED_UPDATE frames
- gf_group->rf_level[frame_index] = INTER_NORMAL;
- gf_group->bit_allocation[frame_index] =
- target_frame_size - (target_frame_size >> 1);
- } else if (gf_group->update_type[frame_index] == BIPRED_UPDATE) {
- // TODO(zoeliu): To investigate whether the allocated bits on
- // BIPRED_UPDATE frames need to be further adjusted.
- gf_group->rf_level[frame_index] = INTER_NORMAL;
- gf_group->bit_allocation[frame_index] = target_frame_size;
- } else {
-#endif // CONFIG_EXT_REFS
- gf_group->rf_level[frame_index] = INTER_NORMAL;
- gf_group->bit_allocation[frame_index] = target_frame_size;
-#if CONFIG_EXT_REFS
- }
-#endif // CONFIG_EXT_REFS
-
++frame_index;
#if CONFIG_EXT_REFS
- // Check if we need to update the ARF
+ // Check if we need to update the ARF.
if (is_sg_bipred_enabled && cpi->num_extra_arfs && which_arf > 0 &&
- frame_index > arf_pos[which_arf]) {
+ frame_index > cpi->arf_pos_for_ovrly[which_arf]) {
--which_arf;
accumulative_subgroup_interval += subgroup_interval[which_arf] + 1;
- // Meet the new subgroup. Reset the bipred_group_end flag;
+
+ // Meet the new subgroup; Reset the bipred_group_end flag.
bipred_group_end = 0;
// Insert another extra ARF after the overlay frame
if (which_arf) {
- gf_group->update_type[frame_index] = ARF_UPDATE;
+ gf_group->update_type[frame_index] = INTNL_ARF_UPDATE;
gf_group->rf_level[frame_index] = GF_ARF_LOW;
gf_group->arf_src_offset[frame_index] = ext_arf_interval;
+
gf_group->arf_update_idx[frame_index] = which_arf;
gf_group->arf_ref_idx[frame_index] = 0;
++frame_index;
@@ -1973,10 +2506,9 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
#endif // CONFIG_EXT_REFS
}
-// 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.
+// 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 CONFIG_EXT_REFS
gf_group->arf_update_idx[frame_index] = 0;
gf_group->arf_ref_idx[frame_index] = 0;
@@ -1990,23 +2522,22 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
gf_group->rf_level[frame_index] = INTER_NORMAL;
#if CONFIG_EXT_REFS
+ cpi->arf_pos_in_gf[0] = 1;
if (cpi->num_extra_arfs) {
+ // Overwrite the update_type for extra-ARF's corresponding internal
+ // OVERLAY's: Change from LF_UPDATE to INTNL_OVERLAY_UPDATE.
for (i = cpi->num_extra_arfs; i > 0; --i) {
- int arf_pos_in_gf = (i == cpi->num_extra_arfs ? 2 : arf_pos[i + 1] + 1);
- gf_group->bit_allocation[arf_pos_in_gf] =
- gf_group->bit_allocation[arf_pos[i]];
- gf_group->update_type[arf_pos[i]] = INTNL_OVERLAY_UPDATE;
- gf_group->bit_allocation[arf_pos[i]] = 0;
- gf_group->rf_level[arf_pos[i]] = INTER_NORMAL;
+ cpi->arf_pos_in_gf[i] =
+ (i == cpi->num_extra_arfs ? 2 : cpi->arf_pos_for_ovrly[i + 1] + 1);
+
+ gf_group->update_type[cpi->arf_pos_for_ovrly[i]] = INTNL_OVERLAY_UPDATE;
+ gf_group->rf_level[cpi->arf_pos_for_ovrly[i]] = INTER_NORMAL;
}
}
#else
// Final setup for second arf and its overlay.
if (cpi->multi_arf_enabled) {
- gf_group->bit_allocation[2] =
- gf_group->bit_allocation[mid_frame_idx] + mid_boost_bits;
gf_group->update_type[mid_frame_idx] = OVERLAY_UPDATE;
- gf_group->bit_allocation[mid_frame_idx] = 0;
}
#endif // CONFIG_EXT_REFS
} else {
@@ -2018,6 +2549,168 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
gf_group->bidir_pred_enabled[frame_index] = 0;
gf_group->brf_src_offset[frame_index] = 0;
#endif // CONFIG_EXT_REFS
+}
+
+static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
+ double group_error, int gf_arf_bits) {
+ RATE_CONTROL *const rc = &cpi->rc;
+ const AV1EncoderConfig *const oxcf = &cpi->oxcf;
+ TWO_PASS *const twopass = &cpi->twopass;
+ GF_GROUP *const gf_group = &twopass->gf_group;
+ FIRSTPASS_STATS frame_stats;
+ int i;
+ int frame_index = 0;
+ int target_frame_size;
+ int key_frame;
+ const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
+ int64_t total_group_bits = gf_group_bits;
+ double modified_err = 0.0;
+ double err_fraction;
+ int mid_boost_bits = 0;
+#if CONFIG_EXT_REFS
+ int ext_arf_boost[MAX_EXT_ARFS];
+#else
+ int mid_frame_idx;
+#endif // CONFIG_EXT_REFS
+
+ define_gf_group_structure(cpi);
+
+#if CONFIG_EXT_REFS
+ av1_zero_array(ext_arf_boost, MAX_EXT_ARFS);
+#endif // CONFIG_EXT_REFS
+
+ key_frame = cpi->common.frame_type == KEY_FRAME;
+
+ // For key frames the frame target rate is already set and it
+ // is also the golden frame.
+ // === [frame_index == 0] ===
+ if (!key_frame) {
+ if (rc->source_alt_ref_active)
+ gf_group->bit_allocation[frame_index] = 0;
+ else
+ gf_group->bit_allocation[frame_index] = gf_arf_bits;
+
+ // Step over the golden frame / overlay frame
+ if (EOF == input_stats(twopass, &frame_stats)) return;
+ }
+
+ // Deduct the boost bits for arf (or gf if it is not a key frame)
+ // from the group total.
+ if (rc->source_alt_ref_pending || !key_frame) total_group_bits -= gf_arf_bits;
+
+ frame_index++;
+
+ // Store the bits to spend on the ARF if there is one.
+ // === [frame_index == 1] ===
+ if (rc->source_alt_ref_pending) {
+ gf_group->bit_allocation[frame_index] = gf_arf_bits;
+
+ ++frame_index;
+
+#if CONFIG_EXT_REFS
+ // Skip all the extra-ARF's right after ARF at the starting segment of
+ // the current GF group.
+ if (cpi->num_extra_arfs) {
+ while (gf_group->update_type[frame_index] == INTNL_ARF_UPDATE)
+ ++frame_index;
+ }
+#else // !CONFIG_EXT_ARFS
+ // Set aside a slot for a level 1 arf.
+ if (cpi->multi_arf_enabled) ++frame_index;
+#endif // CONFIG_EXT_ARFS
+ }
+
+#if !CONFIG_EXT_REFS
+ // Define middle frame
+ mid_frame_idx = frame_index + (rc->baseline_gf_interval >> 1) - 1;
+#endif // !CONFIG_EXT_REFS
+
+ // Allocate bits to the other frames in the group.
+ for (i = 0; i < rc->baseline_gf_interval - rc->source_alt_ref_pending; ++i) {
+ if (EOF == input_stats(twopass, &frame_stats)) break;
+
+ modified_err = calculate_modified_err(cpi, twopass, oxcf, &frame_stats);
+
+ if (group_error > 0)
+ err_fraction = modified_err / DOUBLE_DIVIDE_CHECK(group_error);
+ else
+ err_fraction = 0.0;
+
+ target_frame_size = (int)((double)total_group_bits * err_fraction);
+
+ if (rc->source_alt_ref_pending && cpi->multi_arf_enabled) {
+ mid_boost_bits += (target_frame_size >> 4);
+ target_frame_size -= (target_frame_size >> 4);
+ }
+
+ target_frame_size =
+ clamp(target_frame_size, 0, AOMMIN(max_bits, (int)total_group_bits));
+
+#if CONFIG_EXT_REFS
+ if (gf_group->update_type[frame_index] == BRF_UPDATE) {
+ // Boost up the allocated bits on BWDREF_FRAME
+ gf_group->bit_allocation[frame_index] =
+ target_frame_size + (target_frame_size >> 2);
+ } else if (gf_group->update_type[frame_index] == LAST_BIPRED_UPDATE) {
+ // Press down the allocated bits on LAST_BIPRED_UPDATE frames
+ gf_group->bit_allocation[frame_index] =
+ target_frame_size - (target_frame_size >> 1);
+ } else if (gf_group->update_type[frame_index] == BIPRED_UPDATE) {
+ // 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;
+ } else {
+ assert(gf_group->update_type[frame_index] == LF_UPDATE ||
+ gf_group->update_type[frame_index] == INTNL_OVERLAY_UPDATE);
+#endif // CONFIG_EXT_REFS
+ gf_group->bit_allocation[frame_index] = target_frame_size;
+#if CONFIG_EXT_REFS
+ }
+#endif // CONFIG_EXT_REFS
+
+ ++frame_index;
+
+#if CONFIG_EXT_REFS
+ // Skip all the extra-ARF's.
+ if (cpi->num_extra_arfs) {
+ while (gf_group->update_type[frame_index] == INTNL_ARF_UPDATE)
+ ++frame_index;
+ }
+#endif // CONFIG_EXT_REFS
+ }
+
+ // 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) {
+#if CONFIG_EXT_REFS
+ if (cpi->num_extra_arfs) {
+ // NOTE: For bit allocation, move the allocated bits associated with
+ // INTNL_OVERLAY_UPDATE to the corresponding INTNL_ARF_UPDATE.
+ // i > 0 for extra-ARF's and i == 0 for ARF:
+ // arf_pos_for_ovrly[i]: Position for INTNL_OVERLAY_UPDATE
+ // arf_pos_in_gf[i]: Position for INTNL_ARF_UPDATE
+ for (i = cpi->num_extra_arfs; i > 0; --i) {
+ assert(gf_group->update_type[cpi->arf_pos_for_ovrly[i]] ==
+ INTNL_OVERLAY_UPDATE);
+
+ // Encoder's choice:
+ // Set show_existing_frame == 1 for all extra-ARF's, and hence
+ // allocate zero bit for both all internal OVERLAY frames.
+ gf_group->bit_allocation[cpi->arf_pos_in_gf[i]] =
+ gf_group->bit_allocation[cpi->arf_pos_for_ovrly[i]];
+ gf_group->bit_allocation[cpi->arf_pos_for_ovrly[i]] = 0;
+ }
+ }
+#else
+ // Final setup for second arf and its overlay.
+ if (cpi->multi_arf_enabled) {
+ gf_group->bit_allocation[2] =
+ gf_group->bit_allocation[mid_frame_idx] + mid_boost_bits;
+ gf_group->bit_allocation[mid_frame_idx] = 0;
+ }
+#endif // CONFIG_EXT_REFS
+ }
// Note whether multi-arf was enabled this group for next time.
cpi->multi_arf_last_grp_enabled = cpi->multi_arf_enabled;
@@ -2068,10 +2761,10 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
const int is_key_frame = frame_is_intra_only(cm);
const int arf_active_or_kf = is_key_frame || rc->source_alt_ref_active;
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
cpi->extra_arf_allowed = 1;
cpi->bwd_ref_allowed = 1;
-#endif
+#endif // CONFIG_EXT_REFS
// Reset the GF group data structures unless this is a key
// frame in which case it will already have been done.
@@ -2133,11 +2826,15 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
}
}
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS || CONFIG_BGSPRITE
double avg_sr_coded_error = 0;
double avg_raw_err_stdev = 0;
int non_zero_stdev_count = 0;
-#endif // CONFIG_FLEX_REFS
+#endif // CONFIG_EXT_REFS || CONFIG_BGSPRITE
+#if CONFIG_BGSPRITE
+ double avg_pcnt_second_ref = 0;
+ int non_zero_pcnt_second_ref_count = 0;
+#endif
i = 0;
while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
@@ -2162,14 +2859,20 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
accumulate_frame_motion_stats(
&next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator,
&abs_mv_in_out_accumulator, &mv_ratio_accumulator);
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS || CONFIG_BGSPRITE
// sum up the metric values of current gf group
avg_sr_coded_error += next_frame.sr_coded_error;
- if (next_frame.raw_error_stdev) {
+ if (fabs(next_frame.raw_error_stdev) > 0.000001) {
non_zero_stdev_count++;
avg_raw_err_stdev += next_frame.raw_error_stdev;
}
-#endif // CONFIG_FLEX_REFS
+#endif // CONFIG_EXT_REFS || CONFIG_BGSPRITE
+#if CONFIG_BGSPRITE
+ if (this_frame->pcnt_second_ref) {
+ avg_pcnt_second_ref += this_frame->pcnt_second_ref;
+ }
+ non_zero_pcnt_second_ref_count++;
+#endif // CONFIG_BGSPRITE
// Accumulate the effect of prediction quality decay.
if (!flash_detected) {
@@ -2209,8 +2912,18 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
(abs_mv_in_out_accumulator > 3.0) ||
(mv_in_out_accumulator < -2.0) ||
((boost_score - old_boost_score) < BOOST_BREAKOUT)))) {
- boost_score = old_boost_score;
- break;
+#if CONFIG_EXT_REFS
+ // If GF group interval is < 12, we force it to be 8. Otherwise,
+ // if it is >= 12, we keep it as is.
+ // NOTE: 'i' is 1 more than the GF group interval candidate that is being
+ // checked.
+ if (i == (8 + 1) || i >= (12 + 1)) {
+#endif // CONFIG_EXT_REFS
+ boost_score = old_boost_score;
+ break;
+#if CONFIG_EXT_REFS
+ }
+#endif // CONFIG_EXT_REFS
}
*this_frame = next_frame;
@@ -2221,6 +2934,13 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Was the group length constrained by the requirement for a new KF?
rc->constrained_gf_group = (i >= rc->frames_to_key) ? 1 : 0;
+#if CONFIG_EXT_REFS || CONFIG_BGSPRITE
+ const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) ? cpi->initial_mbs
+ : cpi->common.MBs;
+ assert(num_mbs > 0);
+ if (i) avg_sr_coded_error /= i;
+#endif // CONFIG_EXT_REFS || CONFIG_BGSPRITE
+
// Should we use the alternate reference frame.
if (allow_alt_ref && (i < cpi->oxcf.lag_in_frames) &&
(i >= rc->min_gf_interval)) {
@@ -2235,6 +2955,17 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
(zero_motion_accumulator < 0.995))
? 1
: 0;
+#if CONFIG_BGSPRITE
+ if (non_zero_pcnt_second_ref_count) {
+ avg_pcnt_second_ref /= non_zero_pcnt_second_ref_count;
+ }
+
+ cpi->bgsprite_allowed = 1;
+ if (abs_mv_in_out_accumulator > 0.30 || decay_accumulator < 0.90 ||
+ avg_sr_coded_error / num_mbs < 20 || avg_pcnt_second_ref < 0.30) {
+ cpi->bgsprite_allowed = 0;
+ }
+#endif // CONFIG_BGSPRITE
} else {
rc->gfu_boost = AOMMAX((int)boost_score, MIN_ARF_GF_BOOST);
rc->source_alt_ref_pending = 0;
@@ -2243,19 +2974,13 @@ 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 CONFIG_EXT_REFS
-#if CONFIG_FLEX_REFS
- const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) ? cpi->initial_mbs
- : cpi->common.MBs;
- if (i) avg_sr_coded_error /= i;
if (non_zero_stdev_count) avg_raw_err_stdev /= non_zero_stdev_count;
- // Disable extra alter refs and backward ref for "still" gf group
- // zero_motion_accumulator indicates the minimum percentage of (0, 0) motion
- // in gf group
- // avg_sr_coded_error indicates the average of the sse per pixel of each frame
- // in gf group
- // avg_raw_err_stdev indicates the average of the standard deviation of (0, 0)
- // motion error per block of each frame in gf group
+ // Disable extra altrefs and backward refs for "still" gf group:
+ // zero_motion_accumulator: minimum percentage of (0,0) motion;
+ // avg_sr_coded_error: average of the SSE per pixel of each frame;
+ // avg_raw_err_stdev: average of the standard deviation of (0,0)
+ // motion error per block of each frame.
assert(num_mbs > 0);
const int disable_bwd_extarf =
(zero_motion_accumulator > MIN_ZERO_MOTION &&
@@ -2264,13 +2989,13 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
if (disable_bwd_extarf) cpi->extra_arf_allowed = cpi->bwd_ref_allowed = 0;
- if (!cpi->extra_arf_allowed)
+ if (!cpi->extra_arf_allowed) {
cpi->num_extra_arfs = 0;
- else
-#endif // CONFIG_FLEX_REFS
+ } 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);
+ }
// Currently at maximum two extra ARFs' are allowed
assert(cpi->num_extra_arfs <= MAX_EXT_ARFS);
#endif // CONFIG_EXT_REFS
@@ -2652,7 +3377,8 @@ static void find_next_key_frame(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
boost_score += (decay_accumulator * frame_boost);
}
}
- av_decay_accumulator /= (double)loop_decay_counter;
+ if (loop_decay_counter > 0)
+ av_decay_accumulator /= (double)loop_decay_counter;
reset_fpf_position(twopass, start_position);
@@ -2698,11 +3424,158 @@ static void find_next_key_frame(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
twopass->modified_error_left -= kf_group_err;
}
+#if USE_GF16_MULTI_LAYER
+// === GF Group of 16 ===
+void av1_ref_frame_map_idx_updates(AV1_COMP *cpi, int gf_frame_index) {
+ TWO_PASS *const twopass = &cpi->twopass;
+ GF_GROUP *const gf_group = &twopass->gf_group;
+
+ int ref_fb_idx_prev[REF_FRAMES];
+ int ref_fb_idx_curr[REF_FRAMES];
+
+ ref_fb_idx_prev[LAST_FRAME - LAST_FRAME] =
+ cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME];
+ ref_fb_idx_prev[LAST2_FRAME - LAST_FRAME] =
+ cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME];
+ ref_fb_idx_prev[LAST3_FRAME - LAST_FRAME] =
+ cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME];
+ ref_fb_idx_prev[GOLDEN_FRAME - LAST_FRAME] = cpi->gld_fb_idx;
+ ref_fb_idx_prev[BWDREF_FRAME - LAST_FRAME] = cpi->bwd_fb_idx;
+ ref_fb_idx_prev[ALTREF2_FRAME - LAST_FRAME] = cpi->alt2_fb_idx;
+ ref_fb_idx_prev[ALTREF_FRAME - LAST_FRAME] = cpi->alt_fb_idx;
+ ref_fb_idx_prev[REF_FRAMES - LAST_FRAME] = cpi->ext_fb_idx;
+
+ // Update map index for each reference frame
+ for (int ref_idx = 0; ref_idx < REF_FRAMES; ++ref_idx) {
+ int ref_frame = gf_group->ref_fb_idx_map[gf_frame_index][ref_idx];
+ ref_fb_idx_curr[ref_idx] = ref_fb_idx_prev[ref_frame - LAST_FRAME];
+ }
+
+ cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME] =
+ ref_fb_idx_curr[LAST_FRAME - LAST_FRAME];
+ cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME] =
+ ref_fb_idx_curr[LAST2_FRAME - LAST_FRAME];
+ cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME] =
+ ref_fb_idx_curr[LAST3_FRAME - LAST_FRAME];
+ cpi->gld_fb_idx = ref_fb_idx_curr[GOLDEN_FRAME - LAST_FRAME];
+ cpi->bwd_fb_idx = ref_fb_idx_curr[BWDREF_FRAME - LAST_FRAME];
+ cpi->alt2_fb_idx = ref_fb_idx_curr[ALTREF2_FRAME - LAST_FRAME];
+ cpi->alt_fb_idx = ref_fb_idx_curr[ALTREF_FRAME - LAST_FRAME];
+ cpi->ext_fb_idx = ref_fb_idx_curr[REF_FRAMES - LAST_FRAME];
+}
+
+// Define the reference buffers that will be updated post encode.
+static void configure_buffer_updates_16(AV1_COMP *cpi) {
+ TWO_PASS *const twopass = &cpi->twopass;
+ GF_GROUP *const gf_group = &twopass->gf_group;
+
+ if (gf_group->update_type[gf_group->index] == KF_UPDATE) {
+ cpi->refresh_fb_idx = 0;
+
+ 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;
+
+ return;
+ }
+
+ // Update reference frame map indexes
+ av1_ref_frame_map_idx_updates(cpi, gf_group->index);
+
+ // Update refresh index
+ switch (gf_group->refresh_idx[gf_group->index]) {
+ case LAST_FRAME:
+ cpi->refresh_fb_idx = cpi->lst_fb_idxes[LAST_FRAME - LAST_FRAME];
+ break;
+
+ case LAST2_FRAME:
+ cpi->refresh_fb_idx = cpi->lst_fb_idxes[LAST2_FRAME - LAST_FRAME];
+ break;
+
+ case LAST3_FRAME:
+ cpi->refresh_fb_idx = cpi->lst_fb_idxes[LAST3_FRAME - LAST_FRAME];
+ break;
+
+ case GOLDEN_FRAME: cpi->refresh_fb_idx = cpi->gld_fb_idx; break;
+
+ case BWDREF_FRAME: cpi->refresh_fb_idx = cpi->bwd_fb_idx; break;
+
+ case ALTREF2_FRAME: cpi->refresh_fb_idx = cpi->alt2_fb_idx; break;
+
+ case ALTREF_FRAME: cpi->refresh_fb_idx = cpi->alt_fb_idx; break;
+
+ case REF_FRAMES: cpi->refresh_fb_idx = cpi->ext_fb_idx; break;
+
+ default: assert(0); break;
+ }
+
+ // Update refresh flags
+ switch (gf_group->refresh_flag[gf_group->index]) {
+ case LAST_FRAME:
+ 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 GOLDEN_FRAME:
+ 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;
+ break;
+
+ case BWDREF_FRAME:
+ 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;
+ break;
+
+ case ALTREF2_FRAME:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 1;
+ cpi->refresh_alt_ref_frame = 0;
+ break;
+
+ case ALTREF_FRAME:
+ cpi->refresh_last_frame = 0;
+ cpi->refresh_golden_frame = 0;
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
+ cpi->refresh_alt_ref_frame = 1;
+ break;
+
+ default: assert(0); break;
+ }
+
+ switch (gf_group->update_type[gf_group->index]) {
+ case BRF_UPDATE: cpi->rc.is_bwd_ref_frame = 1; break;
+
+ case LAST_BIPRED_UPDATE: cpi->rc.is_last_bipred_frame = 1; break;
+
+ case BIPRED_UPDATE: cpi->rc.is_bipred_frame = 1; break;
+
+ case INTNL_OVERLAY_UPDATE: cpi->rc.is_src_frame_ext_arf = 1;
+ case OVERLAY_UPDATE: cpi->rc.is_src_frame_alt_ref = 1; break;
+
+ default: break;
+ }
+}
+#endif // USE_GF16_MULTI_LAYER
+
// Define the reference buffers that will be updated post encode.
static void configure_buffer_updates(AV1_COMP *cpi) {
TWO_PASS *const twopass = &cpi->twopass;
- // Wei-Ting: Should we define another function to take care of
+ // 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;
@@ -2711,45 +3584,42 @@ static void configure_buffer_updates(AV1_COMP *cpi) {
cpi->rc.is_last_bipred_frame = 0;
cpi->rc.is_bipred_frame = 0;
cpi->rc.is_src_frame_ext_arf = 0;
+
+#if USE_GF16_MULTI_LAYER
+ RATE_CONTROL *const rc = &cpi->rc;
+ if (rc->baseline_gf_interval == 16) {
+ configure_buffer_updates_16(cpi);
+ return;
+ }
+#endif // USE_GF16_MULTI_LAYER
#endif // CONFIG_EXT_REFS
switch (twopass->gf_group.update_type[twopass->gf_group.index]) {
- case KF_UPDATE:
+ case KF_UPDATE: cpi->refresh_last_frame = 1; cpi->refresh_golden_frame = 1;
#if CONFIG_EXT_REFS
cpi->refresh_bwd_ref_frame = 1;
+ cpi->refresh_alt2_ref_frame = 1;
#endif // CONFIG_EXT_REFS
- cpi->refresh_last_frame = 1;
- cpi->refresh_golden_frame = 1;
cpi->refresh_alt_ref_frame = 1;
break;
- case LF_UPDATE:
+ case LF_UPDATE: cpi->refresh_last_frame = 1; cpi->refresh_golden_frame = 0;
#if CONFIG_EXT_REFS
- // If we have extra ALT_REFs, we can use the farthest ALT (ALT0) as
- // the BWD_REF.
- if (cpi->num_extra_arfs) {
- int tmp = cpi->bwd_fb_idx;
-
- cpi->bwd_fb_idx = cpi->alt_fb_idx;
- cpi->alt_fb_idx = cpi->arf_map[0];
- cpi->arf_map[0] = tmp;
-
- cpi->rc.is_bwd_ref_frame = 1;
- } else {
- cpi->rc.is_bwd_ref_frame = 0;
- }
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
#endif // CONFIG_EXT_REFS
- cpi->refresh_last_frame = 1;
- cpi->refresh_golden_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;
#if CONFIG_EXT_REFS
cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
#endif // CONFIG_EXT_REFS
- cpi->refresh_last_frame = 1;
- cpi->refresh_golden_frame = 1;
cpi->refresh_alt_ref_frame = 0;
break;
@@ -2758,17 +3628,19 @@ static void configure_buffer_updates(AV1_COMP *cpi) {
cpi->refresh_golden_frame = 1;
#if CONFIG_EXT_REFS
cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
#endif // CONFIG_EXT_REFS
cpi->refresh_alt_ref_frame = 0;
+
cpi->rc.is_src_frame_alt_ref = 1;
break;
- case ARF_UPDATE:
+ case ARF_UPDATE: cpi->refresh_last_frame = 0; cpi->refresh_golden_frame = 0;
#if CONFIG_EXT_REFS
- cpi->refresh_bwd_ref_frame = 1;
+ // NOTE: BWDREF does not get updated along with ALTREF_FRAME.
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 0;
#endif // CONFIG_EXT_REFS
- cpi->refresh_last_frame = 0;
- cpi->refresh_golden_frame = 0;
cpi->refresh_alt_ref_frame = 1;
break;
@@ -2777,26 +3649,19 @@ static void configure_buffer_updates(AV1_COMP *cpi) {
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;
- if (cpi->num_extra_arfs) {
- // Allow BRF use the farthest ALT_REF (ALT0) as BWD_REF by swapping
- // the virtual indices.
- // NOTE: The indices will be swapped back after this frame is encoded
- // (in av1_update_reference_frames()).
- int tmp = cpi->bwd_fb_idx;
-
- cpi->bwd_fb_idx = cpi->alt_fb_idx;
- cpi->alt_fb_idx = cpi->arf_map[0];
- cpi->arf_map[0] = tmp;
- }
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;
@@ -2804,7 +3669,9 @@ static void configure_buffer_updates(AV1_COMP *cpi) {
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;
@@ -2812,10 +3679,20 @@ static void configure_buffer_updates(AV1_COMP *cpi) {
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;
+ cpi->refresh_bwd_ref_frame = 0;
+ cpi->refresh_alt2_ref_frame = 1;
+ cpi->refresh_alt_ref_frame = 0;
+ break;
#endif // CONFIG_EXT_REFS
default: assert(0); break;
@@ -2857,7 +3734,11 @@ void av1_rc_get_second_pass_params(AV1_COMP *cpi) {
// If this is an arf frame then we dont want to read the stats file or
// advance the input pointer as we already have what we need.
- if (gf_group->update_type[gf_group->index] == ARF_UPDATE) {
+ if (gf_group->update_type[gf_group->index] == ARF_UPDATE
+#if CONFIG_EXT_REFS
+ || gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE
+#endif // CONFIG_EXT_REFS
+ ) {
configure_buffer_updates(cpi);
target_rate = gf_group->bit_allocation[gf_group->index];
target_rate = av1_rc_clamp_pframe_target_size(cpi, target_rate);
@@ -2935,7 +3816,7 @@ void av1_rc_get_second_pass_params(AV1_COMP *cpi) {
FILE *fpfile;
fpfile = fopen("arf.stt", "a");
++arf_count;
- fprintf(fpfile, "%10d %10ld %10d %10d %10ld\n", cm->current_video_frame,
+ fprintf(fpfile, "%10d %10d %10d %10d %10d\n", cm->current_video_frame,
rc->frames_till_gf_update_due, rc->kf_boost, arf_count,
rc->gfu_boost);