53ef7aed3c7c28001af2d64c9986ab9c455c1b99
[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 void parse_options(int argc, char **argv, const OptionDef *options,
207 void (* parse_arg_function)(const char*))
208 {
209 const char *opt, *arg;
210 int optindex, handleoptions=1;
211 const OptionDef *po;
212
213 /* perform system-dependent conversions for arguments list */
214 prepare_app_arguments(&argc, &argv);
215
216 /* parse options */
217 optindex = 1;
218 while (optindex < argc) {
219 void *dst;
220 opt = argv[optindex++];
221
222 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
223 int bool_val = 1;
224 if (opt[1] == '-' && opt[2] == '\0') {
225 handleoptions = 0;
226 continue;
227 }
228 opt++;
229 po= find_option(options, opt);
230 if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
231 /* handle 'no' bool option */
232 po = find_option(options, opt + 2);
233 if (!(po->name && (po->flags & OPT_BOOL)))
234 goto unknown_opt;
235 bool_val = 0;
236 }
237 if (!po->name)
238 po= find_option(options, "default");
239 if (!po->name) {
240 unknown_opt:
241 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
242 exit_program(1);
243 }
244 arg = NULL;
245 if (po->flags & HAS_ARG) {
246 arg = argv[optindex++];
247 if (!arg) {
248 fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
249 exit_program(1);
250 }
251 }
252 dst = po->u.dst_ptr;
253 if (po->flags & OPT_STRING) {
254 char *str;
255 str = av_strdup(arg);
256 *(char**)dst = str;
257 } else if (po->flags & OPT_BOOL) {
258 *(int*)dst = bool_val;
259 } else if (po->flags & OPT_INT) {
260 *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
261 } else if (po->flags & OPT_INT64) {
262 *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
263 } else if (po->flags & OPT_FLOAT) {
264 *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
265 } else if (po->u.func_arg) {
266 if (po->u.func_arg(opt, arg) < 0) {
267 fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
268 exit_program(1);
269 }
270 }
271 if(po->flags & OPT_EXIT)
272 exit_program(0);
273 } else {
274 if (parse_arg_function)
275 parse_arg_function(opt);
276 }
277 }
278 }
279
280 #define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
281 int opt_default(const char *opt, const char *arg)
282 {
283 const AVOption *o;
284 char opt_stripped[128];
285 const char *p;
286 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc = sws_get_class();
287
288 if (!(p = strchr(opt, ':')))
289 p = opt + strlen(opt);
290 av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
291
292 if ((o = av_opt_find(&cc, opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN|AV_OPT_SEARCH_FAKE_OBJ)) ||
293 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
294 (o = av_opt_find(&cc, opt+1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
295 av_dict_set(&codec_opts, opt, arg, FLAGS);
296 else if ((o = av_opt_find(&fc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
297 av_dict_set(&format_opts, opt, arg, FLAGS);
298 else if ((o = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
299 // XXX we only support sws_flags, not arbitrary sws options
300 int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
301 if (ret < 0) {
302 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
303 return ret;
304 }
305 }
306
307 if (o)
308 return 0;
309 fprintf(stderr, "Unrecognized option '%s'\n", opt);
310 return AVERROR_OPTION_NOT_FOUND;
311 }
312
313 int opt_loglevel(const char *opt, const char *arg)
314 {
315 const struct { const char *name; int level; } log_levels[] = {
316 { "quiet" , AV_LOG_QUIET },
317 { "panic" , AV_LOG_PANIC },
318 { "fatal" , AV_LOG_FATAL },
319 { "error" , AV_LOG_ERROR },
320 { "warning", AV_LOG_WARNING },
321 { "info" , AV_LOG_INFO },
322 { "verbose", AV_LOG_VERBOSE },
323 { "debug" , AV_LOG_DEBUG },
324 };
325 char *tail;
326 int level;
327 int i;
328
329 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
330 if (!strcmp(log_levels[i].name, arg)) {
331 av_log_set_level(log_levels[i].level);
332 return 0;
333 }
334 }
335
336 level = strtol(arg, &tail, 10);
337 if (*tail) {
338 fprintf(stderr, "Invalid loglevel \"%s\". "
339 "Possible levels are numbers or:\n", arg);
340 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
341 fprintf(stderr, "\"%s\"\n", log_levels[i].name);
342 exit_program(1);
343 }
344 av_log_set_level(level);
345 return 0;
346 }
347
348 int opt_timelimit(const char *opt, const char *arg)
349 {
350 #if HAVE_SETRLIMIT
351 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
352 struct rlimit rl = { lim, lim + 1 };
353 if (setrlimit(RLIMIT_CPU, &rl))
354 perror("setrlimit");
355 #else
356 fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
357 #endif
358 return 0;
359 }
360
361 void print_error(const char *filename, int err)
362 {
363 char errbuf[128];
364 const char *errbuf_ptr = errbuf;
365
366 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
367 errbuf_ptr = strerror(AVUNERROR(err));
368 fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
369 }
370
371 static int warned_cfg = 0;
372
373 #define INDENT 1
374 #define SHOW_VERSION 2
375 #define SHOW_CONFIG 4
376
377 #define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags) \
378 if (CONFIG_##LIBNAME) { \
379 const char *indent = flags & INDENT? " " : ""; \
380 if (flags & SHOW_VERSION) { \
381 unsigned int version = libname##_version(); \
382 fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
383 indent, #libname, \
384 LIB##LIBNAME##_VERSION_MAJOR, \
385 LIB##LIBNAME##_VERSION_MINOR, \
386 LIB##LIBNAME##_VERSION_MICRO, \
387 version >> 16, version >> 8 & 0xff, version & 0xff); \
388 } \
389 if (flags & SHOW_CONFIG) { \
390 const char *cfg = libname##_configuration(); \
391 if (strcmp(LIBAV_CONFIGURATION, cfg)) { \
392 if (!warned_cfg) { \
393 fprintf(outstream, \
394 "%sWARNING: library configuration mismatch\n", \
395 indent); \
396 warned_cfg = 1; \
397 } \
398 fprintf(stderr, "%s%-11s configuration: %s\n", \
399 indent, #libname, cfg); \
400 } \
401 } \
402 } \
403
404 static void print_all_libs_info(FILE* outstream, int flags)
405 {
406 PRINT_LIB_INFO(outstream, avutil, AVUTIL, flags);
407 PRINT_LIB_INFO(outstream, avcodec, AVCODEC, flags);
408 PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
409 PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
410 PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
411 PRINT_LIB_INFO(outstream, swscale, SWSCALE, flags);
412 PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
413 }
414
415 void show_banner(void)
416 {
417 fprintf(stderr, "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
418 program_name, program_birth_year, this_year);
419 fprintf(stderr, " built on %s %s with %s %s\n",
420 __DATE__, __TIME__, CC_TYPE, CC_VERSION);
421 fprintf(stderr, " configuration: " LIBAV_CONFIGURATION "\n");
422 print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
423 print_all_libs_info(stderr, INDENT|SHOW_VERSION);
424 }
425
426 void show_version(void) {
427 printf("%s " LIBAV_VERSION "\n", program_name);
428 print_all_libs_info(stdout, SHOW_VERSION);
429 }
430
431 void show_license(void)
432 {
433 printf(
434 #if CONFIG_NONFREE
435 "This version of %s has nonfree parts compiled in.\n"
436 "Therefore it is not legally redistributable.\n",
437 program_name
438 #elif CONFIG_GPLV3
439 "%s is free software; you can redistribute it and/or modify\n"
440 "it under the terms of the GNU General Public License as published by\n"
441 "the Free Software Foundation; either version 3 of the License, or\n"
442 "(at your option) any later version.\n"
443 "\n"
444 "%s is distributed in the hope that it will be useful,\n"
445 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
446 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
447 "GNU General Public License for more details.\n"
448 "\n"
449 "You should have received a copy of the GNU General Public License\n"
450 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
451 program_name, program_name, program_name
452 #elif CONFIG_GPL
453 "%s is free software; you can redistribute it and/or modify\n"
454 "it under the terms of the GNU General Public License as published by\n"
455 "the Free Software Foundation; either version 2 of the License, or\n"
456 "(at your option) any later version.\n"
457 "\n"
458 "%s is distributed in the hope that it will be useful,\n"
459 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
460 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
461 "GNU General Public License for more details.\n"
462 "\n"
463 "You should have received a copy of the GNU General Public License\n"
464 "along with %s; if not, write to the Free Software\n"
465 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
466 program_name, program_name, program_name
467 #elif CONFIG_LGPLV3
468 "%s is free software; you can redistribute it and/or modify\n"
469 "it under the terms of the GNU Lesser General Public License as published by\n"
470 "the Free Software Foundation; either version 3 of the License, or\n"
471 "(at your option) any later version.\n"
472 "\n"
473 "%s is distributed in the hope that it will be useful,\n"
474 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
475 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
476 "GNU Lesser General Public License for more details.\n"
477 "\n"
478 "You should have received a copy of the GNU Lesser General Public License\n"
479 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
480 program_name, program_name, program_name
481 #else
482 "%s is free software; you can redistribute it and/or\n"
483 "modify it under the terms of the GNU Lesser General Public\n"
484 "License as published by the Free Software Foundation; either\n"
485 "version 2.1 of the License, or (at your option) any later version.\n"
486 "\n"
487 "%s is distributed in the hope that it will be useful,\n"
488 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
489 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
490 "Lesser General Public License for more details.\n"
491 "\n"
492 "You should have received a copy of the GNU Lesser General Public\n"
493 "License along with %s; if not, write to the Free Software\n"
494 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
495 program_name, program_name, program_name
496 #endif
497 );
498 }
499
500 void show_formats(void)
501 {
502 AVInputFormat *ifmt=NULL;
503 AVOutputFormat *ofmt=NULL;
504 const char *last_name;
505
506 printf(
507 "File formats:\n"
508 " D. = Demuxing supported\n"
509 " .E = Muxing supported\n"
510 " --\n");
511 last_name= "000";
512 for(;;){
513 int decode=0;
514 int encode=0;
515 const char *name=NULL;
516 const char *long_name=NULL;
517
518 while((ofmt= av_oformat_next(ofmt))) {
519 if((name == NULL || strcmp(ofmt->name, name)<0) &&
520 strcmp(ofmt->name, last_name)>0){
521 name= ofmt->name;
522 long_name= ofmt->long_name;
523 encode=1;
524 }
525 }
526 while((ifmt= av_iformat_next(ifmt))) {
527 if((name == NULL || strcmp(ifmt->name, name)<0) &&
528 strcmp(ifmt->name, last_name)>0){
529 name= ifmt->name;
530 long_name= ifmt->long_name;
531 encode=0;
532 }
533 if(name && strcmp(ifmt->name, name)==0)
534 decode=1;
535 }
536 if(name==NULL)
537 break;
538 last_name= name;
539
540 printf(
541 " %s%s %-15s %s\n",
542 decode ? "D":" ",
543 encode ? "E":" ",
544 name,
545 long_name ? long_name:" ");
546 }
547 }
548
549 void show_codecs(void)
550 {
551 AVCodec *p=NULL, *p2;
552 const char *last_name;
553 printf(
554 "Codecs:\n"
555 " D..... = Decoding supported\n"
556 " .E.... = Encoding supported\n"
557 " ..V... = Video codec\n"
558 " ..A... = Audio codec\n"
559 " ..S... = Subtitle codec\n"
560 " ...S.. = Supports draw_horiz_band\n"
561 " ....D. = Supports direct rendering method 1\n"
562 " .....T = Supports weird frame truncation\n"
563 " ------\n");
564 last_name= "000";
565 for(;;){
566 int decode=0;
567 int encode=0;
568 int cap=0;
569 const char *type_str;
570
571 p2=NULL;
572 while((p= av_codec_next(p))) {
573 if((p2==NULL || strcmp(p->name, p2->name)<0) &&
574 strcmp(p->name, last_name)>0){
575 p2= p;
576 decode= encode= cap=0;
577 }
578 if(p2 && strcmp(p->name, p2->name)==0){
579 if(p->decode) decode=1;
580 if(p->encode) encode=1;
581 cap |= p->capabilities;
582 }
583 }
584 if(p2==NULL)
585 break;
586 last_name= p2->name;
587
588 switch(p2->type) {
589 case AVMEDIA_TYPE_VIDEO:
590 type_str = "V";
591 break;
592 case AVMEDIA_TYPE_AUDIO:
593 type_str = "A";
594 break;
595 case AVMEDIA_TYPE_SUBTITLE:
596 type_str = "S";
597 break;
598 default:
599 type_str = "?";
600 break;
601 }
602 printf(
603 " %s%s%s%s%s%s %-15s %s",
604 decode ? "D": (/*p2->decoder ? "d":*/" "),
605 encode ? "E":" ",
606 type_str,
607 cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
608 cap & CODEC_CAP_DR1 ? "D":" ",
609 cap & CODEC_CAP_TRUNCATED ? "T":" ",
610 p2->name,
611 p2->long_name ? p2->long_name : "");
612 /* if(p2->decoder && decode==0)
613 printf(" use %s for decoding", p2->decoder->name);*/
614 printf("\n");
615 }
616 printf("\n");
617 printf(
618 "Note, the names of encoders and decoders do not always match, so there are\n"
619 "several cases where the above table shows encoder only or decoder only entries\n"
620 "even though both encoding and decoding are supported. For example, the h263\n"
621 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
622 "worse.\n");
623 }
624
625 void show_bsfs(void)
626 {
627 AVBitStreamFilter *bsf=NULL;
628
629 printf("Bitstream filters:\n");
630 while((bsf = av_bitstream_filter_next(bsf)))
631 printf("%s\n", bsf->name);
632 printf("\n");
633 }
634
635 void show_protocols(void)
636 {
637 void *opaque = NULL;
638 const char *name;
639
640 printf("Supported file protocols:\n"
641 "Input:\n");
642 while ((name = avio_enum_protocols(&opaque, 0)))
643 printf("%s\n", name);
644 printf("Output:\n");
645 while ((name = avio_enum_protocols(&opaque, 1)))
646 printf("%s\n", name);
647 }
648
649 void show_filters(void)
650 {
651 AVFilter av_unused(**filter) = NULL;
652
653 printf("Filters:\n");
654 #if CONFIG_AVFILTER
655 while ((filter = av_filter_next(filter)) && *filter)
656 printf("%-16s %s\n", (*filter)->name, (*filter)->description);
657 #endif
658 }
659
660 void show_pix_fmts(void)
661 {
662 enum PixelFormat pix_fmt;
663
664 printf(
665 "Pixel formats:\n"
666 "I.... = Supported Input format for conversion\n"
667 ".O... = Supported Output format for conversion\n"
668 "..H.. = Hardware accelerated format\n"
669 "...P. = Paletted format\n"
670 "....B = Bitstream format\n"
671 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
672 "-----\n");
673
674 #if !CONFIG_SWSCALE
675 # define sws_isSupportedInput(x) 0
676 # define sws_isSupportedOutput(x) 0
677 #endif
678
679 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
680 const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
681 printf("%c%c%c%c%c %-16s %d %2d\n",
682 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
683 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
684 pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
685 pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
686 pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
687 pix_desc->name,
688 pix_desc->nb_components,
689 av_get_bits_per_pixel(pix_desc));
690 }
691 }
692
693 int read_yesno(void)
694 {
695 int c = getchar();
696 int yesno = (toupper(c) == 'Y');
697
698 while (c != '\n' && c != EOF)
699 c = getchar();
700
701 return yesno;
702 }
703
704 int read_file(const char *filename, char **bufptr, size_t *size)
705 {
706 FILE *f = fopen(filename, "rb");
707
708 if (!f) {
709 fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
710 return AVERROR(errno);
711 }
712 fseek(f, 0, SEEK_END);
713 *size = ftell(f);
714 fseek(f, 0, SEEK_SET);
715 *bufptr = av_malloc(*size + 1);
716 if (!*bufptr) {
717 fprintf(stderr, "Could not allocate file buffer\n");
718 fclose(f);
719 return AVERROR(ENOMEM);
720 }
721 fread(*bufptr, 1, *size, f);
722 (*bufptr)[*size++] = '\0';
723
724 fclose(f);
725 return 0;
726 }
727
728 void init_pts_correction(PtsCorrectionContext *ctx)
729 {
730 ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
731 ctx->last_pts = ctx->last_dts = INT64_MIN;
732 }
733
734 int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts, int64_t dts)
735 {
736 int64_t pts = AV_NOPTS_VALUE;
737
738 if (dts != AV_NOPTS_VALUE) {
739 ctx->num_faulty_dts += dts <= ctx->last_dts;
740 ctx->last_dts = dts;
741 }
742 if (reordered_pts != AV_NOPTS_VALUE) {
743 ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
744 ctx->last_pts = reordered_pts;
745 }
746 if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
747 && reordered_pts != AV_NOPTS_VALUE)
748 pts = reordered_pts;
749 else
750 pts = dts;
751
752 return pts;
753 }
754
755 FILE *get_preset_file(char *filename, size_t filename_size,
756 const char *preset_name, int is_path, const char *codec_name)
757 {
758 FILE *f = NULL;
759 int i;
760 const char *base[3]= { getenv("AVCONV_DATADIR"),
761 getenv("HOME"),
762 AVCONV_DATADIR,
763 };
764
765 if (is_path) {
766 av_strlcpy(filename, preset_name, filename_size);
767 f = fopen(filename, "r");
768 } else {
769 for (i = 0; i < 3 && !f; i++) {
770 if (!base[i])
771 continue;
772 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", preset_name);
773 f = fopen(filename, "r");
774 if (!f && codec_name) {
775 snprintf(filename, filename_size,
776 "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", codec_name, preset_name);
777 f = fopen(filename, "r");
778 }
779 }
780 }
781
782 return f;
783 }
784
785 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
786 {
787 if (*spec <= '9' && *spec >= '0') /* opt:index */
788 return strtol(spec, NULL, 0) == st->index;
789 else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd') { /* opt:[vasd] */
790 enum AVMediaType type;
791
792 switch (*spec++) {
793 case 'v': type = AVMEDIA_TYPE_VIDEO; break;
794 case 'a': type = AVMEDIA_TYPE_AUDIO; break;
795 case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
796 case 'd': type = AVMEDIA_TYPE_DATA; break;
797 }
798 if (type != st->codec->codec_type)
799 return 0;
800 if (*spec++ == ':') { /* possibly followed by :index */
801 int i, index = strtol(spec, NULL, 0);
802 for (i = 0; i < s->nb_streams; i++)
803 if (s->streams[i]->codec->codec_type == type && index-- == 0)
804 return i == st->index;
805 return 0;
806 }
807 return 1;
808 } else if (!*spec) /* empty specifier, matches everything */
809 return 1;
810
811 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
812 return AVERROR(EINVAL);
813 }
814
815 AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
816 {
817 AVDictionary *ret = NULL;
818 AVDictionaryEntry *t = NULL;
819 AVCodec *codec = s->oformat ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
820 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
821 char prefix = 0;
822 const AVClass *cc = avcodec_get_class();
823
824 if (!codec)
825 return NULL;
826
827 switch (codec->type) {
828 case AVMEDIA_TYPE_VIDEO: prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM; break;
829 case AVMEDIA_TYPE_AUDIO: prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM; break;
830 case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
831 }
832
833 while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
834 char *p = strchr(t->key, ':');
835
836 /* check stream specification in opt name */
837 if (p)
838 switch (check_stream_specifier(s, st, p + 1)) {
839 case 1: *p = 0; break;
840 case 0: continue;
841 default: return NULL;
842 }
843
844 if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
845 (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ)))
846 av_dict_set(&ret, t->key, t->value, 0);
847 else if (t->key[0] == prefix && av_opt_find(&cc, t->key+1, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))
848 av_dict_set(&ret, t->key+1, t->value, 0);
849
850 if (p)
851 *p = ':';
852 }
853 return ret;
854 }
855
856 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
857 {
858 int i;
859 AVDictionary **opts;
860
861 if (!s->nb_streams)
862 return NULL;
863 opts = av_mallocz(s->nb_streams * sizeof(*opts));
864 if (!opts) {
865 av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
866 return NULL;
867 }
868 for (i = 0; i < s->nb_streams; i++)
869 opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
870 return opts;
871 }
872
873 #if CONFIG_AVFILTER
874
875 static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
876 {
877 FFSinkContext *priv = ctx->priv;
878
879 if (!opaque)
880 return AVERROR(EINVAL);
881 *priv = *(FFSinkContext *)opaque;
882
883 return 0;
884 }
885
886 static void null_end_frame(AVFilterLink *inlink) { }
887
888 static int ffsink_query_formats(AVFilterContext *ctx)
889 {
890 FFSinkContext *priv = ctx->priv;
891 enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
892
893 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
894 return 0;
895 }
896
897 AVFilter ffsink = {
898 .name = "ffsink",
899 .priv_size = sizeof(FFSinkContext),
900 .init = ffsink_init,
901
902 .query_formats = ffsink_query_formats,
903
904 .inputs = (AVFilterPad[]) {{ .name = "default",
905 .type = AVMEDIA_TYPE_VIDEO,
906 .end_frame = null_end_frame,
907 .min_perms = AV_PERM_READ, },
908 { .name = NULL }},
909 .outputs = (AVFilterPad[]) {{ .name = NULL }},
910 };
911
912 int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
913 AVFilterBufferRef **picref_ptr, AVRational *tb)
914 {
915 int ret;
916 AVFilterBufferRef *picref;
917
918 if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
919 return ret;
920 if (!(picref = ctx->inputs[0]->cur_buf))
921 return AVERROR(ENOENT);
922 *picref_ptr = picref;
923 ctx->inputs[0]->cur_buf = NULL;
924 *tb = ctx->inputs[0]->time_base;
925
926 memcpy(frame->data, picref->data, sizeof(frame->data));
927 memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
928 frame->interlaced_frame = picref->video->interlaced;
929 frame->top_field_first = picref->video->top_field_first;
930 frame->key_frame = picref->video->key_frame;
931 frame->pict_type = picref->video->pict_type;
932
933 return 1;
934 }
935
936 void *grow_array(void *array, int elem_size, int *size, int new_size)
937 {
938 if (new_size >= INT_MAX / elem_size) {
939 av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
940 exit_program(1);
941 }
942 if (*size < new_size) {
943 uint8_t *tmp = av_realloc(array, new_size*elem_size);
944 if (!tmp) {
945 av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
946 exit_program(1);
947 }
948 memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
949 *size = new_size;
950 return tmp;
951 }
952 return array;
953 }
954
955 #endif /* CONFIG_AVFILTER */