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