]> git.sesse.net Git - ffmpeg/blob - cmdutils.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / cmdutils.c
1 /*
2  * Various utilities for command line tools
3  * Copyright (c) 2000-2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <math.h>
26
27 /* Include only the enabled headers since some compilers (namely, Sun
28    Studio) will not omit unused inline functions and create undefined
29    references to libraries that are not being built. */
30
31 #include "config.h"
32 #include "libavformat/avformat.h"
33 #include "libavfilter/avfilter.h"
34 #include "libavdevice/avdevice.h"
35 #include "libswscale/swscale.h"
36 #include "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/opt.h"
42 #include "cmdutils.h"
43 #include "version.h"
44 #if CONFIG_NETWORK
45 #include "libavformat/network.h"
46 #endif
47 #if HAVE_SYS_RESOURCE_H
48 #include <sys/resource.h>
49 #endif
50
51 const char **opt_names;
52 const char **opt_values;
53 static int opt_name_count;
54 AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
55 AVFormatContext *avformat_opts;
56 struct SwsContext *sws_opts;
57
58 static const int this_year = 2011;
59
60 void init_opts(void)
61 {
62     int i;
63     for (i = 0; i < AVMEDIA_TYPE_NB; i++)
64         avcodec_opts[i] = avcodec_alloc_context2(i);
65     avformat_opts = avformat_alloc_context();
66 #if CONFIG_SWSCALE
67     sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
68 #endif
69 }
70
71 void uninit_opts(void)
72 {
73     int i;
74     for (i = 0; i < AVMEDIA_TYPE_NB; i++)
75         av_freep(&avcodec_opts[i]);
76     av_freep(&avformat_opts->key);
77     av_freep(&avformat_opts);
78 #if CONFIG_SWSCALE
79     av_freep(&sws_opts);
80 #endif
81     for (i = 0; i < opt_name_count; i++) {
82         av_freep(&opt_names[i]);
83         av_freep(&opt_values[i]);
84     }
85     av_freep(&opt_names);
86     av_freep(&opt_values);
87     opt_name_count = 0;
88 }
89
90 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
91 {
92     vfprintf(stdout, fmt, vl);
93 }
94
95 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
96 {
97     char *tail;
98     const char *error;
99     double d = av_strtod(numstr, &tail);
100     if (*tail)
101         error= "Expected number for %s but found: %s\n";
102     else if (d < min || d > max)
103         error= "The value for %s was %s which is not within %f - %f\n";
104     else if(type == OPT_INT64 && (int64_t)d != d)
105         error= "Expected int64 for %s but found %s\n";
106     else if (type == OPT_INT && (int)d != d)
107         error= "Expected int for %s but found %s\n";
108     else
109         return d;
110     fprintf(stderr, error, context, numstr, min, max);
111     exit(1);
112 }
113
114 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
115 {
116     int64_t us;
117     if (av_parse_time(&us, timestr, is_duration) < 0) {
118         fprintf(stderr, "Invalid %s specification for %s: %s\n",
119                 is_duration ? "duration" : "date", context, timestr);
120         exit(1);
121     }
122     return us;
123 }
124
125 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
126 {
127     const OptionDef *po;
128     int first;
129
130     first = 1;
131     for(po = options; po->name != NULL; po++) {
132         char buf[64];
133         if ((po->flags & mask) == value) {
134             if (first) {
135                 printf("%s", msg);
136                 first = 0;
137             }
138             av_strlcpy(buf, po->name, sizeof(buf));
139             if (po->flags & HAS_ARG) {
140                 av_strlcat(buf, " ", sizeof(buf));
141                 av_strlcat(buf, po->argname, sizeof(buf));
142             }
143             printf("-%-17s  %s\n", buf, po->help);
144         }
145     }
146 }
147
148 static const OptionDef* find_option(const OptionDef *po, const char *name){
149     while (po->name != NULL) {
150         if (!strcmp(name, po->name))
151             break;
152         po++;
153     }
154     return po;
155 }
156
157 #if defined(_WIN32) && !defined(__MINGW32CE__)
158 #include <windows.h>
159 /* Will be leaked on exit */
160 static char** win32_argv_utf8 = NULL;
161 static int win32_argc = 0;
162
163 /**
164  * Prepare command line arguments for executable.
165  * For Windows - perform wide-char to UTF-8 conversion.
166  * Input arguments should be main() function arguments.
167  * @param argc_ptr Arguments number (including executable)
168  * @param argv_ptr Arguments list.
169  */
170 static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
171 {
172     char *argstr_flat;
173     wchar_t **argv_w;
174     int i, buffsize = 0, offset = 0;
175
176     if (win32_argv_utf8) {
177         *argc_ptr = win32_argc;
178         *argv_ptr = win32_argv_utf8;
179         return;
180     }
181
182     win32_argc = 0;
183     argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
184     if (win32_argc <= 0 || !argv_w)
185         return;
186
187     /* determine the UTF-8 buffer size (including NULL-termination symbols) */
188     for (i = 0; i < win32_argc; i++)
189         buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
190                                         NULL, 0, NULL, NULL);
191
192     win32_argv_utf8 = av_mallocz(sizeof(char*) * (win32_argc + 1) + buffsize);
193     argstr_flat     = (char*)win32_argv_utf8 + sizeof(char*) * (win32_argc + 1);
194     if (win32_argv_utf8 == NULL) {
195         LocalFree(argv_w);
196         return;
197     }
198
199     for (i = 0; i < win32_argc; i++) {
200         win32_argv_utf8[i] = &argstr_flat[offset];
201         offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
202                                       &argstr_flat[offset],
203                                       buffsize - offset, NULL, NULL);
204     }
205     win32_argv_utf8[i] = NULL;
206     LocalFree(argv_w);
207
208     *argc_ptr = win32_argc;
209     *argv_ptr = win32_argv_utf8;
210 }
211 #else
212 static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
213 {
214     /* nothing to do */
215 }
216 #endif /* WIN32 && !__MINGW32CE__ */
217
218 void parse_options(int argc, char **argv, const OptionDef *options,
219                    void (* parse_arg_function)(const char*))
220 {
221     const char *opt, *arg;
222     int optindex, handleoptions=1;
223     const OptionDef *po;
224
225     /* perform system-dependent conversions for arguments list */
226     prepare_app_arguments(&argc, &argv);
227
228     /* parse options */
229     optindex = 1;
230     while (optindex < argc) {
231         opt = argv[optindex++];
232
233         if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
234             int bool_val = 1;
235             if (opt[1] == '-' && opt[2] == '\0') {
236                 handleoptions = 0;
237                 continue;
238             }
239             opt++;
240             po= find_option(options, opt);
241             if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
242                 /* handle 'no' bool option */
243                 po = find_option(options, opt + 2);
244                 if (!(po->name && (po->flags & OPT_BOOL)))
245                     goto unknown_opt;
246                 bool_val = 0;
247             }
248             if (!po->name)
249                 po= find_option(options, "default");
250             if (!po->name) {
251 unknown_opt:
252                 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
253                 exit(1);
254             }
255             arg = NULL;
256             if (po->flags & HAS_ARG) {
257                 arg = argv[optindex++];
258                 if (!arg) {
259                     fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
260                     exit(1);
261                 }
262             }
263             if (po->flags & OPT_STRING) {
264                 char *str;
265                 str = av_strdup(arg);
266                 *po->u.str_arg = str;
267             } else if (po->flags & OPT_BOOL) {
268                 *po->u.int_arg = bool_val;
269             } else if (po->flags & OPT_INT) {
270                 *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
271             } else if (po->flags & OPT_INT64) {
272                 *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
273             } else if (po->flags & OPT_FLOAT) {
274                 *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
275             } else if (po->flags & OPT_FUNC2) {
276                 if (po->u.func2_arg(opt, arg) < 0) {
277                     fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
278                     exit(1);
279                 }
280             } else if (po->flags & OPT_DUMMY) {
281                 /* Do nothing for this option */
282             } else {
283                 po->u.func_arg(arg);
284             }
285             if(po->flags & OPT_EXIT)
286                 exit(0);
287         } else {
288             if (parse_arg_function)
289                 parse_arg_function(opt);
290         }
291     }
292 }
293
294 int opt_default(const char *opt, const char *arg){
295     int type;
296     int ret= 0;
297     const AVOption *o= NULL;
298     int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
299     AVCodec *p = NULL;
300     AVOutputFormat *oformat = NULL;
301     AVInputFormat *iformat = NULL;
302
303     while ((p = av_codec_next(p))) {
304         AVClass *c = p->priv_class;
305         if (c && av_find_opt(&c, opt, NULL, 0, 0))
306             break;
307     }
308     if (p)
309         goto out;
310     while ((oformat = av_oformat_next(oformat))) {
311         const AVClass *c = oformat->priv_class;
312         if (c && av_find_opt(&c, opt, NULL, 0, 0))
313             break;
314     }
315     if (oformat)
316         goto out;
317     while ((iformat = av_iformat_next(iformat))) {
318         const AVClass *c = iformat->priv_class;
319         if (c && av_find_opt(&c, opt, NULL, 0, 0))
320             break;
321     }
322     if (iformat)
323         goto out;
324
325     for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
326         const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
327         if(o2)
328             ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
329     }
330     if(!o && avformat_opts)
331         ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
332     if(!o && sws_opts)
333         ret = av_set_string3(sws_opts, opt, arg, 1, &o);
334     if(!o){
335         if (opt[0] == 'a' && avcodec_opts[AVMEDIA_TYPE_AUDIO])
336             ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o);
337         else if(opt[0] == 'v' && avcodec_opts[AVMEDIA_TYPE_VIDEO])
338             ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
339         else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE])
340             ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
341         if (ret >= 0)
342             opt += 1;
343     }
344     if (o && ret < 0) {
345         fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
346         exit(1);
347     }
348     if (!o) {
349         fprintf(stderr, "Unrecognized option '%s'\n", opt);
350         exit(1);
351     }
352
353  out:
354 //    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));
355
356     opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
357     opt_values[opt_name_count] = av_strdup(arg);
358     opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
359     opt_names[opt_name_count++] = av_strdup(opt);
360
361     if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug))
362         av_log_set_level(AV_LOG_DEBUG);
363     return 0;
364 }
365
366 int opt_loglevel(const char *opt, const char *arg)
367 {
368     const struct { const char *name; int level; } log_levels[] = {
369         { "quiet"  , AV_LOG_QUIET   },
370         { "panic"  , AV_LOG_PANIC   },
371         { "fatal"  , AV_LOG_FATAL   },
372         { "error"  , AV_LOG_ERROR   },
373         { "warning", AV_LOG_WARNING },
374         { "info"   , AV_LOG_INFO    },
375         { "verbose", AV_LOG_VERBOSE },
376         { "debug"  , AV_LOG_DEBUG   },
377     };
378     char *tail;
379     int level;
380     int i;
381
382     for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
383         if (!strcmp(log_levels[i].name, arg)) {
384             av_log_set_level(log_levels[i].level);
385             return 0;
386         }
387     }
388
389     level = strtol(arg, &tail, 10);
390     if (*tail) {
391         fprintf(stderr, "Invalid loglevel \"%s\". "
392                         "Possible levels are numbers or:\n", arg);
393         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
394             fprintf(stderr, "\"%s\"\n", log_levels[i].name);
395         exit(1);
396     }
397     av_log_set_level(level);
398     return 0;
399 }
400
401 int opt_timelimit(const char *opt, const char *arg)
402 {
403 #if HAVE_SETRLIMIT
404     int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
405     struct rlimit rl = { lim, lim + 1 };
406     if (setrlimit(RLIMIT_CPU, &rl))
407         perror("setrlimit");
408 #else
409     fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
410 #endif
411     return 0;
412 }
413
414 static void *alloc_priv_context(int size, AVClass *class){
415     void *p = av_mallocz(size);
416     if (p) {
417         *(AVClass**)p = class;
418         av_opt_set_defaults(p);
419     }
420     return p;
421 }
422
423 void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec)
424 {
425     int i;
426     void *priv_ctx=NULL;
427     if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){
428         AVCodecContext *avctx= ctx;
429         if(codec && codec->priv_class){
430             if(!avctx->priv_data && codec->priv_data_size)
431                 avctx->priv_data= alloc_priv_context(codec->priv_data_size, codec->priv_class);
432             priv_ctx= avctx->priv_data;
433         }
434     } else if (!strcmp("AVFormatContext", (*(AVClass**)ctx)->class_name)) {
435         AVFormatContext *avctx = ctx;
436         if (avctx->oformat && avctx->oformat->priv_class) {
437             priv_ctx = avctx->priv_data;
438         } else if (avctx->iformat && avctx->iformat->priv_class) {
439             priv_ctx = avctx->priv_data;
440         }
441     }
442
443     for(i=0; i<opt_name_count; i++){
444         char buf[256];
445         const AVOption *opt;
446         const char *str;
447         if (priv_ctx) {
448             if (av_find_opt(priv_ctx, opt_names[i], NULL, flags, flags)) {
449                 if (av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL) < 0) {
450                     fprintf(stderr, "Invalid value '%s' for option '%s'\n",
451                             opt_names[i], opt_values[i]);
452                     exit(1);
453                 }
454             } else
455                 goto global;
456         } else {
457         global:
458             str = av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
459             /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
460             if (str && ((opt->flags & flags) == flags))
461                 av_set_string3(ctx, opt_names[i], str, 1, NULL);
462         }
463     }
464 }
465
466 void print_error(const char *filename, int err)
467 {
468     char errbuf[128];
469     const char *errbuf_ptr = errbuf;
470
471     if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
472         errbuf_ptr = strerror(AVUNERROR(err));
473     fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
474 }
475
476 static int warned_cfg = 0;
477
478 #define INDENT        1
479 #define SHOW_VERSION  2
480 #define SHOW_CONFIG   4
481
482 #define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags)                 \
483     if (CONFIG_##LIBNAME) {                                             \
484         const char *indent = flags & INDENT? "  " : "";                 \
485         if (flags & SHOW_VERSION) {                                     \
486             unsigned int version = libname##_version();                 \
487             fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
488                     indent, #libname,                                   \
489                     LIB##LIBNAME##_VERSION_MAJOR,                       \
490                     LIB##LIBNAME##_VERSION_MINOR,                       \
491                     LIB##LIBNAME##_VERSION_MICRO,                       \
492                     version >> 16, version >> 8 & 0xff, version & 0xff); \
493         }                                                               \
494         if (flags & SHOW_CONFIG) {                                      \
495             const char *cfg = libname##_configuration();                \
496             if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \
497                 if (!warned_cfg) {                                      \
498                     fprintf(outstream,                                  \
499                             "%sWARNING: library configuration mismatch\n", \
500                             indent);                                    \
501                     warned_cfg = 1;                                     \
502                 }                                                       \
503                 fprintf(stderr, "%s%-11s configuration: %s\n",          \
504                         indent, #libname, cfg);                         \
505             }                                                           \
506         }                                                               \
507     }                                                                   \
508
509 static void print_all_libs_info(FILE* outstream, int flags)
510 {
511     PRINT_LIB_INFO(outstream, avutil,   AVUTIL,   flags);
512     PRINT_LIB_INFO(outstream, avcodec,  AVCODEC,  flags);
513     PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
514     PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
515     PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
516     PRINT_LIB_INFO(outstream, swscale,  SWSCALE,  flags);
517     PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
518 }
519
520 void show_banner(void)
521 {
522     fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n",
523             program_name, program_birth_year, this_year);
524     fprintf(stderr, "  built on %s %s with %s %s\n",
525             __DATE__, __TIME__, CC_TYPE, CC_VERSION);
526     fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
527     print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
528     print_all_libs_info(stderr, INDENT|SHOW_VERSION);
529 }
530
531 void show_version(void) {
532     printf("%s " FFMPEG_VERSION "\n", program_name);
533     print_all_libs_info(stdout, SHOW_VERSION);
534 }
535
536 void show_license(void)
537 {
538     printf(
539 #if CONFIG_NONFREE
540     "This version of %s has nonfree parts compiled in.\n"
541     "Therefore it is not legally redistributable.\n",
542     program_name
543 #elif CONFIG_GPLV3
544     "%s is free software; you can redistribute it and/or modify\n"
545     "it under the terms of the GNU General Public License as published by\n"
546     "the Free Software Foundation; either version 3 of the License, or\n"
547     "(at your option) any later version.\n"
548     "\n"
549     "%s is distributed in the hope that it will be useful,\n"
550     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
551     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
552     "GNU General Public License for more details.\n"
553     "\n"
554     "You should have received a copy of the GNU General Public License\n"
555     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
556     program_name, program_name, program_name
557 #elif CONFIG_GPL
558     "%s is free software; you can redistribute it and/or modify\n"
559     "it under the terms of the GNU General Public License as published by\n"
560     "the Free Software Foundation; either version 2 of the License, or\n"
561     "(at your option) any later version.\n"
562     "\n"
563     "%s is distributed in the hope that it will be useful,\n"
564     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
565     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
566     "GNU General Public License for more details.\n"
567     "\n"
568     "You should have received a copy of the GNU General Public License\n"
569     "along with %s; if not, write to the Free Software\n"
570     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
571     program_name, program_name, program_name
572 #elif CONFIG_LGPLV3
573     "%s is free software; you can redistribute it and/or modify\n"
574     "it under the terms of the GNU Lesser General Public License as published by\n"
575     "the Free Software Foundation; either version 3 of the License, or\n"
576     "(at your option) any later version.\n"
577     "\n"
578     "%s is distributed in the hope that it will be useful,\n"
579     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
580     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
581     "GNU Lesser General Public License for more details.\n"
582     "\n"
583     "You should have received a copy of the GNU Lesser General Public License\n"
584     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
585     program_name, program_name, program_name
586 #else
587     "%s is free software; you can redistribute it and/or\n"
588     "modify it under the terms of the GNU Lesser General Public\n"
589     "License as published by the Free Software Foundation; either\n"
590     "version 2.1 of the License, or (at your option) any later version.\n"
591     "\n"
592     "%s is distributed in the hope that it will be useful,\n"
593     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
594     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
595     "Lesser General Public License for more details.\n"
596     "\n"
597     "You should have received a copy of the GNU Lesser General Public\n"
598     "License along with %s; if not, write to the Free Software\n"
599     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
600     program_name, program_name, program_name
601 #endif
602     );
603 }
604
605 void show_formats(void)
606 {
607     AVInputFormat *ifmt=NULL;
608     AVOutputFormat *ofmt=NULL;
609     const char *last_name;
610
611     printf(
612         "File formats:\n"
613         " D. = Demuxing supported\n"
614         " .E = Muxing supported\n"
615         " --\n");
616     last_name= "000";
617     for(;;){
618         int decode=0;
619         int encode=0;
620         const char *name=NULL;
621         const char *long_name=NULL;
622
623         while((ofmt= av_oformat_next(ofmt))) {
624             if((name == NULL || strcmp(ofmt->name, name)<0) &&
625                 strcmp(ofmt->name, last_name)>0){
626                 name= ofmt->name;
627                 long_name= ofmt->long_name;
628                 encode=1;
629             }
630         }
631         while((ifmt= av_iformat_next(ifmt))) {
632             if((name == NULL || strcmp(ifmt->name, name)<0) &&
633                 strcmp(ifmt->name, last_name)>0){
634                 name= ifmt->name;
635                 long_name= ifmt->long_name;
636                 encode=0;
637             }
638             if(name && strcmp(ifmt->name, name)==0)
639                 decode=1;
640         }
641         if(name==NULL)
642             break;
643         last_name= name;
644
645         printf(
646             " %s%s %-15s %s\n",
647             decode ? "D":" ",
648             encode ? "E":" ",
649             name,
650             long_name ? long_name:" ");
651     }
652 }
653
654 void show_codecs(void)
655 {
656     AVCodec *p=NULL, *p2;
657     const char *last_name;
658     printf(
659         "Codecs:\n"
660         " D..... = Decoding supported\n"
661         " .E.... = Encoding supported\n"
662         " ..V... = Video codec\n"
663         " ..A... = Audio codec\n"
664         " ..S... = Subtitle codec\n"
665         " ...S.. = Supports draw_horiz_band\n"
666         " ....D. = Supports direct rendering method 1\n"
667         " .....T = Supports weird frame truncation\n"
668         " ------\n");
669     last_name= "000";
670     for(;;){
671         int decode=0;
672         int encode=0;
673         int cap=0;
674         const char *type_str;
675
676         p2=NULL;
677         while((p= av_codec_next(p))) {
678             if((p2==NULL || strcmp(p->name, p2->name)<0) &&
679                 strcmp(p->name, last_name)>0){
680                 p2= p;
681                 decode= encode= cap=0;
682             }
683             if(p2 && strcmp(p->name, p2->name)==0){
684                 if(p->decode) decode=1;
685                 if(p->encode) encode=1;
686                 cap |= p->capabilities;
687             }
688         }
689         if(p2==NULL)
690             break;
691         last_name= p2->name;
692
693         switch(p2->type) {
694         case AVMEDIA_TYPE_VIDEO:
695             type_str = "V";
696             break;
697         case AVMEDIA_TYPE_AUDIO:
698             type_str = "A";
699             break;
700         case AVMEDIA_TYPE_SUBTITLE:
701             type_str = "S";
702             break;
703         default:
704             type_str = "?";
705             break;
706         }
707         printf(
708             " %s%s%s%s%s%s %-15s %s",
709             decode ? "D": (/*p2->decoder ? "d":*/" "),
710             encode ? "E":" ",
711             type_str,
712             cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
713             cap & CODEC_CAP_DR1 ? "D":" ",
714             cap & CODEC_CAP_TRUNCATED ? "T":" ",
715             p2->name,
716             p2->long_name ? p2->long_name : "");
717        /* if(p2->decoder && decode==0)
718             printf(" use %s for decoding", p2->decoder->name);*/
719         printf("\n");
720     }
721     printf("\n");
722     printf(
723 "Note, the names of encoders and decoders do not always match, so there are\n"
724 "several cases where the above table shows encoder only or decoder only entries\n"
725 "even though both encoding and decoding are supported. For example, the h263\n"
726 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
727 "worse.\n");
728 }
729
730 void show_bsfs(void)
731 {
732     AVBitStreamFilter *bsf=NULL;
733
734     printf("Bitstream filters:\n");
735     while((bsf = av_bitstream_filter_next(bsf)))
736         printf("%s\n", bsf->name);
737     printf("\n");
738 }
739
740 void show_protocols(void)
741 {
742     URLProtocol *up=NULL;
743
744     printf("Supported file protocols:\n"
745            "I.. = Input  supported\n"
746            ".O. = Output supported\n"
747            "..S = Seek   supported\n"
748            "FLAGS NAME\n"
749            "----- \n");
750     while((up = av_protocol_next(up)))
751         printf("%c%c%c   %s\n",
752                up->url_read  ? 'I' : '.',
753                up->url_write ? 'O' : '.',
754                up->url_seek  ? 'S' : '.',
755                up->name);
756 }
757
758 void show_filters(void)
759 {
760     AVFilter av_unused(**filter) = NULL;
761
762     printf("Filters:\n");
763 #if CONFIG_AVFILTER
764     while ((filter = av_filter_next(filter)) && *filter)
765         printf("%-16s %s\n", (*filter)->name, (*filter)->description);
766 #endif
767 }
768
769 void show_pix_fmts(void)
770 {
771     enum PixelFormat pix_fmt;
772
773     printf(
774         "Pixel formats:\n"
775         "I.... = Supported Input  format for conversion\n"
776         ".O... = Supported Output format for conversion\n"
777         "..H.. = Hardware accelerated format\n"
778         "...P. = Paletted format\n"
779         "....B = Bitstream format\n"
780         "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL\n"
781         "-----\n");
782
783 #if !CONFIG_SWSCALE
784 #   define sws_isSupportedInput(x)  0
785 #   define sws_isSupportedOutput(x) 0
786 #endif
787
788     for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
789         const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
790         printf("%c%c%c%c%c %-16s       %d            %2d\n",
791                sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
792                sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
793                pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
794                pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
795                pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
796                pix_desc->name,
797                pix_desc->nb_components,
798                av_get_bits_per_pixel(pix_desc));
799     }
800 }
801
802 int read_yesno(void)
803 {
804     int c = getchar();
805     int yesno = (toupper(c) == 'Y');
806
807     while (c != '\n' && c != EOF)
808         c = getchar();
809
810     return yesno;
811 }
812
813 int read_file(const char *filename, char **bufptr, size_t *size)
814 {
815     FILE *f = fopen(filename, "rb");
816
817     if (!f) {
818         fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
819         return AVERROR(errno);
820     }
821     fseek(f, 0, SEEK_END);
822     *size = ftell(f);
823     fseek(f, 0, SEEK_SET);
824     *bufptr = av_malloc(*size + 1);
825     if (!*bufptr) {
826         fprintf(stderr, "Could not allocate file buffer\n");
827         fclose(f);
828         return AVERROR(ENOMEM);
829     }
830     fread(*bufptr, 1, *size, f);
831     (*bufptr)[*size++] = '\0';
832
833     fclose(f);
834     return 0;
835 }
836
837 FILE *get_preset_file(char *filename, size_t filename_size,
838                       const char *preset_name, int is_path, const char *codec_name)
839 {
840     FILE *f = NULL;
841     int i;
842     const char *base[3]= { getenv("FFMPEG_DATADIR"),
843                            getenv("HOME"),
844                            FFMPEG_DATADIR,
845                          };
846
847     if (is_path) {
848         av_strlcpy(filename, preset_name, filename_size);
849         f = fopen(filename, "r");
850     } else {
851         for (i = 0; i < 3 && !f; i++) {
852             if (!base[i])
853                 continue;
854             snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name);
855             f = fopen(filename, "r");
856             if (!f && codec_name) {
857                 snprintf(filename, filename_size,
858                          "%s%s/%s-%s.ffpreset", base[i],  i != 1 ? "" : "/.ffmpeg", codec_name, preset_name);
859                 f = fopen(filename, "r");
860             }
861         }
862     }
863
864     return f;
865 }
866
867 #if CONFIG_AVFILTER
868
869 static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
870 {
871     FFSinkContext *priv = ctx->priv;
872
873     if (!opaque)
874         return AVERROR(EINVAL);
875     *priv = *(FFSinkContext *)opaque;
876
877     return 0;
878 }
879
880 static void null_end_frame(AVFilterLink *inlink) { }
881
882 static int ffsink_query_formats(AVFilterContext *ctx)
883 {
884     FFSinkContext *priv = ctx->priv;
885     enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
886
887     avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
888     return 0;
889 }
890
891 AVFilter ffsink = {
892     .name      = "ffsink",
893     .priv_size = sizeof(FFSinkContext),
894     .init      = ffsink_init,
895
896     .query_formats = ffsink_query_formats,
897
898     .inputs    = (AVFilterPad[]) {{ .name          = "default",
899                                     .type          = AVMEDIA_TYPE_VIDEO,
900                                     .end_frame     = null_end_frame,
901                                     .min_perms     = AV_PERM_READ, },
902                                   { .name = NULL }},
903     .outputs   = (AVFilterPad[]) {{ .name = NULL }},
904 };
905
906 int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
907                              AVFilterBufferRef **picref_ptr, AVRational *tb)
908 {
909     int ret;
910     AVFilterBufferRef *picref;
911
912     if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
913         return ret;
914     if (!(picref = ctx->inputs[0]->cur_buf))
915         return AVERROR(ENOENT);
916     *picref_ptr = picref;
917     ctx->inputs[0]->cur_buf = NULL;
918     *tb = ctx->inputs[0]->time_base;
919
920     memcpy(frame->data,     picref->data,     sizeof(frame->data));
921     memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
922     frame->pkt_pos          = picref->pos;
923     frame->interlaced_frame = picref->video->interlaced;
924     frame->top_field_first  = picref->video->top_field_first;
925     frame->key_frame        = picref->video->key_frame;
926     frame->pict_type        = picref->video->pict_type;
927     frame->sample_aspect_ratio = picref->video->sample_aspect_ratio;
928
929     return 1;
930 }
931
932 #endif /* CONFIG_AVFILTER */