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
47const char **opt_names;
48static int opt_name_count;
49AVCodecContext *avctx_opts[CODEC_TYPE_NB];
50AVFormatContext *avformat_opts;
51struct SwsContext *sws_opts;
52
53const int this_year = 2009;
54
55double 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
72int64_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
83void 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
106static 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
115void 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            if (opt[1] == '-' && opt[2] == '\0') {
129                handleoptions = 0;
130                continue;
131            }
132            po= find_option(options, opt + 1);
133            if (!po->name)
134                po= find_option(options, "default");
135            if (!po->name) {
136unknown_opt:
137                fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
138                exit(1);
139            }
140            arg = NULL;
141            if (po->flags & HAS_ARG) {
142                arg = argv[optindex++];
143                if (!arg) {
144                    fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
145                    exit(1);
146                }
147            }
148            if (po->flags & OPT_STRING) {
149                char *str;
150                str = av_strdup(arg);
151                *po->u.str_arg = str;
152            } else if (po->flags & OPT_BOOL) {
153                *po->u.int_arg = 1;
154            } else if (po->flags & OPT_INT) {
155                *po->u.int_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT_MIN, INT_MAX);
156            } else if (po->flags & OPT_INT64) {
157                *po->u.int64_arg = parse_number_or_die(opt+1, arg, OPT_INT64, INT64_MIN, INT64_MAX);
158            } else if (po->flags & OPT_FLOAT) {
159                *po->u.float_arg = parse_number_or_die(opt+1, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
160            } else if (po->flags & OPT_FUNC2) {
161                if(po->u.func2_arg(opt+1, arg)<0)
162                    goto unknown_opt;
163            } else {
164                po->u.func_arg(arg);
165            }
166            if(po->flags & OPT_EXIT)
167                exit(0);
168        } else {
169            if (parse_arg_function)
170                parse_arg_function(opt);
171        }
172    }
173}
174
175int opt_default(const char *opt, const char *arg){
176    int type;
177    int ret= 0;
178    const AVOption *o= NULL;
179    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
180
181    for(type=0; type<CODEC_TYPE_NB && ret>= 0; type++){
182        const AVOption *o2 = av_find_opt(avctx_opts[0], opt, NULL, opt_types[type], opt_types[type]);
183        if(o2)
184            ret = av_set_string3(avctx_opts[type], opt, arg, 1, &o);
185    }
186    if(!o)
187        ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
188    if(!o)
189        ret = av_set_string3(sws_opts, opt, arg, 1, &o);
190    if(!o){
191        if(opt[0] == 'a')
192            ret = av_set_string3(avctx_opts[CODEC_TYPE_AUDIO], opt+1, arg, 1, &o);
193        else if(opt[0] == 'v')
194            ret = av_set_string3(avctx_opts[CODEC_TYPE_VIDEO], opt+1, arg, 1, &o);
195        else if(opt[0] == 's')
196            ret = av_set_string3(avctx_opts[CODEC_TYPE_SUBTITLE], opt+1, arg, 1, &o);
197    }
198    if (o && ret < 0) {
199        fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
200        exit(1);
201    }
202    if(!o)
203        return -1;
204
205//    av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avctx_opts, opt, NULL), (int)av_get_int(avctx_opts, opt, NULL));
206
207    //FIXME we should always use avctx_opts, ... for storing options so there will not be any need to keep track of what i set over this
208    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
209    opt_names[opt_name_count++]= o->name;
210
211    if(avctx_opts[0]->debug || avformat_opts->debug)
212        av_log_set_level(AV_LOG_DEBUG);
213    return 0;
214}
215
216void set_context_opts(void *ctx, void *opts_ctx, int flags)
217{
218    int i;
219    for(i=0; i<opt_name_count; i++){
220        char buf[256];
221        const AVOption *opt;
222        const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
223        /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
224        if(str && ((opt->flags & flags) == flags))
225            av_set_string3(ctx, opt_names[i], str, 1, NULL);
226    }
227}
228
229void print_error(const char *filename, int err)
230{
231    switch(err) {
232    case AVERROR_NUMEXPECTED:
233        fprintf(stderr, "%s: Incorrect image filename syntax.\n"
234                "Use '%%d' to specify the image number:\n"
235                "  for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
236                "  for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
237                filename);
238        break;
239    case AVERROR_INVALIDDATA:
240        fprintf(stderr, "%s: Error while parsing header\n", filename);
241        break;
242    case AVERROR_NOFMT:
243        fprintf(stderr, "%s: Unknown format\n", filename);
244        break;
245    case AVERROR(EIO):
246        fprintf(stderr, "%s: I/O error occurred\n"
247                "Usually that means that input file is truncated and/or corrupted.\n",
248                filename);
249        break;
250    case AVERROR(ENOMEM):
251        fprintf(stderr, "%s: memory allocation error occurred\n", filename);
252        break;
253    case AVERROR(ENOENT):
254        fprintf(stderr, "%s: no such file or directory\n", filename);
255        break;
256#if CONFIG_NETWORK
257    case AVERROR(FF_NETERROR(EPROTONOSUPPORT)):
258        fprintf(stderr, "%s: Unsupported network protocol\n", filename);
259        break;
260#endif
261    default:
262        fprintf(stderr, "%s: Error while opening file\n", filename);
263        break;
264    }
265}
266
267#define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \
268    version= libname##_version(); \
269    fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n", indent? "  " : "", #libname, \
270            LIB##LIBNAME##_VERSION_MAJOR, LIB##LIBNAME##_VERSION_MINOR, LIB##LIBNAME##_VERSION_MICRO, \
271            version >> 16, version >> 8 & 0xff, version & 0xff);
272
273static void print_all_lib_versions(FILE* outstream, int indent)
274{
275    unsigned int version;
276    PRINT_LIB_VERSION(outstream, avutil,   AVUTIL,   indent);
277    PRINT_LIB_VERSION(outstream, avcodec,  AVCODEC,  indent);
278    PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
279    PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
280#if CONFIG_AVFILTER
281    PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
282#endif
283#if CONFIG_SWSCALE
284    PRINT_LIB_VERSION(outstream, swscale,  SWSCALE,  indent);
285#endif
286#if CONFIG_POSTPROC
287    PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent);
288#endif
289}
290
291void show_banner(void)
292{
293    fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d Fabrice Bellard, et al.\n",
294            program_name, program_birth_year, this_year);
295    fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
296    print_all_lib_versions(stderr, 1);
297    fprintf(stderr, "  built on " __DATE__ " " __TIME__);
298#ifdef __GNUC__
299    fprintf(stderr, ", gcc: " __VERSION__ "\n");
300#else
301    fprintf(stderr, ", using a non-gcc compiler\n");
302#endif
303}
304
305void show_version(void) {
306    printf("%s " FFMPEG_VERSION "\n", program_name);
307    print_all_lib_versions(stdout, 0);
308}
309
310void show_license(void)
311{
312    printf(
313#if CONFIG_NONFREE
314    "This version of %s has nonfree parts compiled in.\n"
315    "Therefore it is not legally redistributable.\n",
316    program_name
317#elif CONFIG_GPLV3
318    "%s is free software; you can redistribute it and/or modify\n"
319    "it under the terms of the GNU General Public License as published by\n"
320    "the Free Software Foundation; either version 3 of the License, or\n"
321    "(at your option) any later version.\n"
322    "\n"
323    "%s is distributed in the hope that it will be useful,\n"
324    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
325    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
326    "GNU General Public License for more details.\n"
327    "\n"
328    "You should have received a copy of the GNU General Public License\n"
329    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
330    program_name, program_name, program_name
331#elif CONFIG_GPL
332    "%s is free software; you can redistribute it and/or modify\n"
333    "it under the terms of the GNU General Public License as published by\n"
334    "the Free Software Foundation; either version 2 of the License, or\n"
335    "(at your option) any later version.\n"
336    "\n"
337    "%s is distributed in the hope that it will be useful,\n"
338    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
339    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
340    "GNU General Public License for more details.\n"
341    "\n"
342    "You should have received a copy of the GNU General Public License\n"
343    "along with %s; if not, write to the Free Software\n"
344    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
345    program_name, program_name, program_name
346#elif CONFIG_LGPLV3
347    "%s is free software; you can redistribute it and/or modify\n"
348    "it under the terms of the GNU Lesser General Public License as published by\n"
349    "the Free Software Foundation; either version 3 of the License, or\n"
350    "(at your option) any later version.\n"
351    "\n"
352    "%s is distributed in the hope that it will be useful,\n"
353    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
354    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
355    "GNU Lesser General Public License for more details.\n"
356    "\n"
357    "You should have received a copy of the GNU Lesser General Public License\n"
358    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
359    program_name, program_name, program_name
360#else
361    "%s is free software; you can redistribute it and/or\n"
362    "modify it under the terms of the GNU Lesser General Public\n"
363    "License as published by the Free Software Foundation; either\n"
364    "version 2.1 of the License, or (at your option) any later version.\n"
365    "\n"
366    "%s is distributed in the hope that it will be useful,\n"
367    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
368    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
369    "Lesser General Public License for more details.\n"
370    "\n"
371    "You should have received a copy of the GNU Lesser General Public\n"
372    "License along with %s; if not, write to the Free Software\n"
373    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
374    program_name, program_name, program_name
375#endif
376    );
377}
378
379void show_formats(void)
380{
381    AVInputFormat *ifmt=NULL;
382    AVOutputFormat *ofmt=NULL;
383    URLProtocol *up=NULL;
384    AVCodec *p=NULL, *p2;
385    AVBitStreamFilter *bsf=NULL;
386    const char *last_name;
387
388    printf("File formats:\n");
389    last_name= "000";
390    for(;;){
391        int decode=0;
392        int encode=0;
393        const char *name=NULL;
394        const char *long_name=NULL;
395
396        while((ofmt= av_oformat_next(ofmt))) {
397            if((name == NULL || strcmp(ofmt->name, name)<0) &&
398                strcmp(ofmt->name, last_name)>0){
399                name= ofmt->name;
400                long_name= ofmt->long_name;
401                encode=1;
402            }
403        }
404        while((ifmt= av_iformat_next(ifmt))) {
405            if((name == NULL || strcmp(ifmt->name, name)<0) &&
406                strcmp(ifmt->name, last_name)>0){
407                name= ifmt->name;
408                long_name= ifmt->long_name;
409                encode=0;
410            }
411            if(name && strcmp(ifmt->name, name)==0)
412                decode=1;
413        }
414        if(name==NULL)
415            break;
416        last_name= name;
417
418        printf(
419            " %s%s %-15s %s\n",
420            decode ? "D":" ",
421            encode ? "E":" ",
422            name,
423            long_name ? long_name:" ");
424    }
425    printf("\n");
426
427    printf("Codecs:\n");
428    last_name= "000";
429    for(;;){
430        int decode=0;
431        int encode=0;
432        int cap=0;
433        const char *type_str;
434
435        p2=NULL;
436        while((p= av_codec_next(p))) {
437            if((p2==NULL || strcmp(p->name, p2->name)<0) &&
438                strcmp(p->name, last_name)>0){
439                p2= p;
440                decode= encode= cap=0;
441            }
442            if(p2 && strcmp(p->name, p2->name)==0){
443                if(p->decode) decode=1;
444                if(p->encode) encode=1;
445                cap |= p->capabilities;
446            }
447        }
448        if(p2==NULL)
449            break;
450        last_name= p2->name;
451
452        switch(p2->type) {
453        case CODEC_TYPE_VIDEO:
454            type_str = "V";
455            break;
456        case CODEC_TYPE_AUDIO:
457            type_str = "A";
458            break;
459        case CODEC_TYPE_SUBTITLE:
460            type_str = "S";
461            break;
462        default:
463            type_str = "?";
464            break;
465        }
466        printf(
467            " %s%s%s%s%s%s %-15s %s",
468            decode ? "D": (/*p2->decoder ? "d":*/" "),
469            encode ? "E":" ",
470            type_str,
471            cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
472            cap & CODEC_CAP_DR1 ? "D":" ",
473            cap & CODEC_CAP_TRUNCATED ? "T":" ",
474            p2->name,
475            p2->long_name ? p2->long_name : "");
476       /* if(p2->decoder && decode==0)
477            printf(" use %s for decoding", p2->decoder->name);*/
478        printf("\n");
479    }
480    printf("\n");
481
482    printf("Bitstream filters:\n");
483    while((bsf = av_bitstream_filter_next(bsf)))
484        printf(" %s", bsf->name);
485    printf("\n");
486
487    printf("Supported file protocols:\n");
488    while((up = av_protocol_next(up)))
489        printf(" %s:", up->name);
490    printf("\n");
491
492    printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
493    printf("\n");
494    printf(
495"Note, the names of encoders and decoders do not always match, so there are\n"
496"several cases where the above table shows encoder only or decoder only entries\n"
497"even though both encoding and decoding are supported. For example, the h263\n"
498"decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
499"worse.\n");
500}
501