Statistics
| Branch: | Revision:

ffmpeg / libavcodec / opts.c @ ea937d01

History | View | Annotate | Download (7.06 KB)

1
/*
2
 * LGPL
3
 */
4

    
5
/*
6
 * typical parsed command line:
7
 * msmpeg4:bitrate=720000:qmax=16
8
 *
9
 */
10

    
11
#include "avcodec.h"
12
#ifdef OPTS_MAIN
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <string.h>
16
#endif
17

    
18
/*
19
 * todo - use for decoder options also
20
 */
21

    
22
static int parse_bool(avc_config_t* c, char* s)
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
    if (c && c->val)
37
        *(int*)(c->val) = b;
38
    return 0;
39
}
40

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

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

    
77
static int parse_string(AVCodecContext* avctx, avc_config_t* c, char* s)
78
{
79
    if (!s)
80
        return -1;
81

    
82
    if (c->type == FF_CONF_TYPE_RCOVERIDE) {
83
        int sf, ef, qs;
84
        float qf;
85
        if (sscanf(s, "%d,%d,%d,%f", &sf, &ef, &qs, &qf) == 4 && sf < ef) {
86
            RcOverride* o;
87
            *((RcOverride**)c->val) =
88
                realloc(*((RcOverride**)c->val),
89
                        sizeof(RcOverride) * (avctx->rc_override_count + 1));
90
            o = *((RcOverride**)c->val) + avctx->rc_override_count++;
91
            o->start_frame = sf;
92
            o->end_frame = ef;
93
            o->qscale = qs;
94
            o->quality_factor = qf;
95

    
96
            //printf("parsed Rc:  %d,%d,%d,%f  (%d)\n", sf,ef,qs,qf, avctx->rc_override_count);
97
        } else {
98
            printf("incorrect/unparsable Rc: \"%s\"\n", s);
99
        }
100
    } else
101
        (char*)(c->val) = strdup(s);
102
    return 0;
103
}
104

    
105
static int parse(AVCodecContext* avctx, avc_config_t* config, char* str)
106
{
107
    while (str && *str) {
108
        avc_config_t* c = config;
109
        char* e = strchr(str, ':');
110
        char* p;
111
        if (e)
112
            *e++ = 0;
113

    
114
        p = strchr(str, '=');
115
        if (p)
116
            *p++ = 0;
117

    
118
        while (c->name) {
119
            if (!strcmp(c->name, str)) {
120
                switch (c->type & FF_CONF_TYPE_MASK) {
121
                case FF_CONF_TYPE_BOOL:
122
                    parse_bool(c, p);
123
                    break;
124
                case FF_CONF_TYPE_DOUBLE:
125
                    parse_double(c, p);
126
                    break;
127
                case FF_CONF_TYPE_INT:
128
                    parse_int(c, p);
129
                    break;
130
                case FF_CONF_TYPE_STRING:
131
                    parse_string(avctx, c, p);
132
                    break;
133
                default:
134
                    abort();
135
                    break;
136
                }
137
            }
138
            c++;
139
        }
140
        str = e;
141
    }
142
    return 0;
143
}
144

    
145
/**
146
 *
147
 * \param avctx  where to store parsed results
148
 * \param str    string with options for parsing
149
 *               or selectional string (pick only options appliable
150
 *               for codec - use  ,msmpeg4, (with commas to avoid mismatch)
151
 * \param config allocated avc_config_t for external parsing
152
 *               i.e. external program might learn about all available
153
 *               options for given codec
154
 **/
155
void avcodec_getopt(AVCodecContext* avctx, const char* str, avc_config_t** config)
156
{
157
    AVCodecContext avctx_tmp;
158
    AVCodecContext* ctx = (avctx) ? avctx : &avctx_tmp;
159
    static const char* class_h263 = ",msmpeg4,";
160
    //"huffyuv,wmv1,msmpeg4v2,msmpeg4,mpeg4,mpeg1,mpeg1video,mjpeg,rv10,h263,h263p"
161

    
162
    avc_config_t cnf[] =
163
    {
164
        // FIXME: sorted by importance!!!
165
        // expert option should follow more common ones
166
        {
167
            "bitrate", "desired video bitrate",
168
            FF_CONF_TYPE_INT, &ctx->bit_rate, 4, 240000000, 800000, NULL, class_h263
169
        }, {
170
            "vhq", "very high quality",
171
            FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_HQ, 0, NULL, class_h263
172
        }, {
173
            "ratetol", "number of bits the bitstream is allowed to diverge from the reference"
174
            "the reference can be CBR (for CBR pass1) or VBR (for pass2)",
175
            FF_CONF_TYPE_INT, &ctx->bit_rate_tolerance, 4, 240000000, 8000, NULL, class_h263
176
        }, {
177
            "qmin", "minimum quantizer", FF_CONF_TYPE_INT, &ctx->qmin, 1, 31, 2, NULL, class_h263
178
        }, {
179
            "qmax", "maximum qunatizer", FF_CONF_TYPE_INT, &ctx->qmax, 1, 31, 31, NULL, class_h263
180
        }, {
181
            "rc_eq", "rate control equation",
182
            FF_CONF_TYPE_STRING, &ctx->rc_eq, 0, 0, 0, "tex^qComp" /* FILLME options */, class_h263
183
        }, {
184
            "rc_minrate", "rate control minimum bitrate",
185
            FF_CONF_TYPE_INT, &ctx->rc_min_rate, 4, 24000000, 0, NULL, class_h263
186
        }, {
187
            "rc_maxrate", "rate control maximum bitrate",
188
            FF_CONF_TYPE_INT, &ctx->rc_max_rate, 4, 24000000, 0, NULL, class_h263
189
        }, {
190
            "psnr", "calculate PSNR of compressed frames",
191
            FF_CONF_TYPE_FLAG, &ctx->flags, 0, CODEC_FLAG_PSNR, 0, NULL, class_h263
192
        }, {
193
            "rc_override", "ratecontrol override (=startframe,endframe,qscale,quality_factor)",
194
            FF_CONF_TYPE_RCOVERIDE, &ctx->rc_override, 0, 0, 0, "0,0,0,0", class_h263
195
        },
196

    
197
        { NULL, NULL, 0, NULL, 0, 0, 0, NULL, NULL }
198
    };
199

    
200
    if (config) {
201
        *config = malloc(sizeof(cnf));
202
        if (*config) {
203
            avc_config_t* src = cnf;
204
            avc_config_t* dst = *config;
205
            while (src->name) {
206
                if (!str || !src->supported || strstr(src->supported, str))
207
                    memcpy(dst++, src, sizeof(avc_config_t));
208
                src++;
209
            }
210
            memset(dst, 0, sizeof(avc_config_t));
211
        }
212
    } else if (str) {
213
        char* s = strdup(str);
214
        if (s) {
215
            parse(avctx, cnf, s);
216
            free(s);
217
        }
218
    }
219
}
220

    
221
#ifdef OPTS_MAIN
222
/*
223
 * API test -
224
 * arg1: options
225
 * arg2: codec type
226
 *
227
 * compile standalone: make CFLAGS="-DOPTS_MAIN" opts
228
 */
229
int main(int argc, char* argv[])
230
{
231
    AVCodecContext avctx;
232
    avc_config_t* config;
233
    char* def = malloc(5000);
234
    const char* col = "";
235
    int i = 0;
236

    
237
    memset(&avctx, 0, sizeof(avctx));
238
    *def = 0;
239
    avcodec_getopt(&avctx, argv[1], NULL);
240

    
241
    avcodec_getopt(NULL, (argc > 2) ? argv[2] : NULL, &config);
242
    if (config)
243
        while (config->name) {
244
            int t = config->type & FF_CONF_TYPE_MASK;
245
            printf("Config   %s  %s\n", config->name,
246
                   t == FF_CONF_TYPE_BOOL ? "bool" :
247
                   t == FF_CONF_TYPE_DOUBLE ? "double" :
248
                   t == FF_CONF_TYPE_INT ? "integer" :
249
                   t == FF_CONF_TYPE_STRING ? "string" :
250
                   "unknown??");
251
            switch (t) {
252
            case FF_CONF_TYPE_BOOL:
253
                i += sprintf(def + i, "%s%s=%s",
254
                             col, config->name,
255
                             config->defval != 0. ? "on" : "off");
256
                break;
257
            case FF_CONF_TYPE_DOUBLE:
258
                i += sprintf(def + i, "%s%s=%f",
259
                             col, config->name, config->defval);
260
                break;
261
            case FF_CONF_TYPE_INT:
262
                i += sprintf(def + i, "%s%s=%d",
263
                             col, config->name, (int) config->defval);
264
                break;
265
            case FF_CONF_TYPE_STRING:
266
                i += sprintf(def + i, "%s%s=%s",
267
                             col, config->name, config->defstr);
268
                break;
269
            }
270
            col = ":";
271
            config++;
272
        }
273

    
274
    printf("Default Options: %s\n", def);
275

    
276
    return 0;
277
}
278
#endif