cmdutils.c 20.9 KB
Newer Older
Fabrice Bellard's avatar
Fabrice Bellard committed
1 2 3 4
/*
 * Various utilities for command line tools
 * Copyright (c) 2000-2003 Fabrice Bellard
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
Fabrice Bellard's avatar
Fabrice Bellard committed
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
Fabrice Bellard committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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
Fabrice Bellard's avatar
Fabrice Bellard committed
20
 */
21

22 23 24
#include <string.h>
#include <stdlib.h>
#include <errno.h>
25
#include <math.h>
26

27 28 29 30
/* Include only the enabled headers since some compilers (namely, Sun
   Studio) will not omit unused inline functions and create undefined
   references to libraries that are not being built. */

31
#include "config.h"
32 33 34
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
#include "libavdevice/avdevice.h"
35
#include "libswscale/swscale.h"
36
#include "libpostproc/postprocess.h"
37
#include "libavutil/avstring.h"
38
#include "libavcodec/opt.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
39
#include "cmdutils.h"
40
#include "version.h"
Ramiro Polla's avatar
Ramiro Polla committed
41
#if CONFIG_NETWORK
42
#include "libavformat/network.h"
Ramiro Polla's avatar
Ramiro Polla committed
43
#endif
Måns Rullgård's avatar
Måns Rullgård committed
44 45 46
#if HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
Fabrice Bellard's avatar
Fabrice Bellard committed
47

Michael Niedermayer's avatar
Michael Niedermayer committed
48 49
#undef exit

50 51
const char **opt_names;
static int opt_name_count;
52
AVCodecContext *avcodec_opts[CODEC_TYPE_NB];
53 54
AVFormatContext *avformat_opts;
struct SwsContext *sws_opts;
Michael Niedermayer's avatar
Michael Niedermayer committed
55

Stefano Sabatini's avatar
Stefano Sabatini committed
56
const int this_year = 2010;
57

Michael Niedermayer's avatar
Michael Niedermayer committed
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
{
    char *tail;
    const char *error;
    double d = strtod(numstr, &tail);
    if (*tail)
        error= "Expected number for %s but found: %s\n";
    else if (d < min || d > max)
        error= "The value for %s was %s which is not within %f - %f\n";
    else if(type == OPT_INT64 && (int64_t)d != d)
        error= "Expected int64 for %s but found %s\n";
    else
        return d;
    fprintf(stderr, error, context, numstr, min, max);
    exit(1);
}

75 76 77 78 79 80 81 82 83 84 85
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
{
    int64_t us = parse_date(timestr, is_duration);
    if (us == INT64_MIN) {
        fprintf(stderr, "Invalid %s specification for %s: %s\n",
                is_duration ? "duration" : "date", context, timestr);
        exit(1);
    }
    return us;
}

86
void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
Fabrice Bellard's avatar
Fabrice Bellard committed
87 88
{
    const OptionDef *po;
89
    int first;
Fabrice Bellard's avatar
Fabrice Bellard committed
90

91 92 93 94 95 96 97 98
    first = 1;
    for(po = options; po->name != NULL; po++) {
        char buf[64];
        if ((po->flags & mask) == value) {
            if (first) {
                printf("%s", msg);
                first = 0;
            }
99
            av_strlcpy(buf, po->name, sizeof(buf));
100
            if (po->flags & HAS_ARG) {
101 102
                av_strlcat(buf, " ", sizeof(buf));
                av_strlcat(buf, po->argname, sizeof(buf));
Fabrice Bellard's avatar
Fabrice Bellard committed
103
            }
104
            printf("-%-17s  %s\n", buf, po->help);
Fabrice Bellard's avatar
Fabrice Bellard committed
105 106 107 108
        }
    }
}

Måns Rullgård's avatar
Måns Rullgård committed
109
static const OptionDef* find_option(const OptionDef *po, const char *name){
Michael Niedermayer's avatar
Michael Niedermayer committed
110 111 112 113 114 115 116 117
    while (po->name != NULL) {
        if (!strcmp(name, po->name))
            break;
        po++;
    }
    return po;
}

118 119
void parse_options(int argc, char **argv, const OptionDef *options,
                   void (* parse_arg_function)(const char*))
Fabrice Bellard's avatar
Fabrice Bellard committed
120 121
{
    const char *opt, *arg;
122
    int optindex, handleoptions=1;
Fabrice Bellard's avatar
Fabrice Bellard committed
123 124 125 126 127 128
    const OptionDef *po;

    /* parse options */
    optindex = 1;
    while (optindex < argc) {
        opt = argv[optindex++];
129

130
        if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
Benoit Fouet's avatar
Benoit Fouet committed
131
            int bool_val = 1;
Stefano Sabatini's avatar
Stefano Sabatini committed
132 133 134 135
            if (opt[1] == '-' && opt[2] == '\0') {
                handleoptions = 0;
                continue;
            }
136 137 138
            opt++;
            po= find_option(options, opt);
            if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
Benoit Fouet's avatar
Benoit Fouet committed
139
                /* handle 'no' bool option */
140
                po = find_option(options, opt + 2);
Benoit Fouet's avatar
Benoit Fouet committed
141 142 143 144
                if (!(po->name && (po->flags & OPT_BOOL)))
                    goto unknown_opt;
                bool_val = 0;
            }
Michael Niedermayer's avatar
Michael Niedermayer committed
145 146
            if (!po->name)
                po= find_option(options, "default");
Fabrice Bellard's avatar
Fabrice Bellard committed
147
            if (!po->name) {
Michael Niedermayer's avatar
Michael Niedermayer committed
148
unknown_opt:
Fabrice Bellard's avatar
Fabrice Bellard committed
149 150 151 152 153 154 155 156 157 158 159 160 161
                fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
                exit(1);
            }
            arg = NULL;
            if (po->flags & HAS_ARG) {
                arg = argv[optindex++];
                if (!arg) {
                    fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
                    exit(1);
                }
            }
            if (po->flags & OPT_STRING) {
                char *str;
162
                str = av_strdup(arg);
Fabrice Bellard's avatar
Fabrice Bellard committed
163 164
                *po->u.str_arg = str;
            } else if (po->flags & OPT_BOOL) {
Benoit Fouet's avatar
Benoit Fouet committed
165
                *po->u.int_arg = bool_val;
Michael Niedermayer's avatar
OPT_INT  
Michael Niedermayer committed
166
            } else if (po->flags & OPT_INT) {
167
                *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
168
            } else if (po->flags & OPT_INT64) {
169
                *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
Michael Niedermayer's avatar
Michael Niedermayer committed
170
            } else if (po->flags & OPT_FLOAT) {
171
                *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
Michael Niedermayer's avatar
Michael Niedermayer committed
172
            } else if (po->flags & OPT_FUNC2) {
173
                if(po->u.func2_arg(opt, arg)<0)
Michael Niedermayer's avatar
Michael Niedermayer committed
174
                    goto unknown_opt;
Fabrice Bellard's avatar
Fabrice Bellard committed
175
            } else {
176
                po->u.func_arg(arg);
Fabrice Bellard's avatar
Fabrice Bellard committed
177
            }
Michael Niedermayer's avatar
Michael Niedermayer committed
178 179
            if(po->flags & OPT_EXIT)
                exit(0);
Fabrice Bellard's avatar
Fabrice Bellard committed
180
        } else {
181 182
            if (parse_arg_function)
                parse_arg_function(opt);
Fabrice Bellard's avatar
Fabrice Bellard committed
183 184 185 186
        }
    }
}

187 188
int opt_default(const char *opt, const char *arg){
    int type;
189
    int ret= 0;
190 191 192
    const AVOption *o= NULL;
    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};

193
    for(type=0; type<CODEC_TYPE_NB && ret>= 0; type++){
194
        const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
195
        if(o2)
196
            ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
197 198
    }
    if(!o)
199
        ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
200
    if(!o)
201
        ret = av_set_string3(sws_opts, opt, arg, 1, &o);
202 203
    if(!o){
        if(opt[0] == 'a')
204
            ret = av_set_string3(avcodec_opts[CODEC_TYPE_AUDIO], opt+1, arg, 1, &o);
205
        else if(opt[0] == 'v')
206
            ret = av_set_string3(avcodec_opts[CODEC_TYPE_VIDEO], opt+1, arg, 1, &o);
207
        else if(opt[0] == 's')
208
            ret = av_set_string3(avcodec_opts[CODEC_TYPE_SUBTITLE], opt+1, arg, 1, &o);
209 210 211 212
    }
    if (o && ret < 0) {
        fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
        exit(1);
213 214 215 216
    }
    if(!o)
        return -1;

217
//    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));
218

219
    //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
220 221 222
    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
    opt_names[opt_name_count++]= o->name;

223
    if(avcodec_opts[0]->debug || avformat_opts->debug)
224 225 226 227
        av_log_set_level(AV_LOG_DEBUG);
    return 0;
}

228 229
int opt_loglevel(const char *opt, const char *arg)
{
Carl Eugen Hoyos's avatar
Carl Eugen Hoyos committed
230
    const struct { const char *name; int level; } log_levels[] = {
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
        { "quiet"  , AV_LOG_QUIET   },
        { "panic"  , AV_LOG_PANIC   },
        { "fatal"  , AV_LOG_FATAL   },
        { "error"  , AV_LOG_ERROR   },
        { "warning", AV_LOG_WARNING },
        { "info"   , AV_LOG_INFO    },
        { "verbose", AV_LOG_VERBOSE },
        { "debug"  , AV_LOG_DEBUG   },
    };
    char *tail;
    int level;
    int i;

    for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
        if (!strcmp(log_levels[i].name, arg)) {
            av_log_set_level(log_levels[i].level);
            return 0;
        }
    }

    level = strtol(arg, &tail, 10);
    if (*tail) {
        fprintf(stderr, "Invalid loglevel \"%s\". "
                        "Possible levels are numbers or:\n", arg);
        for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
            fprintf(stderr, "\"%s\"\n", log_levels[i].name);
        exit(1);
    }
    av_log_set_level(level);
    return 0;
}

Måns Rullgård's avatar
Måns Rullgård committed
263 264 265 266 267 268 269 270 271 272 273 274 275
int opt_timelimit(const char *opt, const char *arg)
{
#if HAVE_SYS_RESOURCE_H
    int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
    struct rlimit rl = { lim, lim + 1 };
    if (setrlimit(RLIMIT_CPU, &rl))
        perror("setrlimit");
#else
    fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
#endif
    return 0;
}

276 277 278 279 280 281 282 283 284
void set_context_opts(void *ctx, void *opts_ctx, int flags)
{
    int i;
    for(i=0; i<opt_name_count; i++){
        char buf[256];
        const AVOption *opt;
        const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
        /* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
        if(str && ((opt->flags & flags) == flags))
285
            av_set_string3(ctx, opt_names[i], str, 1, NULL);
286 287 288
    }
}

Fabrice Bellard's avatar
Fabrice Bellard committed
289 290 291 292 293 294 295
void print_error(const char *filename, int err)
{
    switch(err) {
    case AVERROR_NUMEXPECTED:
        fprintf(stderr, "%s: Incorrect image filename syntax.\n"
                "Use '%%d' to specify the image number:\n"
                "  for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n"
296
                "  for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n",
Fabrice Bellard's avatar
Fabrice Bellard committed
297 298 299 300 301 302 303 304
                filename);
        break;
    case AVERROR_INVALIDDATA:
        fprintf(stderr, "%s: Error while parsing header\n", filename);
        break;
    case AVERROR_NOFMT:
        fprintf(stderr, "%s: Unknown format\n", filename);
        break;
305
    case AVERROR(EIO):
Diego Biurrun's avatar
Diego Biurrun committed
306
        fprintf(stderr, "%s: I/O error occurred\n"
307 308
                "Usually that means that input file is truncated and/or corrupted.\n",
                filename);
309
        break;
310
    case AVERROR(ENOMEM):
Diego Biurrun's avatar
Diego Biurrun committed
311
        fprintf(stderr, "%s: memory allocation error occurred\n", filename);
312
        break;
313
    case AVERROR(ENOENT):
314 315
        fprintf(stderr, "%s: no such file or directory\n", filename);
        break;
316
#if CONFIG_NETWORK
317 318 319
    case AVERROR(FF_NETERROR(EPROTONOSUPPORT)):
        fprintf(stderr, "%s: Unsupported network protocol\n", filename);
        break;
320
#endif
Fabrice Bellard's avatar
Fabrice Bellard committed
321 322 323 324 325
    default:
        fprintf(stderr, "%s: Error while opening file\n", filename);
        break;
    }
}
326

327 328 329 330 331 332
#define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \
    version= libname##_version(); \
    fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n", indent? "  " : "", #libname, \
            LIB##LIBNAME##_VERSION_MAJOR, LIB##LIBNAME##_VERSION_MINOR, LIB##LIBNAME##_VERSION_MICRO, \
            version >> 16, version >> 8 & 0xff, version & 0xff);

333
static void print_all_lib_versions(FILE* outstream, int indent)
334 335
{
    unsigned int version;
336 337
    PRINT_LIB_VERSION(outstream, avutil,   AVUTIL,   indent);
    PRINT_LIB_VERSION(outstream, avcodec,  AVCODEC,  indent);
338 339
    PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
    PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
340
#if CONFIG_AVFILTER
341 342
    PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
#endif
343
    PRINT_LIB_VERSION(outstream, swscale,  SWSCALE,  indent);
344
#if CONFIG_POSTPROC
345 346
    PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent);
#endif
347 348
}

349 350 351 352 353 354 355 356 357 358 359 360 361
static void maybe_print_config(const char *lib, const char *cfg)
{
    static int warned_cfg;

    if (strcmp(FFMPEG_CONFIGURATION, cfg)) {
        if (!warned_cfg) {
            fprintf(stderr, "  WARNING: library configuration mismatch\n");
            warned_cfg = 1;
        }
        fprintf(stderr, "  %-11s configuration: %s\n", lib, cfg);
    }
}

362
void show_banner(void)
363
{
364 365
    fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d Fabrice Bellard, et al.\n",
            program_name, program_birth_year, this_year);
366 367
    fprintf(stderr, "  built on %s %s with %s %s\n",
            __DATE__, __TIME__, CC_TYPE, CC_VERSION);
368
    fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
369 370 371 372 373 374 375 376 377 378 379
    maybe_print_config("libavutil",   avutil_configuration());
    maybe_print_config("libavcodec",  avcodec_configuration());
    maybe_print_config("libavformat", avformat_configuration());
    maybe_print_config("libavdevice", avdevice_configuration());
#if CONFIG_AVFILTER
    maybe_print_config("libavfilter", avfilter_configuration());
#endif
    maybe_print_config("libswscale",  swscale_configuration());
#if CONFIG_POSTPROC
    maybe_print_config("libpostproc", postproc_configuration());
#endif
380
    print_all_lib_versions(stderr, 1);
381 382
}

383
void show_version(void) {
384
    printf("%s " FFMPEG_VERSION "\n", program_name);
385
    print_all_lib_versions(stdout, 0);
386 387
}

388 389
void show_license(void)
{
390
    printf(
391
#if CONFIG_NONFREE
392 393 394
    "This version of %s has nonfree parts compiled in.\n"
    "Therefore it is not legally redistributable.\n",
    program_name
395 396 397 398 399 400 401 402 403 404 405 406 407 408
#elif CONFIG_GPLV3
    "%s is free software; you can redistribute it and/or modify\n"
    "it under the terms of the GNU General Public License as published by\n"
    "the Free Software Foundation; either version 3 of the License, or\n"
    "(at your option) any later version.\n"
    "\n"
    "%s is distributed in the hope that it will be useful,\n"
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
    "GNU General Public License for more details.\n"
    "\n"
    "You should have received a copy of the GNU General Public License\n"
    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
    program_name, program_name, program_name
409
#elif CONFIG_GPL
410
    "%s is free software; you can redistribute it and/or modify\n"
411 412 413 414
    "it under the terms of the GNU General Public License as published by\n"
    "the Free Software Foundation; either version 2 of the License, or\n"
    "(at your option) any later version.\n"
    "\n"
415
    "%s is distributed in the hope that it will be useful,\n"
416 417 418 419 420
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
    "GNU General Public License for more details.\n"
    "\n"
    "You should have received a copy of the GNU General Public License\n"
421 422 423
    "along with %s; if not, write to the Free Software\n"
    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
    program_name, program_name, program_name
424 425 426 427 428 429 430 431 432 433 434 435 436 437
#elif CONFIG_LGPLV3
    "%s is free software; you can redistribute it and/or modify\n"
    "it under the terms of the GNU Lesser General Public License as published by\n"
    "the Free Software Foundation; either version 3 of the License, or\n"
    "(at your option) any later version.\n"
    "\n"
    "%s is distributed in the hope that it will be useful,\n"
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
    "GNU Lesser General Public License for more details.\n"
    "\n"
    "You should have received a copy of the GNU Lesser General Public License\n"
    "along with %s.  If not, see <http://www.gnu.org/licenses/>.\n",
    program_name, program_name, program_name
438
#else
439
    "%s is free software; you can redistribute it and/or\n"
440 441 442 443
    "modify it under the terms of the GNU Lesser General Public\n"
    "License as published by the Free Software Foundation; either\n"
    "version 2.1 of the License, or (at your option) any later version.\n"
    "\n"
444
    "%s is distributed in the hope that it will be useful,\n"
445 446 447 448 449
    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
    "Lesser General Public License for more details.\n"
    "\n"
    "You should have received a copy of the GNU Lesser General Public\n"
450 451 452
    "License along with %s; if not, write to the Free Software\n"
    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
    program_name, program_name, program_name
453
#endif
454
    );
455
}
456

457 458 459 460 461 462 463 464 465 466
void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
{
    int i;
    char fmt_str[128];
    for (i=-1; i < nb_fmts; i++) {
        get_fmt_string (fmt_str, sizeof(fmt_str), i);
        fprintf(stdout, "%s\n", fmt_str);
    }
}

467 468 469 470 471 472
void show_formats(void)
{
    AVInputFormat *ifmt=NULL;
    AVOutputFormat *ofmt=NULL;
    const char *last_name;

473 474 475 476 477
    printf(
        "File formats:\n"
        " D. = Demuxing supported\n"
        " .E = Muxing supported\n"
        " --\n");
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
    last_name= "000";
    for(;;){
        int decode=0;
        int encode=0;
        const char *name=NULL;
        const char *long_name=NULL;

        while((ofmt= av_oformat_next(ofmt))) {
            if((name == NULL || strcmp(ofmt->name, name)<0) &&
                strcmp(ofmt->name, last_name)>0){
                name= ofmt->name;
                long_name= ofmt->long_name;
                encode=1;
            }
        }
        while((ifmt= av_iformat_next(ifmt))) {
            if((name == NULL || strcmp(ifmt->name, name)<0) &&
                strcmp(ifmt->name, last_name)>0){
                name= ifmt->name;
                long_name= ifmt->long_name;
                encode=0;
            }
            if(name && strcmp(ifmt->name, name)==0)
                decode=1;
        }
        if(name==NULL)
            break;
        last_name= name;

        printf(
            " %s%s %-15s %s\n",
            decode ? "D":" ",
            encode ? "E":" ",
            name,
            long_name ? long_name:" ");
    }
Michael Niedermayer's avatar
Michael Niedermayer committed
514
}
515

Michael Niedermayer's avatar
Michael Niedermayer committed
516 517 518 519
void show_codecs(void)
{
    AVCodec *p=NULL, *p2;
    const char *last_name;
520 521 522 523 524 525 526 527 528 529 530
    printf(
        "Codecs:\n"
        " D..... = Decoding supported\n"
        " .E.... = Encoding supported\n"
        " ..V... = Video codec\n"
        " ..A... = Audio codec\n"
        " ..S... = Subtitle codec\n"
        " ...S.. = Supports draw_horiz_band\n"
        " ....D. = Supports direct rendering method 1\n"
        " .....T = Supports weird frame truncation\n"
        " ------\n");
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
    last_name= "000";
    for(;;){
        int decode=0;
        int encode=0;
        int cap=0;
        const char *type_str;

        p2=NULL;
        while((p= av_codec_next(p))) {
            if((p2==NULL || strcmp(p->name, p2->name)<0) &&
                strcmp(p->name, last_name)>0){
                p2= p;
                decode= encode= cap=0;
            }
            if(p2 && strcmp(p->name, p2->name)==0){
                if(p->decode) decode=1;
                if(p->encode) encode=1;
                cap |= p->capabilities;
            }
        }
        if(p2==NULL)
            break;
        last_name= p2->name;

        switch(p2->type) {
        case CODEC_TYPE_VIDEO:
            type_str = "V";
            break;
        case CODEC_TYPE_AUDIO:
            type_str = "A";
            break;
        case CODEC_TYPE_SUBTITLE:
            type_str = "S";
            break;
        default:
            type_str = "?";
            break;
        }
        printf(
            " %s%s%s%s%s%s %-15s %s",
            decode ? "D": (/*p2->decoder ? "d":*/" "),
            encode ? "E":" ",
            type_str,
            cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
            cap & CODEC_CAP_DR1 ? "D":" ",
            cap & CODEC_CAP_TRUNCATED ? "T":" ",
            p2->name,
            p2->long_name ? p2->long_name : "");
       /* if(p2->decoder && decode==0)
            printf(" use %s for decoding", p2->decoder->name);*/
        printf("\n");
    }
    printf("\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
584 585 586 587 588 589 590 591 592 593 594
    printf(
"Note, the names of encoders and decoders do not always match, so there are\n"
"several cases where the above table shows encoder only or decoder only entries\n"
"even though both encoding and decoding are supported. For example, the h263\n"
"decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
"worse.\n");
}

void show_bsfs(void)
{
    AVBitStreamFilter *bsf=NULL;
595 596 597

    printf("Bitstream filters:\n");
    while((bsf = av_bitstream_filter_next(bsf)))
598
        printf("%s\n", bsf->name);
599
    printf("\n");
Michael Niedermayer's avatar
Michael Niedermayer committed
600 601 602 603 604
}

void show_protocols(void)
{
    URLProtocol *up=NULL;
605 606 607

    printf("Supported file protocols:\n");
    while((up = av_protocol_next(up)))
608
        printf("%s\n", up->name);
609 610 611 612
    printf("\n");

    printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n");
}
Stefano Sabatini's avatar
Stefano Sabatini committed
613

614 615
void show_filters(void)
{
616
    AVFilter av_unused(**filter) = NULL;
617 618

    printf("Filters:\n");
619
#if CONFIG_AVFILTER
620 621
    while ((filter = av_filter_next(filter)) && *filter)
        printf("%-16s %s\n", (*filter)->name, (*filter)->description);
622
#endif
623 624
}

625 626 627 628 629
void show_pix_fmts(void)
{
    list_fmts(avcodec_pix_fmt_string, PIX_FMT_NB);
}

Stefano Sabatini's avatar
Stefano Sabatini committed
630 631 632 633 634 635 636 637 638 639
int read_yesno(void)
{
    int c = getchar();
    int yesno = (toupper(c) == 'Y');

    while (c != '\n' && c != EOF)
        c = getchar();

    return yesno;
}