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