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 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);
98 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
101 if (av_parse_time(&us, timestr, is_duration) < 0) {
102 fprintf(stderr, "Invalid %s specification for %s: %s\n",
103 is_duration ? "duration" : "date", context, timestr);
109 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
115 for(po = options; po->name != NULL; po++) {
117 if ((po->flags & mask) == value) {
122 av_strlcpy(buf, po->name, sizeof(buf));
123 if (po->flags & HAS_ARG) {
124 av_strlcat(buf, " ", sizeof(buf));
125 av_strlcat(buf, po->argname, sizeof(buf));
127 printf("-%-17s %s\n", buf, po->help);
132 static const OptionDef* find_option(const OptionDef *po, const char *name){
133 const char *p = strchr(name, ':');
134 int len = p ? p - name : strlen(name);
136 while (po->name != NULL) {
137 if (!strncmp(name, po->name, len) && strlen(po->name) == len)
144 #if defined(_WIN32) && !defined(__MINGW32CE__)
146 /* Will be leaked on exit */
147 static char** win32_argv_utf8 = NULL;
148 static int win32_argc = 0;
151 * Prepare command line arguments for executable.
152 * For Windows - perform wide-char to UTF-8 conversion.
153 * Input arguments should be main() function arguments.
154 * @param argc_ptr Arguments number (including executable)
155 * @param argv_ptr Arguments list.
157 static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
161 int i, buffsize = 0, offset = 0;
163 if (win32_argv_utf8) {
164 *argc_ptr = win32_argc;
165 *argv_ptr = win32_argv_utf8;
170 argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
171 if (win32_argc <= 0 || !argv_w)
174 /* determine the UTF-8 buffer size (including NULL-termination symbols) */
175 for (i = 0; i < win32_argc; i++)
176 buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
177 NULL, 0, NULL, NULL);
179 win32_argv_utf8 = av_mallocz(sizeof(char*) * (win32_argc + 1) + buffsize);
180 argstr_flat = (char*)win32_argv_utf8 + sizeof(char*) * (win32_argc + 1);
181 if (win32_argv_utf8 == NULL) {
186 for (i = 0; i < win32_argc; i++) {
187 win32_argv_utf8[i] = &argstr_flat[offset];
188 offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
189 &argstr_flat[offset],
190 buffsize - offset, NULL, NULL);
192 win32_argv_utf8[i] = NULL;
195 *argc_ptr = win32_argc;
196 *argv_ptr = win32_argv_utf8;
199 static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
203 #endif /* WIN32 && !__MINGW32CE__ */
205 void parse_options(int argc, char **argv, const OptionDef *options,
206 void (* parse_arg_function)(const char*))
208 const char *opt, *arg;
209 int optindex, handleoptions=1;
212 /* perform system-dependent conversions for arguments list */
213 prepare_app_arguments(&argc, &argv);
217 while (optindex < argc) {
218 opt = argv[optindex++];
220 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
222 if (opt[1] == '-' && opt[2] == '\0') {
227 po= find_option(options, opt);
228 if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
229 /* handle 'no' bool option */
230 po = find_option(options, opt + 2);
231 if (!(po->name && (po->flags & OPT_BOOL)))
236 po= find_option(options, "default");
239 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
243 if (po->flags & HAS_ARG) {
244 arg = argv[optindex++];
246 fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
250 if (po->flags & OPT_STRING) {
252 str = av_strdup(arg);
253 *po->u.str_arg = str;
254 } else if (po->flags & OPT_BOOL) {
255 *po->u.int_arg = bool_val;
256 } else if (po->flags & OPT_INT) {
257 *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
258 } else if (po->flags & OPT_INT64) {
259 *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
260 } else if (po->flags & OPT_FLOAT) {
261 *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
262 } else if (po->u.func_arg) {
263 if (po->u.func_arg(opt, arg) < 0) {
264 fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
268 if(po->flags & OPT_EXIT)
271 if (parse_arg_function)
272 parse_arg_function(opt);
277 #define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
278 int opt_default(const char *opt, const char *arg)
281 char opt_stripped[128];
283 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc = sws_get_class();
285 if (!(p = strchr(opt, ':')))
286 p = opt + strlen(opt);
287 av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
289 if ((o = av_opt_find(&cc, opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN|AV_OPT_SEARCH_FAKE_OBJ)) ||
290 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
291 (o = av_opt_find(&cc, opt+1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
292 av_dict_set(&codec_opts, opt, arg, FLAGS);
293 else if ((o = av_opt_find(&fc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
294 av_dict_set(&format_opts, opt, arg, FLAGS);
295 else if ((o = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
296 // XXX we only support sws_flags, not arbitrary sws options
297 int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
299 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
306 fprintf(stderr, "Unrecognized option '%s'\n", opt);
307 return AVERROR_OPTION_NOT_FOUND;
310 int opt_loglevel(const char *opt, const char *arg)
312 const struct { const char *name; int level; } log_levels[] = {
313 { "quiet" , AV_LOG_QUIET },
314 { "panic" , AV_LOG_PANIC },
315 { "fatal" , AV_LOG_FATAL },
316 { "error" , AV_LOG_ERROR },
317 { "warning", AV_LOG_WARNING },
318 { "info" , AV_LOG_INFO },
319 { "verbose", AV_LOG_VERBOSE },
320 { "debug" , AV_LOG_DEBUG },
326 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
327 if (!strcmp(log_levels[i].name, arg)) {
328 av_log_set_level(log_levels[i].level);
333 level = strtol(arg, &tail, 10);
335 fprintf(stderr, "Invalid loglevel \"%s\". "
336 "Possible levels are numbers or:\n", arg);
337 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
338 fprintf(stderr, "\"%s\"\n", log_levels[i].name);
341 av_log_set_level(level);
345 int opt_timelimit(const char *opt, const char *arg)
348 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
349 struct rlimit rl = { lim, lim + 1 };
350 if (setrlimit(RLIMIT_CPU, &rl))
353 fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
358 void print_error(const char *filename, int err)
361 const char *errbuf_ptr = errbuf;
363 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
364 errbuf_ptr = strerror(AVUNERROR(err));
365 fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
368 static int warned_cfg = 0;
371 #define SHOW_VERSION 2
372 #define SHOW_CONFIG 4
374 #define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags) \
375 if (CONFIG_##LIBNAME) { \
376 const char *indent = flags & INDENT? " " : ""; \
377 if (flags & SHOW_VERSION) { \
378 unsigned int version = libname##_version(); \
379 fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
381 LIB##LIBNAME##_VERSION_MAJOR, \
382 LIB##LIBNAME##_VERSION_MINOR, \
383 LIB##LIBNAME##_VERSION_MICRO, \
384 version >> 16, version >> 8 & 0xff, version & 0xff); \
386 if (flags & SHOW_CONFIG) { \
387 const char *cfg = libname##_configuration(); \
388 if (strcmp(LIBAV_CONFIGURATION, cfg)) { \
391 "%sWARNING: library configuration mismatch\n", \
395 fprintf(stderr, "%s%-11s configuration: %s\n", \
396 indent, #libname, cfg); \
401 static void print_all_libs_info(FILE* outstream, int flags)
403 PRINT_LIB_INFO(outstream, avutil, AVUTIL, flags);
404 PRINT_LIB_INFO(outstream, avcodec, AVCODEC, flags);
405 PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
406 PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
407 PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
408 PRINT_LIB_INFO(outstream, swscale, SWSCALE, flags);
409 PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
412 void show_banner(void)
414 fprintf(stderr, "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
415 program_name, program_birth_year, this_year);
416 fprintf(stderr, " built on %s %s with %s %s\n",
417 __DATE__, __TIME__, CC_TYPE, CC_VERSION);
418 fprintf(stderr, " configuration: " LIBAV_CONFIGURATION "\n");
419 print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
420 print_all_libs_info(stderr, INDENT|SHOW_VERSION);
423 void show_version(void) {
424 printf("%s " LIBAV_VERSION "\n", program_name);
425 print_all_libs_info(stdout, SHOW_VERSION);
428 void show_license(void)
432 "This version of %s has nonfree parts compiled in.\n"
433 "Therefore it is not legally redistributable.\n",
436 "%s is free software; you can redistribute it and/or modify\n"
437 "it under the terms of the GNU General Public License as published by\n"
438 "the Free Software Foundation; either version 3 of the License, or\n"
439 "(at your option) any later version.\n"
441 "%s is distributed in the hope that it will be useful,\n"
442 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
443 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
444 "GNU General Public License for more details.\n"
446 "You should have received a copy of the GNU General Public License\n"
447 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
448 program_name, program_name, program_name
450 "%s is free software; you can redistribute it and/or modify\n"
451 "it under the terms of the GNU General Public License as published by\n"
452 "the Free Software Foundation; either version 2 of the License, or\n"
453 "(at your option) any later version.\n"
455 "%s is distributed in the hope that it will be useful,\n"
456 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
457 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
458 "GNU General Public License for more details.\n"
460 "You should have received a copy of the GNU General Public License\n"
461 "along with %s; if not, write to the Free Software\n"
462 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
463 program_name, program_name, program_name
465 "%s is free software; you can redistribute it and/or modify\n"
466 "it under the terms of the GNU Lesser General Public License as published by\n"
467 "the Free Software Foundation; either version 3 of the License, or\n"
468 "(at your option) any later version.\n"
470 "%s is distributed in the hope that it will be useful,\n"
471 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
472 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
473 "GNU Lesser General Public License for more details.\n"
475 "You should have received a copy of the GNU Lesser General Public License\n"
476 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
477 program_name, program_name, program_name
479 "%s is free software; you can redistribute it and/or\n"
480 "modify it under the terms of the GNU Lesser General Public\n"
481 "License as published by the Free Software Foundation; either\n"
482 "version 2.1 of the License, or (at your option) any later version.\n"
484 "%s is distributed in the hope that it will be useful,\n"
485 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
486 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
487 "Lesser General Public License for more details.\n"
489 "You should have received a copy of the GNU Lesser General Public\n"
490 "License along with %s; if not, write to the Free Software\n"
491 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
492 program_name, program_name, program_name
497 void show_formats(void)
499 AVInputFormat *ifmt=NULL;
500 AVOutputFormat *ofmt=NULL;
501 const char *last_name;
505 " D. = Demuxing supported\n"
506 " .E = Muxing supported\n"
512 const char *name=NULL;
513 const char *long_name=NULL;
515 while((ofmt= av_oformat_next(ofmt))) {
516 if((name == NULL || strcmp(ofmt->name, name)<0) &&
517 strcmp(ofmt->name, last_name)>0){
519 long_name= ofmt->long_name;
523 while((ifmt= av_iformat_next(ifmt))) {
524 if((name == NULL || strcmp(ifmt->name, name)<0) &&
525 strcmp(ifmt->name, last_name)>0){
527 long_name= ifmt->long_name;
530 if(name && strcmp(ifmt->name, name)==0)
542 long_name ? long_name:" ");
546 void show_codecs(void)
548 AVCodec *p=NULL, *p2;
549 const char *last_name;
552 " D..... = Decoding supported\n"
553 " .E.... = Encoding supported\n"
554 " ..V... = Video codec\n"
555 " ..A... = Audio codec\n"
556 " ..S... = Subtitle codec\n"
557 " ...S.. = Supports draw_horiz_band\n"
558 " ....D. = Supports direct rendering method 1\n"
559 " .....T = Supports weird frame truncation\n"
566 const char *type_str;
569 while((p= av_codec_next(p))) {
570 if((p2==NULL || strcmp(p->name, p2->name)<0) &&
571 strcmp(p->name, last_name)>0){
573 decode= encode= cap=0;
575 if(p2 && strcmp(p->name, p2->name)==0){
576 if(p->decode) decode=1;
577 if(p->encode) encode=1;
578 cap |= p->capabilities;
586 case AVMEDIA_TYPE_VIDEO:
589 case AVMEDIA_TYPE_AUDIO:
592 case AVMEDIA_TYPE_SUBTITLE:
600 " %s%s%s%s%s%s %-15s %s",
601 decode ? "D": (/*p2->decoder ? "d":*/" "),
604 cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
605 cap & CODEC_CAP_DR1 ? "D":" ",
606 cap & CODEC_CAP_TRUNCATED ? "T":" ",
608 p2->long_name ? p2->long_name : "");
609 /* if(p2->decoder && decode==0)
610 printf(" use %s for decoding", p2->decoder->name);*/
615 "Note, the names of encoders and decoders do not always match, so there are\n"
616 "several cases where the above table shows encoder only or decoder only entries\n"
617 "even though both encoding and decoding are supported. For example, the h263\n"
618 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
624 AVBitStreamFilter *bsf=NULL;
626 printf("Bitstream filters:\n");
627 while((bsf = av_bitstream_filter_next(bsf)))
628 printf("%s\n", bsf->name);
632 void show_protocols(void)
637 printf("Supported file protocols:\n"
639 while ((name = avio_enum_protocols(&opaque, 0)))
640 printf("%s\n", name);
642 while ((name = avio_enum_protocols(&opaque, 1)))
643 printf("%s\n", name);
646 void show_filters(void)
648 AVFilter av_unused(**filter) = NULL;
650 printf("Filters:\n");
652 while ((filter = av_filter_next(filter)) && *filter)
653 printf("%-16s %s\n", (*filter)->name, (*filter)->description);
657 void show_pix_fmts(void)
659 enum PixelFormat pix_fmt;
663 "I.... = Supported Input format for conversion\n"
664 ".O... = Supported Output format for conversion\n"
665 "..H.. = Hardware accelerated format\n"
666 "...P. = Paletted format\n"
667 "....B = Bitstream format\n"
668 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
672 # define sws_isSupportedInput(x) 0
673 # define sws_isSupportedOutput(x) 0
676 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
677 const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
678 printf("%c%c%c%c%c %-16s %d %2d\n",
679 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
680 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
681 pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
682 pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
683 pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
685 pix_desc->nb_components,
686 av_get_bits_per_pixel(pix_desc));
693 int yesno = (toupper(c) == 'Y');
695 while (c != '\n' && c != EOF)
701 int read_file(const char *filename, char **bufptr, size_t *size)
703 FILE *f = fopen(filename, "rb");
706 fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
707 return AVERROR(errno);
709 fseek(f, 0, SEEK_END);
711 fseek(f, 0, SEEK_SET);
712 *bufptr = av_malloc(*size + 1);
714 fprintf(stderr, "Could not allocate file buffer\n");
716 return AVERROR(ENOMEM);
718 fread(*bufptr, 1, *size, f);
719 (*bufptr)[*size++] = '\0';
725 void init_pts_correction(PtsCorrectionContext *ctx)
727 ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
728 ctx->last_pts = ctx->last_dts = INT64_MIN;
731 int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts, int64_t dts)
733 int64_t pts = AV_NOPTS_VALUE;
735 if (dts != AV_NOPTS_VALUE) {
736 ctx->num_faulty_dts += dts <= ctx->last_dts;
739 if (reordered_pts != AV_NOPTS_VALUE) {
740 ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
741 ctx->last_pts = reordered_pts;
743 if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
744 && reordered_pts != AV_NOPTS_VALUE)
752 FILE *get_preset_file(char *filename, size_t filename_size,
753 const char *preset_name, int is_path, const char *codec_name)
757 const char *base[3]= { getenv("AVCONV_DATADIR"),
763 av_strlcpy(filename, preset_name, filename_size);
764 f = fopen(filename, "r");
766 for (i = 0; i < 3 && !f; i++) {
769 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", preset_name);
770 f = fopen(filename, "r");
771 if (!f && codec_name) {
772 snprintf(filename, filename_size,
773 "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", codec_name, preset_name);
774 f = fopen(filename, "r");
782 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
784 if (*spec <= '9' && *spec >= '0') /* opt:index */
785 return strtol(spec, NULL, 0) == st->index;
786 else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd') { /* opt:[vasd] */
787 enum AVMediaType type;
790 case 'v': type = AVMEDIA_TYPE_VIDEO; break;
791 case 'a': type = AVMEDIA_TYPE_AUDIO; break;
792 case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
793 case 'd': type = AVMEDIA_TYPE_DATA; break;
795 if (type != st->codec->codec_type)
797 if (*spec++ == ':') { /* possibly followed by :index */
798 int i, index = strtol(spec, NULL, 0);
799 for (i = 0; i < s->nb_streams; i++)
800 if (s->streams[i]->codec->codec_type == type && index-- == 0)
801 return i == st->index;
805 } else if (!*spec) /* empty specifier, matches everything */
808 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
809 return AVERROR(EINVAL);
812 AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
814 AVDictionary *ret = NULL;
815 AVDictionaryEntry *t = NULL;
816 AVCodec *codec = s->oformat ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
817 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
819 const AVClass *cc = avcodec_get_class();
824 switch (codec->type) {
825 case AVMEDIA_TYPE_VIDEO: prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM; break;
826 case AVMEDIA_TYPE_AUDIO: prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM; break;
827 case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
830 while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
831 char *p = strchr(t->key, ':');
833 /* check stream specification in opt name */
835 switch (check_stream_specifier(s, st, p + 1)) {
836 case 1: *p = 0; break;
838 default: return NULL;
841 if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
842 (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ)))
843 av_dict_set(&ret, t->key, t->value, 0);
844 else if (t->key[0] == prefix && av_opt_find(&cc, t->key+1, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))
845 av_dict_set(&ret, t->key+1, t->value, 0);
853 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
860 opts = av_mallocz(s->nb_streams * sizeof(*opts));
862 av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
865 for (i = 0; i < s->nb_streams; i++)
866 opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
872 static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
874 FFSinkContext *priv = ctx->priv;
877 return AVERROR(EINVAL);
878 *priv = *(FFSinkContext *)opaque;
883 static void null_end_frame(AVFilterLink *inlink) { }
885 static int ffsink_query_formats(AVFilterContext *ctx)
887 FFSinkContext *priv = ctx->priv;
888 enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
890 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
896 .priv_size = sizeof(FFSinkContext),
899 .query_formats = ffsink_query_formats,
901 .inputs = (AVFilterPad[]) {{ .name = "default",
902 .type = AVMEDIA_TYPE_VIDEO,
903 .end_frame = null_end_frame,
904 .min_perms = AV_PERM_READ, },
906 .outputs = (AVFilterPad[]) {{ .name = NULL }},
909 int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
910 AVFilterBufferRef **picref_ptr, AVRational *tb)
913 AVFilterBufferRef *picref;
915 if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
917 if (!(picref = ctx->inputs[0]->cur_buf))
918 return AVERROR(ENOENT);
919 *picref_ptr = picref;
920 ctx->inputs[0]->cur_buf = NULL;
921 *tb = ctx->inputs[0]->time_base;
923 memcpy(frame->data, picref->data, sizeof(frame->data));
924 memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
925 frame->interlaced_frame = picref->video->interlaced;
926 frame->top_field_first = picref->video->top_field_first;
927 frame->key_frame = picref->video->key_frame;
928 frame->pict_type = picref->video->pict_type;
933 #endif /* CONFIG_AVFILTER */