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