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