diff --git a/args.c b/args.c index 782929022..7b2cc3a10 100644 --- a/args.c +++ b/args.c @@ -135,6 +135,17 @@ void arg_show_usage(FILE *fp, const struct arg_def *const *defs) def->long_name, long_val); fprintf(fp, " %-37s\t%s\n", option_text, def->desc); + + if(def->enums) + { + const struct arg_enum_list *listptr; + + fprintf(fp, " %-37s\t ", ""); + + for(listptr = def->enums; listptr->name; listptr++) + fprintf(fp, "%s%s", listptr->name, + listptr[1].name ? ", " : "\n"); + } } } @@ -218,3 +229,37 @@ struct vpx_rational arg_parse_rational(const struct arg *arg) return rat; } + + +int arg_parse_enum(const struct arg *arg) +{ + const struct arg_enum_list *listptr; + long int rawval; + char *endptr; + + /* First see if the value can be parsed as a raw value */ + rawval = strtol(arg->val, &endptr, 10); + if (arg->val[0] != '\0' && endptr[0] == '\0') + { + /* Got a raw value, make sure it's valid */ + for(listptr = arg->def->enums; listptr->name; listptr++) + if(listptr->val == rawval) + return rawval; + } + + /* Next see if it can be parsed as a string */ + for(listptr = arg->def->enums; listptr->name; listptr++) + if(!strcmp(arg->val, listptr->name)) + return listptr->val; + + die("Option %s: Invalid value '%s'\n", arg->name, arg->val); + return 0; +} + + +int arg_parse_enum_or_int(const struct arg *arg) +{ + if(arg->def->enums) + return arg_parse_enum(arg); + return arg_parse_int(arg); +} diff --git a/args.h b/args.h index 4fafcf8a4..7963fa6b7 100644 --- a/args.h +++ b/args.h @@ -22,14 +22,23 @@ struct arg const struct arg_def *def; }; +struct arg_enum_list +{ + const char *name; + int val; +}; +#define ARG_ENUM_LIST_END {0} + typedef struct arg_def { const char *short_name; const char *long_name; int has_val; const char *desc; + const struct arg_enum_list *enums; } arg_def_t; -#define ARG_DEF(s,l,v,d) {s,l,v,d} +#define ARG_DEF(s,l,v,d) {s,l,v,d, NULL} +#define ARG_DEF_ENUM(s,l,v,d,e) {s,l,v,d,e} #define ARG_DEF_LIST_END {0} struct arg arg_init(char **argv); @@ -41,4 +50,5 @@ char **argv_dup(int argc, const char **argv); unsigned int arg_parse_uint(const struct arg *arg); int arg_parse_int(const struct arg *arg); struct vpx_rational arg_parse_rational(const struct arg *arg); +int arg_parse_enum_or_int(const struct arg *arg); #endif diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h index 3c199d1c2..3724b11e0 100644 --- a/vp8/common/onyx.h +++ b/vp8/common/onyx.h @@ -18,6 +18,7 @@ extern "C" #endif #include "vpx/internal/vpx_codec_internal.h" +#include "vpx/vp8cx.h" #include "vpx_scale/yv12config.h" #include "type_aliases.h" #include "ppflags.h" @@ -189,6 +190,8 @@ extern "C" struct vpx_fixed_buf two_pass_stats_in; struct vpx_codec_pkt_list *output_pkt_list; + + vp8e_tuning tuning; } VP8_CONFIG; diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 5f9e54b4b..84631c45f 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -507,7 +507,8 @@ void encode_mb_row(VP8_COMP *cpi, x->rddiv = cpi->RDDIV; x->rdmult = cpi->RDMULT; - activity_sum += vp8_activity_masking(cpi, x); + if(cpi->oxcf.tuning == VP8_TUNE_SSIM) + activity_sum += vp8_activity_masking(cpi, x); // Is segmentation enabled // MB level adjutment to quantizer diff --git a/vp8/encoder/ethreading.c b/vp8/encoder/ethreading.c index 0cab70253..7599568c8 100644 --- a/vp8/encoder/ethreading.c +++ b/vp8/encoder/ethreading.c @@ -115,7 +115,8 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data) x->rddiv = cpi->RDDIV; x->rdmult = cpi->RDMULT; - activity_sum += vp8_activity_masking(cpi, x); + if(cpi->oxcf.tuning == VP8_TUNE_SSIM) + activity_sum += vp8_activity_masking(cpi, x); // Is segmentation enabled // MB level adjutment to quantizer diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index edadd73e3..a833ea5cf 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -38,6 +38,8 @@ struct vp8_extracfg unsigned int arnr_strength; /* alt_ref Noise Reduction Strength */ unsigned int arnr_type; /* alt_ref filter type */ unsigned int experimental; + vp8e_tuning tuning; + }; struct extraconfig_map @@ -68,6 +70,7 @@ static const struct extraconfig_map extracfg_map[] = 3, /* arnr_strength */ 3, /* arnr_type*/ 0, /* experimental mode */ + 0, /* tuning*/ } } }; @@ -338,6 +341,7 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf, oxcf->arnr_strength = vp8_cfg.arnr_strength; oxcf->arnr_type = vp8_cfg.arnr_type; + oxcf->tuning = vp8_cfg.tuning; /* printf("Current VP8 Settings: \n"); @@ -451,6 +455,7 @@ static vpx_codec_err_t set_param(vpx_codec_alg_priv_t *ctx, MAP(VP8E_SET_ARNR_MAXFRAMES, xcfg.arnr_max_frames); MAP(VP8E_SET_ARNR_STRENGTH , xcfg.arnr_strength); MAP(VP8E_SET_ARNR_TYPE , xcfg.arnr_type); + MAP(VP8E_SET_TUNING, xcfg.tuning); } @@ -1050,6 +1055,7 @@ static vpx_codec_ctrl_fn_map_t vp8e_ctf_maps[] = {VP8E_SET_ARNR_MAXFRAMES, set_param}, {VP8E_SET_ARNR_STRENGTH , set_param}, {VP8E_SET_ARNR_TYPE , set_param}, + {VP8E_SET_TUNING, set_param}, { -1, NULL}, }; diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h index 5ab6fbfb7..0e6eea614 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -150,7 +150,8 @@ enum vp8e_enc_control_id VP8E_SET_ARNR_MAXFRAMES, /**< control function to set the max number of frames blurred creating arf*/ VP8E_SET_ARNR_STRENGTH , /**< control function to set the filter strength for the arf */ VP8E_SET_ARNR_TYPE , /**< control function to set the type of filter to use for the arf*/ -} ; + VP8E_SET_TUNING, /**< control function to set visual tuning */ +}; /*!\brief vpx 1-D scaling mode * @@ -234,6 +235,18 @@ typedef enum } vp8e_token_partitions; +/*!\brief VP8 model tuning parameters + * + * Changes the encoder to tune for certain types of input material. + * + */ +typedef enum +{ + VP8_TUNE_PSNR, + VP8_TUNE_SSIM +} vp8e_tuning; + + /*!\brief VP8 encoder control function parameter type * * Defines the data types that VP8E control functions take. Note that @@ -263,7 +276,7 @@ VPX_CTRL_USE_TYPE(VP8E_SET_TOKEN_PARTITIONS, vp8e_token_partitions) VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_MAXFRAMES, unsigned int) VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_STRENGTH , unsigned int) VPX_CTRL_USE_TYPE(VP8E_SET_ARNR_TYPE , unsigned int) - +VPX_CTRL_USE_TYPE(VP8E_SET_TUNING, vp8e_tuning) VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER, int *) VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER_64, int *) diff --git a/vpxenc.c b/vpxenc.c index c77996dcf..dc235e340 100755 --- a/vpxenc.c +++ b/vpxenc.c @@ -997,18 +997,27 @@ static const arg_def_t arnr_strength = ARG_DEF(NULL, "arnr-strength", 1, "AltRef Strength"); static const arg_def_t arnr_type = ARG_DEF(NULL, "arnr-type", 1, "AltRef Type"); +static const struct arg_enum_list tuning_enum[] = { + {"psnr", VP8_TUNE_PSNR}, + {"ssim", VP8_TUNE_SSIM}, + {NULL, 0} +}; +static const arg_def_t tune_ssim = ARG_DEF_ENUM(NULL, "tune", 1, + "Material to favor", tuning_enum); static const arg_def_t *vp8_args[] = { &cpu_used, &auto_altref, &noise_sens, &sharpness, &static_thresh, - &token_parts, &arnr_maxframes, &arnr_strength, &arnr_type, NULL + &token_parts, &arnr_maxframes, &arnr_strength, &arnr_type, + &tune_ssim, NULL }; static const int vp8_arg_ctrl_map[] = { VP8E_SET_CPUUSED, VP8E_SET_ENABLEAUTOALTREF, VP8E_SET_NOISE_SENSITIVITY, VP8E_SET_SHARPNESS, VP8E_SET_STATIC_THRESHOLD, VP8E_SET_TOKEN_PARTITIONS, - VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH , VP8E_SET_ARNR_TYPE, 0 + VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH , VP8E_SET_ARNR_TYPE, + VP8E_SET_TUNING, 0 }; #endif @@ -1325,7 +1334,7 @@ int main(int argc, const char **argv_) if (arg_ctrl_cnt < ARG_CTRL_CNT_MAX) { arg_ctrls[arg_ctrl_cnt][0] = ctrl_args_map[i]; - arg_ctrls[arg_ctrl_cnt][1] = arg_parse_int(&arg); + arg_ctrls[arg_ctrl_cnt][1] = arg_parse_enum_or_int(&arg); arg_ctrl_cnt++; } }