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