diff options
author | Zdenek Kabelac <kabi@informatics.muni.cz> | 2003-02-10 09:38:38 +0000 |
---|---|---|
committer | Zdenek Kabelac <kabi@informatics.muni.cz> | 2003-02-10 09:38:38 +0000 |
commit | 97d96aaa76e11661967b7bd67cc7ef49d0212a8b (patch) | |
tree | f362a394259a4edf6004eff4582af6967d0b8b16 /libavcodec/opts.c | |
parent | 5c91a6755b6412c918e20ff4735ca30f38a12569 (diff) | |
download | ffmpeg-97d96aaa76e11661967b7bd67cc7ef49d0212a8b.tar.gz |
* still unfinished code for Options
Originally committed as revision 1568 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/opts.c')
-rw-r--r-- | libavcodec/opts.c | 271 |
1 files changed, 80 insertions, 191 deletions
diff --git a/libavcodec/opts.c b/libavcodec/opts.c index 01fddd7c8f..cf5cf0eef7 100644 --- a/libavcodec/opts.c +++ b/libavcodec/opts.c @@ -9,17 +9,15 @@ */ #include "avcodec.h" -#ifdef OPTS_MAIN -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#endif -/* - * todo - use for decoder options also - */ +extern const AVOption common_options[2]; -static int parse_bool(avc_config_t* c, char* s) +const AVOption common_options[2] = { + AVOPTION_CODEC_INT("common", "test", bit_rate, 0, 10, 0), + AVOPTION_END() +}; + +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 @@ static int parse_bool(avc_config_t* c, char* s) 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 @@ static int parse_double(avc_config_t* c, char* s) 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 @@ static int parse_int(avc_config_t* c, char* s) 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 @@ static int parse_string(AVCodecContext* avctx, avc_config_t* c, char* s) 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) -{ - 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" - - 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 - }, - - { 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++; - } - memset(dst, 0, sizeof(avc_config_t)); - } - } else if (str) { - char* s = strdup(str); - if (s) { - parse(avctx, cnf, s); - free(s); - } - } -} - -#ifdef OPTS_MAIN -/* - * API test - - * arg1: options - * arg2: codec type - * - * compile standalone: make CFLAGS="-DOPTS_MAIN" opts */ -int main(int argc, char* argv[]) +int avcodec_parse(const AVCodec *codec, const char *opts, AVCodecContext *avctx) { - 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; + 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; + + // 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; + + 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++; + } } - col = ":"; - config++; + str = e; } - - printf("Default Options: %s\n", def); - - return 0; + av_free(dopts); + } + return r; } -#endif |