OSDN Git Service

Factorize opt+1 out in parse_options(), simplify.
[coroid/libav_saccubus.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 only the enabled headers since some compilers (namely, Sun
28    Studio) will not omit unused inline functions and create undefined
29    references to libraries that are not being built. */
30
31 #include "config.h"
32 #include "libavformat/avformat.h"
33 #include "libavfilter/avfilter.h"
34 #include "libavdevice/avdevice.h"
35 #include "libswscale/swscale.h"
36 #include "libpostproc/postprocess.h"
37 #include "libavutil/avstring.h"
38 #include "libavcodec/opt.h"
39 #include "cmdutils.h"
40 #include "version.h"
41 #if CONFIG_NETWORK
42 #include "libavformat/network.h"
43 #endif
44
45 #undef exit
46
47 const char **opt_names;
48 static int opt_name_count;
49 AVCodecContext *avcodec_opts[CODEC_TYPE_NB];
50 AVFormatContext *avformat_opts;
51 struct SwsContext *sws_opts;
52
53 const int this_year = 2009;
54
55 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
56 {
57     char *tail;
58     const char *error;
59     double d = strtod(numstr, &tail);
60     if (*tail)
61         error= "Expected number for %s but found: %s\n";
62     else if (d < min || d > max)
63         error= "The value for %s was %s which is not within %f - %f\n";
64     else if(type == OPT_INT64 && (int64_t)d != d)
65         error= "Expected int64 for %s but found %s\n";
66     else
67         return d;
68     fprintf(stderr, error, context, numstr, min, max);
69     exit(1);
70 }
71
72 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
73 {
74     int64_t us = parse_date(timestr, is_duration);
75     if (us == INT64_MIN) {
76         fprintf(stderr, "Invalid %s specification for %s: %s\n",
77                 is_duration ? "duration" : "date", context, timestr);
78         exit(1);
79     }
80     return us;
81 }
82
83 void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
84 {
85     const OptionDef *po;
86     int first;
87
88     first = 1;
89     for(po = options; po->name != NULL; po++) {
90         char buf[64];
91         if ((po->flags & mask) == value) {
92             if (first) {
93                 printf("%s", msg);
94                 first = 0;
95             }
96             av_strlcpy(buf, po->name, sizeof(buf));
97             if (po->flags & HAS_ARG) {
98                 av_strlcat(buf, " ", sizeof(buf));
99                 av_strlcat(buf, po->argname, sizeof(buf));
100             }
101             printf("-%-17s  %s\n", buf, po->help);
102         }
103     }
104 }
105
106 static const OptionDef* find_option(const OptionDef *po, const char *name){
107     while (po->name != NULL) {
108         if (!strcmp(name, po->name))
109             break;
110         po++;
111     }
112     return po;
113 }
114
115 void parse_options(int argc, char **argv, const OptionDef *options,
116                    void (* parse_arg_function)(const char*))
117 {
118     const char *opt, *arg;
119     int optindex, handleoptions=1;
120     const OptionDef *po;
121
122     /* parse options */
123     optindex = 1;
124     while (optindex < argc) {
125         opt = argv[optindex++];
126
127         if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
128             int bool_val = 1;
129             if (opt[1] == '-' && opt[2] == '\0') {
130                 handleoptions = 0;
131                 continue;
132             }
133             opt++;
134             po= find_option(options, opt);
135             if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
136                 /* handle 'no' bool option */
137                 po = find_option(options, opt + 2);
138                 if (!(po->name && (po->flags & OPT_BOOL)))
139                     goto unknown_opt;
140                 bool_val = 0;
141             }
142             if (!po->name)
143                 po= find_option(options, "default");
144             if (!po->name) {
145 unknown_opt:
146                 fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
147                 exit(1);
148             }
149             arg = NULL;
150             if (po->flags & HAS_ARG) {
151                 arg = argv[optindex++];
152                 if (!arg) {
153                     fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
154                     exit(1);
155                 }
156             }
157             if (po->flags & OPT_STRING) {
158                 char *str;
159                 str = av_strdup(arg);
160                 *po->u.str_arg = str;
161             } else if (po->flags & OPT_BOOL) {
162                 *po->u.int_arg = bool_val;
163             } else if (po->flags & OPT_INT) {
164                 *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
165             } else if (po->flags & OPT_INT64) {
166                 *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
167             } else if (po->flags & OPT_FLOAT) {
168                 *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
169             } else if (po->flags & OPT_FUNC2) {
170                 if(po->u.func2_arg(opt, arg)<0)
171                     goto unknown_opt;
172             } else {
173                 po->u.func_arg(arg);
174             }
175             if(po->flags & OPT_EXIT)
176                 exit(0);
177         } else {
178             if (parse_arg_function)
179                 parse_arg_function(opt);
180         }
181     }
182 }
183
184 int opt_default(const char *opt, const char *arg){
185     int type;
186     int ret= 0;
187     const AVOption *o= NULL;
188     int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
189
190     for(type=0; type<CODEC_TYPE_NB && ret>= 0; type++){
191         const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
192         if(o2)
193             ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
194     }
195     if(!o)
196         ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
197     if(!o)
198         ret = av_set_string3(sws_opts, opt, arg, 1, &o);
199     if(!o){
200         if(opt[0] == 'a')
201             ret = av_set_string3(avcodec_opts[CODEC_TYPE_AUDIO], opt+1, arg, 1, &o);
202         else if(opt[0] == 'v')
203             ret = av_set_string3(avcodec_opts[CODEC_TYPE_VIDEO], opt+1, arg, 1, &o);
204         else if(opt[0] == 's')
205             ret = av_set_string3(avcodec_opts[CODEC_TYPE_SUBTITLE], opt+1, arg, 1, &o);
206     }
207     if (o && ret < 0) {
208         fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
209         exit(1);
210     }
211     if(!o)
212         return -1;
213
214 //    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));
215
216     //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
217     opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
218     opt_names[opt_name_count++]= o->name;
219
220     if(avcodec_opts[0]->debug || avformat_opts->debug)
221         av_log_set_level(AV_LOG_DEBUG);
222     return 0;
223 }
224
225 int opt_loglevel(const char *opt, const char *arg)
226 {
227     const struct { const char *name; int level; } log_levels[] = {
228         { "quiet"  , AV_LOG_QUIET   },
229         { "panic"  , AV_LOG_PANIC   },
230         { "fatal"  , AV_LOG_FATAL   },
231         { "error"  , AV_LOG_ERROR   },
232         { "warning", AV_LOG_WARNING },
233         { "info"   , AV_LOG_INFO    },
234         { "verbose", AV_LOG_VERBOSE },
235         { "debug"  , AV_LOG_DEBUG   },
236     };
237     char *tail;
238     int level;
239     int i;
240
241     for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
242         if (!strcmp(log_levels[i].name, arg)) {
243             av_log_set_level(log_levels[i].level);
244             return 0;
245         }
246     }
247
248     level = strtol(arg, &tail, 10);
249     if (*tail) {
250         fprintf(stderr, "Invalid loglevel \"%s\". "
251                         "Possible levels are numbers or:\n", arg);
252         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
253             fprintf(stderr, "\"%s\"\n", log_levels[i].name);
254         exit(1);
255     }
256     av_log_set_level(level);
257     return 0;
258 }
259
260 void set_context_opts(void *ctx, void *opts_ctx, int flags)
261 {
262     int i;
263     for(i=0; i<opt_name_count; i++){
264         char buf[256];
265         const AVOption *opt;
266         const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
267         /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
268         if(str && ((opt->flags & flags) == flags))
269             av_set_string3(ctx, opt_names[i], str, 1, NULL);
270     }
271 }
272
273 void print_error(const char *filename, int err)
274 {
275     switch(err) {
276     case AVERROR_NUMEXPECTED:
277         fprintf(stderr, "%s: Incorrect image filename syntax.\n"
278                 "Use '%%d' to specify the image number:\n"
279                 "  for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
280                 "  for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
281                 filename);
282         break;
283     case AVERROR_INVALIDDATA:
284         fprintf(stderr, "%s: Error while parsing header\n", filename);
285         break;
286     case AVERROR_NOFMT:
287         fprintf(stderr, "%s: Unknown format\n", filename);
288         break;
289     case AVERROR(EIO):
290         fprintf(stderr, "%s: I/O error occurred\n"
291                 "Usually that means that input file is truncated and/or corrupted.\n",
292                 filename);
293         break;
294     case AVERROR(ENOMEM):
295         fprintf(stderr, "%s: memory allocation error occurred\n", filename);
296         break;
297     case AVERROR(ENOENT):
298         fprintf(stderr, "%s: no such file or directory\n", filename);
299         break;
300 #if CONFIG_NETWORK
301     case AVERROR(FF_NETERROR(EPROTONOSUPPORT)):
302         fprintf(stderr, "%s: Unsupported network protocol\n", filename);
303         break;
304 #endif
305     default:
306         fprintf(stderr, "%s: Error while opening file\n", filename);
307         break;
308     }
309 }
310
311 #define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \
312     version= libname##_version(); \
313     fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n", indent? "  " : "", #libname, \
314             LIB##LIBNAME##_VERSION_MAJOR, LIB##LIBNAME##_VERSION_MINOR, LIB##LIBNAME##_VERSION_MICRO, \
315             version >> 16, version >> 8 & 0xff, version & 0xff);
316
317 static void print_all_lib_versions(FILE* outstream, int indent)
318 {
319     unsigned int version;
320     PRINT_LIB_VERSION(outstream, avutil,   AVUTIL,   indent);
321     PRINT_LIB_VERSION(outstream, avcodec,  AVCODEC,  indent);
322     PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
323     PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
324 #if CONFIG_AVFILTER
325     PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
326 #endif
327     PRINT_LIB_VERSION(outstream, swscale,  SWSCALE,  indent);
328 #if CONFIG_POSTPROC
329     PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent);
330 #endif
331 }
332
333 void show_banner(void)
334 {
335     fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d Fabrice Bellard, et al.\n",
336             program_name, program_birth_year, this_year);
337     fprintf(stderr, "  built on %s %s with %s %s\n",
338             __DATE__, __TIME__, CC_TYPE, CC_VERSION);
339     fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
340     print_all_lib_versions(stderr, 1);
341 }
342
343 void show_version(void) {
344     printf("%s " FFMPEG_VERSION "\n", program_name);
345     print_all_lib_versions(stdout, 0);
346 }
347
348 void show_license(void)
349 {
350     printf(
351 #if CONFIG_NONFREE
352     "This version of %s has nonfree parts compiled in.\n"
353     "Therefore it is not legally redistributable.\n",
354     program_name
355 #elif CONFIG_GPLV3
356     "%s is free software; you can redistribute it and/or modify\n"
357     "it under the terms of the GNU General Public License as published by\n"
358     "the Free Software Foundation; either version 3 of the License, or\n"
359     "(at your option) any later version.\n"
360     "\n"
361     "%s is distributed in the hope that it will be useful,\n"
362     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
363     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
364     "GNU General Public License for more details.\n"
365     "\n"
366     "You should have received a copy of the GNU General Public License\n"
367     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
368     program_name, program_name, program_name
369 #elif CONFIG_GPL
370     "%s is free software; you can redistribute it and/or modify\n"
371     "it under the terms of the GNU General Public License as published by\n"
372     "the Free Software Foundation; either version 2 of the License, or\n"
373     "(at your option) any later version.\n"
374     "\n"
375     "%s is distributed in the hope that it will be useful,\n"
376     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
377     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
378     "GNU General Public License for more details.\n"
379     "\n"
380     "You should have received a copy of the GNU General Public License\n"
381     "along with %s; if not, write to the Free Software\n"
382     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
383     program_name, program_name, program_name
384 #elif CONFIG_LGPLV3
385     "%s is free software; you can redistribute it and/or modify\n"
386     "it under the terms of the GNU Lesser General Public License as published by\n"
387     "the Free Software Foundation; either version 3 of the License, or\n"
388     "(at your option) any later version.\n"
389     "\n"
390     "%s is distributed in the hope that it will be useful,\n"
391     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
392     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
393     "GNU Lesser General Public License for more details.\n"
394     "\n"
395     "You should have received a copy of the GNU Lesser General Public License\n"
396     "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
397     program_name, program_name, program_name
398 #else
399     "%s is free software; you can redistribute it and/or\n"
400     "modify it under the terms of the GNU Lesser General Public\n"
401     "License as published by the Free Software Foundation; either\n"
402     "version 2.1 of the License, or (at your option) any later version.\n"
403     "\n"
404     "%s is distributed in the hope that it will be useful,\n"
405     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
406     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
407     "Lesser General Public License for more details.\n"
408     "\n"
409     "You should have received a copy of the GNU Lesser General Public\n"
410     "License along with %s; if not, write to the Free Software\n"
411     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
412     program_name, program_name, program_name
413 #endif
414     );
415 }
416
417 void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
418 {
419     int i;
420     char fmt_str[128];
421     for (i=-1; i < nb_fmts; i++) {
422         get_fmt_string (fmt_str, sizeof(fmt_str), i);
423         fprintf(stdout, "%s\n", fmt_str);
424     }
425 }
426
427 void show_formats(void)
428 {
429     AVInputFormat *ifmt=NULL;
430     AVOutputFormat *ofmt=NULL;
431     const char *last_name;
432
433     printf(
434         "File formats:\n"
435         " D. = Demuxing supported\n"
436         " .E = Muxing supported\n"
437         " --\n");
438     last_name= "000";
439     for(;;){
440         int decode=0;
441         int encode=0;
442         const char *name=NULL;
443         const char *long_name=NULL;
444
445         while((ofmt= av_oformat_next(ofmt))) {
446             if((name == NULL || strcmp(ofmt->name, name)<0) &&
447                 strcmp(ofmt->name, last_name)>0){
448                 name= ofmt->name;
449                 long_name= ofmt->long_name;
450                 encode=1;
451             }
452         }
453         while((ifmt= av_iformat_next(ifmt))) {
454             if((name == NULL || strcmp(ifmt->name, name)<0) &&
455                 strcmp(ifmt->name, last_name)>0){
456                 name= ifmt->name;
457                 long_name= ifmt->long_name;
458                 encode=0;
459             }
460             if(name && strcmp(ifmt->name, name)==0)
461                 decode=1;
462         }
463         if(name==NULL)
464             break;
465         last_name= name;
466
467         printf(
468             " %s%s %-15s %s\n",
469             decode ? "D":" ",
470             encode ? "E":" ",
471             name,
472             long_name ? long_name:" ");
473     }
474 }
475
476 void show_codecs(void)
477 {
478     AVCodec *p=NULL, *p2;
479     const char *last_name;
480     printf(
481         "Codecs:\n"
482         " D..... = Decoding supported\n"
483         " .E.... = Encoding supported\n"
484         " ..V... = Video codec\n"
485         " ..A... = Audio codec\n"
486         " ..S... = Subtitle codec\n"
487         " ...S.. = Supports draw_horiz_band\n"
488         " ....D. = Supports direct rendering method 1\n"
489         " .....T = Supports weird frame truncation\n"
490         " ------\n");
491     last_name= "000";
492     for(;;){
493         int decode=0;
494         int encode=0;
495         int cap=0;
496         const char *type_str;
497
498         p2=NULL;
499         while((p= av_codec_next(p))) {
500             if((p2==NULL || strcmp(p->name, p2->name)<0) &&
501                 strcmp(p->name, last_name)>0){
502                 p2= p;
503                 decode= encode= cap=0;
504             }
505             if(p2 && strcmp(p->name, p2->name)==0){
506                 if(p->decode) decode=1;
507                 if(p->encode) encode=1;
508                 cap |= p->capabilities;
509             }
510         }
511         if(p2==NULL)
512             break;
513         last_name= p2->name;
514
515         switch(p2->type) {
516         case CODEC_TYPE_VIDEO:
517             type_str = "V";
518             break;
519         case CODEC_TYPE_AUDIO:
520             type_str = "A";
521             break;
522         case CODEC_TYPE_SUBTITLE:
523             type_str = "S";
524             break;
525         default:
526             type_str = "?";
527             break;
528         }
529         printf(
530             " %s%s%s%s%s%s %-15s %s",
531             decode ? "D": (/*p2->decoder ? "d":*/" "),
532             encode ? "E":" ",
533             type_str,
534             cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
535             cap & CODEC_CAP_DR1 ? "D":" ",
536             cap & CODEC_CAP_TRUNCATED ? "T":" ",
537             p2->name,
538             p2->long_name ? p2->long_name : "");
539        /* if(p2->decoder && decode==0)
540             printf(" use %s for decoding", p2->decoder->name);*/
541         printf("\n");
542     }
543     printf("\n");
544     printf(
545 "Note, the names of encoders and decoders do not always match, so there are\n"
546 "several cases where the above table shows encoder only or decoder only entries\n"
547 "even though both encoding and decoding are supported. For example, the h263\n"
548 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
549 "worse.\n");
550 }
551
552 void show_bsfs(void)
553 {
554     AVBitStreamFilter *bsf=NULL;
555
556     printf("Bitstream filters:\n");
557     while((bsf = av_bitstream_filter_next(bsf)))
558         printf("%s\n", bsf->name);
559     printf("\n");
560 }
561
562 void show_protocols(void)
563 {
564     URLProtocol *up=NULL;
565
566     printf("Supported file protocols:\n");
567     while((up = av_protocol_next(up)))
568         printf("%s\n", up->name);
569     printf("\n");
570
571     printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
572 }
573
574 void show_filters(void)
575 {
576     AVFilter **filter = NULL;
577
578     printf("Filters:\n");
579 #if CONFIG_AVFILTER
580     while ((filter = av_filter_next(filter)) && *filter)
581         printf("%-16s %s\n", (*filter)->name, (*filter)->description);
582 #endif
583 }
584
585 int read_yesno(void)
586 {
587     int c = getchar();
588     int yesno = (toupper(c) == 'Y');
589
590     while (c != '\n' && c != EOF)
591         c = getchar();
592
593     return yesno;
594 }