cmdutils: add support for caller-provided option context.
[libav.git] / cmdutils.c
CommitLineData
01310af2
FB
1/*
2 * Various utilities for command line tools
3 * Copyright (c) 2000-2003 Fabrice Bellard
4 *
2912e87a 5 * This file is part of Libav.
b78e7197 6 *
2912e87a 7 * Libav is free software; you can redistribute it and/or
01310af2
FB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
01310af2 11 *
2912e87a 12 * Libav is distributed in the hope that it will be useful,
01310af2
FB
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
2912e87a 18 * License along with Libav; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
01310af2 20 */
364a9607 21
0f4e8165
RB
22#include <string.h>
23#include <stdlib.h>
24#include <errno.h>
7c84b8bc 25#include <math.h>
0f4e8165 26
2cd39dbf
DP
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
63d026b1 31#include "config.h"
245976da
DB
32#include "libavformat/avformat.h"
33#include "libavfilter/avfilter.h"
34#include "libavdevice/avdevice.h"
db6d50c7 35#include "libswscale/swscale.h"
1981deaf 36#include "libpostproc/postprocess.h"
245976da 37#include "libavutil/avstring.h"
f6c7375a 38#include "libavutil/parseutils.h"
9cb5c760 39#include "libavutil/pixdesc.h"
25e25617 40#include "libavutil/eval.h"
9ba38229 41#include "libavutil/dict.h"
41d0eb1c 42#include "libavutil/opt.h"
01310af2 43#include "cmdutils.h"
86074ed1 44#include "version.h"
da2dc39e 45#if CONFIG_NETWORK
245976da 46#include "libavformat/network.h"
da2dc39e 47#endif
ffcc6e24
MR
48#if HAVE_SYS_RESOURCE_H
49#include <sys/resource.h>
50#endif
01310af2 51
85663ef3 52struct SwsContext *sws_opts;
8c8eab8b 53AVDictionary *format_opts, *codec_opts;
086ab001 54
3568853f 55static const int this_year = 2011;
ef4c0bb1 56
a5c33faa
RD
57void init_opts(void)
58{
be4876ea 59#if CONFIG_SWSCALE
a5c33faa 60 sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
be4876ea 61#endif
a5c33faa
RD
62}
63
64void uninit_opts(void)
65{
be4876ea 66#if CONFIG_SWSCALE
faf8d3dd
RB
67 sws_freeContext(sws_opts);
68 sws_opts = NULL;
be4876ea 69#endif
9ba38229 70 av_dict_free(&format_opts);
8c8eab8b 71 av_dict_free(&codec_opts);
a5c33faa
RD
72}
73
1790d3b3
SS
74void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
75{
76 vfprintf(stdout, fmt, vl);
77}
78
086ab001
MN
79double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
80{
81 char *tail;
82 const char *error;
25e25617 83 double d = av_strtod(numstr, &tail);
086ab001
MN
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";
3372ec32
SS
90 else if (type == OPT_INT && (int)d != d)
91 error= "Expected int for %s but found %s\n";
086ab001
MN
92 else
93 return d;
94 fprintf(stderr, error, context, numstr, min, max);
dad09ff9
AK
95 exit_program(1);
96 return 0;
086ab001
MN
97}
98
7542157d
SS
99int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
100{
f6c7375a
SS
101 int64_t us;
102 if (av_parse_time(&us, timestr, is_duration) < 0) {
7542157d
SS
103 fprintf(stderr, "Invalid %s specification for %s: %s\n",
104 is_duration ? "duration" : "date", context, timestr);
dad09ff9 105 exit_program(1);
7542157d
SS
106 }
107 return us;
108}
109
02d504a7 110void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
01310af2
FB
111{
112 const OptionDef *po;
02d504a7 113 int first;
01310af2 114
02d504a7
FB
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 }
f7d78f36 123 av_strlcpy(buf, po->name, sizeof(buf));
02d504a7 124 if (po->flags & HAS_ARG) {
f7d78f36
MR
125 av_strlcat(buf, " ", sizeof(buf));
126 av_strlcat(buf, po->argname, sizeof(buf));
01310af2 127 }
02d504a7 128 printf("-%-17s %s\n", buf, po->help);
01310af2
FB
129 }
130 }
131}
132
fccfc475 133static const OptionDef* find_option(const OptionDef *po, const char *name){
d70e5122
AK
134 const char *p = strchr(name, ':');
135 int len = p ? p - name : strlen(name);
136
8bbf6db9 137 while (po->name != NULL) {
d70e5122 138 if (!strncmp(name, po->name, len) && strlen(po->name) == len)
8bbf6db9
MN
139 break;
140 po++;
141 }
142 return po;
143}
144
b1ac139d 145#if defined(_WIN32) && !defined(__MINGW32CE__)
ba9327ea 146#include <windows.h>
b1ac139d
KG
147/* Will be leaked on exit */
148static char** win32_argv_utf8 = NULL;
149static 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 */
158static 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
200static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
201{
202 /* nothing to do */
203}
204#endif /* WIN32 && !__MINGW32CE__ */
205
7cc8d638
AK
206void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
207 void (* parse_arg_function)(void *, const char*))
01310af2
FB
208{
209 const char *opt, *arg;
b0d7bc1e 210 int optindex, handleoptions=1;
01310af2
FB
211 const OptionDef *po;
212
b1ac139d
KG
213 /* perform system-dependent conversions for arguments list */
214 prepare_app_arguments(&argc, &argv);
215
01310af2
FB
216 /* parse options */
217 optindex = 1;
218 while (optindex < argc) {
7efe05ab 219 void *dst;
01310af2 220 opt = argv[optindex++];
115329f1 221
84bf226b 222 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
b1d6e5e8 223 int bool_val = 1;
3749076c
SS
224 if (opt[1] == '-' && opt[2] == '\0') {
225 handleoptions = 0;
226 continue;
227 }
c3c78324
SS
228 opt++;
229 po= find_option(options, opt);
230 if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
b1d6e5e8 231 /* handle 'no' bool option */
c3c78324 232 po = find_option(options, opt + 2);
b1d6e5e8
BF
233 if (!(po->name && (po->flags & OPT_BOOL)))
234 goto unknown_opt;
235 bool_val = 0;
236 }
8bbf6db9
MN
237 if (!po->name)
238 po= find_option(options, "default");
01310af2 239 if (!po->name) {
8bbf6db9 240unknown_opt:
01310af2 241 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
dad09ff9 242 exit_program(1);
01310af2
FB
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);
dad09ff9 249 exit_program(1);
01310af2
FB
250 }
251 }
7cc8d638
AK
252 /* new-style options contain an offset into optctx, old-style address of
253 * a global var*/
254 dst = po->flags & OPT_OFFSET ? (uint8_t*)optctx + po->u.off : po->u.dst_ptr;
01310af2
FB
255 if (po->flags & OPT_STRING) {
256 char *str;
02d504a7 257 str = av_strdup(arg);
7efe05ab 258 *(char**)dst = str;
01310af2 259 } else if (po->flags & OPT_BOOL) {
7efe05ab 260 *(int*)dst = bool_val;
26d4f26b 261 } else if (po->flags & OPT_INT) {
7efe05ab 262 *(int*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
ffdf9a1f 263 } else if (po->flags & OPT_INT64) {
7efe05ab 264 *(int64_t*)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
1f631450 265 } else if (po->flags & OPT_FLOAT) {
7efe05ab 266 *(float*)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
de859358 267 } else if (po->u.func_arg) {
7cc8d638
AK
268 int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg) :
269 po->u.func_arg(opt, arg);
270 if (ret < 0) {
330d86f5 271 fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
dad09ff9 272 exit_program(1);
9e5381a2 273 }
01310af2 274 }
a0b3bcd9 275 if(po->flags & OPT_EXIT)
dad09ff9 276 exit_program(0);
01310af2 277 } else {
60a9966e 278 if (parse_arg_function)
7cc8d638 279 parse_arg_function(optctx, opt);
01310af2
FB
280 }
281 }
282}
283
9ba38229 284#define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
35d2e4e5 285int opt_default(const char *opt, const char *arg)
9ba38229
AK
286{
287 const AVOption *o;
d4863fc1
AK
288 char opt_stripped[128];
289 const char *p;
20c21f8b 290 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc = sws_get_class();
d4863fc1
AK
291
292 if (!(p = strchr(opt, ':')))
293 p = opt + strlen(opt);
294 av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
295
20c21f8b 296 if ((o = av_opt_find(&cc, opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN|AV_OPT_SEARCH_FAKE_OBJ)) ||
8c8eab8b 297 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
20c21f8b 298 (o = av_opt_find(&cc, opt+1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
8c8eab8b 299 av_dict_set(&codec_opts, opt, arg, FLAGS);
20c21f8b 300 else if ((o = av_opt_find(&fc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
9ba38229 301 av_dict_set(&format_opts, opt, arg, FLAGS);
20c21f8b 302 else if ((o = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
9ba38229
AK
303 // XXX we only support sws_flags, not arbitrary sws options
304 int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
305 if (ret < 0) {
306 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
307 return ret;
308 }
309 }
310
9ba38229
AK
311 if (o)
312 return 0;
313 fprintf(stderr, "Unrecognized option '%s'\n", opt);
314 return AVERROR_OPTION_NOT_FOUND;
315}
316
4c97a6fa
SS
317int opt_loglevel(const char *opt, const char *arg)
318{
da4c2dab 319 const struct { const char *name; int level; } log_levels[] = {
4c97a6fa
SS
320 { "quiet" , AV_LOG_QUIET },
321 { "panic" , AV_LOG_PANIC },
322 { "fatal" , AV_LOG_FATAL },
323 { "error" , AV_LOG_ERROR },
324 { "warning", AV_LOG_WARNING },
325 { "info" , AV_LOG_INFO },
326 { "verbose", AV_LOG_VERBOSE },
327 { "debug" , AV_LOG_DEBUG },
328 };
329 char *tail;
330 int level;
331 int i;
332
333 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
334 if (!strcmp(log_levels[i].name, arg)) {
335 av_log_set_level(log_levels[i].level);
336 return 0;
337 }
338 }
339
340 level = strtol(arg, &tail, 10);
341 if (*tail) {
342 fprintf(stderr, "Invalid loglevel \"%s\". "
343 "Possible levels are numbers or:\n", arg);
344 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
345 fprintf(stderr, "\"%s\"\n", log_levels[i].name);
dad09ff9 346 exit_program(1);
4c97a6fa
SS
347 }
348 av_log_set_level(level);
349 return 0;
350}
351
ffcc6e24
MR
352int opt_timelimit(const char *opt, const char *arg)
353{
0104b608 354#if HAVE_SETRLIMIT
ffcc6e24
MR
355 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
356 struct rlimit rl = { lim, lim + 1 };
357 if (setrlimit(RLIMIT_CPU, &rl))
358 perror("setrlimit");
359#else
360 fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
361#endif
362 return 0;
363}
364
01310af2
FB
365void print_error(const char *filename, int err)
366{
7a5bdd79 367 char errbuf[128];
735ef67b 368 const char *errbuf_ptr = errbuf;
7a5bdd79 369
9e94bd3e
SS
370 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
371 errbuf_ptr = strerror(AVUNERROR(err));
372 fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
01310af2 373}
f35917b2 374
d101e731
SS
375static int warned_cfg = 0;
376
208749a0
SS
377#define INDENT 1
378#define SHOW_VERSION 2
d101e731 379#define SHOW_CONFIG 4
208749a0 380
1044a92a 381#define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags) \
5116571d 382 if (CONFIG_##LIBNAME) { \
65dd2ded 383 const char *indent = flags & INDENT? " " : ""; \
208749a0 384 if (flags & SHOW_VERSION) { \
b6525b4b 385 unsigned int version = libname##_version(); \
c0dd5653 386 fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
65dd2ded 387 indent, #libname, \
b6525b4b
SS
388 LIB##LIBNAME##_VERSION_MAJOR, \
389 LIB##LIBNAME##_VERSION_MINOR, \
390 LIB##LIBNAME##_VERSION_MICRO, \
391 version >> 16, version >> 8 & 0xff, version & 0xff); \
208749a0 392 } \
d101e731
SS
393 if (flags & SHOW_CONFIG) { \
394 const char *cfg = libname##_configuration(); \
29ba0911 395 if (strcmp(LIBAV_CONFIGURATION, cfg)) { \
d101e731
SS
396 if (!warned_cfg) { \
397 fprintf(outstream, \
398 "%sWARNING: library configuration mismatch\n", \
65dd2ded 399 indent); \
d101e731
SS
400 warned_cfg = 1; \
401 } \
402 fprintf(stderr, "%s%-11s configuration: %s\n", \
65dd2ded 403 indent, #libname, cfg); \
d101e731
SS
404 } \
405 } \
208749a0 406 } \
9a109272 407
1044a92a 408static void print_all_libs_info(FILE* outstream, int flags)
9a109272 409{
1044a92a 410 PRINT_LIB_INFO(outstream, avutil, AVUTIL, flags);
1044a92a
SS
411 PRINT_LIB_INFO(outstream, avcodec, AVCODEC, flags);
412 PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
413 PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
414 PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
415 PRINT_LIB_INFO(outstream, swscale, SWSCALE, flags);
416 PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
9a109272
SS
417}
418
ea9c581f 419void show_banner(void)
86074ed1 420{
a03be6e1 421 fprintf(stderr, "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
ef4c0bb1 422 program_name, program_birth_year, this_year);
a3d7c197
DB
423 fprintf(stderr, " built on %s %s with %s %s\n",
424 __DATE__, __TIME__, CC_TYPE, CC_VERSION);
29ba0911 425 fprintf(stderr, " configuration: " LIBAV_CONFIGURATION "\n");
d101e731 426 print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
1044a92a 427 print_all_libs_info(stderr, INDENT|SHOW_VERSION);
86074ed1
SS
428}
429
64555bd9 430void show_version(void) {
a03be6e1 431 printf("%s " LIBAV_VERSION "\n", program_name);
1044a92a 432 print_all_libs_info(stdout, SHOW_VERSION);
86074ed1
SS
433}
434
f35917b2
SS
435void show_license(void)
436{
7ead693b 437 printf(
3bf28f9d 438#if CONFIG_NONFREE
304ba23a
SS
439 "This version of %s has nonfree parts compiled in.\n"
440 "Therefore it is not legally redistributable.\n",
441 program_name
9cad0e4e
DB
442#elif CONFIG_GPLV3
443 "%s is free software; you can redistribute it and/or modify\n"
444 "it under the terms of the GNU General Public License as published by\n"
445 "the Free Software Foundation; either version 3 of the License, or\n"
446 "(at your option) any later version.\n"
447 "\n"
448 "%s is distributed in the hope that it will be useful,\n"
449 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
450 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
451 "GNU General Public License for more details.\n"
452 "\n"
453 "You should have received a copy of the GNU General Public License\n"
454 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
455 program_name, program_name, program_name
7ead693b 456#elif CONFIG_GPL
304ba23a 457 "%s is free software; you can redistribute it and/or modify\n"
f35917b2
SS
458 "it under the terms of the GNU General Public License as published by\n"
459 "the Free Software Foundation; either version 2 of the License, or\n"
460 "(at your option) any later version.\n"
461 "\n"
304ba23a 462 "%s is distributed in the hope that it will be useful,\n"
f35917b2
SS
463 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
464 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
465 "GNU General Public License for more details.\n"
466 "\n"
467 "You should have received a copy of the GNU General Public License\n"
304ba23a
SS
468 "along with %s; if not, write to the Free Software\n"
469 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
470 program_name, program_name, program_name
9cad0e4e
DB
471#elif CONFIG_LGPLV3
472 "%s is free software; you can redistribute it and/or modify\n"
473 "it under the terms of the GNU Lesser General Public License as published by\n"
474 "the Free Software Foundation; either version 3 of the License, or\n"
475 "(at your option) any later version.\n"
476 "\n"
477 "%s is distributed in the hope that it will be useful,\n"
478 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
479 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
480 "GNU Lesser General Public License for more details.\n"
481 "\n"
482 "You should have received a copy of the GNU Lesser General Public License\n"
483 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
484 program_name, program_name, program_name
f35917b2 485#else
304ba23a 486 "%s is free software; you can redistribute it and/or\n"
f35917b2
SS
487 "modify it under the terms of the GNU Lesser General Public\n"
488 "License as published by the Free Software Foundation; either\n"
489 "version 2.1 of the License, or (at your option) any later version.\n"
490 "\n"
304ba23a 491 "%s is distributed in the hope that it will be useful,\n"
f35917b2
SS
492 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
493 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
494 "Lesser General Public License for more details.\n"
495 "\n"
496 "You should have received a copy of the GNU Lesser General Public\n"
304ba23a
SS
497 "License along with %s; if not, write to the Free Software\n"
498 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
499 program_name, program_name, program_name
f35917b2 500#endif
3bf28f9d 501 );
f35917b2 502}
ba9880c1
SS
503
504void show_formats(void)
505{
506 AVInputFormat *ifmt=NULL;
507 AVOutputFormat *ofmt=NULL;
ba9880c1
SS
508 const char *last_name;
509
5a8597a0
WZ
510 printf(
511 "File formats:\n"
512 " D. = Demuxing supported\n"
513 " .E = Muxing supported\n"
514 " --\n");
ba9880c1
SS
515 last_name= "000";
516 for(;;){
517 int decode=0;
518 int encode=0;
519 const char *name=NULL;
520 const char *long_name=NULL;
521
522 while((ofmt= av_oformat_next(ofmt))) {
523 if((name == NULL || strcmp(ofmt->name, name)<0) &&
524 strcmp(ofmt->name, last_name)>0){
525 name= ofmt->name;
526 long_name= ofmt->long_name;
527 encode=1;
528 }
529 }
530 while((ifmt= av_iformat_next(ifmt))) {
531 if((name == NULL || strcmp(ifmt->name, name)<0) &&
532 strcmp(ifmt->name, last_name)>0){
533 name= ifmt->name;
534 long_name= ifmt->long_name;
535 encode=0;
536 }
537 if(name && strcmp(ifmt->name, name)==0)
538 decode=1;
539 }
540 if(name==NULL)
541 break;
542 last_name= name;
543
544 printf(
545 " %s%s %-15s %s\n",
546 decode ? "D":" ",
547 encode ? "E":" ",
548 name,
549 long_name ? long_name:" ");
550 }
8447f0bd 551}
ba9880c1 552
8447f0bd
MN
553void show_codecs(void)
554{
555 AVCodec *p=NULL, *p2;
556 const char *last_name;
5a8597a0
WZ
557 printf(
558 "Codecs:\n"
559 " D..... = Decoding supported\n"
560 " .E.... = Encoding supported\n"
561 " ..V... = Video codec\n"
562 " ..A... = Audio codec\n"
563 " ..S... = Subtitle codec\n"
564 " ...S.. = Supports draw_horiz_band\n"
565 " ....D. = Supports direct rendering method 1\n"
566 " .....T = Supports weird frame truncation\n"
567 " ------\n");
ba9880c1
SS
568 last_name= "000";
569 for(;;){
570 int decode=0;
571 int encode=0;
572 int cap=0;
573 const char *type_str;
574
575 p2=NULL;
576 while((p= av_codec_next(p))) {
577 if((p2==NULL || strcmp(p->name, p2->name)<0) &&
578 strcmp(p->name, last_name)>0){
579 p2= p;
580 decode= encode= cap=0;
581 }
582 if(p2 && strcmp(p->name, p2->name)==0){
583 if(p->decode) decode=1;
584 if(p->encode) encode=1;
585 cap |= p->capabilities;
586 }
587 }
588 if(p2==NULL)
589 break;
590 last_name= p2->name;
591
592 switch(p2->type) {
72415b2a 593 case AVMEDIA_TYPE_VIDEO:
ba9880c1
SS
594 type_str = "V";
595 break;
72415b2a 596 case AVMEDIA_TYPE_AUDIO:
ba9880c1
SS
597 type_str = "A";
598 break;
72415b2a 599 case AVMEDIA_TYPE_SUBTITLE:
ba9880c1
SS
600 type_str = "S";
601 break;
602 default:
603 type_str = "?";
604 break;
605 }
606 printf(
607 " %s%s%s%s%s%s %-15s %s",
608 decode ? "D": (/*p2->decoder ? "d":*/" "),
609 encode ? "E":" ",
610 type_str,
611 cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
612 cap & CODEC_CAP_DR1 ? "D":" ",
613 cap & CODEC_CAP_TRUNCATED ? "T":" ",
614 p2->name,
615 p2->long_name ? p2->long_name : "");
616 /* if(p2->decoder && decode==0)
617 printf(" use %s for decoding", p2->decoder->name);*/
618 printf("\n");
619 }
620 printf("\n");
8447f0bd
MN
621 printf(
622"Note, the names of encoders and decoders do not always match, so there are\n"
623"several cases where the above table shows encoder only or decoder only entries\n"
624"even though both encoding and decoding are supported. For example, the h263\n"
625"decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
626"worse.\n");
627}
628
629void show_bsfs(void)
630{
631 AVBitStreamFilter *bsf=NULL;
ba9880c1
SS
632
633 printf("Bitstream filters:\n");
634 while((bsf = av_bitstream_filter_next(bsf)))
2091b27b 635 printf("%s\n", bsf->name);
ba9880c1 636 printf("\n");
8447f0bd
MN
637}
638
639void show_protocols(void)
640{
cdc6a87f
AK
641 void *opaque = NULL;
642 const char *name;
ba9880c1 643
2ee5c789 644 printf("Supported file protocols:\n"
cdc6a87f
AK
645 "Input:\n");
646 while ((name = avio_enum_protocols(&opaque, 0)))
647 printf("%s\n", name);
648 printf("Output:\n");
649 while ((name = avio_enum_protocols(&opaque, 1)))
650 printf("%s\n", name);
ba9880c1 651}
090b61b2 652
62d75662
SS
653void show_filters(void)
654{
78638628 655 AVFilter av_unused(**filter) = NULL;
62d75662
SS
656
657 printf("Filters:\n");
663c2edf 658#if CONFIG_AVFILTER
62d75662
SS
659 while ((filter = av_filter_next(filter)) && *filter)
660 printf("%-16s %s\n", (*filter)->name, (*filter)->description);
663c2edf 661#endif
62d75662
SS
662}
663
3f7bb426
SS
664void show_pix_fmts(void)
665{
9cb5c760
SS
666 enum PixelFormat pix_fmt;
667
668 printf(
669 "Pixel formats:\n"
670 "I.... = Supported Input format for conversion\n"
671 ".O... = Supported Output format for conversion\n"
672 "..H.. = Hardware accelerated format\n"
673 "...P. = Paletted format\n"
674 "....B = Bitstream format\n"
675 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
676 "-----\n");
677
e24db3e3
MR
678#if !CONFIG_SWSCALE
679# define sws_isSupportedInput(x) 0
680# define sws_isSupportedOutput(x) 0
681#endif
682
9cb5c760
SS
683 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
684 const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
685 printf("%c%c%c%c%c %-16s %d %2d\n",
686 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
687 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
688 pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
689 pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
690 pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
691 pix_desc->name,
692 pix_desc->nb_components,
693 av_get_bits_per_pixel(pix_desc));
694 }
3f7bb426
SS
695}
696
090b61b2
SS
697int read_yesno(void)
698{
699 int c = getchar();
700 int yesno = (toupper(c) == 'Y');
701
702 while (c != '\n' && c != EOF)
703 c = getchar();
704
705 return yesno;
706}
458b062d
SS
707
708int read_file(const char *filename, char **bufptr, size_t *size)
709{
c56e9e05 710 FILE *f = fopen(filename, "rb");
458b062d
SS
711
712 if (!f) {
713 fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
714 return AVERROR(errno);
715 }
716 fseek(f, 0, SEEK_END);
717 *size = ftell(f);
718 fseek(f, 0, SEEK_SET);
719 *bufptr = av_malloc(*size + 1);
720 if (!*bufptr) {
721 fprintf(stderr, "Could not allocate file buffer\n");
722 fclose(f);
723 return AVERROR(ENOMEM);
724 }
725 fread(*bufptr, 1, *size, f);
726 (*bufptr)[*size++] = '\0';
727
728 fclose(f);
729 return 0;
730}
7a8bfa5d
AS
731
732void init_pts_correction(PtsCorrectionContext *ctx)
733{
734 ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
735 ctx->last_pts = ctx->last_dts = INT64_MIN;
736}
737
738int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts, int64_t dts)
739{
740 int64_t pts = AV_NOPTS_VALUE;
741
742 if (dts != AV_NOPTS_VALUE) {
743 ctx->num_faulty_dts += dts <= ctx->last_dts;
744 ctx->last_dts = dts;
745 }
746 if (reordered_pts != AV_NOPTS_VALUE) {
747 ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
748 ctx->last_pts = reordered_pts;
749 }
01d46198 750 if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
7a8bfa5d
AS
751 && reordered_pts != AV_NOPTS_VALUE)
752 pts = reordered_pts;
753 else
754 pts = dts;
755
756 return pts;
757}
f7ead94c 758
6e872935
SS
759FILE *get_preset_file(char *filename, size_t filename_size,
760 const char *preset_name, int is_path, const char *codec_name)
761{
762 FILE *f = NULL;
763 int i;
6291d7e4 764 const char *base[3]= { getenv("AVCONV_DATADIR"),
6e872935 765 getenv("HOME"),
6291d7e4 766 AVCONV_DATADIR,
6e872935
SS
767 };
768
769 if (is_path) {
770 av_strlcpy(filename, preset_name, filename_size);
771 f = fopen(filename, "r");
772 } else {
773 for (i = 0; i < 3 && !f; i++) {
774 if (!base[i])
775 continue;
6291d7e4 776 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", preset_name);
6e872935
SS
777 f = fopen(filename, "r");
778 if (!f && codec_name) {
779 snprintf(filename, filename_size,
6291d7e4 780 "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", codec_name, preset_name);
6e872935
SS
781 f = fopen(filename, "r");
782 }
783 }
784 }
785
786 return f;
787}
788
d4863fc1
AK
789int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
790{
791 if (*spec <= '9' && *spec >= '0') /* opt:index */
792 return strtol(spec, NULL, 0) == st->index;
793 else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd') { /* opt:[vasd] */
794 enum AVMediaType type;
795
796 switch (*spec++) {
797 case 'v': type = AVMEDIA_TYPE_VIDEO; break;
798 case 'a': type = AVMEDIA_TYPE_AUDIO; break;
799 case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
800 case 'd': type = AVMEDIA_TYPE_DATA; break;
801 }
802 if (type != st->codec->codec_type)
803 return 0;
804 if (*spec++ == ':') { /* possibly followed by :index */
805 int i, index = strtol(spec, NULL, 0);
806 for (i = 0; i < s->nb_streams; i++)
807 if (s->streams[i]->codec->codec_type == type && index-- == 0)
808 return i == st->index;
809 return 0;
810 }
811 return 1;
812 } else if (!*spec) /* empty specifier, matches everything */
813 return 1;
814
815 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
816 return AVERROR(EINVAL);
817}
818
819AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
8c8eab8b
AK
820{
821 AVDictionary *ret = NULL;
822 AVDictionaryEntry *t = NULL;
d4863fc1
AK
823 AVCodec *codec = s->oformat ? avcodec_find_encoder(codec_id) : avcodec_find_decoder(codec_id);
824 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
8c8eab8b 825 char prefix = 0;
20c21f8b 826 const AVClass *cc = avcodec_get_class();
8c8eab8b
AK
827
828 if (!codec)
829 return NULL;
830
831 switch (codec->type) {
832 case AVMEDIA_TYPE_VIDEO: prefix = 'v'; flags |= AV_OPT_FLAG_VIDEO_PARAM; break;
833 case AVMEDIA_TYPE_AUDIO: prefix = 'a'; flags |= AV_OPT_FLAG_AUDIO_PARAM; break;
834 case AVMEDIA_TYPE_SUBTITLE: prefix = 's'; flags |= AV_OPT_FLAG_SUBTITLE_PARAM; break;
835 }
836
837 while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
d4863fc1
AK
838 char *p = strchr(t->key, ':');
839
840 /* check stream specification in opt name */
841 if (p)
842 switch (check_stream_specifier(s, st, p + 1)) {
843 case 1: *p = 0; break;
844 case 0: continue;
845 default: return NULL;
846 }
847
20c21f8b
AK
848 if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
849 (codec && codec->priv_class && av_opt_find(&codec->priv_class, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ)))
8c8eab8b 850 av_dict_set(&ret, t->key, t->value, 0);
20c21f8b 851 else if (t->key[0] == prefix && av_opt_find(&cc, t->key+1, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))
8c8eab8b 852 av_dict_set(&ret, t->key+1, t->value, 0);
d4863fc1
AK
853
854 if (p)
855 *p = ':';
8c8eab8b
AK
856 }
857 return ret;
858}
859
8ec19f84 860AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
3009f521
AK
861{
862 int i;
863 AVDictionary **opts;
864
865 if (!s->nb_streams)
866 return NULL;
867 opts = av_mallocz(s->nb_streams * sizeof(*opts));
868 if (!opts) {
869 av_log(NULL, AV_LOG_ERROR, "Could not alloc memory for stream options.\n");
870 return NULL;
871 }
872 for (i = 0; i < s->nb_streams; i++)
d4863fc1 873 opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
3009f521
AK
874 return opts;
875}
876
f7ead94c
SS
877#if CONFIG_AVFILTER
878
879static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
880{
881 FFSinkContext *priv = ctx->priv;
882
883 if (!opaque)
884 return AVERROR(EINVAL);
885 *priv = *(FFSinkContext *)opaque;
886
887 return 0;
888}
889
890static void null_end_frame(AVFilterLink *inlink) { }
891
892static int ffsink_query_formats(AVFilterContext *ctx)
893{
894 FFSinkContext *priv = ctx->priv;
895 enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
896
897 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
898 return 0;
899}
900
901AVFilter ffsink = {
902 .name = "ffsink",
903 .priv_size = sizeof(FFSinkContext),
904 .init = ffsink_init,
905
906 .query_formats = ffsink_query_formats,
907
908 .inputs = (AVFilterPad[]) {{ .name = "default",
909 .type = AVMEDIA_TYPE_VIDEO,
910 .end_frame = null_end_frame,
911 .min_perms = AV_PERM_READ, },
912 { .name = NULL }},
913 .outputs = (AVFilterPad[]) {{ .name = NULL }},
914};
915
ff0652e5
SS
916int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
917 AVFilterBufferRef **picref_ptr, AVRational *tb)
918{
919 int ret;
920 AVFilterBufferRef *picref;
921
922 if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
923 return ret;
924 if (!(picref = ctx->inputs[0]->cur_buf))
925 return AVERROR(ENOENT);
926 *picref_ptr = picref;
927 ctx->inputs[0]->cur_buf = NULL;
928 *tb = ctx->inputs[0]->time_base;
929
930 memcpy(frame->data, picref->data, sizeof(frame->data));
931 memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
932 frame->interlaced_frame = picref->video->interlaced;
933 frame->top_field_first = picref->video->top_field_first;
10d39405
RPM
934 frame->key_frame = picref->video->key_frame;
935 frame->pict_type = picref->video->pict_type;
ff0652e5
SS
936
937 return 1;
938}
939
cac651c8
AK
940void *grow_array(void *array, int elem_size, int *size, int new_size)
941{
942 if (new_size >= INT_MAX / elem_size) {
943 av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
944 exit_program(1);
945 }
946 if (*size < new_size) {
947 uint8_t *tmp = av_realloc(array, new_size*elem_size);
948 if (!tmp) {
949 av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
950 exit_program(1);
951 }
952 memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
953 *size = new_size;
954 return tmp;
955 }
956 return array;
957}
958
f7ead94c 959#endif /* CONFIG_AVFILTER */