cmdutils.c 31.2 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 "libavutil/parseutils.h"
39
#include "libavutil/pixdesc.h"
40
#include "libavutil/eval.h"
41
#include "libavutil/dict.h"
42
#include "libavutil/opt.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
43
#include "cmdutils.h"
44
#include "version.h"
Ramiro Polla's avatar
Ramiro Polla committed
45
#if CONFIG_NETWORK
46
#include "libavformat/network.h"
Ramiro Polla's avatar
Ramiro Polla committed
47
#endif
Måns Rullgård's avatar
Måns Rullgård committed
48 49 50
#if HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
Fabrice Bellard's avatar
Fabrice Bellard committed
51

52
const char **opt_names;
53
const char **opt_values;
54
static int opt_name_count;
55
AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
56 57
AVFormatContext *avformat_opts;
struct SwsContext *sws_opts;
58
AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts;
59

60
static const int this_year = 2011;
61

62 63 64 65 66 67
void init_opts(void)
{
    int i;
    for (i = 0; i < AVMEDIA_TYPE_NB; i++)
        avcodec_opts[i] = avcodec_alloc_context2(i);
    avformat_opts = avformat_alloc_context();
68
#if CONFIG_SWSCALE
69
    sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC, NULL, NULL, NULL);
70
#endif
71 72 73 74 75 76 77 78 79
}

void uninit_opts(void)
{
    int i;
    for (i = 0; i < AVMEDIA_TYPE_NB; i++)
        av_freep(&avcodec_opts[i]);
    av_freep(&avformat_opts->key);
    av_freep(&avformat_opts);
80
#if CONFIG_SWSCALE
81 82
    sws_freeContext(sws_opts);
    sws_opts = NULL;
83
#endif
84
    for (i = 0; i < opt_name_count; i++) {
85 86
        av_freep(&opt_names[i]);
        av_freep(&opt_values[i]);
87
    }
88 89
    av_freep(&opt_names);
    av_freep(&opt_values);
90
    opt_name_count = 0;
91 92 93 94
    av_dict_free(&format_opts);
    av_dict_free(&video_opts);
    av_dict_free(&audio_opts);
    av_dict_free(&sub_opts);
95 96
}

97 98 99 100 101
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
{
    vfprintf(stdout, fmt, vl);
}

102 103 104 105
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
{
    char *tail;
    const char *error;
106
    double d = av_strtod(numstr, &tail);
107 108 109 110 111 112
    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";
113 114
    else if (type == OPT_INT && (int)d != d)
        error= "Expected int for %s but found %s\n";
115 116 117 118 119 120
    else
        return d;
    fprintf(stderr, error, context, numstr, min, max);
    exit(1);
}

121 122
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
{
123 124
    int64_t us;
    if (av_parse_time(&us, timestr, is_duration) < 0) {
125 126 127 128 129 130 131
        fprintf(stderr, "Invalid %s specification for %s: %s\n",
                is_duration ? "duration" : "date", context, timestr);
        exit(1);
    }
    return us;
}

132
void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
Fabrice Bellard's avatar
Fabrice Bellard committed
133 134
{
    const OptionDef *po;
135
    int first;
Fabrice Bellard's avatar
Fabrice Bellard committed
136

137 138 139 140 141 142 143 144
    first = 1;
    for(po = options; po->name != NULL; po++) {
        char buf[64];
        if ((po->flags & mask) == value) {
            if (first) {
                printf("%s", msg);
                first = 0;
            }
145
            av_strlcpy(buf, po->name, sizeof(buf));
146
            if (po->flags & HAS_ARG) {
147 148
                av_strlcat(buf, " ", sizeof(buf));
                av_strlcat(buf, po->argname, sizeof(buf));
Fabrice Bellard's avatar
Fabrice Bellard committed
149
            }
150
            printf("-%-17s  %s\n", buf, po->help);
Fabrice Bellard's avatar
Fabrice Bellard committed
151 152 153 154
        }
    }
}

Måns Rullgård's avatar
Måns Rullgård committed
155
static const OptionDef* find_option(const OptionDef *po, const char *name){
156 157 158 159 160 161 162 163
    while (po->name != NULL) {
        if (!strcmp(name, po->name))
            break;
        po++;
    }
    return po;
}

164
#if defined(_WIN32) && !defined(__MINGW32CE__)
165
#include <windows.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 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
/* 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);

    win32_argv_utf8 = av_mallocz(sizeof(char*) * (win32_argc + 1) + buffsize);
    argstr_flat     = (char*)win32_argv_utf8 + sizeof(char*) * (win32_argc + 1);
    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
void parse_options(int argc, char **argv, const OptionDef *options,
226
                   int (* parse_arg_function)(const char *opt, const char *arg))
Fabrice Bellard's avatar
Fabrice Bellard committed
227 228
{
    const char *opt, *arg;
229
    int optindex, handleoptions=1;
Fabrice Bellard's avatar
Fabrice Bellard committed
230 231
    const OptionDef *po;

232 233 234
    /* perform system-dependent conversions for arguments list */
    prepare_app_arguments(&argc, &argv);

Fabrice Bellard's avatar
Fabrice Bellard committed
235 236 237 238
    /* parse options */
    optindex = 1;
    while (optindex < argc) {
        opt = argv[optindex++];
239

240
        if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
241
            int bool_val = 1;
Stefano Sabatini's avatar
Stefano Sabatini committed
242 243 244 245
            if (opt[1] == '-' && opt[2] == '\0') {
                handleoptions = 0;
                continue;
            }
246 247 248
            opt++;
            po= find_option(options, opt);
            if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
249
                /* handle 'no' bool option */
250
                po = find_option(options, opt + 2);
251 252 253 254
                if (!(po->name && (po->flags & OPT_BOOL)))
                    goto unknown_opt;
                bool_val = 0;
            }
255 256
            if (!po->name)
                po= find_option(options, "default");
Fabrice Bellard's avatar
Fabrice Bellard committed
257
            if (!po->name) {
258
unknown_opt:
Fabrice Bellard's avatar
Fabrice Bellard committed
259 260 261 262 263 264 265 266 267 268 269 270 271
                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;
272
                str = av_strdup(arg);
Fabrice Bellard's avatar
Fabrice Bellard committed
273 274
                *po->u.str_arg = str;
            } else if (po->flags & OPT_BOOL) {
275
                *po->u.int_arg = bool_val;
Michael Niedermayer's avatar
Michael Niedermayer committed
276
            } else if (po->flags & OPT_INT) {
277
                *po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
278
            } else if (po->flags & OPT_INT64) {
279
                *po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
Michael Niedermayer's avatar
Michael Niedermayer committed
280
            } else if (po->flags & OPT_FLOAT) {
281
                *po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
282
            } else if (po->u.func_arg) {
283 284 285 286
                if (po->u.func_arg(opt, arg) < 0) {
                    fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
                    exit(1);
                }
Fabrice Bellard's avatar
Fabrice Bellard committed
287
            }
Michael Niedermayer's avatar
Michael Niedermayer committed
288 289
            if(po->flags & OPT_EXIT)
                exit(0);
Fabrice Bellard's avatar
Fabrice Bellard committed
290
        } else {
291 292 293 294
            if (parse_arg_function) {
                if (parse_arg_function(NULL, opt) < 0)
                    exit(1);
            }
Fabrice Bellard's avatar
Fabrice Bellard committed
295 296 297 298
        }
    }
}

299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
#define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
#define SET_PREFIXED_OPTS(ch, flag, output) \
    if (opt[0] == ch && avcodec_opts[0] && (o = av_opt_find(avcodec_opts[0], opt+1, NULL, flag, 0)))\
        av_dict_set(&output, opt+1, arg, FLAGS);
static int opt_default2(const char *opt, const char *arg)
{
    const AVOption *o;
    if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
        if (o->flags & AV_OPT_FLAG_VIDEO_PARAM)
            av_dict_set(&video_opts, opt, arg, FLAGS);
        if (o->flags & AV_OPT_FLAG_AUDIO_PARAM)
            av_dict_set(&audio_opts, opt, arg, FLAGS);
        if (o->flags & AV_OPT_FLAG_SUBTITLE_PARAM)
            av_dict_set(&sub_opts, opt, arg, FLAGS);
    } else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN)))
        av_dict_set(&format_opts, opt, arg, FLAGS);
    else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) {
        // XXX we only support sws_flags, not arbitrary sws options
        int ret = av_set_string3(sws_opts, opt, arg, 1, NULL);
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
            return ret;
        }
    }

    if (!o) {
        SET_PREFIXED_OPTS('v', AV_OPT_FLAG_VIDEO_PARAM,    video_opts)
        SET_PREFIXED_OPTS('a', AV_OPT_FLAG_AUDIO_PARAM,    audio_opts)
        SET_PREFIXED_OPTS('s', AV_OPT_FLAG_SUBTITLE_PARAM, sub_opts)
    }

    if (o)
        return 0;
    fprintf(stderr, "Unrecognized option '%s'\n", opt);
    return AVERROR_OPTION_NOT_FOUND;
}

336 337
int opt_default(const char *opt, const char *arg){
    int type;
338
    int ret= 0;
339 340
    const AVOption *o= NULL;
    int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
341 342
    AVCodec *p = NULL;
    AVOutputFormat *oformat = NULL;
343
    AVInputFormat *iformat = NULL;
344 345

    while ((p = av_codec_next(p))) {
346
        const AVClass *c = p->priv_class;
347 348 349 350 351 352 353 354 355 356 357 358
        if (c && av_find_opt(&c, opt, NULL, 0, 0))
            break;
    }
    if (p)
        goto out;
    while ((oformat = av_oformat_next(oformat))) {
        const AVClass *c = oformat->priv_class;
        if (c && av_find_opt(&c, opt, NULL, 0, 0))
            break;
    }
    if (oformat)
        goto out;
359 360 361 362 363 364 365
    while ((iformat = av_iformat_next(iformat))) {
        const AVClass *c = iformat->priv_class;
        if (c && av_find_opt(&c, opt, NULL, 0, 0))
            break;
    }
    if (iformat)
        goto out;
366

367
    for(type=0; *avcodec_opts && type<AVMEDIA_TYPE_NB && ret>= 0; type++){
368
        const AVOption *o2 = av_opt_find(avcodec_opts[0], opt, NULL, opt_types[type], 0);
369
        if(o2)
370
            ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
371
    }
372
    if(!o && avformat_opts)
373
        ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
374
    if(!o && sws_opts)
375
        ret = av_set_string3(sws_opts, opt, arg, 1, &o);
376
    if(!o){
377
        if (opt[0] == 'a' && avcodec_opts[AVMEDIA_TYPE_AUDIO])
378
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o);
379
        else if(opt[0] == 'v' && avcodec_opts[AVMEDIA_TYPE_VIDEO])
380
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
381
        else if(opt[0] == 's' && avcodec_opts[AVMEDIA_TYPE_SUBTITLE])
382
            ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
383 384
        if (ret >= 0)
            opt += 1;
385 386 387 388
    }
    if (o && ret < 0) {
        fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
        exit(1);
389
    }
390
    if (!o) {
391 392
        fprintf(stderr, "Unrecognized option '%s'\n", opt);
        exit(1);
393
    }
394

395
 out:
396 397 398
    if ((ret = opt_default2(opt, arg)) < 0)
        return ret;

399
//    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));
400

401
    opt_values= av_realloc(opt_values, sizeof(void*)*(opt_name_count+1));
402
    opt_values[opt_name_count] = av_strdup(arg);
403
    opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
404
    opt_names[opt_name_count++] = av_strdup(opt);
405

406
    if ((*avcodec_opts && avcodec_opts[0]->debug) || (avformat_opts && avformat_opts->debug))
407 408 409 410
        av_log_set_level(AV_LOG_DEBUG);
    return 0;
}

411 412
int opt_loglevel(const char *opt, const char *arg)
{
413
    const struct { const char *name; int level; } log_levels[] = {
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
        { "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
446 447
int opt_timelimit(const char *opt, const char *arg)
{
Måns Rullgård's avatar
Måns Rullgård committed
448
#if HAVE_SETRLIMIT
Måns Rullgård's avatar
Måns Rullgård committed
449 450 451 452 453 454 455 456 457 458
    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;
}

459 460
static void *alloc_priv_context(int size, const AVClass *class)
{
461 462
    void *p = av_mallocz(size);
    if (p) {
463
        *(const AVClass **)p = class;
464 465 466 467 468
        av_opt_set_defaults(p);
    }
    return p;
}

469
void set_context_opts(void *ctx, void *opts_ctx, int flags, AVCodec *codec)
470 471
{
    int i;
472 473 474
    void *priv_ctx=NULL;
    if(!strcmp("AVCodecContext", (*(AVClass**)ctx)->class_name)){
        AVCodecContext *avctx= ctx;
475 476 477
        if(codec && codec->priv_class){
            if(!avctx->priv_data && codec->priv_data_size)
                avctx->priv_data= alloc_priv_context(codec->priv_data_size, codec->priv_class);
478 479
            priv_ctx= avctx->priv_data;
        }
480 481 482 483
    } else if (!strcmp("AVFormatContext", (*(AVClass**)ctx)->class_name)) {
        AVFormatContext *avctx = ctx;
        if (avctx->oformat && avctx->oformat->priv_class) {
            priv_ctx = avctx->priv_data;
484 485
        } else if (avctx->iformat && avctx->iformat->priv_class) {
            priv_ctx = avctx->priv_data;
486
        }
487
    }
488

489 490 491
    for(i=0; i<opt_name_count; i++){
        char buf[256];
        const AVOption *opt;
492 493 494
        const char *str;
        if (priv_ctx) {
            if (av_find_opt(priv_ctx, opt_names[i], NULL, flags, flags)) {
495
                if (av_set_string3(priv_ctx, opt_names[i], opt_values[i], 1, NULL) < 0) {
496 497 498 499 500 501 502 503 504 505 506 507
                    fprintf(stderr, "Invalid value '%s' for option '%s'\n",
                            opt_names[i], opt_values[i]);
                    exit(1);
                }
            } else
                goto global;
        } else {
        global:
            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))
                av_set_string3(ctx, opt_names[i], str, 1, NULL);
508
        }
509 510 511
    }
}

Fabrice Bellard's avatar
Fabrice Bellard committed
512 513
void print_error(const char *filename, int err)
{
514
    char errbuf[128];
515
    const char *errbuf_ptr = errbuf;
516

517 518 519
    if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
        errbuf_ptr = strerror(AVUNERROR(err));
    fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
Fabrice Bellard's avatar
Fabrice Bellard committed
520
}
521

522 523
static int warned_cfg = 0;

524 525
#define INDENT        1
#define SHOW_VERSION  2
526
#define SHOW_CONFIG   4
527

Stefano Sabatini's avatar
Stefano Sabatini committed
528
#define PRINT_LIB_INFO(outstream,libname,LIBNAME,flags)                 \
529
    if (CONFIG_##LIBNAME) {                                             \
530
        const char *indent = flags & INDENT? "  " : "";                 \
531
        if (flags & SHOW_VERSION) {                                     \
Stefano Sabatini's avatar
Stefano Sabatini committed
532
            unsigned int version = libname##_version();                 \
533
            fprintf(outstream, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n", \
534
                    indent, #libname,                                   \
Stefano Sabatini's avatar
Stefano Sabatini committed
535 536 537 538
                    LIB##LIBNAME##_VERSION_MAJOR,                       \
                    LIB##LIBNAME##_VERSION_MINOR,                       \
                    LIB##LIBNAME##_VERSION_MICRO,                       \
                    version >> 16, version >> 8 & 0xff, version & 0xff); \
539
        }                                                               \
540 541
        if (flags & SHOW_CONFIG) {                                      \
            const char *cfg = libname##_configuration();                \
542
            if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \
543 544 545
                if (!warned_cfg) {                                      \
                    fprintf(outstream,                                  \
                            "%sWARNING: library configuration mismatch\n", \
546
                            indent);                                    \
547 548 549
                    warned_cfg = 1;                                     \
                }                                                       \
                fprintf(stderr, "%s%-11s configuration: %s\n",          \
550
                        indent, #libname, cfg);                         \
551 552
            }                                                           \
        }                                                               \
553
    }                                                                   \
554

Stefano Sabatini's avatar
Stefano Sabatini committed
555
static void print_all_libs_info(FILE* outstream, int flags)
556
{
Stefano Sabatini's avatar
Stefano Sabatini committed
557 558 559 560 561 562 563
    PRINT_LIB_INFO(outstream, avutil,   AVUTIL,   flags);
    PRINT_LIB_INFO(outstream, avcodec,  AVCODEC,  flags);
    PRINT_LIB_INFO(outstream, avformat, AVFORMAT, flags);
    PRINT_LIB_INFO(outstream, avdevice, AVDEVICE, flags);
    PRINT_LIB_INFO(outstream, avfilter, AVFILTER, flags);
    PRINT_LIB_INFO(outstream, swscale,  SWSCALE,  flags);
    PRINT_LIB_INFO(outstream, postproc, POSTPROC, flags);
564 565
}

566
void show_banner(void)
567
{
568
    fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n",
569
            program_name, program_birth_year, this_year);
570 571
    fprintf(stderr, "  built on %s %s with %s %s\n",
            __DATE__, __TIME__, CC_TYPE, CC_VERSION);
572
    fprintf(stderr, "  configuration: " FFMPEG_CONFIGURATION "\n");
573
    print_all_libs_info(stderr, INDENT|SHOW_CONFIG);
Stefano Sabatini's avatar
Stefano Sabatini committed
574
    print_all_libs_info(stderr, INDENT|SHOW_VERSION);
575 576
}

577
int opt_version(const char *opt, const char *arg) {
578
    printf("%s " FFMPEG_VERSION "\n", program_name);
Stefano Sabatini's avatar
Stefano Sabatini committed
579
    print_all_libs_info(stdout, SHOW_VERSION);
580
    return 0;
581 582
}

583
int opt_license(const char *opt, const char *arg)
584
{
585
    printf(
586
#if CONFIG_NONFREE
587 588 589
    "This version of %s has nonfree parts compiled in.\n"
    "Therefore it is not legally redistributable.\n",
    program_name
590 591 592 593 594 595 596 597 598 599 600 601 602 603
#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
604
#elif CONFIG_GPL
605
    "%s is free software; you can redistribute it and/or modify\n"
606 607 608 609
    "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"
610
    "%s is distributed in the hope that it will be useful,\n"
611 612 613 614 615
    "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"
616 617 618
    "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
619 620 621 622 623 624 625 626 627 628 629 630 631 632
#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
633
#else
634
    "%s is free software; you can redistribute it and/or\n"
635 636 637 638
    "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"
639
    "%s is distributed in the hope that it will be useful,\n"
640 641 642 643 644
    "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"
645 646 647
    "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
648
#endif
649
    );
650
    return 0;
651
}
652

653
int opt_formats(const char *opt, const char *arg)
654 655 656 657 658
{
    AVInputFormat *ifmt=NULL;
    AVOutputFormat *ofmt=NULL;
    const char *last_name;

659 660 661 662 663
    printf(
        "File formats:\n"
        " D. = Demuxing supported\n"
        " .E = Muxing supported\n"
        " --\n");
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 695 696 697 698 699
    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:" ");
    }
700
    return 0;
701
}
702

703
int opt_codecs(const char *opt, const char *arg)
704 705 706
{
    AVCodec *p=NULL, *p2;
    const char *last_name;
707 708 709 710 711 712 713 714 715 716 717
    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");
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
    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) {
743
        case AVMEDIA_TYPE_VIDEO:
744 745
            type_str = "V";
            break;
746
        case AVMEDIA_TYPE_AUDIO:
747 748
            type_str = "A";
            break;
749
        case AVMEDIA_TYPE_SUBTITLE:
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
            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");
771 772 773 774 775 776
    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");
777
    return 0;
778 779
}

780
int opt_bsfs(const char *opt, const char *arg)
781 782
{
    AVBitStreamFilter *bsf=NULL;
783 784 785

    printf("Bitstream filters:\n");
    while((bsf = av_bitstream_filter_next(bsf)))
786
        printf("%s\n", bsf->name);
787
    printf("\n");
788
    return 0;
789 790
}

791
int opt_protocols(const char *opt, const char *arg)
792 793
{
    URLProtocol *up=NULL;
794

795 796 797 798 799 800
    printf("Supported file protocols:\n"
           "I.. = Input  supported\n"
           ".O. = Output supported\n"
           "..S = Seek   supported\n"
           "FLAGS NAME\n"
           "----- \n");
801
    while((up = av_protocol_next(up)))
802 803 804 805 806
        printf("%c%c%c   %s\n",
               up->url_read  ? 'I' : '.',
               up->url_write ? 'O' : '.',
               up->url_seek  ? 'S' : '.',
               up->name);
807
    return 0;
808
}
809

810
int opt_filters(const char *opt, const char *arg)
811
{
812
    AVFilter av_unused(**filter) = NULL;
813 814

    printf("Filters:\n");
815
#if CONFIG_AVFILTER
816 817
    while ((filter = av_filter_next(filter)) && *filter)
        printf("%-16s %s\n", (*filter)->name, (*filter)->description);
818
#endif
819
    return 0;
820 821
}

822
int opt_pix_fmts(const char *opt, const char *arg)
823
{
824 825 826 827 828 829 830 831 832 833 834 835
    enum PixelFormat pix_fmt;

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

836 837 838 839 840
#if !CONFIG_SWSCALE
#   define sws_isSupportedInput(x)  0
#   define sws_isSupportedOutput(x) 0
#endif

841 842 843 844 845 846 847 848 849 850 851 852
    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));
    }
853
    return 0;
854 855
}

856 857 858 859 860 861 862 863 864 865
int read_yesno(void)
{
    int c = getchar();
    int yesno = (toupper(c) == 'Y');

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

    return yesno;
}
866 867 868

int read_file(const char *filename, char **bufptr, size_t *size)
{
869
    FILE *f = fopen(filename, "rb");
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889

    if (!f) {
        fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
        return AVERROR(errno);
    }
    fseek(f, 0, SEEK_END);
    *size = ftell(f);
    fseek(f, 0, SEEK_SET);
    *bufptr = av_malloc(*size + 1);
    if (!*bufptr) {
        fprintf(stderr, "Could not allocate file buffer\n");
        fclose(f);
        return AVERROR(ENOMEM);
    }
    fread(*bufptr, 1, *size, f);
    (*bufptr)[*size++] = '\0';

    fclose(f);
    return 0;
}
890

891 892 893 894 895 896 897 898 899 900 901 902 903 904
FILE *get_preset_file(char *filename, size_t filename_size,
                      const char *preset_name, int is_path, const char *codec_name)
{
    FILE *f = NULL;
    int i;
    const char *base[3]= { getenv("FFMPEG_DATADIR"),
                           getenv("HOME"),
                           FFMPEG_DATADIR,
                         };

    if (is_path) {
        av_strlcpy(filename, preset_name, filename_size);
        f = fopen(filename, "r");
    } else {
Gianluigi Tiesi's avatar
Gianluigi Tiesi committed
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921
#ifdef _WIN32
        char datadir[MAX_PATH], *ls;
        base[2] = NULL;

        if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
        {
            for (ls = datadir; ls < datadir + strlen(datadir); ls++)
                if (*ls == '\\') *ls = '/';

            if (ls = strrchr(datadir, '/'))
            {
                *ls = 0;
                strncat(datadir, "/ffpresets",  sizeof(datadir) - 1 - strlen(datadir));
                base[2] = datadir;
            }
        }
#endif
922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
        for (i = 0; i < 3 && !f; i++) {
            if (!base[i])
                continue;
            snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name);
            f = fopen(filename, "r");
            if (!f && codec_name) {
                snprintf(filename, filename_size,
                         "%s%s/%s-%s.ffpreset", base[i],  i != 1 ? "" : "/.ffmpeg", codec_name, preset_name);
                f = fopen(filename, "r");
            }
        }
    }

    return f;
}