Command-line option for max references per frame. Currently works for 7 references (default) or 3 references. Change-Id: Ib4133600352e52975efab080734b8107d06ec82a
diff --git a/aom/aomcx.h b/aom/aomcx.h index b1536a5..223e7c3 100644 --- a/aom/aomcx.h +++ b/aom/aomcx.h
@@ -979,6 +979,10 @@ /*!\brief Control to select maximum height for the GF group pyramid structure * (valid values: 1 - 4) */ AV1E_SET_GF_MAX_PYRAMID_HEIGHT, + + /*!\brief Control to select maximum reference frames allowed per frame + * (valid values: 3 - 7) */ + AV1E_SET_MAX_REFERENCE_FRAMES, }; /*!\brief aom 1-D scaling mode @@ -1359,6 +1363,9 @@ AOM_CTRL_USE_TYPE(AV1E_SET_GF_MAX_PYRAMID_HEIGHT, unsigned int) #define AOM_CTRL_AV1E_SET_GF_MAX_PYRAMID_HEIGHT +AOM_CTRL_USE_TYPE(AV1E_SET_MAX_REFERENCE_FRAMES, unsigned int) +#define AOM_CTRL_AV1E_SET_MAX_REFERENCE_FRAMES + /*!\endcond */ /*! @} - end defgroup aom_encoder */ #ifdef __cplusplus
diff --git a/apps/aomenc.c b/apps/aomenc.c index c4ea248..123ab15 100644 --- a/apps/aomenc.c +++ b/apps/aomenc.c
@@ -604,6 +604,9 @@ static const arg_def_t gf_max_pyr_height = ARG_DEF(NULL, "gf-max-pyr-height", 1, "maximum height for GF group pyramid structure (1 to 4 (default))"); +static const arg_def_t max_reference_frames = ARG_DEF( + NULL, "max-reference-frames", 1, + "maximum number of reference frames allowed per frame (3 to 7 (default))"); static const struct arg_enum_list color_primaries_enum[] = { { "bt709", AOM_CICP_CP_BT_709 }, @@ -782,7 +785,8 @@ #if CONFIG_DENOISE &denoise_noise_level, &denoise_block_size, -#endif +#endif // CONFIG_DENOISE + &max_reference_frames, &enable_ref_frame_mvs, &bitdeptharg, &inbitdeptharg, @@ -865,7 +869,8 @@ #if CONFIG_DENOISE AV1E_SET_DENOISE_NOISE_LEVEL, AV1E_SET_DENOISE_BLOCK_SIZE, -#endif +#endif // CONFIG_DENOISE + AV1E_SET_MAX_REFERENCE_FRAMES, AV1E_SET_ENABLE_REF_FRAME_MVS, 0 }; #endif // CONFIG_AV1_ENCODER
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index d513caf..e15209e 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c
@@ -25,6 +25,7 @@ #include "av1/encoder/bitstream.h" #include "av1/encoder/encoder.h" #include "av1/encoder/firstpass.h" +#include "common/tools_common.h" #define MAG_SIZE (4) #define MAX_NUM_ENHANCEMENT_LAYERS 3 @@ -96,6 +97,7 @@ int enable_order_hint; // enable order hint for sequence int enable_tx64; // enable 64-pt transform usage for sequence int enable_dist_wtd_comp; // enable dist wtd compound for sequence + int max_reference_frames; // maximum number of references per frame int enable_ref_frame_mvs; // sequence level int allow_ref_frame_mvs; // frame level int enable_masked_comp; // enable masked compound for sequence @@ -191,6 +193,7 @@ 1, // frame order hint 1, // enable 64-pt transform usage 1, // dist-wtd compound + 7, // max_reference_frames 1, // enable_ref_frame_mvs sequence level 1, // allow ref_frame_mvs frame level 1, // enable masked compound at sequence level @@ -421,6 +424,7 @@ #endif } + RANGE_CHECK(extra_cfg, max_reference_frames, 3, 7); RANGE_CHECK_HI(extra_cfg, chroma_subsampling_x, 1); RANGE_CHECK_HI(extra_cfg, chroma_subsampling_y, 1); @@ -714,6 +718,14 @@ oxcf->enable_order_hint = extra_cfg->enable_order_hint; oxcf->enable_dist_wtd_comp = extra_cfg->enable_dist_wtd_comp & extra_cfg->enable_order_hint; + oxcf->max_reference_frames = extra_cfg->max_reference_frames; + if (oxcf->max_reference_frames > 3 && oxcf->max_reference_frames < 7) { + // TODO(urvang): Enable all possible values, after they work properly. + warn( + "max_reference_frames values between 3 and 7 are not supported yet. " + "Using value 3 instead."); + oxcf->max_reference_frames = 3; + } oxcf->enable_masked_comp = extra_cfg->enable_masked_comp; oxcf->enable_diff_wtd_comp = extra_cfg->enable_masked_comp & extra_cfg->enable_diff_wtd_comp; @@ -1112,6 +1124,13 @@ return update_extra_cfg(ctx, &extra_cfg); } +static aom_codec_err_t ctrl_set_max_reference_frames(aom_codec_alg_priv_t *ctx, + va_list args) { + struct av1_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.max_reference_frames = CAST(AV1E_SET_MAX_REFERENCE_FRAMES, args); + return update_extra_cfg(ctx, &extra_cfg); +} + static aom_codec_err_t ctrl_set_enable_ref_frame_mvs(aom_codec_alg_priv_t *ctx, va_list args) { struct av1_extracfg extra_cfg = ctx->extra_cfg; @@ -1997,6 +2016,7 @@ { AV1E_SET_ENABLE_ORDER_HINT, ctrl_set_enable_order_hint }, { AV1E_SET_ENABLE_TX64, ctrl_set_enable_tx64 }, { AV1E_SET_ENABLE_DIST_WTD_COMP, ctrl_set_enable_dist_wtd_comp }, + { AV1E_SET_MAX_REFERENCE_FRAMES, ctrl_set_max_reference_frames }, { AV1E_SET_ENABLE_REF_FRAME_MVS, ctrl_set_enable_ref_frame_mvs }, { AV1E_SET_ALLOW_REF_FRAME_MVS, ctrl_set_allow_ref_frame_mvs }, { AV1E_SET_ENABLE_MASKED_COMP, ctrl_set_enable_masked_comp },
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index 9a4e533..f7abda7 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -329,6 +329,7 @@ int enable_order_hint; int enable_dist_wtd_comp; int enable_ref_frame_mvs; + unsigned int max_reference_frames; unsigned int allow_ref_frame_mvs; int enable_masked_comp; int enable_interintra_comp;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index f87a99b..44a364d 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -10867,6 +10867,28 @@ } mask->mode[INTRA_FRAME] |= ~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]); + + // Disable some frames to enforce max number of reference frames requested. + // TODO(urvang): Should this logic be moved to enforce_max_ref_frames()? + const MV_REFERENCE_FRAME disable_order[] = { + LAST3_FRAME, LAST2_FRAME, ALTREF2_FRAME, BWDREF_FRAME, + // GOLDEN_FRAME, + }; + assert(cpi->oxcf.max_reference_frames <= INTER_REFS_PER_FRAME); + const int num_frames_to_disable = + INTER_REFS_PER_FRAME - cpi->oxcf.max_reference_frames; + for (int i = 0; i < num_frames_to_disable; ++i) { + const MV_REFERENCE_FRAME ref_frame_to_disable = disable_order[i]; + + mask->ref_frame1 |= (1 << ref_frame_to_disable); + mask->ref_frame2 |= (1 << ref_frame_to_disable); + + if (ref_frame_to_disable == BWDREF_FRAME && + (cpi->ref_frame_flags & AOM_BWD_FLAG)) { + mask->ref_frame1 |= (1 << ALTREF_FRAME); + mask->ref_frame2 |= (1 << ALTREF_FRAME); + } + } } // Please add/modify parameter setting in this function, making it consistent