diff --git a/args.c b/args.c index 782929022a7137aa2ae041beef2bfe5978178524..7b2cc3a10104f6fdd3802af00d676fbc0bebedcc 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 4fafcf8a4a17b4bb5ec7c150835d0c6baf57f022..7963fa6b71643da4c5fa482229573955c9dead3b 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 3c199d1c21af5d17385a8d951d3e555951acb8e3..3724b11e0318963be149df4e8036723f469cc541 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 2002735d22c9b52b4c5d552d1ae2712e0aee4d64..1528389468fac8b1164d3739b3d24820182c5621 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -497,7 +497,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 0611d5bf6b907f4596d1c869d1d4a20063135304..2cd24da67943b11ea1b4401ab75969cc25a05ea8 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 ed830cca0b4ac64e840d400a7576ff9993284db8..f9592077553ca839ae30ab12c381975832680eb7 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -37,6 +37,7 @@ struct vp8_extracfg unsigned int arnr_max_frames; /* alt_ref Noise Reduction Max Frame Count */ unsigned int arnr_strength; /* alt_ref Noise Reduction Strength */ unsigned int arnr_type; /* alt_ref filter type */ + vp8e_tuning tuning; }; @@ -67,6 +68,7 @@ static const struct extraconfig_map extracfg_map[] = 0, /* arnr_max_frames */ 3, /* arnr_strength */ 3, /* arnr_type*/ + 0, /* tuning*/ } } }; @@ -336,6 +338,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"); @@ -449,6 +452,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); } @@ -1029,6 +1033,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 efd79459aeb152fc32d04ce77af5951c094e0ee5..3ed1cf18279fd7172f2ccccc16d5bf881e938ef9 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -140,7 +140,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 * @@ -224,6 +225,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 @@ -253,7 +266,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 4baeefcdf034410c904b535b788f0d4221fa6785..5e4fe3f0f107bfb80d106e539d2f145346acf5aa 100755 --- a/vpxenc.c +++ b/vpxenc.c @@ -993,18 +993,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 @@ -1317,7 +1326,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++; } }