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