]> git.sesse.net Git - ffmpeg/blob - cmdutils.c
Fix svq3_* function declarations.
[ffmpeg] / cmdutils.c
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     if (CONFIG_##LIBNAME) {                                             \
329         version= libname##_version();                                   \
330         fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n",    \
331                 indent? "  " : "", #libname,                            \
332                 LIB##LIBNAME##_VERSION_MAJOR,                           \
333                 LIB##LIBNAME##_VERSION_MINOR,                           \
334                 LIB##LIBNAME##_VERSION_MICRO,                           \
335                 version >> 16, version >> 8 & 0xff, version & 0xff);    \
336     }
337
338 static void print_all_lib_versions(FILE* outstream, int indent)
339 {
340     unsigned int version;
341     PRINT_LIB_VERSION(outstream, avutil,   AVUTIL,   indent);
342     PRINT_LIB_VERSION(outstream, avcodec,  AVCODEC,  indent);
343     PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
344     PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
345     PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
346     PRINT_LIB_VERSION(outstream, swscale,  SWSCALE,  indent);
347     PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent);
348 }
349
350 static void maybe_print_config(const char *lib, const char *cfg)
351 {
352     static int warned_cfg;
353
354     if (strcmp(FFMPEG_CONFIGURATION, cfg)) {
355         if (!warned_cfg) {
356             fprintf(stderr, "  WARNING: library configuration mismatch\n");
357             warned_cfg = 1;
358         }
359         fprintf(stderr, "  %-11s configuration: %s\n", lib, cfg);
360     }
361 }
362
363 #define PRINT_LIB_CONFIG(lib, tag, cfg) do {    \
364         if (CONFIG_##lib)                       \
365             maybe_print_config(tag, cfg);       \
366     } while (0)
367
368 void show_banner(void)
369 {
370     fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d Fabrice Bellard, et al.\n",
371             program_name, program_birth_year, this_year);
372     fprintf(stderr, "  built on %s %s with %s %s\n",
373             __DATE__, __TIME__, CC_TYPE, CC_VERSION);
374     fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
375     PRINT_LIB_CONFIG(AVUTIL,   "libavutil",   avutil_configuration());
376     PRINT_LIB_CONFIG(AVCODEC,  "libavcodec",  avcodec_configuration());
377     PRINT_LIB_CONFIG(AVFORMAT, "libavformat", avformat_configuration());
378     PRINT_LIB_CONFIG(AVDEVICE, "libavdevice", avdevice_configuration());
379     PRINT_LIB_CONFIG(AVFILTER, "libavfilter", avfilter_configuration());
380     PRINT_LIB_CONFIG(SWSCALE,  "libswscale",  swscale_configuration());
381     PRINT_LIB_CONFIG(POSTPROC, "libpostproc", postproc_configuration());
382     print_all_lib_versions(stderr, 1);
383 }
384
385 void show_version(void) {
386     printf("%s " FFMPEG_VERSION "\n", program_name);
387     print_all_lib_versions(stdout, 0);
388 }
389
390 void show_license(void)
391 {
392     printf(
393 #if CONFIG_NONFREE
394     "This version of %s has nonfree parts compiled in.\n"
395     "Therefore it is not legally redistributable.\n",
396     program_name
397 #elif CONFIG_GPLV3
398     "%s is free software; you can redistribute it and/or modify\n"
399     "it under the terms of the GNU General Public License as published by\n"
400     "the Free Software Foundation; either version 3 of the License, or\n"
401     "(at your option) any later version.\n"
402     "\n"
403     "%s is distributed in the hope that it will be useful,\n"
404     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
405     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
406     "GNU General Public License for more details.\n"
407     "\n"
408     "You should have received a copy of the GNU General Public License\n"
409     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
410     program_name, program_name, program_name
411 #elif CONFIG_GPL
412     "%s is free software; you can redistribute it and/or modify\n"
413     "it under the terms of the GNU General Public License as published by\n"
414     "the Free Software Foundation; either version 2 of the License, or\n"
415     "(at your option) any later version.\n"
416     "\n"
417     "%s is distributed in the hope that it will be useful,\n"
418     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
419     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
420     "GNU General Public License for more details.\n"
421     "\n"
422     "You should have received a copy of the GNU General Public License\n"
423     "along with %s; if not, write to the Free Software\n"
424     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
425     program_name, program_name, program_name
426 #elif CONFIG_LGPLV3
427     "%s is free software; you can redistribute it and/or modify\n"
428     "it under the terms of the GNU Lesser General Public License as published by\n"
429     "the Free Software Foundation; either version 3 of the License, or\n"
430     "(at your option) any later version.\n"
431     "\n"
432     "%s is distributed in the hope that it will be useful,\n"
433     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
434     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
435     "GNU Lesser General Public License for more details.\n"
436     "\n"
437     "You should have received a copy of the GNU Lesser General Public License\n"
438     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
439     program_name, program_name, program_name
440 #else
441     "%s is free software; you can redistribute it and/or\n"
442     "modify it under the terms of the GNU Lesser General Public\n"
443     "License as published by the Free Software Foundation; either\n"
444     "version 2.1 of the License, or (at your option) any later version.\n"
445     "\n"
446     "%s is distributed in the hope that it will be useful,\n"
447     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
448     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
449     "Lesser General Public License for more details.\n"
450     "\n"
451     "You should have received a copy of the GNU Lesser General Public\n"
452     "License along with %s; if not, write to the Free Software\n"
453     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
454     program_name, program_name, program_name
455 #endif
456     );
457 }
458
459 void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
460 {
461     int i;
462     char fmt_str[128];
463     for (i=-1; i < nb_fmts; i++) {
464         get_fmt_string (fmt_str, sizeof(fmt_str), i);
465         fprintf(stdout, "%s\n", fmt_str);
466     }
467 }
468
469 void show_formats(void)
470 {
471     AVInputFormat *ifmt=NULL;
472     AVOutputFormat *ofmt=NULL;
473     const char *last_name;
474
475     printf(
476         "File formats:\n"
477         " D. = Demuxing supported\n"
478         " .E = Muxing supported\n"
479         " --\n");
480     last_name= "000";
481     for(;;){
482         int decode=0;
483         int encode=0;
484         const char *name=NULL;
485         const char *long_name=NULL;
486
487         while((ofmt= av_oformat_next(ofmt))) {
488             if((name == NULL || strcmp(ofmt->name, name)<0) &&
489                 strcmp(ofmt->name, last_name)>0){
490                 name= ofmt->name;
491                 long_name= ofmt->long_name;
492                 encode=1;
493             }
494         }
495         while((ifmt= av_iformat_next(ifmt))) {
496             if((name == NULL || strcmp(ifmt->name, name)<0) &&
497                 strcmp(ifmt->name, last_name)>0){
498                 name= ifmt->name;
499                 long_name= ifmt->long_name;
500                 encode=0;
501             }
502             if(name && strcmp(ifmt->name, name)==0)
503                 decode=1;
504         }
505         if(name==NULL)
506             break;
507         last_name= name;
508
509         printf(
510             " %s%s %-15s %s\n",
511             decode ? "D":" ",
512             encode ? "E":" ",
513             name,
514             long_name ? long_name:" ");
515     }
516 }
517
518 void show_codecs(void)
519 {
520     AVCodec *p=NULL, *p2;
521     const char *last_name;
522     printf(
523         "Codecs:\n"
524         " D..... = Decoding supported\n"
525         " .E.... = Encoding supported\n"
526         " ..V... = Video codec\n"
527         " ..A... = Audio codec\n"
528         " ..S... = Subtitle codec\n"
529         " ...S.. = Supports draw_horiz_band\n"
530         " ....D. = Supports direct rendering method 1\n"
531         " .....T = Supports weird frame truncation\n"
532         " ------\n");
533     last_name= "000";
534     for(;;){
535         int decode=0;
536         int encode=0;
537         int cap=0;
538         const char *type_str;
539
540         p2=NULL;
541         while((p= av_codec_next(p))) {
542             if((p2==NULL || strcmp(p->name, p2->name)<0) &&
543                 strcmp(p->name, last_name)>0){
544                 p2= p;
545                 decode= encode= cap=0;
546             }
547             if(p2 && strcmp(p->name, p2->name)==0){
548                 if(p->decode) decode=1;
549                 if(p->encode) encode=1;
550                 cap |= p->capabilities;
551             }
552         }
553         if(p2==NULL)
554             break;
555         last_name= p2->name;
556
557         switch(p2->type) {
558         case CODEC_TYPE_VIDEO:
559             type_str = "V";
560             break;
561         case CODEC_TYPE_AUDIO:
562             type_str = "A";
563             break;
564         case CODEC_TYPE_SUBTITLE:
565             type_str = "S";
566             break;
567         default:
568             type_str = "?";
569             break;
570         }
571         printf(
572             " %s%s%s%s%s%s %-15s %s",
573             decode ? "D": (/*p2->decoder ? "d":*/" "),
574             encode ? "E":" ",
575             type_str,
576             cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
577             cap & CODEC_CAP_DR1 ? "D":" ",
578             cap & CODEC_CAP_TRUNCATED ? "T":" ",
579             p2->name,
580             p2->long_name ? p2->long_name : "");
581        /* if(p2->decoder && decode==0)
582             printf(" use %s for decoding", p2->decoder->name);*/
583         printf("\n");
584     }
585     printf("\n");
586     printf(
587 "Note, the names of encoders and decoders do not always match, so there are\n"
588 "several cases where the above table shows encoder only or decoder only entries\n"
589 "even though both encoding and decoding are supported. For example, the h263\n"
590 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
591 "worse.\n");
592 }
593
594 void show_bsfs(void)
595 {
596     AVBitStreamFilter *bsf=NULL;
597
598     printf("Bitstream filters:\n");
599     while((bsf = av_bitstream_filter_next(bsf)))
600         printf("%s\n", bsf->name);
601     printf("\n");
602 }
603
604 void show_protocols(void)
605 {
606     URLProtocol *up=NULL;
607
608     printf("Supported file protocols:\n");
609     while((up = av_protocol_next(up)))
610         printf("%s\n", up->name);
611     printf("\n");
612
613     printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
614 }
615
616 void show_filters(void)
617 {
618     AVFilter av_unused(**filter) = NULL;
619
620     printf("Filters:\n");
621 #if CONFIG_AVFILTER
622     while ((filter = av_filter_next(filter)) && *filter)
623         printf("%-16s %s\n", (*filter)->name, (*filter)->description);
624 #endif
625 }
626
627 void show_pix_fmts(void)
628 {
629     list_fmts(avcodec_pix_fmt_string, PIX_FMT_NB);
630 }
631
632 int read_yesno(void)
633 {
634     int c = getchar();
635     int yesno = (toupper(c) == 'Y');
636
637     while (c != '\n' && c != EOF)
638         c = getchar();
639
640     return yesno;
641 }