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();
00373 #if CONFIG_SWSCALE
00374     const AVClass *sc = sws_get_class();
00375 #endif
00376 
00377     if (!(p = strchr(opt, ':')))
00378         p = opt + strlen(opt);
00379     av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
00380 
00381     if ((o = av_opt_find(&cc, opt_stripped, NULL, 0,
00382                          AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
00383         ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
00384          (o = av_opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
00385         av_dict_set(&codec_opts, opt, arg, FLAGS);
00386     else if ((o = av_opt_find(&fc, opt, NULL, 0,
00387                               AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
00388         av_dict_set(&format_opts, opt, arg, FLAGS);
00389 #if CONFIG_SWSCALE
00390     else if ((o = av_opt_find(&sc, opt, NULL, 0,
00391                               AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
00392         // XXX we only support sws_flags, not arbitrary sws options
00393         int ret = av_opt_set(sws_opts, opt, arg, 0);
00394         if (ret < 0) {
00395             av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
00396             return ret;
00397         }
00398     }
00399 #endif
00400 
00401     if (o)
00402         return 0;
00403     av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
00404     return AVERROR_OPTION_NOT_FOUND;
00405 }
00406 
00407 int opt_loglevel(const char *opt, const char *arg)
00408 {
00409     const struct { const char *name; int level; } log_levels[] = {
00410         { "quiet"  , AV_LOG_QUIET   },
00411         { "panic"  , AV_LOG_PANIC   },
00412         { "fatal"  , AV_LOG_FATAL   },
00413         { "error"  , AV_LOG_ERROR   },
00414         { "warning", AV_LOG_WARNING },
00415         { "info"   , AV_LOG_INFO    },
00416         { "verbose", AV_LOG_VERBOSE },
00417         { "debug"  , AV_LOG_DEBUG   },
00418     };
00419     char *tail;
00420     int level;
00421     int i;
00422 
00423     for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
00424         if (!strcmp(log_levels[i].name, arg)) {
00425             av_log_set_level(log_levels[i].level);
00426             return 0;
00427         }
00428     }
00429 
00430     level = strtol(arg, &tail, 10);
00431     if (*tail) {
00432         av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
00433                "Possible levels are numbers or:\n", arg);
00434         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
00435             av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
00436         exit_program(1);
00437     }
00438     av_log_set_level(level);
00439     return 0;
00440 }
00441 
00442 int opt_timelimit(const char *opt, const char *arg)
00443 {
00444 #if HAVE_SETRLIMIT
00445     int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
00446     struct rlimit rl = { lim, lim + 1 };
00447     if (setrlimit(RLIMIT_CPU, &rl))
00448         perror("setrlimit");
00449 #else
00450     av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
00451 #endif
00452     return 0;
00453 }
00454 
00455 void print_error(const char *filename, int err)
00456 {
00457     char errbuf[128];
00458     const char *errbuf_ptr = errbuf;
00459 
00460     if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
00461         errbuf_ptr = strerror(AVUNERROR(err));
00462     av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
00463 }
00464 
00465 // Debian/Ubuntu: see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=619530
00466 //                    https://launchpad.net/bugs/765357
00467 static int warned_cfg = 1;
00468 
00469 #define INDENT        1
00470 #define SHOW_VERSION  2
00471 #define SHOW_CONFIG   4
00472 
00473 #define PRINT_LIB_INFO(libname, LIBNAME, flags, level)                  \
00474     if (CONFIG_##LIBNAME) {                                             \
00475         const char *indent = flags & INDENT? "  " : "";                 \
00476         if (flags & SHOW_VERSION) {                                     \
00477             unsigned int version = libname##_version();                 \
00478             av_log(NULL, level, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n",\
00479                    indent, #libname,                                    \
00480                    LIB##LIBNAME##_VERSION_MAJOR,                        \
00481                    LIB##LIBNAME##_VERSION_MINOR,                        \
00482                    LIB##LIBNAME##_VERSION_MICRO,                        \
00483                    version >> 16, version >> 8 & 0xff, version & 0xff); \
00484         }                                                               \
00485         if (flags & SHOW_CONFIG) {                                      \
00486             const char *cfg = libname##_configuration();                \
00487             if (strcmp(LIBAV_CONFIGURATION, cfg)) {                     \
00488                 if (!warned_cfg) {                                      \
00489                     av_log(NULL, level,                                 \
00490                             "%sWARNING: library configuration mismatch\n", \
00491                             indent);                                    \
00492                     warned_cfg = 1;                                     \
00493                 }                                                       \
00494                 av_log(NULL, level, "%s%-11s configuration: %s\n",      \
00495                         indent, #libname, cfg);                         \
00496             }                                                           \
00497         }                                                               \
00498     }                                                                   \
00499 
00500 static void print_all_libs_info(int flags, int level)
00501 {
00502     PRINT_LIB_INFO(avutil,   AVUTIL,   flags, level);
00503     PRINT_LIB_INFO(avcodec,  AVCODEC,  flags, level);
00504     PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
00505     PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
00506     PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
00507     PRINT_LIB_INFO(swscale,  SWSCALE,  flags, level);
00508 #if CONFIG_POSTPROC
00509     PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
00510 #endif
00511 }
00512 
00513 void show_banner(void)
00514 {
00515     av_log(NULL, AV_LOG_INFO,
00516            "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
00517            program_name, program_birth_year, this_year);
00518     av_log(NULL, AV_LOG_INFO, "  built on %s %s with %s %s\n",
00519            __DATE__, __TIME__, CC_TYPE, CC_VERSION);
00520     av_log(NULL, AV_LOG_VERBOSE, "  configuration: " LIBAV_CONFIGURATION "\n");
00521     print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_VERBOSE);
00522     print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_VERBOSE);
00523 }
00524 
00525 void show_version(void) {
00526     av_log_set_callback(log_callback_help);
00527     printf("%s " LIBAV_VERSION "\n", program_name);
00528     print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
00529 }
00530 
00531 void show_license(void)
00532 {
00533     printf(
00534 #if CONFIG_NONFREE
00535     "This version of %s has nonfree parts compiled in.\n"
00536     "Therefore it is not legally redistributable.\n",
00537     program_name
00538 #elif CONFIG_GPLV3
00539     "%s is free software; you can redistribute it and/or modify\n"
00540     "it under the terms of the GNU General Public License as published by\n"
00541     "the Free Software Foundation; either version 3 of the License, or\n"
00542     "(at your option) any later version.\n"
00543     "\n"
00544     "%s is distributed in the hope that it will be useful,\n"
00545     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00546     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
00547     "GNU General Public License for more details.\n"
00548     "\n"
00549     "You should have received a copy of the GNU General Public License\n"
00550     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
00551     program_name, program_name, program_name
00552 #elif CONFIG_GPL
00553     "%s is free software; you can redistribute it and/or modify\n"
00554     "it under the terms of the GNU General Public License as published by\n"
00555     "the Free Software Foundation; either version 2 of the License, or\n"
00556     "(at your option) any later version.\n"
00557     "\n"
00558     "%s is distributed in the hope that it will be useful,\n"
00559     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00560     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
00561     "GNU General Public License for more details.\n"
00562     "\n"
00563     "You should have received a copy of the GNU General Public License\n"
00564     "along with %s; if not, write to the Free Software\n"
00565     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
00566     program_name, program_name, program_name
00567 #elif CONFIG_LGPLV3
00568     "%s is free software; you can redistribute it and/or modify\n"
00569     "it under the terms of the GNU Lesser General Public License as published by\n"
00570     "the Free Software Foundation; either version 3 of the License, or\n"
00571     "(at your option) any later version.\n"
00572     "\n"
00573     "%s is distributed in the hope that it will be useful,\n"
00574     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00575     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
00576     "GNU Lesser General Public License for more details.\n"
00577     "\n"
00578     "You should have received a copy of the GNU Lesser General Public License\n"
00579     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
00580     program_name, program_name, program_name
00581 #else
00582     "%s is free software; you can redistribute it and/or\n"
00583     "modify it under the terms of the GNU Lesser General Public\n"
00584     "License as published by the Free Software Foundation; either\n"
00585     "version 2.1 of the License, or (at your option) any later version.\n"
00586     "\n"
00587     "%s is distributed in the hope that it will be useful,\n"
00588     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00589     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
00590     "Lesser General Public License for more details.\n"
00591     "\n"
00592     "You should have received a copy of the GNU Lesser General Public\n"
00593     "License along with %s; if not, write to the Free Software\n"
00594     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
00595     program_name, program_name, program_name
00596 #endif
00597     );
00598 }
00599 
00600 void show_formats(void)
00601 {
00602     AVInputFormat *ifmt  = NULL;
00603     AVOutputFormat *ofmt = NULL;
00604     const char *last_name;
00605 
00606     printf("File formats:\n"
00607            " D. = Demuxing supported\n"
00608            " .E = Muxing supported\n"
00609            " --\n");
00610     last_name = "000";
00611     for (;;) {
00612         int decode = 0;
00613         int encode = 0;
00614         const char *name      = NULL;
00615         const char *long_name = NULL;
00616 
00617         while ((ofmt = av_oformat_next(ofmt))) {
00618             if ((name == NULL || strcmp(ofmt->name, name) < 0) &&
00619                 strcmp(ofmt->name, last_name) > 0) {
00620                 name      = ofmt->name;
00621                 long_name = ofmt->long_name;
00622                 encode    = 1;
00623             }
00624         }
00625         while ((ifmt = av_iformat_next(ifmt))) {
00626             if ((name == NULL || strcmp(ifmt->name, name) < 0) &&
00627                 strcmp(ifmt->name, last_name) > 0) {
00628                 name      = ifmt->name;
00629                 long_name = ifmt->long_name;
00630                 encode    = 0;
00631             }
00632             if (name && strcmp(ifmt->name, name) == 0)
00633                 decode = 1;
00634         }
00635         if (name == NULL)
00636             break;
00637         last_name = name;
00638 
00639         printf(" %s%s %-15s %s\n",
00640                decode ? "D" : " ",
00641                encode ? "E" : " ",
00642                name,
00643             long_name ? long_name:" ");
00644     }
00645 }
00646 
00647 void show_codecs(void)
00648 {
00649     AVCodec *p = NULL, *p2;
00650     const char *last_name;
00651     printf("Codecs:\n"
00652            " D..... = Decoding supported\n"
00653            " .E.... = Encoding supported\n"
00654            " ..V... = Video codec\n"
00655            " ..A... = Audio codec\n"
00656            " ..S... = Subtitle codec\n"
00657            " ...S.. = Supports draw_horiz_band\n"
00658            " ....D. = Supports direct rendering method 1\n"
00659            " .....T = Supports weird frame truncation\n"
00660            " ------\n");
00661     last_name= "000";
00662     for (;;) {
00663         int decode = 0;
00664         int encode = 0;
00665         int cap    = 0;
00666         const char *type_str;
00667 
00668         p2 = NULL;
00669         while ((p = av_codec_next(p))) {
00670             if ((p2 == NULL || strcmp(p->name, p2->name) < 0) &&
00671                 strcmp(p->name, last_name) > 0) {
00672                 p2 = p;
00673                 decode = encode = cap = 0;
00674             }
00675             if (p2 && strcmp(p->name, p2->name) == 0) {
00676                 if (p->decode)
00677                     decode = 1;
00678                 if (p->encode)
00679                     encode = 1;
00680                 cap |= p->capabilities;
00681             }
00682         }
00683         if (p2 == NULL)
00684             break;
00685         last_name = p2->name;
00686 
00687         switch (p2->type) {
00688         case AVMEDIA_TYPE_VIDEO:
00689             type_str = "V";
00690             break;
00691         case AVMEDIA_TYPE_AUDIO:
00692             type_str = "A";
00693             break;
00694         case AVMEDIA_TYPE_SUBTITLE:
00695             type_str = "S";
00696             break;
00697         default:
00698             type_str = "?";
00699             break;
00700         }
00701         printf(" %s%s%s%s%s%s %-15s %s",
00702                decode ? "D" : (/* p2->decoder ? "d" : */ " "),
00703                encode ? "E" : " ",
00704                type_str,
00705                cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S" : " ",
00706                cap & CODEC_CAP_DR1 ? "D" : " ",
00707                cap & CODEC_CAP_TRUNCATED ? "T" : " ",
00708                p2->name,
00709                p2->long_name ? p2->long_name : "");
00710 #if 0
00711             if (p2->decoder && decode == 0)
00712                 printf(" use %s for decoding", p2->decoder->name);
00713 #endif
00714         printf("\n");
00715     }
00716     printf("\n");
00717     printf("Note, the names of encoders and decoders do not always match, so there are\n"
00718            "several cases where the above table shows encoder only or decoder only entries\n"
00719            "even though both encoding and decoding are supported. For example, the h263\n"
00720            "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
00721            "worse.\n");
00722 }
00723 
00724 void show_bsfs(void)
00725 {
00726     AVBitStreamFilter *bsf = NULL;
00727 
00728     printf("Bitstream filters:\n");
00729     while ((bsf = av_bitstream_filter_next(bsf)))
00730         printf("%s\n", bsf->name);
00731     printf("\n");
00732 }
00733 
00734 void show_protocols(void)
00735 {
00736     void *opaque = NULL;
00737     const char *name;
00738 
00739     printf("Supported file protocols:\n"
00740            "Input:\n");
00741     while ((name = avio_enum_protocols(&opaque, 0)))
00742         printf("%s\n", name);
00743     printf("Output:\n");
00744     while ((name = avio_enum_protocols(&opaque, 1)))
00745         printf("%s\n", name);
00746 }
00747 
00748 void show_filters(void)
00749 {
00750     AVFilter av_unused(**filter) = NULL;
00751 
00752     printf("Filters:\n");
00753 #if CONFIG_AVFILTER
00754     while ((filter = av_filter_next(filter)) && *filter)
00755         printf("%-16s %s\n", (*filter)->name, (*filter)->description);
00756 #endif
00757 }
00758 
00759 void show_pix_fmts(void)
00760 {
00761     enum PixelFormat pix_fmt;
00762 
00763     printf("Pixel formats:\n"
00764            "I.... = Supported Input  format for conversion\n"
00765            ".O... = Supported Output format for conversion\n"
00766            "..H.. = Hardware accelerated format\n"
00767            "...P. = Paletted format\n"
00768            "....B = Bitstream format\n"
00769            "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL\n"
00770            "-----\n");
00771 
00772 #if !CONFIG_SWSCALE
00773 #   define sws_isSupportedInput(x)  0
00774 #   define sws_isSupportedOutput(x) 0
00775 #endif
00776 
00777     for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
00778         const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
00779         printf("%c%c%c%c%c %-16s       %d            %2d\n",
00780                sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
00781                sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
00782                pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
00783                pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
00784                pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
00785                pix_desc->name,
00786                pix_desc->nb_components,
00787                av_get_bits_per_pixel(pix_desc));
00788     }
00789 }
00790 
00791 int show_sample_fmts(const char *opt, const char *arg)
00792 {
00793     int i;
00794     char fmt_str[128];
00795     for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
00796         printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
00797     return 0;
00798 }
00799 
00800 int read_yesno(void)
00801 {
00802     int c = getchar();
00803     int yesno = (toupper(c) == 'Y');
00804 
00805     while (c != '\n' && c != EOF)
00806         c = getchar();
00807 
00808     return yesno;
00809 }
00810 
00811 int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
00812 {
00813     int ret;
00814     FILE *f = fopen(filename, "rb");
00815 
00816     if (!f) {
00817         av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
00818                strerror(errno));
00819         return AVERROR(errno);
00820     }
00821     fseek(f, 0, SEEK_END);
00822     *size = ftell(f);
00823     fseek(f, 0, SEEK_SET);
00824     *bufptr = av_malloc(*size + 1);
00825     if (!*bufptr) {
00826         av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
00827         fclose(f);
00828         return AVERROR(ENOMEM);
00829     }
00830     ret = fread(*bufptr, 1, *size, f);
00831     if (ret < *size) {
00832         av_free(*bufptr);
00833         if (ferror(f)) {
00834             av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
00835                    filename, strerror(errno));
00836             ret = AVERROR(errno);
00837         } else
00838             ret = AVERROR_EOF;
00839     } else {
00840         ret = 0;
00841         (*bufptr)[*size++] = '\0';
00842     }
00843 
00844     fclose(f);
00845     return ret;
00846 }
00847 
00848 void init_pts_correction(PtsCorrectionContext *ctx)
00849 {
00850     ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
00851     ctx->last_pts = ctx->last_dts = INT64_MIN;
00852 }
00853 
00854 int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts,
00855                           int64_t dts)
00856 {
00857     int64_t pts = AV_NOPTS_VALUE;
00858 
00859     if (dts != AV_NOPTS_VALUE) {
00860         ctx->num_faulty_dts += dts <= ctx->last_dts;
00861         ctx->last_dts = dts;
00862     }
00863     if (reordered_pts != AV_NOPTS_VALUE) {
00864         ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
00865         ctx->last_pts = reordered_pts;
00866     }
00867     if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
00868         && reordered_pts != AV_NOPTS_VALUE)
00869         pts = reordered_pts;
00870     else
00871         pts = dts;
00872 
00873     return pts;
00874 }
00875 
00876 FILE *get_preset_file(char *filename, size_t filename_size,
00877                       const char *preset_name, int is_path,
00878                       const char *codec_name)
00879 {
00880     FILE *f = NULL;
00881     int i;
00882     const char *base[3] = { getenv("AVCONV_DATADIR"),
00883                             getenv("HOME"),
00884                             AVCONV_DATADIR, };
00885 
00886     if (is_path) {
00887         av_strlcpy(filename, preset_name, filename_size);
00888         f = fopen(filename, "r");
00889     } else {
00890         for (i = 0; i < 3 && !f; i++) {
00891             if (!base[i])
00892                 continue;
00893             snprintf(filename, filename_size, "%s%s/%s.avpreset", base[i],
00894                      i != 1 ? "" : "/.avconv", preset_name);
00895             f = fopen(filename, "r");
00896             if (!f && codec_name) {
00897                 snprintf(filename, filename_size,
00898                          "%s%s/%s-%s.avpreset",
00899                          base[i], i != 1 ? "" : "/.avconv", codec_name,
00900                          preset_name);
00901                 f = fopen(filename, "r");
00902             }
00903         }
00904     }
00905 
00906     return f;
00907 }
00908 
00909 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
00910 {
00911     if (*spec <= '9' && *spec >= '0') /* opt:index */
00912         return strtol(spec, NULL, 0) == st->index;
00913     else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
00914              *spec == 't') { /* opt:[vasdt] */
00915         enum AVMediaType type;
00916 
00917         switch (*spec++) {
00918         case 'v': type = AVMEDIA_TYPE_VIDEO;      break;
00919         case 'a': type = AVMEDIA_TYPE_AUDIO;      break;
00920         case 's': type = AVMEDIA_TYPE_SUBTITLE;   break;
00921         case 'd': type = AVMEDIA_TYPE_DATA;       break;
00922         case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
00923         }
00924         if (type != st->codec->codec_type)
00925             return 0;
00926         if (*spec++ == ':') { /* possibly followed by :index */
00927             int i, index = strtol(spec, NULL, 0);
00928             for (i = 0; i < s->nb_streams; i++)
00929                 if (s->streams[i]->codec->codec_type == type && index-- == 0)
00930                    return i == st->index;
00931             return 0;
00932         }
00933         return 1;
00934     } else if (*spec == 'p' && *(spec + 1) == ':') {
00935         int prog_id, i, j;
00936         char *endptr;
00937         spec += 2;
00938         prog_id = strtol(spec, &endptr, 0);
00939         for (i = 0; i < s->nb_programs; i++) {
00940             if (s->programs[i]->id != prog_id)
00941                 continue;
00942 
00943             if (*endptr++ == ':') {
00944                 int stream_idx = strtol(endptr, NULL, 0);
00945                 return stream_idx >= 0 &&
00946                     stream_idx < s->programs[i]->nb_stream_indexes &&
00947                     st->index == s->programs[i]->stream_index[stream_idx];
00948             }
00949 
00950             for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
00951                 if (st->index == s->programs[i]->stream_index[j])
00952                     return 1;
00953         }
00954         return 0;
00955     } else if (!*spec) /* empty specifier, matches everything */
00956         return 1;
00957 
00958     av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
00959     return AVERROR(EINVAL);
00960 }
00961 
00962 AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id,
00963                                 AVFormatContext *s, AVStream *st)
00964 {
00965     AVDictionary    *ret = NULL;
00966     AVDictionaryEntry *t = NULL;
00967     AVCodec       *codec = s->oformat ? avcodec_find_encoder(codec_id)
00968                                       : avcodec_find_decoder(codec_id);
00969     int            flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
00970                                       : AV_OPT_FLAG_DECODING_PARAM;
00971     char          prefix = 0;
00972     const AVClass    *cc = avcodec_get_class();
00973 
00974     if (!codec)
00975         return NULL;
00976 
00977     switch (codec->type) {
00978     case AVMEDIA_TYPE_VIDEO:
00979         prefix  = 'v';
00980         flags  |= AV_OPT_FLAG_VIDEO_PARAM;
00981         break;
00982     case AVMEDIA_TYPE_AUDIO:
00983         prefix  = 'a';
00984         flags  |= AV_OPT_FLAG_AUDIO_PARAM;
00985         break;
00986     case AVMEDIA_TYPE_SUBTITLE:
00987         prefix  = 's';
00988         flags  |= AV_OPT_FLAG_SUBTITLE_PARAM;
00989         break;
00990     }
00991 
00992     while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
00993         char *p = strchr(t->key, ':');
00994 
00995         /* check stream specification in opt name */
00996         if (p)
00997             switch (check_stream_specifier(s, st, p + 1)) {
00998             case  1: *p = 0; break;
00999             case  0:         continue;
01000             default:         return NULL;
01001             }
01002 
01003         if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
01004             (codec && codec->priv_class &&
01005              av_opt_find(&codec->priv_class, t->key, NULL, flags,
01006                          AV_OPT_SEARCH_FAKE_OBJ)))
01007             av_dict_set(&ret, t->key, t->value, 0);
01008         else if (t->key[0] == prefix &&
01009                  av_opt_find(&cc, t->key + 1, NULL, flags,
01010                              AV_OPT_SEARCH_FAKE_OBJ))
01011             av_dict_set(&ret, t->key + 1, t->value, 0);
01012 
01013         if (p)
01014             *p = ':';
01015     }
01016     return ret;
01017 }
01018 
01019 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
01020                                            AVDictionary *codec_opts)
01021 {
01022     int i;
01023     AVDictionary **opts;
01024 
01025     if (!s->nb_streams)
01026         return NULL;
01027     opts = av_mallocz(s->nb_streams * sizeof(*opts));
01028     if (!opts) {
01029         av_log(NULL, AV_LOG_ERROR,
01030                "Could not alloc memory for stream options.\n");
01031         return NULL;
01032     }
01033     for (i = 0; i < s->nb_streams; i++)
01034         opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id,
01035                                     s, s->streams[i]);
01036     return opts;
01037 }
01038 
01039 #if CONFIG_AVFILTER
01040 
01041 static int avsink_init(AVFilterContext *ctx, const char *args, void *opaque)
01042 {
01043     AVSinkContext *priv = ctx->priv;
01044 
01045     if (!opaque)
01046         return AVERROR(EINVAL);
01047     *priv = *(AVSinkContext *)opaque;
01048 
01049     return 0;
01050 }
01051 
01052 static void null_end_frame(AVFilterLink *inlink) { }
01053 
01054 static int avsink_query_formats(AVFilterContext *ctx)
01055 {
01056     AVSinkContext *priv = ctx->priv;
01057     enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
01058 
01059     avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
01060     return 0;
01061 }
01062 
01063 AVFilter avsink = {
01064     .name      = "avsink",
01065     .priv_size = sizeof(AVSinkContext),
01066     .init      = avsink_init,
01067 
01068     .query_formats = avsink_query_formats,
01069 
01070     .inputs    = (AVFilterPad[]) {{ .name          = "default",
01071                                     .type          = AVMEDIA_TYPE_VIDEO,
01072                                     .end_frame     = null_end_frame,
01073                                     .min_perms     = AV_PERM_READ, },
01074                                   { .name = NULL }},
01075     .outputs   = (AVFilterPad[]) {{ .name = NULL }},
01076 };
01077 
01078 int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
01079                              AVFilterBufferRef **picref_ptr, AVRational *tb)
01080 {
01081     int ret;
01082     AVFilterBufferRef *picref;
01083 
01084     if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
01085         return ret;
01086     if (!(picref = ctx->inputs[0]->cur_buf))
01087         return AVERROR(ENOENT);
01088     *picref_ptr = picref;
01089     ctx->inputs[0]->cur_buf = NULL;
01090     *tb = ctx->inputs[0]->time_base;
01091 
01092     memcpy(frame->data,     picref->data,     sizeof(frame->data));
01093     memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
01094     frame->interlaced_frame    = picref->video->interlaced;
01095     frame->top_field_first     = picref->video->top_field_first;
01096     frame->key_frame           = picref->video->key_frame;
01097     frame->pict_type           = picref->video->pict_type;
01098     frame->sample_aspect_ratio = picref->video->pixel_aspect;
01099 
01100     return 1;
01101 }
01102 
01103 #endif /* CONFIG_AVFILTER */
01104 
01105 void *grow_array(void *array, int elem_size, int *size, int new_size)
01106 {
01107     if (new_size >= INT_MAX / elem_size) {
01108         av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
01109         exit_program(1);
01110     }
01111     if (*size < new_size) {
01112         uint8_t *tmp = av_realloc(array, new_size*elem_size);
01113         if (!tmp) {
01114             av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
01115             exit_program(1);
01116         }
01117         memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
01118         *size = new_size;
01119         return tmp;
01120     }
01121     return array;
01122 }