Statistics
| Branch: | Revision:

ffmpeg / cmdutils.c @ ffcc6e24

History | View | Annotate | Download (20 KB)

1
/*
2
 * Various utilities for command line tools
3
 * Copyright (c) 2000-2003 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * 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
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
22
#include <string.h>
23
#include <stdlib.h>
24
#include <errno.h>
25
#include <math.h>
26

    
27
/* 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
#include "config.h"
32
#include "libavformat/avformat.h"
33
#include "libavfilter/avfilter.h"
34
#include "libavdevice/avdevice.h"
35
#include "libswscale/swscale.h"
36
#include "libpostproc/postprocess.h"
37
#include "libavutil/avstring.h"
38
#include "libavcodec/opt.h"
39
#include "cmdutils.h"
40
#include "version.h"
41
#if CONFIG_NETWORK
42
#include "libavformat/network.h"
43
#endif
44
#if HAVE_SYS_RESOURCE_H
45
#include <sys/resource.h>
46
#endif
47

    
48
#undef exit
49

    
50
const char **opt_names;
51
static int opt_name_count;
52
AVCodecContext *avcodec_opts[CODEC_TYPE_NB];
53
AVFormatContext *avformat_opts;
54
struct SwsContext *sws_opts;
55

    
56
const int this_year = 2010;
57

    
58
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
59
{
60
    char *tail;
61
    const char *error;
62
    double d = strtod(numstr, &tail);
63
    if (*tail)
64
        error= "Expected number for %s but found: %s\n";
65
    else if (d < min || d > max)
66
        error= "The value for %s was %s which is not within %f - %f\n";
67
    else if(type == OPT_INT64 && (int64_t)d != d)
68
        error= "Expected int64 for %s but found %s\n";
69
    else
70
        return d;
71
    fprintf(stderr, error, context, numstr, min, max);
72
    exit(1);
73
}
74

    
75
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
76
{
77
    int64_t us = parse_date(timestr, is_duration);
78
    if (us == INT64_MIN) {
79
        fprintf(stderr, "Invalid %s specification for %s: %s\n",
80
                is_duration ? "duration" : "date", context, timestr);
81
        exit(1);
82
    }
83
    return us;
84
}
85

    
86
void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
87
{
88
    const OptionDef *po;
89
    int first;
90

    
91
    first = 1;
92
    for(po = options; po->name != NULL; po++) {
93
        char buf[64];
94
        if ((po->flags & mask) == value) {
95
            if (first) {
96
                printf("%s", msg);
97
                first = 0;
98
            }
99
            av_strlcpy(buf, po->name, sizeof(buf));
100
            if (po->flags & HAS_ARG) {
101
                av_strlcat(buf, " ", sizeof(buf));
102
                av_strlcat(buf, po->argname, sizeof(buf));
103
            }
104
            printf("-%-17s  %s\n", buf, po->help);
105
        }
106
    }
107
}
108

    
109
static const OptionDef* find_option(const OptionDef *po, const char *name){
110
    while (po->name != NULL) {
111
        if (!strcmp(name, po->name))
112
            break;
113
        po++;
114
    }
115
    return po;
116
}
117

    
118
void parse_options(int argc, char **argv, const OptionDef *options,
119
                   void (* parse_arg_function)(const char*))
120
{
121
    const char *opt, *arg;
122
    int optindex, handleoptions=1;
123
    const OptionDef *po;
124

    
125
    /* parse options */
126
    optindex = 1;
127
    while (optindex < argc) {
128
        opt = argv[optindex++];
129

    
130
        if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
131
            int bool_val = 1;
132
            if (opt[1] == '-' && opt[2] == '\0') {
133
                handleoptions = 0;
134
                continue;
135
            }
136
            opt++;
137
            po= find_option(options, opt);
138
            if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
139
                /* handle 'no' bool option */
140
                po = find_option(options, opt + 2);
141
                if (!(po->name && (po->flags & OPT_BOOL)))
142
                    goto unknown_opt;
143
                bool_val = 0;
144
            }
145
            if (!po->name)
146
                po= find_option(options, "default");
147
            if (!po->name) {
148
unknown_opt:
149
                fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
150
                exit(1);
151
            }
152
            arg = NULL;
153
            if (po->flags & HAS_ARG) {
154
                arg = argv[optindex++];
155
                if (!arg) {
156
                    fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
157
                    exit(1);
158
                }
159
            }
160
            if (po->flags & OPT_STRING) {
161
                char *str;
162
                str = av_strdup(arg);
163
                *po->u.str_arg = str;
164
            } else if (po->flags & OPT_BOOL) {
165
                *po->u.int_arg = bool_val;
166
            } else if (po->flags & OPT_INT) {
167
                *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
168
            } else if (po->flags & OPT_INT64) {
169
                *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
170
            } else if (po->flags & OPT_FLOAT) {
171
                *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
172
            } else if (po->flags & OPT_FUNC2) {
173
                if(po->u.func2_arg(opt, arg)<0)
174
                    goto unknown_opt;
175
            } else {
176
                po->u.func_arg(arg);
177
            }
178
            if(po->flags & OPT_EXIT)
179
                exit(0);
180
        } else {
181
            if (parse_arg_function)
182
                parse_arg_function(opt);
183
        }
184
    }
185
}
186

    
187
int opt_default(const char *opt, const char *arg){
188
    int type;
189
    int ret= 0;
190
    const AVOption *o= NULL;
191
    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
192

    
193
    for(type=0; type<CODEC_TYPE_NB && ret>= 0; type++){
194
        const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
195
        if(o2)
196
            ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
197
    }
198
    if(!o)
199
        ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
200
    if(!o)
201
        ret = av_set_string3(sws_opts, opt, arg, 1, &o);
202
    if(!o){
203
        if(opt[0] == 'a')
204
            ret = av_set_string3(avcodec_opts[CODEC_TYPE_AUDIO], opt+1, arg, 1, &o);
205
        else if(opt[0] == 'v')
206
            ret = av_set_string3(avcodec_opts[CODEC_TYPE_VIDEO], opt+1, arg, 1, &o);
207
        else if(opt[0] == 's')
208
            ret = av_set_string3(avcodec_opts[CODEC_TYPE_SUBTITLE], opt+1, arg, 1, &o);
209
    }
210
    if (o && ret < 0) {
211
        fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
212
        exit(1);
213
    }
214
    if(!o)
215
        return -1;
216

    
217
//    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));
218

    
219
    //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
220
    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
221
    opt_names[opt_name_count++]= o->name;
222

    
223
    if(avcodec_opts[0]->debug || avformat_opts->debug)
224
        av_log_set_level(AV_LOG_DEBUG);
225
    return 0;
226
}
227

    
228
int opt_loglevel(const char *opt, const char *arg)
229
{
230
    const struct { const char *name; int level; } log_levels[] = {
231
        { "quiet"  , AV_LOG_QUIET   },
232
        { "panic"  , AV_LOG_PANIC   },
233
        { "fatal"  , AV_LOG_FATAL   },
234
        { "error"  , AV_LOG_ERROR   },
235
        { "warning", AV_LOG_WARNING },
236
        { "info"   , AV_LOG_INFO    },
237
        { "verbose", AV_LOG_VERBOSE },
238
        { "debug"  , AV_LOG_DEBUG   },
239
    };
240
    char *tail;
241
    int level;
242
    int i;
243

    
244
    for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
245
        if (!strcmp(log_levels[i].name, arg)) {
246
            av_log_set_level(log_levels[i].level);
247
            return 0;
248
        }
249
    }
250

    
251
    level = strtol(arg, &tail, 10);
252
    if (*tail) {
253
        fprintf(stderr, "Invalid loglevel \"%s\". "
254
                        "Possible levels are numbers or:\n", arg);
255
        for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
256
            fprintf(stderr, "\"%s\"\n", log_levels[i].name);
257
        exit(1);
258
    }
259
    av_log_set_level(level);
260
    return 0;
261
}
262

    
263
int opt_timelimit(const char *opt, const char *arg)
264
{
265
#if HAVE_SYS_RESOURCE_H
266
    int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
267
    struct rlimit rl = { lim, lim + 1 };
268
    if (setrlimit(RLIMIT_CPU, &rl))
269
        perror("setrlimit");
270
#else
271
    fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
272
#endif
273
    return 0;
274
}
275

    
276
void set_context_opts(void *ctx, void *opts_ctx, int flags)
277
{
278
    int i;
279
    for(i=0; i<opt_name_count; i++){
280
        char buf[256];
281
        const AVOption *opt;
282
        const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
283
        /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
284
        if(str && ((opt->flags & flags) == flags))
285
            av_set_string3(ctx, opt_names[i], str, 1, NULL);
286
    }
287
}
288

    
289
void print_error(const char *filename, int err)
290
{
291
    switch(err) {
292
    case AVERROR_NUMEXPECTED:
293
        fprintf(stderr, "%s: Incorrect image filename syntax.\n"
294
                "Use '%%d' to specify the image number:\n"
295
                "  for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
296
                "  for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
297
                filename);
298
        break;
299
    case AVERROR_INVALIDDATA:
300
        fprintf(stderr, "%s: Error while parsing header\n", filename);
301
        break;
302
    case AVERROR_NOFMT:
303
        fprintf(stderr, "%s: Unknown format\n", filename);
304
        break;
305
    case AVERROR(EIO):
306
        fprintf(stderr, "%s: I/O error occurred\n"
307
                "Usually that means that input file is truncated and/or corrupted.\n",
308
                filename);
309
        break;
310
    case AVERROR(ENOMEM):
311
        fprintf(stderr, "%s: memory allocation error occurred\n", filename);
312
        break;
313
    case AVERROR(ENOENT):
314
        fprintf(stderr, "%s: no such file or directory\n", filename);
315
        break;
316
#if CONFIG_NETWORK
317
    case AVERROR(FF_NETERROR(EPROTONOSUPPORT)):
318
        fprintf(stderr, "%s: Unsupported network protocol\n", filename);
319
        break;
320
#endif
321
    default:
322
        fprintf(stderr, "%s: Error while opening file\n", filename);
323
        break;
324
    }
325
}
326

    
327
#define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \
328
    version= libname##_version(); \
329
    fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n", indent? "  " : "", #libname, \
330
            LIB##LIBNAME##_VERSION_MAJOR, LIB##LIBNAME##_VERSION_MINOR, LIB##LIBNAME##_VERSION_MICRO, \
331
            version >> 16, version >> 8 & 0xff, version & 0xff);
332

    
333
static void print_all_lib_versions(FILE* outstream, int indent)
334
{
335
    unsigned int version;
336
    PRINT_LIB_VERSION(outstream, avutil,   AVUTIL,   indent);
337
    PRINT_LIB_VERSION(outstream, avcodec,  AVCODEC,  indent);
338
    PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
339
    PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
340
#if CONFIG_AVFILTER
341
    PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
342
#endif
343
    PRINT_LIB_VERSION(outstream, swscale,  SWSCALE,  indent);
344
#if CONFIG_POSTPROC
345
    PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent);
346
#endif
347
}
348

    
349
void show_banner(void)
350
{
351
    fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d Fabrice Bellard, et al.\n",
352
            program_name, program_birth_year, this_year);
353
    fprintf(stderr, "  built on %s %s with %s %s\n",
354
            __DATE__, __TIME__, CC_TYPE, CC_VERSION);
355
    fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
356
    print_all_lib_versions(stderr, 1);
357
}
358

    
359
void show_version(void) {
360
    printf("%s " FFMPEG_VERSION "\n", program_name);
361
    print_all_lib_versions(stdout, 0);
362
}
363

    
364
void show_license(void)
365
{
366
    printf(
367
#if CONFIG_NONFREE
368
    "This version of %s has nonfree parts compiled in.\n"
369
    "Therefore it is not legally redistributable.\n",
370
    program_name
371
#elif CONFIG_GPLV3
372
    "%s is free software; you can redistribute it and/or modify\n"
373
    "it under the terms of the GNU General Public License as published by\n"
374
    "the Free Software Foundation; either version 3 of the License, or\n"
375
    "(at your option) any later version.\n"
376
    "\n"
377
    "%s is distributed in the hope that it will be useful,\n"
378
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
379
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
380
    "GNU General Public License for more details.\n"
381
    "\n"
382
    "You should have received a copy of the GNU General Public License\n"
383
    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
384
    program_name, program_name, program_name
385
#elif CONFIG_GPL
386
    "%s is free software; you can redistribute it and/or modify\n"
387
    "it under the terms of the GNU General Public License as published by\n"
388
    "the Free Software Foundation; either version 2 of the License, or\n"
389
    "(at your option) any later version.\n"
390
    "\n"
391
    "%s is distributed in the hope that it will be useful,\n"
392
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
393
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
394
    "GNU General Public License for more details.\n"
395
    "\n"
396
    "You should have received a copy of the GNU General Public License\n"
397
    "along with %s; if not, write to the Free Software\n"
398
    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
399
    program_name, program_name, program_name
400
#elif CONFIG_LGPLV3
401
    "%s is free software; you can redistribute it and/or modify\n"
402
    "it under the terms of the GNU Lesser General Public License as published by\n"
403
    "the Free Software Foundation; either version 3 of the License, or\n"
404
    "(at your option) any later version.\n"
405
    "\n"
406
    "%s is distributed in the hope that it will be useful,\n"
407
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
408
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
409
    "GNU Lesser General Public License for more details.\n"
410
    "\n"
411
    "You should have received a copy of the GNU Lesser General Public License\n"
412
    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
413
    program_name, program_name, program_name
414
#else
415
    "%s is free software; you can redistribute it and/or\n"
416
    "modify it under the terms of the GNU Lesser General Public\n"
417
    "License as published by the Free Software Foundation; either\n"
418
    "version 2.1 of the License, or (at your option) any later version.\n"
419
    "\n"
420
    "%s is distributed in the hope that it will be useful,\n"
421
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
422
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
423
    "Lesser General Public License for more details.\n"
424
    "\n"
425
    "You should have received a copy of the GNU Lesser General Public\n"
426
    "License along with %s; if not, write to the Free Software\n"
427
    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
428
    program_name, program_name, program_name
429
#endif
430
    );
431
}
432

    
433
void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
434
{
435
    int i;
436
    char fmt_str[128];
437
    for (i=-1; i < nb_fmts; i++) {
438
        get_fmt_string (fmt_str, sizeof(fmt_str), i);
439
        fprintf(stdout, "%s\n", fmt_str);
440
    }
441
}
442

    
443
void show_formats(void)
444
{
445
    AVInputFormat *ifmt=NULL;
446
    AVOutputFormat *ofmt=NULL;
447
    const char *last_name;
448

    
449
    printf(
450
        "File formats:\n"
451
        " D. = Demuxing supported\n"
452
        " .E = Muxing supported\n"
453
        " --\n");
454
    last_name= "000";
455
    for(;;){
456
        int decode=0;
457
        int encode=0;
458
        const char *name=NULL;
459
        const char *long_name=NULL;
460

    
461
        while((ofmt= av_oformat_next(ofmt))) {
462
            if((name == NULL || strcmp(ofmt->name, name)<0) &&
463
                strcmp(ofmt->name, last_name)>0){
464
                name= ofmt->name;
465
                long_name= ofmt->long_name;
466
                encode=1;
467
            }
468
        }
469
        while((ifmt= av_iformat_next(ifmt))) {
470
            if((name == NULL || strcmp(ifmt->name, name)<0) &&
471
                strcmp(ifmt->name, last_name)>0){
472
                name= ifmt->name;
473
                long_name= ifmt->long_name;
474
                encode=0;
475
            }
476
            if(name && strcmp(ifmt->name, name)==0)
477
                decode=1;
478
        }
479
        if(name==NULL)
480
            break;
481
        last_name= name;
482

    
483
        printf(
484
            " %s%s %-15s %s\n",
485
            decode ? "D":" ",
486
            encode ? "E":" ",
487
            name,
488
            long_name ? long_name:" ");
489
    }
490
}
491

    
492
void show_codecs(void)
493
{
494
    AVCodec *p=NULL, *p2;
495
    const char *last_name;
496
    printf(
497
        "Codecs:\n"
498
        " D..... = Decoding supported\n"
499
        " .E.... = Encoding supported\n"
500
        " ..V... = Video codec\n"
501
        " ..A... = Audio codec\n"
502
        " ..S... = Subtitle codec\n"
503
        " ...S.. = Supports draw_horiz_band\n"
504
        " ....D. = Supports direct rendering method 1\n"
505
        " .....T = Supports weird frame truncation\n"
506
        " ------\n");
507
    last_name= "000";
508
    for(;;){
509
        int decode=0;
510
        int encode=0;
511
        int cap=0;
512
        const char *type_str;
513

    
514
        p2=NULL;
515
        while((p= av_codec_next(p))) {
516
            if((p2==NULL || strcmp(p->name, p2->name)<0) &&
517
                strcmp(p->name, last_name)>0){
518
                p2= p;
519
                decode= encode= cap=0;
520
            }
521
            if(p2 && strcmp(p->name, p2->name)==0){
522
                if(p->decode) decode=1;
523
                if(p->encode) encode=1;
524
                cap |= p->capabilities;
525
            }
526
        }
527
        if(p2==NULL)
528
            break;
529
        last_name= p2->name;
530

    
531
        switch(p2->type) {
532
        case CODEC_TYPE_VIDEO:
533
            type_str = "V";
534
            break;
535
        case CODEC_TYPE_AUDIO:
536
            type_str = "A";
537
            break;
538
        case CODEC_TYPE_SUBTITLE:
539
            type_str = "S";
540
            break;
541
        default:
542
            type_str = "?";
543
            break;
544
        }
545
        printf(
546
            " %s%s%s%s%s%s %-15s %s",
547
            decode ? "D": (/*p2->decoder ? "d":*/" "),
548
            encode ? "E":" ",
549
            type_str,
550
            cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
551
            cap & CODEC_CAP_DR1 ? "D":" ",
552
            cap & CODEC_CAP_TRUNCATED ? "T":" ",
553
            p2->name,
554
            p2->long_name ? p2->long_name : "");
555
       /* if(p2->decoder && decode==0)
556
            printf(" use %s for decoding", p2->decoder->name);*/
557
        printf("\n");
558
    }
559
    printf("\n");
560
    printf(
561
"Note, the names of encoders and decoders do not always match, so there are\n"
562
"several cases where the above table shows encoder only or decoder only entries\n"
563
"even though both encoding and decoding are supported. For example, the h263\n"
564
"decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
565
"worse.\n");
566
}
567

    
568
void show_bsfs(void)
569
{
570
    AVBitStreamFilter *bsf=NULL;
571

    
572
    printf("Bitstream filters:\n");
573
    while((bsf = av_bitstream_filter_next(bsf)))
574
        printf("%s\n", bsf->name);
575
    printf("\n");
576
}
577

    
578
void show_protocols(void)
579
{
580
    URLProtocol *up=NULL;
581

    
582
    printf("Supported file protocols:\n");
583
    while((up = av_protocol_next(up)))
584
        printf("%s\n", up->name);
585
    printf("\n");
586

    
587
    printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
588
}
589

    
590
void show_filters(void)
591
{
592
    AVFilter av_unused(**filter) = NULL;
593

    
594
    printf("Filters:\n");
595
#if CONFIG_AVFILTER
596
    while ((filter = av_filter_next(filter)) && *filter)
597
        printf("%-16s %s\n", (*filter)->name, (*filter)->description);
598
#endif
599
}
600

    
601
void show_pix_fmts(void)
602
{
603
    list_fmts(avcodec_pix_fmt_string, PIX_FMT_NB);
604
}
605

    
606
int read_yesno(void)
607
{
608
    int c = getchar();
609
    int yesno = (toupper(c) == 'Y');
610

    
611
    while (c != '\n' && c != EOF)
612
        c = getchar();
613

    
614
    return yesno;
615
}