]> git.sesse.net Git - ffmpeg/blob - cmdutils.c
d02b36e66e51e2d3daaeebfab3483394541a15db
[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 "libavutil/pixdesc.h"
39 #include "libavcodec/opt.h"
40 #include "cmdutils.h"
41 #include "version.h"
42 #if CONFIG_NETWORK
43 #include "libavformat/network.h"
44 #endif
45 #if HAVE_SYS_RESOURCE_H
46 #include <sys/resource.h>
47 #endif
48
49 const char **opt_names;
50 static int opt_name_count;
51 AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
52 AVFormatContext *avformat_opts;
53 struct SwsContext *sws_opts;
54
55 const int this_year = 2010;
56
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 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 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
86 {
87     const OptionDef *po;
88     int first;
89
90     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             av_strlcpy(buf, po->name, sizeof(buf));
99             if (po->flags & HAS_ARG) {
100                 av_strlcat(buf, " ", sizeof(buf));
101                 av_strlcat(buf, po->argname, sizeof(buf));
102             }
103             printf("-%-17s  %s\n", buf, po->help);
104         }
105     }
106 }
107
108 static const OptionDef* find_option(const OptionDef *po, const char *name){
109     while (po->name != NULL) {
110         if (!strcmp(name, po->name))
111             break;
112         po++;
113     }
114     return po;
115 }
116
117 void parse_options(int argc, char **argv, const OptionDef *options,
118                    void (* parse_arg_function)(const char*))
119 {
120     const char *opt, *arg;
121     int optindex, handleoptions=1;
122     const OptionDef *po;
123
124     /* parse options */
125     optindex = 1;
126     while (optindex < argc) {
127         opt = argv[optindex++];
128
129         if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
130             int bool_val = 1;
131             if (opt[1] == '-' && opt[2] == '\0') {
132                 handleoptions = 0;
133                 continue;
134             }
135             opt++;
136             po= find_option(options, opt);
137             if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
138                 /* handle 'no' bool option */
139                 po = find_option(options, opt + 2);
140                 if (!(po->name && (po->flags & OPT_BOOL)))
141                     goto unknown_opt;
142                 bool_val = 0;
143             }
144             if (!po->name)
145                 po= find_option(options, "default");
146             if (!po->name) {
147 unknown_opt:
148                 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
149                 exit(1);
150             }
151             arg = NULL;
152             if (po->flags & HAS_ARG) {
153                 arg = argv[optindex++];
154                 if (!arg) {
155                     fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
156                     exit(1);
157                 }
158             }
159             if (po->flags & OPT_STRING) {
160                 char *str;
161                 str = av_strdup(arg);
162                 *po->u.str_arg = str;
163             } else if (po->flags & OPT_BOOL) {
164                 *po->u.int_arg = bool_val;
165             } else if (po->flags & OPT_INT) {
166                 *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
167             } else if (po->flags & OPT_INT64) {
168                 *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
169             } else if (po->flags & OPT_FLOAT) {
170                 *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
171             } else if (po->flags & OPT_FUNC2) {
172                 if (po->u.func2_arg(opt, arg) < 0) {
173                     fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
174                     exit(1);
175                 }
176             } else {
177                 po->u.func_arg(arg);
178             }
179             if(po->flags & OPT_EXIT)
180                 exit(0);
181         } else {
182             if (parse_arg_function)
183                 parse_arg_function(opt);
184         }
185     }
186 }
187
188 int opt_default(const char *opt, const char *arg){
189     int type;
190     int ret= 0;
191     const AVOption *o= NULL;
192     int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
193
194     for(type=0; type<AVMEDIA_TYPE_NB && ret>= 0; type++){
195         const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
196         if(o2)
197             ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
198     }
199     if(!o)
200         ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
201     if(!o && sws_opts)
202         ret = av_set_string3(sws_opts, opt, arg, 1, &o);
203     if(!o){
204         if(opt[0] == 'a')
205             ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o);
206         else if(opt[0] == 'v')
207             ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
208         else if(opt[0] == 's')
209             ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
210     }
211     if (o && ret < 0) {
212         fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
213         exit(1);
214     }
215     if (!o) {
216         fprintf(stderr, "Unrecognized option '%s'\n", opt);
217         exit(1);
218     }
219
220 //    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));
221
222     //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
223     opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
224     opt_names[opt_name_count++]= o->name;
225
226     if(avcodec_opts[0]->debug || avformat_opts->debug)
227         av_log_set_level(AV_LOG_DEBUG);
228     return 0;
229 }
230
231 int opt_loglevel(const char *opt, const char *arg)
232 {
233     const struct { const char *name; int level; } log_levels[] = {
234         { "quiet"  , AV_LOG_QUIET   },
235         { "panic"  , AV_LOG_PANIC   },
236         { "fatal"  , AV_LOG_FATAL   },
237         { "error"  , AV_LOG_ERROR   },
238         { "warning", AV_LOG_WARNING },
239         { "info"   , AV_LOG_INFO    },
240         { "verbose", AV_LOG_VERBOSE },
241         { "debug"  , AV_LOG_DEBUG   },
242     };
243     char *tail;
244     int level;
245     int i;
246
247     for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
248         if (!strcmp(log_levels[i].name, arg)) {
249             av_log_set_level(log_levels[i].level);
250             return 0;
251         }
252     }
253
254     level = strtol(arg, &tail, 10);
255     if (*tail) {
256         fprintf(stderr, "Invalid loglevel \"%s\". "
257                         "Possible levels are numbers or:\n", arg);
258         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
259             fprintf(stderr, "\"%s\"\n", log_levels[i].name);
260         exit(1);
261     }
262     av_log_set_level(level);
263     return 0;
264 }
265
266 int opt_timelimit(const char *opt, const char *arg)
267 {
268 #if HAVE_SETRLIMIT
269     int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
270     struct rlimit rl = { lim, lim + 1 };
271     if (setrlimit(RLIMIT_CPU, &rl))
272         perror("setrlimit");
273 #else
274     fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
275 #endif
276     return 0;
277 }
278
279 void set_context_opts(void *ctx, void *opts_ctx, int flags)
280 {
281     int i;
282     for(i=0; i<opt_name_count; i++){
283         char buf[256];
284         const AVOption *opt;
285         const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
286         /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
287         if(str && ((opt->flags & flags) == flags))
288             av_set_string3(ctx, opt_names[i], str, 1, NULL);
289     }
290 }
291
292 void print_error(const char *filename, int err)
293 {
294     char errbuf[128];
295     const char *errbuf_ptr = errbuf;
296
297     switch(err) {
298 #if CONFIG_NETWORK
299     case FF_NETERROR(EPROTONOSUPPORT):
300         fprintf(stderr, "%s: Unsupported network protocol\n", filename);
301         break;
302 #endif
303     default:
304         if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
305             errbuf_ptr = strerror(AVUNERROR(err));
306         fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
307     }
308 }
309
310 #define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent)             \
311     if (CONFIG_##LIBNAME) {                                             \
312         unsigned int version = libname##_version();                     \
313         fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n",    \
314                 indent? "  " : "", #libname,                            \
315                 LIB##LIBNAME##_VERSION_MAJOR,                           \
316                 LIB##LIBNAME##_VERSION_MINOR,                           \
317                 LIB##LIBNAME##_VERSION_MICRO,                           \
318                 version >> 16, version >> 8 & 0xff, version & 0xff);    \
319     }
320
321 static void print_all_lib_versions(FILE* outstream, int indent)
322 {
323     PRINT_LIB_VERSION(outstream, avutil,   AVUTIL,   indent);
324     PRINT_LIB_VERSION(outstream, avcodec,  AVCODEC,  indent);
325     PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
326     PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
327     PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
328     PRINT_LIB_VERSION(outstream, swscale,  SWSCALE,  indent);
329     PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent);
330 }
331
332 static void maybe_print_config(const char *lib, const char *cfg)
333 {
334     static int warned_cfg;
335
336     if (strcmp(FFMPEG_CONFIGURATION, cfg)) {
337         if (!warned_cfg) {
338             fprintf(stderr, "  WARNING: library configuration mismatch\n");
339             warned_cfg = 1;
340         }
341         fprintf(stderr, "  %-11s configuration: %s\n", lib, cfg);
342     }
343 }
344
345 #define PRINT_LIB_CONFIG(lib, tag, cfg) do {    \
346         if (CONFIG_##lib)                       \
347             maybe_print_config(tag, cfg);       \
348     } while (0)
349
350 void show_banner(void)
351 {
352     fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n",
353             program_name, program_birth_year, this_year);
354     fprintf(stderr, "  built on %s %s with %s %s\n",
355             __DATE__, __TIME__, CC_TYPE, CC_VERSION);
356     fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
357     PRINT_LIB_CONFIG(AVUTIL,   "libavutil",   avutil_configuration());
358     PRINT_LIB_CONFIG(AVCODEC,  "libavcodec",  avcodec_configuration());
359     PRINT_LIB_CONFIG(AVFORMAT, "libavformat", avformat_configuration());
360     PRINT_LIB_CONFIG(AVDEVICE, "libavdevice", avdevice_configuration());
361     PRINT_LIB_CONFIG(AVFILTER, "libavfilter", avfilter_configuration());
362     PRINT_LIB_CONFIG(SWSCALE,  "libswscale",  swscale_configuration());
363     PRINT_LIB_CONFIG(POSTPROC, "libpostproc", postproc_configuration());
364     print_all_lib_versions(stderr, 1);
365 }
366
367 void show_version(void) {
368     printf("%s " FFMPEG_VERSION "\n", program_name);
369     print_all_lib_versions(stdout, 0);
370 }
371
372 void show_license(void)
373 {
374     printf(
375 #if CONFIG_NONFREE
376     "This version of %s has nonfree parts compiled in.\n"
377     "Therefore it is not legally redistributable.\n",
378     program_name
379 #elif CONFIG_GPLV3
380     "%s is free software; you can redistribute it and/or modify\n"
381     "it under the terms of the GNU General Public License as published by\n"
382     "the Free Software Foundation; either version 3 of the License, or\n"
383     "(at your option) any later version.\n"
384     "\n"
385     "%s is distributed in the hope that it will be useful,\n"
386     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
387     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
388     "GNU General Public License for more details.\n"
389     "\n"
390     "You should have received a copy of the GNU General Public License\n"
391     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
392     program_name, program_name, program_name
393 #elif CONFIG_GPL
394     "%s is free software; you can redistribute it and/or modify\n"
395     "it under the terms of the GNU General Public License as published by\n"
396     "the Free Software Foundation; either version 2 of the License, or\n"
397     "(at your option) any later version.\n"
398     "\n"
399     "%s is distributed in the hope that it will be useful,\n"
400     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
401     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
402     "GNU General Public License for more details.\n"
403     "\n"
404     "You should have received a copy of the GNU General Public License\n"
405     "along with %s; if not, write to the Free Software\n"
406     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
407     program_name, program_name, program_name
408 #elif CONFIG_LGPLV3
409     "%s is free software; you can redistribute it and/or modify\n"
410     "it under the terms of the GNU Lesser General Public License as published by\n"
411     "the Free Software Foundation; either version 3 of the License, or\n"
412     "(at your option) any later version.\n"
413     "\n"
414     "%s is distributed in the hope that it will be useful,\n"
415     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
416     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
417     "GNU Lesser General Public License for more details.\n"
418     "\n"
419     "You should have received a copy of the GNU Lesser General Public License\n"
420     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
421     program_name, program_name, program_name
422 #else
423     "%s is free software; you can redistribute it and/or\n"
424     "modify it under the terms of the GNU Lesser General Public\n"
425     "License as published by the Free Software Foundation; either\n"
426     "version 2.1 of the License, or (at your option) any later version.\n"
427     "\n"
428     "%s is distributed in the hope that it will be useful,\n"
429     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
430     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
431     "Lesser General Public License for more details.\n"
432     "\n"
433     "You should have received a copy of the GNU Lesser General Public\n"
434     "License along with %s; if not, write to the Free Software\n"
435     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
436     program_name, program_name, program_name
437 #endif
438     );
439 }
440
441 void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
442 {
443     int i;
444     char fmt_str[128];
445     for (i=-1; i < nb_fmts; i++) {
446         get_fmt_string (fmt_str, sizeof(fmt_str), i);
447         fprintf(stdout, "%s\n", fmt_str);
448     }
449 }
450
451 void show_formats(void)
452 {
453     AVInputFormat *ifmt=NULL;
454     AVOutputFormat *ofmt=NULL;
455     const char *last_name;
456
457     printf(
458         "File formats:\n"
459         " D. = Demuxing supported\n"
460         " .E = Muxing supported\n"
461         " --\n");
462     last_name= "000";
463     for(;;){
464         int decode=0;
465         int encode=0;
466         const char *name=NULL;
467         const char *long_name=NULL;
468
469         while((ofmt= av_oformat_next(ofmt))) {
470             if((name == NULL || strcmp(ofmt->name, name)<0) &&
471                 strcmp(ofmt->name, last_name)>0){
472                 name= ofmt->name;
473                 long_name= ofmt->long_name;
474                 encode=1;
475             }
476         }
477         while((ifmt= av_iformat_next(ifmt))) {
478             if((name == NULL || strcmp(ifmt->name, name)<0) &&
479                 strcmp(ifmt->name, last_name)>0){
480                 name= ifmt->name;
481                 long_name= ifmt->long_name;
482                 encode=0;
483             }
484             if(name && strcmp(ifmt->name, name)==0)
485                 decode=1;
486         }
487         if(name==NULL)
488             break;
489         last_name= name;
490
491         printf(
492             " %s%s %-15s %s\n",
493             decode ? "D":" ",
494             encode ? "E":" ",
495             name,
496             long_name ? long_name:" ");
497     }
498 }
499
500 void show_codecs(void)
501 {
502     AVCodec *p=NULL, *p2;
503     const char *last_name;
504     printf(
505         "Codecs:\n"
506         " D..... = Decoding supported\n"
507         " .E.... = Encoding supported\n"
508         " ..V... = Video codec\n"
509         " ..A... = Audio codec\n"
510         " ..S... = Subtitle codec\n"
511         " ...S.. = Supports draw_horiz_band\n"
512         " ....D. = Supports direct rendering method 1\n"
513         " .....T = Supports weird frame truncation\n"
514         " ------\n");
515     last_name= "000";
516     for(;;){
517         int decode=0;
518         int encode=0;
519         int cap=0;
520         const char *type_str;
521
522         p2=NULL;
523         while((p= av_codec_next(p))) {
524             if((p2==NULL || strcmp(p->name, p2->name)<0) &&
525                 strcmp(p->name, last_name)>0){
526                 p2= p;
527                 decode= encode= cap=0;
528             }
529             if(p2 && strcmp(p->name, p2->name)==0){
530                 if(p->decode) decode=1;
531                 if(p->encode) encode=1;
532                 cap |= p->capabilities;
533             }
534         }
535         if(p2==NULL)
536             break;
537         last_name= p2->name;
538
539         switch(p2->type) {
540         case AVMEDIA_TYPE_VIDEO:
541             type_str = "V";
542             break;
543         case AVMEDIA_TYPE_AUDIO:
544             type_str = "A";
545             break;
546         case AVMEDIA_TYPE_SUBTITLE:
547             type_str = "S";
548             break;
549         default:
550             type_str = "?";
551             break;
552         }
553         printf(
554             " %s%s%s%s%s%s %-15s %s",
555             decode ? "D": (/*p2->decoder ? "d":*/" "),
556             encode ? "E":" ",
557             type_str,
558             cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
559             cap & CODEC_CAP_DR1 ? "D":" ",
560             cap & CODEC_CAP_TRUNCATED ? "T":" ",
561             p2->name,
562             p2->long_name ? p2->long_name : "");
563        /* if(p2->decoder && decode==0)
564             printf(" use %s for decoding", p2->decoder->name);*/
565         printf("\n");
566     }
567     printf("\n");
568     printf(
569 "Note, the names of encoders and decoders do not always match, so there are\n"
570 "several cases where the above table shows encoder only or decoder only entries\n"
571 "even though both encoding and decoding are supported. For example, the h263\n"
572 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
573 "worse.\n");
574 }
575
576 void show_bsfs(void)
577 {
578     AVBitStreamFilter *bsf=NULL;
579
580     printf("Bitstream filters:\n");
581     while((bsf = av_bitstream_filter_next(bsf)))
582         printf("%s\n", bsf->name);
583     printf("\n");
584 }
585
586 void show_protocols(void)
587 {
588     URLProtocol *up=NULL;
589
590     printf("Supported file protocols:\n");
591     while((up = av_protocol_next(up)))
592         printf("%s\n", up->name);
593 }
594
595 void show_filters(void)
596 {
597     AVFilter av_unused(**filter) = NULL;
598
599     printf("Filters:\n");
600 #if CONFIG_AVFILTER
601     while ((filter = av_filter_next(filter)) && *filter)
602         printf("%-16s %s\n", (*filter)->name, (*filter)->description);
603 #endif
604 }
605
606 void show_pix_fmts(void)
607 {
608     enum PixelFormat pix_fmt;
609
610     printf(
611         "Pixel formats:\n"
612         "I.... = Supported Input  format for conversion\n"
613         ".O... = Supported Output format for conversion\n"
614         "..H.. = Hardware accelerated format\n"
615         "...P. = Paletted format\n"
616         "....B = Bitstream format\n"
617         "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL\n"
618         "-----\n");
619
620     for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
621         const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
622         printf("%c%c%c%c%c %-16s       %d            %2d\n",
623                sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
624                sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
625                pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
626                pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
627                pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
628                pix_desc->name,
629                pix_desc->nb_components,
630                av_get_bits_per_pixel(pix_desc));
631     }
632 }
633
634 int read_yesno(void)
635 {
636     int c = getchar();
637     int yesno = (toupper(c) == 'Y');
638
639     while (c != '\n' && c != EOF)
640         c = getchar();
641
642     return yesno;
643 }
644
645 int read_file(const char *filename, char **bufptr, size_t *size)
646 {
647     FILE *f = fopen(filename, "r");
648
649     if (!f) {
650         fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
651         return AVERROR(errno);
652     }
653     fseek(f, 0, SEEK_END);
654     *size = ftell(f);
655     fseek(f, 0, SEEK_SET);
656     *bufptr = av_malloc(*size + 1);
657     if (!*bufptr) {
658         fprintf(stderr, "Could not allocate file buffer\n");
659         fclose(f);
660         return AVERROR(ENOMEM);
661     }
662     fread(*bufptr, 1, *size, f);
663     (*bufptr)[*size++] = '\0';
664
665     fclose(f);
666     return 0;
667 }