Let aomenc use the key & value api.
Now aomenc also checks the key & value api after checking the
ctrl ID api.
After adding a new parameter to the key & value api, now one just
need to additionally append that entry in the array av1_args. Then
aomenc should be able to support this paramter too.
BUG=aomedia:2875
Change-Id: I24f948585babe9d300ef4d28b406f91610e97453
(cherry picked from commit 77edd8c2d2d92783f4fa02dc3cc8786ecc84b70b)
diff --git a/apps/aomenc.c b/apps/aomenc.c
index f75e9b1..2061ece 100644
--- a/apps/aomenc.c
+++ b/apps/aomenc.c
@@ -315,6 +315,13 @@
&g_av1_codec_arg_defs.sframe_mode,
NULL };
+// The first part of this array should match the control IDs in the array
+// av1_arg_ctrl_map. To add a new option with its control ID, insert the option
+// before the comment "Option that supports the control ID API ends here."
+// Alternatively, to add a new option supported by the key & value API, just
+// append the option to this array.
+// TODO(bohanli): Currently all options are supported by the key & value API.
+// Consider removing the control ID usages?
const arg_def_t *av1_args[] = {
&g_av1_codec_arg_defs.cpu_used_av1,
&g_av1_codec_arg_defs.auto_altref,
@@ -421,7 +428,7 @@
&g_av1_codec_arg_defs.input_chroma_subsampling_y,
#if CONFIG_TUNE_VMAF
&g_av1_codec_arg_defs.vmaf_model_path,
-#endif
+#endif // Option that supports the control ID API ends here.
&g_av1_codec_arg_defs.subgop_config_str,
&g_av1_codec_arg_defs.subgop_config_path,
NULL
@@ -491,6 +498,8 @@
stereo_format_t stereo_fmt;
int arg_ctrls[ARG_CTRL_CNT_MAX][2];
int arg_ctrl_cnt;
+ const char *arg_key_vals[ARG_CTRL_CNT_MAX][2];
+ int arg_key_val_cnt;
int write_webm;
const char *film_grain_filename;
int write_ivf;
@@ -840,11 +849,40 @@
return quantizer_to_qindex[quantizer];
}
+static void set_config_arg_key_vals(struct stream_config *config,
+ const char *name, const char *val) {
+ int j;
+
+ // For target level, the settings should accumulate rather than overwrite,
+ // so we simply append it.
+ if (strcmp(name, "target-seq-level-idx") == 0) {
+ j = config->arg_key_val_cnt;
+ assert(j < (int)ARG_CTRL_CNT_MAX);
+ config->arg_key_vals[j][0] = name;
+ config->arg_key_vals[j][1] = val;
+ ++config->arg_key_val_cnt;
+ return;
+ }
+
+ /* Point either to the next free element or the first instance of this
+ * control.
+ */
+ for (j = 0; j < config->arg_ctrl_cnt; j++)
+ if (strcmp(name, config->arg_key_vals[j][0]) == 0) break;
+
+ /* Update/insert */
+ assert(j < (int)ARG_CTRL_CNT_MAX);
+ config->arg_key_vals[j][0] = name;
+ config->arg_key_vals[j][1] = val;
+
+ if (j == config->arg_key_val_cnt) config->arg_key_val_cnt++;
+}
+
static int parse_stream_params(struct AvxEncoderConfig *global,
struct stream_state *stream, char **argv) {
char **argi, **argj;
struct arg arg;
- static const arg_def_t **ctrl_args = no_args;
+ static const arg_def_t **args_list = no_args;
static const int *ctrl_args_map = NULL;
struct stream_config *config = &stream->config;
int eos_mark_found = 0;
@@ -856,7 +894,7 @@
} else if (strcmp(get_short_name_by_aom_encoder(global->codec), "av1") == 0) {
// TODO(jingning): Reuse AV1 specific encoder configuration parameters.
// Consider to expand this set for AV1 encoder control.
- ctrl_args = av1_args;
+ args_list = av1_args;
ctrl_args_map = av1_arg_ctrl_map;
#endif
}
@@ -1066,14 +1104,23 @@
++config->arg_ctrl_cnt;
} else {
int i, match = 0;
- for (i = 0; ctrl_args[i]; i++) {
- if (arg_match(&arg, ctrl_args[i], argi)) {
+ // check if the ctrl APIs supports this arg
+ for (i = 0; ctrl_args_map && ctrl_args_map[i] && args_list[i]; i++) {
+ if (arg_match(&arg, args_list[i], argi)) {
match = 1;
if (ctrl_args_map) {
set_config_arg_ctrls(config, ctrl_args_map[i], &arg);
}
}
}
+ // check if the key & value API supports this arg
+ for (i = 0; !match && args_list[i]; i++) {
+ if (arg_match(&arg, args_list[i], argi)) {
+ match = 1;
+ set_config_arg_key_vals(config, args_list[i]->long_name, arg.val);
+ break;
+ }
+ }
if (!match) argj++;
}
}
@@ -1415,6 +1462,15 @@
ctx_exit_on_error(&stream->encoder, "Failed to control codec");
}
+ for (i = 0; i < stream->config.arg_key_val_cnt; i++) {
+ const char *name = stream->config.arg_key_vals[i][0];
+ const char *val = stream->config.arg_key_vals[i][1];
+ if (aom_codec_set_option(&stream->encoder, name, val))
+ fprintf(stderr, "Error: Tried to set option %s = %s\n", name, val);
+
+ ctx_exit_on_error(&stream->encoder, "Failed to set codec option");
+ }
+
#if CONFIG_TUNE_VMAF
if (stream->config.vmaf_model_path) {
AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder, AV1E_SET_VMAF_MODEL_PATH,
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index c31d23c..dfb6bbb 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -30,6 +30,7 @@
#include "av1/arg_defs.h"
#include "common/args_helper.h"
+#include "common/tools_common.h"
#include "aom_dsp/psnr.h"
#include "aom_ports/aom_timer.h"
@@ -3153,6 +3154,10 @@
} else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.auto_altref, argv,
err_string)) {
extra_cfg.enable_auto_alt_ref = arg_parse_uint_helper(&arg, err_string);
+ if (strlen(err_string) == 0 && extra_cfg.enable_auto_alt_ref > 1) {
+ warn("auto-alt-ref > 1 is deprecated... setting auto-alt-ref=1\n");
+ extra_cfg.enable_auto_alt_ref = 1;
+ }
} else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.noise_sens, argv,
err_string)) {
extra_cfg.noise_sensitivity = arg_parse_uint_helper(&arg, err_string);