diff options
author | trav90 <travawine@palemoon.org> | 2018-10-18 21:53:44 -0500 |
---|---|---|
committer | trav90 <travawine@palemoon.org> | 2018-10-18 21:53:44 -0500 |
commit | ec910d81405c736a4490383a250299a7837c2e64 (patch) | |
tree | 4f27cc226f93a863121aef6c56313e4153a69b3e /third_party/aom/av1/encoder/firstpass.c | |
parent | 01eb57073ba97b2d6cbf20f745dfcc508197adc3 (diff) | |
download | UXP-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.c | 1269 |
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); |