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