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