]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/opt.c
define FLAC metadata types in flac.h
[ffmpeg] / libavcodec / opt.c
index acf94ba824043e971e57bee15fee019d56050cee..78fbfaeb5793fbaeb528bfc25691b3398e383e90 100644 (file)
@@ -47,15 +47,17 @@ const AVOption *av_next_option(void *obj, const AVOption *last){
     else                     return (*(AVClass**)obj)->option;
 }
 
-static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){
+static int av_set_number2(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out){
     const AVOption *o= av_find_opt(obj, name, NULL, 0, 0);
     void *dst;
+    if(o_out)
+        *o_out= o;
     if(!o || o->offset<=0)
-        return NULL;
+        return AVERROR(ENOENT);
 
     if(o->max*den < num*intnum || o->min*den > num*intnum) {
-        av_log(NULL, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range.\n", num, name);
-        return NULL;
+        av_log(NULL, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n", num, name);
+        return AVERROR(ERANGE);
     }
 
     dst= ((uint8_t*)obj) + o->offset;
@@ -71,27 +73,17 @@ static const AVOption *av_set_number(void *obj, const char *name, double num, in
         else                *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24);
         break;
     default:
-        return NULL;
+        return AVERROR(EINVAL);
     }
-    return o;
+    return 0;
 }
 
-static const AVOption *set_all_opt(void *v, const char *unit, double d){
-    AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass
-    const AVOption *o= c->option;
-    const 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;
+static const AVOption *av_set_number(void *obj, const char *name, double num, int den, int64_t intnum){
+    const AVOption *o = NULL;
+    if (av_set_number2(obj, name, num, den, intnum, &o) < 0)
+        return NULL;
+    else
+        return o;
 }
 
 static const double const_values[]={
@@ -115,13 +107,16 @@ static int hexchar2int(char c) {
     return -1;
 }
 
-const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc){
+int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out){
+    int ret;
     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_out)
+        *o_out = o;
+    if(!o)
+        return AVERROR(ENOENT);
+    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);
@@ -129,7 +124,7 @@ const AVOption *av_set_string2(void *obj, const char *name, const char *val, int
         int len = strlen(val);
         av_freep(dst);
         *lendst = 0;
-        if (len & 1) return NULL;
+        if (len & 1) return AVERROR(EINVAL);
         len /= 2;
         ptr = bin = av_malloc(len);
         while (*val) {
@@ -137,13 +132,13 @@ const AVOption *av_set_string2(void *obj, const char *name, const char *val, int
             int b = hexchar2int(*val++);
             if (a < 0 || b < 0) {
                 av_free(bin);
-                return NULL;
+                return AVERROR(EINVAL);
             }
             *ptr++ = (a << 4) | b;
         }
         *dst = bin;
         *lendst = len;
-        return o;
+        return 0;
     }
     if(o->type != FF_OPT_TYPE_STRING){
         int notfirst=0;
@@ -174,7 +169,7 @@ const AVOption *av_set_string2(void *obj, const char *name, const char *val, int
                 else {
                     if (error)
                         av_log(NULL, AV_LOG_ERROR, "Unable to parse option value \"%s\": %s\n", val, error);
-                    return NULL;
+                    return AVERROR(EINVAL);
                 }
             }
             if(o->type == FF_OPT_TYPE_FLAGS){
@@ -185,14 +180,14 @@ const AVOption *av_set_string2(void *obj, const char *name, const char *val, int
                 else if(cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d;
             }
 
-            if (!av_set_number(obj, name, d, 1, 1))
-                return NULL;
+            if ((ret = av_set_number2(obj, name, d, 1, 1, o_out)) < 0)
+                return ret;
             val+= i;
             if(!*val)
-                return o;
+                return 0;
             notfirst=1;
         }
-        return NULL;
+        return AVERROR(EINVAL);
     }
 
     if(alloc){
@@ -201,12 +196,24 @@ const AVOption *av_set_string2(void *obj, const char *name, const char *val, int
     }
 
     memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val));
+    return 0;
+}
+
+#if LIBAVCODEC_VERSION_MAJOR < 53
+const AVOption *av_set_string2(void *obj, const char *name, const char *val, int alloc){
+    const AVOption *o;
+    if (av_set_string3(obj, name, val, alloc, &o) < 0)
+        return NULL;
     return o;
 }
 
 const AVOption *av_set_string(void *obj, const char *name, const char *val){
-    return av_set_string2(obj, name, val, 0);
+    const AVOption *o;
+    if (av_set_string3(obj, name, val, 0, &o) < 0)
+        return NULL;
+    return o;
 }
+#endif
 
 const AVOption *av_set_double(void *obj, const char *name, double n){
     return av_set_number(obj, name, n, 1, 1);
@@ -415,6 +422,11 @@ void av_opt_set_defaults2(void *s, int mask, int flags)
                 av_set_int(s, opt->name, val);
             }
             break;
+            case FF_OPT_TYPE_INT64:
+                if((double)(opt->default_val+0.6) == opt->default_val)
+                    av_log(s, AV_LOG_DEBUG, "loss of precission in default of %s\n", opt->name);
+                av_set_int(s, opt->name, opt->default_val);
+            break;
             case FF_OPT_TYPE_FLOAT: {
                 double val;
                 val = opt->default_val;