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