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