cmdutils.c 39 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 52 53
#if HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
Fabrice Bellard's avatar
Fabrice Bellard committed
54

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

58
static const int this_year = 2012;
59

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

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

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

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

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

116 117
void show_help_options(const OptionDef *options, const char *msg, int mask,
                       int value)
Fabrice Bellard's avatar
Fabrice Bellard committed
118 119
{
    const OptionDef *po;
120
    int first;
Fabrice Bellard's avatar
Fabrice Bellard committed
121

122
    first = 1;
123
    for (po = options; po->name != NULL; po++) {
124 125 126 127 128 129
        char buf[64];
        if ((po->flags & mask) == value) {
            if (first) {
                printf("%s", msg);
                first = 0;
            }
130
            av_strlcpy(buf, po->name, sizeof(buf));
131
            if (po->flags & HAS_ARG) {
132 133
                av_strlcat(buf, " ", sizeof(buf));
                av_strlcat(buf, po->argname, sizeof(buf));
Fabrice Bellard's avatar
Fabrice Bellard committed
134
            }
135
            printf("-%-17s  %s\n", buf, po->help);
Fabrice Bellard's avatar
Fabrice Bellard committed
136 137 138 139
        }
    }
}

140 141 142 143 144 145 146 147 148 149
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);
}

150 151
static const OptionDef *find_option(const OptionDef *po, const char *name)
{
152 153 154
    const char *p = strchr(name, ':');
    int len = p ? p - name : strlen(name);

Michael Niedermayer's avatar
Michael Niedermayer committed
155
    while (po->name != NULL) {
156
        if (!strncmp(name, po->name, len) && strlen(po->name) == len)
Michael Niedermayer's avatar
Michael Niedermayer committed
157 158 159 160 161 162
            break;
        po++;
    }
    return po;
}

163
#if defined(_WIN32) && !defined(__MINGW32CE__)
164
#include <windows.h>
165
#include <shellapi.h>
166 167 168 169 170 171 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
/* 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);

199 200
    win32_argv_utf8 = av_mallocz(sizeof(char *) * (win32_argc + 1) + buffsize);
    argstr_flat     = (char *)win32_argv_utf8 + sizeof(char *) * (win32_argc + 1);
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
    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__ */

225 226
int parse_option(void *optctx, const char *opt, const char *arg,
                 const OptionDef *options)
227 228 229
{
    const OptionDef *po;
    int bool_val = 1;
230
    int *dstcount;
231 232 233 234 235 236
    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);
237 238
        if ((po->name && (po->flags & OPT_BOOL)))
            bool_val = 0;
239 240 241 242 243 244 245 246 247 248 249 250 251 252
    }
    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*/
253 254
    dst = po->flags & (OPT_OFFSET | OPT_SPEC) ? (uint8_t *)optctx + po->u.off
                                              : po->u.dst_ptr;
255 256 257 258 259

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

260
        dstcount = (int *)(so + 1);
261 262 263 264
        *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
        (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : "");
        dst = &(*so)[*dstcount - 1].u;
    }
265 266 267 268

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

296
void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
297
                   void (*parse_arg_function)(void *, const char*))
Fabrice Bellard's avatar
Fabrice Bellard committed
298
{
299 300
    const char *opt;
    int optindex, handleoptions = 1, ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
301

302 303 304
    /* perform system-dependent conversions for arguments list */
    prepare_app_arguments(&argc, &argv);

Fabrice Bellard's avatar
Fabrice Bellard committed
305 306 307 308
    /* parse options */
    optindex = 1;
    while (optindex < argc) {
        opt = argv[optindex++];
309

310
        if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
Stefano Sabatini's avatar
Stefano Sabatini committed
311 312 313 314
            if (opt[1] == '-' && opt[2] == '\0') {
                handleoptions = 0;
                continue;
            }
315
            opt++;
316 317

            if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
318
                exit_program(1);
319
            optindex += ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
320
        } else {
321
            if (parse_arg_function)
322
                parse_arg_function(optctx, opt);
Fabrice Bellard's avatar
Fabrice Bellard committed
323 324 325 326
        }
    }
}

327 328
int locate_option(int argc, char **argv, const OptionDef *options,
                  const char *optname)
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
{
    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");
356 357
    if (!idx)
        idx = locate_option(argc, argv, options, "v");
358 359 360 361
    if (idx && argv[idx + 1])
        opt_loglevel("loglevel", argv[idx + 1]);
}

362
#define FLAGS (o->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
363
int opt_default(const char *opt, const char *arg)
Anton Khirnov's avatar
Anton Khirnov committed
364 365
{
    const AVOption *o;
366 367
    char opt_stripped[128];
    const char *p;
368
    const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc = sws_get_class();
369 370 371 372 373

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

374 375 376 377
    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))))
378
        av_dict_set(&codec_opts, opt, arg, FLAGS);
379 380
    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
381
        av_dict_set(&format_opts, opt, arg, FLAGS);
382 383
    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
384
        // XXX we only support sws_flags, not arbitrary sws options
385
        int ret = av_opt_set(sws_opts, opt, arg, 0);
Anton Khirnov's avatar
Anton Khirnov committed
386 387 388 389 390 391 392 393
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
            return ret;
        }
    }

    if (o)
        return 0;
394
    av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
Anton Khirnov's avatar
Anton Khirnov committed
395 396 397
    return AVERROR_OPTION_NOT_FOUND;
}

398 399
int opt_loglevel(const char *opt, const char *arg)
{
Carl Eugen Hoyos's avatar
Carl Eugen Hoyos committed
400
    const struct { const char *name; int level; } log_levels[] = {
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
        { "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) {
423 424
        av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
               "Possible levels are numbers or:\n", arg);
425
        for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
426
            av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
427
        exit_program(1);
428 429 430 431 432
    }
    av_log_set_level(level);
    return 0;
}

Måns Rullgård's avatar
Måns Rullgård committed
433 434
int opt_timelimit(const char *opt, const char *arg)
{
Måns Rullgård's avatar
Måns Rullgård committed
435
#if HAVE_SETRLIMIT
Måns Rullgård's avatar
Måns Rullgård committed
436 437 438 439 440
    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
441
    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
442 443 444 445
#endif
    return 0;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
446 447
void print_error(const char *filename, int err)
{
448
    char errbuf[128];
449
    const char *errbuf_ptr = errbuf;
450

451 452
    if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
        errbuf_ptr = strerror(AVUNERROR(err));
453
    av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
Fabrice Bellard's avatar
Fabrice Bellard committed
454
}
455

456 457
static int warned_cfg = 0;

458 459
#define INDENT        1
#define SHOW_VERSION  2
460
#define SHOW_CONFIG   4
461

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

490
static void print_all_libs_info(int flags, int level)
491
{
492 493 494 495 496
    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
497
    PRINT_LIB_INFO(avresample, AVRESAMPLE, flags, level);
498
    PRINT_LIB_INFO(swscale,  SWSCALE,  flags, level);
499 500
}

501
void show_banner(void)
502
{
503 504
    av_log(NULL, AV_LOG_INFO,
           "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
505
           program_name, program_birth_year, this_year);
506 507
    av_log(NULL, AV_LOG_INFO, "  built on %s %s with %s\n",
           __DATE__, __TIME__, CC_IDENT);
508 509 510
    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);
511 512
}

513 514
int show_version(const char *opt, const char *arg)
{
515
    av_log_set_callback(log_callback_help);
516
    printf("%s " LIBAV_VERSION "\n", program_name);
517
    print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
518 519

    return 0;
520 521
}

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

    return 0;
591
}
592

593
int show_formats(const char *opt, const char *arg)
594
{
595 596
    AVInputFormat *ifmt  = NULL;
    AVOutputFormat *ofmt = NULL;
597 598
    const char *last_name;

599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
    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;
616 617
            }
        }
618 619 620 621 622 623
        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;
624
            }
625 626
            if (name && strcmp(ifmt->name, name) == 0)
                decode = 1;
627
        }
628
        if (name == NULL)
629
            break;
630
        last_name = name;
631

632 633 634 635
        printf(" %s%s %-15s %s\n",
               decode ? "D" : " ",
               encode ? "E" : " ",
               name,
636 637
            long_name ? long_name:" ");
    }
638
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
639
}
640

641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673
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(")");
}

674
int show_codecs(const char *opt, const char *arg)
Michael Niedermayer's avatar
Michael Niedermayer committed
675
{
676 677
    const AVCodecDescriptor *desc = NULL;

678
    printf("Codecs:\n"
679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702
           " 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"
           " -----\n");
    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" : ".");

        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;
703
            }
704 705 706 707 708 709
        }
        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;
710 711 712 713 714
            }
        }

        printf("\n");
    }
715
    return 0;
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 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
}

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");
        }
    }
}

int show_decoders(const char *opt, const char *arg)
{
    print_codecs(0);
    return 0;
}

int show_encoders(const char *opt, const char *arg)
{
    print_codecs(1);
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
759 760
}

761
int show_bsfs(const char *opt, const char *arg)
Michael Niedermayer's avatar
Michael Niedermayer committed
762
{
763
    AVBitStreamFilter *bsf = NULL;
764 765

    printf("Bitstream filters:\n");
766
    while ((bsf = av_bitstream_filter_next(bsf)))
767
        printf("%s\n", bsf->name);
768
    printf("\n");
769
    return 0;
Michael Niedermayer's avatar
Michael Niedermayer committed
770 771
}

772
int show_protocols(const char *opt, const char *arg)
Michael Niedermayer's avatar
Michael Niedermayer committed
773
{
774 775
    void *opaque = NULL;
    const char *name;
776

777
    printf("Supported file protocols:\n"
778 779 780 781 782 783
           "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);
784
    return 0;
785
}
Stefano Sabatini's avatar
Stefano Sabatini committed
786

787
int show_filters(const char *opt, const char *arg)
788
{
789
    AVFilter av_unused(**filter) = NULL;
790 791

    printf("Filters:\n");
792
#if CONFIG_AVFILTER
793 794
    while ((filter = av_filter_next(filter)) && *filter)
        printf("%-16s %s\n", (*filter)->name, (*filter)->description);
795
#endif
796
    return 0;
797 798
}

799
int show_pix_fmts(const char *opt, const char *arg)
800
{
801 802
    enum PixelFormat pix_fmt;

803 804 805 806 807 808 809 810
    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");
811

812 813 814 815 816
#if !CONFIG_SWSCALE
#   define sws_isSupportedInput(x)  0
#   define sws_isSupportedOutput(x) 0
#endif

817 818 819 820 821 822 823 824 825 826 827 828
    for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
        const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
        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));
    }
829
    return 0;
830 831
}

832 833 834 835 836 837 838 839 840
int show_sample_fmts(const char *opt, const char *arg)
{
    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;
}

Stefano Sabatini's avatar
Stefano Sabatini committed
841 842 843 844 845 846 847 848 849 850
int read_yesno(void)
{
    int c = getchar();
    int yesno = (toupper(c) == 'Y');

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

    return yesno;
}
851

852
int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
853
{
854
    int ret;
855
    FILE *f = fopen(filename, "rb");
856 857

    if (!f) {
858 859
        av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
               strerror(errno));
860 861 862 863 864 865 866
        return AVERROR(errno);
    }
    fseek(f, 0, SEEK_END);
    *size = ftell(f);
    fseek(f, 0, SEEK_SET);
    *bufptr = av_malloc(*size + 1);
    if (!*bufptr) {
867
        av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
868 869 870
        fclose(f);
        return AVERROR(ENOMEM);
    }
871 872 873 874 875 876 877 878 879 880 881 882 883
    ret = fread(*bufptr, 1, *size, f);
    if (ret < *size) {
        av_free(*bufptr);
        if (ferror(f)) {
            av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
                   filename, strerror(errno));
            ret = AVERROR(errno);
        } else
            ret = AVERROR_EOF;
    } else {
        ret = 0;
        (*bufptr)[*size++] = '\0';
    }
884 885

    fclose(f);
886
    return ret;
887
}
888 889 890 891 892 893 894

void init_pts_correction(PtsCorrectionContext *ctx)
{
    ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
    ctx->last_pts = ctx->last_dts = INT64_MIN;
}

895 896
int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts,
                          int64_t dts)
897 898 899 900 901 902 903 904 905 906 907
{
    int64_t pts = AV_NOPTS_VALUE;

    if (dts != AV_NOPTS_VALUE) {
        ctx->num_faulty_dts += dts <= ctx->last_dts;
        ctx->last_dts = dts;
    }
    if (reordered_pts != AV_NOPTS_VALUE) {
        ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
        ctx->last_pts = reordered_pts;
    }
908
    if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
909
        && reordered_pts != AV_NOPTS_VALUE)
910 911 912 913 914 915
        pts = reordered_pts;
    else
        pts = dts;

    return pts;
}
916

917
FILE *get_preset_file(char *filename, size_t filename_size,
918 919
                      const char *preset_name, int is_path,
                      const char *codec_name)
920 921 922
{
    FILE *f = NULL;
    int i;
923 924 925
    const char *base[3] = { getenv("AVCONV_DATADIR"),
                            getenv("HOME"),
                            AVCONV_DATADIR, };
926 927 928 929 930 931 932 933

    if (is_path) {
        av_strlcpy(filename, preset_name, filename_size);
        f = fopen(filename, "r");
    } else {
        for (i = 0; i < 3 && !f; i++) {
            if (!base[i])
                continue;
934
            snprintf(filename, filename_size, "%s%s/%s.avpreset", base[i],
935
                     i != 1 ? "" : "/.avconv", preset_name);
936 937 938
            f = fopen(filename, "r");
            if (!f && codec_name) {
                snprintf(filename, filename_size,
939
                         "%s%s/%s-%s.avpreset",
940 941
                         base[i], i != 1 ? "" : "/.avconv", codec_name,
                         preset_name);
942 943 944 945 946 947 948 949
                f = fopen(filename, "r");
            }
        }
    }

    return f;
}

950 951
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
{
952
    if (*spec <= '9' && *spec >= '0') /* opt:index */
953
        return strtol(spec, NULL, 0) == st->index;
954 955
    else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
             *spec == 't') { /* opt:[vasdt] */
956 957 958
        enum AVMediaType type;

        switch (*spec++) {
959 960 961 962
        case 'v': type = AVMEDIA_TYPE_VIDEO;      break;
        case 'a': type = AVMEDIA_TYPE_AUDIO;      break;
        case 's': type = AVMEDIA_TYPE_SUBTITLE;   break;
        case 'd': type = AVMEDIA_TYPE_DATA;       break;
963
        case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
964
        default:  av_assert0(0);
965 966 967
        }
        if (type != st->codec->codec_type)
            return 0;
</