Correctly handle empty frames
[libav.git] / cmdutils.c
CommitLineData
01310af2
FB
1/*
2 * Various utilities for command line tools
3 * Copyright (c) 2000-2003 Fabrice Bellard
4 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
01310af2
FB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
01310af2 11 *
b78e7197 12 * FFmpeg is distributed in the hope that it will be useful,
01310af2
FB
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
b78e7197 18 * License along with FFmpeg; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
01310af2 20 */
364a9607 21
0f4e8165
RB
22#include <string.h>
23#include <stdlib.h>
24#include <errno.h>
7c84b8bc 25#include <math.h>
0f4e8165 26
01310af2 27#include "avformat.h"
ab4b28f0 28#include "avfilter.h"
2208741a 29#include "avdevice.h"
01310af2 30#include "cmdutils.h"
f7d78f36 31#include "avstring.h"
86074ed1 32#include "version.h"
b6cd8593 33#include "config.h"
01310af2 34
c367d067
MN
35#undef exit
36
086ab001
MN
37
38double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
39{
40 char *tail;
41 const char *error;
42 double d = strtod(numstr, &tail);
43 if (*tail)
44 error= "Expected number for %s but found: %s\n";
45 else if (d < min || d > max)
46 error= "The value for %s was %s which is not within %f - %f\n";
47 else if(type == OPT_INT64 && (int64_t)d != d)
48 error= "Expected int64 for %s but found %s\n";
49 else
50 return d;
51 fprintf(stderr, error, context, numstr, min, max);
52 exit(1);
53}
54
02d504a7 55void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
01310af2
FB
56{
57 const OptionDef *po;
02d504a7 58 int first;
01310af2 59
02d504a7
FB
60 first = 1;
61 for(po = options; po->name != NULL; po++) {
62 char buf[64];
63 if ((po->flags & mask) == value) {
64 if (first) {
65 printf("%s", msg);
66 first = 0;
67 }
f7d78f36 68 av_strlcpy(buf, po->name, sizeof(buf));
02d504a7 69 if (po->flags & HAS_ARG) {
f7d78f36
MR
70 av_strlcat(buf, " ", sizeof(buf));
71 av_strlcat(buf, po->argname, sizeof(buf));
01310af2 72 }
02d504a7 73 printf("-%-17s %s\n", buf, po->help);
01310af2
FB
74 }
75 }
76}
77
fccfc475 78static const OptionDef* find_option(const OptionDef *po, const char *name){
8bbf6db9
MN
79 while (po->name != NULL) {
80 if (!strcmp(name, po->name))
81 break;
82 po++;
83 }
84 return po;
85}
86
60a9966e
SS
87void parse_options(int argc, char **argv, const OptionDef *options,
88 void (* parse_arg_function)(const char*))
01310af2
FB
89{
90 const char *opt, *arg;
b0d7bc1e 91 int optindex, handleoptions=1;
01310af2
FB
92 const OptionDef *po;
93
94 /* parse options */
95 optindex = 1;
96 while (optindex < argc) {
97 opt = argv[optindex++];
115329f1 98
84bf226b
TL
99 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
100 if (opt[1] == '-' && opt[2] == '\0') {
101 handleoptions = 0;
102 continue;
103 }
8bbf6db9
MN
104 po= find_option(options, opt + 1);
105 if (!po->name)
106 po= find_option(options, "default");
01310af2 107 if (!po->name) {
8bbf6db9 108unknown_opt:
01310af2
FB
109 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
110 exit(1);
111 }
112 arg = NULL;
113 if (po->flags & HAS_ARG) {
114 arg = argv[optindex++];
115 if (!arg) {
116 fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
117 exit(1);
118 }
119 }
120 if (po->flags & OPT_STRING) {
121 char *str;
02d504a7 122 str = av_strdup(arg);
01310af2
FB
123 *po->u.str_arg = str;
124 } else if (po->flags & OPT_BOOL) {
125 *po->u.int_arg = 1;
26d4f26b 126 } else if (po->flags & OPT_INT) {
7c84b8bc 127 *po->u.int_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT_MIN, INT_MAX);
ffdf9a1f 128 } else if (po->flags & OPT_INT64) {
7c84b8bc 129 *po->u.int64_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT64_MIN, INT64_MAX);
1f631450 130 } else if (po->flags & OPT_FLOAT) {
1f3d74d3 131 *po->u.float_arg = parse_number_or_die(opt+1, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
8bbf6db9
MN
132 } else if (po->flags & OPT_FUNC2) {
133 if(po->u.func2_arg(opt+1, arg)<0)
134 goto unknown_opt;
01310af2 135 } else {
bb270c08 136 po->u.func_arg(arg);
01310af2
FB
137 }
138 } else {
60a9966e
SS
139 if (parse_arg_function)
140 parse_arg_function(opt);
01310af2
FB
141 }
142 }
143}
144
145void print_error(const char *filename, int err)
146{
147 switch(err) {
148 case AVERROR_NUMEXPECTED:
149 fprintf(stderr, "%s: Incorrect image filename syntax.\n"
150 "Use '%%d' to specify the image number:\n"
151 " for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
115329f1 152 " for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
01310af2
FB
153 filename);
154 break;
155 case AVERROR_INVALIDDATA:
156 fprintf(stderr, "%s: Error while parsing header\n", filename);
157 break;
158 case AVERROR_NOFMT:
159 fprintf(stderr, "%s: Unknown format\n", filename);
160 break;
6f3e0b21 161 case AVERROR(EIO):
45ce5ddb 162 fprintf(stderr, "%s: I/O error occured\n"
bb270c08
DB
163 "Usually that means that input file is truncated and/or corrupted.\n",
164 filename);
45ce5ddb 165 break;
769e10f0 166 case AVERROR(ENOMEM):
45ce5ddb
KS
167 fprintf(stderr, "%s: memory allocation error occured\n", filename);
168 break;
24fddf48 169 case AVERROR(ENOENT):
0ba0c8de
BF
170 fprintf(stderr, "%s: no such file or directory\n", filename);
171 break;
01310af2
FB
172 default:
173 fprintf(stderr, "%s: Error while opening file\n", filename);
174 break;
175 }
176}
f35917b2 177
86074ed1
SS
178void show_banner(const char *program_name, int program_birth_year)
179{
69c12fbb 180 fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-2008 Fabrice Bellard, et al.\n",
86074ed1
SS
181 program_name, program_birth_year);
182 fprintf(stderr, " configuration: " FFMPEG_CONFIGURATION "\n");
183 fprintf(stderr, " libavutil version: " AV_STRINGIFY(LIBAVUTIL_VERSION) "\n");
184 fprintf(stderr, " libavcodec version: " AV_STRINGIFY(LIBAVCODEC_VERSION) "\n");
185 fprintf(stderr, " libavformat version: " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\n");
2208741a 186 fprintf(stderr, " libavdevice version: " AV_STRINGIFY(LIBAVDEVICE_VERSION) "\n");
ab4b28f0
VS
187#if ENABLE_AVFILTER
188 fprintf(stderr, " libavfilter version: " AV_STRINGIFY(LIBAVFILTER_VERSION) "\n");
189#endif
86074ed1
SS
190 fprintf(stderr, " built on " __DATE__ " " __TIME__);
191#ifdef __GNUC__
192 fprintf(stderr, ", gcc: " __VERSION__ "\n");
193#else
194 fprintf(stderr, ", using a non-gcc compiler\n");
195#endif
196}
197
198void show_version(const char *program_name) {
2208741a 199 /* TODO: add function interface to avutil and avformat avdevice*/
86074ed1
SS
200 printf("%s " FFMPEG_VERSION "\n", program_name);
201 printf("libavutil %d\n"
202 "libavcodec %d\n"
2208741a
MN
203 "libavformat %d\n"
204 "libavdevice %d\n",
205 LIBAVUTIL_BUILD, avcodec_build(), LIBAVFORMAT_BUILD, LIBAVDEVICE_BUILD);
86074ed1
SS
206}
207
f35917b2
SS
208void show_license(void)
209{
7ead693b
DB
210#ifdef CONFIG_NONFREE
211 printf(
212 "This version of FFmpeg has nonfree parts compiled in.\n"
213 "Therefore it is not legally redistributable.\n"
214 );
215#elif CONFIG_GPL
f35917b2
SS
216 printf(
217 "FFmpeg is free software; you can redistribute it and/or modify\n"
218 "it under the terms of the GNU General Public License as published by\n"
219 "the Free Software Foundation; either version 2 of the License, or\n"
220 "(at your option) any later version.\n"
221 "\n"
222 "FFmpeg is distributed in the hope that it will be useful,\n"
223 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
224 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
225 "GNU General Public License for more details.\n"
226 "\n"
227 "You should have received a copy of the GNU General Public License\n"
228 "along with FFmpeg; if not, write to the Free Software\n"
229 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
230 );
231#else
232 printf(
233 "FFmpeg is free software; you can redistribute it and/or\n"
234 "modify it under the terms of the GNU Lesser General Public\n"
235 "License as published by the Free Software Foundation; either\n"
236 "version 2.1 of the License, or (at your option) any later version.\n"
237 "\n"
238 "FFmpeg is distributed in the hope that it will be useful,\n"
239 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
240 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
241 "Lesser General Public License for more details.\n"
242 "\n"
243 "You should have received a copy of the GNU Lesser General Public\n"
244 "License along with FFmpeg; if not, write to the Free Software\n"
245 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
246 );
247#endif
248}