diff options
Diffstat (limited to 'third_party/aom/av1/encoder/firstpass.c')
-rw-r--r-- | third_party/aom/av1/encoder/firstpass.c | 992 |
1 files changed, 192 insertions, 800 deletions
diff --git a/third_party/aom/av1/encoder/firstpass.c b/third_party/aom/av1/encoder/firstpass.c index ef0800c79..69dd20c52 100644 --- a/third_party/aom/av1/encoder/firstpass.c +++ b/third_party/aom/av1/encoder/firstpass.c @@ -31,6 +31,7 @@ #include "av1/encoder/aq_variance.h" #include "av1/encoder/av1_quantize.h" #include "av1/encoder/block.h" +#include "av1/encoder/dwt.h" #include "av1/encoder/encodeframe.h" #include "av1/encoder/encodemb.h" #include "av1/encoder/encodemv.h" @@ -39,7 +40,7 @@ #include "av1/encoder/firstpass.h" #include "av1/encoder/mcomp.h" #include "av1/encoder/rd.h" -#include "av1/encoder/dwt.h" +#include "av1/encoder/reconinter_enc.h" #define OUTPUT_FPF 0 #define ARF_STATS_OUTPUT 0 @@ -51,9 +52,10 @@ #define FACTOR_PT_LOW 0.70 #define FACTOR_PT_HIGH 0.90 #define FIRST_PASS_Q 10.0 -#define GF_MAX_BOOST 96.0 +#define GF_MAX_BOOST 90.0 #define INTRA_MODE_PENALTY 1024 -#define KF_MAX_BOOST 128.0 +#define KF_MIN_FRAME_BOOST 80.0 +#define KF_MAX_FRAME_BOOST 128.0 #define MIN_ARF_GF_BOOST 240 #define MIN_DECAY_FACTOR 0.01 #define MIN_KF_BOOST 300 @@ -62,6 +64,7 @@ #define DEFAULT_GRP_WEIGHT 1.0 #define RC_FACTOR_MIN 0.75 #define RC_FACTOR_MAX 1.75 +#define MIN_FWD_KF_INTERVAL 8 #define NCOUNT_INTRA_THRESH 8192 #define NCOUNT_INTRA_FACTOR 3 @@ -1562,576 +1565,9 @@ static int calculate_boost_bits(int frame_count, int boost, 0); } -#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; - TWO_PASS *const twopass = &cpi->twopass; - GF_GROUP *const gf_group = &twopass->gf_group; - const int key_frame = cpi->common.frame_type == KEY_FRAME; - - assert(rc->baseline_gf_interval == GF_INTERVAL_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->ref_fb_idx[LAST_FRAME - 1]; - gf_group->refresh_flag[frame_index] = cpi->ref_fb_idx[LAST_FRAME - 1]; - - 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 - #if USE_SYMM_MULTI_LAYER +// #define CHCEK_GF_PARAMETER +#ifdef CHCEK_GF_PARAMETER void check_frame_params(GF_GROUP *const gf_group, int gf_interval, int frame_nums) { static const char *update_type_strings[] = { @@ -2149,9 +1585,15 @@ void check_frame_params(GF_GROUP *const gf_group, int gf_interval, gf_group->arf_src_offset[i], gf_group->arf_pos_in_gf[i], gf_group->arf_update_idx[i], gf_group->pyramid_level[i]); } + + fprintf(fid, "number of nodes in each level: \n"); + for (int i = 0; i < MAX_PYRAMID_LVL; ++i) { + fprintf(fid, "lvl %d: %d ", i, gf_group->pyramid_lvl_nodes[i]); + } + fprintf(fid, "\n"); fclose(fid); } - +#endif // CHCEK_GF_PARAMETER static int update_type_2_rf_level(FRAME_UPDATE_TYPE update_type) { // Derive rf_level from update_type switch (update_type) { @@ -2169,14 +1611,17 @@ static int update_type_2_rf_level(FRAME_UPDATE_TYPE update_type) { static void set_multi_layer_params(GF_GROUP *const gf_group, int l, int r, int *frame_ind, int arf_ind, int level) { - if (r - l == 2) { - // leaf node, not a look-ahead frame - gf_group->update_type[*frame_ind] = LF_UPDATE; - gf_group->arf_src_offset[*frame_ind] = 0; - gf_group->arf_pos_in_gf[*frame_ind] = 0; - gf_group->arf_update_idx[*frame_ind] = arf_ind; - gf_group->pyramid_level[*frame_ind] = level; - ++(*frame_ind); + if (r - l < 4) { + while (++l < r) { + // leaf nodes, not a look-ahead frame + gf_group->update_type[*frame_ind] = LF_UPDATE; + gf_group->arf_src_offset[*frame_ind] = 0; + gf_group->arf_pos_in_gf[*frame_ind] = 0; + gf_group->arf_update_idx[*frame_ind] = arf_ind; + gf_group->pyramid_level[*frame_ind] = 0; + ++gf_group->pyramid_lvl_nodes[0]; + ++(*frame_ind); + } } else { int m = (l + r) / 2; int arf_pos_in_gf = *frame_ind; @@ -2186,6 +1631,7 @@ static void set_multi_layer_params(GF_GROUP *const gf_group, int l, int r, gf_group->arf_pos_in_gf[*frame_ind] = 0; gf_group->arf_update_idx[*frame_ind] = 1; // mark all internal ARF 1 gf_group->pyramid_level[*frame_ind] = level; + ++gf_group->pyramid_lvl_nodes[level]; ++(*frame_ind); // set parameters for frames displayed before this frame @@ -2209,7 +1655,7 @@ static INLINE unsigned char get_pyramid_height(int pyramid_width) { assert(pyramid_width <= 16 && pyramid_width >= 4 && "invalid gf interval for pyramid structure"); - return pyramid_width == 16 ? 4 : (pyramid_width >= 8 ? 3 : 2); + return pyramid_width > 12 ? 4 : (pyramid_width > 6 ? 3 : 2); } static int construct_multi_layer_gf_structure(GF_GROUP *const gf_group, @@ -2217,6 +1663,10 @@ static int construct_multi_layer_gf_structure(GF_GROUP *const gf_group, int frame_index = 0; gf_group->pyramid_height = get_pyramid_height(gf_interval); + assert(gf_group->pyramid_height <= MAX_PYRAMID_LVL); + + av1_zero_array(gf_group->pyramid_lvl_nodes, MAX_PYRAMID_LVL); + // At the beginning of each GF group it will be a key or overlay frame, gf_group->update_type[frame_index] = OVERLAY_UPDATE; gf_group->arf_src_offset[frame_index] = 0; @@ -2236,9 +1686,6 @@ static int construct_multi_layer_gf_structure(GF_GROUP *const gf_group, // set parameters for the rest of the frames set_multi_layer_params(gf_group, 0, gf_interval, &frame_index, 0, gf_group->pyramid_height - 1); - - // check_frame_params(gf_group, gf_interval, frame_index); - return frame_index; } @@ -2248,8 +1695,8 @@ void define_customized_gf_group_structure(AV1_COMP *cpi) { GF_GROUP *const gf_group = &twopass->gf_group; const int key_frame = cpi->common.frame_type == KEY_FRAME; - assert(rc->baseline_gf_interval == 4 || rc->baseline_gf_interval == 8 || - rc->baseline_gf_interval == 16); + assert(rc->baseline_gf_interval >= 4 && + rc->baseline_gf_interval <= MAX_PYRAMID_SIZE); const int gf_update_frames = construct_multi_layer_gf_structure(gf_group, rc->baseline_gf_interval); @@ -2305,8 +1752,9 @@ void define_customized_gf_group_structure(AV1_COMP *cpi) { // This parameter is useless? gf_group->arf_ref_idx[frame_index] = 0; - +#ifdef CHCEK_GF_PARAMETER check_frame_params(gf_group, rc->baseline_gf_interval, gf_update_frames); +#endif } // It is an example of how to define a GF stucture manually. The function will @@ -2447,16 +1895,10 @@ static int define_gf_group_structure_4(AV1_COMP *cpi) { static void define_gf_group_structure(AV1_COMP *cpi) { RATE_CONTROL *const rc = &cpi->rc; -#if USE_GF16_MULTI_LAYER - if (rc->baseline_gf_interval == 16) { - define_gf_group_structure_16(cpi); - return; - } -#endif // USE_GF16_MULTI_LAYER #if USE_SYMM_MULTI_LAYER - const int valid_customized_gf_length = rc->baseline_gf_interval == 4 || - rc->baseline_gf_interval == 8 || - rc->baseline_gf_interval == 16; + const int valid_customized_gf_length = + rc->baseline_gf_interval >= 4 && + rc->baseline_gf_interval <= MAX_PYRAMID_SIZE; // used the new structure only if extra_arf is allowed if (valid_customized_gf_length && rc->source_alt_ref_pending && cpi->extra_arf_allowed > 0) { @@ -2685,6 +2127,18 @@ static void define_gf_group_structure(AV1_COMP *cpi) { gf_group->brf_src_offset[frame_index] = 0; } +#if USE_SYMM_MULTI_LAYER +#define LEAF_REDUCTION_FACTOR 0.75f +#define LVL_3_BOOST_FACTOR 0.8f +#define LVL_2_BOOST_FACTOR 0.3f + +static float_t lvl_budget_factor[MAX_PYRAMID_LVL - 1][MAX_PYRAMID_LVL - 1] = { + { 1, 0, 0 }, + { LVL_3_BOOST_FACTOR, 0, 0 }, // Leaking budget works better + { LVL_3_BOOST_FACTOR, (1 - LVL_3_BOOST_FACTOR) * LVL_2_BOOST_FACTOR, + (1 - LVL_3_BOOST_FACTOR) * (1 - LVL_2_BOOST_FACTOR) } +}; +#endif // USE_SYMM_MULTI_LAYER 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; @@ -2771,20 +2225,39 @@ static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits, // BIPRED_UPDATE frames need to be further adjusted. gf_group->bit_allocation[frame_index] = target_frame_size; #if USE_SYMM_MULTI_LAYER - } else if (cpi->new_bwdref_update_rule == 1 && + } else if (cpi->new_bwdref_update_rule && gf_group->update_type[frame_index] == INTNL_OVERLAY_UPDATE) { + assert(gf_group->pyramid_height <= MAX_PYRAMID_LVL && + gf_group->pyramid_height >= 0 && + "non-valid height for a pyramid structure"); + int arf_pos = gf_group->arf_pos_in_gf[frame_index]; gf_group->bit_allocation[frame_index] = 0; - // Tried boosting up the allocated bits on backward reference frame - // by (target_frame_size >> 2) as in the original setting. However it - // does not bring gains for pyramid structure with GF length = 16. gf_group->bit_allocation[arf_pos] = target_frame_size; -#endif +#if MULTI_LVL_BOOST_VBR_CQ + const int pyr_h = gf_group->pyramid_height - 2; + const int this_lvl = gf_group->pyramid_level[arf_pos]; + const int dist2top = gf_group->pyramid_height - 1 - this_lvl; + + const float_t budget = + LEAF_REDUCTION_FACTOR * gf_group->pyramid_lvl_nodes[0]; + const float_t lvl_boost = budget * lvl_budget_factor[pyr_h][dist2top] / + gf_group->pyramid_lvl_nodes[this_lvl]; + + gf_group->bit_allocation[arf_pos] += (int)(target_frame_size * lvl_boost); +#endif // MULTI_LVL_BOOST_VBR_CQ +#endif // USE_SYMM_MULTI_LAYER } else { assert(gf_group->update_type[frame_index] == LF_UPDATE || gf_group->update_type[frame_index] == INTNL_OVERLAY_UPDATE); gf_group->bit_allocation[frame_index] = target_frame_size; +#if MULTI_LVL_BOOST_VBR_CQ + if (cpi->new_bwdref_update_rule) { + gf_group->bit_allocation[frame_index] -= + (int)(target_frame_size * LEAF_REDUCTION_FACTOR); + } +#endif // MULTI_LVL_BOOST_VBR_CQ } ++frame_index; @@ -2833,9 +2306,11 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { int i; double boost_score = 0.0; -#if !FIX_GF_INTERVAL_LENGTH +#if !CONFIG_FIX_GF_LENGTH double old_boost_score = 0.0; double mv_ratio_accumulator_thresh; + int active_max_gf_interval; + int active_min_gf_interval; #endif double gf_group_err = 0.0; #if GROUP_ADAPTIVE_MAXQ @@ -2862,8 +2337,6 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { int f_boost = 0; int b_boost = 0; int flash_detected; - int active_max_gf_interval; - int active_min_gf_interval; int64_t gf_group_bits; double gf_group_error_left; int gf_arf_bits; @@ -2898,11 +2371,10 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { gf_group_skip_pct -= this_frame->intra_skip_pct; gf_group_inactive_zone_rows -= this_frame->inactive_zone_rows; } -#if !FIX_GF_INTERVAL_LENGTH +#if !CONFIG_FIX_GF_LENGTH // Motion breakout threshold for loop below depends on image size. mv_ratio_accumulator_thresh = (cpi->initial_height + cpi->initial_width) / 4.0; -#endif // Set a maximum and minimum interval for the GF group. // If the image appears almost completely static we can extend beyond this. { @@ -2915,23 +2387,19 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { if (active_min_gf_interval > rc->max_gf_interval) active_min_gf_interval = rc->max_gf_interval; - if (cpi->multi_arf_allowed) { + // The value chosen depends on the active Q range. At low Q we have + // bits to spare and are better with a smaller interval and smaller boost. + // At high Q when there are few bits to spare we are better with a longer + // interval to spread the cost of the GF. + active_max_gf_interval = 12 + AOMMIN(4, (int_lbq / 6)); + + // We have: active_min_gf_interval <= rc->max_gf_interval + if (active_max_gf_interval < active_min_gf_interval) + active_max_gf_interval = active_min_gf_interval; + else if (active_max_gf_interval > rc->max_gf_interval) active_max_gf_interval = rc->max_gf_interval; - } else { - // The value chosen depends on the active Q range. At low Q we have - // bits to spare and are better with a smaller interval and smaller boost. - // At high Q when there are few bits to spare we are better with a longer - // interval to spread the cost of the GF. - active_max_gf_interval = 12 + AOMMIN(4, (int_lbq / 6)); - - // We have: active_min_gf_interval <= rc->max_gf_interval - if (active_max_gf_interval < active_min_gf_interval) - active_max_gf_interval = active_min_gf_interval; - else if (active_max_gf_interval > rc->max_gf_interval) - active_max_gf_interval = rc->max_gf_interval; - } } - +#endif // !CONFIG_FIX_GF_LENGTH double avg_sr_coded_error = 0; double avg_raw_err_stdev = 0; int non_zero_stdev_count = 0; @@ -2990,10 +2458,10 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { boost_score += decay_accumulator * calc_frame_boost(cpi, &next_frame, this_frame_mv_in_out, GF_MAX_BOOST); -#if FIX_GF_INTERVAL_LENGTH +#if CONFIG_FIX_GF_LENGTH if (i == (FIXED_GF_LENGTH + 1)) break; #else - // Skip breaking condition for FIX_GF_INTERVAL_LENGTH + // Skip breaking condition for CONFIG_FIX_GF_LENGTH // Break out conditions. if ( // Break at active_max_gf_interval unless almost totally static. @@ -3017,7 +2485,7 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { } } old_boost_score = boost_score; -#endif // FIX_GF_INTERVAL_LENGTH +#endif // CONFIG_FIX_GF_LENGTH *this_frame = next_frame; } twopass->gf_zeromotion_pct = (int)(zero_motion_accumulator * 1000.0); @@ -3030,44 +2498,116 @@ static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { assert(num_mbs > 0); if (i) avg_sr_coded_error /= i; + if (non_zero_stdev_count) avg_raw_err_stdev /= non_zero_stdev_count; + + // 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. + const int disable_bwd_extarf = + (zero_motion_accumulator > MIN_ZERO_MOTION && + avg_sr_coded_error / num_mbs < MAX_SR_CODED_ERROR && + avg_raw_err_stdev < MAX_RAW_ERR_VAR); + + if (disable_bwd_extarf) cpi->extra_arf_allowed = 0; + +#define REDUCE_GF_LENGTH_THRESH 4 +#define REDUCE_GF_LENGTH_TO_KEY_THRESH 9 +#define REDUCE_GF_LENGTH_BY 1 + int alt_offset = 0; +#if REDUCE_LAST_GF_LENGTH + // TODO(weitinglin): The length reduction stretagy is tweaking using AOM_Q + // mode, and hurting the performance of VBR mode. We need to investigate how + // to adjust GF length for other modes. + + int allow_gf_length_reduction = + cpi->oxcf.rc_mode == AOM_Q || cpi->extra_arf_allowed == 0; + + // We are going to have an alt ref, but we don't have do adjustment for + // lossless mode + if (allow_alt_ref && allow_gf_length_reduction && + (i < cpi->oxcf.lag_in_frames) && (i >= rc->min_gf_interval) && + !is_lossless_requested(&cpi->oxcf)) { + // adjust length of this gf group if one of the following condition met + // 1: only one overlay frame left and this gf is too long + // 2: next gf group is too short to have arf compared to the current gf + + // maximum length of next gf group + const int next_gf_len = rc->frames_to_key - i; + const int single_overlay_left = + next_gf_len == 0 && i > REDUCE_GF_LENGTH_THRESH; + // the next gf is probably going to have a ARF but it will be shorter than + // this gf + const int unbalanced_gf = + i > REDUCE_GF_LENGTH_TO_KEY_THRESH && + next_gf_len + 1 < REDUCE_GF_LENGTH_TO_KEY_THRESH && + next_gf_len + 1 >= rc->min_gf_interval; + + if (single_overlay_left || unbalanced_gf) { + // Note: Tried roll_back = DIVIDE_AND_ROUND(i, 8), but is does not work + // better in the current setting + const int roll_back = REDUCE_GF_LENGTH_BY; + alt_offset = -roll_back; + i -= roll_back; + } + } +#endif + // Should we use the alternate reference frame. if (allow_alt_ref && (i < cpi->oxcf.lag_in_frames) && (i >= rc->min_gf_interval)) { // Calculate the boost for alt ref. rc->gfu_boost = - calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost, &b_boost); + calc_arf_boost(cpi, alt_offset, (i - 1), (i - 1), &f_boost, &b_boost); rc->source_alt_ref_pending = 1; + + // do not replace ARFs with overlay frames, and keep it as GOLDEN_REF + cpi->preserve_arf_as_gld = 1; } else { rc->gfu_boost = AOMMAX((int)boost_score, MIN_ARF_GF_BOOST); rc->source_alt_ref_pending = 0; + cpi->preserve_arf_as_gld = 0; } // Set the interval until the next gf. - if (cpi->oxcf.fwd_kf_enabled) { - // Ensure the gf group before the next keyframe will contain an altref - if ((rc->frames_to_key - i < rc->min_gf_interval) && - (rc->frames_to_key != i)) { - rc->baseline_gf_interval = AOMMIN(rc->frames_to_key - rc->min_gf_interval, - rc->static_scene_max_gf_interval); - } else { + // If forward keyframes are enabled, ensure the final gf group obeys the + // MIN_FWD_KF_INTERVAL. + if (cpi->oxcf.fwd_kf_enabled && + ((twopass->stats_in - i + rc->frames_to_key) < twopass->stats_in_end)) { + if (i == rc->frames_to_key) { rc->baseline_gf_interval = i; + // if the last gf group will be smaller than MIN_FWD_KF_INTERVAL + } else if ((rc->frames_to_key - i < + AOMMAX(MIN_FWD_KF_INTERVAL, rc->min_gf_interval)) && + (rc->frames_to_key != i)) { + // if possible, merge the last two gf groups + if (rc->frames_to_key <= MAX_PYRAMID_SIZE) { + rc->baseline_gf_interval = rc->frames_to_key; + // if merging the last two gf groups creates a group that is too long, + // split them and force the last gf group to be the MIN_FWD_KF_INTERVAL + } else { + rc->baseline_gf_interval = rc->frames_to_key - MIN_FWD_KF_INTERVAL; + } + } else { + rc->baseline_gf_interval = + i - (is_key_frame || rc->source_alt_ref_pending); } } else { rc->baseline_gf_interval = i - (is_key_frame || rc->source_alt_ref_pending); } - if (non_zero_stdev_count) avg_raw_err_stdev /= non_zero_stdev_count; - // Disable extra altrefs and backward refs for "still" gf group: - // 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. - const int disable_bwd_extarf = - (zero_motion_accumulator > MIN_ZERO_MOTION && - avg_sr_coded_error / num_mbs < MAX_SR_CODED_ERROR && - avg_raw_err_stdev < MAX_RAW_ERR_VAR); - - if (disable_bwd_extarf) cpi->extra_arf_allowed = 0; +#if REDUCE_LAST_ALT_BOOST +#define LAST_ALR_BOOST_FACTOR 0.2f + rc->arf_boost_factor = 1.0; + if (rc->source_alt_ref_pending && !is_lossless_requested(&cpi->oxcf)) { + // Reduce the boost of altref in the last gf group + if (rc->frames_to_key - i == REDUCE_GF_LENGTH_BY || + rc->frames_to_key - i == 0) { + rc->arf_boost_factor = LAST_ALR_BOOST_FACTOR; + } + } +#endif if (!cpi->extra_arf_allowed) { cpi->num_extra_arfs = 0; @@ -3439,6 +2979,11 @@ static void find_next_key_frame(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { // how many bits to spend on it. decay_accumulator = 1.0; boost_score = 0.0; + const double kf_max_boost = + cpi->oxcf.rc_mode == AOM_Q + ? AOMMIN(AOMMAX(rc->frames_to_key * 2.0, KF_MIN_FRAME_BOOST), + KF_MAX_FRAME_BOOST) + : KF_MAX_FRAME_BOOST; for (i = 0; i < (rc->frames_to_key - 1); ++i) { if (EOF == input_stats(twopass, &next_frame)) break; @@ -3450,7 +2995,7 @@ static void find_next_key_frame(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) { if ((i <= rc->max_gf_interval) || ((i <= (rc->max_gf_interval * 4)) && (decay_accumulator > 0.5))) { const double frame_boost = - calc_frame_boost(cpi, this_frame, 0, KF_MAX_BOOST); + calc_frame_boost(cpi, this_frame, 0, kf_max_boost); // How fast is prediction quality decaying. if (!detect_flash(twopass, 0)) { @@ -3513,147 +3058,6 @@ 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]; - - for (int ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame) { - ref_fb_idx_prev[ref_frame] = cpi->ref_fb_idx[ref_frame]; - } - - // 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]; - } - - for (int ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame) { - cpi->ref_fb_idx[ref_frame] = ref_fb_idx_curr[ref_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->ref_fb_idx[LAST_FRAME - LAST_FRAME]; - break; - - case LAST2_FRAME: - cpi->refresh_fb_idx = cpi->ref_fb_idx[LAST2_FRAME - LAST_FRAME]; - break; - - case LAST3_FRAME: - cpi->refresh_fb_idx = cpi->ref_fb_idx[LAST3_FRAME - LAST_FRAME]; - break; - - case GOLDEN_FRAME: - cpi->refresh_fb_idx = cpi->ref_fb_idx[GOLDEN_FRAME - 1]; - break; - - case BWDREF_FRAME: - cpi->refresh_fb_idx = cpi->ref_fb_idx[BWDREF_FRAME - 1]; - break; - - case ALTREF2_FRAME: - cpi->refresh_fb_idx = cpi->ref_fb_idx[ALTREF2_FRAME - 1]; - break; - - case ALTREF_FRAME: - cpi->refresh_fb_idx = cpi->ref_fb_idx[ALTREF_FRAME - 1]; - break; - - case REF_FRAMES: - cpi->refresh_fb_idx = cpi->ref_fb_idx[REF_FRAMES - 1]; - 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; @@ -3667,14 +3071,6 @@ static void configure_buffer_updates(AV1_COMP *cpi) { 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 - switch (twopass->gf_group.update_type[twopass->gf_group.index]) { case KF_UPDATE: cpi->refresh_last_frame = 1; @@ -3979,8 +3375,7 @@ void av1_rc_get_second_pass_params(AV1_COMP *cpi) { : cpi->common.MBs; // The multiplication by 256 reverses a scaling factor of (>> 8) // applied when combining MB error values for the frame. - twopass->mb_av_energy = - log(((this_frame.intra_error * 256.0) / num_mbs) + 1.0); + twopass->mb_av_energy = log((this_frame.intra_error / num_mbs) + 1.0); twopass->frame_avg_haar_energy = log((this_frame.frame_avg_wavelet_energy / num_mbs) + 1.0); } @@ -4020,9 +3415,6 @@ void av1_twopass_postencode_update(AV1_COMP *cpi) { } twopass->kf_group_bits = AOMMAX(twopass->kf_group_bits, 0); - // Increment the gf group index ready for the next frame. - ++twopass->gf_group.index; - // If the rate control is drifting consider adjustment to min or maxq. if ((cpi->oxcf.rc_mode != AOM_Q) && (cpi->twopass.gf_zeromotion_pct < VLOW_MOTION_THRESHOLD) && |