00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <string.h>
00023 #include <stdlib.h>
00024 #include <errno.h>
00025 #include <math.h>
00026
00027
00028
00029
00030
00031 #include "config.h"
00032 #include "libavformat/avformat.h"
00033 #include "libavfilter/avfilter.h"
00034 #include "libavdevice/avdevice.h"
00035 #include "libavresample/avresample.h"
00036 #include "libswscale/swscale.h"
00037 #include "libswresample/swresample.h"
00038 #if CONFIG_POSTPROC
00039 #include "libpostproc/postprocess.h"
00040 #endif
00041 #include "libavutil/avassert.h"
00042 #include "libavutil/avstring.h"
00043 #include "libavutil/mathematics.h"
00044 #include "libavutil/parseutils.h"
00045 #include "libavutil/pixdesc.h"
00046 #include "libavutil/eval.h"
00047 #include "libavutil/dict.h"
00048 #include "libavutil/opt.h"
00049 #include "cmdutils.h"
00050 #include "version.h"
00051 #if CONFIG_NETWORK
00052 #include "libavformat/network.h"
00053 #endif
00054 #if HAVE_SYS_RESOURCE_H
00055 #include <sys/resource.h>
00056 #endif
00057
00058 struct SwsContext *sws_opts;
00059 SwrContext *swr_opts;
00060 AVDictionary *format_opts, *codec_opts;
00061
00062 const int this_year = 2012;
00063
00064 static FILE *report_file;
00065
00066 void init_opts(void)
00067 {
00068 #if CONFIG_SWSCALE
00069 sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC,
00070 NULL, NULL, NULL);
00071 #endif
00072 swr_opts = swr_alloc();
00073 }
00074
00075 void uninit_opts(void)
00076 {
00077 #if CONFIG_SWSCALE
00078 sws_freeContext(sws_opts);
00079 sws_opts = NULL;
00080 #endif
00081 swr_free(&swr_opts);
00082 av_dict_free(&format_opts);
00083 av_dict_free(&codec_opts);
00084 }
00085
00086 void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
00087 {
00088 vfprintf(stdout, fmt, vl);
00089 }
00090
00091 static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
00092 {
00093 va_list vl2;
00094 char line[1024];
00095 static int print_prefix = 1;
00096
00097 va_copy(vl2, vl);
00098 av_log_default_callback(ptr, level, fmt, vl);
00099 av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
00100 va_end(vl2);
00101 fputs(line, report_file);
00102 fflush(report_file);
00103 }
00104
00105 double parse_number_or_die(const char *context, const char *numstr, int type,
00106 double min, double max)
00107 {
00108 char *tail;
00109 const char *error;
00110 double d = av_strtod(numstr, &tail);
00111 if (*tail)
00112 error = "Expected number for %s but found: %s\n";
00113 else if (d < min || d > max)
00114 error = "The value for %s was %s which is not within %f - %f\n";
00115 else if (type == OPT_INT64 && (int64_t)d != d)
00116 error = "Expected int64 for %s but found %s\n";
00117 else if (type == OPT_INT && (int)d != d)
00118 error = "Expected int for %s but found %s\n";
00119 else
00120 return d;
00121 av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
00122 exit_program(1);
00123 return 0;
00124 }
00125
00126 int64_t parse_time_or_die(const char *context, const char *timestr,
00127 int is_duration)
00128 {
00129 int64_t us;
00130 if (av_parse_time(&us, timestr, is_duration) < 0) {
00131 av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
00132 is_duration ? "duration" : "date", context, timestr);
00133 exit_program(1);
00134 }
00135 return us;
00136 }
00137
00138 void show_help_options(const OptionDef *options, const char *msg, int mask,
00139 int value)
00140 {
00141 const OptionDef *po;
00142 int first;
00143
00144 first = 1;
00145 for (po = options; po->name != NULL; po++) {
00146 char buf[64];
00147 if ((po->flags & mask) == value) {
00148 if (first) {
00149 printf("%s", msg);
00150 first = 0;
00151 }
00152 av_strlcpy(buf, po->name, sizeof(buf));
00153 if (po->flags & HAS_ARG) {
00154 av_strlcat(buf, " ", sizeof(buf));
00155 av_strlcat(buf, po->argname, sizeof(buf));
00156 }
00157 printf("-%-17s %s\n", buf, po->help);
00158 }
00159 }
00160 }
00161
00162 void show_help_children(const AVClass *class, int flags)
00163 {
00164 const AVClass *child = NULL;
00165 av_opt_show2(&class, NULL, flags, 0);
00166 printf("\n");
00167
00168 while (child = av_opt_child_class_next(class, child))
00169 show_help_children(child, flags);
00170 }
00171
00172 static const OptionDef *find_option(const OptionDef *po, const char *name)
00173 {
00174 const char *p = strchr(name, ':');
00175 int len = p ? p - name : strlen(name);
00176
00177 while (po->name != NULL) {
00178 if (!strncmp(name, po->name, len) && strlen(po->name) == len)
00179 break;
00180 po++;
00181 }
00182 return po;
00183 }
00184
00185 #if defined(_WIN32) && !defined(__MINGW32CE__)
00186 #include <windows.h>
00187
00188 static char** win32_argv_utf8 = NULL;
00189 static int win32_argc = 0;
00190
00198 static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
00199 {
00200 char *argstr_flat;
00201 wchar_t **argv_w;
00202 int i, buffsize = 0, offset = 0;
00203
00204 if (win32_argv_utf8) {
00205 *argc_ptr = win32_argc;
00206 *argv_ptr = win32_argv_utf8;
00207 return;
00208 }
00209
00210 win32_argc = 0;
00211 argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
00212 if (win32_argc <= 0 || !argv_w)
00213 return;
00214
00215
00216 for (i = 0; i < win32_argc; i++)
00217 buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
00218 NULL, 0, NULL, NULL);
00219
00220 win32_argv_utf8 = av_mallocz(sizeof(char *) * (win32_argc + 1) + buffsize);
00221 argstr_flat = (char *)win32_argv_utf8 + sizeof(char *) * (win32_argc + 1);
00222 if (win32_argv_utf8 == NULL) {
00223 LocalFree(argv_w);
00224 return;
00225 }
00226
00227 for (i = 0; i < win32_argc; i++) {
00228 win32_argv_utf8[i] = &argstr_flat[offset];
00229 offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
00230 &argstr_flat[offset],
00231 buffsize - offset, NULL, NULL);
00232 }
00233 win32_argv_utf8[i] = NULL;
00234 LocalFree(argv_w);
00235
00236 *argc_ptr = win32_argc;
00237 *argv_ptr = win32_argv_utf8;
00238 }
00239 #else
00240 static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
00241 {
00242
00243 }
00244 #endif
00245
00246 int parse_option(void *optctx, const char *opt, const char *arg,
00247 const OptionDef *options)
00248 {
00249 const OptionDef *po;
00250 int bool_val = 1;
00251 int *dstcount;
00252 void *dst;
00253
00254 po = find_option(options, opt);
00255 if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
00256
00257 po = find_option(options, opt + 2);
00258 if ((po->name && (po->flags & OPT_BOOL)))
00259 bool_val = 0;
00260 }
00261 if (!po->name)
00262 po = find_option(options, "default");
00263 if (!po->name) {
00264 av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
00265 return AVERROR(EINVAL);
00266 }
00267 if (po->flags & HAS_ARG && !arg) {
00268 av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
00269 return AVERROR(EINVAL);
00270 }
00271
00272
00273
00274 dst = po->flags & (OPT_OFFSET | OPT_SPEC) ? (uint8_t *)optctx + po->u.off
00275 : po->u.dst_ptr;
00276
00277 if (po->flags & OPT_SPEC) {
00278 SpecifierOpt **so = dst;
00279 char *p = strchr(opt, ':');
00280
00281 dstcount = (int *)(so + 1);
00282 *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
00283 (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : "");
00284 dst = &(*so)[*dstcount - 1].u;
00285 }
00286
00287 if (po->flags & OPT_STRING) {
00288 char *str;
00289 str = av_strdup(arg);
00290 *(char **)dst = str;
00291 } else if (po->flags & OPT_BOOL) {
00292 *(int *)dst = bool_val;
00293 } else if (po->flags & OPT_INT) {
00294 *(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
00295 } else if (po->flags & OPT_INT64) {
00296 *(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
00297 } else if (po->flags & OPT_TIME) {
00298 *(int64_t *)dst = parse_time_or_die(opt, arg, 1);
00299 } else if (po->flags & OPT_FLOAT) {
00300 *(float *)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
00301 } else if (po->flags & OPT_DOUBLE) {
00302 *(double *)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
00303 } else if (po->u.func_arg) {
00304 int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg)
00305 : po->u.func_arg(opt, arg);
00306 if (ret < 0) {
00307 av_log(NULL, AV_LOG_ERROR,
00308 "Failed to set value '%s' for option '%s'\n", arg, opt);
00309 return ret;
00310 }
00311 }
00312 if (po->flags & OPT_EXIT)
00313 exit_program(0);
00314 return !!(po->flags & HAS_ARG);
00315 }
00316
00317 void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
00318 void (*parse_arg_function)(void *, const char*))
00319 {
00320 const char *opt;
00321 int optindex, handleoptions = 1, ret;
00322
00323
00324 prepare_app_arguments(&argc, &argv);
00325
00326
00327 optindex = 1;
00328 while (optindex < argc) {
00329 opt = argv[optindex++];
00330
00331 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
00332 if (opt[1] == '-' && opt[2] == '\0') {
00333 handleoptions = 0;
00334 continue;
00335 }
00336 opt++;
00337
00338 if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
00339 exit_program(1);
00340 optindex += ret;
00341 } else {
00342 if (parse_arg_function)
00343 parse_arg_function(optctx, opt);
00344 }
00345 }
00346 }
00347
00348 int locate_option(int argc, char **argv, const OptionDef *options,
00349 const char *optname)
00350 {
00351 const OptionDef *po;
00352 int i;
00353
00354 for (i = 1; i < argc; i++) {
00355 const char *cur_opt = argv[i];
00356
00357 if (*cur_opt++ != '-')
00358 continue;
00359
00360 po = find_option(options, cur_opt);
00361 if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
00362 po = find_option(options, cur_opt + 2);
00363
00364 if ((!po->name && !strcmp(cur_opt, optname)) ||
00365 (po->name && !strcmp(optname, po->name)))
00366 return i;
00367
00368 if (!po || po->flags & HAS_ARG)
00369 i++;
00370 }
00371 return 0;
00372 }
00373
00374 static void dump_argument(const char *a)
00375 {
00376 const unsigned char *p;
00377
00378 for (p = a; *p; p++)
00379 if (!((*p >= '+' && *p <= ':') || (*p >= '@' && *p <= 'Z') ||
00380 *p == '_' || (*p >= 'a' && *p <= 'z')))
00381 break;
00382 if (!*p) {
00383 fputs(a, report_file);
00384 return;
00385 }
00386 fputc('"', report_file);
00387 for (p = a; *p; p++) {
00388 if (*p == '\\' || *p == '"' || *p == '$' || *p == '`')
00389 fprintf(report_file, "\\%c", *p);
00390 else if (*p < ' ' || *p > '~')
00391 fprintf(report_file, "\\x%02x", *p);
00392 else
00393 fputc(*p, report_file);
00394 }
00395 fputc('"', report_file);
00396 }
00397
00398 void parse_loglevel(int argc, char **argv, const OptionDef *options)
00399 {
00400 int idx = locate_option(argc, argv, options, "loglevel");
00401 if (!idx)
00402 idx = locate_option(argc, argv, options, "v");
00403 if (idx && argv[idx + 1])
00404 opt_loglevel("loglevel", argv[idx + 1]);
00405 idx = locate_option(argc, argv, options, "report");
00406 if (idx || getenv("FFREPORT")) {
00407 opt_report("report");
00408 if (report_file) {
00409 int i;
00410 fprintf(report_file, "Command line:\n");
00411 for (i = 0; i < argc; i++) {
00412 dump_argument(argv[i]);
00413 fputc(i < argc - 1 ? ' ' : '\n', report_file);
00414 }
00415 fflush(report_file);
00416 }
00417 }
00418 }
00419
00420 #define FLAGS(o) ((o)->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
00421 int opt_default(const char *opt, const char *arg)
00422 {
00423 const AVOption *oc, *of, *os, *oswr = NULL;
00424 char opt_stripped[128];
00425 const char *p;
00426 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc, *swr_class;
00427
00428 if (!(p = strchr(opt, ':')))
00429 p = opt + strlen(opt);
00430 av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
00431
00432 if ((oc = av_opt_find(&cc, opt_stripped, NULL, 0,
00433 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
00434 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
00435 (oc = av_opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
00436 av_dict_set(&codec_opts, opt, arg, FLAGS(oc));
00437 if ((of = av_opt_find(&fc, opt, NULL, 0,
00438 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
00439 av_dict_set(&format_opts, opt, arg, FLAGS(of));
00440 #if CONFIG_SWSCALE
00441 sc = sws_get_class();
00442 if ((os = av_opt_find(&sc, opt, NULL, 0,
00443 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
00444
00445 int ret = av_opt_set(sws_opts, opt, arg, 0);
00446 if (ret < 0) {
00447 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
00448 return ret;
00449 }
00450 }
00451 #endif
00452 swr_class = swr_get_class();
00453 if (!oc && !of && !os && (oswr = av_opt_find(&swr_class, opt, NULL, 0,
00454 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
00455 int ret = av_opt_set(swr_opts, opt, arg, 0);
00456 if (ret < 0) {
00457 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
00458 return ret;
00459 }
00460 }
00461
00462 if (oc || of || os || oswr)
00463 return 0;
00464 av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
00465 return AVERROR_OPTION_NOT_FOUND;
00466 }
00467
00468 int opt_loglevel(const char *opt, const char *arg)
00469 {
00470 const struct { const char *name; int level; } log_levels[] = {
00471 { "quiet" , AV_LOG_QUIET },
00472 { "panic" , AV_LOG_PANIC },
00473 { "fatal" , AV_LOG_FATAL },
00474 { "error" , AV_LOG_ERROR },
00475 { "warning", AV_LOG_WARNING },
00476 { "info" , AV_LOG_INFO },
00477 { "verbose", AV_LOG_VERBOSE },
00478 { "debug" , AV_LOG_DEBUG },
00479 };
00480 char *tail;
00481 int level;
00482 int i;
00483
00484 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
00485 if (!strcmp(log_levels[i].name, arg)) {
00486 av_log_set_level(log_levels[i].level);
00487 return 0;
00488 }
00489 }
00490
00491 level = strtol(arg, &tail, 10);
00492 if (*tail) {
00493 av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
00494 "Possible levels are numbers or:\n", arg);
00495 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
00496 av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
00497 exit_program(1);
00498 }
00499 av_log_set_level(level);
00500 return 0;
00501 }
00502
00503 int opt_report(const char *opt)
00504 {
00505 char filename[64];
00506 time_t now;
00507 struct tm *tm;
00508
00509 if (report_file)
00510 return 0;
00511 time(&now);
00512 tm = localtime(&now);
00513 snprintf(filename, sizeof(filename), "%s-%04d%02d%02d-%02d%02d%02d.log",
00514 program_name,
00515 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
00516 tm->tm_hour, tm->tm_min, tm->tm_sec);
00517 report_file = fopen(filename, "w");
00518 if (!report_file) {
00519 av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
00520 filename, strerror(errno));
00521 return AVERROR(errno);
00522 }
00523 av_log_set_callback(log_callback_report);
00524 av_log(NULL, AV_LOG_INFO,
00525 "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
00526 "Report written to \"%s\"\n",
00527 program_name,
00528 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
00529 tm->tm_hour, tm->tm_min, tm->tm_sec,
00530 filename);
00531 av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE));
00532 return 0;
00533 }
00534
00535 int opt_max_alloc(const char *opt, const char *arg)
00536 {
00537 char *tail;
00538 size_t max;
00539
00540 max = strtol(arg, &tail, 10);
00541 if (*tail) {
00542 av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
00543 exit_program(1);
00544 }
00545 av_max_alloc(max);
00546 return 0;
00547 }
00548
00549 int opt_cpuflags(const char *opt, const char *arg)
00550 {
00551 int ret;
00552 unsigned flags = av_get_cpu_flags();
00553
00554 if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
00555 return ret;
00556
00557 av_force_cpu_flags(flags);
00558 return 0;
00559 }
00560
00561 int opt_codec_debug(const char *opt, const char *arg)
00562 {
00563 av_log_set_level(AV_LOG_DEBUG);
00564 return opt_default(opt, arg);
00565 }
00566
00567 int opt_timelimit(const char *opt, const char *arg)
00568 {
00569 #if HAVE_SETRLIMIT
00570 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
00571 struct rlimit rl = { lim, lim + 1 };
00572 if (setrlimit(RLIMIT_CPU, &rl))
00573 perror("setrlimit");
00574 #else
00575 av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
00576 #endif
00577 return 0;
00578 }
00579
00580 void print_error(const char *filename, int err)
00581 {
00582 char errbuf[128];
00583 const char *errbuf_ptr = errbuf;
00584
00585 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
00586 errbuf_ptr = strerror(AVUNERROR(err));
00587 av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
00588 }
00589
00590 static int warned_cfg = 0;
00591
00592 #define INDENT 1
00593 #define SHOW_VERSION 2
00594 #define SHOW_CONFIG 4
00595 #define SHOW_COPYRIGHT 8
00596
00597 #define PRINT_LIB_INFO(libname, LIBNAME, flags, level) \
00598 if (CONFIG_##LIBNAME) { \
00599 const char *indent = flags & INDENT? " " : ""; \
00600 if (flags & SHOW_VERSION) { \
00601 unsigned int version = libname##_version(); \
00602 av_log(NULL, level, \
00603 "%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n", \
00604 indent, #libname, \
00605 LIB##LIBNAME##_VERSION_MAJOR, \
00606 LIB##LIBNAME##_VERSION_MINOR, \
00607 LIB##LIBNAME##_VERSION_MICRO, \
00608 version >> 16, version >> 8 & 0xff, version & 0xff); \
00609 } \
00610 if (flags & SHOW_CONFIG) { \
00611 const char *cfg = libname##_configuration(); \
00612 if (strcmp(FFMPEG_CONFIGURATION, cfg)) { \
00613 if (!warned_cfg) { \
00614 av_log(NULL, level, \
00615 "%sWARNING: library configuration mismatch\n", \
00616 indent); \
00617 warned_cfg = 1; \
00618 } \
00619 av_log(NULL, level, "%s%-11s configuration: %s\n", \
00620 indent, #libname, cfg); \
00621 } \
00622 } \
00623 } \
00624
00625 static void print_all_libs_info(int flags, int level)
00626 {
00627 PRINT_LIB_INFO(avutil, AVUTIL, flags, level);
00628 PRINT_LIB_INFO(avcodec, AVCODEC, flags, level);
00629 PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
00630 PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
00631 PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
00632
00633 PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
00634 PRINT_LIB_INFO(swresample,SWRESAMPLE, flags, level);
00635 #if CONFIG_POSTPROC
00636 PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
00637 #endif
00638 }
00639
00640 static void print_program_info(int flags, int level)
00641 {
00642 const char *indent = flags & INDENT? " " : "";
00643
00644 av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
00645 if (flags & SHOW_COPYRIGHT)
00646 av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
00647 program_birth_year, this_year);
00648 av_log(NULL, level, "\n");
00649 av_log(NULL, level, "%sbuilt on %s %s with %s %s\n",
00650 indent, __DATE__, __TIME__, CC_TYPE, CC_VERSION);
00651 av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
00652 }
00653
00654 void show_banner(int argc, char **argv, const OptionDef *options)
00655 {
00656 int idx = locate_option(argc, argv, options, "version");
00657 if (idx)
00658 return;
00659
00660 print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);
00661 print_all_libs_info(INDENT|SHOW_CONFIG, AV_LOG_INFO);
00662 print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
00663 }
00664
00665 int opt_version(const char *opt, const char *arg) {
00666 av_log_set_callback(log_callback_help);
00667 print_program_info (0 , AV_LOG_INFO);
00668 print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
00669 return 0;
00670 }
00671
00672 int opt_license(const char *opt, const char *arg)
00673 {
00674 printf(
00675 #if CONFIG_NONFREE
00676 "This version of %s has nonfree parts compiled in.\n"
00677 "Therefore it is not legally redistributable.\n",
00678 program_name
00679 #elif CONFIG_GPLV3
00680 "%s is free software; you can redistribute it and/or modify\n"
00681 "it under the terms of the GNU General Public License as published by\n"
00682 "the Free Software Foundation; either version 3 of the License, or\n"
00683 "(at your option) any later version.\n"
00684 "\n"
00685 "%s is distributed in the hope that it will be useful,\n"
00686 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00687 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00688 "GNU General Public License for more details.\n"
00689 "\n"
00690 "You should have received a copy of the GNU General Public License\n"
00691 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
00692 program_name, program_name, program_name
00693 #elif CONFIG_GPL
00694 "%s is free software; you can redistribute it and/or modify\n"
00695 "it under the terms of the GNU General Public License as published by\n"
00696 "the Free Software Foundation; either version 2 of the License, or\n"
00697 "(at your option) any later version.\n"
00698 "\n"
00699 "%s is distributed in the hope that it will be useful,\n"
00700 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00701 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00702 "GNU General Public License for more details.\n"
00703 "\n"
00704 "You should have received a copy of the GNU General Public License\n"
00705 "along with %s; if not, write to the Free Software\n"
00706 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
00707 program_name, program_name, program_name
00708 #elif CONFIG_LGPLV3
00709 "%s is free software; you can redistribute it and/or modify\n"
00710 "it under the terms of the GNU Lesser General Public License as published by\n"
00711 "the Free Software Foundation; either version 3 of the License, or\n"
00712 "(at your option) any later version.\n"
00713 "\n"
00714 "%s is distributed in the hope that it will be useful,\n"
00715 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00716 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00717 "GNU Lesser General Public License for more details.\n"
00718 "\n"
00719 "You should have received a copy of the GNU Lesser General Public License\n"
00720 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
00721 program_name, program_name, program_name
00722 #else
00723 "%s is free software; you can redistribute it and/or\n"
00724 "modify it under the terms of the GNU Lesser General Public\n"
00725 "License as published by the Free Software Foundation; either\n"
00726 "version 2.1 of the License, or (at your option) any later version.\n"
00727 "\n"
00728 "%s is distributed in the hope that it will be useful,\n"
00729 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00730 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
00731 "Lesser General Public License for more details.\n"
00732 "\n"
00733 "You should have received a copy of the GNU Lesser General Public\n"
00734 "License along with %s; if not, write to the Free Software\n"
00735 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
00736 program_name, program_name, program_name
00737 #endif
00738 );
00739 return 0;
00740 }
00741
00742 int opt_formats(const char *opt, const char *arg)
00743 {
00744 AVInputFormat *ifmt = NULL;
00745 AVOutputFormat *ofmt = NULL;
00746 const char *last_name;
00747
00748 printf("File formats:\n"
00749 " D. = Demuxing supported\n"
00750 " .E = Muxing supported\n"
00751 " --\n");
00752 last_name = "000";
00753 for (;;) {
00754 int decode = 0;
00755 int encode = 0;
00756 const char *name = NULL;
00757 const char *long_name = NULL;
00758
00759 while ((ofmt = av_oformat_next(ofmt))) {
00760 if ((name == NULL || strcmp(ofmt->name, name) < 0) &&
00761 strcmp(ofmt->name, last_name) > 0) {
00762 name = ofmt->name;
00763 long_name = ofmt->long_name;
00764 encode = 1;
00765 }
00766 }
00767 while ((ifmt = av_iformat_next(ifmt))) {
00768 if ((name == NULL || strcmp(ifmt->name, name) < 0) &&
00769 strcmp(ifmt->name, last_name) > 0) {
00770 name = ifmt->name;
00771 long_name = ifmt->long_name;
00772 encode = 0;
00773 }
00774 if (name && strcmp(ifmt->name, name) == 0)
00775 decode = 1;
00776 }
00777 if (name == NULL)
00778 break;
00779 last_name = name;
00780
00781 printf(" %s%s %-15s %s\n",
00782 decode ? "D" : " ",
00783 encode ? "E" : " ",
00784 name,
00785 long_name ? long_name:" ");
00786 }
00787 return 0;
00788 }
00789
00790 static char get_media_type_char(enum AVMediaType type)
00791 {
00792 static const char map[AVMEDIA_TYPE_NB] = {
00793 [AVMEDIA_TYPE_VIDEO] = 'V',
00794 [AVMEDIA_TYPE_AUDIO] = 'A',
00795 [AVMEDIA_TYPE_DATA] = 'D',
00796 [AVMEDIA_TYPE_SUBTITLE] = 'S',
00797 [AVMEDIA_TYPE_ATTACHMENT] = 'T',
00798 };
00799 return type >= 0 && type < AVMEDIA_TYPE_NB && map[type] ? map[type] : '?';
00800 }
00801
00802 int opt_codecs(const char *opt, const char *arg)
00803 {
00804 AVCodec *p = NULL, *p2;
00805 const char *last_name;
00806 printf("Codecs:\n"
00807 " D..... = Decoding supported\n"
00808 " .E.... = Encoding supported\n"
00809 " ..V... = Video codec\n"
00810 " ..A... = Audio codec\n"
00811 " ..S... = Subtitle codec\n"
00812 " ...S.. = Supports draw_horiz_band\n"
00813 " ....D. = Supports direct rendering method 1\n"
00814 " .....T = Supports weird frame truncation\n"
00815 " ------\n");
00816 last_name= "000";
00817 for (;;) {
00818 int decode = 0;
00819 int encode = 0;
00820 int cap = 0;
00821
00822 p2 = NULL;
00823 while ((p = av_codec_next(p))) {
00824 if ((p2 == NULL || strcmp(p->name, p2->name) < 0) &&
00825 strcmp(p->name, last_name) > 0) {
00826 p2 = p;
00827 decode = encode = cap = 0;
00828 }
00829 if (p2 && strcmp(p->name, p2->name) == 0) {
00830 if (av_codec_is_decoder(p))
00831 decode = 1;
00832 if (av_codec_is_encoder(p))
00833 encode = 1;
00834 cap |= p->capabilities;
00835 }
00836 }
00837 if (p2 == NULL)
00838 break;
00839 last_name = p2->name;
00840
00841 printf(" %s%s%c%s%s%s %-15s %s",
00842 decode ? "D" : ( " "),
00843 encode ? "E" : " ",
00844 get_media_type_char(p2->type),
00845 cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S" : " ",
00846 cap & CODEC_CAP_DR1 ? "D" : " ",
00847 cap & CODEC_CAP_TRUNCATED ? "T" : " ",
00848 p2->name,
00849 p2->long_name ? p2->long_name : "");
00850 #if 0
00851 if (p2->decoder && decode == 0)
00852 printf(" use %s for decoding", p2->decoder->name);
00853 #endif
00854 printf("\n");
00855 }
00856 printf("\n");
00857 printf("Note, the names of encoders and decoders do not always match, so there are\n"
00858 "several cases where the above table shows encoder only or decoder only entries\n"
00859 "even though both encoding and decoding are supported. For example, the h263\n"
00860 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
00861 "worse.\n");
00862 return 0;
00863 }
00864
00865 int opt_bsfs(const char *opt, const char *arg)
00866 {
00867 AVBitStreamFilter *bsf = NULL;
00868
00869 printf("Bitstream filters:\n");
00870 while ((bsf = av_bitstream_filter_next(bsf)))
00871 printf("%s\n", bsf->name);
00872 printf("\n");
00873 return 0;
00874 }
00875
00876 int opt_protocols(const char *opt, const char *arg)
00877 {
00878 void *opaque = NULL;
00879 const char *name;
00880
00881 printf("Supported file protocols:\n"
00882 "Input:\n");
00883 while ((name = avio_enum_protocols(&opaque, 0)))
00884 printf("%s\n", name);
00885 printf("Output:\n");
00886 while ((name = avio_enum_protocols(&opaque, 1)))
00887 printf("%s\n", name);
00888 return 0;
00889 }
00890
00891 int opt_filters(const char *opt, const char *arg)
00892 {
00893 AVFilter av_unused(**filter) = NULL;
00894 char descr[64], *descr_cur;
00895 int i, j;
00896 const AVFilterPad *pad;
00897
00898 printf("Filters:\n");
00899 #if CONFIG_AVFILTER
00900 while ((filter = av_filter_next(filter)) && *filter) {
00901 descr_cur = descr;
00902 for (i = 0; i < 2; i++) {
00903 if (i) {
00904 *(descr_cur++) = '-';
00905 *(descr_cur++) = '>';
00906 }
00907 pad = i ? (*filter)->outputs : (*filter)->inputs;
00908 for (j = 0; pad[j].name; j++) {
00909 if (descr_cur >= descr + sizeof(descr) - 4)
00910 break;
00911 *(descr_cur++) = get_media_type_char(pad[j].type);
00912 }
00913 if (!j)
00914 *(descr_cur++) = '|';
00915 }
00916 *descr_cur = 0;
00917 printf("%-16s %-10s %s\n", (*filter)->name, descr, (*filter)->description);
00918 }
00919 #endif
00920 return 0;
00921 }
00922
00923 int opt_pix_fmts(const char *opt, const char *arg)
00924 {
00925 enum PixelFormat pix_fmt;
00926
00927 printf("Pixel formats:\n"
00928 "I.... = Supported Input format for conversion\n"
00929 ".O... = Supported Output format for conversion\n"
00930 "..H.. = Hardware accelerated format\n"
00931 "...P. = Paletted format\n"
00932 "....B = Bitstream format\n"
00933 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
00934 "-----\n");
00935
00936 #if !CONFIG_SWSCALE
00937 # define sws_isSupportedInput(x) 0
00938 # define sws_isSupportedOutput(x) 0
00939 #endif
00940
00941 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
00942 const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
00943 if(!pix_desc->name)
00944 continue;
00945 printf("%c%c%c%c%c %-16s %d %2d\n",
00946 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
00947 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
00948 pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
00949 pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
00950 pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
00951 pix_desc->name,
00952 pix_desc->nb_components,
00953 av_get_bits_per_pixel(pix_desc));
00954 }
00955 return 0;
00956 }
00957
00958 int show_sample_fmts(const char *opt, const char *arg)
00959 {
00960 int i;
00961 char fmt_str[128];
00962 for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
00963 printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
00964 return 0;
00965 }
00966
00967 int read_yesno(void)
00968 {
00969 int c = getchar();
00970 int yesno = (toupper(c) == 'Y');
00971
00972 while (c != '\n' && c != EOF)
00973 c = getchar();
00974
00975 return yesno;
00976 }
00977
00978 int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
00979 {
00980 int ret;
00981 FILE *f = fopen(filename, "rb");
00982
00983 if (!f) {
00984 av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
00985 strerror(errno));
00986 return AVERROR(errno);
00987 }
00988 fseek(f, 0, SEEK_END);
00989 *size = ftell(f);
00990 fseek(f, 0, SEEK_SET);
00991 *bufptr = av_malloc(*size + 1);
00992 if (!*bufptr) {
00993 av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
00994 fclose(f);
00995 return AVERROR(ENOMEM);
00996 }
00997 ret = fread(*bufptr, 1, *size, f);
00998 if (ret < *size) {
00999 av_free(*bufptr);
01000 if (ferror(f)) {
01001 av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
01002 filename, strerror(errno));
01003 ret = AVERROR(errno);
01004 } else
01005 ret = AVERROR_EOF;
01006 } else {
01007 ret = 0;
01008 (*bufptr)[*size++] = '\0';
01009 }
01010
01011 fclose(f);
01012 return ret;
01013 }
01014
01015 FILE *get_preset_file(char *filename, size_t filename_size,
01016 const char *preset_name, int is_path,
01017 const char *codec_name)
01018 {
01019 FILE *f = NULL;
01020 int i;
01021 const char *base[3] = { getenv("FFMPEG_DATADIR"),
01022 getenv("HOME"),
01023 FFMPEG_DATADIR, };
01024
01025 if (is_path) {
01026 av_strlcpy(filename, preset_name, filename_size);
01027 f = fopen(filename, "r");
01028 } else {
01029 #ifdef _WIN32
01030 char datadir[MAX_PATH], *ls;
01031 base[2] = NULL;
01032
01033 if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
01034 {
01035 for (ls = datadir; ls < datadir + strlen(datadir); ls++)
01036 if (*ls == '\\') *ls = '/';
01037
01038 if (ls = strrchr(datadir, '/'))
01039 {
01040 *ls = 0;
01041 strncat(datadir, "/ffpresets", sizeof(datadir) - 1 - strlen(datadir));
01042 base[2] = datadir;
01043 }
01044 }
01045 #endif
01046 for (i = 0; i < 3 && !f; i++) {
01047 if (!base[i])
01048 continue;
01049 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
01050 i != 1 ? "" : "/.ffmpeg", preset_name);
01051 f = fopen(filename, "r");
01052 if (!f && codec_name) {
01053 snprintf(filename, filename_size,
01054 "%s%s/%s-%s.ffpreset",
01055 base[i], i != 1 ? "" : "/.ffmpeg", codec_name,
01056 preset_name);
01057 f = fopen(filename, "r");
01058 }
01059 }
01060 }
01061
01062 return f;
01063 }
01064
01065 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
01066 {
01067 if (*spec <= '9' && *spec >= '0')
01068 return strtol(spec, NULL, 0) == st->index;
01069 else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
01070 *spec == 't') {
01071 enum AVMediaType type;
01072
01073 switch (*spec++) {
01074 case 'v': type = AVMEDIA_TYPE_VIDEO; break;
01075 case 'a': type = AVMEDIA_TYPE_AUDIO; break;
01076 case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
01077 case 'd': type = AVMEDIA_TYPE_DATA; break;
01078 case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
01079 default: av_assert0(0);
01080 }
01081 if (type != st->codec->codec_type)
01082 return 0;
01083 if (*spec++ == ':') {
01084 int i, index = strtol(spec, NULL, 0);
01085 for (i = 0; i < s->nb_streams; i++)
01086 if (s->streams[i]->codec->codec_type == type && index-- == 0)
01087 return i == st->index;
01088 return 0;
01089 }
01090 return 1;
01091 } else if (*spec == 'p' && *(spec + 1) == ':') {
01092 int prog_id, i, j;
01093 char *endptr;
01094 spec += 2;
01095 prog_id = strtol(spec, &endptr, 0);
01096 for (i = 0; i < s->nb_programs; i++) {
01097 if (s->programs[i]->id != prog_id)
01098 continue;
01099
01100 if (*endptr++ == ':') {
01101 int stream_idx = strtol(endptr, NULL, 0);
01102 return stream_idx >= 0 &&
01103 stream_idx < s->programs[i]->nb_stream_indexes &&
01104 st->index == s->programs[i]->stream_index[stream_idx];
01105 }
01106
01107 for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
01108 if (st->index == s->programs[i]->stream_index[j])
01109 return 1;
01110 }
01111 return 0;
01112 } else if (*spec == '#') {
01113 int sid;
01114 char *endptr;
01115 sid = strtol(spec + 1, &endptr, 0);
01116 if (!*endptr)
01117 return st->id == sid;
01118 } else if (!*spec)
01119 return 1;
01120
01121 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
01122 return AVERROR(EINVAL);
01123 }
01124
01125 AVDictionary *filter_codec_opts(AVDictionary *opts, AVCodec *codec,
01126 AVFormatContext *s, AVStream *st)
01127 {
01128 AVDictionary *ret = NULL;
01129 AVDictionaryEntry *t = NULL;
01130 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
01131 : AV_OPT_FLAG_DECODING_PARAM;
01132 char prefix = 0;
01133 const AVClass *cc = avcodec_get_class();
01134
01135 if (!codec)
01136 return NULL;
01137
01138 switch (codec->type) {
01139 case AVMEDIA_TYPE_VIDEO:
01140 prefix = 'v';
01141 flags |= AV_OPT_FLAG_VIDEO_PARAM;
01142 break;
01143 case AVMEDIA_TYPE_AUDIO:
01144 prefix = 'a';
01145 flags |= AV_OPT_FLAG_AUDIO_PARAM;
01146 break;
01147 case AVMEDIA_TYPE_SUBTITLE:
01148 prefix = 's';
01149 flags |= AV_OPT_FLAG_SUBTITLE_PARAM;
01150 break;
01151 }
01152
01153 while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
01154 char *p = strchr(t->key, ':');
01155
01156
01157 if (p)
01158 switch (check_stream_specifier(s, st, p + 1)) {
01159 case 1: *p = 0; break;
01160 case 0: continue;
01161 default: return NULL;
01162 }
01163
01164 if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
01165 (codec && codec->priv_class &&
01166 av_opt_find(&codec->priv_class, t->key, NULL, flags,
01167 AV_OPT_SEARCH_FAKE_OBJ)))
01168 av_dict_set(&ret, t->key, t->value, 0);
01169 else if (t->key[0] == prefix &&
01170 av_opt_find(&cc, t->key + 1, NULL, flags,
01171 AV_OPT_SEARCH_FAKE_OBJ))
01172 av_dict_set(&ret, t->key + 1, t->value, 0);
01173
01174 if (p)
01175 *p = ':';
01176 }
01177 return ret;
01178 }
01179
01180 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
01181 AVDictionary *codec_opts)
01182 {
01183 int i;
01184 AVDictionary **opts;
01185
01186 if (!s->nb_streams)
01187 return NULL;
01188 opts = av_mallocz(s->nb_streams * sizeof(*opts));
01189 if (!opts) {
01190 av_log(NULL, AV_LOG_ERROR,
01191 "Could not alloc memory for stream options.\n");
01192 return NULL;
01193 }
01194 for (i = 0; i < s->nb_streams; i++)
01195 opts[i] = filter_codec_opts(codec_opts, avcodec_find_decoder(s->streams[i]->codec->codec_id),
01196 s, s->streams[i]);
01197 return opts;
01198 }
01199
01200 void *grow_array(void *array, int elem_size, int *size, int new_size)
01201 {
01202 if (new_size >= INT_MAX / elem_size) {
01203 av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
01204 exit_program(1);
01205 }
01206 if (*size < new_size) {
01207 uint8_t *tmp = av_realloc(array, new_size*elem_size);
01208 if (!tmp) {
01209 av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
01210 exit_program(1);
01211 }
01212 memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
01213 *size = new_size;
01214 return tmp;
01215 }
01216 return array;
01217 }