2 * Various utilities for command line tools
3 * Copyright (c) 2000-2003 Fabrice Bellard
5 * This file is part of Libav.
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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 AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
53 AVFormatContext *avformat_opts;
54 struct SwsContext *sws_opts;
55 AVDictionary *format_opts, *codec_opts;
57 static const int this_year = 2011;
62 for (i = 0; i < AVMEDIA_TYPE_NB; i++)
63 avcodec_opts[i] = avcodec_alloc_context3(NULL);
64 avformat_opts = avformat_alloc_context();
66 sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
70 void uninit_opts(void)
73 for (i = 0; i < AVMEDIA_TYPE_NB; i++)
74 av_freep(&avcodec_opts[i]);
75 av_freep(&avformat_opts->key);
76 av_freep(&avformat_opts);
78 sws_freeContext(sws_opts);
81 av_dict_free(&format_opts);
82 av_dict_free(&codec_opts);
85 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
87 vfprintf(stdout, fmt, vl);
90 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
94 double d = av_strtod(numstr, &tail);
96 error= "Expected number for %s but found: %s\n";
97 else if (d < min || d > max)
98 error= "The value for %s was %s which is not within %f - %f\n";
99 else if(type == OPT_INT64 && (int64_t)d != d)
100 error= "Expected int64 for %s but found %s\n";
101 else if (type == OPT_INT && (int)d != d)
102 error= "Expected int for %s but found %s\n";
105 fprintf(stderr, error, context, numstr, min, max);
109 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
112 if (av_parse_time(&us, timestr, is_duration) < 0) {
113 fprintf(stderr, "Invalid %s specification for %s: %s\n",
114 is_duration ? "duration" : "date", context, timestr);
120 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
126 for(po = options; po->name != NULL; po++) {
128 if ((po->flags & mask) == value) {
133 av_strlcpy(buf, po->name, sizeof(buf));
134 if (po->flags & HAS_ARG) {
135 av_strlcat(buf, " ", sizeof(buf));
136 av_strlcat(buf, po->argname, sizeof(buf));
138 printf("-%-17s %s\n", buf, po->help);
143 static const OptionDef* find_option(const OptionDef *po, const char *name){
144 const char *p = strchr(name, ':');
145 int len = p ? p - name : strlen(name);
147 while (po->name != NULL) {
148 if (!strncmp(name, po->name, len) && strlen(po->name) == len)
155 #if defined(_WIN32) && !defined(__MINGW32CE__)
157 /* Will be leaked on exit */
158 static char** win32_argv_utf8 = NULL;
159 static int win32_argc = 0;
162 * Prepare command line arguments for executable.
163 * For Windows - perform wide-char to UTF-8 conversion.
164 * Input arguments should be main() function arguments.
165 * @param argc_ptr Arguments number (including executable)
166 * @param argv_ptr Arguments list.
168 static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
172 int i, buffsize = 0, offset = 0;
174 if (win32_argv_utf8) {
175 *argc_ptr = win32_argc;
176 *argv_ptr = win32_argv_utf8;
181 argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
182 if (win32_argc <= 0 || !argv_w)
185 /* determine the UTF-8 buffer size (including NULL-termination symbols) */
186 for (i = 0; i < win32_argc; i++)
187 buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
188 NULL, 0, NULL, NULL);
190 win32_argv_utf8 = av_mallocz(sizeof(char*) * (win32_argc + 1) + buffsize);
191 argstr_flat = (char*)win32_argv_utf8 + sizeof(char*) * (win32_argc + 1);
192 if (win32_argv_utf8 == NULL) {
197 for (i = 0; i < win32_argc; i++) {
198 win32_argv_utf8[i] = &argstr_flat[offset];
199 offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
200 &argstr_flat[offset],
201 buffsize - offset, NULL, NULL);
203 win32_argv_utf8[i] = NULL;
206 *argc_ptr = win32_argc;
207 *argv_ptr = win32_argv_utf8;
210 static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
214 #endif /* WIN32 && !__MINGW32CE__ */
216 void parse_options(int argc, char **argv, const OptionDef *options,
217 void (* parse_arg_function)(const char*))
219 const char *opt, *arg;
220 int optindex, handleoptions=1;
223 /* perform system-dependent conversions for arguments list */
224 prepare_app_arguments(&argc, &argv);
228 while (optindex < argc) {
229 opt = argv[optindex++];
231 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
233 if (opt[1] == '-' && opt[2] == '\0') {
238 po= find_option(options, opt);
239 if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
240 /* handle 'no' bool option */
241 po = find_option(options, opt + 2);
242 if (!(po->name && (po->flags & OPT_BOOL)))
247 po= find_option(options, "default");
250 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
254 if (po->flags & HAS_ARG) {
255 arg = argv[optindex++];
257 fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
261 if (po->flags & OPT_STRING) {
263 str = av_strdup(arg);
264 *po->u.str_arg = str;
265 } else if (po->flags & OPT_BOOL) {
266 *po->u.int_arg = bool_val;
267 } else if (po->flags & OPT_INT) {
268 *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
269 } else if (po->flags & OPT_INT64) {
270 *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
271 } else if (po->flags & OPT_FLOAT) {
272 *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
273 } else if (po->u.func_arg) {
274 if (po->u.func_arg(opt, arg) < 0) {
275 fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
279 if(po->flags & OPT_EXIT)
282 if (parse_arg_function)
283 parse_arg_function(opt);
288 #define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
289 int opt_default(const char *opt, const char *arg)
292 char opt_stripped[128];
295 if (!(p = strchr(opt, ':')))
296 p = opt + strlen(opt);
297 av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
299 if ((o = av_opt_find(avcodec_opts[0], opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN)) ||
300 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
301 (o = av_opt_find(avcodec_opts[0], opt+1, NULL, 0, 0))))
302 av_dict_set(&codec_opts, opt, arg, FLAGS);
303 else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)))
304 av_dict_set(&format_opts, opt, arg, FLAGS);
305 else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
306 // XXX we only support sws_flags, not arbitrary sws options
307 int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
309 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
316 fprintf(stderr, "Unrecognized option '%s'\n", opt);
317 return AVERROR_OPTION_NOT_FOUND;
320 int opt_loglevel(const char *opt, const char *arg)
322 const struct { const char *name; int level; } log_levels[] = {
323 { "quiet" , AV_LOG_QUIET },
324 { "panic" , AV_LOG_PANIC },
325 { "fatal" , AV_LOG_FATAL },
326 { "error" , AV_LOG_ERROR },
327 { "warning", AV_LOG_WARNING },
328 { "info" , AV_LOG_INFO },
329 { "verbose", AV_LOG_VERBOSE },
330 { "debug" , AV_LOG_DEBUG },
336 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
337 if (!strcmp(log_levels[i].name, arg)) {
338 av_log_set_level(log_levels[i].level);
343 level = strtol(arg, &tail, 10);
345 fprintf(stderr, "Invalid loglevel \"%s\". "
346 "Possible levels are numbers or:\n", arg);
347 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
348 fprintf(stderr, "\"%s\"\n", log_levels[i].name);
351 av_log_set_level(level);
355 int opt_timelimit(const char *opt, const char *arg)
358 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
359 struct rlimit rl = { lim, lim + 1 };
360 if (setrlimit(RLIMIT_CPU, &rl))
363 fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
368 void print_error(const char *filename, int err)
371 const char *errbuf_ptr = errbuf;
373 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
374 errbuf_ptr = strerror(AVUNERROR(err));
375 fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
378 static int warned_cfg = 0;
381 #define SHOW_VERSION 2
382 #define SHOW_CONFIG 4
384 #define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags) \
385 if (CONFIG_##LIBNAME) { \
386 const char *indent = flags & INDENT? " " : ""; \
387 if (flags & SHOW_VERSION) { \
388 unsigned int version = libname##_version(); \
389 fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
391 LIB##LIBNAME##_VERSION_MAJOR, \
392 LIB##LIBNAME##_VERSION_MINOR, \
393 LIB##LIBNAME##_VERSION_MICRO, \
394 version >> 16, version >> 8 & 0xff, version & 0xff); \
396 if (flags & SHOW_CONFIG) { \
397 const char *cfg = libname##_configuration(); \
398 if (strcmp(LIBAV_CONFIGURATION, cfg)) { \
401 "%sWARNING: library configuration mismatch\n", \
405 fprintf(stderr, "%s%-11s configuration: %s\n", \
406 indent, #libname, cfg); \
411 static void print_all_libs_info(FILE* outstream, int flags)
413 PRINT_LIB_INFO(outstream, avutil, AVUTIL, flags);
414 PRINT_LIB_INFO(outstream, avcodec, AVCODEC, flags);
415 PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
416 PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
417 PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
418 PRINT_LIB_INFO(outstream, swscale, SWSCALE, flags);
419 PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
422 void show_banner(void)
424 fprintf(stderr, "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
425 program_name, program_birth_year, this_year);
426 fprintf(stderr, " built on %s %s with %s %s\n",
427 __DATE__, __TIME__, CC_TYPE, CC_VERSION);
428 fprintf(stderr, " configuration: " LIBAV_CONFIGURATION "\n");
429 print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
430 print_all_libs_info(stderr, INDENT|SHOW_VERSION);
433 void show_version(void) {
434 printf("%s " LIBAV_VERSION "\n", program_name);
435 print_all_libs_info(stdout, SHOW_VERSION);
438 void show_license(void)
442 "This version of %s has nonfree parts compiled in.\n"
443 "Therefore it is not legally redistributable.\n",
446 "%s is free software; you can redistribute it and/or modify\n"
447 "it under the terms of the GNU General Public License as published by\n"
448 "the Free Software Foundation; either version 3 of the License, or\n"
449 "(at your option) any later version.\n"
451 "%s is distributed in the hope that it will be useful,\n"
452 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
453 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
454 "GNU General Public License for more details.\n"
456 "You should have received a copy of the GNU General Public License\n"
457 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
458 program_name, program_name, program_name
460 "%s is free software; you can redistribute it and/or modify\n"
461 "it under the terms of the GNU General Public License as published by\n"
462 "the Free Software Foundation; either version 2 of the License, or\n"
463 "(at your option) any later version.\n"
465 "%s is distributed in the hope that it will be useful,\n"
466 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
467 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
468 "GNU General Public License for more details.\n"
470 "You should have received a copy of the GNU General Public License\n"
471 "along with %s; if not, write to the Free Software\n"
472 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
473 program_name, program_name, program_name
475 "%s is free software; you can redistribute it and/or modify\n"
476 "it under the terms of the GNU Lesser General Public License as published by\n"
477 "the Free Software Foundation; either version 3 of the License, or\n"
478 "(at your option) any later version.\n"
480 "%s is distributed in the hope that it will be useful,\n"
481 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
482 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
483 "GNU Lesser General Public License for more details.\n"
485 "You should have received a copy of the GNU Lesser General Public License\n"
486 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
487 program_name, program_name, program_name
489 "%s is free software; you can redistribute it and/or\n"
490 "modify it under the terms of the GNU Lesser General Public\n"
491 "License as published by the Free Software Foundation; either\n"
492 "version 2.1 of the License, or (at your option) any later version.\n"
494 "%s is distributed in the hope that it will be useful,\n"
495 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
496 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
497 "Lesser General Public License for more details.\n"
499 "You should have received a copy of the GNU Lesser General Public\n"
500 "License along with %s; if not, write to the Free Software\n"
501 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
502 program_name, program_name, program_name
507 void show_formats(void)
509 AVInputFormat *ifmt=NULL;
510 AVOutputFormat *ofmt=NULL;
511 const char *last_name;
515 " D. = Demuxing supported\n"
516 " .E = Muxing supported\n"
522 const char *name=NULL;
523 const char *long_name=NULL;
525 while((ofmt= av_oformat_next(ofmt))) {
526 if((name == NULL || strcmp(ofmt->name, name)<0) &&
527 strcmp(ofmt->name, last_name)>0){
529 long_name= ofmt->long_name;
533 while((ifmt= av_iformat_next(ifmt))) {
534 if((name == NULL || strcmp(ifmt->name, name)<0) &&
535 strcmp(ifmt->name, last_name)>0){
537 long_name= ifmt->long_name;
540 if(name && strcmp(ifmt->name, name)==0)
552 long_name ? long_name:" ");
556 void show_codecs(void)
558 AVCodec *p=NULL, *p2;
559 const char *last_name;
562 " D..... = Decoding supported\n"
563 " .E.... = Encoding supported\n"
564 " ..V... = Video codec\n"
565 " ..A... = Audio codec\n"
566 " ..S... = Subtitle codec\n"
567 " ...S.. = Supports draw_horiz_band\n"
568 " ....D. = Supports direct rendering method 1\n"
569 " .....T = Supports weird frame truncation\n"
576 const char *type_str;
579 while((p= av_codec_next(p))) {
580 if((p2==NULL || strcmp(p->name, p2->name)<0) &&
581 strcmp(p->name, last_name)>0){
583 decode= encode= cap=0;
585 if(p2 && strcmp(p->name, p2->name)==0){
586 if(p->decode) decode=1;
587 if(p->encode) encode=1;
588 cap |= p->capabilities;
596 case AVMEDIA_TYPE_VIDEO:
599 case AVMEDIA_TYPE_AUDIO:
602 case AVMEDIA_TYPE_SUBTITLE:
610 " %s%s%s%s%s%s %-15s %s",
611 decode ? "D": (/*p2->decoder ? "d":*/" "),
614 cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
615 cap & CODEC_CAP_DR1 ? "D":" ",
616 cap & CODEC_CAP_TRUNCATED ? "T":" ",
618 p2->long_name ? p2->long_name : "");
619 /* if(p2->decoder && decode==0)
620 printf(" use %s for decoding", p2->decoder->name);*/
625 "Note, the names of encoders and decoders do not always match, so there are\n"
626 "several cases where the above table shows encoder only or decoder only entries\n"
627 "even though both encoding and decoding are supported. For example, the h263\n"
628 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
634 AVBitStreamFilter *bsf=NULL;
636 printf("Bitstream filters:\n");
637 while((bsf = av_bitstream_filter_next(bsf)))
638 printf("%s\n", bsf->name);
642 void show_protocols(void)
647 printf("Supported file protocols:\n"
649 while ((name = avio_enum_protocols(&opaque, 0)))
650 printf("%s\n", name);
652 while ((name = avio_enum_protocols(&opaque, 1)))
653 printf("%s\n", name);
656 void show_filters(void)
658 AVFilter av_unused(**filter) = NULL;
660 printf("Filters:\n");
662 while ((filter = av_filter_next(filter)) && *filter)
663 printf("%-16s %s\n", (*filter)->name, (*filter)->description);
667 void show_pix_fmts(void)
669 enum PixelFormat pix_fmt;
673 "I.... = Supported Input format for conversion\n"
674 ".O... = Supported Output format for conversion\n"
675 "..H.. = Hardware accelerated format\n"
676 "...P. = Paletted format\n"
677 "....B = Bitstream format\n"
678 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
682 # define sws_isSupportedInput(x) 0
683 # define sws_isSupportedOutput(x) 0
686 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
687 const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
688 printf("%c%c%c%c%c %-16s %d %2d\n",
689 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
690 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
691 pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
692 pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
693 pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
695 pix_desc->nb_components,
696 av_get_bits_per_pixel(pix_desc));
703 int yesno = (toupper(c) == 'Y');
705 while (c != '\n' && c != EOF)
711 int read_file(const char *filename, char **bufptr, size_t *size)
713 FILE *f = fopen(filename, "rb");
716 fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
717 return AVERROR(errno);
719 fseek(f, 0, SEEK_END);
721 fseek(f, 0, SEEK_SET);
722 *bufptr = av_malloc(*size + 1);
724 fprintf(stderr, "Could not allocate file buffer\n");
726 return AVERROR(ENOMEM);
728 fread(*bufptr, 1, *size, f);
729 (*bufptr)[*size++] = '\0';
735 void init_pts_correction(PtsCorrectionContext *ctx)
737 ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
738 ctx->last_pts = ctx->last_dts = INT64_MIN;
741 int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts, int64_t dts)
743 int64_t pts = AV_NOPTS_VALUE;
745 if (dts != AV_NOPTS_VALUE) {
746 ctx->num_faulty_dts += dts <= ctx->last_dts;
749 if (reordered_pts != AV_NOPTS_VALUE) {
750 ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
751 ctx->last_pts = reordered_pts;
753 if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
754 && reordered_pts != AV_NOPTS_VALUE)
762 FILE *get_preset_file(char *filename, size_t filename_size,
763 const char *preset_name, int is_path, const char *codec_name)
767 const char *base[3]= { getenv("AVCONV_DATADIR"),
773 av_strlcpy(filename, preset_name, filename_size);
774 f = fopen(filename, "r");
776 for (i = 0; i < 3 && !f; i++) {
779 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", preset_name);
780 f = fopen(filename, "r");
781 if (!f && codec_name) {
782 snprintf(filename, filename_size,
783 "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", codec_name, preset_name);
784 f = fopen(filename, "r");
792 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
794 if (*spec <= '9' && *spec >= '0') /* opt:index */
795 return strtol(spec, NULL, 0) == st->index;
796 else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd') { /* opt:[vasd] */
797 enum AVMediaType type;
800 case 'v': type = AVMEDIA_TYPE_VIDEO; break;
801 case 'a': type = AVMEDIA_TYPE_AUDIO; break;
802 case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
803 case 'd': type = AVMEDIA_TYPE_DATA; break;
805 if (type != st->codec->codec_type)
807 if (*spec++ == ':') { /* possibly followed by :index */
808 int i, index = strtol(spec, NULL, 0);
809 for (i = 0; i < s->nb_streams; i++)
810 if (s->streams[i]->codec->codec_type == type && index-- == 0)
811 return i == st->index;
815 } else if (!*spec) /* empty specifier, matches everything */
818 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
819 return AVERROR(EINVAL);
822 AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
824 AVDictionary *ret = NULL;
825 AVDictionaryEntry *t = NULL;
826 AVCodec *codec = s->oformat ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
827 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
833 switch (codec->type) {
834 case AVMEDIA_TYPE_VIDEO: prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM; break;
835 case AVMEDIA_TYPE_AUDIO: prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM; break;
836 case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
839 while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
840 char *p = strchr(t->key, ':');
842 /* check stream specification in opt name */
844 switch (check_stream_specifier(s, st, p + 1)) {
845 case 1: *p = 0; break;
847 default: return NULL;
850 if (av_opt_find(avcodec_opts[0], t->key, NULL, flags, 0) ||
851 (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, 0)))
852 av_dict_set(&ret, t->key, t->value, 0);
853 else if (t->key[0] == prefix && av_opt_find(avcodec_opts[0], t->key+1, NULL, flags, 0))
854 av_dict_set(&ret, t->key+1, t->value, 0);
862 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
869 opts = av_mallocz(s->nb_streams * sizeof(*opts));
871 av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
874 for (i = 0; i < s->nb_streams; i++)
875 opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
881 static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
883 FFSinkContext *priv = ctx->priv;
886 return AVERROR(EINVAL);
887 *priv = *(FFSinkContext *)opaque;
892 static void null_end_frame(AVFilterLink *inlink) { }
894 static int ffsink_query_formats(AVFilterContext *ctx)
896 FFSinkContext *priv = ctx->priv;
897 enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
899 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
905 .priv_size = sizeof(FFSinkContext),
908 .query_formats = ffsink_query_formats,
910 .inputs = (AVFilterPad[]) {{ .name = "default",
911 .type = AVMEDIA_TYPE_VIDEO,
912 .end_frame = null_end_frame,
913 .min_perms = AV_PERM_READ, },
915 .outputs = (AVFilterPad[]) {{ .name = NULL }},
918 int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
919 AVFilterBufferRef **picref_ptr, AVRational *tb)
922 AVFilterBufferRef *picref;
924 if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
926 if (!(picref = ctx->inputs[0]->cur_buf))
927 return AVERROR(ENOENT);
928 *picref_ptr = picref;
929 ctx->inputs[0]->cur_buf = NULL;
930 *tb = ctx->inputs[0]->time_base;
932 memcpy(frame->data, picref->data, sizeof(frame->data));
933 memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
934 frame->interlaced_frame = picref->video->interlaced;
935 frame->top_field_first = picref->video->top_field_first;
936 frame->key_frame = picref->video->key_frame;
937 frame->pict_type = picref->video->pict_type;
942 #endif /* CONFIG_AVFILTER */