Mercurial > libavcodec.hg
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