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 fprintf(stderr, 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 fprintf(stderr, "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);
308 #define FLAGS(o) ((o)->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
309 int opt_default(const char *opt, const char *arg)
311 const AVOption *oc, *of, *os;
312 char opt_stripped[128];
314 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc = sws_get_class();
316 if (!(p = strchr(opt, ':')))
317 p = opt + strlen(opt);
318 av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
320 if ((oc = av_opt_find(&cc, opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN|AV_OPT_SEARCH_FAKE_OBJ)) ||
321 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
322 (oc = av_opt_find(&cc, opt+1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
323 av_dict_set(&codec_opts, opt, arg, FLAGS(oc));
324 if ((of = av_opt_find(&fc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
325 av_dict_set(&format_opts, opt, arg, FLAGS(of));
326 if ((os = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
327 // XXX we only support sws_flags, not arbitrary sws options
328 int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
330 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
337 fprintf(stderr, "Unrecognized option '%s'\n", opt);
338 return AVERROR_OPTION_NOT_FOUND;
341 int opt_loglevel(const char *opt, const char *arg)
343 const struct { const char *name; int level; } log_levels[] = {
344 { "quiet" , AV_LOG_QUIET },
345 { "panic" , AV_LOG_PANIC },
346 { "fatal" , AV_LOG_FATAL },
347 { "error" , AV_LOG_ERROR },
348 { "warning", AV_LOG_WARNING },
349 { "info" , AV_LOG_INFO },
350 { "verbose", AV_LOG_VERBOSE },
351 { "debug" , AV_LOG_DEBUG },
357 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
358 if (!strcmp(log_levels[i].name, arg)) {
359 av_log_set_level(log_levels[i].level);
364 level = strtol(arg, &tail, 10);
366 fprintf(stderr, "Invalid loglevel \"%s\". "
367 "Possible levels are numbers or:\n", arg);
368 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
369 fprintf(stderr, "\"%s\"\n", log_levels[i].name);
372 av_log_set_level(level);
376 int opt_timelimit(const char *opt, const char *arg)
379 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
380 struct rlimit rl = { lim, lim + 1 };
381 if (setrlimit(RLIMIT_CPU, &rl))
384 fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
389 void print_error(const char *filename, int err)
392 const char *errbuf_ptr = errbuf;
394 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
395 errbuf_ptr = strerror(AVUNERROR(err));
396 fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
399 static int warned_cfg = 0;
402 #define SHOW_VERSION 2
403 #define SHOW_CONFIG 4
405 #define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags) \
406 if (CONFIG_##LIBNAME) { \
407 const char *indent = flags & INDENT? " " : ""; \
408 if (flags & SHOW_VERSION) { \
409 unsigned int version = libname##_version(); \
410 fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
412 LIB##LIBNAME##_VERSION_MAJOR, \
413 LIB##LIBNAME##_VERSION_MINOR, \
414 LIB##LIBNAME##_VERSION_MICRO, \
415 version >> 16, version >> 8 & 0xff, version & 0xff); \
417 if (flags & SHOW_CONFIG) { \
418 const char *cfg = libname##_configuration(); \
419 if (strcmp(FFMPEG_CONFIGURATION, cfg)) { \
422 "%sWARNING: library configuration mismatch\n", \
426 fprintf(stderr, "%s%-11s configuration: %s\n", \
427 indent, #libname, cfg); \
432 static void print_all_libs_info(FILE* outstream, int flags)
434 PRINT_LIB_INFO(outstream, avutil, AVUTIL, flags);
435 PRINT_LIB_INFO(outstream, avcodec, AVCODEC, flags);
436 PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
437 PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
438 PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
439 PRINT_LIB_INFO(outstream, swscale, SWSCALE, flags);
440 PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
443 void show_banner(void)
445 fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n",
446 program_name, program_birth_year, this_year);
447 fprintf(stderr, " built on %s %s with %s %s\n",
448 __DATE__, __TIME__, CC_TYPE, CC_VERSION);
449 fprintf(stderr, " configuration: " FFMPEG_CONFIGURATION "\n");
450 print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
451 print_all_libs_info(stderr, INDENT|SHOW_VERSION);
454 int opt_version(const char *opt, const char *arg) {
455 printf("%s " FFMPEG_VERSION "\n", program_name);
456 print_all_libs_info(stdout, SHOW_VERSION);
460 int opt_license(const char *opt, const char *arg)
464 "This version of %s has nonfree parts compiled in.\n"
465 "Therefore it is not legally redistributable.\n",
468 "%s is free software; you can redistribute it and/or modify\n"
469 "it under the terms of the GNU General Public License as published by\n"
470 "the Free Software Foundation; either version 3 of the License, or\n"
471 "(at your option) any later version.\n"
473 "%s is distributed in the hope that it will be useful,\n"
474 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
475 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
476 "GNU General Public License for more details.\n"
478 "You should have received a copy of the GNU General Public License\n"
479 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
480 program_name, program_name, program_name
482 "%s is free software; you can redistribute it and/or modify\n"
483 "it under the terms of the GNU General Public License as published by\n"
484 "the Free Software Foundation; either version 2 of the License, or\n"
485 "(at your option) any later version.\n"
487 "%s is distributed in the hope that it will be useful,\n"
488 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
489 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
490 "GNU General Public License for more details.\n"
492 "You should have received a copy of the GNU General Public License\n"
493 "along with %s; if not, write to the Free Software\n"
494 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
495 program_name, program_name, program_name
497 "%s is free software; you can redistribute it and/or modify\n"
498 "it under the terms of the GNU Lesser General Public License as published by\n"
499 "the Free Software Foundation; either version 3 of the License, or\n"
500 "(at your option) any later version.\n"
502 "%s is distributed in the hope that it will be useful,\n"
503 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
504 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
505 "GNU Lesser General Public License for more details.\n"
507 "You should have received a copy of the GNU Lesser General Public License\n"
508 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
509 program_name, program_name, program_name
511 "%s is free software; you can redistribute it and/or\n"
512 "modify it under the terms of the GNU Lesser General Public\n"
513 "License as published by the Free Software Foundation; either\n"
514 "version 2.1 of the License, or (at your option) any later version.\n"
516 "%s is distributed in the hope that it will be useful,\n"
517 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
518 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
519 "Lesser General Public License for more details.\n"
521 "You should have received a copy of the GNU Lesser General Public\n"
522 "License along with %s; if not, write to the Free Software\n"
523 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
524 program_name, program_name, program_name
530 int opt_formats(const char *opt, const char *arg)
532 AVInputFormat *ifmt=NULL;
533 AVOutputFormat *ofmt=NULL;
534 const char *last_name;
538 " D. = Demuxing supported\n"
539 " .E = Muxing supported\n"
545 const char *name=NULL;
546 const char *long_name=NULL;
548 while((ofmt= av_oformat_next(ofmt))) {
549 if((name == NULL || strcmp(ofmt->name, name)<0) &&
550 strcmp(ofmt->name, last_name)>0){
552 long_name= ofmt->long_name;
556 while((ifmt= av_iformat_next(ifmt))) {
557 if((name == NULL || strcmp(ifmt->name, name)<0) &&
558 strcmp(ifmt->name, last_name)>0){
560 long_name= ifmt->long_name;
563 if(name && strcmp(ifmt->name, name)==0)
575 long_name ? long_name:" ");
580 int opt_codecs(const char *opt, const char *arg)
582 AVCodec *p=NULL, *p2;
583 const char *last_name;
586 " D..... = Decoding supported\n"
587 " .E.... = Encoding supported\n"
588 " ..V... = Video codec\n"
589 " ..A... = Audio codec\n"
590 " ..S... = Subtitle codec\n"
591 " ...S.. = Supports draw_horiz_band\n"
592 " ....D. = Supports direct rendering method 1\n"
593 " .....T = Supports weird frame truncation\n"
600 const char *type_str;
603 while((p= av_codec_next(p))) {
604 if((p2==NULL || strcmp(p->name, p2->name)<0) &&
605 strcmp(p->name, last_name)>0){
607 decode= encode= cap=0;
609 if(p2 && strcmp(p->name, p2->name)==0){
610 if(p->decode) decode=1;
611 if(p->encode) encode=1;
612 cap |= p->capabilities;
620 case AVMEDIA_TYPE_VIDEO:
623 case AVMEDIA_TYPE_AUDIO:
626 case AVMEDIA_TYPE_SUBTITLE:
634 " %s%s%s%s%s%s %-15s %s",
635 decode ? "D": (/*p2->decoder ? "d":*/" "),
638 cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
639 cap & CODEC_CAP_DR1 ? "D":" ",
640 cap & CODEC_CAP_TRUNCATED ? "T":" ",
642 p2->long_name ? p2->long_name : "");
643 /* if(p2->decoder && decode==0)
644 printf(" use %s for decoding", p2->decoder->name);*/
649 "Note, the names of encoders and decoders do not always match, so there are\n"
650 "several cases where the above table shows encoder only or decoder only entries\n"
651 "even though both encoding and decoding are supported. For example, the h263\n"
652 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
657 int opt_bsfs(const char *opt, const char *arg)
659 AVBitStreamFilter *bsf=NULL;
661 printf("Bitstream filters:\n");
662 while((bsf = av_bitstream_filter_next(bsf)))
663 printf("%s\n", bsf->name);
668 int opt_protocols(const char *opt, const char *arg)
670 URLProtocol *up=NULL;
672 printf("Supported file protocols:\n"
673 "I.. = Input supported\n"
674 ".O. = Output supported\n"
675 "..S = Seek supported\n"
678 while((up = av_protocol_next(up)))
679 printf("%c%c%c %s\n",
680 up->url_read ? 'I' : '.',
681 up->url_write ? 'O' : '.',
682 up->url_seek ? 'S' : '.',
687 int opt_filters(const char *opt, const char *arg)
689 AVFilter av_unused(**filter) = NULL;
691 printf("Filters:\n");
693 while ((filter = av_filter_next(filter)) && *filter)
694 printf("%-16s %s\n", (*filter)->name, (*filter)->description);
699 int opt_pix_fmts(const char *opt, const char *arg)
701 enum PixelFormat pix_fmt;
705 "I.... = Supported Input format for conversion\n"
706 ".O... = Supported Output format for conversion\n"
707 "..H.. = Hardware accelerated format\n"
708 "...P. = Paletted format\n"
709 "....B = Bitstream format\n"
710 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
714 # define sws_isSupportedInput(x) 0
715 # define sws_isSupportedOutput(x) 0
718 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
719 const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
720 printf("%c%c%c%c%c %-16s %d %2d\n",
721 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
722 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
723 pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
724 pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
725 pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
727 pix_desc->nb_components,
728 av_get_bits_per_pixel(pix_desc));
736 int yesno = (toupper(c) == 'Y');
738 while (c != '\n' && c != EOF)
744 int read_file(const char *filename, char **bufptr, size_t *size)
746 FILE *f = fopen(filename, "rb");
749 fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
750 return AVERROR(errno);
752 fseek(f, 0, SEEK_END);
754 fseek(f, 0, SEEK_SET);
755 *bufptr = av_malloc(*size + 1);
757 fprintf(stderr, "Could not allocate file buffer\n");
759 return AVERROR(ENOMEM);
761 fread(*bufptr, 1, *size, f);
762 (*bufptr)[*size++] = '\0';
768 FILE *get_preset_file(char *filename, size_t filename_size,
769 const char *preset_name, int is_path, const char *codec_name)
773 const char *base[3]= { getenv("FFMPEG_DATADIR"),
779 av_strlcpy(filename, preset_name, filename_size);
780 f = fopen(filename, "r");
783 char datadir[MAX_PATH], *ls;
786 if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
788 for (ls = datadir; ls < datadir + strlen(datadir); ls++)
789 if (*ls == '\\') *ls = '/';
791 if (ls = strrchr(datadir, '/'))
794 strncat(datadir, "/ffpresets", sizeof(datadir) - 1 - strlen(datadir));
799 for (i = 0; i < 3 && !f; i++) {
802 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name);
803 f = fopen(filename, "r");
804 if (!f && codec_name) {
805 snprintf(filename, filename_size,
806 "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", codec_name, preset_name);
807 f = fopen(filename, "r");
815 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
817 if (*spec <= '9' && *spec >= '0') /* opt:index */
818 return strtol(spec, NULL, 0) == st->index;
819 else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd') { /* opt:[vasd] */
820 enum AVMediaType type;
823 case 'v': type = AVMEDIA_TYPE_VIDEO; break;
824 case 'a': type = AVMEDIA_TYPE_AUDIO; break;
825 case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
826 case 'd': type = AVMEDIA_TYPE_DATA; break;
827 default: abort(); // never reached, silence warning
829 if (type != st->codec->codec_type)
831 if (*spec++ == ':') { /* possibly followed by :index */
832 int i, index = strtol(spec, NULL, 0);
833 for (i = 0; i < s->nb_streams; i++)
834 if (s->streams[i]->codec->codec_type == type && index-- == 0)
835 return i == st->index;
839 } else if (!*spec) /* empty specifier, matches everything */
842 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
843 return AVERROR(EINVAL);
846 AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
848 AVDictionary *ret = NULL;
849 AVDictionaryEntry *t = NULL;
850 AVCodec *codec = s->oformat ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
851 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
853 const AVClass *cc = avcodec_get_class();
858 switch (codec->type) {
859 case AVMEDIA_TYPE_VIDEO: prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM; break;
860 case AVMEDIA_TYPE_AUDIO: prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM; break;
861 case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
864 while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
865 char *p = strchr(t->key, ':');
867 /* check stream specification in opt name */
869 switch (check_stream_specifier(s, st, p + 1)) {
870 case 1: *p = 0; break;
872 default: return NULL;
875 if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
876 (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ)))
877 av_dict_set(&ret, t->key, t->value, 0);
878 else if (t->key[0] == prefix && av_opt_find(&cc, t->key+1, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))
879 av_dict_set(&ret, t->key+1, t->value, 0);
887 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
894 opts = av_mallocz(s->nb_streams * sizeof(*opts));
896 av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
899 for (i = 0; i < s->nb_streams; i++)
900 opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
904 void *grow_array(void *array, int elem_size, int *size, int new_size)
906 if (new_size >= INT_MAX / elem_size) {
907 av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
910 if (*size < new_size) {
911 uint8_t *tmp = av_realloc(array, new_size*elem_size);
913 av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
916 memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);