const AVOption *av_set_string(void *obj, const char *name, const char *val){ const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ return set_all_opt(obj, o->unit, o->default_val); } if(!o || !val || o->offset<=0) return NULL; if(o->type != FF_OPT_TYPE_STRING){ for(;;){ int i; char buf[256]; int cmd=0; double d; char *error = NULL; 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; val+= i; d = ff_eval2(buf, const_values, const_names, NULL, NULL, NULL, NULL, NULL, &error); if(isnan(d)) { const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0); if(o_named && o_named->type == FF_OPT_TYPE_CONST) d= o_named->default_val; else if(!strcmp(buf, "default")) d= o->default_val; 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 { if (!error) av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error); return NULL; } } 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= -d; av_set_number(obj, name, d, 1, 1); if(!*val) return o; } return NULL; } memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); return o; }
//FIXME use eval.c maybe? AVOption *av_set_string(void *obj, const char *name, const char *val){ AVOption *o= find_opt(obj, name, NULL); if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ return set_all_opt(obj, o->unit, o->default_val); } if(!o || !val || o->offset<=0) return NULL; if(o->type != FF_OPT_TYPE_STRING){ for(;;){ int i; char buf[256], *tail; 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; val+= i; d= av_parse_num(buf, &tail); if(tail <= buf){ AVOption *o_named= find_opt(obj, buf, o->unit); if(o_named && o_named->type == FF_OPT_TYPE_CONST) d= o_named->default_val; else if(!strcmp(buf, "default")) d= o->default_val; else if(!strcmp(buf, "max" )) d= o->max; else if(!strcmp(buf, "min" )) d= o->min; else return NULL; } 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= -d; av_set_number(obj, name, d, 1, 1); if(!*val) return o; } return NULL; } memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); return o; }
static AVOption *set_all_opt(void *v, const char *unit, double d){ AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass AVOption *o= c->option; AVOption *ret=NULL; for(;o && o->name; o++){ if(o->type != FF_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)){ double tmp= d; if(o->type == FF_OPT_TYPE_FLAGS) tmp= av_get_int(v, o->name, NULL) | (int64_t)d; av_set_number(v, o->name, tmp, 1, 1); ret= o; } } return ret; }
AVOption *av_set_int(void *obj, const char *name, int64_t n){ return av_set_number(obj, name, 1, 1, n); }
AVOption *av_set_q(void *obj, const char *name, AVRational n){ return av_set_number(obj, name, n.num, n.den, 1); }
AVOption *av_set_double(void *obj, const char *name, double n){ return av_set_number(obj, name, n, 1, 1); }
const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc){ const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); if(o && o->offset==0 && o->type == FF_OPT_TYPE_CONST && o->unit){ return set_all_opt(obj, o->unit, o->default_val); } if(!o || !val || o->offset<=0) return NULL; 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 NULL; 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 NULL; } *ptr++ = (a << 4) | b; } *dst = bin; *lendst = len; return o; } if(o->type != FF_OPT_TYPE_STRING){ int notfirst=0; for(;;){ int i; char buf[256]; int cmd=0; double d; const char *error = NULL; 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; d = ff_eval2(buf, (double *)const_values, (const char **)const_names, NULL, NULL, NULL, NULL, NULL, &error); if(isnan(d)) { const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0); if(o_named && o_named->type == FF_OPT_TYPE_CONST) d= o_named->default_val; else if(!strcmp(buf, "default")) d= o->default_val; 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 { if (error) av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error); return NULL; } } 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 (!av_set_number(obj, name, d, 1, 1)) return NULL; val+= i; if(!*val) return o; notfirst=1; } return NULL; } if(alloc){ av_free(*(void**)(((uint8_t*)obj) + o->offset)); val= av_strdup(val); } memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val)); return o; }