Commit c8d787d2 authored by Anton Khirnov's avatar Anton Khirnov

AVOptions: split av_set_string3 into opt type-specific functions

Also stop attempting to honor the alloc parameter, as things break
horribly in that case.
It will be removed in upcoming successor to av_set_string3.
parent 1703013c
...@@ -116,26 +116,19 @@ static int hexchar2int(char c) { ...@@ -116,26 +116,19 @@ static int hexchar2int(char c) {
return -1; return -1;
} }
int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) static int set_string_binary(void *obj, const AVOption *o, const char *val, uint8_t **dst)
{ {
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)
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); int *lendst = (int *)(dst + 1);
uint8_t *bin, *ptr; uint8_t *bin, *ptr;
int len = strlen(val); int len = strlen(val);
av_freep(dst); av_freep(dst);
*lendst = 0; *lendst = 0;
if (len & 1) return AVERROR(EINVAL);
if (len & 1)
return AVERROR(EINVAL);
len /= 2; len /= 2;
ptr = bin = av_malloc(len); ptr = bin = av_malloc(len);
while (*val) { while (*val) {
int a = hexchar2int(*val++); int a = hexchar2int(*val++);
...@@ -148,32 +141,42 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons ...@@ -148,32 +141,42 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons
} }
*dst = bin; *dst = bin;
*lendst = len; *lendst = len;
return 0; return 0;
} }
if (o->type != FF_OPT_TYPE_STRING) {
int notfirst=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 (;;) { for (;;) {
int i; int i;
char buf[256]; char buf[256];
int cmd=0; int cmd = 0;
double d; double d;
if (*val == '+' || *val == '-') if (*val == '+' || *val == '-')
cmd= *(val++); cmd = *(val++);
for (i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++) for (i = 0; i < sizeof(buf) - 1 && val[i] && val[i] != '+' && val[i] != '-'; i++)
buf[i]= val[i]; buf[i] = val[i];
buf[i]=0; buf[i] = 0;
{ {
const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0); const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
if (o_named && o_named->type == FF_OPT_TYPE_CONST) if (o_named && o_named->type == FF_OPT_TYPE_CONST)
d= o_named->default_val.dbl; d = o_named->default_val.dbl;
else if (!strcmp(buf, "default")) d= o->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, "max" )) d = o->max;
else if (!strcmp(buf, "min" )) d= o->min; else if (!strcmp(buf, "min" )) d = o->min;
else if (!strcmp(buf, "none" )) d= 0; else if (!strcmp(buf, "none" )) d = 0;
else if (!strcmp(buf, "all" )) d= ~0; else if (!strcmp(buf, "all" )) d = ~0;
else { else {
int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj); int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);
if (res < 0) { if (res < 0) {
...@@ -183,29 +186,49 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons ...@@ -183,29 +186,49 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons
} }
} }
if (o->type == FF_OPT_TYPE_FLAGS) { if (o->type == FF_OPT_TYPE_FLAGS) {
if (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d; if (cmd == '+') d = av_get_int(obj, o->name, NULL) | (int64_t)d;
else if (cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d; else if (cmd == '-') d = av_get_int(obj, o->name, NULL) &~(int64_t)d;
} else { } else {
if (cmd=='+') d= notfirst*av_get_double(obj, name, NULL) + d; if (cmd == '+') d = notfirst*av_get_double(obj, o->name, NULL) + d;
else if (cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d; else if (cmd == '-') d = notfirst*av_get_double(obj, o->name, NULL) - d;
} }
if ((ret = av_set_number2(obj, name, d, 1, 1, o_out)) < 0) if ((ret = av_set_number2(obj, o->name, d, 1, 1, NULL)) < 0)
return ret; return ret;
val+= i; val += i;
if (!*val) if (!*val)
return 0; return 0;
notfirst=1; notfirst = 1;
}
} }
if (alloc) { return 0;
av_free(*(void**)(((uint8_t*)obj) + o->offset)); }
val= av_strdup(val);
int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)
{
const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
void *dst;
if (o_out)
*o_out = o;
if (!o)
return AVERROR_OPTION_NOT_FOUND;
if (!val)
return AVERROR(EINVAL);
dst = ((uint8_t*)obj) + o->offset;
switch (o->type) {
case FF_OPT_TYPE_STRING: return set_string(obj, o, val, dst);
case FF_OPT_TYPE_BINARY: return set_string_binary(obj, o, val, dst);
case FF_OPT_TYPE_FLAGS:
case FF_OPT_TYPE_INT:
case FF_OPT_TYPE_INT64:
case FF_OPT_TYPE_FLOAT:
case FF_OPT_TYPE_DOUBLE:
case FF_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst);
} }
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)
......
...@@ -129,9 +129,7 @@ const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int m ...@@ -129,9 +129,7 @@ const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int m
* similarly, '-' unsets a flag. * similarly, '-' unsets a flag.
* @param[out] o_out if non-NULL put here a pointer to the AVOption * @param[out] o_out if non-NULL put here a pointer to the AVOption
* found * found
* @param alloc when 1 then the old value will be av_freed() and the * @param alloc this parameter is currently ignored
* new av_strduped()
* when 0 then no av_free() nor av_strdup() will be used
* @return 0 if the value has been set, or an AVERROR code in case of * @return 0 if the value has been set, or an AVERROR code in case of
* error: * error:
* AVERROR_OPTION_NOT_FOUND if no matching option exists * AVERROR_OPTION_NOT_FOUND if no matching option exists
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment