Support parsing subgop config from file Change-Id: I74ec5fa5d771588e8bdda203c8a016e4581bcd08
diff --git a/aom/aomcx.h b/aom/aomcx.h index bccf882..6d852ba 100644 --- a/aom/aomcx.h +++ b/aom/aomcx.h
@@ -1266,9 +1266,13 @@ */ AV1E_SET_SUBGOP_CONFIG_STR = 158, + /*!\brief Control to set the subgop config path. + */ + AV1E_SET_SUBGOP_CONFIG_PATH = 159, + /*!\brief Control to get baseline gf interval */ - AV1E_GET_BASELINE_GF_INTERVAL = 159, + AV1E_GET_BASELINE_GF_INTERVAL = 160, }; /*!\brief aom 1-D scaling mode @@ -1787,6 +1791,9 @@ AOM_CTRL_USE_TYPE(AV1E_SET_SUBGOP_CONFIG_STR, const char *) #define AOM_CTRL_AV1E_SET_SUBGOP_CONFIG_STR +AOM_CTRL_USE_TYPE(AV1E_SET_SUBGOP_CONFIG_PATH, const char *) +#define AOM_CTRL_AV1E_SET_SUBGOP_CONFIG_PATH + /*!\endcond */ /*! @} - end defgroup aom_encoder */ #ifdef __cplusplus
diff --git a/apps/aomenc.c b/apps/aomenc.c index f82d0f9..ae9483f 100644 --- a/apps/aomenc.c +++ b/apps/aomenc.c
@@ -848,7 +848,15 @@ static const arg_def_t subgop_config_str = ARG_DEF(NULL, "subgop-config-str", 1, - "Set specified SubGOP configurations for various SubGOP lengths. " + "Set specified SubGOP configurations in string format provided " + "for various SubGOP lengths. " + "If this option is not specified (default), the configurations " + "are chosen by the encoder using a default algorithm."); + +static const arg_def_t subgop_config_path = + ARG_DEF(NULL, "subgop-config-path", 1, + "Set specified SubGOP configurations in config file path provided " + "for various SubGOP lengths. " "If this option is not specified (default), the configurations " "are chosen by the encoder using a default algorithm."); @@ -952,6 +960,7 @@ &vmaf_model_path, #endif &subgop_config_str, + &subgop_config_path, NULL }; static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED, AOME_SET_ENABLEAUTOALTREF, @@ -1053,6 +1062,7 @@ AV1E_SET_VMAF_MODEL_PATH, #endif AV1E_SET_SUBGOP_CONFIG_STR, + AV1E_SET_SUBGOP_CONFIG_PATH, 0 }; #endif // CONFIG_AV1_ENCODER @@ -1132,6 +1142,7 @@ const char *vmaf_model_path; #endif const char *subgop_config_str; + const char *subgop_config_path; }; struct stream_state { @@ -1455,6 +1466,10 @@ config->subgop_config_str = arg->val; return; } + if (key == AV1E_SET_SUBGOP_CONFIG_PATH) { + config->subgop_config_path = arg->val; + return; + } // For target level, the settings should accumulate rather than overwrite, // so we simply append it. @@ -2119,6 +2134,10 @@ AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder, AV1E_SET_SUBGOP_CONFIG_STR, stream->config.subgop_config_str); } + if (stream->config.subgop_config_path) { + AOM_CODEC_CONTROL_TYPECHECKED(&stream->encoder, AV1E_SET_SUBGOP_CONFIG_PATH, + stream->config.subgop_config_path); + } #if CONFIG_AV1_DECODER if (global->test_decode != TEST_DECODE_OFF) { aom_codec_iface_t *decoder = get_aom_decoder_by_short_name(
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index 86473c0..dfde0fd 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c
@@ -53,6 +53,7 @@ aom_tune_metric tuning; const char *vmaf_model_path; const char *subgop_config_str; + const char *subgop_config_path; unsigned int qp; // constant/constrained quality level unsigned int rc_max_intra_bitrate_pct; unsigned int rc_max_inter_bitrate_pct; @@ -227,7 +228,8 @@ 5, // gf_max_pyr_height AOM_TUNE_PSNR, // tuning "/usr/local/share/model/vmaf_v0.6.1.pkl", // VMAF model path - NULL, // SubGOP config string + NULL, // subgop_config_str + NULL, // subgop_config_path 40, // qp 0, // rc_max_intra_bitrate_pct 0, // rc_max_inter_bitrate_pct @@ -1063,6 +1065,7 @@ gf_cfg->gf_max_pyr_height = extra_cfg->gf_max_pyr_height; oxcf->subgop_config_str = extra_cfg->subgop_config_str; + oxcf->subgop_config_path = extra_cfg->subgop_config_path; // Set tune related configuration. tune_cfg->tuning = extra_cfg->tuning; @@ -1898,6 +1901,13 @@ return update_extra_cfg(ctx, &extra_cfg); } +static aom_codec_err_t ctrl_set_subgop_config_path(aom_codec_alg_priv_t *ctx, + va_list args) { + struct av1_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.subgop_config_path = CAST(AV1E_SET_SUBGOP_CONFIG_PATH, args); + return update_extra_cfg(ctx, &extra_cfg); +} + static aom_codec_err_t ctrl_set_film_grain_test_vector( aom_codec_alg_priv_t *ctx, va_list args) { struct av1_extracfg extra_cfg = ctx->extra_cfg; @@ -3090,6 +3100,7 @@ { AV1E_SET_SINGLE_TILE_DECODING, ctrl_set_single_tile_decoding }, { AV1E_SET_VMAF_MODEL_PATH, ctrl_set_vmaf_model_path }, { AV1E_SET_SUBGOP_CONFIG_STR, ctrl_set_subgop_config_str }, + { AV1E_SET_SUBGOP_CONFIG_PATH, ctrl_set_subgop_config_path }, { AV1E_SET_FILM_GRAIN_TEST_VECTOR, ctrl_set_film_grain_test_vector }, { AV1E_SET_FILM_GRAIN_TABLE, ctrl_set_film_grain_table }, { AV1E_SET_DENOISE_NOISE_LEVEL, ctrl_set_denoise_noise_level },
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index be04e23..069630e 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -580,6 +580,13 @@ av1_noise_estimate_init(&cpi->noise_estimate, cm->width, cm->height); } +int aom_strcmp(const char *a, const char *b) { + if (a == NULL && b == NULL) return 0; + if (a == NULL && b != NULL) return -1; + if (a != NULL && b == NULL) return 1; + return strcmp(a, b); +} + void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) { AV1_COMMON *const cm = &cpi->common; SequenceHeader *const seq_params = &cm->seq_params; @@ -796,24 +803,40 @@ cpi->oxcf.gf_cfg.lag_in_frames = lap_lag_in_frames; } - if (cpi->subgop_config_str == NULL || - strcmp(cpi->subgop_config_str, oxcf->subgop_config_str)) { + bool subgop_config_changed = false; + if (aom_strcmp(cpi->subgop_config_path, oxcf->subgop_config_path)) { + aom_free(cpi->subgop_config_path); + if (oxcf->subgop_config_path != NULL) { + cpi->subgop_config_path = + (char *)aom_malloc((strlen(oxcf->subgop_config_path) + 1) * + sizeof(*oxcf->subgop_config_path)); + strcpy(cpi->subgop_config_path, oxcf->subgop_config_path); + } + subgop_config_changed = true; + } + if (aom_strcmp(cpi->subgop_config_str, oxcf->subgop_config_str)) { aom_free(cpi->subgop_config_str); if (oxcf->subgop_config_str != NULL) { cpi->subgop_config_str = (char *)aom_malloc((strlen(oxcf->subgop_config_str) + 1) * sizeof(*oxcf->subgop_config_str)); strcpy(cpi->subgop_config_str, oxcf->subgop_config_str); - if (cpi->compressor_stage == ENCODE_STAGE) { - av1_init_subgop_config_set(&cpi->subgop_config_set); - av1_process_subgop_config_set(oxcf->subgop_config_str, - &cpi->subgop_config_set); - printf("Successfully processed %d subgop configs.\n", - cpi->subgop_config_set.num_configs); - // Uncomment to print out the configuration - // av1_print_subgop_config_set(&cpi->subgop_config_set); - } } + subgop_config_changed = true; + } + if (subgop_config_changed && cpi->compressor_stage == ENCODE_STAGE) { + av1_init_subgop_config_set(&cpi->subgop_config_set); + // Parse config file first + av1_process_subgop_config_set_fromfile(cpi->subgop_config_path, + &cpi->subgop_config_set); + // Parse config string next, which may override config file configs + // or append to it. + av1_process_subgop_config_set(cpi->subgop_config_str, + &cpi->subgop_config_set); + printf("Successfully processed %d subgop configs.\n", + cpi->subgop_config_set.num_configs); + // Uncomment to print out the configuration + // av1_print_subgop_config_set(&cpi->subgop_config_set); } } @@ -1506,6 +1529,7 @@ av1_free_ref_frame_buffers(cm->buffer_pool); aom_free(cpi->subgop_config_str); + aom_free(cpi->subgop_config_path); aom_free(cpi); #ifdef OUTPUT_YUV_REC
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index 1ca4fde..742f49a 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -902,6 +902,9 @@ // SubGOP config. const char *subgop_config_str; + // SubGOP config. + const char *subgop_config_path; + // Configuration related to encoder toolsets. ToolCfg tool_cfg; @@ -2288,6 +2291,11 @@ char *subgop_config_str; /*! + * SubGOP configuration file path + */ + char *subgop_config_path; + + /*! * Information related to subGOP configuration if specified. */ SubGOPSetCfg subgop_config_set;