OSDN Git Service

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