summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorZdenek Kabelac <kabi@informatics.muni.cz>2003-01-20 19:04:39 +0000
committerZdenek Kabelac <kabi@informatics.muni.cz>2003-01-20 19:04:39 +0000
commit2a743f633e1c2747a98fa0109f5e0337e9f10dd6 (patch)
treea324af300e8c4bb696dadc168d2739d0e1016165 /libavcodec
parent56f7fda16b4fb12416a158fec8fdcb9cbf4b530e (diff)
* code for parsing options
now options have to be added... - see main for a simple usage example. Originally committed as revision 1480 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/avcodec.h2
-rw-r--r--libavcodec/opts.c219
2 files changed, 211 insertions, 10 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 72d6d32efb..fee760c56c 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1152,7 +1152,7 @@ typedef struct {
const char* supported;
} avc_config_t;
-void avcodec_getopt(AVCodecContext* avctx, char* str, avc_config_t** config);
+void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config);
/**
* Interface for 0.5.0 version
diff --git a/libavcodec/opts.c b/libavcodec/opts.c
index bcefc40a3b..01fddd7c8f 100644
--- a/libavcodec/opts.c
+++ b/libavcodec/opts.c
@@ -9,21 +9,150 @@
*/
#include "avcodec.h"
+#ifdef OPTS_MAIN
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
/*
- * possible extension - use for decoder options
- * - for given codec names filter only correct
- * options given (could be passed with 'str')
+ * todo - use for decoder options also
*/
+static int parse_bool(avc_config_t* c, char* s)
+{
+ int b = 1; /* by default -on- when present */
+ if (s) {
+ if (!strcasecmp(s, "off") || !strcasecmp(s, "false")
+ || !strcmp(s, "0"))
+ b = 0;
+ else if (!strcasecmp(s, "on") || !strcasecmp(s, "true")
+ || !strcmp(s, "1"))
+ b = 1;
+ else
+ return -1;
+ }
+
+ if (c && c->val)
+ *(int*)(c->val) = b;
+ return 0;
+}
+
+static int parse_double(avc_config_t* c, char* s)
+{
+ double d;
+ if (!s)
+ return -1;
+ d = atof(s);
+ if (c->min != c->max) {
+ if (d < c->min || d > c->max) {
+ fprintf(stderr, "Option: %s double value: %f out of range <%f, %f>\n",
+ c->name, d, c->min, c->max);
+ return -1;
+ }
+ }
+ if (c && c->val)
+ *(double*)(c->val) = d;
+ return 0;
+}
+
+static int parse_int(avc_config_t* c, char* s)
+{
+ int i;
+ if (!s)
+ return -1;
+ i = atoi(s);
+ if (c->min != c->max) {
+ if (i < (int)c->min || i > (int)c->max) {
+ fprintf(stderr, "Option: %s integer value: %d out of range <%d, %d>\n",
+ c->name, i, (int)c->min, (int)c->max);
+ return -1;
+ }
+ }
+ if (c && c->val)
+ *(int*)(c->val) = i;
+ return 0;
+}
+
+static int parse_string(AVCodecContext* avctx, avc_config_t* c, char* s)
+{
+ if (!s)
+ return -1;
+
+ if (c->type == FF_CONF_TYPE_RCOVERIDE) {
+ 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++;
+ o->start_frame = sf;
+ o->end_frame = ef;
+ o->qscale = qs;
+ o->quality_factor = qf;
+
+ //printf("parsed Rc: %d,%d,%d,%f (%d)\n", sf,ef,qs,qf, avctx->rc_override_count);
+ } else {
+ 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;
+ }
+ return 0;
+}
+
/**
+ *
* \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, char* str, avc_config_t** config)
+void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config)
{
AVCodecContext avctx_tmp;
AVCodecContext* ctx = (avctx) ? avctx : &avctx_tmp;
@@ -62,16 +191,88 @@ void avcodec_getopt(AVCodecContext* avctx, char* str, avc_config_t** config)
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, NULL, class_h263
+ 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)
- {
+ if (config) {
*config = malloc(sizeof(cnf));
- if (*config)
- memcpy(*config, cnf, 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[])
+{
+ 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