cmdutils: split per-option code out of parse_options().
[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
2f8e586d
AK
206int 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) {
223unknown_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
7cc8d638
AK
261void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
262 void (* parse_arg_function)(void *, const char*))
01310af2 263{
2f8e586d
AK
264 const char *opt;
265 int optindex, handleoptions = 1, ret;
01310af2 266
b1ac139d
KG
267 /* perform system-dependent conversions for arguments list */
268 prepare_app_arguments(&argc, &argv);
269
01310af2
FB
270 /* parse options */
271 optindex = 1;
272 while (optindex < argc) {
273 opt = argv[optindex++];
115329f1 274
84bf226b 275 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
3749076c
SS
276 if (opt[1] == '-' && opt[2] == '\0') {
277 handleoptions = 0;
278 continue;
279 }
c3c78324 280 opt++;
2f8e586d
AK
281
282 if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
dad09ff9 283 exit_program(1);
2f8e586d 284 optindex += ret;
01310af2 285 } else {
60a9966e 286 if (parse_arg_function)
7cc8d638 287 parse_arg_function(optctx, opt);
01310af2
FB
288 }
289 }
290}
291
9ba38229 292#define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
35d2e4e5 293int opt_default(const char *opt, const char *arg)
9ba38229
AK
294{
295 const AVOption *o;
d4863fc1
AK
296 char opt_stripped[128];
297 const char *p;
20c21f8b 298 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc = sws_get_class();
d4863fc1
AK
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
20c21f8b 304 if ((o = av_opt_find(&cc, opt_stripped, NULL, 0, AV_OPT_SEARCH_CHILDREN|AV_OPT_SEARCH_FAKE_OBJ)) ||
8c8eab8b 305 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
20c21f8b 306 (o = av_opt_find(&cc, opt+1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
8c8eab8b 307 av_dict_set(&codec_opts, opt, arg, FLAGS);
20c21f8b 308 else if ((o = av_opt_find(&fc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
9ba38229 309 av_dict_set(&format_opts, opt, arg, FLAGS);
20c21f8b 310 else if ((o = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
9ba38229
AK
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
9ba38229
AK
319 if (o)
320 return 0;
321 fprintf(stderr, "Unrecognized option '%s'\n", opt);
322 return AVERROR_OPTION_NOT_FOUND;
323}
324
4c97a6fa
SS
325int opt_loglevel(const char *opt, const char *arg)
326{
da4c2dab 327 const struct { const char *name; int level; } log_levels[] = {
4c97a6fa
SS
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);
dad09ff9 354 exit_program(1);
4c97a6fa
SS
355 }
356 av_log_set_level(level);
357 return 0;
358}
359
ffcc6e24
MR
360int opt_timelimit(const char *opt, const char *arg)
361{
0104b608 362#if HAVE_SETRLIMIT
ffcc6e24
MR
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
01310af2
FB
373void print_error(const char *filename, int err)
374{
7a5bdd79 375 char errbuf[128];
735ef67b 376 const char *errbuf_ptr = errbuf;
7a5bdd79 377
9e94bd3e
SS
378 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
379 errbuf_ptr = strerror(AVUNERROR(err));
380 fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
01310af2 381}
f35917b2 382
d101e731
SS
383static int warned_cfg = 0;
384
208749a0
SS
385#define INDENT 1
386#define SHOW_VERSION 2
d101e731 387#define SHOW_CONFIG 4
208749a0 388
1044a92a 389#define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags) \
5116571d 390 if (CONFIG_##LIBNAME) { \
65dd2ded 391 const char *indent = flags & INDENT? " " : ""; \
208749a0 392 if (flags & SHOW_VERSION) { \
b6525b4b 393 unsigned int version = libname##_version(); \
c0dd5653 394 fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
65dd2ded 395 indent, #libname, \
b6525b4b
SS
396 LIB##LIBNAME##_VERSION_MAJOR, \
397 LIB##LIBNAME##_VERSION_MINOR, \
398 LIB##LIBNAME##_VERSION_MICRO, \
399 version >> 16, version >> 8 & 0xff, version & 0xff); \
208749a0 400 } \
d101e731
SS
401 if (flags & SHOW_CONFIG) { \
402 const char *cfg = libname##_configuration(); \
29ba0911 403 if (strcmp(LIBAV_CONFIGURATION, cfg)) { \
d101e731
SS
404 if (!warned_cfg) { \
405 fprintf(outstream, \
406 "%sWARNING: library configuration mismatch\n", \
65dd2ded 407 indent); \
d101e731
SS
408 warned_cfg = 1; \
409 } \
410 fprintf(stderr, "%s%-11s configuration: %s\n", \
65dd2ded 411 indent, #libname, cfg); \
d101e731
SS
412 } \
413 } \
208749a0 414 } \
9a109272 415
1044a92a 416static void print_all_libs_info(FILE* outstream, int flags)
9a109272 417{
1044a92a 418 PRINT_LIB_INFO(outstream, avutil, AVUTIL, flags);
1044a92a
SS
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);
9a109272
SS
425}
426
ea9c581f 427void show_banner(void)
86074ed1 428{
a03be6e1 429 fprintf(stderr, "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
ef4c0bb1 430 program_name, program_birth_year, this_year);
a3d7c197
DB
431 fprintf(stderr, " built on %s %s with %s %s\n",
432 __DATE__, __TIME__, CC_TYPE, CC_VERSION);
29ba0911 433 fprintf(stderr, " configuration: " LIBAV_CONFIGURATION "\n");
d101e731 434 print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
1044a92a 435 print_all_libs_info(stderr, INDENT|SHOW_VERSION);
86074ed1
SS
436}
437
64555bd9 438void show_version(void) {
a03be6e1 439 printf("%s " LIBAV_VERSION "\n", program_name);
1044a92a 440 print_all_libs_info(stdout, SHOW_VERSION);
86074ed1
SS
441}
442
f35917b2
SS
443void show_license(void)
444{
7ead693b 445 printf(
3bf28f9d 446#if CONFIG_NONFREE
304ba23a
SS
447 "This version of %s has nonfree parts compiled in.\n"
448 "Therefore it is not legally redistributable.\n",
449 program_name
9cad0e4e
DB
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
7ead693b 464#elif CONFIG_GPL
304ba23a 465 "%s is free software; you can redistribute it and/or modify\n"
f35917b2
SS
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"
304ba23a 470 "%s is distributed in the hope that it will be useful,\n"
f35917b2
SS
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"
304ba23a
SS
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
9cad0e4e
DB
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
f35917b2 493#else
304ba23a 494 "%s is free software; you can redistribute it and/or\n"
f35917b2
SS
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"
304ba23a 499 "%s is distributed in the hope that it will be useful,\n"
f35917b2
SS
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"
304ba23a
SS
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
f35917b2 508#endif
3bf28f9d 509 );
f35917b2 510}
ba9880c1
SS
511
512void show_formats(void)
513{
514 AVInputFormat *ifmt=NULL;
515 AVOutputFormat *ofmt=NULL;
ba9880c1
SS
516 const char *last_name;
517
5a8597a0
WZ
518 printf(
519 "File formats:\n"
520 " D. = Demuxing supported\n"
521 " .E = Muxing supported\n"
522 " --\n");
ba9880c1
SS
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 }
8447f0bd 559}
ba9880c1 560
8447f0bd
MN
561void show_codecs(void)
562{
563 AVCodec *p=NULL, *p2;
564 const char *last_name;
5a8597a0
WZ
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");
ba9880c1
SS
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) {
72415b2a 601 case AVMEDIA_TYPE_VIDEO:
ba9880c1
SS
602 type_str = "V";
603 break;
72415b2a 604 case AVMEDIA_TYPE_AUDIO:
ba9880c1
SS
605 type_str = "A";
606 break;
72415b2a 607 case AVMEDIA_TYPE_SUBTITLE:
ba9880c1
SS
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");
8447f0bd
MN
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
637void show_bsfs(void)
638{
639 AVBitStreamFilter *bsf=NULL;
ba9880c1
SS
640
641 printf("Bitstream filters:\n");
642 while((bsf = av_bitstream_filter_next(bsf)))
2091b27b 643 printf("%s\n", bsf->name);
ba9880c1 644 printf("\n");
8447f0bd
MN
645}
646
647void show_protocols(void)
648{
cdc6a87f
AK
649 void *opaque = NULL;
650 const char *name;
ba9880c1 651
2ee5c789 652 printf("Supported file protocols:\n"
cdc6a87f
AK
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);
ba9880c1 659}
090b61b2 660
62d75662
SS
661void show_filters(void)
662{
78638628 663 AVFilter av_unused(**filter) = NULL;
62d75662
SS
664
665 printf("Filters:\n");
663c2edf 666#if CONFIG_AVFILTER
62d75662
SS
667 while ((filter = av_filter_next(filter)) && *filter)
668 printf("%-16s %s\n", (*filter)->name, (*filter)->description);
663c2edf 669#endif
62d75662
SS
670}
671
3f7bb426
SS
672void show_pix_fmts(void)
673{
9cb5c760
SS
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
e24db3e3
MR
686#if !CONFIG_SWSCALE
687# define sws_isSupportedInput(x) 0
688# define sws_isSupportedOutput(x) 0
689#endif
690
9cb5c760
SS
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 }
3f7bb426
SS
703}
704
090b61b2
SS
705int 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}
458b062d
SS
715
716int read_file(const char *filename, char **bufptr, size_t *size)
717{
c56e9e05 718 FILE *f = fopen(filename, "rb");
458b062d
SS
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}
7a8bfa5d
AS
739
740void 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
746int64_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 }
01d46198 758 if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
7a8bfa5d
AS
759 && reordered_pts != AV_NOPTS_VALUE)
760 pts = reordered_pts;
761 else
762 pts = dts;
763
764 return pts;
765}
f7ead94c 766
6e872935
SS
767FILE *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;
6291d7e4 772 const char *base[3]= { getenv("AVCONV_DATADIR"),
6e872935 773 getenv("HOME"),
6291d7e4 774 AVCONV_DATADIR,
6e872935
SS
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;
6291d7e4 784 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", preset_name);
6e872935
SS
785 f = fopen(filename, "r");
786 if (!f && codec_name) {
787 snprintf(filename, filename_size,
6291d7e4 788 "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.avconv", codec_name, preset_name);
6e872935
SS
789 f = fopen(filename, "r");
790 }
791 }
792 }
793
794 return f;
795}
796
d4863fc1
AK
797int 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
827AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, AVFormatContext *s, AVStream *st)
8c8eab8b
AK
828{
829 AVDictionary *ret = NULL;
830 AVDictionaryEntry *t = NULL;
d4863fc1
AK
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;
8c8eab8b 833 char prefix = 0;
20c21f8b 834 const AVClass *cc = avcodec_get_class();
8c8eab8b
AK
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)) {
d4863fc1
AK
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
20c21f8b
AK
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)))
8c8eab8b 858 av_dict_set(&ret, t->key, t->value, 0);
20c21f8b 859 else if (t->key[0] == prefix && av_opt_find(&cc, t->key+1, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ))
8c8eab8b 860 av_dict_set(&ret, t->key+1, t->value, 0);
d4863fc1
AK
861
862 if (p)
863 *p = ':';
8c8eab8b
AK
864 }
865 return ret;
866}
867
8ec19f84 868AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts)
3009f521
AK
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++)
d4863fc1 881 opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id, s, s->streams[i]);
3009f521
AK
882 return opts;
883}
884
f7ead94c
SS
885#if CONFIG_AVFILTER
886
887static 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
898static void null_end_frame(AVFilterLink *inlink) { }
899
900static 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
909AVFilter 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
ff0652e5
SS
924int 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;
10d39405
RPM
942 frame->key_frame = picref->video->key_frame;
943 frame->pict_type = picref->video->pict_type;
ff0652e5
SS
944
945 return 1;
946}
947
cac651c8
AK
948void *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
f7ead94c 967#endif /* CONFIG_AVFILTER */