changeset 1058:3c3da6edc9a1 libavcodec

* still unfinished code for Options
author kabi
date Mon, 10 Feb 2003 09:38:38 +0000
parents bb5de8a59da8
children 890b9fb44e84
files avcodec.h opts.c
diffstat 2 files changed, 117 insertions(+), 224 deletions(-) [+]
line wrap: on
line diff
--- a/avcodec.h	Mon Feb 10 09:35:32 2003 +0000
+++ b/avcodec.h	Mon Feb 10 09:38:38 2003 +0000
@@ -950,6 +950,42 @@
     enum PixelFormat (*get_format)(struct AVCodecContext *s, enum PixelFormat * fmt);
 } AVCodecContext;
 
+//void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config);
+
+typedef struct AVOption {
+    /** options' name */
+    const char *name; /* if name is NULL, it indicates a link to next */
+    /** short English text help */
+    const char *help;
+    /** offset to context structure where the parsed value should be stored */
+    int offset;
+    /** options' type */
+    int type;
+#define FF_OPT_TYPE_BOOL 1     // boolean - true,1,on  (or simply presence)
+#define FF_OPT_TYPE_DOUBLE 2   // double
+#define FF_OPT_TYPE_INT 3      // integer
+#define FF_OPT_TYPE_STRING 4   // string (finished with \0)
+#define FF_OPT_TYPE_MASK 0x1f	// mask for types - upper bits are various flags
+//#define FF_OPT_TYPE_EXPERT 0x20 // flag for expert option
+#define FF_OPT_TYPE_FLAG (FF_OPT_TYPE_BOOL | 0x40)
+#define FF_OPT_TYPE_RCOVERRIDE (FF_OPT_TYPE_STRING | 0x80)
+    /** min value  (min == max   ->  no limits) */
+    double min;
+    /** maximum value for double/int */
+    double max;
+    /** default boo [0,1]l/double/int value */
+    double defval;
+    /**
+     * default string value (with optional semicolon delimited extra option-list
+     * i.e.   option1;option2;option3
+     * defval might select other then first argument as default
+     */
+    const char *defstr;
+    const struct AVOption *sub; /* used when name is NULL */
+    /* when it's NULL return to previous level (or finish reading) */
+#define FF_OPT_MAX_DEPTH 10
+} AVOption;
+
 typedef struct AVCodec {
     const char *name;
     int type;
@@ -961,10 +997,11 @@
     int (*decode)(AVCodecContext *, void *outdata, int *outdata_size,
                   UINT8 *buf, int buf_size);
     int capabilities;
+    const AVOption *options;
     struct AVCodec *next;
 } AVCodec;
 
-/** 
+/**
  * four components are given, that's all.
  * the last component is alpha
  */
@@ -1135,40 +1172,7 @@
 
 void avcodec_flush_buffers(AVCodecContext *avctx);
 
-typedef struct {
-    /** options' name with default value*/
-    const char* name;
-    /** English text help */
-    const char* help;
-    /** type of variable */
-    int type;
-#define FF_CONF_TYPE_BOOL 1     // boolean - true,1,on  (or simply presence)
-#define FF_CONF_TYPE_DOUBLE 2   // double
-#define FF_CONF_TYPE_INT 3      // integer
-#define FF_CONF_TYPE_STRING 4   // string (finished with \0)
-#define FF_CONF_TYPE_MASK 0x1f	// mask for types - upper bits are various flags
-#define FF_CONF_TYPE_EXPERT 0x20 // flag for expert option
-#define FF_CONF_TYPE_FLAG (FF_CONF_TYPE_BOOL | 0x40)
-#define FF_CONF_TYPE_RCOVERIDE (FF_CONF_TYPE_STRING | 0x80)
-    /** where the parsed value should be stored */
-    void* val;
-    /** min value  (min == max   ->  no limits) */
-    double min;
-    /** maximum value for double/int */
-    double max;
-    /** default boo [0,1]l/double/int value */
-    double defval;
-    /**
-     * default string value (with optional semicolon delimited extra option-list
-     * i.e.   option1;option2;option3
-     * defval might select other then first argument as default
-     */
-    const char* defstr;
-    /** char* list of supported codecs (i.e. ",msmpeg4,h263," NULL - everything */
-    const char* supported;
-} avc_config_t;
 
-void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config);
 
 /**
  * Interface for 0.5.0 version
@@ -1254,7 +1258,7 @@
 char *av_strdup(const char *s);
 void __av_freep(void **ptr);
 #define av_freep(p) __av_freep((void **)(p))
-void *av_fast_realloc(void *ptr, int *size, int min_size);
+void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size);
 /* for static data only */
 /* call av_free_static to release all staticaly allocated tables */
 void av_free_static(void);
--- a/opts.c	Mon Feb 10 09:35:32 2003 +0000
+++ b/opts.c	Mon Feb 10 09:38:38 2003 +0000
@@ -9,17 +9,15 @@
  */
 
 #include "avcodec.h"
-#ifdef OPTS_MAIN
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
+
+extern const AVOption common_options[2];
 
-/*
- * todo - use for decoder options also
- */
+const AVOption common_options[2] = {
+    AVOPTION_CODEC_INT("common", "test", bit_rate, 0, 10, 0),
+    AVOPTION_END()
+};
 
-static int parse_bool(avc_config_t* c, char* s)
+static int parse_bool(const AVOption *c, char *s, int *var)
 {
     int b = 1; /* by default -on- when present */
     if (s) {
@@ -33,12 +31,11 @@
 	    return -1;
     }
 
-    if (c && c->val)
-	*(int*)(c->val) = b;
+    *var = b;
     return 0;
 }
 
-static int parse_double(avc_config_t* c, char* s)
+static int parse_double(const AVOption *c, char *s, double *var)
 {
     double d;
     if (!s)
@@ -51,12 +48,11 @@
 	    return -1;
 	}
     }
-    if (c && c->val)
-	*(double*)(c->val) = d;
+    *var = d;
     return 0;
 }
 
-static int parse_int(avc_config_t* c, char* s)
+static int parse_int(const AVOption* c, char* s, int* var)
 {
     int i;
     if (!s)
@@ -69,25 +65,23 @@
 	    return -1;
 	}
     }
-    if (c && c->val)
-	*(int*)(c->val) = i;
+    *var = i;
     return 0;
 }
 
-static int parse_string(AVCodecContext* avctx, avc_config_t* c, char* s)
+static int parse_string(const AVOption *c, char *s, AVCodecContext *avctx, char **var)
 {
     if (!s)
 	return -1;
 
-    if (c->type == FF_CONF_TYPE_RCOVERIDE) {
+    if (c->type == FF_OPT_TYPE_RCOVERRIDE) {
 	int sf, ef, qs;
 	float qf;
 	if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) {
-	    RcOverride* o;
-	    *((RcOverride**)c->val) =
-		realloc(*((RcOverride**)c->val),
-			sizeof(RcOverride) * (avctx->rc_override_count + 1));
-            o = *((RcOverride**)c->val) + avctx->rc_override_count++;
+	    RcOverride *o;
+	    avctx->rc_override = av_realloc(avctx->rc_override,
+					    sizeof(RcOverride) * (avctx->rc_override_count + 1));
+	    o = avctx->rc_override + avctx->rc_override_count++;
 	    o->start_frame = sf;
 	    o->end_frame = ef;
 	    o->qscale = qs;
@@ -98,181 +92,76 @@
 	    printf("incorrect/unparsable Rc: \"%s\"\n", s);
 	}
     } else
-	(char*)(c->val) = strdup(s);
-    return 0;
-}
-
-static int parse(AVCodecContext* avctx, avc_config_t* config, char* str)
-{
-    while (str && *str) {
-	avc_config_t* c = config;
-	char* e = strchr(str, ':');
-        char* p;
-	if (e)
-            *e++ = 0;
-
-	p = strchr(str, '=');
-	if (p)
-	    *p++ = 0;
-
-	while (c->name) {
-	    if (!strcmp(c->name, str)) {
-		switch (c->type & FF_CONF_TYPE_MASK) {
-		case FF_CONF_TYPE_BOOL:
-                    parse_bool(c, p);
-                    break;
-		case FF_CONF_TYPE_DOUBLE:
-                    parse_double(c, p);
-                    break;
-		case FF_CONF_TYPE_INT:
-                    parse_int(c, p);
-                    break;
-		case FF_CONF_TYPE_STRING:
-		    parse_string(avctx, c, p);
-		    break;
-		default:
-                    abort();
-                    break;
-		}
-	    }
-            c++;
-	}
-	str = e;
-    }
+	*var = av_strdup(s);
     return 0;
 }
 
 /**
  *
+ * \param codec  codec for option parsing
+ * \param opts   string with options for parsing
  * \param avctx  where to store parsed results
- * \param str    string with options for parsing
- *               or selectional string (pick only options appliable
- *               for codec - use  ,msmpeg4, (with commas to avoid mismatch)
- * \param config allocated avc_config_t for external parsing
- *               i.e. external program might learn about all available
- *               options for given codec
- **/
-void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config)
+ */
+int avcodec_parse(const AVCodec *codec, const char *opts, AVCodecContext *avctx)
 {
-    AVCodecContext avctx_tmp;
-    AVCodecContext* ctx = (avctx) ? avctx : &avctx_tmp;
-    static const char* class_h263 = ",msmpeg4,";
-    //"huffyuv,wmv1,msmpeg4v2,msmpeg4,mpeg4,mpeg1,mpeg1video,mjpeg,rv10,h263,h263p"
+    int r = 0;
+    char* dopts = av_strdup(opts);
+    if (dopts) {
+        char *str = dopts;
+
+	while (str && *str && r == 0) {
+	    const AVOption *stack[FF_OPT_MAX_DEPTH];
+	    int depth = 0;
+	    const AVOption *c = codec->options;
+	    char* e = strchr(str, ':');
+	    char* p;
+	    if (e)
+		*e++ = 0;
+
+	    p = strchr(str, '=');
+	    if (p)
+		*p++ = 0;
 
-    avc_config_t cnf[] =
-    {
-	// FIXME: sorted by importance!!!
-        // expert option should follow more common ones
-	{
-	    "bitrate", "desired video bitrate",
-	    FF_CONF_TYPE_INT, &ctx->bit_rate, 4, 240000000, 800000, NULL, class_h263
-	}, {
-	    "vhq", "very high quality",
-	    FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_HQ, 0, NULL, class_h263
-	}, {
-	    "ratetol", "number of bits the bitstream is allowed to diverge from the reference"
-	    "the reference can be CBR (for CBR pass1) or VBR (for pass2)",
-	    FF_CONF_TYPE_INT, &ctx->bit_rate_tolerance, 4, 240000000, 8000, NULL, class_h263
-	}, {
-	    "qmin", "minimum quantizer", FF_CONF_TYPE_INT, &ctx->qmin, 1, 31, 2, NULL, class_h263
-	}, {
-	    "qmax", "maximum qunatizer", FF_CONF_TYPE_INT, &ctx->qmax, 1, 31, 31, NULL, class_h263
-	}, {
-	    "rc_eq", "rate control equation",
-	    FF_CONF_TYPE_STRING, &ctx->rc_eq, 0, 0, 0, "tex^qComp" /* FILLME options */, class_h263
-	}, {
-	    "rc_minrate", "rate control minimum bitrate",
-	    FF_CONF_TYPE_INT, &ctx->rc_min_rate, 4, 24000000, 0, NULL, class_h263
-	}, {
-	    "rc_maxrate", "rate control maximum bitrate",
-	    FF_CONF_TYPE_INT, &ctx->rc_max_rate, 4, 24000000, 0, NULL, class_h263
-	}, {
-	    "psnr", "calculate PSNR of compressed frames",
-	    FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_PSNR, 0, NULL, class_h263
-	}, {
-	    "rc_override", "ratecontrol override (=startframe,endframe,qscale,quality_factor)",
-	    FF_CONF_TYPE_RCOVERIDE, &ctx->rc_override, 0, 0, 0, "0,0,0,0", class_h263
-	},
+            // going through option structures
+	    for (;;) {
+		if (!c->name) {
+		    if (c->sub) {
+			stack[depth++] = c;
+			c = c->sub;
+			assert(depth > FF_OPT_MAX_DEPTH);
+		    } else {
+			if (depth == 0)
+			    break; // finished
+			c = stack[--depth];
+                        c++;
+		    }
+		} else {
+		    if (!strcmp(c->name, str)) {
+			void* ptr = (char*)avctx + c->offset;
 
-        { NULL, NULL, 0, NULL, 0, 0, 0, NULL, NULL }
-    };
-
-    if (config) {
-	*config = malloc(sizeof(cnf));
-	if (*config) {
-	    avc_config_t* src = cnf;
-	    avc_config_t* dst = *config;
-	    while (src->name) {
-		if (!str || !src->supported || strstr(src->supported, str))
-		    memcpy(dst++, src, sizeof(avc_config_t));
-                src++;
+			switch (c->type & FF_OPT_TYPE_MASK) {
+			case FF_OPT_TYPE_BOOL:
+			    r = parse_bool(c, p, (int*)ptr);
+			    break;
+			case FF_OPT_TYPE_DOUBLE:
+			    r = parse_double(c, p, (double*)ptr);
+			    break;
+			case FF_OPT_TYPE_INT:
+			    r = parse_int(c, p, (int*)ptr);
+			    break;
+			case FF_OPT_TYPE_STRING:
+			    r = parse_string(c, p, avctx, (char**)ptr);
+			    break;
+			default:
+			    assert(0 == 1);
+			}
+		    }
+		    c++;
+		}
 	    }
-	    memset(dst, 0, sizeof(avc_config_t));
+	    str = e;
 	}
-    } else if (str) {
-	char* s = strdup(str);
-	if (s) {
-	    parse(avctx, cnf, s);
-            free(s);
-	}
+	av_free(dopts);
     }
+    return r;
 }
-
-#ifdef OPTS_MAIN
-/*
- * API test -
- * arg1: options
- * arg2: codec type
- *
- * compile standalone: make CFLAGS="-DOPTS_MAIN" opts
- */
-int main(int argc, char* argv[])
-{
-    AVCodecContext avctx;
-    avc_config_t* config;
-    char* def = malloc(5000);
-    const char* col = "";
-    int i = 0;
-
-    memset(&avctx, 0, sizeof(avctx));
-    *def = 0;
-    avcodec_getopt(&avctx, argv[1], NULL);
-
-    avcodec_getopt(NULL, (argc > 2) ? argv[2] : NULL, &config);
-    if (config)
-	while (config->name) {
-            int t = config->type & FF_CONF_TYPE_MASK;
-	    printf("Config   %s  %s\n", config->name,
-		   t == FF_CONF_TYPE_BOOL ? "bool" :
-                   t == FF_CONF_TYPE_DOUBLE ? "double" :
-                   t == FF_CONF_TYPE_INT ? "integer" :
-		   t == FF_CONF_TYPE_STRING ? "string" :
-		   "unknown??");
-	    switch (t) {
-	    case FF_CONF_TYPE_BOOL:
-		i += sprintf(def + i, "%s%s=%s",
-			     col, config->name,
-			     config->defval != 0. ? "on" : "off");
-                break;
-	    case FF_CONF_TYPE_DOUBLE:
-		i += sprintf(def + i, "%s%s=%f",
-			     col, config->name, config->defval);
-                break;
-	    case FF_CONF_TYPE_INT:
-		i += sprintf(def + i, "%s%s=%d",
-			     col, config->name, (int) config->defval);
-                break;
-	    case FF_CONF_TYPE_STRING:
-		i += sprintf(def + i, "%s%s=%s",
-			     col, config->name, config->defstr);
-		break;
-	    }
-	    col = ":";
-	    config++;
-	}
-
-    printf("Default Options: %s\n", def);
-
-    return 0;
-}
-#endif