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