cmdutils: add codec_opts parameter to setup_find_stream_info_opts()
[ffmpeg.git] / cmdutils.c
1 /*
2  * Various utilities for command line tools
3  * Copyright (c) 2000-2003 Fabrice Bellard
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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/parseutils.h"
39 #include "libavutil/pixdesc.h"
40 #include "libavutil/eval.h"
41 #include "libavutil/dict.h"
42 #include "libavutil/opt.h"
43 #include "cmdutils.h"
44 #include "version.h"
45 #if CONFIG_NETWORK
46 #include "libavformat/network.h"
47 #endif
48 #if HAVE_SYS_RESOURCE_H
49 #include <sys/resource.h>
50 #endif
51
52 AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
53 AVFormatContext *avformat_opts;
54 struct SwsContext *sws_opts;
55 AVDictionary *format_opts, *codec_opts;
56
57 static const int this_year = 2011;
58
59 void init_opts(void)
60 {
61     int i;
62     for (i = 0; i < AVMEDIA_TYPE_NB; i++)
63         avcodec_opts[i] = avcodec_alloc_context3(NULL);
64     avformat_opts = avformat_alloc_context();
65 #if CONFIG_SWSCALE
66     sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
67 #endif
68 }
69
70 void uninit_opts(void)
71 {
72     int i;
73     for (i = 0; i < AVMEDIA_TYPE_NB; i++)
74         av_freep(&avcodec_opts[i]);
75     av_freep(&avformat_opts->key);
76     av_freep(&avformat_opts);
77 #if CONFIG_SWSCALE
78     sws_freeContext(sws_opts);
79     sws_opts = NULL;
80 #endif
81     av_dict_free(&format_opts);
82     av_dict_free(&codec_opts);
83 }
84
85 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
86 {
87     vfprintf(stdout, fmt, vl);
88 }
89
90 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
91 {
92     char *tail;
93     const char *error;
94     double d = av_strtod(numstr, &tail);
95     if (*tail)
96         error= "Expected number for %s but found: %s\n";
97     else if (d < min || d > max)
98         error= "The value for %s was %s which is not within %f - %f\n";
99     else if(type == OPT_INT64 && (int64_t)d != d)
100         error= "Expected int64 for %s but found %s\n";
101     else if (type == OPT_INT && (int)d != d)
102         error= "Expected int for %s but found %s\n";
103     else
104         return d;
105     fprintf(stderr, error, context, numstr, min, max);
106     exit(1);
107 }
108
109 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
110 {
111     int64_t us;
112     if (av_parse_time(&us, timestr, is_duration) < 0) {
113         fprintf(stderr, "Invalid %s specification for %s: %s\n",
114                 is_duration ? "duration" : "date", context, timestr);
115         exit(1);
116     }
117     return us;
118 }
119
120 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
121 {
122     const OptionDef *po;
123     int first;
124
125     first = 1;
126     for(po = options; po->name != NULL; po++) {
127         char buf[64];
128         if ((po->flags & mask) == value) {
129             if (first) {
130                 printf("%s", msg);
131                 first = 0;
132             }
133             av_strlcpy(buf, po->name, sizeof(buf));
134             if (po->flags & HAS_ARG) {
135                 av_strlcat(buf, " ", sizeof(buf));
136                 av_strlcat(buf, po->argname, sizeof(buf));
137             }
138             printf("-%-17s  %s\n", buf, po->help);
139         }
140     }
141 }
142
143 static const OptionDef* find_option(const OptionDef *po, const char *name){
144     while (po->name != NULL) {
145         if (!strcmp(name, po->name))
146             break;
147         po++;
148     }
149     return po;
150 }
151
152 #if defined(_WIN32) && !defined(__MINGW32CE__)
153 #include <windows.h>
154 /* Will be leaked on exit */
155 static char** win32_argv_utf8 = NULL;
156 static int win32_argc = 0;
157
158 /**
159  * Prepare command line arguments for executable.
160  * For Windows - perform wide-char to UTF-8 conversion.
161  * Input arguments should be main() function arguments.
162  * @param argc_ptr Arguments number (including executable)
163  * @param argv_ptr Arguments list.
164  */
165 static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
166 {
167     char *argstr_flat;
168     wchar_t **argv_w;
169     int i, buffsize = 0, offset = 0;
170
171     if (win32_argv_utf8) {
172         *argc_ptr = win32_argc;
173         *argv_ptr = win32_argv_utf8;
174         return;
175     }
176
177     win32_argc = 0;
178     argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
179     if (win32_argc <= 0 || !argv_w)
180         return;
181
182     /* determine the UTF-8 buffer size (including NULL-termination symbols) */
183     for (i = 0; i < win32_argc; i++)
184         buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
185                                         NULL, 0, NULL, NULL);
186
187     win32_argv_utf8 = av_mallocz(sizeof(char*) * (win32_argc + 1) + buffsize);
188     argstr_flat     = (char*)win32_argv_utf8 + sizeof(char*) * (win32_argc + 1);
189     if (win32_argv_utf8 == NULL) {
190         LocalFree(argv_w);
191         return;
192     }
193
194     for (i = 0; i < win32_argc; i++) {
195         win32_argv_utf8[i] = &argstr_flat[offset];
196         offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
197                                       &argstr_flat[offset],
198                                       buffsize - offset, NULL, NULL);
199     }
200     win32_argv_utf8[i] = NULL;
201     LocalFree(argv_w);
202
203     *argc_ptr = win32_argc;
204     *argv_ptr = win32_argv_utf8;
205 }
206 #else
207 static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
208 {
209     /* nothing to do */
210 }
211 #endif /* WIN32 && !__MINGW32CE__ */
212
213 void parse_options(int argc, char **argv, const OptionDef *options,
214                    void (* parse_arg_function)(const char*))
215 {
216     const char *opt, *arg;
217     int optindex, handleoptions=1;
218     const OptionDef *po;
219
220     /* perform system-dependent conversions for arguments list */
221     prepare_app_arguments(&argc, &argv);
222
223     /* parse options */
224     optindex = 1;
225     while (optindex < argc) {
226         opt = argv[optindex++];
227
228         if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
229             int bool_val = 1;
230             if (opt[1] == '-' && opt[2] == '\0') {
231                 handleoptions = 0;
232                 continue;
233             }
234             opt++;
235             po= find_option(options, opt);
236             if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
237                 /* handle 'no' bool option */
238                 po = find_option(options, opt + 2);
239                 if (!(po->name && (po->flags & OPT_BOOL)))
240                     goto unknown_opt;
241                 bool_val = 0;
242             }
243             if (!po->name)
244                 po= find_option(options, "default");
245             if (!po->name) {
246 unknown_opt:
247                 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
248                 exit(1);
249             }
250             arg = NULL;
251             if (po->flags & HAS_ARG) {
252                 arg = argv[optindex++];
253                 if (!arg) {
254                     fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
255                     exit(1);
256                 }
257             }
258             if (po->flags & OPT_STRING) {
259                 char *str;
260                 str = av_strdup(arg);
261                 *po->u.str_arg = str;
262             } else if (po->flags & OPT_BOOL) {
263                 *po->u.int_arg = bool_val;
264             } else if (po->flags & OPT_INT) {
265                 *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
266             } else if (po->flags & OPT_INT64) {
267                 *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
268             } else if (po->flags & OPT_FLOAT) {
269                 *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
270             } else if (po->u.func_arg) {
271                 if (po->u.func_arg(opt, arg) < 0) {
272                     fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
273                     exit(1);
274                 }
275             }
276             if(po->flags & OPT_EXIT)
277                 exit(0);
278         } else {
279             if (parse_arg_function)
280                 parse_arg_function(opt);
281         }
282     }
283 }
284
285 #define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
286 int opt_default(const char *opt, const char *arg)
287 {
288     const AVOption *o;
289     if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)) ||
290          ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
291           (o = av_opt_find(avcodec_opts[0], opt+1, NULL, 0, 0))))
292         av_dict_set(&codec_opts, opt, arg, FLAGS);
293     else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)))
294         av_dict_set(&format_opts, opt, arg, FLAGS);
295     else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
296         // XXX we only support sws_flags, not arbitrary sws options
297         int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
298         if (ret < 0) {
299             av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
300             return ret;
301         }
302     }
303
304     if (o)
305         return 0;
306     fprintf(stderr, "Unrecognized option '%s'\n", opt);
307     return AVERROR_OPTION_NOT_FOUND;
308 }
309
310 int opt_loglevel(const char *opt, const char *arg)
311 {
312     const struct { const char *name; int level; } log_levels[] = {
313         { "quiet"  , AV_LOG_QUIET   },
314         { "panic"  , AV_LOG_PANIC   },
315         { "fatal"  , AV_LOG_FATAL   },
316         { "error"  , AV_LOG_ERROR   },
317         { "warning", AV_LOG_WARNING },
318         { "info"   , AV_LOG_INFO    },
319         { "verbose", AV_LOG_VERBOSE },
320         { "debug"  , AV_LOG_DEBUG   },
321     };
322     char *tail;
323     int level;
324     int i;
325
326     for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
327         if (!strcmp(log_levels[i].name, arg)) {
328             av_log_set_level(log_levels[i].level);
329             return 0;
330         }
331     }
332
333     level = strtol(arg, &tail, 10);
334     if (*tail) {
335         fprintf(stderr, "Invalid loglevel \"%s\". "
336                         "Possible levels are numbers or:\n", arg);
337         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
338             fprintf(stderr, "\"%s\"\n", log_levels[i].name);
339         exit(1);
340     }
341     av_log_set_level(level);
342     return 0;
343 }
344
345 int opt_timelimit(const char *opt, const char *arg)
346 {
347 #if HAVE_SETRLIMIT
348     int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
349     struct rlimit rl = { lim, lim + 1 };
350     if (setrlimit(RLIMIT_CPU, &rl))
351         perror("setrlimit");
352 #else
353     fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
354 #endif
355     return 0;
356 }
357
358 void print_error(const char *filename, int err)
359 {
360     char errbuf[128];
361     const char *errbuf_ptr = errbuf;
362
363     if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
364         errbuf_ptr = strerror(AVUNERROR(err));
365     fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
366 }
367
368 static int warned_cfg = 0;
369
370 #define INDENT        1
371 #define SHOW_VERSION  2
372 #define SHOW_CONFIG   4
373
374 #define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags)                 \
375     if (CONFIG_##LIBNAME) {                                             \
376         const char *indent = flags & INDENT? "  " : "";                 \
377         if (flags & SHOW_VERSION) {                                     \
378             unsigned int version = libname##_version();                 \
379             fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
380                     indent, #libname,                                   \
381                     LIB##LIBNAME##_VERSION_MAJOR,                       \
382                     LIB##LIBNAME##_VERSION_MINOR,                       \
383                     LIB##LIBNAME##_VERSION_MICRO,                       \
384                     version >> 16, version >> 8 & 0xff, version & 0xff); \
385         }                                                               \
386         if (flags & SHOW_CONFIG) {                                      \
387             const char *cfg = libname##_configuration();                \
388             if (strcmp(LIBAV_CONFIGURATION, cfg)) {                     \
389                 if (!warned_cfg) {                                      \
390                     fprintf(outstream,                                  \
391                             "%sWARNING: library configuration mismatch\n", \
392                             indent);                                    \
393                     warned_cfg = 1;                                     \
394                 }                                                       \
395                 fprintf(stderr, "%s%-11s configuration: %s\n",          \
396                         indent, #libname, cfg);                         \
397             }                                                           \
398         }                                                               \
399     }                                                                   \
400
401 static void print_all_libs_info(FILE* outstream, int flags)
402 {
403     PRINT_LIB_INFO(outstream, avutil,   AVUTIL,   flags);
404     PRINT_LIB_INFO(outstream, avcodec,  AVCODEC,  flags);
405     PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
406     PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
407     PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
408     PRINT_LIB_INFO(outstream, swscale,  SWSCALE,  flags);
409     PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
410 }
411
412 void show_banner(void)
413 {
414     fprintf(stderr, "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
415             program_name, program_birth_year, this_year);
416     fprintf(stderr, "  built on %s %s with %s %s\n",
417             __DATE__, __TIME__, CC_TYPE, CC_VERSION);
418     fprintf(stderr, "  configuration: " LIBAV_CONFIGURATION "\n");
419     print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
420     print_all_libs_info(stderr, INDENT|SHOW_VERSION);
421 }
422
423 void show_version(void) {
424     printf("%s " LIBAV_VERSION "\n", program_name);
425     print_all_libs_info(stdout, SHOW_VERSION);
426 }
427
428 void show_license(void)
429 {
430     printf(
431 #if CONFIG_NONFREE
432     "This version of %s has nonfree parts compiled in.\n"
433     "Therefore it is not legally redistributable.\n",
434     program_name
435 #elif CONFIG_GPLV3
436     "%s is free software; you can redistribute it and/or modify\n"
437     "it under the terms of the GNU General Public License as published by\n"
438     "the Free Software Foundation; either version 3 of the License, or\n"
439     "(at your option) any later version.\n"
440     "\n"
441     "%s is distributed in the hope that it will be useful,\n"
442     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
443     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
444     "GNU General Public License for more details.\n"
445     "\n"
446     "You should have received a copy of the GNU General Public License\n"
447     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
448     program_name, program_name, program_name
449 #elif CONFIG_GPL
450     "%s is free software; you can redistribute it and/or modify\n"
451     "it under the terms of the GNU General Public License as published by\n"
452     "the Free Software Foundation; either version 2 of the License, or\n"
453     "(at your option) any later version.\n"
454     "\n"
455     "%s is distributed in the hope that it will be useful,\n"
456     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
457     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
458     "GNU General Public License for more details.\n"
459     "\n"
460     "You should have received a copy of the GNU General Public License\n"
461     "along with %s; if not, write to the Free Software\n"
462     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
463     program_name, program_name, program_name
464 #elif CONFIG_LGPLV3
465     "%s is free software; you can redistribute it and/or modify\n"
466     "it under the terms of the GNU Lesser General Public License as published by\n"
467     "the Free Software Foundation; either version 3 of the License, or\n"
468     "(at your option) any later version.\n"
469     "\n"
470     "%s is distributed in the hope that it will be useful,\n"
471     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
472     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
473     "GNU Lesser General Public License for more details.\n"
474     "\n"
475     "You should have received a copy of the GNU Lesser General Public License\n"
476     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
477     program_name, program_name, program_name
478 #else
479     "%s is free software; you can redistribute it and/or\n"
480     "modify it under the terms of the GNU Lesser General Public\n"
481     "License as published by the Free Software Foundation; either\n"
482     "version 2.1 of the License, or (at your option) any later version.\n"
483     "\n"
484     "%s is distributed in the hope that it will be useful,\n"
485     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
486     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
487     "Lesser General Public License for more details.\n"
488     "\n"
489     "You should have received a copy of the GNU Lesser General Public\n"
490     "License along with %s; if not, write to the Free Software\n"
491     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
492     program_name, program_name, program_name
493 #endif
494     );
495 }
496
497 void show_formats(void)
498 {
499     AVInputFormat *ifmt=NULL;
500     AVOutputFormat *ofmt=NULL;
501     const char *last_name;
502
503     printf(
504         "File formats:\n"
505         " D. = Demuxing supported\n"
506         " .E = Muxing supported\n"
507         " --\n");
508     last_name= "000";
509     for(;;){
510         int decode=0;
511         int encode=0;
512         const char *name=NULL;
513         const char *long_name=NULL;
514
515         while((ofmt= av_oformat_next(ofmt))) {
516             if((name == NULL || strcmp(ofmt->name, name)<0) &&
517                 strcmp(ofmt->name, last_name)>0){
518                 name= ofmt->name;
519                 long_name= ofmt->long_name;
520                 encode=1;
521             }
522         }
523         while((ifmt= av_iformat_next(ifmt))) {
524             if((name == NULL || strcmp(ifmt->name, name)<0) &&
525                 strcmp(ifmt->name, last_name)>0){
526                 name= ifmt->name;
527                 long_name= ifmt->long_name;
528                 encode=0;
529             }
530             if(name && strcmp(ifmt->name, name)==0)
531                 decode=1;
532         }
533         if(name==NULL)
534             break;
535         last_name= name;
536
537         printf(
538             " %s%s %-15s %s\n",
539             decode ? "D":" ",
540             encode ? "E":" ",
541             name,
542             long_name ? long_name:" ");
543     }
544 }
545
546 void show_codecs(void)
547 {
548     AVCodec *p=NULL, *p2;
549     const char *last_name;
550     printf(
551         "Codecs:\n"
552         " D..... = Decoding supported\n"
553         " .E.... = Encoding supported\n"
554         " ..V... = Video codec\n"
555         " ..A... = Audio codec\n"
556         " ..S... = Subtitle codec\n"
557         " ...S.. = Supports draw_horiz_band\n"
558         " ....D. = Supports direct rendering method 1\n"
559         " .....T = Supports weird frame truncation\n"
560         " ------\n");
561     last_name= "000";
562     for(;;){
563         int decode=0;
564         int encode=0;
565         int cap=0;
566         const char *type_str;
567
568         p2=NULL;
569         while((p= av_codec_next(p))) {
570             if((p2==NULL || strcmp(p->name, p2->name)<0) &&
571                 strcmp(p->name, last_name)>0){
572                 p2= p;
573                 decode= encode= cap=0;
574             }
575             if(p2 && strcmp(p->name, p2->name)==0){
576                 if(p->decode) decode=1;
577                 if(p->encode) encode=1;
578                 cap |= p->capabilities;
579             }
580         }
581         if(p2==NULL)
582             break;
583         last_name= p2->name;
584
585         switch(p2->type) {
586         case AVMEDIA_TYPE_VIDEO:
587             type_str = "V";
588             break;
589         case AVMEDIA_TYPE_AUDIO:
590             type_str = "A";
591             break;
592         case AVMEDIA_TYPE_SUBTITLE:
593             type_str = "S";
594             break;
595         default:
596             type_str = "?";
597             break;
598         }
599         printf(
600             " %s%s%s%s%s%s %-15s %s",
601             decode ? "D": (/*p2->decoder ? "d":*/" "),
602             encode ? "E":" ",
603             type_str,
604             cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
605             cap & CODEC_CAP_DR1 ? "D":" ",
606             cap & CODEC_CAP_TRUNCATED ? "T":" ",
607             p2->name,
608             p2->long_name ? p2->long_name : "");
609        /* if(p2->decoder && decode==0)
610             printf(" use %s for decoding", p2->decoder->name);*/
611         printf("\n");
612     }
613     printf("\n");
614     printf(
615 "Note, the names of encoders and decoders do not always match, so there are\n"
616 "several cases where the above table shows encoder only or decoder only entries\n"
617 "even though both encoding and decoding are supported. For example, the h263\n"
618 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
619 "worse.\n");
620 }
621
622 void show_bsfs(void)
623 {
624     AVBitStreamFilter *bsf=NULL;
625
626     printf("Bitstream filters:\n");
627     while((bsf = av_bitstream_filter_next(bsf)))
628         printf("%s\n", bsf->name);
629     printf("\n");
630 }
631
632 void show_protocols(void)
633 {
634     void *opaque = NULL;
635     const char *name;
636
637     printf("Supported file protocols:\n"
638            "Input:\n");
639     while ((name = avio_enum_protocols(&opaque, 0)))
640         printf("%s\n", name);
641     printf("Output:\n");
642     while ((name = avio_enum_protocols(&opaque, 1)))
643         printf("%s\n", name);
644 }
645
646 void show_filters(void)
647 {
648     AVFilter av_unused(**filter) = NULL;
649
650     printf("Filters:\n");
651 #if CONFIG_AVFILTER
652     while ((filter = av_filter_next(filter)) && *filter)
653         printf("%-16s %s\n", (*filter)->name, (*filter)->description);
654 #endif
655 }
656
657 void show_pix_fmts(void)
658 {
659     enum PixelFormat pix_fmt;
660
661     printf(
662         "Pixel formats:\n"
663         "I.... = Supported Input  format for conversion\n"
664         ".O... = Supported Output format for conversion\n"
665         "..H.. = Hardware accelerated format\n"
666         "...P. = Paletted format\n"
667         "....B = Bitstream format\n"
668         "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL\n"
669         "-----\n");
670
671 #if !CONFIG_SWSCALE
672 #   define sws_isSupportedInput(x)  0
673 #   define sws_isSupportedOutput(x) 0
674 #endif
675
676     for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
677         const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
678         printf("%c%c%c%c%c %-16s       %d            %2d\n",
679                sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
680                sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
681                pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
682                pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
683                pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
684                pix_desc->name,
685                pix_desc->nb_components,
686                av_get_bits_per_pixel(pix_desc));
687     }
688 }
689
690 int read_yesno(void)
691 {
692     int c = getchar();
693     int yesno = (toupper(c) == 'Y');
694
695     while (c != '\n' && c != EOF)
696         c = getchar();
697
698     return yesno;
699 }
700
701 int read_file(const char *filename, char **bufptr, size_t *size)
702 {
703     FILE *f = fopen(filename, "rb");
704
705     if (!f) {
706         fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
707         return AVERROR(errno);
708     }
709     fseek(f, 0, SEEK_END);
710     *size = ftell(f);
711     fseek(f, 0, SEEK_SET);
712     *bufptr = av_malloc(*size + 1);
713     if (!*bufptr) {
714         fprintf(stderr, "Could not allocate file buffer\n");
715         fclose(f);
716         return AVERROR(ENOMEM);
717     }
718     fread(*bufptr, 1, *size, f);
719     (*bufptr)[*size++] = '\0';
720
721     fclose(f);
722     return 0;
723 }
724
725 void init_pts_correction(PtsCorrectionContext *ctx)
726 {
727     ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
728     ctx->last_pts = ctx->last_dts = INT64_MIN;
729 }
730
731 int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts, int64_t dts)
732 {
733     int64_t pts = AV_NOPTS_VALUE;
734
735     if (dts != AV_NOPTS_VALUE) {
736         ctx->num_faulty_dts += dts <= ctx->last_dts;
737         ctx->last_dts = dts;
738     }
739     if (reordered_pts != AV_NOPTS_VALUE) {
740         ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
741         ctx->last_pts = reordered_pts;
742     }
743     if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
744        && reordered_pts != AV_NOPTS_VALUE)
745         pts = reordered_pts;
746     else
747         pts = dts;
748
749     return pts;
750 }
751
752 FILE *get_preset_file(char *filename, size_t filename_size,
753                       const char *preset_name, int is_path, const char *codec_name)
754 {
755     FILE *f = NULL;
756     int i;
757     const char *base[3]= { getenv("FFMPEG_DATADIR"),
758                            getenv("HOME"),
759                            FFMPEG_DATADIR,
760                          };
761
762     if (is_path) {
763         av_strlcpy(filename, preset_name, filename_size);
764         f = fopen(filename, "r");
765     } else {
766         for (i = 0; i < 3 && !f; i++) {
767             if (!base[i])
768                 continue;
769             snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name);
770             f = fopen(filename, "r");
771             if (!f && codec_name) {
772                 snprintf(filename, filename_size,
773                          "%s%s/%s-%s.ffpreset", base[i],  i != 1 ? "" : "/.ffmpeg", codec_name, preset_name);
774                 f = fopen(filename, "r");
775             }
776         }
777     }
778
779     return f;
780 }
781
782 AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, int encoder)
783 {
784     AVDictionary    *ret = NULL;
785     AVDictionaryEntry *t = NULL;
786     AVCodec       *codec = encoder ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
787     int            flags = encoder ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
788     char          prefix = 0;
789
790     if (!codec)
791         return NULL;
792
793     switch (codec->type) {
794     case AVMEDIA_TYPE_VIDEO:    prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM;    break;
795     case AVMEDIA_TYPE_AUDIO:    prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM;    break;
796     case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
797     }
798
799     while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
800         if (av_opt_find(avcodec_opts[0], t->key, NULL, flags, 0) ||
801             (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, 0)))
802             av_dict_set(&ret, t->key, t->value, 0);
803         else if (t->key[0] == prefix && av_opt_find(avcodec_opts[0], t->key+1, NULL, flags, 0))
804             av_dict_set(&ret, t->key+1, t->value, 0);
805     }
806     return ret;
807 }
808
809 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
810 {
811     int i;
812     AVDictionary **opts;
813
814     if (!s->nb_streams)
815         return NULL;
816     opts = av_mallocz(s->nb_streams * sizeof(*opts));
817     if (!opts) {
818         av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
819         return NULL;
820     }
821     for (i = 0; i < s->nb_streams; i++)
822         opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, 0);
823     return opts;
824 }
825
826 #if CONFIG_AVFILTER
827
828 static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
829 {
830     FFSinkContext *priv = ctx->priv;
831
832     if (!opaque)
833         return AVERROR(EINVAL);
834     *priv = *(FFSinkContext *)opaque;
835
836     return 0;
837 }
838
839 static void null_end_frame(AVFilterLink *inlink) { }
840
841 static int ffsink_query_formats(AVFilterContext *ctx)
842 {
843     FFSinkContext *priv = ctx->priv;
844     enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
845
846     avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
847     return 0;
848 }
849
850 AVFilter ffsink = {
851     .name      = "ffsink",
852     .priv_size = sizeof(FFSinkContext),
853     .init      = ffsink_init,
854
855     .query_formats = ffsink_query_formats,
856
857     .inputs    = (AVFilterPad[]) {{ .name          = "default",
858                                     .type          = AVMEDIA_TYPE_VIDEO,
859                                     .end_frame     = null_end_frame,
860                                     .min_perms     = AV_PERM_READ, },
861                                   { .name = NULL }},
862     .outputs   = (AVFilterPad[]) {{ .name = NULL }},
863 };
864
865 int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
866                              AVFilterBufferRef **picref_ptr, AVRational *tb)
867 {
868     int ret;
869     AVFilterBufferRef *picref;
870
871     if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
872         return ret;
873     if (!(picref = ctx->inputs[0]->cur_buf))
874         return AVERROR(ENOENT);
875     *picref_ptr = picref;
876     ctx->inputs[0]->cur_buf = NULL;
877     *tb = ctx->inputs[0]->time_base;
878
879     memcpy(frame->data,     picref->data,     sizeof(frame->data));
880     memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
881     frame->interlaced_frame = picref->video->interlaced;
882     frame->top_field_first  = picref->video->top_field_first;
883     frame->key_frame        = picref->video->key_frame;
884     frame->pict_type        = picref->video->pict_type;
885
886     return 1;
887 }
888
889 #endif /* CONFIG_AVFILTER */