cmdutils.c 45.6 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
 * This file is part of Libav.
6
 *
7
 * Libav 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
 * Libav 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 Libav; 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"
Justin Ruggles's avatar
Justin Ruggles committed
35
#include "libavresample/avresample.h"
36
#include "libswscale/swscale.h"
37
#include "libavutil/avassert.h"
38
#include "libavutil/avstring.h"
39
#include "libavutil/mathematics.h"
40
#include "libavutil/imgutils.h"
41
#include "libavutil/parseutils.h"
42
#include "libavutil/pixdesc.h"
43
#include "libavutil/eval.h"
Anton Khirnov's avatar
Anton Khirnov committed
44
#include "libavutil/dict.h"
45
#include "libavutil/opt.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
46
#include "cmdutils.h"
47
#include "version.h"
Ramiro Polla's avatar
Ramiro Polla committed
48
#if CONFIG_NETWORK
49
#include "libavformat/network.h"
Ramiro Polla's avatar
Ramiro Polla committed
50
#endif
Måns Rullgård's avatar
Måns Rullgård committed
51
#if HAVE_SYS_RESOURCE_H
52
#include <sys/time.h>
Måns Rullgård's avatar
Måns Rullgård committed
53 54
#include <sys/resource.h>
#endif
Fabrice Bellard's avatar
Fabrice Bellard committed
55

56
struct SwsContext *sws_opts;
57
AVDictionary *format_opts, *codec_opts;
Michael Niedermayer's avatar
Michael Niedermayer committed
58

59
static const int this_year = 2012;
60

61 62
void init_opts(void)
{
63
#if CONFIG_SWSCALE
64 65
    sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC,
                              NULL, NULL, NULL);
66
#endif
67 68 69 70
}

void uninit_opts(void)
{
71
#if CONFIG_SWSCALE
72 73
    sws_freeContext(sws_opts);
    sws_opts = NULL;
74
#endif
Anton Khirnov's avatar
Anton Khirnov committed
75
    av_dict_free(&format_opts);
76
    av_dict_free(&codec_opts);
77 78
}

79
void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
80 81 82 83
{
    vfprintf(stdout, fmt, vl);
}

84 85
double parse_number_or_die(const char *context, const char *numstr, int type,
                           double min, double max)
Michael Niedermayer's avatar
Michael Niedermayer committed
86 87 88
{
    char *tail;
    const char *error;
89
    double d = av_strtod(numstr, &tail);
Michael Niedermayer's avatar
Michael Niedermayer committed
90
    if (*tail)
91
        error = "Expected number for %s but found: %s\n";
Michael Niedermayer's avatar
Michael Niedermayer committed
92
    else if (d < min || d > max)
93 94 95
        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";
96
    else if (type == OPT_INT && (int)d != d)
97
        error = "Expected int for %s but found %s\n";
Michael Niedermayer's avatar
Michael Niedermayer committed
98 99
    else
        return d;
100
    av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
101
    exit(1);
102
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
103 104
}

105 106
int64_t parse_time_or_die(const char *context, const char *timestr,
                          int is_duration)
107
{
108 109
    int64_t us;
    if (av_parse_time(&us, timestr, is_duration) < 0) {
110 111
        av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
               is_duration ? "duration" : "date", context, timestr);
112
        exit(1);
113 114 115 116
    }
    return us;
}

117
void show_help_options(const OptionDef *options, const char *msg, int req_flags,
118
                       int rej_flags, int alt_flags)
Fabrice Bellard's avatar
Fabrice Bellard committed
119 120
{
    const OptionDef *po;
121
    int first;
Fabrice Bellard's avatar
Fabrice Bellard committed
122

123
    first = 1;
124
    for (po = options; po->name != NULL; po++) {
125
        char buf[64];
126 127

        if (((po->flags & req_flags) != req_flags) ||
128
            (alt_flags && !(po->flags & alt_flags)) ||
129 130 131 132 133 134 135 136
            (po->flags & rej_flags))
            continue;

        if (first) {
            printf("%s\n", msg);
            first = 0;
        }
        av_strlcpy(buf, po->name, sizeof(buf));
137
        if (po->argname) {
138 139
            av_strlcat(buf, " ", sizeof(buf));
            av_strlcat(buf, po->argname, sizeof(buf));
Fabrice Bellard's avatar
Fabrice Bellard committed
140
        }
141
        printf("-%-17s  %s\n", buf, po->help);
Fabrice Bellard's avatar
Fabrice Bellard committed
142
    }
143
    printf("\n");
Fabrice Bellard's avatar
Fabrice Bellard committed
144 145
}

146 147 148 149 150 151 152 153 154 155
void show_help_children(const AVClass *class, int flags)
{
    const AVClass *child = NULL;
    av_opt_show2(&class, NULL, flags, 0);
    printf("\n");

    while (child = av_opt_child_class_next(class, child))
        show_help_children(child, flags);
}

156 157
static const OptionDef *find_option(const OptionDef *po, const char *name)
{
158 159 160
    const char *p = strchr(name, ':');
    int len = p ? p - name : strlen(name);

Michael Niedermayer's avatar
Michael Niedermayer committed
161
    while (po->name != NULL) {
162
        if (!strncmp(name, po->name, len) && strlen(po->name) == len)
Michael Niedermayer's avatar
Michael Niedermayer committed
163 164 165 166 167 168
            break;
        po++;
    }
    return po;
}

169
#if defined(_WIN32) && !defined(__MINGW32CE__)
170
#include <windows.h>
171
#include <shellapi.h>
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
/* Will be leaked on exit */
static char** win32_argv_utf8 = NULL;
static int win32_argc = 0;

/**
 * Prepare command line arguments for executable.
 * For Windows - perform wide-char to UTF-8 conversion.
 * Input arguments should be main() function arguments.
 * @param argc_ptr Arguments number (including executable)
 * @param argv_ptr Arguments list.
 */
static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
{
    char *argstr_flat;
    wchar_t **argv_w;
    int i, buffsize = 0, offset = 0;

    if (win32_argv_utf8) {
        *argc_ptr = win32_argc;
        *argv_ptr = win32_argv_utf8;
        return;
    }

    win32_argc = 0;
    argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
    if (win32_argc <= 0 || !argv_w)
        return;

    /* determine the UTF-8 buffer size (including NULL-termination symbols) */
    for (i = 0; i < win32_argc; i++)
        buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
                                        NULL, 0, NULL, NULL);

205 206
    win32_argv_utf8 = av_mallocz(sizeof(char *) * (win32_argc + 1) + buffsize);
    argstr_flat     = (char *)win32_argv_utf8 + sizeof(char *) * (win32_argc + 1);
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
    if (win32_argv_utf8 == NULL) {
        LocalFree(argv_w);
        return;
    }

    for (i = 0; i < win32_argc; i++) {
        win32_argv_utf8[i] = &argstr_flat[offset];
        offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
                                      &argstr_flat[offset],
                                      buffsize - offset, NULL, NULL);
    }
    win32_argv_utf8[i] = NULL;
    LocalFree(argv_w);

    *argc_ptr = win32_argc;
    *argv_ptr = win32_argv_utf8;
}
#else
static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
{
    /* nothing to do */
}
#endif /* WIN32 && !__MINGW32CE__ */

231 232
int parse_option(void *optctx, const char *opt, const char *arg,
                 const OptionDef *options)
233 234 235
{
    const OptionDef *po;
    int bool_val = 1;
236
    int *dstcount;
237 238 239 240 241 242
    void *dst;

    po = find_option(options, opt);
    if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
        /* handle 'no' bool option */
        po = find_option(options, opt + 2);
243 244
        if ((po->name && (po->flags & OPT_BOOL)))
            bool_val = 0;
245 246 247 248 249 250 251 252 253 254 255 256 257 258
    }
    if (!po->name)
        po = find_option(options, "default");
    if (!po->name) {
        av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
        return AVERROR(EINVAL);
    }
    if (po->flags & HAS_ARG && !arg) {
        av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
        return AVERROR(EINVAL);
    }

    /* new-style options contain an offset into optctx, old-style address of
     * a global var*/
259 260
    dst = po->flags & (OPT_OFFSET | OPT_SPEC) ? (uint8_t *)optctx + po->u.off
                                              : po->u.dst_ptr;
261 262 263 264 265

    if (po->flags & OPT_SPEC) {
        SpecifierOpt **so = dst;
        char *p = strchr(opt, ':');

266
        dstcount = (int *)(so + 1);
267 268 269 270
        *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
        (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : "");
        dst = &(*so)[*dstcount - 1].u;
    }
271 272 273 274

    if (po->flags & OPT_STRING) {
        char *str;
        str = av_strdup(arg);
275
        av_freep(dst);
276
        *(char **)dst = str;
277
    } else if (po->flags & OPT_BOOL) {
278
        *(int *)dst = bool_val;
279
    } else if (po->flags & OPT_INT) {
280
        *(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
281
    } else if (po->flags & OPT_INT64) {
282
        *(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
283
    } else if (po->flags & OPT_TIME) {
284
        *(int64_t *)dst = parse_time_or_die(opt, arg, 1);
285
    } else if (po->flags & OPT_FLOAT) {
286
        *(float *)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
287
    } else if (po->flags & OPT_DOUBLE) {
288
        *(double *)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
289
    } else if (po->u.func_arg) {
290
        int ret = po->u.func_arg(optctx, opt, arg);
291
        if (ret < 0) {
292 293
            av_log(NULL, AV_LOG_ERROR,
                   "Failed to set value '%s' for option '%s'\n", arg, opt);
294 295 296 297
            return ret;
        }
    }
    if (po->flags & OPT_EXIT)
298
        exit(0);
299 300 301
    return !!(po->flags & HAS_ARG);
}

302
void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
303
                   void (*parse_arg_function)(void *, const char*))
Fabrice Bellard's avatar
Fabrice Bellard committed
304
{
305 306
    const char *opt;
    int optindex, handleoptions = 1, ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
307

308 309 310
    /* perform system-dependent conversions for arguments list */
    prepare_app_arguments(&argc, &argv);

Fabrice Bellard's avatar
Fabrice Bellard committed
311 312 313 314
    /* parse options */
    optindex = 1;
    while (optindex < argc) {
        opt = argv[optindex++];
315

316
        if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
Stefano Sabatini's avatar
Stefano Sabatini committed
317 318 319 320
            if (opt[1] == '-' && opt[2] == '\0') {
                handleoptions = 0;
                continue;
            }
321
            opt++;
322 323

            if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
324
                exit(1);
325
            optindex += ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
326
        } else {
327
            if (parse_arg_function)
328
                parse_arg_function(optctx, opt);
Fabrice Bellard's avatar
Fabrice Bellard committed
329 330 331 332
        }
    }
}

333 334
int locate_option(int argc, char **argv, const OptionDef *options,
                  const char *optname)
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
{
    const OptionDef *po;
    int i;

    for (i = 1; i < argc; i++) {
        const char *cur_opt = argv[i];

        if (*cur_opt++ != '-')
            continue;

        po = find_option(options, cur_opt);
        if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
            po = find_option(options, cur_opt + 2);

        if ((!po->name && !strcmp(cur_opt, optname)) ||
             (po->name && !strcmp(optname, po->name)))
            return i;

        if (!po || po->flags & HAS_ARG)
            i++;
    }
    return 0;
}

void parse_loglevel(int argc, char **argv, const OptionDef *options)
{
    int idx = locate_option(argc, argv, options, "loglevel");
362 363
    if (!idx)
        idx = locate_option(argc, argv, options, "v");
364
    if (idx && argv[idx + 1])
365
        opt_loglevel(NULL, "loglevel", argv[idx + 1]);
366 367
}

368
#define FLAGS (o->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
369
int opt_default(void *optctx, const char *opt, const char *arg)
Anton Khirnov's avatar
Anton Khirnov committed
370 371
{
    const AVOption *o;
372 373
    char opt_stripped[128];
    const char *p;
374 375 376 377
    const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();
#if CONFIG_SWSCALE
    const AVClass *sc = sws_get_class();
#endif
378 379 380 381 382

    if (!(p = strchr(opt, ':')))
        p = opt + strlen(opt);
    av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));

383 384 385 386
    if ((o = av_opt_find(&cc, opt_stripped, NULL, 0,
                         AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
        ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
         (o = av_opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
387
        av_dict_set(&codec_opts, opt, arg, FLAGS);
388 389
    else if ((o = av_opt_find(&fc, opt, NULL, 0,
                              AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
Anton Khirnov's avatar
Anton Khirnov committed
390
        av_dict_set(&format_opts, opt, arg, FLAGS);
391
#if CONFIG_SWSCALE
392 393
    else if ((o = av_opt_find(&sc, opt, NULL, 0,
                              AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
Anton Khirnov's avatar
Anton Khirnov committed
394
        // XXX we only support sws_flags, not arbitrary sws options
395
        int ret = av_opt_set(sws_opts, opt, arg, 0);
Anton Khirnov's avatar
Anton Khirnov committed
396 397 398 399 400
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
            return ret;
        }
    }
401
#endif
Anton Khirnov's avatar
Anton Khirnov committed
402 403 404

    if (o)
        return 0;
405
    av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
Anton Khirnov's avatar
Anton Khirnov committed
406 407 408
    return AVERROR_OPTION_NOT_FOUND;
}

409
int opt_loglevel(void *optctx, const char *opt, const char *arg)
410
{
Carl Eugen Hoyos's avatar
Carl Eugen Hoyos committed
411
    const struct { const char *name; int level; } log_levels[] = {
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
        { "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) {
434 435
        av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
               "Possible levels are numbers or:\n", arg);
436
        for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
437
            av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
438
        exit(1);
439 440 441 442 443
    }
    av_log_set_level(level);
    return 0;
}

444
int opt_timelimit(void *optctx, const char *opt, const char *arg)
Måns Rullgård's avatar
Måns Rullgård committed
445
{
Måns Rullgård's avatar
Måns Rullgård committed
446
#if HAVE_SETRLIMIT
Måns Rullgård's avatar
Måns Rullgård committed
447 448 449 450 451
    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
452
    av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
Måns Rullgård's avatar
Måns Rullgård committed
453 454 455 456
#endif
    return 0;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
457 458
void print_error(const char *filename, int err)
{
459
    char errbuf[128];
460
    const char *errbuf_ptr = errbuf;
461

462 463
    if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
        errbuf_ptr = strerror(AVUNERROR(err));
464
    av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
Fabrice Bellard's avatar
Fabrice Bellard committed
465
}
466

467 468
static int warned_cfg = 0;

469 470
#define INDENT        1
#define SHOW_VERSION  2
471
#define SHOW_CONFIG   4
472

473
#define PRINT_LIB_INFO(libname, LIBNAME, flags, level)                  \
474
    if (CONFIG_##LIBNAME) {                                             \
475
        const char *indent = flags & INDENT? "  " : "";                 \
476
        if (flags & SHOW_VERSION) {                                     \
Stefano Sabatini's avatar
Stefano Sabatini committed
477
            unsigned int version = libname##_version();                 \
Justin Ruggles's avatar
Justin Ruggles committed
478 479
            av_log(NULL, level,                                         \
                   "%slib%-10s %2d.%3d.%2d / %2d.%3d.%2d\n",            \
480 481 482 483 484
                   indent, #libname,                                    \
                   LIB##LIBNAME##_VERSION_MAJOR,                        \
                   LIB##LIBNAME##_VERSION_MINOR,                        \
                   LIB##LIBNAME##_VERSION_MICRO,                        \
                   version >> 16, version >> 8 & 0xff, version & 0xff); \
485
        }                                                               \
486 487
        if (flags & SHOW_CONFIG) {                                      \
            const char *cfg = libname##_configuration();                \
488
            if (strcmp(LIBAV_CONFIGURATION, cfg)) {                     \
489
                if (!warned_cfg) {                                      \
490
                    av_log(NULL, level,                                 \
491
                            "%sWARNING: library configuration mismatch\n", \
492
                            indent);                                    \
493 494
                    warned_cfg = 1;                                     \
                }                                                       \
495
                av_log(NULL, level, "%s%-11s configuration: %s\n",      \
496
                        indent, #libname, cfg);                         \
497 498
            }                                                           \
        }                                                               \
499
    }                                                                   \
500

501
static void print_all_libs_info(int flags, int level)
502
{
503 504 505 506 507
    PRINT_LIB_INFO(avutil,   AVUTIL,   flags, level);
    PRINT_LIB_INFO(avcodec,  AVCODEC,  flags, level);
    PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
    PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
    PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
Justin Ruggles's avatar
Justin Ruggles committed
508
    PRINT_LIB_INFO(avresample, AVRESAMPLE, flags, level);
509
    PRINT_LIB_INFO(swscale,  SWSCALE,  flags, level);
510 511
}

512
void show_banner(void)
513
{
514 515
    av_log(NULL, AV_LOG_INFO,
           "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
516
           program_name, program_birth_year, this_year);
517 518
    av_log(NULL, AV_LOG_INFO, "  built on %s %s with %s\n",
           __DATE__, __TIME__, CC_IDENT);
519 520 521
    av_log(NULL, AV_LOG_VERBOSE, "  configuration: " LIBAV_CONFIGURATION "\n");
    print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_VERBOSE);
    print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_VERBOSE);
522 523
}

524
int show_version(void *optctx, const char *opt, const char *arg)
525
{
526
    av_log_set_callback(log_callback_help);
527
    printf("%s " LIBAV_VERSION "\n", program_name);
528
    print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
529 530

    return 0;
531 532
}

533
int show_license(void *optctx, const char *opt, const char *arg)
534
{
535
    printf(
536
#if CONFIG_NONFREE
537 538 539
    "This version of %s has nonfree parts compiled in.\n"
    "Therefore it is not legally redistributable.\n",
    program_name
540 541 542 543 544 545 546 547 548 549 550 551 552 553
#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
554
#elif CONFIG_GPL
555
    "%s is free software; you can redistribute it and/or modify\n"
556 557 558 559
    "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"
560
    "%s is distributed in the hope that it will be useful,\n"
561 562 563 564 565
    "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"
566 567 568
    "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
569 570 571 572 573 574 575 576 577 578 579 580 581 582
#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
583
#else
584
    "%s is free software; you can redistribute it and/or\n"
585 586 587 588
    "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"
589
    "%s is distributed in the hope that it will be useful,\n"
590 591 592 593 594
    "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"
595 596 597
    "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
598
#endif
599
    );
600 601

    return 0;
602
}
603

604
int show_formats(void *optctx, const char *opt, const char *arg)
605
{
606 607
    AVInputFormat *ifmt  = NULL;
    AVOutputFormat *ofmt = NULL;
608 609
    const char *last_name;

610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
    printf("File formats:\n"
           " D. = Demuxing supported\n"
           " .E = Muxing supported\n"
           " --\n");
    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;
627 628
            }
        }
629 630 631 632 633 634
        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;
635
            }
636 637
            if (name && strcmp(ifmt->name, name) == 0)
                decode = 1;
638
        }
639
        if (name == NULL)
640
            break;
641
        last_name = name;
642

643 644 645 646
        printf(" %s%s %-15s %s\n",
               decode ? "D" : " ",
               encode ? "E" : " ",
               name,
647 648
            long_name ? long_name:" ");
    }
649
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
650
}
651

652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
    if (codec->field) {                                                      \
        const type *p = c->field;                                            \
                                                                             \
        printf("    Supported " list_name ":");                              \
        while (*p != term) {                                                 \
            get_name(*p);                                                    \
            printf(" %s", name);                                             \
            p++;                                                             \
        }                                                                    \
        printf("\n");                                                        \
    }                                                                        \

static void print_codec(const AVCodec *c)
{
    int encoder = av_codec_is_encoder(c);

    printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
           c->long_name ? c->long_name : "");

    if (c->type == AVMEDIA_TYPE_VIDEO) {
        printf("    Threading capabilities: ");
        switch (c->capabilities & (CODEC_CAP_FRAME_THREADS |
                                   CODEC_CAP_SLICE_THREADS)) {
        case CODEC_CAP_FRAME_THREADS |
             CODEC_CAP_SLICE_THREADS: printf("frame and slice"); break;
        case CODEC_CAP_FRAME_THREADS: printf("frame");           break;
        case CODEC_CAP_SLICE_THREADS: printf("slice");           break;
        default:                      printf("no");              break;
        }
        printf("\n");
    }

    if (c->supported_framerates) {
        const AVRational *fps = c->supported_framerates;

        printf("    Supported framerates:");
        while (fps->num) {
            printf(" %d/%d", fps->num, fps->den);
            fps++;
        }
        printf("\n");
    }
695 696
    PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel formats",
                          AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
697 698 699 700 701 702 703 704 705 706 707 708 709 710
    PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0,
                          GET_SAMPLE_RATE_NAME);
    PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats",
                          AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
    PRINT_CODEC_SUPPORTED(c, channel_layouts, uint64_t, "channel layouts",
                          0, GET_CH_LAYOUT_DESC);

    if (c->priv_class) {
        show_help_children(c->priv_class,
                           AV_OPT_FLAG_ENCODING_PARAM |
                           AV_OPT_FLAG_DECODING_PARAM);
    }
}

711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
static char get_media_type_char(enum AVMediaType type)
{
    switch (type) {
        case AVMEDIA_TYPE_VIDEO:    return 'V';
        case AVMEDIA_TYPE_AUDIO:    return 'A';
        case AVMEDIA_TYPE_SUBTITLE: return 'S';
        default:                    return '?';
    }
}

static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
                                        int encoder)
{
    while ((prev = av_codec_next(prev))) {
        if (prev->id == id &&
            (encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
            return prev;
    }
    return NULL;
}

static void print_codecs_for_id(enum AVCodecID id, int encoder)
{
    const AVCodec *codec = NULL;

    printf(" (%s: ", encoder ? "encoders" : "decoders");

    while ((codec = next_codec_for_id(id, codec, encoder)))
        printf("%s ", codec->name);

    printf(")");
}

744
int show_codecs(void *optctx, const char *opt, const char *arg)
Michael Niedermayer's avatar
Michael Niedermayer committed
745
{
746 747
    const AVCodecDescriptor *desc = NULL;

748
    printf("Codecs:\n"
749 750 751 752 753 754 755 756 757
           " D..... = Decoding supported\n"
           " .E.... = Encoding supported\n"
           " ..V... = Video codec\n"
           " ..A... = Audio codec\n"
           " ..S... = Subtitle codec\n"
           " ...I.. = Intra frame-only codec\n"
           " ....L. = Lossy compression\n"
           " .....S = Lossless compression\n"
           " -------\n");
758 759 760 761 762 763 764 765
    while ((desc = avcodec_descriptor_next(desc))) {
        const AVCodec *codec = NULL;

        printf(avcodec_find_decoder(desc->id) ? "D" : ".");
        printf(avcodec_find_encoder(desc->id) ? "E" : ".");

        printf("%c", get_media_type_char(desc->type));
        printf((desc->props & AV_CODEC_PROP_INTRA_ONLY) ? "I" : ".");
766 767
        printf((desc->props & AV_CODEC_PROP_LOSSY)      ? "L" : ".");
        printf((desc->props & AV_CODEC_PROP_LOSSLESS)   ? "S" : ".");
768 769 770 771 772 773 774 775 776

        printf(" %-20s %s", desc->name, desc->long_name ? desc->long_name : "");

        /* print decoders/encoders when there's more than one or their
         * names are different from codec name */
        while ((codec = next_codec_for_id(desc->id, codec, 0))) {
            if (strcmp(codec->name, desc->name)) {
                print_codecs_for_id(desc->id, 0);
                break;
777
            }
778 779 780 781 782 783
        }
        codec = NULL;
        while ((codec = next_codec_for_id(desc->id, codec, 1))) {
            if (strcmp(codec->name, desc->name)) {
                print_codecs_for_id(desc->id, 1);
                break;
784 785 786 787 788
            }
        }

        printf("\n");
    }
789
    return 0;
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
}

static void print_codecs(int encoder)
{
    const AVCodecDescriptor *desc = NULL;

    printf("%s:\n"
           " V... = Video\n"
           " A... = Audio\n"
           " S... = Subtitle\n"
           " .F.. = Frame-level multithreading\n"
           " ..S. = Slice-level multithreading\n"
           " ...X = Codec is experimental\n"
           " ---\n",
           encoder ? "Encoders" : "Decoders");
    while ((desc = avcodec_descriptor_next(desc))) {
        const AVCodec *codec = NULL;

        while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
            printf("%c", get_media_type_char(desc->type));
            printf((codec->capabilities & CODEC_CAP_FRAME_THREADS) ? "F" : ".");
            printf((codec->capabilities & CODEC_CAP_SLICE_THREADS) ? "S" : ".");
            printf((codec->capabilities & CODEC_CAP_EXPERIMENTAL)  ? "X" : ".");

            printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
            if (strcmp(codec->name, desc->name))
                printf(" (codec %s)", desc->name);

            printf("\n");
        }
    }
}

823
int show_decoders(void *optctx, const char *opt, const char *arg)
824 825 826 827 828
{
    print_codecs(0);
    return 0;
}

829
int show_encoders(void *optctx, const char *opt, const char *arg)
830 831 832
{
    print_codecs(1);
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
833 834
}

835
int show_bsfs(void *optctx, const char *opt, const char *arg)
Michael Niedermayer's avatar
Michael Niedermayer committed
836
{
837
    AVBitStreamFilter *bsf = NULL;
838 839

    printf("Bitstream filters:\n");
840
    while ((bsf = av_bitstream_filter_next(bsf)))
841
        printf("%s\n", bsf->name);
842
    printf("\n");
843
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
844 845
}

846
int show_protocols(void *optctx, const char *opt, const char *arg)
Michael Niedermayer's avatar
Michael Niedermayer committed
847
{
848 849
    void *opaque = NULL;
    const char *name;
850

851
    printf("Supported file protocols:\n"
852 853 854 855 856 857
           "Input:\n");
    while ((name = avio_enum_protocols(&opaque, 0)))
        printf("%s\n", name);
    printf("Output:\n");
    while ((name = avio_enum_protocols(&opaque, 1)))
        printf("%s\n", name);
858
    return 0;
859
}
Stefano Sabatini's avatar
Stefano Sabatini committed
860

861
int show_filters(void *optctx, const char *opt, const char *arg)
862
{
863
    AVFilter av_unused(**filter) = NULL;
864 865

    printf("Filters:\n");
866
#if CONFIG_AVFILTER
867 868
    while ((filter = av_filter_next(filter)) && *filter)
        printf("%-16s %s\n", (*filter)->name, (*filter)->description);
869
#endif
870
    return 0;
871 872
}

873
int show_pix_fmts(void *optctx, const char *opt, const char *arg)
874
{
875
    const AVPixFmtDescriptor *pix_desc = NULL;
876

877 878 879 880 881 882 883 884
    printf("Pixel formats:\n"
           "I.... = Supported Input  format for conversion\n"
           ".O... = Supported Output format for conversion\n"
           "..H.. = Hardware accelerated format\n"
           "...P. = Paletted format\n"
           "....B = Bitstream format\n"
           "FLAGS NAME            NB_COMPONENTS BITS_PER_PIXEL\n"
           "-----\n");
885

886 887 888 889 890
#if !CONFIG_SWSCALE
#   define sws_isSupportedInput(x)  0
#   define sws_isSupportedOutput(x) 0
#endif

891 892
    while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
        enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
893 894 895 896 897 898 899 900 901 902
        printf("%c%c%c%c%c %-16s       %d            %2d\n",
               sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
               sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
               pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
               pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
               pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
               pix_desc->name,
               pix_desc->nb_components,
               av_get_bits_per_pixel(pix_desc));
    }
903
    return 0;
904 905
}

906
int show_sample_fmts(void *optctx, const char *opt, const char *arg)
907 908 909 910 911 912 913 914
{
    int i;
    char fmt_str[128];
    for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
        printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
    return 0;
}

915 916