Statistics
| Branch: | Revision:

ffmpeg / libavcodec / opts.c @ 983e3246

History | View | Annotate | Download (3.56 KB)

1
/*
2
 * LGPL
3
 */
4

    
5
/**
6
 * @file opts.c
7
 * options parser.
8
 * typical parsed command line:
9
 * msmpeg4:bitrate=720000:qmax=16
10
 *
11
 */
12

    
13
#include "avcodec.h"
14

    
15
extern const AVOption common_options[2];
16

    
17
const AVOption common_options[2] = {
18
    AVOPTION_CODEC_INT("common", "test", bit_rate, 0, 10, 0),
19
    AVOPTION_END()
20
};
21

    
22
static int parse_bool(const AVOption *c, char *s, int *var)
23
{
24
    int b = 1; /* by default -on- when present */
25
    if (s) {
26
        if (!strcasecmp(s, "off") || !strcasecmp(s, "false")
27
            || !strcmp(s, "0"))
28
            b = 0;
29
        else if (!strcasecmp(s, "on") || !strcasecmp(s, "true")
30
                 || !strcmp(s, "1"))
31
            b = 1;
32
        else
33
            return -1;
34
    }
35

    
36
    *var = b;
37
    return 0;
38
}
39

    
40
static int parse_double(const AVOption *c, char *s, double *var)
41
{
42
    double d;
43
    if (!s)
44
        return -1;
45
    d = atof(s);
46
    if (c->min != c->max) {
47
        if (d < c->min || d > c->max) {
48
            fprintf(stderr, "Option: %s double value: %f out of range <%f, %f>\n",
49
                    c->name, d, c->min, c->max);
50
            return -1;
51
        }
52
    }
53
    *var = d;
54
    return 0;
55
}
56

    
57
static int parse_int(const AVOption* c, char* s, int* var)
58
{
59
    int i;
60
    if (!s)
61
        return -1;
62
    i = atoi(s);
63
    if (c->min != c->max) {
64
        if (i < (int)c->min || i > (int)c->max) {
65
            fprintf(stderr, "Option: %s integer value: %d out of range <%d, %d>\n",
66
                    c->name, i, (int)c->min, (int)c->max);
67
            return -1;
68
        }
69
    }
70
    *var = i;
71
    return 0;
72
}
73

    
74
static int parse_string(const AVOption *c, char *s, AVCodecContext *avctx, char **var)
75
{
76
    if (!s)
77
        return -1;
78

    
79
    if (c->type == FF_OPT_TYPE_RCOVERRIDE) {
80
        int sf, ef, qs;
81
        float qf;
82
        if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) {
83
            RcOverride *o;
84
            avctx->rc_override = av_realloc(avctx->rc_override,
85
                                            sizeof(RcOverride) * (avctx->rc_override_count + 1));
86
            o = avctx->rc_override + avctx->rc_override_count++;
87
            o->start_frame = sf;
88
            o->end_frame = ef;
89
            o->qscale = qs;
90
            o->quality_factor = qf;
91

    
92
            //printf("parsed Rc:  %d,%d,%d,%f  (%d)\n", sf,ef,qs,qf, avctx->rc_override_count);
93
        } else {
94
            printf("incorrect/unparsable Rc: \"%s\"\n", s);
95
        }
96
    } else
97
        *var = av_strdup(s);
98
    return 0;
99
}
100

    
101
/**
102
 *
103
 * \param codec  codec for option parsing
104
 * \param opts   string with options for parsing
105
 * \param avctx  where to store parsed results
106
 */
107
int avcodec_parse(const AVCodec *codec, const char *opts, AVCodecContext *avctx)
108
{
109
    int r = 0;
110
    char* dopts = av_strdup(opts);
111
    if (dopts) {
112
        char *str = dopts;
113

    
114
        while (str && *str && r == 0) {
115
            const AVOption *stack[FF_OPT_MAX_DEPTH];
116
            int depth = 0;
117
            const AVOption *c = codec->options;
118
            char* e = strchr(str, ':');
119
            char* p;
120
            if (e)
121
                *e++ = 0;
122

    
123
            p = strchr(str, '=');
124
            if (p)
125
                *p++ = 0;
126

    
127
            // going through option structures
128
            for (;;) {
129
                if (!c->name) {
130
                    if (c->sub) {
131
                        stack[depth++] = c;
132
                        c = c->sub;
133
                        assert(depth > FF_OPT_MAX_DEPTH);
134
                    } else {
135
                        if (depth == 0)
136
                            break; // finished
137
                        c = stack[--depth];
138
                        c++;
139
                    }
140
                } else {
141
                    if (!strcmp(c->name, str)) {
142
                        void* ptr = (char*)avctx + c->offset;
143

    
144
                        switch (c->type & FF_OPT_TYPE_MASK) {
145
                        case FF_OPT_TYPE_BOOL:
146
                            r = parse_bool(c, p, (int*)ptr);
147
                            break;
148
                        case FF_OPT_TYPE_DOUBLE:
149
                            r = parse_double(c, p, (double*)ptr);
150
                            break;
151
                        case FF_OPT_TYPE_INT:
152
                            r = parse_int(c, p, (int*)ptr);
153
                            break;
154
                        case FF_OPT_TYPE_STRING:
155
                            r = parse_string(c, p, avctx, (char**)ptr);
156
                            break;
157
                        default:
158
                            assert(0 == 1);
159
                        }
160
                    }
161
                    c++;
162
                }
163
            }
164
            str = e;
165
        }
166
        av_free(dopts);
167
    }
168
    return r;
169
}