OSDN Git Service

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