Statistics
| Branch: | Revision:

ffmpeg / cmdutils.c @ 470bce2b

History | View | Annotate | Download (15.7 KB)

1 01310af2 Fabrice Bellard
/*
2
 * Various utilities for command line tools
3
 * Copyright (c) 2000-2003 Fabrice Bellard
4
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 01310af2 Fabrice Bellard
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 01310af2 Fabrice Bellard
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 01310af2 Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 01310af2 Fabrice Bellard
 */
21 364a9607 Diego Biurrun
22 0f4e8165 Ronald S. Bultje
#include <string.h>
23
#include <stdlib.h>
24
#include <errno.h>
25 7c84b8bc Stefano Sabatini
#include <math.h>
26 0f4e8165 Ronald S. Bultje
27 2cd39dbf Diego Pettenò
/* Include only the enabled headers since some compilers (namely, Sun
28
   Studio) will not omit unused inline functions and create undefined
29
   references to libraries that are not being built. */
30
31 63d026b1 Diego Biurrun
#include "config.h"
32 245976da Diego Biurrun
#include "libavformat/avformat.h"
33 2cd39dbf Diego Pettenò
#ifdef CONFIG_AVFILTER
34 245976da Diego Biurrun
#include "libavfilter/avfilter.h"
35 2cd39dbf Diego Pettenò
#endif
36 245976da Diego Biurrun
#include "libavdevice/avdevice.h"
37 db6d50c7 Stefano Sabatini
#include "libswscale/swscale.h"
38 2cd39dbf Diego Pettenò
#ifdef CONFIG_POSTPROC
39 1981deaf Stefano Sabatini
#include "libpostproc/postprocess.h"
40 2cd39dbf Diego Pettenò
#endif
41 245976da Diego Biurrun
#include "libavutil/avstring.h"
42 85663ef3 Michael Niedermayer
#include "libavcodec/opt.h"
43 01310af2 Fabrice Bellard
#include "cmdutils.h"
44 86074ed1 Stefano Sabatini
#include "version.h"
45 0b705fa4 Ramiro Polla
#ifdef CONFIG_NETWORK
46 245976da Diego Biurrun
#include "libavformat/network.h"
47 0b705fa4 Ramiro Polla
#endif
48 01310af2 Fabrice Bellard
49 c367d067 Michael Niedermayer
#undef exit
50
51 85663ef3 Michael Niedermayer
const char **opt_names;
52
static int opt_name_count;
53
AVCodecContext *avctx_opts[CODEC_TYPE_NB];
54
AVFormatContext *avformat_opts;
55
struct SwsContext *sws_opts;
56 086ab001 Michael Niedermayer
57
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
58
{
59
    char *tail;
60
    const char *error;
61
    double d = strtod(numstr, &tail);
62
    if (*tail)
63
        error= "Expected number for %s but found: %s\n";
64
    else if (d < min || d > max)
65
        error= "The value for %s was %s which is not within %f - %f\n";
66
    else if(type == OPT_INT64 && (int64_t)d != d)
67
        error= "Expected int64 for %s but found %s\n";
68
    else
69
        return d;
70
    fprintf(stderr, error, context, numstr, min, max);
71
    exit(1);
72
}
73
74 7542157d Stefano Sabatini
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
75
{
76
    int64_t us = parse_date(timestr, is_duration);
77
    if (us == INT64_MIN) {
78
        fprintf(stderr, "Invalid %s specification for %s: %s\n",
79
                is_duration ? "duration" : "date", context, timestr);
80
        exit(1);
81
    }
82
    return us;
83
}
84
85 02d504a7 Fabrice Bellard
void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
86 01310af2 Fabrice Bellard
{
87
    const OptionDef *po;
88 02d504a7 Fabrice Bellard
    int first;
89 01310af2 Fabrice Bellard
90 02d504a7 Fabrice Bellard
    first = 1;
91
    for(po = options; po->name != NULL; po++) {
92
        char buf[64];
93
        if ((po->flags & mask) == value) {
94
            if (first) {
95
                printf("%s", msg);
96
                first = 0;
97
            }
98 f7d78f36 Måns Rullgård
            av_strlcpy(buf, po->name, sizeof(buf));
99 02d504a7 Fabrice Bellard
            if (po->flags & HAS_ARG) {
100 f7d78f36 Måns Rullgård
                av_strlcat(buf, " ", sizeof(buf));
101
                av_strlcat(buf, po->argname, sizeof(buf));
102 01310af2 Fabrice Bellard
            }
103 02d504a7 Fabrice Bellard
            printf("-%-17s  %s\n", buf, po->help);
104 01310af2 Fabrice Bellard
        }
105
    }
106
}
107
108 fccfc475 Måns Rullgård
static const OptionDef* find_option(const OptionDef *po, const char *name){
109 8bbf6db9 Michael Niedermayer
    while (po->name != NULL) {
110
        if (!strcmp(name, po->name))
111
            break;
112
        po++;
113
    }
114
    return po;
115
}
116
117 60a9966e Stefano Sabatini
void parse_options(int argc, char **argv, const OptionDef *options,
118
                   void (* parse_arg_function)(const char*))
119 01310af2 Fabrice Bellard
{
120
    const char *opt, *arg;
121 b0d7bc1e Loren Merritt
    int optindex, handleoptions=1;
122 01310af2 Fabrice Bellard
    const OptionDef *po;
123
124
    /* parse options */
125
    optindex = 1;
126
    while (optindex < argc) {
127
        opt = argv[optindex++];
128 115329f1 Diego Biurrun
129 84bf226b Timo Lindfors
        if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
130 3749076c Stefano Sabatini
            if (opt[1] == '-' && opt[2] == '\0') {
131
                handleoptions = 0;
132
                continue;
133
            }
134 8bbf6db9 Michael Niedermayer
            po= find_option(options, opt + 1);
135
            if (!po->name)
136
                po= find_option(options, "default");
137 01310af2 Fabrice Bellard
            if (!po->name) {
138 8bbf6db9 Michael Niedermayer
unknown_opt:
139 01310af2 Fabrice Bellard
                fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
140
                exit(1);
141
            }
142
            arg = NULL;
143
            if (po->flags & HAS_ARG) {
144
                arg = argv[optindex++];
145
                if (!arg) {
146
                    fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
147
                    exit(1);
148
                }
149
            }
150
            if (po->flags & OPT_STRING) {
151
                char *str;
152 02d504a7 Fabrice Bellard
                str = av_strdup(arg);
153 01310af2 Fabrice Bellard
                *po->u.str_arg = str;
154
            } else if (po->flags & OPT_BOOL) {
155
                *po->u.int_arg = 1;
156 26d4f26b Michael Niedermayer
            } else if (po->flags & OPT_INT) {
157 7c84b8bc Stefano Sabatini
                *po->u.int_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT_MIN, INT_MAX);
158 ffdf9a1f Baptiste Coudurier
            } else if (po->flags & OPT_INT64) {
159 7c84b8bc Stefano Sabatini
                *po->u.int64_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT64_MIN, INT64_MAX);
160 1f631450 Michael Niedermayer
            } else if (po->flags & OPT_FLOAT) {
161 1f3d74d3 Michael Niedermayer
                *po->u.float_arg = parse_number_or_die(opt+1, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
162 8bbf6db9 Michael Niedermayer
            } else if (po->flags & OPT_FUNC2) {
163
                if(po->u.func2_arg(opt+1, arg)<0)
164
                    goto unknown_opt;
165 01310af2 Fabrice Bellard
            } else {
166 bb270c08 Diego Biurrun
                po->u.func_arg(arg);
167 01310af2 Fabrice Bellard
            }
168 a0b3bcd9 Michael Niedermayer
            if(po->flags & OPT_EXIT)
169
                exit(0);
170 01310af2 Fabrice Bellard
        } else {
171 60a9966e Stefano Sabatini
            if (parse_arg_function)
172
                parse_arg_function(opt);
173 01310af2 Fabrice Bellard
        }
174
    }
175
}
176
177 85663ef3 Michael Niedermayer
int opt_default(const char *opt, const char *arg){
178
    int type;
179 5c3383e5 Stefano Sabatini
    int ret= 0;
180 85663ef3 Michael Niedermayer
    const AVOption *o= NULL;
181
    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
182
183 5c3383e5 Stefano Sabatini
    for(type=0; type<CODEC_TYPE_NB && ret>= 0; type++){
184 85663ef3 Michael Niedermayer
        const AVOption *o2 = av_find_opt(avctx_opts[0], opt, NULL, opt_types[type], opt_types[type]);
185
        if(o2)
186 5c3383e5 Stefano Sabatini
            ret = av_set_string3(avctx_opts[type], opt, arg, 1, &o);
187 85663ef3 Michael Niedermayer
    }
188
    if(!o)
189 5c3383e5 Stefano Sabatini
        ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
190 85663ef3 Michael Niedermayer
    if(!o)
191 5c3383e5 Stefano Sabatini
        ret = av_set_string3(sws_opts, opt, arg, 1, &o);
192 85663ef3 Michael Niedermayer
    if(!o){
193
        if(opt[0] == 'a')
194 5c3383e5 Stefano Sabatini
            ret = av_set_string3(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg, 1, &o);
195 85663ef3 Michael Niedermayer
        else if(opt[0] == 'v')
196 5c3383e5 Stefano Sabatini
            ret = av_set_string3(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg, 1, &o);
197 85663ef3 Michael Niedermayer
        else if(opt[0] == 's')
198 5c3383e5 Stefano Sabatini
            ret = av_set_string3(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg, 1, &o);
199
    }
200
    if (o && ret < 0) {
201
        fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
202
        exit(1);
203 85663ef3 Michael Niedermayer
    }
204
    if(!o)
205
        return -1;
206
207
//    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avctx_opts, opt, NULL), (int)av_get_int(avctx_opts, opt, NULL));
208
209
    //FIXME we should always use avctx_opts, ... for storing options so there will not be any need to keep track of what i set over this
210
    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
211
    opt_names[opt_name_count++]= o->name;
212
213
    if(avctx_opts[0]->debug || avformat_opts->debug)
214
        av_log_set_level(AV_LOG_DEBUG);
215
    return 0;
216
}
217
218
void set_context_opts(void *ctx, void *opts_ctx, int flags)
219
{
220
    int i;
221
    for(i=0; i<opt_name_count; i++){
222
        char buf[256];
223
        const AVOption *opt;
224
        const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
225
        /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
226
        if(str && ((opt->flags & flags) == flags))
227 f16dd7e6 Stefano Sabatini
            av_set_string3(ctx, opt_names[i], str, 1, NULL);
228 85663ef3 Michael Niedermayer
    }
229
}
230
231 01310af2 Fabrice Bellard
void print_error(const char *filename, int err)
232
{
233
    switch(err) {
234
    case AVERROR_NUMEXPECTED:
235
        fprintf(stderr, "%s: Incorrect image filename syntax.\n"
236
                "Use '%%d' to specify the image number:\n"
237
                "  for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
238 115329f1 Diego Biurrun
                "  for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
239 01310af2 Fabrice Bellard
                filename);
240
        break;
241
    case AVERROR_INVALIDDATA:
242
        fprintf(stderr, "%s: Error while parsing header\n", filename);
243
        break;
244
    case AVERROR_NOFMT:
245
        fprintf(stderr, "%s: Unknown format\n", filename);
246
        break;
247 6f3e0b21 Panagiotis Issaris
    case AVERROR(EIO):
248 d9526386 Diego Biurrun
        fprintf(stderr, "%s: I/O error occurred\n"
249 bb270c08 Diego Biurrun
                "Usually that means that input file is truncated and/or corrupted.\n",
250
                filename);
251 45ce5ddb Kostya Shishkov
        break;
252 769e10f0 Panagiotis Issaris
    case AVERROR(ENOMEM):
253 d9526386 Diego Biurrun
        fprintf(stderr, "%s: memory allocation error occurred\n", filename);
254 45ce5ddb Kostya Shishkov
        break;
255 24fddf48 Panagiotis Issaris
    case AVERROR(ENOENT):
256 0ba0c8de Benoit Fouet
        fprintf(stderr, "%s: no such file or directory\n", filename);
257
        break;
258 0b705fa4 Ramiro Polla
#ifdef CONFIG_NETWORK
259 18ec0460 Luca Barbato
    case AVERROR(FF_NETERROR(EPROTONOSUPPORT)):
260
        fprintf(stderr, "%s: Unsupported network protocol\n", filename);
261
        break;
262 0b705fa4 Ramiro Polla
#endif
263 01310af2 Fabrice Bellard
    default:
264
        fprintf(stderr, "%s: Error while opening file\n", filename);
265
        break;
266
    }
267
}
268 f35917b2 Stefano Sabatini
269 9a109272 Stefano Sabatini
#define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \
270
    version= libname##_version(); \
271
    fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n", indent? "  " : "", #libname, \
272
            LIB##LIBNAME##_VERSION_MAJOR, LIB##LIBNAME##_VERSION_MINOR, LIB##LIBNAME##_VERSION_MICRO, \
273
            version >> 16, version >> 8 & 0xff, version & 0xff);
274
275 88b77ef1 Diego Pettenò
static void print_all_lib_versions(FILE* outstream, int indent)
276 9a109272 Stefano Sabatini
{
277
    unsigned int version;
278 e9df66a7 Stefano Sabatini
    PRINT_LIB_VERSION(outstream, avutil,   AVUTIL,   indent);
279
    PRINT_LIB_VERSION(outstream, avcodec,  AVCODEC,  indent);
280 9a109272 Stefano Sabatini
    PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
281
    PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
282 a14b362f Diego Pettenò
#ifdef CONFIG_AVFILTER
283 9a109272 Stefano Sabatini
    PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
284
#endif
285 a14b362f Diego Pettenò
#ifdef CONFIG_SWSCALE
286 e9df66a7 Stefano Sabatini
    PRINT_LIB_VERSION(outstream, swscale,  SWSCALE,  indent);
287 db6d50c7 Stefano Sabatini
#endif
288 a14b362f Diego Pettenò
#ifdef CONFIG_POSTPROC
289 1981deaf Stefano Sabatini
    PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent);
290
#endif
291 9a109272 Stefano Sabatini
}
292
293 ea9c581f Stefano Sabatini
void show_banner(void)
294 86074ed1 Stefano Sabatini
{
295 e329b6ec Stefano Sabatini
    fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-2009 Fabrice Bellard, et al.\n",
296 86074ed1 Stefano Sabatini
            program_name, program_birth_year);
297
    fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
298 9a109272 Stefano Sabatini
    print_all_lib_versions(stderr, 1);
299 86074ed1 Stefano Sabatini
    fprintf(stderr, "  built on " __DATE__ " " __TIME__);
300
#ifdef __GNUC__
301
    fprintf(stderr, ", gcc: " __VERSION__ "\n");
302
#else
303
    fprintf(stderr, ", using a non-gcc compiler\n");
304
#endif
305
}
306
307 64555bd9 Michael Niedermayer
void show_version(void) {
308 86074ed1 Stefano Sabatini
    printf("%s " FFMPEG_VERSION "\n", program_name);
309 9a109272 Stefano Sabatini
    print_all_lib_versions(stdout, 0);
310 86074ed1 Stefano Sabatini
}
311
312 f35917b2 Stefano Sabatini
void show_license(void)
313
{
314 7ead693b Diego Biurrun
#ifdef CONFIG_NONFREE
315
    printf(
316 304ba23a Stefano Sabatini
    "This version of %s has nonfree parts compiled in.\n"
317
    "Therefore it is not legally redistributable.\n",
318
    program_name
319 7ead693b Diego Biurrun
    );
320
#elif CONFIG_GPL
321 f35917b2 Stefano Sabatini
    printf(
322 304ba23a Stefano Sabatini
    "%s is free software; you can redistribute it and/or modify\n"
323 f35917b2 Stefano Sabatini
    "it under the terms of the GNU General Public License as published by\n"
324
    "the Free Software Foundation; either version 2 of the License, or\n"
325
    "(at your option) any later version.\n"
326
    "\n"
327 304ba23a Stefano Sabatini
    "%s is distributed in the hope that it will be useful,\n"
328 f35917b2 Stefano Sabatini
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
329
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
330
    "GNU General Public License for more details.\n"
331
    "\n"
332
    "You should have received a copy of the GNU General Public License\n"
333 304ba23a Stefano Sabatini
    "along with %s; if not, write to the Free Software\n"
334
    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
335
    program_name, program_name, program_name
336 f35917b2 Stefano Sabatini
    );
337
#else
338
    printf(
339 304ba23a Stefano Sabatini
    "%s is free software; you can redistribute it and/or\n"
340 f35917b2 Stefano Sabatini
    "modify it under the terms of the GNU Lesser General Public\n"
341
    "License as published by the Free Software Foundation; either\n"
342
    "version 2.1 of the License, or (at your option) any later version.\n"
343
    "\n"
344 304ba23a Stefano Sabatini
    "%s is distributed in the hope that it will be useful,\n"
345 f35917b2 Stefano Sabatini
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
346
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
347
    "Lesser General Public License for more details.\n"
348
    "\n"
349
    "You should have received a copy of the GNU Lesser General Public\n"
350 304ba23a Stefano Sabatini
    "License along with %s; if not, write to the Free Software\n"
351
    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
352
    program_name, program_name, program_name
353 f35917b2 Stefano Sabatini
    );
354
#endif
355
}
356 ba9880c1 Stefano Sabatini
357
void show_formats(void)
358
{
359
    AVInputFormat *ifmt=NULL;
360
    AVOutputFormat *ofmt=NULL;
361
    URLProtocol *up=NULL;
362
    AVCodec *p=NULL, *p2;
363
    AVBitStreamFilter *bsf=NULL;
364
    const char *last_name;
365
366
    printf("File formats:\n");
367
    last_name= "000";
368
    for(;;){
369
        int decode=0;
370
        int encode=0;
371
        const char *name=NULL;
372
        const char *long_name=NULL;
373
374
        while((ofmt= av_oformat_next(ofmt))) {
375
            if((name == NULL || strcmp(ofmt->name, name)<0) &&
376
                strcmp(ofmt->name, last_name)>0){
377
                name= ofmt->name;
378
                long_name= ofmt->long_name;
379
                encode=1;
380
            }
381
        }
382
        while((ifmt= av_iformat_next(ifmt))) {
383
            if((name == NULL || strcmp(ifmt->name, name)<0) &&
384
                strcmp(ifmt->name, last_name)>0){
385
                name= ifmt->name;
386
                long_name= ifmt->long_name;
387
                encode=0;
388
            }
389
            if(name && strcmp(ifmt->name, name)==0)
390
                decode=1;
391
        }
392
        if(name==NULL)
393
            break;
394
        last_name= name;
395
396
        printf(
397
            " %s%s %-15s %s\n",
398
            decode ? "D":" ",
399
            encode ? "E":" ",
400
            name,
401
            long_name ? long_name:" ");
402
    }
403
    printf("\n");
404
405
    printf("Codecs:\n");
406
    last_name= "000";
407
    for(;;){
408
        int decode=0;
409
        int encode=0;
410
        int cap=0;
411
        const char *type_str;
412
413
        p2=NULL;
414
        while((p= av_codec_next(p))) {
415
            if((p2==NULL || strcmp(p->name, p2->name)<0) &&
416
                strcmp(p->name, last_name)>0){
417
                p2= p;
418
                decode= encode= cap=0;
419
            }
420
            if(p2 && strcmp(p->name, p2->name)==0){
421
                if(p->decode) decode=1;
422
                if(p->encode) encode=1;
423
                cap |= p->capabilities;
424
            }
425
        }
426
        if(p2==NULL)
427
            break;
428
        last_name= p2->name;
429
430
        switch(p2->type) {
431
        case CODEC_TYPE_VIDEO:
432
            type_str = "V";
433
            break;
434
        case CODEC_TYPE_AUDIO:
435
            type_str = "A";
436
            break;
437
        case CODEC_TYPE_SUBTITLE:
438
            type_str = "S";
439
            break;
440
        default:
441
            type_str = "?";
442
            break;
443
        }
444
        printf(
445
            " %s%s%s%s%s%s %-15s %s",
446
            decode ? "D": (/*p2->decoder ? "d":*/" "),
447
            encode ? "E":" ",
448
            type_str,
449
            cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
450
            cap & CODEC_CAP_DR1 ? "D":" ",
451
            cap & CODEC_CAP_TRUNCATED ? "T":" ",
452
            p2->name,
453
            p2->long_name ? p2->long_name : "");
454
       /* if(p2->decoder && decode==0)
455
            printf(" use %s for decoding", p2->decoder->name);*/
456
        printf("\n");
457
    }
458
    printf("\n");
459
460
    printf("Bitstream filters:\n");
461
    while((bsf = av_bitstream_filter_next(bsf)))
462
        printf(" %s", bsf->name);
463
    printf("\n");
464
465
    printf("Supported file protocols:\n");
466
    while((up = av_protocol_next(up)))
467
        printf(" %s:", up->name);
468
    printf("\n");
469
470
    printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
471
    printf("\n");
472
    printf(
473
"Note, the names of encoders and decoders do not always match, so there are\n"
474
"several cases where the above table shows encoder only or decoder only entries\n"
475
"even though both encoding and decoding are supported. For example, the h263\n"
476
"decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
477
"worse.\n");
478
}