• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

cmdutils.c

Go to the documentation of this file.
00001 /*
00002  * Various utilities for command line tools
00003  * Copyright (c) 2000-2003 Fabrice Bellard
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include <string.h>
00023 #include <stdlib.h>
00024 #include <errno.h>
00025 #include <math.h>
00026 
00027 /* Include only the enabled headers since some compilers (namely, Sun
00028    Studio) will not omit unused inline functions and create undefined
00029    references to libraries that are not being built. */
00030 
00031 #include "config.h"
00032 #include "libavformat/avformat.h"
00033 #include "libavfilter/avfilter.h"
00034 #include "libavdevice/avdevice.h"
00035 #include "libswscale/swscale.h"
00036 #include "libpostproc/postprocess.h"
00037 #include "libavutil/avstring.h"
00038 #include "libavcodec/opt.h"
00039 #include "cmdutils.h"
00040 #include "version.h"
00041 #if CONFIG_NETWORK
00042 #include "libavformat/network.h"
00043 #endif
00044 
00045 #undef exit
00046 
00047 const char **opt_names;
00048 static int opt_name_count;
00049 AVCodecContext *avctx_opts[CODEC_TYPE_NB];
00050 AVFormatContext *avformat_opts;
00051 struct SwsContext *sws_opts;
00052 
00053 const int this_year = 2009;
00054 
00055 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
00056 {
00057     char *tail;
00058     const char *error;
00059     double d = strtod(numstr, &tail);
00060     if (*tail)
00061         error= "Expected number for %s but found: %s\n";
00062     else if (d < min || d > max)
00063         error= "The value for %s was %s which is not within %f - %f\n";
00064     else if(type == OPT_INT64 && (int64_t)d != d)
00065         error= "Expected int64 for %s but found %s\n";
00066     else
00067         return d;
00068     fprintf(stderr, error, context, numstr, min, max);
00069     exit(1);
00070 }
00071 
00072 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
00073 {
00074     int64_t us = parse_date(timestr, is_duration);
00075     if (us == INT64_MIN) {
00076         fprintf(stderr, "Invalid %s specification for %s: %s\n",
00077                 is_duration ? "duration" : "date", context, timestr);
00078         exit(1);
00079     }
00080     return us;
00081 }
00082 
00083 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
00084 {
00085     const OptionDef *po;
00086     int first;
00087 
00088     first = 1;
00089     for(po = options; po->name != NULL; po++) {
00090         char buf[64];
00091         if ((po->flags & mask) == value) {
00092             if (first) {
00093                 printf("%s", msg);
00094                 first = 0;
00095             }
00096             av_strlcpy(buf, po->name, sizeof(buf));
00097             if (po->flags & HAS_ARG) {
00098                 av_strlcat(buf, " ", sizeof(buf));
00099                 av_strlcat(buf, po->argname, sizeof(buf));
00100             }
00101             printf("-%-17s  %s\n", buf, po->help);
00102         }
00103     }
00104 }
00105 
00106 static const OptionDef* find_option(const OptionDef *po, const char *name){
00107     while (po->name != NULL) {
00108         if (!strcmp(name, po->name))
00109             break;
00110         po++;
00111     }
00112     return po;
00113 }
00114 
00115 void parse_options(int argc, char **argv, const OptionDef *options,
00116                    void (* parse_arg_function)(const char*))
00117 {
00118     const char *opt, *arg;
00119     int optindex, handleoptions=1;
00120     const OptionDef *po;
00121 
00122     /* parse options */
00123     optindex = 1;
00124     while (optindex < argc) {
00125         opt = argv[optindex++];
00126 
00127         if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
00128             if (opt[1] == '-' && opt[2] == '\0') {
00129                 handleoptions = 0;
00130                 continue;
00131             }
00132             po= find_option(options, opt + 1);
00133             if (!po->name)
00134                 po= find_option(options, "default");
00135             if (!po->name) {
00136 unknown_opt:
00137                 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
00138                 exit(1);
00139             }
00140             arg = NULL;
00141             if (po->flags & HAS_ARG) {
00142                 arg = argv[optindex++];
00143                 if (!arg) {
00144                     fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
00145                     exit(1);
00146                 }
00147             }
00148             if (po->flags & OPT_STRING) {
00149                 char *str;
00150                 str = av_strdup(arg);
00151                 *po->u.str_arg = str;
00152             } else if (po->flags & OPT_BOOL) {
00153                 *po->u.int_arg = 1;
00154             } else if (po->flags & OPT_INT) {
00155                 *po->u.int_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT_MIN, INT_MAX);
00156             } else if (po->flags & OPT_INT64) {
00157                 *po->u.int64_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT64_MIN, INT64_MAX);
00158             } else if (po->flags & OPT_FLOAT) {
00159                 *po->u.float_arg = parse_number_or_die(opt+1, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
00160             } else if (po->flags & OPT_FUNC2) {
00161                 if(po->u.func2_arg(opt+1, arg)<0)
00162                     goto unknown_opt;
00163             } else {
00164                 po->u.func_arg(arg);
00165             }
00166             if(po->flags & OPT_EXIT)
00167                 exit(0);
00168         } else {
00169             if (parse_arg_function)
00170                 parse_arg_function(opt);
00171         }
00172     }
00173 }
00174 
00175 int opt_default(const char *opt, const char *arg){
00176     int type;
00177     int ret= 0;
00178     const AVOption *o= NULL;
00179     int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
00180 
00181     for(type=0; type<CODEC_TYPE_NB && ret>= 0; type++){
00182         const AVOption *o2 = av_find_opt(avctx_opts[0], opt, NULL, opt_types[type], opt_types[type]);
00183         if(o2)
00184             ret = av_set_string3(avctx_opts[type], opt, arg, 1, &o);
00185     }
00186     if(!o)
00187         ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
00188     if(!o)
00189         ret = av_set_string3(sws_opts, opt, arg, 1, &o);
00190     if(!o){
00191         if(opt[0] == 'a')
00192             ret = av_set_string3(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg, 1, &o);
00193         else if(opt[0] == 'v')
00194             ret = av_set_string3(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg, 1, &o);
00195         else if(opt[0] == 's')
00196             ret = av_set_string3(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg, 1, &o);
00197     }
00198     if (o && ret < 0) {
00199         fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
00200         exit(1);
00201     }
00202     if(!o)
00203         return -1;
00204 
00205 //    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avctx_opts, opt, NULL), (int)av_get_int(avctx_opts, opt, NULL));
00206 
00207     //FIXME we should always use avctx_opts, ... for storing options so there will not be any need to keep track of what i set over this
00208     opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
00209     opt_names[opt_name_count++]= o->name;
00210 
00211     if(avctx_opts[0]->debug || avformat_opts->debug)
00212         av_log_set_level(AV_LOG_DEBUG);
00213     return 0;
00214 }
00215 
00216 void set_context_opts(void *ctx, void *opts_ctx, int flags)
00217 {
00218     int i;
00219     for(i=0; i<opt_name_count; i++){
00220         char buf[256];
00221         const AVOption *opt;
00222         const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
00223         /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
00224         if(str && ((opt->flags & flags) == flags))
00225             av_set_string3(ctx, opt_names[i], str, 1, NULL);
00226     }
00227 }
00228 
00229 void print_error(const char *filename, int err)
00230 {
00231     switch(err) {
00232     case AVERROR_NUMEXPECTED:
00233         fprintf(stderr, "%s: Incorrect image filename syntax.\n"
00234                 "Use '%%d' to specify the image number:\n"
00235                 "  for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
00236                 "  for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
00237                 filename);
00238         break;
00239     case AVERROR_INVALIDDATA:
00240         fprintf(stderr, "%s: Error while parsing header\n", filename);
00241         break;
00242     case AVERROR_NOFMT:
00243         fprintf(stderr, "%s: Unknown format\n", filename);
00244         break;
00245     case AVERROR(EIO):
00246         fprintf(stderr, "%s: I/O error occurred\n"
00247                 "Usually that means that input file is truncated and/or corrupted.\n",
00248                 filename);
00249         break;
00250     case AVERROR(ENOMEM):
00251         fprintf(stderr, "%s: memory allocation error occurred\n", filename);
00252         break;
00253     case AVERROR(ENOENT):
00254         fprintf(stderr, "%s: no such file or directory\n", filename);
00255         break;
00256 #if CONFIG_NETWORK
00257     case AVERROR(FF_NETERROR(EPROTONOSUPPORT)):
00258         fprintf(stderr, "%s: Unsupported network protocol\n", filename);
00259         break;
00260 #endif
00261     default:
00262         fprintf(stderr, "%s: Error while opening file\n", filename);
00263         break;
00264     }
00265 }
00266 
00267 #define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \
00268     version= libname##_version(); \
00269     fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n", indent? "  " : "", #libname, \
00270             LIB##LIBNAME##_VERSION_MAJOR, LIB##LIBNAME##_VERSION_MINOR, LIB##LIBNAME##_VERSION_MICRO, \
00271             version >> 16, version >> 8 & 0xff, version & 0xff);
00272 
00273 static void print_all_lib_versions(FILE* outstream, int indent)
00274 {
00275     unsigned int version;
00276     PRINT_LIB_VERSION(outstream, avutil,   AVUTIL,   indent);
00277     PRINT_LIB_VERSION(outstream, avcodec,  AVCODEC,  indent);
00278     PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
00279     PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
00280 #if CONFIG_AVFILTER
00281     PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
00282 #endif
00283 #if CONFIG_SWSCALE
00284     PRINT_LIB_VERSION(outstream, swscale,  SWSCALE,  indent);
00285 #endif
00286 #if CONFIG_POSTPROC
00287     PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent);
00288 #endif
00289 }
00290 
00291 void show_banner(void)
00292 {
00293     fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d Fabrice Bellard, et al.\n",
00294             program_name, program_birth_year, this_year);
00295     fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
00296     print_all_lib_versions(stderr, 1);
00297     fprintf(stderr, "  built on " __DATE__ " " __TIME__);
00298 #ifdef __GNUC__
00299     fprintf(stderr, ", gcc: " __VERSION__ "\n");
00300 #else
00301     fprintf(stderr, ", using a non-gcc compiler\n");
00302 #endif
00303 }
00304 
00305 void show_version(void) {
00306     printf("%s " FFMPEG_VERSION "\n", program_name);
00307     print_all_lib_versions(stdout, 0);
00308 }
00309 
00310 void show_license(void)
00311 {
00312     printf(
00313 #if CONFIG_NONFREE
00314     "This version of %s has nonfree parts compiled in.\n"
00315     "Therefore it is not legally redistributable.\n",
00316     program_name
00317 #elif CONFIG_GPLV3
00318     "%s is free software; you can redistribute it and/or modify\n"
00319     "it under the terms of the GNU General Public License as published by\n"
00320     "the Free Software Foundation; either version 3 of the License, or\n"
00321     "(at your option) any later version.\n"
00322     "\n"
00323     "%s is distributed in the hope that it will be useful,\n"
00324     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00325     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
00326     "GNU General Public License for more details.\n"
00327     "\n"
00328     "You should have received a copy of the GNU General Public License\n"
00329     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
00330     program_name, program_name, program_name
00331 #elif CONFIG_GPL
00332     "%s is free software; you can redistribute it and/or modify\n"
00333     "it under the terms of the GNU General Public License as published by\n"
00334     "the Free Software Foundation; either version 2 of the License, or\n"
00335     "(at your option) any later version.\n"
00336     "\n"
00337     "%s is distributed in the hope that it will be useful,\n"
00338     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00339     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
00340     "GNU General Public License for more details.\n"
00341     "\n"
00342     "You should have received a copy of the GNU General Public License\n"
00343     "along with %s; if not, write to the Free Software\n"
00344     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
00345     program_name, program_name, program_name
00346 #elif CONFIG_LGPLV3
00347     "%s is free software; you can redistribute it and/or modify\n"
00348     "it under the terms of the GNU Lesser General Public License as published by\n"
00349     "the Free Software Foundation; either version 3 of the License, or\n"
00350     "(at your option) any later version.\n"
00351     "\n"
00352     "%s is distributed in the hope that it will be useful,\n"
00353     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00354     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
00355     "GNU Lesser General Public License for more details.\n"
00356     "\n"
00357     "You should have received a copy of the GNU Lesser General Public License\n"
00358     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
00359     program_name, program_name, program_name
00360 #else
00361     "%s is free software; you can redistribute it and/or\n"
00362     "modify it under the terms of the GNU Lesser General Public\n"
00363     "License as published by the Free Software Foundation; either\n"
00364     "version 2.1 of the License, or (at your option) any later version.\n"
00365     "\n"
00366     "%s is distributed in the hope that it will be useful,\n"
00367     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00368     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
00369     "Lesser General Public License for more details.\n"
00370     "\n"
00371     "You should have received a copy of the GNU Lesser General Public\n"
00372     "License along with %s; if not, write to the Free Software\n"
00373     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
00374     program_name, program_name, program_name
00375 #endif
00376     );
00377 }
00378 
00379 void show_formats(void)
00380 {
00381     AVInputFormat *ifmt=NULL;
00382     AVOutputFormat *ofmt=NULL;
00383     URLProtocol *up=NULL;
00384     AVCodec *p=NULL, *p2;
00385     AVBitStreamFilter *bsf=NULL;
00386     const char *last_name;
00387 
00388     printf("File formats:\n");
00389     last_name= "000";
00390     for(;;){
00391         int decode=0;
00392         int encode=0;
00393         const char *name=NULL;
00394         const char *long_name=NULL;
00395 
00396         while((ofmt= av_oformat_next(ofmt))) {
00397             if((name == NULL || strcmp(ofmt->name, name)<0) &&
00398                 strcmp(ofmt->name, last_name)>0){
00399                 name= ofmt->name;
00400                 long_name= ofmt->long_name;
00401                 encode=1;
00402             }
00403         }
00404         while((ifmt= av_iformat_next(ifmt))) {
00405             if((name == NULL || strcmp(ifmt->name, name)<0) &&
00406                 strcmp(ifmt->name, last_name)>0){
00407                 name= ifmt->name;
00408                 long_name= ifmt->long_name;
00409                 encode=0;
00410             }
00411             if(name && strcmp(ifmt->name, name)==0)
00412                 decode=1;
00413         }
00414         if(name==NULL)
00415             break;
00416         last_name= name;
00417 
00418         printf(
00419             " %s%s %-15s %s\n",
00420             decode ? "D":" ",
00421             encode ? "E":" ",
00422             name,
00423             long_name ? long_name:" ");
00424     }
00425     printf("\n");
00426 
00427     printf("Codecs:\n");
00428     last_name= "000";
00429     for(;;){
00430         int decode=0;
00431         int encode=0;
00432         int cap=0;
00433         const char *type_str;
00434 
00435         p2=NULL;
00436         while((p= av_codec_next(p))) {
00437             if((p2==NULL || strcmp(p->name, p2->name)<0) &&
00438                 strcmp(p->name, last_name)>0){
00439                 p2= p;
00440                 decode= encode= cap=0;
00441             }
00442             if(p2 && strcmp(p->name, p2->name)==0){
00443                 if(p->decode) decode=1;
00444                 if(p->encode) encode=1;
00445                 cap |= p->capabilities;
00446             }
00447         }
00448         if(p2==NULL)
00449             break;
00450         last_name= p2->name;
00451 
00452         switch(p2->type) {
00453         case CODEC_TYPE_VIDEO:
00454             type_str = "V";
00455             break;
00456         case CODEC_TYPE_AUDIO:
00457             type_str = "A";
00458             break;
00459         case CODEC_TYPE_SUBTITLE:
00460             type_str = "S";
00461             break;
00462         default:
00463             type_str = "?";
00464             break;
00465         }
00466         printf(
00467             " %s%s%s%s%s%s %-15s %s",
00468             decode ? "D": (/*p2->decoder ? "d":*/" "),
00469             encode ? "E":" ",
00470             type_str,
00471             cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
00472             cap & CODEC_CAP_DR1 ? "D":" ",
00473             cap & CODEC_CAP_TRUNCATED ? "T":" ",
00474             p2->name,
00475             p2->long_name ? p2->long_name : "");
00476        /* if(p2->decoder && decode==0)
00477             printf(" use %s for decoding", p2->decoder->name);*/
00478         printf("\n");
00479     }
00480     printf("\n");
00481 
00482     printf("Bitstream filters:\n");
00483     while((bsf = av_bitstream_filter_next(bsf)))
00484         printf(" %s", bsf->name);
00485     printf("\n");
00486 
00487     printf("Supported file protocols:\n");
00488     while((up = av_protocol_next(up)))
00489         printf(" %s:", up->name);
00490     printf("\n");
00491 
00492     printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
00493     printf("\n");
00494     printf(
00495 "Note, the names of encoders and decoders do not always match, so there are\n"
00496 "several cases where the above table shows encoder only or decoder only entries\n"
00497 "even though both encoding and decoding are supported. For example, the h263\n"
00498 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
00499 "worse.\n");
00500 }

Generated on Sat Feb 16 2013 09:23:11 for ffmpeg by  doxygen 1.7.1