2904ca953db1c785a65046770230afa5ef724708
[ffmpeg.git] / cmdutils.c
1 /*
2  * Various utilities for command line tools
3  * Copyright (c) 2000-2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
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
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
20  */
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <math.h>
26
27 #include "config.h"
28 #include "libavformat/avformat.h"
29 #include "libavfilter/avfilter.h"
30 #include "libavdevice/avdevice.h"
31 #include "libavutil/avstring.h"
32 #include "cmdutils.h"
33 #include "version.h"
34 #ifdef CONFIG_NETWORK
35 #include "libavformat/network.h"
36 #endif
37
38 #undef exit
39
40
41 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
42 {
43     char *tail;
44     const char *error;
45     double d = strtod(numstr, &tail);
46     if (*tail)
47         error= "Expected number for %s but found: %s\n";
48     else if (d < min || d > max)
49         error= "The value for %s was %s which is not within %f - %f\n";
50     else if(type == OPT_INT64 && (int64_t)d != d)
51         error= "Expected int64 for %s but found %s\n";
52     else
53         return d;
54     fprintf(stderr, error, context, numstr, min, max);
55     exit(1);
56 }
57
58 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
59 {
60     int64_t us = parse_date(timestr, is_duration);
61     if (us == INT64_MIN) {
62         fprintf(stderr, "Invalid %s specification for %s: %s\n",
63                 is_duration ? "duration" : "date", context, timestr);
64         exit(1);
65     }
66     return us;
67 }
68
69 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
70 {
71     const OptionDef *po;
72     int first;
73
74     first = 1;
75     for(po = options; po->name != NULL; po++) {
76         char buf[64];
77         if ((po->flags & mask) == value) {
78             if (first) {
79                 printf("%s", msg);
80                 first = 0;
81             }
82             av_strlcpy(buf, po->name, sizeof(buf));
83             if (po->flags & HAS_ARG) {
84                 av_strlcat(buf, " ", sizeof(buf));
85                 av_strlcat(buf, po->argname, sizeof(buf));
86             }
87             printf("-%-17s  %s\n", buf, po->help);
88         }
89     }
90 }
91
92 static const OptionDef* find_option(const OptionDef *po, const char *name){
93     while (po->name != NULL) {
94         if (!strcmp(name, po->name))
95             break;
96         po++;
97     }
98     return po;
99 }
100
101 void parse_options(int argc, char **argv, const OptionDef *options,
102                    void (* parse_arg_function)(const char*))
103 {
104     const char *opt, *arg;
105     int optindex, handleoptions=1;
106     const OptionDef *po;
107
108     /* parse options */
109     optindex = 1;
110     while (optindex < argc) {
111         opt = argv[optindex++];
112
113         if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
114           if (opt[1] == '-' && opt[2] == '\0') {
115             handleoptions = 0;
116             continue;
117           }
118             po= find_option(options, opt + 1);
119             if (!po->name)
120                 po= find_option(options, "default");
121             if (!po->name) {
122 unknown_opt:
123                 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
124                 exit(1);
125             }
126             arg = NULL;
127             if (po->flags & HAS_ARG) {
128                 arg = argv[optindex++];
129                 if (!arg) {
130                     fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
131                     exit(1);
132                 }
133             }
134             if (po->flags & OPT_STRING) {
135                 char *str;
136                 str = av_strdup(arg);
137                 *po->u.str_arg = str;
138             } else if (po->flags & OPT_BOOL) {
139                 *po->u.int_arg = 1;
140             } else if (po->flags & OPT_INT) {
141                 *po->u.int_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT_MIN, INT_MAX);
142             } else if (po->flags & OPT_INT64) {
143                 *po->u.int64_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT64_MIN, INT64_MAX);
144             } else if (po->flags & OPT_FLOAT) {
145                 *po->u.float_arg = parse_number_or_die(opt+1, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
146             } else if (po->flags & OPT_FUNC2) {
147                 if(po->u.func2_arg(opt+1, arg)<0)
148                     goto unknown_opt;
149             } else {
150                 po->u.func_arg(arg);
151             }
152             if(po->flags & OPT_EXIT)
153                 exit(0);
154         } else {
155             if (parse_arg_function)
156                 parse_arg_function(opt);
157         }
158     }
159 }
160
161 void print_error(const char *filename, int err)
162 {
163     switch(err) {
164     case AVERROR_NUMEXPECTED:
165         fprintf(stderr, "%s: Incorrect image filename syntax.\n"
166                 "Use '%%d' to specify the image number:\n"
167                 "  for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
168                 "  for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
169                 filename);
170         break;
171     case AVERROR_INVALIDDATA:
172         fprintf(stderr, "%s: Error while parsing header\n", filename);
173         break;
174     case AVERROR_NOFMT:
175         fprintf(stderr, "%s: Unknown format\n", filename);
176         break;
177     case AVERROR(EIO):
178         fprintf(stderr, "%s: I/O error occurred\n"
179                 "Usually that means that input file is truncated and/or corrupted.\n",
180                 filename);
181         break;
182     case AVERROR(ENOMEM):
183         fprintf(stderr, "%s: memory allocation error occurred\n", filename);
184         break;
185     case AVERROR(ENOENT):
186         fprintf(stderr, "%s: no such file or directory\n", filename);
187         break;
188 #ifdef CONFIG_NETWORK
189     case AVERROR(FF_NETERROR(EPROTONOSUPPORT)):
190         fprintf(stderr, "%s: Unsupported network protocol\n", filename);
191         break;
192 #endif
193     default:
194         fprintf(stderr, "%s: Error while opening file\n", filename);
195         break;
196     }
197 }
198
199 #define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \
200     version= libname##_version(); \
201     fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n", indent? "  " : "", #libname, \
202             LIB##LIBNAME##_VERSION_MAJOR, LIB##LIBNAME##_VERSION_MINOR, LIB##LIBNAME##_VERSION_MICRO, \
203             version >> 16, version >> 8 & 0xff, version & 0xff);
204
205 void print_all_lib_versions(FILE* outstream, int indent)
206 {
207     unsigned int version;
208     PRINT_LIB_VERSION(outstream, avutil, AVUTIL, indent);
209     PRINT_LIB_VERSION(outstream, avcodec, AVCODEC, indent);
210     PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
211     PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
212 #if ENABLE_AVFILTER
213     PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
214 #endif
215 }
216
217 void show_banner(void)
218 {
219     fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-2008 Fabrice Bellard, et al.\n",
220             program_name, program_birth_year);
221     fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
222     print_all_lib_versions(stderr, 1);
223     fprintf(stderr, "  built on " __DATE__ " " __TIME__);
224 #ifdef __GNUC__
225     fprintf(stderr, ", gcc: " __VERSION__ "\n");
226 #else
227     fprintf(stderr, ", using a non-gcc compiler\n");
228 #endif
229 }
230
231 void show_version(void) {
232     printf("%s " FFMPEG_VERSION "\n", program_name);
233     print_all_lib_versions(stdout, 0);
234 }
235
236 void show_license(void)
237 {
238 #ifdef CONFIG_NONFREE
239     printf(
240     "This version of %s has nonfree parts compiled in.\n"
241     "Therefore it is not legally redistributable.\n",
242     program_name
243     );
244 #elif CONFIG_GPL
245     printf(
246     "%s is free software; you can redistribute it and/or modify\n"
247     "it under the terms of the GNU General Public License as published by\n"
248     "the Free Software Foundation; either version 2 of the License, or\n"
249     "(at your option) any later version.\n"
250     "\n"
251     "%s is distributed in the hope that it will be useful,\n"
252     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
253     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
254     "GNU General Public License for more details.\n"
255     "\n"
256     "You should have received a copy of the GNU General Public License\n"
257     "along with %s; if not, write to the Free Software\n"
258     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
259     program_name, program_name, program_name
260     );
261 #else
262     printf(
263     "%s is free software; you can redistribute it and/or\n"
264     "modify it under the terms of the GNU Lesser General Public\n"
265     "License as published by the Free Software Foundation; either\n"
266     "version 2.1 of the License, or (at your option) any later version.\n"
267     "\n"
268     "%s is distributed in the hope that it will be useful,\n"
269     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
270     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
271     "Lesser General Public License for more details.\n"
272     "\n"
273     "You should have received a copy of the GNU Lesser General Public\n"
274     "License along with %s; if not, write to the Free Software\n"
275     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
276     program_name, program_name, program_name
277     );
278 #endif
279 }
280
281 void show_formats(void)
282 {
283     AVInputFormat *ifmt=NULL;
284     AVOutputFormat *ofmt=NULL;
285     URLProtocol *up=NULL;
286     AVCodec *p=NULL, *p2;
287     AVBitStreamFilter *bsf=NULL;
288     const char *last_name;
289
290     printf("File formats:\n");
291     last_name= "000";
292     for(;;){
293         int decode=0;
294         int encode=0;
295         const char *name=NULL;
296         const char *long_name=NULL;
297
298         while((ofmt= av_oformat_next(ofmt))) {
299             if((name == NULL || strcmp(ofmt->name, name)<0) &&
300                 strcmp(ofmt->name, last_name)>0){
301                 name= ofmt->name;
302                 long_name= ofmt->long_name;
303                 encode=1;
304             }
305         }
306         while((ifmt= av_iformat_next(ifmt))) {
307             if((name == NULL || strcmp(ifmt->name, name)<0) &&
308                 strcmp(ifmt->name, last_name)>0){
309                 name= ifmt->name;
310                 long_name= ifmt->long_name;
311                 encode=0;
312             }
313             if(name && strcmp(ifmt->name, name)==0)
314                 decode=1;
315         }
316         if(name==NULL)
317             break;
318         last_name= name;
319
320         printf(
321             " %s%s %-15s %s\n",
322             decode ? "D":" ",
323             encode ? "E":" ",
324             name,
325             long_name ? long_name:" ");
326     }
327     printf("\n");
328
329     printf("Codecs:\n");
330     last_name= "000";
331     for(;;){
332         int decode=0;
333         int encode=0;
334         int cap=0;
335         const char *type_str;
336
337         p2=NULL;
338         while((p= av_codec_next(p))) {
339             if((p2==NULL || strcmp(p->name, p2->name)<0) &&
340                 strcmp(p->name, last_name)>0){
341                 p2= p;
342                 decode= encode= cap=0;
343             }
344             if(p2 && strcmp(p->name, p2->name)==0){
345                 if(p->decode) decode=1;
346                 if(p->encode) encode=1;
347                 cap |= p->capabilities;
348             }
349         }
350         if(p2==NULL)
351             break;
352         last_name= p2->name;
353
354         switch(p2->type) {
355         case CODEC_TYPE_VIDEO:
356             type_str = "V";
357             break;
358         case CODEC_TYPE_AUDIO:
359             type_str = "A";
360             break;
361         case CODEC_TYPE_SUBTITLE:
362             type_str = "S";
363             break;
364         default:
365             type_str = "?";
366             break;
367         }
368         printf(
369             " %s%s%s%s%s%s %-15s %s",
370             decode ? "D": (/*p2->decoder ? "d":*/" "),
371             encode ? "E":" ",
372             type_str,
373             cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
374             cap & CODEC_CAP_DR1 ? "D":" ",
375             cap & CODEC_CAP_TRUNCATED ? "T":" ",
376             p2->name,
377             p2->long_name ? p2->long_name : "");
378        /* if(p2->decoder && decode==0)
379             printf(" use %s for decoding", p2->decoder->name);*/
380         printf("\n");
381     }
382     printf("\n");
383
384     printf("Bitstream filters:\n");
385     while((bsf = av_bitstream_filter_next(bsf)))
386         printf(" %s", bsf->name);
387     printf("\n");
388
389     printf("Supported file protocols:\n");
390     while((up = av_protocol_next(up)))
391         printf(" %s:", up->name);
392     printf("\n");
393
394     printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
395     printf("\n");
396     printf(
397 "Note, the names of encoders and decoders do not always match, so there are\n"
398 "several cases where the above table shows encoder only or decoder only entries\n"
399 "even though both encoding and decoding are supported. For example, the h263\n"
400 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
401 "worse.\n");
402 }