]> git.sesse.net Git - ffmpeg/blob - cmdutils.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / cmdutils.c
1 /*
2  * Various utilities for command line tools
3  * Copyright (c) 2000-2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <math.h>
26
27 /* Include only the enabled headers since some compilers (namely, Sun
28    Studio) will not omit unused inline functions and create undefined
29    references to libraries that are not being built. */
30
31 #include "config.h"
32 #include "libavformat/avformat.h"
33 #include "libavfilter/avfilter.h"
34 #include "libavdevice/avdevice.h"
35 #include "libswscale/swscale.h"
36 #include "libswresample/swresample.h"
37 #if CONFIG_POSTPROC
38 #include "libpostproc/postprocess.h"
39 #endif
40 #include "libavutil/avstring.h"
41 #include "libavutil/mathematics.h"
42 #include "libavutil/parseutils.h"
43 #include "libavutil/pixdesc.h"
44 #include "libavutil/eval.h"
45 #include "libavutil/dict.h"
46 #include "libavutil/opt.h"
47 #include "cmdutils.h"
48 #include "version.h"
49 #if CONFIG_NETWORK
50 #include "libavformat/network.h"
51 #endif
52 #if HAVE_SYS_RESOURCE_H
53 #include <sys/resource.h>
54 #endif
55
56 struct SwsContext *sws_opts;
57 SwrContext *swr_opts;
58 AVDictionary *format_opts, *codec_opts;
59
60 const int this_year = 2012;
61
62 static FILE *report_file;
63
64 void init_opts(void)
65 {
66 #if CONFIG_SWSCALE
67     sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC,
68                               NULL, NULL, NULL);
69 #endif
70     swr_opts = swr_alloc();
71 }
72
73 void uninit_opts(void)
74 {
75 #if CONFIG_SWSCALE
76     sws_freeContext(sws_opts);
77     sws_opts = NULL;
78 #endif
79     swr_free(&swr_opts);
80     av_dict_free(&format_opts);
81     av_dict_free(&codec_opts);
82 }
83
84 void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
85 {
86     vfprintf(stdout, fmt, vl);
87 }
88
89 static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
90 {
91     va_list vl2;
92     char line[1024];
93     static int print_prefix = 1;
94
95     va_copy(vl2, vl);
96     av_log_default_callback(ptr, level, fmt, vl);
97     av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
98     va_end(vl2);
99     fputs(line, report_file);
100     fflush(report_file);
101 }
102
103 double parse_number_or_die(const char *context, const char *numstr, int type,
104                            double min, double max)
105 {
106     char *tail;
107     const char *error;
108     double d = av_strtod(numstr, &tail);
109     if (*tail)
110         error = "Expected number for %s but found: %s\n";
111     else if (d < min || d > max)
112         error = "The value for %s was %s which is not within %f - %f\n";
113     else if (type == OPT_INT64 && (int64_t)d != d)
114         error = "Expected int64 for %s but found %s\n";
115     else if (type == OPT_INT && (int)d != d)
116         error = "Expected int for %s but found %s\n";
117     else
118         return d;
119     av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
120     exit_program(1);
121     return 0;
122 }
123
124 int64_t parse_time_or_die(const char *context, const char *timestr,
125                           int is_duration)
126 {
127     int64_t us;
128     if (av_parse_time(&us, timestr, is_duration) < 0) {
129         av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
130                is_duration ? "duration" : "date", context, timestr);
131         exit_program(1);
132     }
133     return us;
134 }
135
136 void show_help_options(const OptionDef *options, const char *msg, int mask,
137                        int value)
138 {
139     const OptionDef *po;
140     int first;
141
142     first = 1;
143     for (po = options; po->name != NULL; po++) {
144         char buf[64];
145         if ((po->flags & mask) == value) {
146             if (first) {
147                 printf("%s", msg);
148                 first = 0;
149             }
150             av_strlcpy(buf, po->name, sizeof(buf));
151             if (po->flags & HAS_ARG) {
152                 av_strlcat(buf, " ", sizeof(buf));
153                 av_strlcat(buf, po->argname, sizeof(buf));
154             }
155             printf("-%-17s  %s\n", buf, po->help);
156         }
157     }
158 }
159
160 void show_help_children(const AVClass *class, int flags)
161 {
162     const AVClass *child = NULL;
163     av_opt_show2(&class, NULL, flags, 0);
164     printf("\n");
165
166     while (child = av_opt_child_class_next(class, child))
167         show_help_children(child, flags);
168 }
169
170 static const OptionDef *find_option(const OptionDef *po, const char *name)
171 {
172     const char *p = strchr(name, ':');
173     int len = p ? p - name : strlen(name);
174
175     while (po->name != NULL) {
176         if (!strncmp(name, po->name, len) && strlen(po->name) == len)
177             break;
178         po++;
179     }
180     return po;
181 }
182
183 #if defined(_WIN32) && !defined(__MINGW32CE__)
184 #include <windows.h>
185 /* Will be leaked on exit */
186 static char** win32_argv_utf8 = NULL;
187 static int win32_argc = 0;
188
189 /**
190  * Prepare command line arguments for executable.
191  * For Windows - perform wide-char to UTF-8 conversion.
192  * Input arguments should be main() function arguments.
193  * @param argc_ptr Arguments number (including executable)
194  * @param argv_ptr Arguments list.
195  */
196 static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
197 {
198     char *argstr_flat;
199     wchar_t **argv_w;
200     int i, buffsize = 0, offset = 0;
201
202     if (win32_argv_utf8) {
203         *argc_ptr = win32_argc;
204         *argv_ptr = win32_argv_utf8;
205         return;
206     }
207
208     win32_argc = 0;
209     argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
210     if (win32_argc <= 0 || !argv_w)
211         return;
212
213     /* determine the UTF-8 buffer size (including NULL-termination symbols) */
214     for (i = 0; i < win32_argc; i++)
215         buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
216                                         NULL, 0, NULL, NULL);
217
218     win32_argv_utf8 = av_mallocz(sizeof(char *) * (win32_argc + 1) + buffsize);
219     argstr_flat     = (char *)win32_argv_utf8 + sizeof(char *) * (win32_argc + 1);
220     if (win32_argv_utf8 == NULL) {
221         LocalFree(argv_w);
222         return;
223     }
224
225     for (i = 0; i < win32_argc; i++) {
226         win32_argv_utf8[i] = &argstr_flat[offset];
227         offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
228                                       &argstr_flat[offset],
229                                       buffsize - offset, NULL, NULL);
230     }
231     win32_argv_utf8[i] = NULL;
232     LocalFree(argv_w);
233
234     *argc_ptr = win32_argc;
235     *argv_ptr = win32_argv_utf8;
236 }
237 #else
238 static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
239 {
240     /* nothing to do */
241 }
242 #endif /* WIN32 && !__MINGW32CE__ */
243
244 int parse_option(void *optctx, const char *opt, const char *arg,
245                  const OptionDef *options)
246 {
247     const OptionDef *po;
248     int bool_val = 1;
249     int *dstcount;
250     void *dst;
251
252     po = find_option(options, opt);
253     if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
254         /* handle 'no' bool option */
255         po = find_option(options, opt + 2);
256         if ((po->name && (po->flags & OPT_BOOL)))
257             bool_val = 0;
258     }
259     if (!po->name)
260         po = find_option(options, "default");
261     if (!po->name) {
262         av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
263         return AVERROR(EINVAL);
264     }
265     if (po->flags & HAS_ARG && !arg) {
266         av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
267         return AVERROR(EINVAL);
268     }
269
270     /* new-style options contain an offset into optctx, old-style address of
271      * a global var*/
272     dst = po->flags & (OPT_OFFSET | OPT_SPEC) ? (uint8_t *)optctx + po->u.off
273                                               : po->u.dst_ptr;
274
275     if (po->flags & OPT_SPEC) {
276         SpecifierOpt **so = dst;
277         char *p = strchr(opt, ':');
278
279         dstcount = (int *)(so + 1);
280         *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
281         (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : "");
282         dst = &(*so)[*dstcount - 1].u;
283     }
284
285     if (po->flags & OPT_STRING) {
286         char *str;
287         str = av_strdup(arg);
288         *(char **)dst = str;
289     } else if (po->flags & OPT_BOOL) {
290         *(int *)dst = bool_val;
291     } else if (po->flags & OPT_INT) {
292         *(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
293     } else if (po->flags & OPT_INT64) {
294         *(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
295     } else if (po->flags & OPT_TIME) {
296         *(int64_t *)dst = parse_time_or_die(opt, arg, 1);
297     } else if (po->flags & OPT_FLOAT) {
298         *(float *)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
299     } else if (po->flags & OPT_DOUBLE) {
300         *(double *)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
301     } else if (po->u.func_arg) {
302         int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg)
303                                         : po->u.func_arg(opt, arg);
304         if (ret < 0) {
305             av_log(NULL, AV_LOG_ERROR,
306                    "Failed to set value '%s' for option '%s'\n", arg, opt);
307             return ret;
308         }
309     }
310     if (po->flags & OPT_EXIT)
311         exit_program(0);
312     return !!(po->flags & HAS_ARG);
313 }
314
315 void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
316                    void (*parse_arg_function)(void *, const char*))
317 {
318     const char *opt;
319     int optindex, handleoptions = 1, ret;
320
321     /* perform system-dependent conversions for arguments list */
322     prepare_app_arguments(&argc, &argv);
323
324     /* parse options */
325     optindex = 1;
326     while (optindex < argc) {
327         opt = argv[optindex++];
328
329         if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
330             if (opt[1] == '-' && opt[2] == '\0') {
331                 handleoptions = 0;
332                 continue;
333             }
334             opt++;
335
336             if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
337                 exit_program(1);
338             optindex += ret;
339         } else {
340             if (parse_arg_function)
341                 parse_arg_function(optctx, opt);
342         }
343     }
344 }
345
346 int locate_option(int argc, char **argv, const OptionDef *options,
347                   const char *optname)
348 {
349     const OptionDef *po;
350     int i;
351
352     for (i = 1; i < argc; i++) {
353         const char *cur_opt = argv[i];
354
355         if (*cur_opt++ != '-')
356             continue;
357
358         po = find_option(options, cur_opt);
359         if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
360             po = find_option(options, cur_opt + 2);
361
362         if ((!po->name && !strcmp(cur_opt, optname)) ||
363              (po->name && !strcmp(optname, po->name)))
364             return i;
365
366         if (!po || po->flags & HAS_ARG)
367             i++;
368     }
369     return 0;
370 }
371
372 static void dump_argument(const char *a)
373 {
374     const unsigned char *p;
375
376     for (p = a; *p; p++)
377         if (!((*p >= '+' && *p <= ':') || (*p >= '@' && *p <= 'Z') ||
378               *p == '_' || (*p >= 'a' && *p <= 'z')))
379             break;
380     if (!*p) {
381         fputs(a, report_file);
382         return;
383     }
384     fputc('"', report_file);
385     for (p = a; *p; p++) {
386         if (*p == '\\' || *p == '"' || *p == '$' || *p == '`')
387             fprintf(report_file, "\\%c", *p);
388         else if (*p < ' ' || *p > '~')
389             fprintf(report_file, "\\x%02x", *p);
390         else
391             fputc(*p, report_file);
392     }
393     fputc('"', report_file);
394 }
395
396 void parse_loglevel(int argc, char **argv, const OptionDef *options)
397 {
398     int idx = locate_option(argc, argv, options, "loglevel");
399     if (!idx)
400         idx = locate_option(argc, argv, options, "v");
401     if (idx && argv[idx + 1])
402         opt_loglevel("loglevel", argv[idx + 1]);
403     idx = locate_option(argc, argv, options, "report");
404     if (idx || getenv("FFREPORT")) {
405         opt_report("report");
406         if (report_file) {
407             int i;
408             fprintf(report_file, "Command line:\n");
409             for (i = 0; i < argc; i++) {
410                 dump_argument(argv[i]);
411                 fputc(i < argc - 1 ? ' ' : '\n', report_file);
412             }
413             fflush(report_file);
414         }
415     }
416 }
417
418 #define FLAGS(o) ((o)->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
419 int opt_default(const char *opt, const char *arg)
420 {
421     const AVOption *oc, *of, *os, *oswr = NULL;
422     char opt_stripped[128];
423     const char *p;
424     const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc, *swr_class;
425
426     if (!(p = strchr(opt, ':')))
427         p = opt + strlen(opt);
428     av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
429
430     if ((oc = av_opt_find(&cc, opt_stripped, NULL, 0,
431                          AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
432         ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
433          (oc = av_opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
434         av_dict_set(&codec_opts, opt, arg, FLAGS(oc));
435     if ((of = av_opt_find(&fc, opt, NULL, 0,
436                           AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
437         av_dict_set(&format_opts, opt, arg, FLAGS(of));
438 #if CONFIG_SWSCALE
439     sc = sws_get_class();
440     if ((os = av_opt_find(&sc, opt, NULL, 0,
441                           AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
442         // XXX we only support sws_flags, not arbitrary sws options
443         int ret = av_opt_set(sws_opts, opt, arg, 0);
444         if (ret < 0) {
445             av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
446             return ret;
447         }
448     }
449 #endif
450     swr_class = swr_get_class();
451     if (!oc && !of && !os && (oswr = av_opt_find(&swr_class, opt, NULL, 0,
452                           AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
453         int ret = av_opt_set(swr_opts, opt, arg, 0);
454         if (ret < 0) {
455             av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
456             return ret;
457         }
458     }
459
460     if (oc || of || os || oswr)
461         return 0;
462     av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
463     return AVERROR_OPTION_NOT_FOUND;
464 }
465
466 int opt_loglevel(const char *opt, const char *arg)
467 {
468     const struct { const char *name; int level; } log_levels[] = {
469         { "quiet"  , AV_LOG_QUIET   },
470         { "panic"  , AV_LOG_PANIC   },
471         { "fatal"  , AV_LOG_FATAL   },
472         { "error"  , AV_LOG_ERROR   },
473         { "warning", AV_LOG_WARNING },
474         { "info"   , AV_LOG_INFO    },
475         { "verbose", AV_LOG_VERBOSE },
476         { "debug"  , AV_LOG_DEBUG   },
477     };
478     char *tail;
479     int level;
480     int i;
481
482     for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
483         if (!strcmp(log_levels[i].name, arg)) {
484             av_log_set_level(log_levels[i].level);
485             return 0;
486         }
487     }
488
489     level = strtol(arg, &tail, 10);
490     if (*tail) {
491         av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
492                "Possible levels are numbers or:\n", arg);
493         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
494             av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
495         exit_program(1);
496     }
497     av_log_set_level(level);
498     return 0;
499 }
500
501 int opt_report(const char *opt)
502 {
503     char filename[64];
504     time_t now;
505     struct tm *tm;
506
507     if (report_file) /* already opened */
508         return 0;
509     time(&now);
510     tm = localtime(&now);
511     snprintf(filename, sizeof(filename), "%s-%04d%02d%02d-%02d%02d%02d.log",
512              program_name,
513              tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
514              tm->tm_hour, tm->tm_min, tm->tm_sec);
515     report_file = fopen(filename, "w");
516     if (!report_file) {
517         av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
518                filename, strerror(errno));
519         return AVERROR(errno);
520     }
521     av_log_set_callback(log_callback_report);
522     av_log(NULL, AV_LOG_INFO,
523            "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
524            "Report written to \"%s\"\n",
525            program_name,
526            tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
527            tm->tm_hour, tm->tm_min, tm->tm_sec,
528            filename);
529     av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE));
530     return 0;
531 }
532
533 int opt_max_alloc(const char *opt, const char *arg)
534 {
535     char *tail;
536     size_t max;
537
538     max = strtol(arg, &tail, 10);
539     if (*tail) {
540         av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
541         exit_program(1);
542     }
543     av_max_alloc(max);
544     return 0;
545 }
546
547 int opt_cpuflags(const char *opt, const char *arg)
548 {
549     static const AVOption cpuflags_opts[] = {
550         { "flags"   , NULL, 0, AV_OPT_TYPE_FLAGS, { 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
551         { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ALTIVEC  },    .unit = "flags" },
552         { "mmx"     , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_MMX      },    .unit = "flags" },
553         { "mmx2"    , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_MMX2     },    .unit = "flags" },
554         { "sse"     , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE      },    .unit = "flags" },
555         { "sse2"    , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE2     },    .unit = "flags" },
556         { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE2SLOW },    .unit = "flags" },
557         { "sse3"    , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE3     },    .unit = "flags" },
558         { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE3SLOW },    .unit = "flags" },
559         { "ssse3"   , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSSE3    },    .unit = "flags" },
560         { "atom"    , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_ATOM     },    .unit = "flags" },
561         { "sse4.1"  , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE4     },    .unit = "flags" },
562         { "sse4.2"  , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_SSE42    },    .unit = "flags" },
563         { "avx"     , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_AVX      },    .unit = "flags" },
564         { "xop"     , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_XOP      },    .unit = "flags" },
565         { "fma4"    , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_FMA4     },    .unit = "flags" },
566         { "3dnow"   , NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_3DNOW    },    .unit = "flags" },
567         { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { AV_CPU_FLAG_3DNOWEXT },    .unit = "flags" },
568         { NULL },
569     };
570     static const AVClass class = {
571         .class_name = "cpuflags",
572         .item_name  = av_default_item_name,
573         .option     = cpuflags_opts,
574         .version    = LIBAVUTIL_VERSION_INT,
575     };
576     int flags = av_get_cpu_flags();
577     int ret;
578     const AVClass *pclass = &class;
579
580     if ((ret = av_opt_eval_flags(&pclass, &cpuflags_opts[0], arg, &flags)) < 0)
581         return ret;
582
583     av_force_cpu_flags(flags);
584     return 0;
585 }
586
587 int opt_codec_debug(const char *opt, const char *arg)
588 {
589     av_log_set_level(AV_LOG_DEBUG);
590     return opt_default(opt, arg);
591 }
592
593 int opt_timelimit(const char *opt, const char *arg)
594 {
595 #if HAVE_SETRLIMIT
596     int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
597     struct rlimit rl = { lim, lim + 1 };
598     if (setrlimit(RLIMIT_CPU, &rl))
599         perror("setrlimit");
600 #else
601     av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
602 #endif
603     return 0;
604 }
605
606 void print_error(const char *filename, int err)
607 {
608     char errbuf[128];
609     const char *errbuf_ptr = errbuf;
610
611     if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
612         errbuf_ptr = strerror(AVUNERROR(err));
613     av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
614 }
615
616 static int warned_cfg = 0;
617
618 #define INDENT        1
619 #define SHOW_VERSION  2
620 #define SHOW_CONFIG   4
621 #define SHOW_COPYRIGHT 8
622
623 #define PRINT_LIB_INFO(libname, LIBNAME, flags, level)                  \
624     if (CONFIG_##LIBNAME) {                                             \
625         const char *indent = flags & INDENT? "  " : "";                 \
626         if (flags & SHOW_VERSION) {                                     \
627             unsigned int version = libname##_version();                 \
628             av_log(NULL, level, "%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n",\
629                    indent, #libname,                                    \
630                    LIB##LIBNAME##_VERSION_MAJOR,                        \
631                    LIB##LIBNAME##_VERSION_MINOR,                        \
632                    LIB##LIBNAME##_VERSION_MICRO,                        \
633                    version >> 16, version >> 8 & 0xff, version & 0xff); \
634         }                                                               \
635         if (flags & SHOW_CONFIG) {                                      \
636             const char *cfg = libname##_configuration();                \
637             if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \
638                 if (!warned_cfg) {                                      \
639                     av_log(NULL, level,                                 \
640                             "%sWARNING: library configuration mismatch\n", \
641                             indent);                                    \
642                     warned_cfg = 1;                                     \
643                 }                                                       \
644                 av_log(NULL, level, "%s%-11s configuration: %s\n",      \
645                         indent, #libname, cfg);                         \
646             }                                                           \
647         }                                                               \
648     }                                                                   \
649
650 static void print_all_libs_info(int flags, int level)
651 {
652     PRINT_LIB_INFO(avutil,   AVUTIL,   flags, level);
653     PRINT_LIB_INFO(avcodec,  AVCODEC,  flags, level);
654     PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
655     PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
656     PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
657     PRINT_LIB_INFO(swscale,  SWSCALE,  flags, level);
658     PRINT_LIB_INFO(swresample,SWRESAMPLE,  flags, level);
659 #if CONFIG_POSTPROC
660     PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
661 #endif
662 }
663
664 static void print_program_info(int flags, int level)
665 {
666     const char *indent = flags & INDENT? "  " : "";
667
668     av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
669     if (flags & SHOW_COPYRIGHT)
670         av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
671                program_birth_year, this_year);
672     av_log(NULL, level, "\n");
673     av_log(NULL, level, "%sbuilt on %s %s with %s %s\n",
674            indent, __DATE__, __TIME__, CC_TYPE, CC_VERSION);
675     av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
676 }
677
678 void show_banner(int argc, char **argv, const OptionDef *options)
679 {
680     int idx = locate_option(argc, argv, options, "version");
681     if (idx)
682         return;
683
684     print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);
685     print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_INFO);
686     print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
687 }
688
689 int opt_version(const char *opt, const char *arg) {
690     av_log_set_callback(log_callback_help);
691     print_program_info (0           , AV_LOG_INFO);
692     print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
693     return 0;
694 }
695
696 int opt_license(const char *opt, const char *arg)
697 {
698     printf(
699 #if CONFIG_NONFREE
700     "This version of %s has nonfree parts compiled in.\n"
701     "Therefore it is not legally redistributable.\n",
702     program_name
703 #elif CONFIG_GPLV3
704     "%s is free software; you can redistribute it and/or modify\n"
705     "it under the terms of the GNU General Public License as published by\n"
706     "the Free Software Foundation; either version 3 of the License, or\n"
707     "(at your option) any later version.\n"
708     "\n"
709     "%s is distributed in the hope that it will be useful,\n"
710     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
711     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
712     "GNU General Public License for more details.\n"
713     "\n"
714     "You should have received a copy of the GNU General Public License\n"
715     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
716     program_name, program_name, program_name
717 #elif CONFIG_GPL
718     "%s is free software; you can redistribute it and/or modify\n"
719     "it under the terms of the GNU General Public License as published by\n"
720     "the Free Software Foundation; either version 2 of the License, or\n"
721     "(at your option) any later version.\n"
722     "\n"
723     "%s is distributed in the hope that it will be useful,\n"
724     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
725     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
726     "GNU General Public License for more details.\n"
727     "\n"
728     "You should have received a copy of the GNU General Public License\n"
729     "along with %s; if not, write to the Free Software\n"
730     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
731     program_name, program_name, program_name
732 #elif CONFIG_LGPLV3
733     "%s is free software; you can redistribute it and/or modify\n"
734     "it under the terms of the GNU Lesser General Public License as published by\n"
735     "the Free Software Foundation; either version 3 of the License, or\n"
736     "(at your option) any later version.\n"
737     "\n"
738     "%s is distributed in the hope that it will be useful,\n"
739     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
740     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
741     "GNU Lesser General Public License for more details.\n"
742     "\n"
743     "You should have received a copy of the GNU Lesser General Public License\n"
744     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
745     program_name, program_name, program_name
746 #else
747     "%s is free software; you can redistribute it and/or\n"
748     "modify it under the terms of the GNU Lesser General Public\n"
749     "License as published by the Free Software Foundation; either\n"
750     "version 2.1 of the License, or (at your option) any later version.\n"
751     "\n"
752     "%s is distributed in the hope that it will be useful,\n"
753     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
754     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
755     "Lesser General Public License for more details.\n"
756     "\n"
757     "You should have received a copy of the GNU Lesser General Public\n"
758     "License along with %s; if not, write to the Free Software\n"
759     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
760     program_name, program_name, program_name
761 #endif
762     );
763     return 0;
764 }
765
766 int opt_formats(const char *opt, const char *arg)
767 {
768     AVInputFormat *ifmt  = NULL;
769     AVOutputFormat *ofmt = NULL;
770     const char *last_name;
771
772     printf("File formats:\n"
773            " D. = Demuxing supported\n"
774            " .E = Muxing supported\n"
775            " --\n");
776     last_name = "000";
777     for (;;) {
778         int decode = 0;
779         int encode = 0;
780         const char *name      = NULL;
781         const char *long_name = NULL;
782
783         while ((ofmt = av_oformat_next(ofmt))) {
784             if ((name == NULL || strcmp(ofmt->name, name) < 0) &&
785                 strcmp(ofmt->name, last_name) > 0) {
786                 name      = ofmt->name;
787                 long_name = ofmt->long_name;
788                 encode    = 1;
789             }
790         }
791         while ((ifmt = av_iformat_next(ifmt))) {
792             if ((name == NULL || strcmp(ifmt->name, name) < 0) &&
793                 strcmp(ifmt->name, last_name) > 0) {
794                 name      = ifmt->name;
795                 long_name = ifmt->long_name;
796                 encode    = 0;
797             }
798             if (name && strcmp(ifmt->name, name) == 0)
799                 decode = 1;
800         }
801         if (name == NULL)
802             break;
803         last_name = name;
804
805         printf(" %s%s %-15s %s\n",
806                decode ? "D" : " ",
807                encode ? "E" : " ",
808                name,
809             long_name ? long_name:" ");
810     }
811     return 0;
812 }
813
814 static char get_media_type_char(enum AVMediaType type)
815 {
816     static const char map[AVMEDIA_TYPE_NB] = {
817         [AVMEDIA_TYPE_VIDEO]      = 'V',
818         [AVMEDIA_TYPE_AUDIO]      = 'A',
819         [AVMEDIA_TYPE_DATA]       = 'D',
820         [AVMEDIA_TYPE_SUBTITLE]   = 'S',
821         [AVMEDIA_TYPE_ATTACHMENT] = 'T',
822     };
823     return type >= 0 && type < AVMEDIA_TYPE_NB && map[type] ? map[type] : '?';
824 }
825
826 int opt_codecs(const char *opt, const char *arg)
827 {
828     AVCodec *p = NULL, *p2;
829     const char *last_name;
830     printf("Codecs:\n"
831            " D..... = Decoding supported\n"
832            " .E.... = Encoding supported\n"
833            " ..V... = Video codec\n"
834            " ..A... = Audio codec\n"
835            " ..S... = Subtitle codec\n"
836            " ...S.. = Supports draw_horiz_band\n"
837            " ....D. = Supports direct rendering method 1\n"
838            " .....T = Supports weird frame truncation\n"
839            " ------\n");
840     last_name= "000";
841     for (;;) {
842         int decode = 0;
843         int encode = 0;
844         int cap    = 0;
845
846         p2 = NULL;
847         while ((p = av_codec_next(p))) {
848             if ((p2 == NULL || strcmp(p->name, p2->name) < 0) &&
849                 strcmp(p->name, last_name) > 0) {
850                 p2 = p;
851                 decode = encode = cap = 0;
852             }
853             if (p2 && strcmp(p->name, p2->name) == 0) {
854                 if (av_codec_is_decoder(p))
855                     decode = 1;
856                 if (av_codec_is_encoder(p))
857                     encode = 1;
858                 cap |= p->capabilities;
859             }
860         }
861         if (p2 == NULL)
862             break;
863         last_name = p2->name;
864
865         printf(" %s%s%c%s%s%s %-15s %s",
866                decode ? "D" : (/* p2->decoder ? "d" : */ " "),
867                encode ? "E" : " ",
868                get_media_type_char(p2->type),
869                cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S" : " ",
870                cap & CODEC_CAP_DR1 ? "D" : " ",
871                cap & CODEC_CAP_TRUNCATED ? "T" : " ",
872                p2->name,
873                p2->long_name ? p2->long_name : "");
874 #if 0
875             if (p2->decoder && decode == 0)
876                 printf(" use %s for decoding", p2->decoder->name);
877 #endif
878         printf("\n");
879     }
880     printf("\n");
881     printf("Note, the names of encoders and decoders do not always match, so there are\n"
882            "several cases where the above table shows encoder only or decoder only entries\n"
883            "even though both encoding and decoding are supported. For example, the h263\n"
884            "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
885            "worse.\n");
886     return 0;
887 }
888
889 int opt_bsfs(const char *opt, const char *arg)
890 {
891     AVBitStreamFilter *bsf = NULL;
892
893     printf("Bitstream filters:\n");
894     while ((bsf = av_bitstream_filter_next(bsf)))
895         printf("%s\n", bsf->name);
896     printf("\n");
897     return 0;
898 }
899
900 int opt_protocols(const char *opt, const char *arg)
901 {
902     void *opaque = NULL;
903     const char *name;
904
905     printf("Supported file protocols:\n"
906            "Input:\n");
907     while ((name = avio_enum_protocols(&opaque, 0)))
908         printf("%s\n", name);
909     printf("Output:\n");
910     while ((name = avio_enum_protocols(&opaque, 1)))
911         printf("%s\n", name);
912     return 0;
913 }
914
915 int opt_filters(const char *opt, const char *arg)
916 {
917     AVFilter av_unused(**filter) = NULL;
918     char descr[64], *descr_cur;
919     int i, j;
920     const AVFilterPad *pad;
921
922     printf("Filters:\n");
923 #if CONFIG_AVFILTER
924     while ((filter = av_filter_next(filter)) && *filter) {
925         descr_cur = descr;
926         for (i = 0; i < 2; i++) {
927             if (i) {
928                 *(descr_cur++) = '-';
929                 *(descr_cur++) = '>';
930             }
931             pad = i ? (*filter)->outputs : (*filter)->inputs;
932             for (j = 0; pad[j].name; j++) {
933                 if (descr_cur >= descr + sizeof(descr) - 4)
934                     break;
935                 *(descr_cur++) = get_media_type_char(pad[j].type);
936             }
937             if (!j)
938                 *(descr_cur++) = '|';
939         }
940         *descr_cur = 0;
941         printf("%-16s %-10s %s\n", (*filter)->name, descr, (*filter)->description);
942     }
943 #endif
944     return 0;
945 }
946
947 int opt_pix_fmts(const char *opt, const char *arg)
948 {
949     enum PixelFormat pix_fmt;
950
951     printf("Pixel formats:\n"
952            "I.... = Supported Input  format for conversion\n"
953            ".O... = Supported Output format for conversion\n"
954            "..H.. = Hardware accelerated format\n"
955            "...P. = Paletted format\n"
956            "....B = Bitstream format\n"
957            "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL\n"
958            "-----\n");
959
960 #if !CONFIG_SWSCALE
961 #   define sws_isSupportedInput(x)  0
962 #   define sws_isSupportedOutput(x) 0
963 #endif
964
965     for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
966         const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
967         if(!pix_desc->name)
968             continue;
969         printf("%c%c%c%c%c %-16s       %d            %2d\n",
970                sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
971                sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
972                pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
973                pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
974                pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
975                pix_desc->name,
976                pix_desc->nb_components,
977                av_get_bits_per_pixel(pix_desc));
978     }
979     return 0;
980 }
981
982 int show_sample_fmts(const char *opt, const char *arg)
983 {
984     int i;
985     char fmt_str[128];
986     for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
987         printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
988     return 0;
989 }
990
991 int read_yesno(void)
992 {
993     int c = getchar();
994     int yesno = (toupper(c) == 'Y');
995
996     while (c != '\n' && c != EOF)
997         c = getchar();
998
999     return yesno;
1000 }
1001
1002 int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
1003 {
1004     int ret;
1005     FILE *f = fopen(filename, "rb");
1006
1007     if (!f) {
1008         av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
1009                strerror(errno));
1010         return AVERROR(errno);
1011     }
1012     fseek(f, 0, SEEK_END);
1013     *size = ftell(f);
1014     fseek(f, 0, SEEK_SET);
1015     *bufptr = av_malloc(*size + 1);
1016     if (!*bufptr) {
1017         av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
1018         fclose(f);
1019         return AVERROR(ENOMEM);
1020     }
1021     ret = fread(*bufptr, 1, *size, f);
1022     if (ret < *size) {
1023         av_free(*bufptr);
1024         if (ferror(f)) {
1025             av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
1026                    filename, strerror(errno));
1027             ret = AVERROR(errno);
1028         } else
1029             ret = AVERROR_EOF;
1030     } else {
1031         ret = 0;
1032         (*bufptr)[*size++] = '\0';
1033     }
1034
1035     fclose(f);
1036     return ret;
1037 }
1038
1039 FILE *get_preset_file(char *filename, size_t filename_size,
1040                       const char *preset_name, int is_path,
1041                       const char *codec_name)
1042 {
1043     FILE *f = NULL;
1044     int i;
1045     const char *base[3] = { getenv("FFMPEG_DATADIR"),
1046                             getenv("HOME"),
1047                             FFMPEG_DATADIR, };
1048
1049     if (is_path) {
1050         av_strlcpy(filename, preset_name, filename_size);
1051         f = fopen(filename, "r");
1052     } else {
1053 #ifdef _WIN32
1054         char datadir[MAX_PATH], *ls;
1055         base[2] = NULL;
1056
1057         if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
1058         {
1059             for (ls = datadir; ls < datadir + strlen(datadir); ls++)
1060                 if (*ls == '\\') *ls = '/';
1061
1062             if (ls = strrchr(datadir, '/'))
1063             {
1064                 *ls = 0;
1065                 strncat(datadir, "/ffpresets",  sizeof(datadir) - 1 - strlen(datadir));
1066                 base[2] = datadir;
1067             }
1068         }
1069 #endif
1070         for (i = 0; i < 3 && !f; i++) {
1071             if (!base[i])
1072                 continue;
1073             snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
1074                      i != 1 ? "" : "/.ffmpeg", preset_name);
1075             f = fopen(filename, "r");
1076             if (!f && codec_name) {
1077                 snprintf(filename, filename_size,
1078                          "%s%s/%s-%s.ffpreset",
1079                          base[i], i != 1 ? "" : "/.ffmpeg", codec_name,
1080                          preset_name);
1081                 f = fopen(filename, "r");
1082             }
1083         }
1084     }
1085
1086     return f;
1087 }
1088
1089 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
1090 {
1091     if (*spec <= '9' && *spec >= '0') /* opt:index */
1092         return strtol(spec, NULL, 0) == st->index;
1093     else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
1094              *spec == 't') { /* opt:[vasdt] */
1095         enum AVMediaType type;
1096
1097         switch (*spec++) {
1098         case 'v': type = AVMEDIA_TYPE_VIDEO;      break;
1099         case 'a': type = AVMEDIA_TYPE_AUDIO;      break;
1100         case 's': type = AVMEDIA_TYPE_SUBTITLE;   break;
1101         case 'd': type = AVMEDIA_TYPE_DATA;       break;
1102         case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
1103         default: abort(); // never reached, silence warning
1104         }
1105         if (type != st->codec->codec_type)
1106             return 0;
1107         if (*spec++ == ':') { /* possibly followed by :index */
1108             int i, index = strtol(spec, NULL, 0);
1109             for (i = 0; i < s->nb_streams; i++)
1110                 if (s->streams[i]->codec->codec_type == type && index-- == 0)
1111                    return i == st->index;
1112             return 0;
1113         }
1114         return 1;
1115     } else if (*spec == 'p' && *(spec + 1) == ':') {
1116         int prog_id, i, j;
1117         char *endptr;
1118         spec += 2;
1119         prog_id = strtol(spec, &endptr, 0);
1120         for (i = 0; i < s->nb_programs; i++) {
1121             if (s->programs[i]->id != prog_id)
1122                 continue;
1123
1124             if (*endptr++ == ':') {
1125                 int stream_idx = strtol(endptr, NULL, 0);
1126                 return stream_idx >= 0 &&
1127                     stream_idx < s->programs[i]->nb_stream_indexes &&
1128                     st->index == s->programs[i]->stream_index[stream_idx];
1129             }
1130
1131             for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
1132                 if (st->index == s->programs[i]->stream_index[j])
1133                     return 1;
1134         }
1135         return 0;
1136     } else if (!*spec) /* empty specifier, matches everything */
1137         return 1;
1138
1139     av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
1140     return AVERROR(EINVAL);
1141 }
1142
1143 AVDictionary *filter_codec_opts(AVDictionary *opts, AVCodec *codec,
1144                                 AVFormatContext *s, AVStream *st)
1145 {
1146     AVDictionary    *ret = NULL;
1147     AVDictionaryEntry *t = NULL;
1148     int            flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
1149                                       : AV_OPT_FLAG_DECODING_PARAM;
1150     char          prefix = 0;
1151     const AVClass    *cc = avcodec_get_class();
1152
1153     if (!codec)
1154         return NULL;
1155
1156     switch (codec->type) {
1157     case AVMEDIA_TYPE_VIDEO:
1158         prefix  = 'v';
1159         flags  |= AV_OPT_FLAG_VIDEO_PARAM;
1160         break;
1161     case AVMEDIA_TYPE_AUDIO:
1162         prefix  = 'a';
1163         flags  |= AV_OPT_FLAG_AUDIO_PARAM;
1164         break;
1165     case AVMEDIA_TYPE_SUBTITLE:
1166         prefix  = 's';
1167         flags  |= AV_OPT_FLAG_SUBTITLE_PARAM;
1168         break;
1169     }
1170
1171     while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
1172         char *p = strchr(t->key, ':');
1173
1174         /* check stream specification in opt name */
1175         if (p)
1176             switch (check_stream_specifier(s, st, p + 1)) {
1177             case  1: *p = 0; break;
1178             case  0:         continue;
1179             default:         return NULL;
1180             }
1181
1182         if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
1183             (codec && codec->priv_class &&
1184              av_opt_find(&codec->priv_class, t->key, NULL, flags,
1185                          AV_OPT_SEARCH_FAKE_OBJ)))
1186             av_dict_set(&ret, t->key, t->value, 0);
1187         else if (t->key[0] == prefix &&
1188                  av_opt_find(&cc, t->key + 1, NULL, flags,
1189                              AV_OPT_SEARCH_FAKE_OBJ))
1190             av_dict_set(&ret, t->key + 1, t->value, 0);
1191
1192         if (p)
1193             *p = ':';
1194     }
1195     return ret;
1196 }
1197
1198 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
1199                                            AVDictionary *codec_opts)
1200 {
1201     int i;
1202     AVDictionary **opts;
1203
1204     if (!s->nb_streams)
1205         return NULL;
1206     opts = av_mallocz(s->nb_streams * sizeof(*opts));
1207     if (!opts) {
1208         av_log(NULL, AV_LOG_ERROR,
1209                "Could not alloc memory for stream options.\n");
1210         return NULL;
1211     }
1212     for (i = 0; i < s->nb_streams; i++)
1213         opts[i] = filter_codec_opts(codec_opts, avcodec_find_decoder(s->streams[i]->codec->codec_id),
1214                                     s, s->streams[i]);
1215     return opts;
1216 }
1217
1218 void *grow_array(void *array, int elem_size, int *size, int new_size)
1219 {
1220     if (new_size >= INT_MAX / elem_size) {
1221         av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
1222         exit_program(1);
1223     }
1224     if (*size < new_size) {
1225         uint8_t *tmp = av_realloc(array, new_size*elem_size);
1226         if (!tmp) {
1227             av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
1228             exit_program(1);
1229         }
1230         memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
1231         *size = new_size;
1232         return tmp;
1233     }
1234     return array;
1235 }