2 * Various utilities for command line tools
3 * Copyright (c) 2000-2003 Fabrice Bellard
5 * This file is part of FFmpeg.
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.
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.
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
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. */
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"
46 #include "libavformat/network.h"
48 #if HAVE_SYS_RESOURCE_H
49 #include <sys/resource.h>
52 struct SwsContext *sws_opts;
53 AVDictionary *format_opts, *codec_opts;
55 static const int this_year = 2011;
60 sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
64 void uninit_opts(void)
67 sws_freeContext(sws_opts);
70 av_dict_free(&format_opts);
71 av_dict_free(&codec_opts);
74 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
76 vfprintf(stdout, fmt, vl);
79 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
83 double d = av_strtod(numstr, &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";
94 av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
99 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
102 if (av_parse_time(&us, timestr, is_duration) < 0) {
103 av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
104 is_duration ? "duration" : "date", context, timestr);
110 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
116 for(po = options; po->name != NULL; po++) {
118 if ((po->flags & mask) == value) {
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));
128 printf("-%-17s %s\n", buf, po->help);
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);
137 while (po->name != NULL) {
138 if (!strncmp(name, po->name, len) && strlen(po->name) == len)
145 #if defined(_WIN32) && !defined(__MINGW32CE__)
147 /* Will be leaked on exit */
148 static char** win32_argv_utf8 = NULL;
149 static int win32_argc = 0;
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.
158 static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
162 int i, buffsize = 0, offset = 0;
164 if (win32_argv_utf8) {
165 *argc_ptr = win32_argc;
166 *argv_ptr = win32_argv_utf8;
171 argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
172 if (win32_argc <= 0 || !argv_w)
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);
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) {
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);
193 win32_argv_utf8[i] = NULL;
196 *argc_ptr = win32_argc;
197 *argv_ptr = win32_argv_utf8;
200 static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
204 #endif /* WIN32 && !__MINGW32CE__ */
207 int parse_option(void *optctx, const char *opt, const char *arg, const OptionDef *options)
214 po = find_option(options, opt);
215 if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
216 /* handle 'no' bool option */
217 po = find_option(options, opt + 2);
218 if (!(po->name && (po->flags & OPT_BOOL)))
223 po = find_option(options, "default");
226 av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
227 return AVERROR(EINVAL);
229 if (po->flags & HAS_ARG && !arg) {
230 av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
231 return AVERROR(EINVAL);
234 /* new-style options contain an offset into optctx, old-style address of
236 dst = po->flags & (OPT_OFFSET|OPT_SPEC) ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr;
238 if (po->flags & OPT_SPEC) {
239 SpecifierOpt **so = dst;
240 char *p = strchr(opt, ':');
242 dstcount = (int*)(so + 1);
243 *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
244 (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : "");
245 dst = &(*so)[*dstcount - 1].u;
248 if (po->flags & OPT_STRING) {
250 str = av_strdup(arg);
252 } else if (po->flags & OPT_BOOL) {
253 *(int*)dst = bool_val;
254 } else if (po->flags & OPT_INT) {
255 *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
256 } else if (po->flags & OPT_INT64) {
257 *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
258 } else if (po->flags & OPT_TIME) {
259 *(int64_t*)dst = parse_time_or_die(opt, arg, 1);
260 } else if (po->flags & OPT_FLOAT) {
261 *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
262 } else if (po->flags & OPT_DOUBLE) {
263 *(double*)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
264 } else if (po->u.func_arg) {
265 int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg) :
266 po->u.func_arg(opt, arg);
268 av_log(NULL, AV_LOG_ERROR, "Failed to set value '%s' for option '%s'\n", arg, opt);
272 if (po->flags & OPT_EXIT)
274 return !!(po->flags & HAS_ARG);
277 void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
278 void (* parse_arg_function)(void *, const char*))
281 int optindex, handleoptions = 1, ret;
283 /* perform system-dependent conversions for arguments list */
284 prepare_app_arguments(&argc, &argv);
288 while (optindex < argc) {
289 opt = argv[optindex++];
291 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
292 if (opt[1] == '-' && opt[2] == '\0') {
298 if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
302 if (parse_arg_function)
303 parse_arg_function(optctx, opt);
309 * Return index of option opt in argv or 0 if not found.
311 static int locate_option(int argc, char **argv, const OptionDef *options, const char *optname)
316 for (i = 1; i < argc; i++) {
317 const char *cur_opt = argv[i];
319 if (*cur_opt++ != '-')
322 po = find_option(options, cur_opt);
323 if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
324 po = find_option(options, cur_opt + 2);
326 if ((!po->name && !strcmp(cur_opt, optname)) ||
327 (po->name && !strcmp(optname, po->name)))
330 if (!po || po->flags & HAS_ARG)
336 void parse_loglevel(int argc, char **argv, const OptionDef *options)
338 int idx = locate_option(argc, argv, options, "loglevel");
340 idx = locate_option(argc, argv, options, "v");
341 if (idx && argv[idx + 1])
342 opt_loglevel("loglevel", argv[idx + 1]);
345 #define FLAGS(o) ((o)->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
346 int opt_default(const char *opt, const char *arg)
348 const AVOption *oc, *of, *os;
349 char opt_stripped[128];
351 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc;
353 if (!(p = strchr(opt, ':')))
354 p = opt + strlen(opt);
355 av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
357 if ((oc = av_opt_find(&cc, opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN|AV_OPT_SEARCH_FAKE_OBJ)) ||
358 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
359 (oc = av_opt_find(&cc, opt+1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
360 av_dict_set(&codec_opts, opt, arg, FLAGS(oc));
361 if ((of = av_opt_find(&fc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
362 av_dict_set(&format_opts, opt, arg, FLAGS(of));
364 sc = sws_get_class();
365 if ((os = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
366 // XXX we only support sws_flags, not arbitrary sws options
367 int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
369 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
377 av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
378 return AVERROR_OPTION_NOT_FOUND;
381 int opt_loglevel(const char *opt, const char *arg)
383 const struct { const char *name; int level; } log_levels[] = {
384 { "quiet" , AV_LOG_QUIET },
385 { "panic" , AV_LOG_PANIC },
386 { "fatal" , AV_LOG_FATAL },
387 { "error" , AV_LOG_ERROR },
388 { "warning", AV_LOG_WARNING },
389 { "info" , AV_LOG_INFO },
390 { "verbose", AV_LOG_VERBOSE },
391 { "debug" , AV_LOG_DEBUG },
397 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
398 if (!strcmp(log_levels[i].name, arg)) {
399 av_log_set_level(log_levels[i].level);
404 level = strtol(arg, &tail, 10);
406 av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
407 "Possible levels are numbers or:\n", arg);
408 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
409 av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
412 av_log_set_level(level);
416 int opt_timelimit(const char *opt, const char *arg)
419 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
420 struct rlimit rl = { lim, lim + 1 };
421 if (setrlimit(RLIMIT_CPU, &rl))
424 av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
429 void print_error(const char *filename, int err)
432 const char *errbuf_ptr = errbuf;
434 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
435 errbuf_ptr = strerror(AVUNERROR(err));
436 av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
439 static int warned_cfg = 0;
442 #define SHOW_VERSION 2
443 #define SHOW_CONFIG 4
445 #define PRINT_LIB_INFO(libname, LIBNAME, flags, level) \
446 if (CONFIG_##LIBNAME) { \
447 const char *indent = flags & INDENT? " " : ""; \
448 if (flags & SHOW_VERSION) { \
449 unsigned int version = libname##_version(); \
450 av_log(NULL, level, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n",\
452 LIB##LIBNAME##_VERSION_MAJOR, \
453 LIB##LIBNAME##_VERSION_MINOR, \
454 LIB##LIBNAME##_VERSION_MICRO, \
455 version >> 16, version >> 8 & 0xff, version & 0xff); \
457 if (flags & SHOW_CONFIG) { \
458 const char *cfg = libname##_configuration(); \
459 if (strcmp(FFMPEG_CONFIGURATION, cfg)) { \
461 av_log(NULL, level, \
462 "%sWARNING: library configuration mismatch\n", \
466 av_log(NULL, level, "%s%-11s configuration: %s\n", \
467 indent, #libname, cfg); \
472 static void print_all_libs_info(int flags, int level)
474 PRINT_LIB_INFO(avutil, AVUTIL, flags, level);
475 PRINT_LIB_INFO(avcodec, AVCODEC, flags, level);
476 PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
477 PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
478 PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
479 PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
480 PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
483 void show_banner(void)
485 av_log(NULL, AV_LOG_INFO, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n",
486 program_name, program_birth_year, this_year);
487 av_log(NULL, AV_LOG_INFO, " built on %s %s with %s %s\n",
488 __DATE__, __TIME__, CC_TYPE, CC_VERSION);
489 av_log(NULL, AV_LOG_INFO, " configuration: " FFMPEG_CONFIGURATION "\n");
490 print_all_libs_info(INDENT|SHOW_CONFIG, AV_LOG_INFO);
491 print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
494 int opt_version(const char *opt, const char *arg) {
495 av_log_set_callback(log_callback_help);
496 printf("%s " FFMPEG_VERSION "\n", program_name);
497 print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
501 int opt_license(const char *opt, const char *arg)
505 "This version of %s has nonfree parts compiled in.\n"
506 "Therefore it is not legally redistributable.\n",
509 "%s is free software; you can redistribute it and/or modify\n"
510 "it under the terms of the GNU General Public License as published by\n"
511 "the Free Software Foundation; either version 3 of the License, or\n"
512 "(at your option) any later version.\n"
514 "%s is distributed in the hope that it will be useful,\n"
515 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
516 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
517 "GNU General Public License for more details.\n"
519 "You should have received a copy of the GNU General Public License\n"
520 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
521 program_name, program_name, program_name
523 "%s is free software; you can redistribute it and/or modify\n"
524 "it under the terms of the GNU General Public License as published by\n"
525 "the Free Software Foundation; either version 2 of the License, or\n"
526 "(at your option) any later version.\n"
528 "%s is distributed in the hope that it will be useful,\n"
529 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
530 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
531 "GNU General Public License for more details.\n"
533 "You should have received a copy of the GNU General Public License\n"
534 "along with %s; if not, write to the Free Software\n"
535 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
536 program_name, program_name, program_name
538 "%s is free software; you can redistribute it and/or modify\n"
539 "it under the terms of the GNU Lesser General Public License as published by\n"
540 "the Free Software Foundation; either version 3 of the License, or\n"
541 "(at your option) any later version.\n"
543 "%s is distributed in the hope that it will be useful,\n"
544 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
545 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
546 "GNU Lesser General Public License for more details.\n"
548 "You should have received a copy of the GNU Lesser General Public License\n"
549 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
550 program_name, program_name, program_name
552 "%s is free software; you can redistribute it and/or\n"
553 "modify it under the terms of the GNU Lesser General Public\n"
554 "License as published by the Free Software Foundation; either\n"
555 "version 2.1 of the License, or (at your option) any later version.\n"
557 "%s is distributed in the hope that it will be useful,\n"
558 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
559 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
560 "Lesser General Public License for more details.\n"
562 "You should have received a copy of the GNU Lesser General Public\n"
563 "License along with %s; if not, write to the Free Software\n"
564 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
565 program_name, program_name, program_name
571 int opt_formats(const char *opt, const char *arg)
573 AVInputFormat *ifmt=NULL;
574 AVOutputFormat *ofmt=NULL;
575 const char *last_name;
579 " D. = Demuxing supported\n"
580 " .E = Muxing supported\n"
586 const char *name=NULL;
587 const char *long_name=NULL;
589 while((ofmt= av_oformat_next(ofmt))) {
590 if((name == NULL || strcmp(ofmt->name, name)<0) &&
591 strcmp(ofmt->name, last_name)>0){
593 long_name= ofmt->long_name;
597 while((ifmt= av_iformat_next(ifmt))) {
598 if((name == NULL || strcmp(ifmt->name, name)<0) &&
599 strcmp(ifmt->name, last_name)>0){
601 long_name= ifmt->long_name;
604 if(name && strcmp(ifmt->name, name)==0)
616 long_name ? long_name:" ");
621 int opt_codecs(const char *opt, const char *arg)
623 AVCodec *p=NULL, *p2;
624 const char *last_name;
627 " D..... = Decoding supported\n"
628 " .E.... = Encoding supported\n"
629 " ..V... = Video codec\n"
630 " ..A... = Audio codec\n"
631 " ..S... = Subtitle codec\n"
632 " ...S.. = Supports draw_horiz_band\n"
633 " ....D. = Supports direct rendering method 1\n"
634 " .....T = Supports weird frame truncation\n"
641 const char *type_str;
644 while((p= av_codec_next(p))) {
645 if((p2==NULL || strcmp(p->name, p2->name)<0) &&
646 strcmp(p->name, last_name)>0){
648 decode= encode= cap=0;
650 if(p2 && strcmp(p->name, p2->name)==0){
651 if(p->decode) decode=1;
652 if(p->encode) encode=1;
653 cap |= p->capabilities;
661 case AVMEDIA_TYPE_VIDEO:
664 case AVMEDIA_TYPE_AUDIO:
667 case AVMEDIA_TYPE_SUBTITLE:
675 " %s%s%s%s%s%s %-15s %s",
676 decode ? "D": (/*p2->decoder ? "d":*/" "),
679 cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
680 cap & CODEC_CAP_DR1 ? "D":" ",
681 cap & CODEC_CAP_TRUNCATED ? "T":" ",
683 p2->long_name ? p2->long_name : "");
684 /* if(p2->decoder && decode==0)
685 printf(" use %s for decoding", p2->decoder->name);*/
690 "Note, the names of encoders and decoders do not always match, so there are\n"
691 "several cases where the above table shows encoder only or decoder only entries\n"
692 "even though both encoding and decoding are supported. For example, the h263\n"
693 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
698 int opt_bsfs(const char *opt, const char *arg)
700 AVBitStreamFilter *bsf=NULL;
702 printf("Bitstream filters:\n");
703 while((bsf = av_bitstream_filter_next(bsf)))
704 printf("%s\n", bsf->name);
709 int opt_protocols(const char *opt, const char *arg)
711 URLProtocol *up=NULL;
713 printf("Supported file protocols:\n"
714 "I.. = Input supported\n"
715 ".O. = Output supported\n"
716 "..S = Seek supported\n"
719 while((up = av_protocol_next(up)))
720 printf("%c%c%c %s\n",
721 up->url_read ? 'I' : '.',
722 up->url_write ? 'O' : '.',
723 up->url_seek ? 'S' : '.',
728 int opt_filters(const char *opt, const char *arg)
730 AVFilter av_unused(**filter) = NULL;
732 printf("Filters:\n");
734 while ((filter = av_filter_next(filter)) && *filter)
735 printf("%-16s %s\n", (*filter)->name, (*filter)->description);
740 int opt_pix_fmts(const char *opt, const char *arg)
742 enum PixelFormat pix_fmt;
746 "I.... = Supported Input format for conversion\n"
747 ".O... = Supported Output format for conversion\n"
748 "..H.. = Hardware accelerated format\n"
749 "...P. = Paletted format\n"
750 "....B = Bitstream format\n"
751 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
755 # define sws_isSupportedInput(x) 0
756 # define sws_isSupportedOutput(x) 0
759 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
760 const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
761 printf("%c%c%c%c%c %-16s %d %2d\n",
762 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
763 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
764 pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
765 pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
766 pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
768 pix_desc->nb_components,
769 av_get_bits_per_pixel(pix_desc));
774 int show_sample_fmts(const char *opt, const char *arg)
778 for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
779 printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
786 int yesno = (toupper(c) == 'Y');
788 while (c != '\n' && c != EOF)
794 int read_file(const char *filename, char **bufptr, size_t *size)
796 FILE *f = fopen(filename, "rb");
799 av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename, strerror(errno));
800 return AVERROR(errno);
802 fseek(f, 0, SEEK_END);
804 fseek(f, 0, SEEK_SET);
805 *bufptr = av_malloc(*size + 1);
807 av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
809 return AVERROR(ENOMEM);
811 fread(*bufptr, 1, *size, f);
812 (*bufptr)[*size++] = '\0';
818 FILE *get_preset_file(char *filename, size_t filename_size,
819 const char *preset_name, int is_path, const char *codec_name)
823 const char *base[3]= { getenv("FFMPEG_DATADIR"),
829 av_strlcpy(filename, preset_name, filename_size);
830 f = fopen(filename, "r");
833 char datadir[MAX_PATH], *ls;
836 if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
838 for (ls = datadir; ls < datadir + strlen(datadir); ls++)
839 if (*ls == '\\') *ls = '/';
841 if (ls = strrchr(datadir, '/'))
844 strncat(datadir, "/ffpresets", sizeof(datadir) - 1 - strlen(datadir));
849 for (i = 0; i < 3 && !f; i++) {
852 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name);
853 f = fopen(filename, "r");
854 if (!f && codec_name) {
855 snprintf(filename, filename_size,
856 "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", codec_name, preset_name);
857 f = fopen(filename, "r");
865 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
867 if (*spec <= '9' && *spec >= '0') /* opt:index */
868 return strtol(spec, NULL, 0) == st->index;
869 else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' || *spec == 't') { /* opt:[vasdt] */
870 enum AVMediaType type;
873 case 'v': type = AVMEDIA_TYPE_VIDEO; break;
874 case 'a': type = AVMEDIA_TYPE_AUDIO; break;
875 case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
876 case 'd': type = AVMEDIA_TYPE_DATA; break;
877 case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
878 default: abort(); // never reached, silence warning
880 if (type != st->codec->codec_type)
882 if (*spec++ == ':') { /* possibly followed by :index */
883 int i, index = strtol(spec, NULL, 0);
884 for (i = 0; i < s->nb_streams; i++)
885 if (s->streams[i]->codec->codec_type == type && index-- == 0)
886 return i == st->index;
890 } else if (*spec == 'p' && *(spec + 1) == ':') {
894 prog_id = strtol(spec, &endptr, 0);
895 for (i = 0; i < s->nb_programs; i++) {
896 if (s->programs[i]->id != prog_id)
899 if (*endptr++ == ':') {
900 int stream_idx = strtol(endptr, NULL, 0);
901 return (stream_idx >= 0 && stream_idx < s->programs[i]->nb_stream_indexes &&
902 st->index == s->programs[i]->stream_index[stream_idx]);
905 for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
906 if (st->index == s->programs[i]->stream_index[j])
910 } else if (!*spec) /* empty specifier, matches everything */
913 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
914 return AVERROR(EINVAL);
917 AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
919 AVDictionary *ret = NULL;
920 AVDictionaryEntry *t = NULL;
921 AVCodec *codec = s->oformat ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
922 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
924 const AVClass *cc = avcodec_get_class();
929 switch (codec->type) {
930 case AVMEDIA_TYPE_VIDEO: prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM; break;
931 case AVMEDIA_TYPE_AUDIO: prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM; break;
932 case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
935 while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
936 char *p = strchr(t->key, ':');
938 /* check stream specification in opt name */
940 switch (check_stream_specifier(s, st, p + 1)) {
941 case 1: *p = 0; break;
943 default: return NULL;
946 if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
947 (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ)))
948 av_dict_set(&ret, t->key, t->value, 0);
949 else if (t->key[0] == prefix && av_opt_find(&cc, t->key+1, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))
950 av_dict_set(&ret, t->key+1, t->value, 0);
958 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
965 opts = av_mallocz(s->nb_streams * sizeof(*opts));
967 av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
970 for (i = 0; i < s->nb_streams; i++)
971 opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
975 void *grow_array(void *array, int elem_size, int *size, int new_size)
977 if (new_size >= INT_MAX / elem_size) {
978 av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
981 if (*size < new_size) {
982 uint8_t *tmp = av_realloc(array, new_size*elem_size);
984 av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
987 memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);