cmdutils.c 9.12 KB
Newer Older
Fabrice Bellard's avatar
Fabrice Bellard committed
1 2 3 4
/*
 * Various utilities for command line tools
 * Copyright (c) 2000-2003 Fabrice Bellard
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
Fabrice Bellard's avatar
Fabrice Bellard committed
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
Fabrice Bellard committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Fabrice Bellard's avatar
Fabrice Bellard committed
20
 */
21

22 23 24
#include <string.h>
#include <stdlib.h>
#include <errno.h>
25
#include <math.h>
26

27
#include "config.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
28
#include "avformat.h"
29
#include "avfilter.h"
30
#include "avdevice.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
31
#include "cmdutils.h"
32
#include "avstring.h"
33
#include "version.h"
34
#include "network.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
35

Michael Niedermayer's avatar
Michael Niedermayer committed
36 37
#undef exit

Michael Niedermayer's avatar
Michael Niedermayer committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
{
    char *tail;
    const char *error;
    double d = strtod(numstr, &tail);
    if (*tail)
        error= "Expected number for %s but found: %s\n";
    else if (d < min || d > max)
        error= "The value for %s was %s which is not within %f - %f\n";
    else if(type == OPT_INT64 && (int64_t)d != d)
        error= "Expected int64 for %s but found %s\n";
    else
        return d;
    fprintf(stderr, error, context, numstr, min, max);
    exit(1);
}

56 57 58 59 60 61 62 63 64 65 66
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
{
    int64_t us = parse_date(timestr, is_duration);
    if (us == INT64_MIN) {
        fprintf(stderr, "Invalid %s specification for %s: %s\n",
                is_duration ? "duration" : "date", context, timestr);
        exit(1);
    }
    return us;
}

67
void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
Fabrice Bellard's avatar
Fabrice Bellard committed
68 69
{
    const OptionDef *po;
70
    int first;
Fabrice Bellard's avatar
Fabrice Bellard committed
71

72 73 74 75 76 77 78 79
    first = 1;
    for(po = options; po->name != NULL; po++) {
        char buf[64];
        if ((po->flags & mask) == value) {
            if (first) {
                printf("%s", msg);
                first = 0;
            }
80
            av_strlcpy(buf, po->name, sizeof(buf));
81
            if (po->flags & HAS_ARG) {
82 83
                av_strlcat(buf, " ", sizeof(buf));
                av_strlcat(buf, po->argname, sizeof(buf));
Fabrice Bellard's avatar
Fabrice Bellard committed
84
            }
85
            printf("-%-17s  %s\n", buf, po->help);
Fabrice Bellard's avatar
Fabrice Bellard committed
86 87 88 89
        }
    }
}

Måns Rullgård's avatar
Måns Rullgård committed
90
static const OptionDef* find_option(const OptionDef *po, const char *name){
Michael Niedermayer's avatar
Michael Niedermayer committed
91 92 93 94 95 96 97 98
    while (po->name != NULL) {
        if (!strcmp(name, po->name))
            break;
        po++;
    }
    return po;
}

99 100
void parse_options(int argc, char **argv, const OptionDef *options,
                   void (* parse_arg_function)(const char*))
Fabrice Bellard's avatar
Fabrice Bellard committed
101 102
{
    const char *opt, *arg;
103
    int optindex, handleoptions=1;
Fabrice Bellard's avatar
Fabrice Bellard committed
104 105 106 107 108 109
    const OptionDef *po;

    /* parse options */
    optindex = 1;
    while (optindex < argc) {
        opt = argv[optindex++];
110

111 112 113 114 115
        if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
          if (opt[1] == '-' && opt[2] == '\0') {
            handleoptions = 0;
            continue;
          }
Michael Niedermayer's avatar
Michael Niedermayer committed
116 117 118
            po= find_option(options, opt + 1);
            if (!po->name)
                po= find_option(options, "default");
Fabrice Bellard's avatar
Fabrice Bellard committed
119
            if (!po->name) {
Michael Niedermayer's avatar
Michael Niedermayer committed
120
unknown_opt:
Fabrice Bellard's avatar
Fabrice Bellard committed
121 122 123 124 125 126 127 128 129 130 131 132 133
                fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
                exit(1);
            }
            arg = NULL;
            if (po->flags & HAS_ARG) {
                arg = argv[optindex++];
                if (!arg) {
                    fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
                    exit(1);
                }
            }
            if (po->flags & OPT_STRING) {
                char *str;
134
                str = av_strdup(arg);
Fabrice Bellard's avatar
Fabrice Bellard committed
135 136 137
                *po->u.str_arg = str;
            } else if (po->flags & OPT_BOOL) {
                *po->u.int_arg = 1;
Michael Niedermayer's avatar
OPT_INT  
Michael Niedermayer committed
138
            } else if (po->flags & OPT_INT) {
139
                *po->u.int_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT_MIN, INT_MAX);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
140
            } else if (po->flags & OPT_INT64) {
141
                *po->u.int64_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT64_MIN, INT64_MAX);
Michael Niedermayer's avatar
Michael Niedermayer committed
142
            } else if (po->flags & OPT_FLOAT) {
143
                *po->u.float_arg = parse_number_or_die(opt+1, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
Michael Niedermayer's avatar
Michael Niedermayer committed
144 145 146
            } else if (po->flags & OPT_FUNC2) {
                if(po->u.func2_arg(opt+1, arg)<0)
                    goto unknown_opt;
Fabrice Bellard's avatar
Fabrice Bellard committed
147
            } else {
148
                po->u.func_arg(arg);
Fabrice Bellard's avatar
Fabrice Bellard committed
149 150
            }
        } else {
151 152
            if (parse_arg_function)
                parse_arg_function(opt);
Fabrice Bellard's avatar
Fabrice Bellard committed
153 154 155 156 157 158 159 160 161 162 163
        }
    }
}

void print_error(const char *filename, int err)
{
    switch(err) {
    case AVERROR_NUMEXPECTED:
        fprintf(stderr, "%s: Incorrect image filename syntax.\n"
                "Use '%%d' to specify the image number:\n"
                "  for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
164
                "  for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
Fabrice Bellard's avatar
Fabrice Bellard committed
165 166 167 168 169 170 171 172
                filename);
        break;
    case AVERROR_INVALIDDATA:
        fprintf(stderr, "%s: Error while parsing header\n", filename);
        break;
    case AVERROR_NOFMT:
        fprintf(stderr, "%s: Unknown format\n", filename);
        break;
173
    case AVERROR(EIO):
Diego Biurrun's avatar
Diego Biurrun committed
174
        fprintf(stderr, "%s: I/O error occurred\n"
175 176
                "Usually that means that input file is truncated and/or corrupted.\n",
                filename);
177
        break;
178
    case AVERROR(ENOMEM):
Diego Biurrun's avatar
Diego Biurrun committed
179
        fprintf(stderr, "%s: memory allocation error occurred\n", filename);
180
        break;
181
    case AVERROR(ENOENT):
182 183
        fprintf(stderr, "%s: no such file or directory\n", filename);
        break;
184 185 186
    case AVERROR(FF_NETERROR(EPROTONOSUPPORT)):
        fprintf(stderr, "%s: Unsupported network protocol\n", filename);
        break;
Fabrice Bellard's avatar
Fabrice Bellard committed
187 188 189 190 191
    default:
        fprintf(stderr, "%s: Error while opening file\n", filename);
        break;
    }
}
192

193 194
void show_banner(const char *program_name, int program_birth_year)
{
Benoit Fouet's avatar
Benoit Fouet committed
195
    fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-2008 Fabrice Bellard, et al.\n",
196 197 198 199 200
            program_name, program_birth_year);
    fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
    fprintf(stderr, "  libavutil version: " AV_STRINGIFY(LIBAVUTIL_VERSION) "\n");
    fprintf(stderr, "  libavcodec version: " AV_STRINGIFY(LIBAVCODEC_VERSION) "\n");
    fprintf(stderr, "  libavformat version: " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\n");
201
    fprintf(stderr, "  libavdevice version: " AV_STRINGIFY(LIBAVDEVICE_VERSION) "\n");
202 203 204
#if ENABLE_AVFILTER
    fprintf(stderr, "  libavfilter version: " AV_STRINGIFY(LIBAVFILTER_VERSION) "\n");
#endif
205 206 207 208 209 210 211 212 213
    fprintf(stderr, "  built on " __DATE__ " " __TIME__);
#ifdef __GNUC__
    fprintf(stderr, ", gcc: " __VERSION__ "\n");
#else
    fprintf(stderr, ", using a non-gcc compiler\n");
#endif
}

void show_version(const char *program_name) {
214
     /* TODO: add function interface to avutil and avformat avdevice*/
215 216 217
    printf("%s " FFMPEG_VERSION "\n", program_name);
    printf("libavutil   %d\n"
           "libavcodec  %d\n"
218 219 220
           "libavformat %d\n"
           "libavdevice %d\n",
           LIBAVUTIL_BUILD, avcodec_build(), LIBAVFORMAT_BUILD, LIBAVDEVICE_BUILD);
221 222
}

223 224
void show_license(void)
{
225 226 227 228 229 230
#ifdef CONFIG_NONFREE
    printf(
    "This version of FFmpeg has nonfree parts compiled in.\n"
    "Therefore it is not legally redistributable.\n"
    );
#elif CONFIG_GPL
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
    printf(
    "FFmpeg is free software; you can redistribute it and/or modify\n"
    "it under the terms of the GNU General Public License as published by\n"
    "the Free Software Foundation; either version 2 of the License, or\n"
    "(at your option) any later version.\n"
    "\n"
    "FFmpeg is distributed in the hope that it will be useful,\n"
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
    "GNU General Public License for more details.\n"
    "\n"
    "You should have received a copy of the GNU General Public License\n"
    "along with FFmpeg; if not, write to the Free Software\n"
    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
    );
#else
    printf(
    "FFmpeg is free software; you can redistribute it and/or\n"
    "modify it under the terms of the GNU Lesser General Public\n"
    "License as published by the Free Software Foundation; either\n"
    "version 2.1 of the License, or (at your option) any later version.\n"
    "\n"
    "FFmpeg is distributed in the hope that it will be useful,\n"
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
    "Lesser General Public License for more details.\n"
    "\n"
    "You should have received a copy of the GNU Lesser General Public\n"
    "License along with FFmpeg; if not, write to the Free Software\n"
    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
    );
#endif
}