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