int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) { int ret; const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); if (o_out) *o_out = o; if (!o) return AVERROR_OPTION_NOT_FOUND; if (!val || o->offset<=0) return AVERROR(EINVAL); if (o->type == FF_OPT_TYPE_BINARY) { uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset); int *lendst = (int *)(dst + 1); uint8_t *bin, *ptr; int len = strlen(val); av_freep(dst); *lendst = 0; if (len & 1) return AVERROR(EINVAL); len /= 2; ptr = bin = av_malloc(len); while (*val) { int a = hexchar2int(*val++); int b = hexchar2int(*val++); if (a < 0 || b < 0) { av_free(bin); return AVERROR(EINVAL); } *ptr++ = (a << 4) | b; } *dst = bin; *lendst = len; return 0; } if (o->type != FF_OPT_TYPE_STRING) { int notfirst=0; for (;;) { int i; char buf[256]; int cmd=0; double d; if (*val == '+' || *val == '-') cmd= *(val++); for (i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++) buf[i]= val[i]; buf[i]=0; { const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0); if (o_named && o_named->type == FF_OPT_TYPE_CONST) d= o_named->default_val.dbl; else if (!strcmp(buf, "default")) d= o->default_val.dbl; else if (!strcmp(buf, "max" )) d= o->max; else if (!strcmp(buf, "min" )) d= o->min; else if (!strcmp(buf, "none" )) d= 0; else if (!strcmp(buf, "all" )) d= ~0; else { int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); if (res < 0) { av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val); return res; } } } if (o->type == FF_OPT_TYPE_FLAGS) { if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; else if (cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; } else { if (cmd=='+') d= notfirst*av_get_double(obj, name, NULL) + d; else if (cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d; } if ((ret = av_set_number2(obj, name, d, 1, 1, o_out)) < 0) return ret; val+= i; if (!*val) return 0; notfirst=1; } return AVERROR(EINVAL); } if (alloc) { av_free(*(void**)(((uint8_t*)obj) + o->offset)); val= av_strdup(val); } memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val)); return 0; }