|
|
@ -116,10 +116,98 @@ static int hexchar2int(char c) { |
|
|
|
return -1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
av_freep(dst); |
|
|
|
|
|
|
|
*dst = av_strdup(val); |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int set_string_number(void *obj, const AVOption *o, const char *val, void *dst) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int ret = 0, 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, o->name, NULL) | (int64_t)d; |
|
|
|
|
|
|
|
else if (cmd == '-') d = av_get_int(obj, o->name, NULL) &~(int64_t)d; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (cmd == '+') d = notfirst*av_get_double(obj, o->name, NULL) + d; |
|
|
|
|
|
|
|
else if (cmd == '-') d = notfirst*av_get_double(obj, o->name, NULL) - d; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((ret = av_set_number2(obj, o->name, d, 1, 1, NULL)) < 0) |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
val += i; |
|
|
|
|
|
|
|
if (!*val) |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
notfirst = 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) |
|
|
|
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); |
|
|
|
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); |
|
|
|
|
|
|
|
void *dst; |
|
|
|
if (o_out) |
|
|
|
if (o_out) |
|
|
|
*o_out = o; |
|
|
|
*o_out = o; |
|
|
|
if (!o) |
|
|
|
if (!o) |
|
|
@ -127,85 +215,20 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons |
|
|
|
if (!val) |
|
|
|
if (!val) |
|
|
|
return AVERROR(EINVAL); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
|
|
|
|
|
|
|
|
if (o->type == FF_OPT_TYPE_BINARY) { |
|
|
|
dst = ((uint8_t*)obj) + o->offset; |
|
|
|
uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset); |
|
|
|
switch (o->type) { |
|
|
|
int *lendst = (int *)(dst + 1); |
|
|
|
case FF_OPT_TYPE_STRING: return set_string(obj, o, val, dst); |
|
|
|
uint8_t *bin, *ptr; |
|
|
|
case FF_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst); |
|
|
|
int len = strlen(val); |
|
|
|
case FF_OPT_TYPE_FLAGS: |
|
|
|
av_freep(dst); |
|
|
|
case FF_OPT_TYPE_INT: |
|
|
|
*lendst = 0; |
|
|
|
case FF_OPT_TYPE_INT64: |
|
|
|
if (len & 1) return AVERROR(EINVAL); |
|
|
|
case FF_OPT_TYPE_FLOAT: |
|
|
|
len /= 2; |
|
|
|
case FF_OPT_TYPE_DOUBLE: |
|
|
|
ptr = bin = av_malloc(len); |
|
|
|
case FF_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst); |
|
|
|
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; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (alloc) { |
|
|
|
|
|
|
|
av_free(*(void**)(((uint8_t*)obj) + o->offset)); |
|
|
|
|
|
|
|
val= av_strdup(val); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val)); |
|
|
|
av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); |
|
|
|
return 0; |
|
|
|
return AVERROR(EINVAL); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const AVOption *av_set_double(void *obj, const char *name, double n) |
|
|
|
const AVOption *av_set_double(void *obj, const char *name, double n) |
|
|
|