Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * ffmpeg option parsing
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
 
21
#include 
22
 
23
#include "ffmpeg.h"
24
#include "cmdutils.h"
25
 
26
#include "libavformat/avformat.h"
27
 
28
#include "libavcodec/avcodec.h"
29
 
30
#include "libavfilter/avfilter.h"
31
 
32
#include "libavutil/avassert.h"
33
#include "libavutil/avstring.h"
34
#include "libavutil/avutil.h"
35
#include "libavutil/channel_layout.h"
36
#include "libavutil/intreadwrite.h"
37
#include "libavutil/fifo.h"
38
#include "libavutil/mathematics.h"
39
#include "libavutil/opt.h"
40
#include "libavutil/parseutils.h"
41
#include "libavutil/pixdesc.h"
42
#include "libavutil/pixfmt.h"
43
 
44
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
45
{\
46
    int i, ret;\
47
    for (i = 0; i < o->nb_ ## name; i++) {\
48
        char *spec = o->name[i].specifier;\
49
        if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
50
            outvar = o->name[i].u.type;\
51
        else if (ret < 0)\
52
            exit_program(1);\
53
    }\
54
}
55
 
56
#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\
57
{\
58
    int i;\
59
    for (i = 0; i < o->nb_ ## name; i++) {\
60
        char *spec = o->name[i].specifier;\
61
        if (!strcmp(spec, mediatype))\
62
            outvar = o->name[i].u.type;\
63
    }\
64
}
65
char *vstats_filename;
66
 
67
float audio_drift_threshold = 0.1;
68
float dts_delta_threshold   = 10;
69
float dts_error_threshold   = 3600*30;
70
 
71
int audio_volume      = 256;
72
int audio_sync_method = 0;
73
int video_sync_method = VSYNC_AUTO;
74
int do_deinterlace    = 0;
75
int do_benchmark      = 0;
76
int do_benchmark_all  = 0;
77
int do_hex_dump       = 0;
78
int do_pkt_dump       = 0;
79
int copy_ts           = 0;
80
int copy_tb           = -1;
81
int debug_ts          = 0;
82
int exit_on_error     = 0;
83
int print_stats       = -1;
84
int qp_hist           = 0;
85
int stdin_interaction = 1;
86
int frame_bits_per_raw_sample = 0;
87
float max_error_rate  = 2.0/3;
88
 
89
 
90
static int intra_only         = 0;
91
static int file_overwrite     = 0;
92
static int no_file_overwrite  = 0;
93
static int video_discard      = 0;
94
static int intra_dc_precision = 8;
95
static int do_psnr            = 0;
96
static int input_sync;
97
static int override_ffserver  = 0;
98
 
99
static void uninit_options(OptionsContext *o)
100
{
101
    const OptionDef *po = options;
102
    int i;
103
 
104
    /* all OPT_SPEC and OPT_STRING can be freed in generic way */
105
    while (po->name) {
106
        void *dst = (uint8_t*)o + po->u.off;
107
 
108
        if (po->flags & OPT_SPEC) {
109
            SpecifierOpt **so = dst;
110
            int i, *count = (int*)(so + 1);
111
            for (i = 0; i < *count; i++) {
112
                av_freep(&(*so)[i].specifier);
113
                if (po->flags & OPT_STRING)
114
                    av_freep(&(*so)[i].u.str);
115
            }
116
            av_freep(so);
117
            *count = 0;
118
        } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
119
            av_freep(dst);
120
        po++;
121
    }
122
 
123
    for (i = 0; i < o->nb_stream_maps; i++)
124
        av_freep(&o->stream_maps[i].linklabel);
125
    av_freep(&o->stream_maps);
126
    av_freep(&o->audio_channel_maps);
127
    av_freep(&o->streamid_map);
128
    av_freep(&o->attachments);
129
}
130
 
131
static void init_options(OptionsContext *o)
132
{
133
    memset(o, 0, sizeof(*o));
134
 
135
    o->stop_time = INT64_MAX;
136
    o->mux_max_delay  = 0.7;
137
    o->start_time     = AV_NOPTS_VALUE;
138
    o->recording_time = INT64_MAX;
139
    o->limit_filesize = UINT64_MAX;
140
    o->chapters_input_file = INT_MAX;
141
    o->accurate_seek  = 1;
142
}
143
 
144
/* return a copy of the input with the stream specifiers removed from the keys */
145
static AVDictionary *strip_specifiers(AVDictionary *dict)
146
{
147
    AVDictionaryEntry *e = NULL;
148
    AVDictionary    *ret = NULL;
149
 
150
    while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
151
        char *p = strchr(e->key, ':');
152
 
153
        if (p)
154
            *p = 0;
155
        av_dict_set(&ret, e->key, e->value, 0);
156
        if (p)
157
            *p = ':';
158
    }
159
    return ret;
160
}
161
 
162
static int opt_sameq(void *optctx, const char *opt, const char *arg)
163
{
164
    av_log(NULL, AV_LOG_ERROR, "Option '%s' was removed. "
165
           "If you are looking for an option to preserve the quality (which is not "
166
           "what -%s was for), use -qscale 0 or an equivalent quality factor option.\n",
167
           opt, opt);
168
    return AVERROR(EINVAL);
169
}
170
 
171
static int opt_video_channel(void *optctx, const char *opt, const char *arg)
172
{
173
    av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -channel.\n");
174
    return opt_default(optctx, "channel", arg);
175
}
176
 
177
static int opt_video_standard(void *optctx, const char *opt, const char *arg)
178
{
179
    av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -standard.\n");
180
    return opt_default(optctx, "standard", arg);
181
}
182
 
183
static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
184
{
185
    OptionsContext *o = optctx;
186
    return parse_option(o, "codec:a", arg, options);
187
}
188
 
189
static int opt_video_codec(void *optctx, const char *opt, const char *arg)
190
{
191
    OptionsContext *o = optctx;
192
    return parse_option(o, "codec:v", arg, options);
193
}
194
 
195
static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
196
{
197
    OptionsContext *o = optctx;
198
    return parse_option(o, "codec:s", arg, options);
199
}
200
 
201
static int opt_data_codec(void *optctx, const char *opt, const char *arg)
202
{
203
    OptionsContext *o = optctx;
204
    return parse_option(o, "codec:d", arg, options);
205
}
206
 
207
static int opt_map(void *optctx, const char *opt, const char *arg)
208
{
209
    OptionsContext *o = optctx;
210
    StreamMap *m = NULL;
211
    int i, negative = 0, file_idx;
212
    int sync_file_idx = -1, sync_stream_idx = 0;
213
    char *p, *sync;
214
    char *map;
215
 
216
    if (*arg == '-') {
217
        negative = 1;
218
        arg++;
219
    }
220
    map = av_strdup(arg);
221
 
222
    /* parse sync stream first, just pick first matching stream */
223
    if (sync = strchr(map, ',')) {
224
        *sync = 0;
225
        sync_file_idx = strtol(sync + 1, &sync, 0);
226
        if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
227
            av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
228
            exit_program(1);
229
        }
230
        if (*sync)
231
            sync++;
232
        for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
233
            if (check_stream_specifier(input_files[sync_file_idx]->ctx,
234
                                       input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
235
                sync_stream_idx = i;
236
                break;
237
            }
238
        if (i == input_files[sync_file_idx]->nb_streams) {
239
            av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
240
                                       "match any streams.\n", arg);
241
            exit_program(1);
242
        }
243
    }
244
 
245
 
246
    if (map[0] == '[') {
247
        /* this mapping refers to lavfi output */
248
        const char *c = map + 1;
249
        GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
250
        m = &o->stream_maps[o->nb_stream_maps - 1];
251
        m->linklabel = av_get_token(&c, "]");
252
        if (!m->linklabel) {
253
            av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
254
            exit_program(1);
255
        }
256
    } else {
257
        file_idx = strtol(map, &p, 0);
258
        if (file_idx >= nb_input_files || file_idx < 0) {
259
            av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
260
            exit_program(1);
261
        }
262
        if (negative)
263
            /* disable some already defined maps */
264
            for (i = 0; i < o->nb_stream_maps; i++) {
265
                m = &o->stream_maps[i];
266
                if (file_idx == m->file_index &&
267
                    check_stream_specifier(input_files[m->file_index]->ctx,
268
                                           input_files[m->file_index]->ctx->streams[m->stream_index],
269
                                           *p == ':' ? p + 1 : p) > 0)
270
                    m->disabled = 1;
271
            }
272
        else
273
            for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
274
                if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
275
                            *p == ':' ? p + 1 : p) <= 0)
276
                    continue;
277
                GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
278
                m = &o->stream_maps[o->nb_stream_maps - 1];
279
 
280
                m->file_index   = file_idx;
281
                m->stream_index = i;
282
 
283
                if (sync_file_idx >= 0) {
284
                    m->sync_file_index   = sync_file_idx;
285
                    m->sync_stream_index = sync_stream_idx;
286
                } else {
287
                    m->sync_file_index   = file_idx;
288
                    m->sync_stream_index = i;
289
                }
290
            }
291
    }
292
 
293
    if (!m) {
294
        av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
295
        exit_program(1);
296
    }
297
 
298
    av_freep(&map);
299
    return 0;
300
}
301
 
302
static int opt_attach(void *optctx, const char *opt, const char *arg)
303
{
304
    OptionsContext *o = optctx;
305
    GROW_ARRAY(o->attachments, o->nb_attachments);
306
    o->attachments[o->nb_attachments - 1] = arg;
307
    return 0;
308
}
309
 
310
static int opt_map_channel(void *optctx, const char *opt, const char *arg)
311
{
312
    OptionsContext *o = optctx;
313
    int n;
314
    AVStream *st;
315
    AudioChannelMap *m;
316
 
317
    GROW_ARRAY(o->audio_channel_maps, o->nb_audio_channel_maps);
318
    m = &o->audio_channel_maps[o->nb_audio_channel_maps - 1];
319
 
320
    /* muted channel syntax */
321
    n = sscanf(arg, "%d:%d.%d", &m->channel_idx, &m->ofile_idx, &m->ostream_idx);
322
    if ((n == 1 || n == 3) && m->channel_idx == -1) {
323
        m->file_idx = m->stream_idx = -1;
324
        if (n == 1)
325
            m->ofile_idx = m->ostream_idx = -1;
326
        return 0;
327
    }
328
 
329
    /* normal syntax */
330
    n = sscanf(arg, "%d.%d.%d:%d.%d",
331
               &m->file_idx,  &m->stream_idx, &m->channel_idx,
332
               &m->ofile_idx, &m->ostream_idx);
333
 
334
    if (n != 3 && n != 5) {
335
        av_log(NULL, AV_LOG_FATAL, "Syntax error, mapchan usage: "
336
               "[file.stream.channel|-1][:syncfile:syncstream]\n");
337
        exit_program(1);
338
    }
339
 
340
    if (n != 5) // only file.stream.channel specified
341
        m->ofile_idx = m->ostream_idx = -1;
342
 
343
    /* check input */
344
    if (m->file_idx < 0 || m->file_idx >= nb_input_files) {
345
        av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file index: %d\n",
346
               m->file_idx);
347
        exit_program(1);
348
    }
349
    if (m->stream_idx < 0 ||
350
        m->stream_idx >= input_files[m->file_idx]->nb_streams) {
351
        av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file stream index #%d.%d\n",
352
               m->file_idx, m->stream_idx);
353
        exit_program(1);
354
    }
355
    st = input_files[m->file_idx]->ctx->streams[m->stream_idx];
356
    if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
357
        av_log(NULL, AV_LOG_FATAL, "mapchan: stream #%d.%d is not an audio stream.\n",
358
               m->file_idx, m->stream_idx);
359
        exit_program(1);
360
    }
361
    if (m->channel_idx < 0 || m->channel_idx >= st->codec->channels) {
362
        av_log(NULL, AV_LOG_FATAL, "mapchan: invalid audio channel #%d.%d.%d\n",
363
               m->file_idx, m->stream_idx, m->channel_idx);
364
        exit_program(1);
365
    }
366
    return 0;
367
}
368
 
369
/**
370
 * Parse a metadata specifier passed as 'arg' parameter.
371
 * @param arg  metadata string to parse
372
 * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
373
 * @param index for type c/p, chapter/program index is written here
374
 * @param stream_spec for type s, the stream specifier is written here
375
 */
376
static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
377
{
378
    if (*arg) {
379
        *type = *arg;
380
        switch (*arg) {
381
        case 'g':
382
            break;
383
        case 's':
384
            if (*(++arg) && *arg != ':') {
385
                av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
386
                exit_program(1);
387
            }
388
            *stream_spec = *arg == ':' ? arg + 1 : "";
389
            break;
390
        case 'c':
391
        case 'p':
392
            if (*(++arg) == ':')
393
                *index = strtol(++arg, NULL, 0);
394
            break;
395
        default:
396
            av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
397
            exit_program(1);
398
        }
399
    } else
400
        *type = 'g';
401
}
402
 
403
static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
404
{
405
    AVDictionary **meta_in = NULL;
406
    AVDictionary **meta_out = NULL;
407
    int i, ret = 0;
408
    char type_in, type_out;
409
    const char *istream_spec = NULL, *ostream_spec = NULL;
410
    int idx_in = 0, idx_out = 0;
411
 
412
    parse_meta_type(inspec,  &type_in,  &idx_in,  &istream_spec);
413
    parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
414
 
415
    if (!ic) {
416
        if (type_out == 'g' || !*outspec)
417
            o->metadata_global_manual = 1;
418
        if (type_out == 's' || !*outspec)
419
            o->metadata_streams_manual = 1;
420
        if (type_out == 'c' || !*outspec)
421
            o->metadata_chapters_manual = 1;
422
        return 0;
423
    }
424
 
425
    if (type_in == 'g' || type_out == 'g')
426
        o->metadata_global_manual = 1;
427
    if (type_in == 's' || type_out == 's')
428
        o->metadata_streams_manual = 1;
429
    if (type_in == 'c' || type_out == 'c')
430
        o->metadata_chapters_manual = 1;
431
 
432
    /* ic is NULL when just disabling automatic mappings */
433
    if (!ic)
434
        return 0;
435
 
436
#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
437
    if ((index) < 0 || (index) >= (nb_elems)) {\
438
        av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
439
                (desc), (index));\
440
        exit_program(1);\
441
    }
442
 
443
#define SET_DICT(type, meta, context, index)\
444
        switch (type) {\
445
        case 'g':\
446
            meta = &context->metadata;\
447
            break;\
448
        case 'c':\
449
            METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
450
            meta = &context->chapters[index]->metadata;\
451
            break;\
452
        case 'p':\
453
            METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
454
            meta = &context->programs[index]->metadata;\
455
            break;\
456
        case 's':\
457
            break; /* handled separately below */ \
458
        default: av_assert0(0);\
459
        }\
460
 
461
    SET_DICT(type_in, meta_in, ic, idx_in);
462
    SET_DICT(type_out, meta_out, oc, idx_out);
463
 
464
    /* for input streams choose first matching stream */
465
    if (type_in == 's') {
466
        for (i = 0; i < ic->nb_streams; i++) {
467
            if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
468
                meta_in = &ic->streams[i]->metadata;
469
                break;
470
            } else if (ret < 0)
471
                exit_program(1);
472
        }
473
        if (!meta_in) {
474
            av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match  any streams.\n", istream_spec);
475
            exit_program(1);
476
        }
477
    }
478
 
479
    if (type_out == 's') {
480
        for (i = 0; i < oc->nb_streams; i++) {
481
            if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
482
                meta_out = &oc->streams[i]->metadata;
483
                av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
484
            } else if (ret < 0)
485
                exit_program(1);
486
        }
487
    } else
488
        av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
489
 
490
    return 0;
491
}
492
 
493
static int opt_recording_timestamp(void *optctx, const char *opt, const char *arg)
494
{
495
    OptionsContext *o = optctx;
496
    char buf[128];
497
    int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6;
498
    struct tm time = *gmtime((time_t*)&recording_timestamp);
499
    strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time);
500
    parse_option(o, "metadata", buf, options);
501
 
502
    av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata "
503
                                 "tag instead.\n", opt);
504
    return 0;
505
}
506
 
507
static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
508
{
509
    const AVCodecDescriptor *desc;
510
    const char *codec_string = encoder ? "encoder" : "decoder";
511
    AVCodec *codec;
512
 
513
    codec = encoder ?
514
        avcodec_find_encoder_by_name(name) :
515
        avcodec_find_decoder_by_name(name);
516
 
517
    if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
518
        codec = encoder ? avcodec_find_encoder(desc->id) :
519
                          avcodec_find_decoder(desc->id);
520
        if (codec)
521
            av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
522
                   codec_string, codec->name, desc->name);
523
    }
524
 
525
    if (!codec) {
526
        av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
527
        exit_program(1);
528
    }
529
    if (codec->type != type) {
530
        av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
531
        exit_program(1);
532
    }
533
    return codec;
534
}
535
 
536
static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
537
{
538
    char *codec_name = NULL;
539
 
540
    MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
541
    if (codec_name) {
542
        AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
543
        st->codec->codec_id = codec->id;
544
        return codec;
545
    } else
546
        return avcodec_find_decoder(st->codec->codec_id);
547
}
548
 
549
/* Add all the streams from the given input file to the global
550
 * list of input streams. */
551
static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
552
{
553
    int i;
554
    char *next, *codec_tag = NULL;
555
 
556
    for (i = 0; i < ic->nb_streams; i++) {
557
        AVStream *st = ic->streams[i];
558
        AVCodecContext *dec = st->codec;
559
        InputStream *ist = av_mallocz(sizeof(*ist));
560
        char *framerate = NULL;
561
 
562
        if (!ist)
563
            exit_program(1);
564
 
565
        GROW_ARRAY(input_streams, nb_input_streams);
566
        input_streams[nb_input_streams - 1] = ist;
567
 
568
        ist->st = st;
569
        ist->file_index = nb_input_files;
570
        ist->discard = 1;
571
        st->discard  = AVDISCARD_ALL;
572
 
573
        ist->ts_scale = 1.0;
574
        MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
575
 
576
        MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
577
        if (codec_tag) {
578
            uint32_t tag = strtol(codec_tag, &next, 0);
579
            if (*next)
580
                tag = AV_RL32(codec_tag);
581
            st->codec->codec_tag = tag;
582
        }
583
 
584
        ist->dec = choose_decoder(o, ic, st);
585
        ist->opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, ist->dec);
586
 
587
        ist->reinit_filters = -1;
588
        MATCH_PER_STREAM_OPT(reinit_filters, i, ist->reinit_filters, ic, st);
589
 
590
        ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE;
591
 
592
        switch (dec->codec_type) {
593
        case AVMEDIA_TYPE_VIDEO:
594
            if(!ist->dec)
595
                ist->dec = avcodec_find_decoder(dec->codec_id);
596
            if (av_codec_get_lowres(dec)) {
597
                dec->flags |= CODEC_FLAG_EMU_EDGE;
598
            }
599
 
600
            ist->resample_height  = dec->height;
601
            ist->resample_width   = dec->width;
602
            ist->resample_pix_fmt = dec->pix_fmt;
603
 
604
            MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
605
            if (framerate && av_parse_video_rate(&ist->framerate,
606
                                                 framerate) < 0) {
607
                av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
608
                       framerate);
609
                exit_program(1);
610
            }
611
 
612
            ist->top_field_first = -1;
613
            MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
614
 
615
            break;
616
        case AVMEDIA_TYPE_AUDIO:
617
            ist->guess_layout_max = INT_MAX;
618
            MATCH_PER_STREAM_OPT(guess_layout_max, i, ist->guess_layout_max, ic, st);
619
            guess_input_channel_layout(ist);
620
 
621
            ist->resample_sample_fmt     = dec->sample_fmt;
622
            ist->resample_sample_rate    = dec->sample_rate;
623
            ist->resample_channels       = dec->channels;
624
            ist->resample_channel_layout = dec->channel_layout;
625
 
626
            break;
627
        case AVMEDIA_TYPE_DATA:
628
        case AVMEDIA_TYPE_SUBTITLE: {
629
            char *canvas_size = NULL;
630
            if(!ist->dec)
631
                ist->dec = avcodec_find_decoder(dec->codec_id);
632
            MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
633
            MATCH_PER_STREAM_OPT(canvas_sizes, str, canvas_size, ic, st);
634
            if (canvas_size &&
635
                av_parse_video_size(&dec->width, &dec->height, canvas_size) < 0) {
636
                av_log(NULL, AV_LOG_FATAL, "Invalid canvas size: %s.\n", canvas_size);
637
                exit_program(1);
638
            }
639
            break;
640
        }
641
        case AVMEDIA_TYPE_ATTACHMENT:
642
        case AVMEDIA_TYPE_UNKNOWN:
643
            break;
644
        default:
645
            abort();
646
        }
647
    }
648
}
649
 
650
static void assert_file_overwrite(const char *filename)
651
{
652
    if (file_overwrite && no_file_overwrite) {
653
        fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
654
        exit_program(1);
655
    }
656
 
657
    if (!file_overwrite &&
658
        (strchr(filename, ':') == NULL || filename[1] == ':' ||
659
         av_strstart(filename, "file:", NULL))) {
660
        if (avio_check(filename, 0) == 0) {
661
            if (stdin_interaction && !no_file_overwrite) {
662
                fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
663
                fflush(stderr);
664
                term_exit();
665
                signal(SIGINT, SIG_DFL);
666
                if (!read_yesno()) {
667
                    av_log(NULL, AV_LOG_FATAL, "Not overwriting - exiting\n");
668
                    exit_program(1);
669
                }
670
                term_init();
671
            }
672
            else {
673
                av_log(NULL, AV_LOG_FATAL, "File '%s' already exists. Exiting.\n", filename);
674
                exit_program(1);
675
            }
676
        }
677
    }
678
}
679
 
680
static void dump_attachment(AVStream *st, const char *filename)
681
{
682
    int ret;
683
    AVIOContext *out = NULL;
684
    AVDictionaryEntry *e;
685
 
686
    if (!st->codec->extradata_size) {
687
        av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
688
               nb_input_files - 1, st->index);
689
        return;
690
    }
691
    if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
692
        filename = e->value;
693
    if (!*filename) {
694
        av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
695
               "in stream #%d:%d.\n", nb_input_files - 1, st->index);
696
        exit_program(1);
697
    }
698
 
699
    assert_file_overwrite(filename);
700
 
701
    if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
702
        av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
703
               filename);
704
        exit_program(1);
705
    }
706
 
707
    avio_write(out, st->codec->extradata, st->codec->extradata_size);
708
    avio_flush(out);
709
    avio_close(out);
710
}
711
 
712
static int open_input_file(OptionsContext *o, const char *filename)
713
{
714
    InputFile *f;
715
    AVFormatContext *ic;
716
    AVInputFormat *file_iformat = NULL;
717
    int err, i, ret;
718
    int64_t timestamp;
719
    uint8_t buf[128];
720
    AVDictionary **opts;
721
    AVDictionary *unused_opts = NULL;
722
    AVDictionaryEntry *e = NULL;
723
    int orig_nb_streams;                     // number of streams before avformat_find_stream_info
724
    char *   video_codec_name = NULL;
725
    char *   audio_codec_name = NULL;
726
    char *subtitle_codec_name = NULL;
727
 
728
    if (o->format) {
729
        if (!(file_iformat = av_find_input_format(o->format))) {
730
            av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
731
            exit_program(1);
732
        }
733
    }
734
 
735
    if (!strcmp(filename, "-"))
736
        filename = "pipe:";
737
 
738
    stdin_interaction &= strncmp(filename, "pipe:", 5) &&
739
                         strcmp(filename, "/dev/stdin");
740
 
741
    /* get default parameters from command line */
742
    ic = avformat_alloc_context();
743
    if (!ic) {
744
        print_error(filename, AVERROR(ENOMEM));
745
        exit_program(1);
746
    }
747
    if (o->nb_audio_sample_rate) {
748
        snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
749
        av_dict_set(&o->g->format_opts, "sample_rate", buf, 0);
750
    }
751
    if (o->nb_audio_channels) {
752
        /* because we set audio_channels based on both the "ac" and
753
         * "channel_layout" options, we need to check that the specified
754
         * demuxer actually has the "channels" option before setting it */
755
        if (file_iformat && file_iformat->priv_class &&
756
            av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
757
                        AV_OPT_SEARCH_FAKE_OBJ)) {
758
            snprintf(buf, sizeof(buf), "%d",
759
                     o->audio_channels[o->nb_audio_channels - 1].u.i);
760
            av_dict_set(&o->g->format_opts, "channels", buf, 0);
761
        }
762
    }
763
    if (o->nb_frame_rates) {
764
        /* set the format-level framerate option;
765
         * this is important for video grabbers, e.g. x11 */
766
        if (file_iformat && file_iformat->priv_class &&
767
            av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
768
                        AV_OPT_SEARCH_FAKE_OBJ)) {
769
            av_dict_set(&o->g->format_opts, "framerate",
770
                        o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
771
        }
772
    }
773
    if (o->nb_frame_sizes) {
774
        av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
775
    }
776
    if (o->nb_frame_pix_fmts)
777
        av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
778
 
779
    MATCH_PER_TYPE_OPT(codec_names, str,    video_codec_name, ic, "v");
780
    MATCH_PER_TYPE_OPT(codec_names, str,    audio_codec_name, ic, "a");
781
    MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, ic, "s");
782
 
783
    ic->video_codec_id   = video_codec_name ?
784
        find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0)->id : AV_CODEC_ID_NONE;
785
    ic->audio_codec_id   = audio_codec_name ?
786
        find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0)->id : AV_CODEC_ID_NONE;
787
    ic->subtitle_codec_id= subtitle_codec_name ?
788
        find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0)->id : AV_CODEC_ID_NONE;
789
 
790
    if (video_codec_name)
791
        av_format_set_video_codec   (ic, find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0));
792
    if (audio_codec_name)
793
        av_format_set_audio_codec   (ic, find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0));
794
    if (subtitle_codec_name)
795
        av_format_set_subtitle_codec(ic, find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0));
796
 
797
    ic->flags |= AVFMT_FLAG_NONBLOCK;
798
    ic->interrupt_callback = int_cb;
799
 
800
    /* open the input file with generic avformat function */
801
    err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
802
    if (err < 0) {
803
        print_error(filename, err);
804
        exit_program(1);
805
    }
806
    assert_avoptions(o->g->format_opts);
807
 
808
    /* apply forced codec ids */
809
    for (i = 0; i < ic->nb_streams; i++)
810
        choose_decoder(o, ic, ic->streams[i]);
811
 
812
    /* Set AVCodecContext options for avformat_find_stream_info */
813
    opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
814
    orig_nb_streams = ic->nb_streams;
815
 
816
    /* If not enough info to get the stream parameters, we decode the
817
       first frames to get it. (used in mpeg case for example) */
818
    ret = avformat_find_stream_info(ic, opts);
819
    if (ret < 0) {
820
        av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
821
        avformat_close_input(&ic);
822
        exit_program(1);
823
    }
824
 
825
    timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
826
    /* add the stream start time */
827
    if (ic->start_time != AV_NOPTS_VALUE)
828
        timestamp += ic->start_time;
829
 
830
    /* if seeking requested, we execute it */
831
    if (o->start_time != AV_NOPTS_VALUE) {
832
        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, timestamp, 0);
833
        if (ret < 0) {
834
            av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
835
                   filename, (double)timestamp / AV_TIME_BASE);
836
        }
837
    }
838
 
839
    /* update the current parameters so that they match the one of the input stream */
840
    add_input_streams(o, ic);
841
 
842
    /* dump the file content */
843
    av_dump_format(ic, nb_input_files, filename, 0);
844
 
845
    GROW_ARRAY(input_files, nb_input_files);
846
    f = av_mallocz(sizeof(*f));
847
    if (!f)
848
        exit_program(1);
849
    input_files[nb_input_files - 1] = f;
850
 
851
    f->ctx        = ic;
852
    f->ist_index  = nb_input_streams - ic->nb_streams;
853
    f->start_time = o->start_time;
854
    f->recording_time = o->recording_time;
855
    f->input_ts_offset = o->input_ts_offset;
856
    f->ts_offset  = o->input_ts_offset - (copy_ts ? 0 : timestamp);
857
    f->nb_streams = ic->nb_streams;
858
    f->rate_emu   = o->rate_emu;
859
    f->accurate_seek = o->accurate_seek;
860
 
861
    /* check if all codec options have been used */
862
    unused_opts = strip_specifiers(o->g->codec_opts);
863
    for (i = f->ist_index; i < nb_input_streams; i++) {
864
        e = NULL;
865
        while ((e = av_dict_get(input_streams[i]->opts, "", e,
866
                                AV_DICT_IGNORE_SUFFIX)))
867
            av_dict_set(&unused_opts, e->key, NULL, 0);
868
    }
869
 
870
    e = NULL;
871
    while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
872
        const AVClass *class = avcodec_get_class();
873
        const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
874
                                             AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
875
        if (!option)
876
            continue;
877
        if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
878
            av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
879
                   "input file #%d (%s) is not a decoding option.\n", e->key,
880
                   option->help ? option->help : "", nb_input_files - 1,
881
                   filename);
882
            exit_program(1);
883
        }
884
 
885
        av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
886
               "input file #%d (%s) has not been used for any stream. The most "
887
               "likely reason is either wrong type (e.g. a video option with "
888
               "no video streams) or that it is a private option of some decoder "
889
               "which was not actually used for any stream.\n", e->key,
890
               option->help ? option->help : "", nb_input_files - 1, filename);
891
    }
892
    av_dict_free(&unused_opts);
893
 
894
    for (i = 0; i < o->nb_dump_attachment; i++) {
895
        int j;
896
 
897
        for (j = 0; j < ic->nb_streams; j++) {
898
            AVStream *st = ic->streams[j];
899
 
900
            if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
901
                dump_attachment(st, o->dump_attachment[i].u.str);
902
        }
903
    }
904
 
905
    for (i = 0; i < orig_nb_streams; i++)
906
        av_dict_free(&opts[i]);
907
    av_freep(&opts);
908
 
909
    return 0;
910
}
911
 
912
static uint8_t *get_line(AVIOContext *s)
913
{
914
    AVIOContext *line;
915
    uint8_t *buf;
916
    char c;
917
 
918
    if (avio_open_dyn_buf(&line) < 0) {
919
        av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
920
        exit_program(1);
921
    }
922
 
923
    while ((c = avio_r8(s)) && c != '\n')
924
        avio_w8(line, c);
925
    avio_w8(line, 0);
926
    avio_close_dyn_buf(line, &buf);
927
 
928
    return buf;
929
}
930
 
931
static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
932
{
933
    int i, ret = 1;
934
    char filename[1000];
935
    const char *base[3] = { getenv("AVCONV_DATADIR"),
936
                            getenv("HOME"),
937
                            AVCONV_DATADIR,
938
                            };
939
 
940
    for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
941
        if (!base[i])
942
            continue;
943
        if (codec_name) {
944
            snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
945
                     i != 1 ? "" : "/.avconv", codec_name, preset_name);
946
            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
947
        }
948
        if (ret) {
949
            snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
950
                     i != 1 ? "" : "/.avconv", preset_name);
951
            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
952
        }
953
    }
954
    return ret;
955
}
956
 
957
static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
958
{
959
    char *codec_name = NULL;
960
 
961
    MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
962
    if (!codec_name) {
963
        ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
964
                                                  NULL, ost->st->codec->codec_type);
965
        ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
966
    } else if (!strcmp(codec_name, "copy"))
967
        ost->stream_copy = 1;
968
    else {
969
        ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
970
        ost->st->codec->codec_id = ost->enc->id;
971
    }
972
}
973
 
974
static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type, int source_index)
975
{
976
    OutputStream *ost;
977
    AVStream *st = avformat_new_stream(oc, NULL);
978
    int idx      = oc->nb_streams - 1, ret = 0;
979
    char *bsf = NULL, *next, *codec_tag = NULL;
980
    AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
981
    double qscale = -1;
982
    int i;
983
 
984
    if (!st) {
985
        av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
986
        exit_program(1);
987
    }
988
 
989
    if (oc->nb_streams - 1 < o->nb_streamid_map)
990
        st->id = o->streamid_map[oc->nb_streams - 1];
991
 
992
    GROW_ARRAY(output_streams, nb_output_streams);
993
    if (!(ost = av_mallocz(sizeof(*ost))))
994
        exit_program(1);
995
    output_streams[nb_output_streams - 1] = ost;
996
 
997
    ost->file_index = nb_output_files - 1;
998
    ost->index      = idx;
999
    ost->st         = st;
1000
    st->codec->codec_type = type;
1001
    choose_encoder(o, oc, ost);
1002
    if (ost->enc) {
1003
        AVIOContext *s = NULL;
1004
        char *buf = NULL, *arg = NULL, *preset = NULL;
1005
 
1006
        ost->opts  = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
1007
 
1008
        MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
1009
        if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
1010
            do  {
1011
                buf = get_line(s);
1012
                if (!buf[0] || buf[0] == '#') {
1013
                    av_free(buf);
1014
                    continue;
1015
                }
1016
                if (!(arg = strchr(buf, '='))) {
1017
                    av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
1018
                    exit_program(1);
1019
                }
1020
                *arg++ = 0;
1021
                av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
1022
                av_free(buf);
1023
            } while (!s->eof_reached);
1024
            avio_close(s);
1025
        }
1026
        if (ret) {
1027
            av_log(NULL, AV_LOG_FATAL,
1028
                   "Preset %s specified for stream %d:%d, but could not be opened.\n",
1029
                   preset, ost->file_index, ost->index);
1030
            exit_program(1);
1031
        }
1032
    } else {
1033
        ost->opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
1034
    }
1035
 
1036
    avcodec_get_context_defaults3(st->codec, ost->enc);
1037
    st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
1038
 
1039
    ost->max_frames = INT64_MAX;
1040
    MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
1041
    for (i = 0; inb_max_frames; i++) {
1042
        char *p = o->max_frames[i].specifier;
1043
        if (!*p && type != AVMEDIA_TYPE_VIDEO) {
1044
            av_log(NULL, AV_LOG_WARNING, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n");
1045
            break;
1046
        }
1047
    }
1048
 
1049
    ost->copy_prior_start = -1;
1050
    MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st);
1051
 
1052
    MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
1053
    while (bsf) {
1054
        if (next = strchr(bsf, ','))
1055
            *next++ = 0;
1056
        if (!(bsfc = av_bitstream_filter_init(bsf))) {
1057
            av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
1058
            exit_program(1);
1059
        }
1060
        if (bsfc_prev)
1061
            bsfc_prev->next = bsfc;
1062
        else
1063
            ost->bitstream_filters = bsfc;
1064
 
1065
        bsfc_prev = bsfc;
1066
        bsf       = next;
1067
    }
1068
 
1069
    MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
1070
    if (codec_tag) {
1071
        uint32_t tag = strtol(codec_tag, &next, 0);
1072
        if (*next)
1073
            tag = AV_RL32(codec_tag);
1074
        st->codec->codec_tag = tag;
1075
    }
1076
 
1077
    MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
1078
    if (qscale >= 0) {
1079
        st->codec->flags |= CODEC_FLAG_QSCALE;
1080
        st->codec->global_quality = FF_QP2LAMBDA * qscale;
1081
    }
1082
 
1083
    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1084
        st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
1085
 
1086
    av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
1087
 
1088
    av_dict_copy(&ost->swr_opts, o->g->swr_opts, 0);
1089
    if (ost->enc && av_get_exact_bits_per_sample(ost->enc->id) == 24)
1090
        av_dict_set(&ost->swr_opts, "output_sample_bits", "24", 0);
1091
 
1092
    av_dict_copy(&ost->resample_opts, o->g->resample_opts, 0);
1093
 
1094
    ost->source_index = source_index;
1095
    if (source_index >= 0) {
1096
        ost->sync_ist = input_streams[source_index];
1097
        input_streams[source_index]->discard = 0;
1098
        input_streams[source_index]->st->discard = AVDISCARD_NONE;
1099
    }
1100
    ost->last_mux_dts = AV_NOPTS_VALUE;
1101
 
1102
    return ost;
1103
}
1104
 
1105
static void parse_matrix_coeffs(uint16_t *dest, const char *str)
1106
{
1107
    int i;
1108
    const char *p = str;
1109
    for (i = 0;; i++) {
1110
        dest[i] = atoi(p);
1111
        if (i == 63)
1112
            break;
1113
        p = strchr(p, ',');
1114
        if (!p) {
1115
            av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
1116
            exit_program(1);
1117
        }
1118
        p++;
1119
    }
1120
}
1121
 
1122
/* read file contents into a string */
1123
static uint8_t *read_file(const char *filename)
1124
{
1125
    AVIOContext *pb      = NULL;
1126
    AVIOContext *dyn_buf = NULL;
1127
    int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
1128
    uint8_t buf[1024], *str;
1129
 
1130
    if (ret < 0) {
1131
        av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
1132
        return NULL;
1133
    }
1134
 
1135
    ret = avio_open_dyn_buf(&dyn_buf);
1136
    if (ret < 0) {
1137
        avio_closep(&pb);
1138
        return NULL;
1139
    }
1140
    while ((ret = avio_read(pb, buf, sizeof(buf))) > 0)
1141
        avio_write(dyn_buf, buf, ret);
1142
    avio_w8(dyn_buf, 0);
1143
    avio_closep(&pb);
1144
 
1145
    ret = avio_close_dyn_buf(dyn_buf, &str);
1146
    if (ret < 0)
1147
        return NULL;
1148
    return str;
1149
}
1150
 
1151
static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
1152
                             OutputStream *ost)
1153
{
1154
    AVStream *st = ost->st;
1155
    char *filter = NULL, *filter_script = NULL;
1156
 
1157
    MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
1158
    MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
1159
 
1160
    if (filter_script && filter) {
1161
        av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
1162
               "output stream #%d:%d.\n", nb_output_files, st->index);
1163
        exit_program(1);
1164
    }
1165
 
1166
    if (filter_script)
1167
        return read_file(filter_script);
1168
    else if (filter)
1169
        return av_strdup(filter);
1170
 
1171
    return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
1172
                     "null" : "anull");
1173
}
1174
 
1175
static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
1176
{
1177
    AVStream *st;
1178
    OutputStream *ost;
1179
    AVCodecContext *video_enc;
1180
    char *frame_rate = NULL, *frame_aspect_ratio = NULL;
1181
 
1182
    ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);
1183
    st  = ost->st;
1184
    video_enc = st->codec;
1185
 
1186
    MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
1187
    if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
1188
        av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
1189
        exit_program(1);
1190
    }
1191
 
1192
    MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
1193
    if (frame_aspect_ratio) {
1194
        AVRational q;
1195
        if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
1196
            q.num <= 0 || q.den <= 0) {
1197
            av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
1198
            exit_program(1);
1199
        }
1200
        ost->frame_aspect_ratio = q;
1201
    }
1202
 
1203
    if (!ost->stream_copy) {
1204
        const char *p = NULL;
1205
        char *frame_size = NULL;
1206
        char *frame_pix_fmt = NULL;
1207
        char *intra_matrix = NULL, *inter_matrix = NULL;
1208
        int do_pass = 0;
1209
        int i;
1210
 
1211
        MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
1212
        if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
1213
            av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
1214
            exit_program(1);
1215
        }
1216
 
1217
        video_enc->bits_per_raw_sample = frame_bits_per_raw_sample;
1218
        MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
1219
        if (frame_pix_fmt && *frame_pix_fmt == '+') {
1220
            ost->keep_pix_fmt = 1;
1221
            if (!*++frame_pix_fmt)
1222
                frame_pix_fmt = NULL;
1223
        }
1224
        if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
1225
            av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
1226
            exit_program(1);
1227
        }
1228
        st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
1229
 
1230
        if (intra_only)
1231
            video_enc->gop_size = 0;
1232
        MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
1233
        if (intra_matrix) {
1234
            if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
1235
                av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
1236
                exit_program(1);
1237
            }
1238
            parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
1239
        }
1240
        MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
1241
        if (inter_matrix) {
1242
            if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
1243
                av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
1244
                exit_program(1);
1245
            }
1246
            parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
1247
        }
1248
 
1249
        MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
1250
        for (i = 0; p; i++) {
1251
            int start, end, q;
1252
            int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
1253
            if (e != 3) {
1254
                av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
1255
                exit_program(1);
1256
            }
1257
            /* FIXME realloc failure */
1258
            video_enc->rc_override =
1259
                av_realloc(video_enc->rc_override,
1260
                           sizeof(RcOverride) * (i + 1));
1261
            video_enc->rc_override[i].start_frame = start;
1262
            video_enc->rc_override[i].end_frame   = end;
1263
            if (q > 0) {
1264
                video_enc->rc_override[i].qscale         = q;
1265
                video_enc->rc_override[i].quality_factor = 1.0;
1266
            }
1267
            else {
1268
                video_enc->rc_override[i].qscale         = 0;
1269
                video_enc->rc_override[i].quality_factor = -q/100.0;
1270
            }
1271
            p = strchr(p, '/');
1272
            if (p) p++;
1273
        }
1274
        video_enc->rc_override_count = i;
1275
        video_enc->intra_dc_precision = intra_dc_precision - 8;
1276
 
1277
        if (do_psnr)
1278
            video_enc->flags|= CODEC_FLAG_PSNR;
1279
 
1280
        /* two pass mode */
1281
        MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
1282
        if (do_pass) {
1283
            if (do_pass & 1) {
1284
                video_enc->flags |= CODEC_FLAG_PASS1;
1285
                av_dict_set(&ost->opts, "flags", "+pass1", AV_DICT_APPEND);
1286
            }
1287
            if (do_pass & 2) {
1288
                video_enc->flags |= CODEC_FLAG_PASS2;
1289
                av_dict_set(&ost->opts, "flags", "+pass2", AV_DICT_APPEND);
1290
            }
1291
        }
1292
 
1293
        MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
1294
        if (ost->logfile_prefix &&
1295
            !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
1296
            exit_program(1);
1297
 
1298
        MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
1299
        if (ost->forced_keyframes)
1300
            ost->forced_keyframes = av_strdup(ost->forced_keyframes);
1301
 
1302
        MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
1303
 
1304
        ost->top_field_first = -1;
1305
        MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
1306
 
1307
 
1308
        ost->avfilter = get_ost_filters(o, oc, ost);
1309
        if (!ost->avfilter)
1310
            exit_program(1);
1311
    } else {
1312
        MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
1313
    }
1314
 
1315
    return ost;
1316
}
1317
 
1318
static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
1319
{
1320
    int n;
1321
    AVStream *st;
1322
    OutputStream *ost;
1323
    AVCodecContext *audio_enc;
1324
 
1325
    ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO, source_index);
1326
    st  = ost->st;
1327
 
1328
    audio_enc = st->codec;
1329
    audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
1330
 
1331
    if (!ost->stream_copy) {
1332
        char *sample_fmt = NULL;
1333
 
1334
        MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
1335
 
1336
        MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
1337
        if (sample_fmt &&
1338
            (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
1339
            av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
1340
            exit_program(1);
1341
        }
1342
 
1343
        MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
1344
 
1345
        MATCH_PER_STREAM_OPT(apad, str, ost->apad, oc, st);
1346
        ost->apad = av_strdup(ost->apad);
1347
 
1348
        ost->avfilter = get_ost_filters(o, oc, ost);
1349
        if (!ost->avfilter)
1350
            exit_program(1);
1351
 
1352
        /* check for channel mapping for this audio stream */
1353
        for (n = 0; n < o->nb_audio_channel_maps; n++) {
1354
            AudioChannelMap *map = &o->audio_channel_maps[n];
1355
            InputStream *ist = input_streams[ost->source_index];
1356
            if ((map->channel_idx == -1 || (ist->file_index == map->file_idx && ist->st->index == map->stream_idx)) &&
1357
                (map->ofile_idx   == -1 || ost->file_index == map->ofile_idx) &&
1358
                (map->ostream_idx == -1 || ost->st->index  == map->ostream_idx)) {
1359
                if (ost->audio_channels_mapped < FF_ARRAY_ELEMS(ost->audio_channels_map))
1360
                    ost->audio_channels_map[ost->audio_channels_mapped++] = map->channel_idx;
1361
                else
1362
                    av_log(NULL, AV_LOG_FATAL, "Max channel mapping for output %d.%d reached\n",
1363
                           ost->file_index, ost->st->index);
1364
            }
1365
        }
1366
    }
1367
 
1368
    return ost;
1369
}
1370
 
1371
static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
1372
{
1373
    OutputStream *ost;
1374
 
1375
    ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA, source_index);
1376
    if (!ost->stream_copy) {
1377
        av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
1378
        exit_program(1);
1379
    }
1380
 
1381
    return ost;
1382
}
1383
 
1384
static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
1385
{
1386
    OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT, source_index);
1387
    ost->stream_copy = 1;
1388
    ost->finished    = 1;
1389
    return ost;
1390
}
1391
 
1392
static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
1393
{
1394
    AVStream *st;
1395
    OutputStream *ost;
1396
    AVCodecContext *subtitle_enc;
1397
 
1398
    ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE, source_index);
1399
    st  = ost->st;
1400
    subtitle_enc = st->codec;
1401
 
1402
    subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
1403
 
1404
    MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc, st);
1405
 
1406
    if (!ost->stream_copy) {
1407
        char *frame_size = NULL;
1408
 
1409
        MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
1410
        if (frame_size && av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size) < 0) {
1411
            av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
1412
            exit_program(1);
1413
        }
1414
    }
1415
 
1416
    return ost;
1417
}
1418
 
1419
/* arg format is "output-stream-index:streamid-value". */
1420
static int opt_streamid(void *optctx, const char *opt, const char *arg)
1421
{
1422
    OptionsContext *o = optctx;
1423
    int idx;
1424
    char *p;
1425
    char idx_str[16];
1426
 
1427
    av_strlcpy(idx_str, arg, sizeof(idx_str));
1428
    p = strchr(idx_str, ':');
1429
    if (!p) {
1430
        av_log(NULL, AV_LOG_FATAL,
1431
               "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
1432
               arg, opt);
1433
        exit_program(1);
1434
    }
1435
    *p++ = '\0';
1436
    idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
1437
    o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
1438
    o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
1439
    return 0;
1440
}
1441
 
1442
static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
1443
{
1444
    AVFormatContext *is = ifile->ctx;
1445
    AVFormatContext *os = ofile->ctx;
1446
    AVChapter **tmp;
1447
    int i;
1448
 
1449
    tmp = av_realloc_f(os->chapters, is->nb_chapters + os->nb_chapters, sizeof(*os->chapters));
1450
    if (!tmp)
1451
        return AVERROR(ENOMEM);
1452
    os->chapters = tmp;
1453
 
1454
    for (i = 0; i < is->nb_chapters; i++) {
1455
        AVChapter *in_ch = is->chapters[i], *out_ch;
1456
        int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
1457
        int64_t ts_off   = av_rescale_q(start_time - ifile->ts_offset,
1458
                                       AV_TIME_BASE_Q, in_ch->time_base);
1459
        int64_t rt       = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
1460
                           av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
1461
 
1462
 
1463
        if (in_ch->end < ts_off)
1464
            continue;
1465
        if (rt != INT64_MAX && in_ch->start > rt + ts_off)
1466
            break;
1467
 
1468
        out_ch = av_mallocz(sizeof(AVChapter));
1469
        if (!out_ch)
1470
            return AVERROR(ENOMEM);
1471
 
1472
        out_ch->id        = in_ch->id;
1473
        out_ch->time_base = in_ch->time_base;
1474
        out_ch->start     = FFMAX(0,  in_ch->start - ts_off);
1475
        out_ch->end       = FFMIN(rt, in_ch->end   - ts_off);
1476
 
1477
        if (copy_metadata)
1478
            av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
1479
 
1480
        os->chapters[os->nb_chapters++] = out_ch;
1481
    }
1482
    return 0;
1483
}
1484
 
1485
static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
1486
{
1487
    int i, err;
1488
    AVFormatContext *ic = avformat_alloc_context();
1489
 
1490
    ic->interrupt_callback = int_cb;
1491
    err = avformat_open_input(&ic, filename, NULL, NULL);
1492
    if (err < 0)
1493
        return err;
1494
    /* copy stream format */
1495
    for(i=0;inb_streams;i++) {
1496
        AVStream *st;
1497
        OutputStream *ost;
1498
        AVCodec *codec;
1499
        AVCodecContext *avctx;
1500
 
1501
        codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
1502
        ost   = new_output_stream(o, s, codec->type, -1);
1503
        st    = ost->st;
1504
        avctx = st->codec;
1505
        ost->enc = codec;
1506
 
1507
        // FIXME: a more elegant solution is needed
1508
        memcpy(st, ic->streams[i], sizeof(AVStream));
1509
        st->cur_dts = 0;
1510
        st->info = av_malloc(sizeof(*st->info));
1511
        memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
1512
        st->codec= avctx;
1513
        avcodec_copy_context(st->codec, ic->streams[i]->codec);
1514
 
1515
        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
1516
            choose_sample_fmt(st, codec);
1517
        else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
1518
            choose_pixel_fmt(st, codec, st->codec->pix_fmt);
1519
    }
1520
 
1521
    avformat_close_input(&ic);
1522
    return err;
1523
}
1524
 
1525
static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
1526
                               AVFormatContext *oc)
1527
{
1528
    OutputStream *ost;
1529
 
1530
    switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1531
                                  ofilter->out_tmp->pad_idx)) {
1532
    case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc, -1); break;
1533
    case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, -1); break;
1534
    default:
1535
        av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
1536
               "currently.\n");
1537
        exit_program(1);
1538
    }
1539
 
1540
    ost->source_index = -1;
1541
    ost->filter       = ofilter;
1542
 
1543
    ofilter->ost      = ost;
1544
 
1545
    if (ost->stream_copy) {
1546
        av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
1547
               "which is fed from a complex filtergraph. Filtering and streamcopy "
1548
               "cannot be used together.\n", ost->file_index, ost->index);
1549
        exit_program(1);
1550
    }
1551
 
1552
    if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
1553
        av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
1554
        exit_program(1);
1555
    }
1556
    avfilter_inout_free(&ofilter->out_tmp);
1557
}
1558
 
1559
static int configure_complex_filters(void)
1560
{
1561
    int i, ret = 0;
1562
 
1563
    for (i = 0; i < nb_filtergraphs; i++)
1564
        if (!filtergraphs[i]->graph &&
1565
            (ret = configure_filtergraph(filtergraphs[i])) < 0)
1566
            return ret;
1567
    return 0;
1568
}
1569
 
1570
static int open_output_file(OptionsContext *o, const char *filename)
1571
{
1572
    AVFormatContext *oc;
1573
    int i, j, err;
1574
    AVOutputFormat *file_oformat;
1575
    OutputFile *of;
1576
    OutputStream *ost;
1577
    InputStream  *ist;
1578
    AVDictionary *unused_opts = NULL;
1579
    AVDictionaryEntry *e = NULL;
1580
 
1581
    if (configure_complex_filters() < 0) {
1582
        av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
1583
        exit_program(1);
1584
    }
1585
 
1586
    if (o->stop_time != INT64_MAX && o->recording_time != INT64_MAX) {
1587
        o->stop_time = INT64_MAX;
1588
        av_log(NULL, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
1589
    }
1590
 
1591
    if (o->stop_time != INT64_MAX && o->recording_time == INT64_MAX) {
1592
        int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
1593
        if (o->stop_time <= start_time) {
1594
            av_log(NULL, AV_LOG_WARNING, "-to value smaller than -ss; ignoring -to.\n");
1595
            o->stop_time = INT64_MAX;
1596
        } else {
1597
            o->recording_time = o->stop_time - start_time;
1598
        }
1599
    }
1600
 
1601
    GROW_ARRAY(output_files, nb_output_files);
1602
    of = av_mallocz(sizeof(*of));
1603
    if (!of)
1604
        exit_program(1);
1605
    output_files[nb_output_files - 1] = of;
1606
 
1607
    of->ost_index      = nb_output_streams;
1608
    of->recording_time = o->recording_time;
1609
    of->start_time     = o->start_time;
1610
    of->limit_filesize = o->limit_filesize;
1611
    of->shortest       = o->shortest;
1612
    av_dict_copy(&of->opts, o->g->format_opts, 0);
1613
 
1614
    if (!strcmp(filename, "-"))
1615
        filename = "pipe:";
1616
 
1617
    err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
1618
    if (!oc) {
1619
        print_error(filename, err);
1620
        exit_program(1);
1621
    }
1622
 
1623
    of->ctx = oc;
1624
    if (o->recording_time != INT64_MAX)
1625
        oc->duration = o->recording_time;
1626
 
1627
    file_oformat= oc->oformat;
1628
    oc->interrupt_callback = int_cb;
1629
 
1630
    /* create streams for all unlabeled output pads */
1631
    for (i = 0; i < nb_filtergraphs; i++) {
1632
        FilterGraph *fg = filtergraphs[i];
1633
        for (j = 0; j < fg->nb_outputs; j++) {
1634
            OutputFilter *ofilter = fg->outputs[j];
1635
 
1636
            if (!ofilter->out_tmp || ofilter->out_tmp->name)
1637
                continue;
1638
 
1639
            switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1640
                                          ofilter->out_tmp->pad_idx)) {
1641
            case AVMEDIA_TYPE_VIDEO:    o->video_disable    = 1; break;
1642
            case AVMEDIA_TYPE_AUDIO:    o->audio_disable    = 1; break;
1643
            case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
1644
            }
1645
            init_output_filter(ofilter, o, oc);
1646
        }
1647
    }
1648
 
1649
    /* ffserver seeking with date=... needs a date reference */
1650
    if (!strcmp(file_oformat->name, "ffm") &&
1651
        av_strstart(filename, "http:", NULL)) {
1652
        int err = parse_option(o, "metadata", "creation_time=now", options);
1653
        if (err < 0) {
1654
            print_error(filename, err);
1655
            exit_program(1);
1656
        }
1657
    }
1658
 
1659
    if (!strcmp(file_oformat->name, "ffm") && !override_ffserver &&
1660
        av_strstart(filename, "http:", NULL)) {
1661
        int j;
1662
        /* special case for files sent to ffserver: we get the stream
1663
           parameters from ffserver */
1664
        int err = read_ffserver_streams(o, oc, filename);
1665
        if (err < 0) {
1666
            print_error(filename, err);
1667
            exit_program(1);
1668
        }
1669
        for(j = nb_output_streams - oc->nb_streams; j < nb_output_streams; j++) {
1670
            ost = output_streams[j];
1671
            for (i = 0; i < nb_input_streams; i++) {
1672
                ist = input_streams[i];
1673
                if(ist->st->codec->codec_type == ost->st->codec->codec_type){
1674
                    ost->sync_ist= ist;
1675
                    ost->source_index= i;
1676
                    if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) ost->avfilter = av_strdup("anull");
1677
                    if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) ost->avfilter = av_strdup("null");
1678
                    ist->discard = 0;
1679
                    ist->st->discard = AVDISCARD_NONE;
1680
                    break;
1681
                }
1682
            }
1683
            if(!ost->sync_ist){
1684
                av_log(NULL, AV_LOG_FATAL, "Missing %s stream which is required by this ffm\n", av_get_media_type_string(ost->st->codec->codec_type));
1685
                exit_program(1);
1686
            }
1687
        }
1688
    } else if (!o->nb_stream_maps) {
1689
        char *subtitle_codec_name = NULL;
1690
        /* pick the "best" stream of each type */
1691
 
1692
        /* video: highest resolution */
1693
        if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
1694
            int area = 0, idx = -1;
1695
            int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
1696
            for (i = 0; i < nb_input_streams; i++) {
1697
                int new_area;
1698
                ist = input_streams[i];
1699
                new_area = ist->st->codec->width * ist->st->codec->height;
1700
                if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1701
                    new_area = 1;
1702
                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
1703
                    new_area > area) {
1704
                    if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1705
                        continue;
1706
                    area = new_area;
1707
                    idx = i;
1708
                }
1709
            }
1710
            if (idx >= 0)
1711
                new_video_stream(o, oc, idx);
1712
        }
1713
 
1714
        /* audio: most channels */
1715
        if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
1716
            int channels = 0, idx = -1;
1717
            for (i = 0; i < nb_input_streams; i++) {
1718
                ist = input_streams[i];
1719
                if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
1720
                    ist->st->codec->channels > channels) {
1721
                    channels = ist->st->codec->channels;
1722
                    idx = i;
1723
                }
1724
            }
1725
            if (idx >= 0)
1726
                new_audio_stream(o, oc, idx);
1727
        }
1728
 
1729
        /* subtitles: pick first */
1730
        MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");
1731
        if (!o->subtitle_disable && (oc->oformat->subtitle_codec != AV_CODEC_ID_NONE || subtitle_codec_name)) {
1732
            for (i = 0; i < nb_input_streams; i++)
1733
                if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1734
                    new_subtitle_stream(o, oc, i);
1735
                    break;
1736
                }
1737
        }
1738
        /* do something with data? */
1739
    } else {
1740
        for (i = 0; i < o->nb_stream_maps; i++) {
1741
            StreamMap *map = &o->stream_maps[i];
1742
 
1743
            if (map->disabled)
1744
                continue;
1745
 
1746
            if (map->linklabel) {
1747
                FilterGraph *fg;
1748
                OutputFilter *ofilter = NULL;
1749
                int j, k;
1750
 
1751
                for (j = 0; j < nb_filtergraphs; j++) {
1752
                    fg = filtergraphs[j];
1753
                    for (k = 0; k < fg->nb_outputs; k++) {
1754
                        AVFilterInOut *out = fg->outputs[k]->out_tmp;
1755
                        if (out && !strcmp(out->name, map->linklabel)) {
1756
                            ofilter = fg->outputs[k];
1757
                            goto loop_end;
1758
                        }
1759
                    }
1760
                }
1761
loop_end:
1762
                if (!ofilter) {
1763
                    av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
1764
                           "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);
1765
                    exit_program(1);
1766
                }
1767
                init_output_filter(ofilter, o, oc);
1768
            } else {
1769
                int src_idx = input_files[map->file_index]->ist_index + map->stream_index;
1770
 
1771
                ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
1772
                if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
1773
                    continue;
1774
                if(o->   audio_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
1775
                    continue;
1776
                if(o->   video_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
1777
                    continue;
1778
                if(o->    data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA)
1779
                    continue;
1780
 
1781
                switch (ist->st->codec->codec_type) {
1782
                case AVMEDIA_TYPE_VIDEO:      ost = new_video_stream     (o, oc, src_idx); break;
1783
                case AVMEDIA_TYPE_AUDIO:      ost = new_audio_stream     (o, oc, src_idx); break;
1784
                case AVMEDIA_TYPE_SUBTITLE:   ost = new_subtitle_stream  (o, oc, src_idx); break;
1785
                case AVMEDIA_TYPE_DATA:       ost = new_data_stream      (o, oc, src_idx); break;
1786
                case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break;
1787
                default:
1788
                    av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
1789
                           map->file_index, map->stream_index);
1790
                    exit_program(1);
1791
                }
1792
            }
1793
        }
1794
    }
1795
 
1796
    /* handle attached files */
1797
    for (i = 0; i < o->nb_attachments; i++) {
1798
        AVIOContext *pb;
1799
        uint8_t *attachment;
1800
        const char *p;
1801
        int64_t len;
1802
 
1803
        if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
1804
            av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
1805
                   o->attachments[i]);
1806
            exit_program(1);
1807
        }
1808
        if ((len = avio_size(pb)) <= 0) {
1809
            av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
1810
                   o->attachments[i]);
1811
            exit_program(1);
1812
        }
1813
        if (!(attachment = av_malloc(len))) {
1814
            av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
1815
                   o->attachments[i]);
1816
            exit_program(1);
1817
        }
1818
        avio_read(pb, attachment, len);
1819
 
1820
        ost = new_attachment_stream(o, oc, -1);
1821
        ost->stream_copy               = 0;
1822
        ost->attachment_filename       = o->attachments[i];
1823
        ost->finished                  = 1;
1824
        ost->st->codec->extradata      = attachment;
1825
        ost->st->codec->extradata_size = len;
1826
 
1827
        p = strrchr(o->attachments[i], '/');
1828
        av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
1829
        avio_close(pb);
1830
    }
1831
 
1832
    for (i = nb_output_streams - oc->nb_streams; i < nb_output_streams; i++) { //for all streams of this output file
1833
        AVDictionaryEntry *e;
1834
        ost = output_streams[i];
1835
 
1836
        if ((ost->stream_copy || ost->attachment_filename)
1837
            && (e = av_dict_get(o->g->codec_opts, "flags", NULL, AV_DICT_IGNORE_SUFFIX))
1838
            && (!e->key[5] || check_stream_specifier(oc, ost->st, e->key+6)))
1839
            if (av_opt_set(ost->st->codec, "flags", e->value, 0) < 0)
1840
                exit_program(1);
1841
    }
1842
 
1843
    /* check if all codec options have been used */
1844
    unused_opts = strip_specifiers(o->g->codec_opts);
1845
    for (i = of->ost_index; i < nb_output_streams; i++) {
1846
        e = NULL;
1847
        while ((e = av_dict_get(output_streams[i]->opts, "", e,
1848
                                AV_DICT_IGNORE_SUFFIX)))
1849
            av_dict_set(&unused_opts, e->key, NULL, 0);
1850
    }
1851
 
1852
    e = NULL;
1853
    while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
1854
        const AVClass *class = avcodec_get_class();
1855
        const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
1856
                                             AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1857
        if (!option)
1858
            continue;
1859
        if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
1860
            av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
1861
                   "output file #%d (%s) is not an encoding option.\n", e->key,
1862
                   option->help ? option->help : "", nb_output_files - 1,
1863
                   filename);
1864
            exit_program(1);
1865
        }
1866
 
1867
        // gop_timecode is injected by generic code but not always used
1868
        if (!strcmp(e->key, "gop_timecode"))
1869
            continue;
1870
 
1871
        av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
1872
               "output file #%d (%s) has not been used for any stream. The most "
1873
               "likely reason is either wrong type (e.g. a video option with "
1874
               "no video streams) or that it is a private option of some encoder "
1875
               "which was not actually used for any stream.\n", e->key,
1876
               option->help ? option->help : "", nb_output_files - 1, filename);
1877
    }
1878
    av_dict_free(&unused_opts);
1879
 
1880
    /* check filename in case of an image number is expected */
1881
    if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
1882
        if (!av_filename_number_test(oc->filename)) {
1883
            print_error(oc->filename, AVERROR(EINVAL));
1884
            exit_program(1);
1885
        }
1886
    }
1887
 
1888
    if (!(oc->oformat->flags & AVFMT_NOFILE)) {
1889
        /* test if it already exists to avoid losing precious files */
1890
        assert_file_overwrite(filename);
1891
 
1892
        /* open the file */
1893
        if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
1894
                              &oc->interrupt_callback,
1895
                              &of->opts)) < 0) {
1896
            print_error(filename, err);
1897
            exit_program(1);
1898
        }
1899
    } else if (strcmp(oc->oformat->name, "image2")==0 && !av_filename_number_test(filename))
1900
        assert_file_overwrite(filename);
1901
 
1902
    if (o->mux_preload) {
1903
        uint8_t buf[64];
1904
        snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
1905
        av_dict_set(&of->opts, "preload", buf, 0);
1906
    }
1907
    oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
1908
 
1909
    /* copy metadata */
1910
    for (i = 0; i < o->nb_metadata_map; i++) {
1911
        char *p;
1912
        int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
1913
 
1914
        if (in_file_index >= nb_input_files) {
1915
            av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
1916
            exit_program(1);
1917
        }
1918
        copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
1919
                      in_file_index >= 0 ?
1920
                      input_files[in_file_index]->ctx : NULL, o);
1921
    }
1922
 
1923
    /* copy chapters */
1924
    if (o->chapters_input_file >= nb_input_files) {
1925
        if (o->chapters_input_file == INT_MAX) {
1926
            /* copy chapters from the first input file that has them*/
1927
            o->chapters_input_file = -1;
1928
            for (i = 0; i < nb_input_files; i++)
1929
                if (input_files[i]->ctx->nb_chapters) {
1930
                    o->chapters_input_file = i;
1931
                    break;
1932
                }
1933
        } else {
1934
            av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
1935
                   o->chapters_input_file);
1936
            exit_program(1);
1937
        }
1938
    }
1939
    if (o->chapters_input_file >= 0)
1940
        copy_chapters(input_files[o->chapters_input_file], of,
1941
                      !o->metadata_chapters_manual);
1942
 
1943
    /* copy global metadata by default */
1944
    if (!o->metadata_global_manual && nb_input_files){
1945
        av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
1946
                     AV_DICT_DONT_OVERWRITE);
1947
        if(o->recording_time != INT64_MAX)
1948
            av_dict_set(&oc->metadata, "duration", NULL, 0);
1949
        av_dict_set(&oc->metadata, "creation_time", NULL, 0);
1950
    }
1951
    if (!o->metadata_streams_manual)
1952
        for (i = of->ost_index; i < nb_output_streams; i++) {
1953
            InputStream *ist;
1954
            if (output_streams[i]->source_index < 0)         /* this is true e.g. for attached files */
1955
                continue;
1956
            ist = input_streams[output_streams[i]->source_index];
1957
            av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
1958
        }
1959
 
1960
    /* process manually set metadata */
1961
    for (i = 0; i < o->nb_metadata; i++) {
1962
        AVDictionary **m;
1963
        char type, *val;
1964
        const char *stream_spec;
1965
        int index = 0, j, ret = 0;
1966
 
1967
        val = strchr(o->metadata[i].u.str, '=');
1968
        if (!val) {
1969
            av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
1970
                   o->metadata[i].u.str);
1971
            exit_program(1);
1972
        }
1973
        *val++ = 0;
1974
 
1975
        parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
1976
        if (type == 's') {
1977
            for (j = 0; j < oc->nb_streams; j++) {
1978
                if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
1979
                    av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
1980
                } else if (ret < 0)
1981
                    exit_program(1);
1982
            }
1983
        }
1984
        else {
1985
            switch (type) {
1986
            case 'g':
1987
                m = &oc->metadata;
1988
                break;
1989
            case 'c':
1990
                if (index < 0 || index >= oc->nb_chapters) {
1991
                    av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
1992
                    exit_program(1);
1993
                }
1994
                m = &oc->chapters[index]->metadata;
1995
                break;
1996
            default:
1997
                av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
1998
                exit_program(1);
1999
            }
2000
            av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
2001
        }
2002
    }
2003
 
2004
    return 0;
2005
}
2006
 
2007
static int opt_target(void *optctx, const char *opt, const char *arg)
2008
{
2009
    OptionsContext *o = optctx;
2010
    enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
2011
    static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
2012
 
2013
    if (!strncmp(arg, "pal-", 4)) {
2014
        norm = PAL;
2015
        arg += 4;
2016
    } else if (!strncmp(arg, "ntsc-", 5)) {
2017
        norm = NTSC;
2018
        arg += 5;
2019
    } else if (!strncmp(arg, "film-", 5)) {
2020
        norm = FILM;
2021
        arg += 5;
2022
    } else {
2023
        /* Try to determine PAL/NTSC by peeking in the input files */
2024
        if (nb_input_files) {
2025
            int i, j, fr;
2026
            for (j = 0; j < nb_input_files; j++) {
2027
                for (i = 0; i < input_files[j]->nb_streams; i++) {
2028
                    AVCodecContext *c = input_files[j]->ctx->streams[i]->codec;
2029
                    if (c->codec_type != AVMEDIA_TYPE_VIDEO)
2030
                        continue;
2031
                    fr = c->time_base.den * 1000 / c->time_base.num;
2032
                    if (fr == 25000) {
2033
                        norm = PAL;
2034
                        break;
2035
                    } else if ((fr == 29970) || (fr == 23976)) {
2036
                        norm = NTSC;
2037
                        break;
2038
                    }
2039
                }
2040
                if (norm != UNKNOWN)
2041
                    break;
2042
            }
2043
        }
2044
        if (norm != UNKNOWN)
2045
            av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
2046
    }
2047
 
2048
    if (norm == UNKNOWN) {
2049
        av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
2050
        av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
2051
        av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
2052
        exit_program(1);
2053
    }
2054
 
2055
    if (!strcmp(arg, "vcd")) {
2056
        opt_video_codec(o, "c:v", "mpeg1video");
2057
        opt_audio_codec(o, "c:a", "mp2");
2058
        parse_option(o, "f", "vcd", options);
2059
        av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
2060
 
2061
        parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
2062
        parse_option(o, "r", frame_rates[norm], options);
2063
        av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
2064
 
2065
        av_dict_set(&o->g->codec_opts, "b:v", "1150000", 0);
2066
        av_dict_set(&o->g->codec_opts, "maxrate", "1150000", 0);
2067
        av_dict_set(&o->g->codec_opts, "minrate", "1150000", 0);
2068
        av_dict_set(&o->g->codec_opts, "bufsize", "327680", 0); // 40*1024*8;
2069
 
2070
        av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
2071
        parse_option(o, "ar", "44100", options);
2072
        parse_option(o, "ac", "2", options);
2073
 
2074
        av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
2075
        av_dict_set(&o->g->format_opts, "muxrate", "1411200", 0); // 2352 * 75 * 8;
2076
 
2077
        /* We have to offset the PTS, so that it is consistent with the SCR.
2078
           SCR starts at 36000, but the first two packs contain only padding
2079
           and the first pack from the other stream, respectively, may also have
2080
           been written before.
2081
           So the real data starts at SCR 36000+3*1200. */
2082
        o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
2083
    } else if (!strcmp(arg, "svcd")) {
2084
 
2085
        opt_video_codec(o, "c:v", "mpeg2video");
2086
        opt_audio_codec(o, "c:a", "mp2");
2087
        parse_option(o, "f", "svcd", options);
2088
 
2089
        parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
2090
        parse_option(o, "r", frame_rates[norm], options);
2091
        parse_option(o, "pix_fmt", "yuv420p", options);
2092
        av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
2093
 
2094
        av_dict_set(&o->g->codec_opts, "b:v", "2040000", 0);
2095
        av_dict_set(&o->g->codec_opts, "maxrate", "2516000", 0);
2096
        av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1145000;
2097
        av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
2098
        av_dict_set(&o->g->codec_opts, "scan_offset", "1", 0);
2099
 
2100
        av_dict_set(&o->g->codec_opts, "b:a", "224000", 0);
2101
        parse_option(o, "ar", "44100", options);
2102
 
2103
        av_dict_set(&o->g->format_opts, "packetsize", "2324", 0);
2104
 
2105
    } else if (!strcmp(arg, "dvd")) {
2106
 
2107
        opt_video_codec(o, "c:v", "mpeg2video");
2108
        opt_audio_codec(o, "c:a", "ac3");
2109
        parse_option(o, "f", "dvd", options);
2110
 
2111
        parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
2112
        parse_option(o, "r", frame_rates[norm], options);
2113
        parse_option(o, "pix_fmt", "yuv420p", options);
2114
        av_dict_set(&o->g->codec_opts, "g", norm == PAL ? "15" : "18", 0);
2115
 
2116
        av_dict_set(&o->g->codec_opts, "b:v", "6000000", 0);
2117
        av_dict_set(&o->g->codec_opts, "maxrate", "9000000", 0);
2118
        av_dict_set(&o->g->codec_opts, "minrate", "0", 0); // 1500000;
2119
        av_dict_set(&o->g->codec_opts, "bufsize", "1835008", 0); // 224*1024*8;
2120
 
2121
        av_dict_set(&o->g->format_opts, "packetsize", "2048", 0);  // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
2122
        av_dict_set(&o->g->format_opts, "muxrate", "10080000", 0); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
2123
 
2124
        av_dict_set(&o->g->codec_opts, "b:a", "448000", 0);
2125
        parse_option(o, "ar", "48000", options);
2126
 
2127
    } else if (!strncmp(arg, "dv", 2)) {
2128
 
2129
        parse_option(o, "f", "dv", options);
2130
 
2131
        parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
2132
        parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
2133
                          norm == PAL ? "yuv420p" : "yuv411p", options);
2134
        parse_option(o, "r", frame_rates[norm], options);
2135
 
2136
        parse_option(o, "ar", "48000", options);
2137
        parse_option(o, "ac", "2", options);
2138
 
2139
    } else {
2140
        av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
2141
        return AVERROR(EINVAL);
2142
    }
2143
    return 0;
2144
}
2145
 
2146
static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
2147
{
2148
    av_free (vstats_filename);
2149
    vstats_filename = av_strdup (arg);
2150
    return 0;
2151
}
2152
 
2153
static int opt_vstats(void *optctx, const char *opt, const char *arg)
2154
{
2155
    char filename[40];
2156
    time_t today2 = time(NULL);
2157
    struct tm *today = localtime(&today2);
2158
 
2159
    snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
2160
             today->tm_sec);
2161
    return opt_vstats_file(NULL, opt, filename);
2162
}
2163
 
2164
static int opt_video_frames(void *optctx, const char *opt, const char *arg)
2165
{
2166
    OptionsContext *o = optctx;
2167
    return parse_option(o, "frames:v", arg, options);
2168
}
2169
 
2170
static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
2171
{
2172
    OptionsContext *o = optctx;
2173
    return parse_option(o, "frames:a", arg, options);
2174
}
2175
 
2176
static int opt_data_frames(void *optctx, const char *opt, const char *arg)
2177
{
2178
    OptionsContext *o = optctx;
2179
    return parse_option(o, "frames:d", arg, options);
2180
}
2181
 
2182
static int opt_default_new(OptionsContext *o, const char *opt, const char *arg)
2183
{
2184
    int ret;
2185
    AVDictionary *cbak = codec_opts;
2186
    AVDictionary *fbak = format_opts;
2187
    codec_opts = NULL;
2188
    format_opts = NULL;
2189
 
2190
    ret = opt_default(NULL, opt, arg);
2191
 
2192
    av_dict_copy(&o->g->codec_opts , codec_opts, 0);
2193
    av_dict_copy(&o->g->format_opts, format_opts, 0);
2194
    av_dict_free(&codec_opts);
2195
    av_dict_free(&format_opts);
2196
    codec_opts = cbak;
2197
    format_opts = fbak;
2198
 
2199
    return ret;
2200
}
2201
 
2202
static int opt_preset(void *optctx, const char *opt, const char *arg)
2203
{
2204
    OptionsContext *o = optctx;
2205
    FILE *f=NULL;
2206
    char filename[1000], line[1000], tmp_line[1000];
2207
    const char *codec_name = NULL;
2208
 
2209
    tmp_line[0] = *opt;
2210
    tmp_line[1] = 0;
2211
    MATCH_PER_TYPE_OPT(codec_names, str, codec_name, NULL, tmp_line);
2212
 
2213
    if (!(f = get_preset_file(filename, sizeof(filename), arg, *opt == 'f', codec_name))) {
2214
        if(!strncmp(arg, "libx264-lossless", strlen("libx264-lossless"))){
2215
            av_log(NULL, AV_LOG_FATAL, "Please use -preset  -qp 0\n");
2216
        }else
2217
            av_log(NULL, AV_LOG_FATAL, "File for preset '%s' not found\n", arg);
2218
        exit_program(1);
2219
    }
2220
 
2221
    while (fgets(line, sizeof(line), f)) {
2222
        char *key = tmp_line, *value, *endptr;
2223
 
2224
        if (strcspn(line, "#\n\r") == 0)
2225
            continue;
2226
        av_strlcpy(tmp_line, line, sizeof(tmp_line));
2227
        if (!av_strtok(key,   "=",    &value) ||
2228
            !av_strtok(value, "\r\n", &endptr)) {
2229
            av_log(NULL, AV_LOG_FATAL, "%s: Invalid syntax: '%s'\n", filename, line);
2230
            exit_program(1);
2231
        }
2232
        av_log(NULL, AV_LOG_DEBUG, "ffpreset[%s]: set '%s' = '%s'\n", filename, key, value);
2233
 
2234
        if      (!strcmp(key, "acodec")) opt_audio_codec   (o, key, value);
2235
        else if (!strcmp(key, "vcodec")) opt_video_codec   (o, key, value);
2236
        else if (!strcmp(key, "scodec")) opt_subtitle_codec(o, key, value);
2237
        else if (!strcmp(key, "dcodec")) opt_data_codec    (o, key, value);
2238
        else if (opt_default_new(o, key, value) < 0) {
2239
            av_log(NULL, AV_LOG_FATAL, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n",
2240
                   filename, line, key, value);
2241
            exit_program(1);
2242
        }
2243
    }
2244
 
2245
    fclose(f);
2246
 
2247
    return 0;
2248
}
2249
 
2250
static int opt_old2new(void *optctx, const char *opt, const char *arg)
2251
{
2252
    OptionsContext *o = optctx;
2253
    char *s = av_asprintf("%s:%c", opt + 1, *opt);
2254
    int ret = parse_option(o, s, arg, options);
2255
    av_free(s);
2256
    return ret;
2257
}
2258
 
2259
static int opt_bitrate(void *optctx, const char *opt, const char *arg)
2260
{
2261
    OptionsContext *o = optctx;
2262
    if(!strcmp(opt, "b")){
2263
        av_log(NULL, AV_LOG_WARNING, "Please use -b:a or -b:v, -b is ambiguous\n");
2264
        av_dict_set(&o->g->codec_opts, "b:v", arg, 0);
2265
        return 0;
2266
    }
2267
    av_dict_set(&o->g->codec_opts, opt, arg, 0);
2268
    return 0;
2269
}
2270
 
2271
static int opt_qscale(void *optctx, const char *opt, const char *arg)
2272
{
2273
    OptionsContext *o = optctx;
2274
    char *s;
2275
    int ret;
2276
    if(!strcmp(opt, "qscale")){
2277
        av_log(NULL, AV_LOG_WARNING, "Please use -q:a or -q:v, -qscale is ambiguous\n");
2278
        return parse_option(o, "q:v", arg, options);
2279
    }
2280
    s = av_asprintf("q%s", opt + 6);
2281
    ret = parse_option(o, s, arg, options);
2282
    av_free(s);
2283
    return ret;
2284
}
2285
 
2286
static int opt_profile(void *optctx, const char *opt, const char *arg)
2287
{
2288
    OptionsContext *o = optctx;
2289
    if(!strcmp(opt, "profile")){
2290
        av_log(NULL, AV_LOG_WARNING, "Please use -profile:a or -profile:v, -profile is ambiguous\n");
2291
        av_dict_set(&o->g->codec_opts, "profile:v", arg, 0);
2292
        return 0;
2293
    }
2294
    av_dict_set(&o->g->codec_opts, opt, arg, 0);
2295
    return 0;
2296
}
2297
 
2298
static int opt_video_filters(void *optctx, const char *opt, const char *arg)
2299
{
2300
    OptionsContext *o = optctx;
2301
    return parse_option(o, "filter:v", arg, options);
2302
}
2303
 
2304
static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
2305
{
2306
    OptionsContext *o = optctx;
2307
    return parse_option(o, "filter:a", arg, options);
2308
}
2309
 
2310
static int opt_vsync(void *optctx, const char *opt, const char *arg)
2311
{
2312
    if      (!av_strcasecmp(arg, "cfr"))         video_sync_method = VSYNC_CFR;
2313
    else if (!av_strcasecmp(arg, "vfr"))         video_sync_method = VSYNC_VFR;
2314
    else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
2315
    else if (!av_strcasecmp(arg, "drop"))        video_sync_method = VSYNC_DROP;
2316
 
2317
    if (video_sync_method == VSYNC_AUTO)
2318
        video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
2319
    return 0;
2320
}
2321
 
2322
static int opt_timecode(void *optctx, const char *opt, const char *arg)
2323
{
2324
    OptionsContext *o = optctx;
2325
    char *tcr = av_asprintf("timecode=%s", arg);
2326
    int ret = parse_option(o, "metadata:g", tcr, options);
2327
    if (ret >= 0)
2328
        ret = av_dict_set(&o->g->codec_opts, "gop_timecode", arg, 0);
2329
    av_free(tcr);
2330
    return 0;
2331
}
2332
 
2333
static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
2334
{
2335
    OptionsContext *o = optctx;
2336
    char layout_str[32];
2337
    char *stream_str;
2338
    char *ac_str;
2339
    int ret, channels, ac_str_size;
2340
    uint64_t layout;
2341
 
2342
    layout = av_get_channel_layout(arg);
2343
    if (!layout) {
2344
        av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
2345
        return AVERROR(EINVAL);
2346
    }
2347
    snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
2348
    ret = opt_default_new(o, opt, layout_str);
2349
    if (ret < 0)
2350
        return ret;
2351
 
2352
    /* set 'ac' option based on channel layout */
2353
    channels = av_get_channel_layout_nb_channels(layout);
2354
    snprintf(layout_str, sizeof(layout_str), "%d", channels);
2355
    stream_str = strchr(opt, ':');
2356
    ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
2357
    ac_str = av_mallocz(ac_str_size);
2358
    if (!ac_str)
2359
        return AVERROR(ENOMEM);
2360
    av_strlcpy(ac_str, "ac", 3);
2361
    if (stream_str)
2362
        av_strlcat(ac_str, stream_str, ac_str_size);
2363
    ret = parse_option(o, ac_str, layout_str, options);
2364
    av_free(ac_str);
2365
 
2366
    return ret;
2367
}
2368
 
2369
static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
2370
{
2371
    OptionsContext *o = optctx;
2372
    return parse_option(o, "q:a", arg, options);
2373
}
2374
 
2375
static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
2376
{
2377
    GROW_ARRAY(filtergraphs, nb_filtergraphs);
2378
    if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
2379
        return AVERROR(ENOMEM);
2380
    filtergraphs[nb_filtergraphs - 1]->index      = nb_filtergraphs - 1;
2381
    filtergraphs[nb_filtergraphs - 1]->graph_desc = av_strdup(arg);
2382
    if (!filtergraphs[nb_filtergraphs - 1]->graph_desc)
2383
        return AVERROR(ENOMEM);
2384
    return 0;
2385
}
2386
 
2387
static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
2388
{
2389
    uint8_t *graph_desc = read_file(arg);
2390
    if (!graph_desc)
2391
        return AVERROR(EINVAL);
2392
 
2393
    GROW_ARRAY(filtergraphs, nb_filtergraphs);
2394
    if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
2395
        return AVERROR(ENOMEM);
2396
    filtergraphs[nb_filtergraphs - 1]->index      = nb_filtergraphs - 1;
2397
    filtergraphs[nb_filtergraphs - 1]->graph_desc = graph_desc;
2398
    return 0;
2399
}
2400
 
2401
void show_help_default(const char *opt, const char *arg)
2402
{
2403
    /* per-file options have at least one of those set */
2404
    const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
2405
    int show_advanced = 0, show_avoptions = 0;
2406
 
2407
    if (opt && *opt) {
2408
        if (!strcmp(opt, "long"))
2409
            show_advanced = 1;
2410
        else if (!strcmp(opt, "full"))
2411
            show_advanced = show_avoptions = 1;
2412
        else
2413
            av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
2414
    }
2415
 
2416
    show_usage();
2417
 
2418
    printf("Getting help:\n"
2419
           "    -h      -- print basic options\n"
2420
           "    -h long -- print more options\n"
2421
           "    -h full -- print all options (including all format and codec specific options, very long)\n"
2422
           "    See man %s for detailed description of the options.\n"
2423
           "\n", program_name);
2424
 
2425
    show_help_options(options, "Print help / information / capabilities:",
2426
                      OPT_EXIT, 0, 0);
2427
 
2428
    show_help_options(options, "Global options (affect whole program "
2429
                      "instead of just one file:",
2430
                      0, per_file | OPT_EXIT | OPT_EXPERT, 0);
2431
    if (show_advanced)
2432
        show_help_options(options, "Advanced global options:", OPT_EXPERT,
2433
                          per_file | OPT_EXIT, 0);
2434
 
2435
    show_help_options(options, "Per-file main options:", 0,
2436
                      OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
2437
                      OPT_EXIT, per_file);
2438
    if (show_advanced)
2439
        show_help_options(options, "Advanced per-file options:",
2440
                          OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
2441
 
2442
    show_help_options(options, "Video options:",
2443
                      OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
2444
    if (show_advanced)
2445
        show_help_options(options, "Advanced Video options:",
2446
                          OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
2447
 
2448
    show_help_options(options, "Audio options:",
2449
                      OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
2450
    if (show_advanced)
2451
        show_help_options(options, "Advanced Audio options:",
2452
                          OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
2453
    show_help_options(options, "Subtitle options:",
2454
                      OPT_SUBTITLE, 0, 0);
2455
    printf("\n");
2456
 
2457
    if (show_avoptions) {
2458
        int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
2459
        show_help_children(avcodec_get_class(), flags);
2460
        show_help_children(avformat_get_class(), flags);
2461
#if CONFIG_SWSCALE
2462
        show_help_children(sws_get_class(), flags);
2463
#endif
2464
        show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
2465
        show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM);
2466
    }
2467
}
2468
 
2469
void show_usage(void)
2470
{
2471
    av_log(NULL, AV_LOG_INFO, "Hyper fast Audio and Video encoder\n");
2472
    av_log(NULL, AV_LOG_INFO, "usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
2473
    av_log(NULL, AV_LOG_INFO, "\n");
2474
}
2475
 
2476
enum OptGroup {
2477
    GROUP_OUTFILE,
2478
    GROUP_INFILE,
2479
};
2480
 
2481
static const OptionGroupDef groups[] = {
2482
    [GROUP_OUTFILE] = { "output file",  NULL, OPT_OUTPUT },
2483
    [GROUP_INFILE]  = { "input file",   "i",  OPT_INPUT },
2484
};
2485
 
2486
static int open_files(OptionGroupList *l, const char *inout,
2487
                      int (*open_file)(OptionsContext*, const char*))
2488
{
2489
    int i, ret;
2490
 
2491
    for (i = 0; i < l->nb_groups; i++) {
2492
        OptionGroup *g = &l->groups[i];
2493
        OptionsContext o;
2494
 
2495
        init_options(&o);
2496
        o.g = g;
2497
 
2498
        ret = parse_optgroup(&o, g);
2499
        if (ret < 0) {
2500
            av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
2501
                   "%s.\n", inout, g->arg);
2502
            return ret;
2503
        }
2504
 
2505
        av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
2506
        ret = open_file(&o, g->arg);
2507
        uninit_options(&o);
2508
        if (ret < 0) {
2509
            av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
2510
                   inout, g->arg);
2511
            return ret;
2512
        }
2513
        av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
2514
    }
2515
 
2516
    return 0;
2517
}
2518
 
2519
int ffmpeg_parse_options(int argc, char **argv)
2520
{
2521
    OptionParseContext octx;
2522
    uint8_t error[128];
2523
    int ret;
2524
 
2525
    memset(&octx, 0, sizeof(octx));
2526
 
2527
    /* split the commandline into an internal representation */
2528
    ret = split_commandline(&octx, argc, argv, options, groups,
2529
                            FF_ARRAY_ELEMS(groups));
2530
    if (ret < 0) {
2531
        av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
2532
        goto fail;
2533
    }
2534
 
2535
    /* apply global options */
2536
    ret = parse_optgroup(NULL, &octx.global_opts);
2537
    if (ret < 0) {
2538
        av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
2539
        goto fail;
2540
    }
2541
 
2542
    /* open input files */
2543
    ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
2544
    if (ret < 0) {
2545
        av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
2546
        goto fail;
2547
    }
2548
 
2549
    /* open output files */
2550
    ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
2551
    if (ret < 0) {
2552
        av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
2553
        goto fail;
2554
    }
2555
 
2556
fail:
2557
    uninit_parse_context(&octx);
2558
    if (ret < 0) {
2559
        av_strerror(ret, error, sizeof(error));
2560
        av_log(NULL, AV_LOG_FATAL, "%s\n", error);
2561
    }
2562
    return ret;
2563
}
2564
 
2565
static int opt_progress(void *optctx, const char *opt, const char *arg)
2566
{
2567
    AVIOContext *avio = NULL;
2568
    int ret;
2569
 
2570
    if (!strcmp(arg, "-"))
2571
        arg = "pipe:";
2572
    ret = avio_open2(&avio, arg, AVIO_FLAG_WRITE, &int_cb, NULL);
2573
    if (ret < 0) {
2574
        av_log(NULL, AV_LOG_ERROR, "Failed to open progress URL \"%s\": %s\n",
2575
               arg, av_err2str(ret));
2576
        return ret;
2577
    }
2578
    progress_avio = avio;
2579
    return 0;
2580
}
2581
 
2582
#define OFFSET(x) offsetof(OptionsContext, x)
2583
const OptionDef options[] = {
2584
    /* main options */
2585
#include "cmdutils_common_opts.h"
2586
    { "f",              HAS_ARG | OPT_STRING | OPT_OFFSET |
2587
                        OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(format) },
2588
        "force format", "fmt" },
2589
    { "y",              OPT_BOOL,                                    {              &file_overwrite },
2590
        "overwrite output files" },
2591
    { "n",              OPT_BOOL,                                    {              &no_file_overwrite },
2592
        "never overwrite output files" },
2593
    { "c",              HAS_ARG | OPT_STRING | OPT_SPEC |
2594
                        OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(codec_names) },
2595
        "codec name", "codec" },
2596
    { "codec",          HAS_ARG | OPT_STRING | OPT_SPEC |
2597
                        OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(codec_names) },
2598
        "codec name", "codec" },
2599
    { "pre",            HAS_ARG | OPT_STRING | OPT_SPEC |
2600
                        OPT_OUTPUT,                                  { .off       = OFFSET(presets) },
2601
        "preset name", "preset" },
2602
    { "map",            HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2603
                        OPT_OUTPUT,                                  { .func_arg = opt_map },
2604
        "set input stream mapping",
2605
        "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
2606
    { "map_channel",    HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_map_channel },
2607
        "map an audio channel from one stream to another", "file.stream.channel[:syncfile.syncstream]" },
2608
    { "map_metadata",   HAS_ARG | OPT_STRING | OPT_SPEC |
2609
                        OPT_OUTPUT,                                  { .off       = OFFSET(metadata_map) },
2610
        "set metadata information of outfile from infile",
2611
        "outfile[,metadata]:infile[,metadata]" },
2612
    { "map_chapters",   HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
2613
                        OPT_OUTPUT,                                  { .off = OFFSET(chapters_input_file) },
2614
        "set chapters mapping", "input_file_index" },
2615
    { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET |
2616
                        OPT_INPUT | OPT_OUTPUT,                      { .off = OFFSET(recording_time) },
2617
        "record or transcode \"duration\" seconds of audio/video",
2618
        "duration" },
2619
    { "to",             HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_OUTPUT,  { .off = OFFSET(stop_time) },
2620
        "record or transcode stop time", "time_stop" },
2621
    { "fs",             HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
2622
        "set the limit file size in bytes", "limit_size" },
2623
    { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET |
2624
                        OPT_INPUT | OPT_OUTPUT,                      { .off = OFFSET(start_time) },
2625
        "set the start time offset", "time_off" },
2626
    { "accurate_seek",  OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
2627
                        OPT_INPUT,                                   { .off = OFFSET(accurate_seek) },
2628
        "enable/disable accurate seeking with -ss" },
2629
    { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET |
2630
                        OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(input_ts_offset) },
2631
        "set the input ts offset", "time_off" },
2632
    { "itsscale",       HAS_ARG | OPT_DOUBLE | OPT_SPEC |
2633
                        OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(ts_scale) },
2634
        "set the input ts scale", "scale" },
2635
    { "timestamp",      HAS_ARG | OPT_PERFILE,                       { .func_arg = opt_recording_timestamp },
2636
        "set the recording timestamp ('now' to set the current time)", "time" },
2637
    { "metadata",       HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
2638
        "add metadata", "string=string" },
2639
    { "dframes",        HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2640
                        OPT_OUTPUT,                                  { .func_arg = opt_data_frames },
2641
        "set the number of data frames to record", "number" },
2642
    { "benchmark",      OPT_BOOL | OPT_EXPERT,                       { &do_benchmark },
2643
        "add timings for benchmarking" },
2644
    { "benchmark_all",  OPT_BOOL | OPT_EXPERT,                       { &do_benchmark_all },
2645
      "add timings for each task" },
2646
    { "progress",       HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_progress },
2647
      "write program-readable progress information", "url" },
2648
    { "stdin",          OPT_BOOL | OPT_EXPERT,                       { &stdin_interaction },
2649
      "enable or disable interaction on standard input" },
2650
    { "timelimit",      HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_timelimit },
2651
        "set max runtime in seconds", "limit" },
2652
    { "dump",           OPT_BOOL | OPT_EXPERT,                       { &do_pkt_dump },
2653
        "dump each input packet" },
2654
    { "hex",            OPT_BOOL | OPT_EXPERT,                       { &do_hex_dump },
2655
        "when dumping packets, also dump the payload" },
2656
    { "re",             OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2657
                        OPT_INPUT,                                   { .off = OFFSET(rate_emu) },
2658
        "read input at native frame rate", "" },
2659
    { "target",         HAS_ARG | OPT_PERFILE | OPT_OUTPUT,          { .func_arg = opt_target },
2660
        "specify target file type (\"vcd\", \"svcd\", \"dvd\","
2661
        " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
2662
    { "vsync",          HAS_ARG | OPT_EXPERT,                        { opt_vsync },
2663
        "video sync method", "" },
2664
    { "async",          HAS_ARG | OPT_INT | OPT_EXPERT,              { &audio_sync_method },
2665
        "audio sync method", "" },
2666
    { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,          { &audio_drift_threshold },
2667
        "audio drift threshold", "threshold" },
2668
    { "copyts",         OPT_BOOL | OPT_EXPERT,                       { ©_ts },
2669
        "copy timestamps" },
2670
    { "copytb",         HAS_ARG | OPT_INT | OPT_EXPERT,              { ©_tb },
2671
        "copy input stream time base when stream copying", "mode" },
2672
    { "shortest",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2673
                        OPT_OUTPUT,                                  { .off = OFFSET(shortest) },
2674
        "finish encoding within shortest input" },
2675
    { "apad",           OPT_STRING | HAS_ARG | OPT_SPEC |
2676
                        OPT_OUTPUT,                                  { .off = OFFSET(apad) },
2677
        "audio pad", "" },
2678
    { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_delta_threshold },
2679
        "timestamp discontinuity delta threshold", "threshold" },
2680
    { "dts_error_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_error_threshold },
2681
        "timestamp error delta threshold", "threshold" },
2682
    { "xerror",         OPT_BOOL | OPT_EXPERT,                       { &exit_on_error },
2683
        "exit on error", "error" },
2684
    { "copyinkf",       OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2685
                        OPT_OUTPUT,                                  { .off = OFFSET(copy_initial_nonkeyframes) },
2686
        "copy initial non-keyframes" },
2687
    { "copypriorss",    OPT_INT | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_OUTPUT,   { .off = OFFSET(copy_prior_start) },
2688
        "copy or discard frames before start time" },
2689
    { "frames",         OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
2690
        "set the number of frames to record", "number" },
2691
    { "tag",            OPT_STRING | HAS_ARG | OPT_SPEC |
2692
                        OPT_EXPERT | OPT_OUTPUT,                     { .off = OFFSET(codec_tags) },
2693
        "force codec tag/fourcc", "fourcc/tag" },
2694
    { "q",              HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2695
                        OPT_SPEC | OPT_OUTPUT,                       { .off = OFFSET(qscale) },
2696
        "use fixed quality scale (VBR)", "q" },
2697
    { "qscale",         HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2698
                        OPT_OUTPUT,                                  { .func_arg = opt_qscale },
2699
        "use fixed quality scale (VBR)", "q" },
2700
    { "profile",        HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_profile },
2701
        "set profile", "profile" },
2702
    { "filter",         HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
2703
        "set stream filtergraph", "filter_graph" },
2704
    { "filter_script",  HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) },
2705
        "read stream filtergraph description from a file", "filename" },
2706
    { "reinit_filter",  HAS_ARG | OPT_INT | OPT_SPEC | OPT_INPUT,    { .off = OFFSET(reinit_filters) },
2707
        "reinit filtergraph on input parameter changes", "" },
2708
    { "filter_complex", HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
2709
        "create a complex filtergraph", "graph_description" },
2710
    { "lavfi",          HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
2711
        "create a complex filtergraph", "graph_description" },
2712
    { "filter_complex_script", HAS_ARG | OPT_EXPERT,                 { .func_arg = opt_filter_complex_script },
2713
        "read complex filtergraph description from a file", "filename" },
2714
    { "stats",          OPT_BOOL,                                    { &print_stats },
2715
        "print progress report during encoding", },
2716
    { "attach",         HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2717
                        OPT_OUTPUT,                                  { .func_arg = opt_attach },
2718
        "add an attachment to the output file", "filename" },
2719
    { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |
2720
                         OPT_EXPERT | OPT_INPUT,                     { .off = OFFSET(dump_attachment) },
2721
        "extract an attachment into a file", "filename" },
2722
    { "debug_ts",       OPT_BOOL | OPT_EXPERT,                       { &debug_ts },
2723
        "print timestamp debugging info" },
2724
    { "max_error_rate",  HAS_ARG | OPT_FLOAT,                        { &max_error_rate },
2725
        "maximum error rate", "ratio of errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success." },
2726
 
2727
    /* video options */
2728
    { "vframes",      OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_video_frames },
2729
        "set the number of video frames to record", "number" },
2730
    { "r",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
2731
                      OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_rates) },
2732
        "set frame rate (Hz value, fraction or abbreviation)", "rate" },
2733
    { "s",            OPT_VIDEO | HAS_ARG | OPT_SUBTITLE | OPT_STRING | OPT_SPEC |
2734
                      OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_sizes) },
2735
        "set frame size (WxH or abbreviation)", "size" },
2736
    { "aspect",       OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
2737
                      OPT_OUTPUT,                                                { .off = OFFSET(frame_aspect_ratios) },
2738
        "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
2739
    { "pix_fmt",      OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
2740
                      OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_pix_fmts) },
2741
        "set pixel format", "format" },
2742
    { "bits_per_raw_sample", OPT_VIDEO | OPT_INT | HAS_ARG,                      { &frame_bits_per_raw_sample },
2743
        "set the number of bits per raw sample", "number" },
2744
    { "intra",        OPT_VIDEO | OPT_BOOL | OPT_EXPERT,                         { &intra_only },
2745
        "deprecated use -g 1" },
2746
    { "vn",           OPT_VIDEO | OPT_BOOL  | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(video_disable) },
2747
        "disable video" },
2748
    { "vdt",          OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT ,               { &video_discard },
2749
        "discard threshold", "n" },
2750
    { "rc_override",  OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
2751
                      OPT_OUTPUT,                                                { .off = OFFSET(rc_overrides) },
2752
        "rate control override for specific intervals", "override" },
2753
    { "vcodec",       OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_INPUT |
2754
                      OPT_OUTPUT,                                                { .func_arg = opt_video_codec },
2755
        "force video codec ('copy' to copy stream)", "codec" },
2756
    { "sameq",        OPT_VIDEO | OPT_EXPERT ,                                   { .func_arg = opt_sameq },
2757
        "Removed" },
2758
    { "same_quant",   OPT_VIDEO | OPT_EXPERT ,                                   { .func_arg = opt_sameq },
2759
        "Removed" },
2760
    { "timecode",     OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT,            { .func_arg = opt_timecode },
2761
        "set initial TimeCode value.", "hh:mm:ss[:;.]ff" },
2762
    { "pass",         OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT | OPT_OUTPUT,     { .off = OFFSET(pass) },
2763
        "select the pass number (1 to 3)", "n" },
2764
    { "passlogfile",  OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
2765
                      OPT_OUTPUT,                                                { .off = OFFSET(passlogfiles) },
2766
        "select two pass log file name prefix", "prefix" },
2767
    { "deinterlace",  OPT_VIDEO | OPT_BOOL | OPT_EXPERT,                         { &do_deinterlace },
2768
        "this option is deprecated, use the yadif filter instead" },
2769
    { "psnr",         OPT_VIDEO | OPT_BOOL | OPT_EXPERT,                         { &do_psnr },
2770
        "calculate PSNR of compressed frames" },
2771
    { "vstats",       OPT_VIDEO | OPT_EXPERT ,                                   { &opt_vstats },
2772
        "dump video coding statistics to file" },
2773
    { "vstats_file",  OPT_VIDEO | HAS_ARG | OPT_EXPERT ,                         { opt_vstats_file },
2774
        "dump video coding statistics to file", "file" },
2775
    { "vf",           OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_video_filters },
2776
        "set video filters", "filter_graph" },
2777
    { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
2778
                      OPT_OUTPUT,                                                { .off = OFFSET(intra_matrices) },
2779
        "specify intra matrix coeffs", "matrix" },
2780
    { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
2781
                      OPT_OUTPUT,                                                { .off = OFFSET(inter_matrices) },
2782
        "specify inter matrix coeffs", "matrix" },
2783
    { "top",          OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_INT| OPT_SPEC |
2784
                      OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(top_field_first) },
2785
        "top=1/bottom=0/auto=-1 field first", "" },
2786
    { "dc",           OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT ,               { &intra_dc_precision },
2787
        "intra_dc_precision", "precision" },
2788
    { "vtag",         OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_PERFILE |
2789
                      OPT_OUTPUT,                                                { .func_arg = opt_old2new },
2790
        "force video tag/fourcc", "fourcc/tag" },
2791
    { "qphist",       OPT_VIDEO | OPT_BOOL | OPT_EXPERT ,                        { &qp_hist },
2792
        "show QP histogram" },
2793
    { "force_fps",    OPT_VIDEO | OPT_BOOL | OPT_EXPERT  | OPT_SPEC |
2794
                      OPT_OUTPUT,                                                { .off = OFFSET(force_fps) },
2795
        "force the selected framerate, disable the best supported framerate selection" },
2796
    { "streamid",     OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2797
                      OPT_OUTPUT,                                                { .func_arg = opt_streamid },
2798
        "set the value of an outfile streamid", "streamIndex:value" },
2799
    { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2800
                          OPT_SPEC | OPT_OUTPUT,                                 { .off = OFFSET(forced_key_frames) },
2801
        "force key frames at specified timestamps", "timestamps" },
2802
    { "b",            OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT,            { .func_arg = opt_bitrate },
2803
        "video bitrate (please use -b:v)", "bitrate" },
2804
 
2805
    /* audio options */
2806
    { "aframes",        OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_frames },
2807
        "set the number of audio frames to record", "number" },
2808
    { "aq",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_qscale },
2809
        "set audio quality (codec-specific)", "quality", },
2810
    { "ar",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC |
2811
                        OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(audio_sample_rate) },
2812
        "set audio sampling rate (in Hz)", "rate" },
2813
    { "ac",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC |
2814
                        OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(audio_channels) },
2815
        "set number of audio channels", "channels" },
2816
    { "an",             OPT_AUDIO | OPT_BOOL | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(audio_disable) },
2817
        "disable audio" },
2818
    { "acodec",         OPT_AUDIO | HAS_ARG  | OPT_PERFILE |
2819
                        OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_audio_codec },
2820
        "force audio codec ('copy' to copy stream)", "codec" },
2821
    { "atag",           OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
2822
                        OPT_OUTPUT,                                                { .func_arg = opt_old2new },
2823
        "force audio tag/fourcc", "fourcc/tag" },
2824
    { "vol",            OPT_AUDIO | HAS_ARG  | OPT_INT,                            { &audio_volume },
2825
        "change audio volume (256=normal)" , "volume" },
2826
    { "sample_fmt",     OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
2827
                        OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(sample_fmts) },
2828
        "set sample format", "format" },
2829
    { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
2830
                        OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_channel_layout },
2831
        "set channel layout", "layout" },
2832
    { "af",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_filters },
2833
        "set audio filters", "filter_graph" },
2834
    { "guess_layout_max", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(guess_layout_max) },
2835
      "set the maximum number of channels to try to guess the channel layout" },
2836
 
2837
    /* subtitle options */
2838
    { "sn",     OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(subtitle_disable) },
2839
        "disable subtitle" },
2840
    { "scodec", OPT_SUBTITLE | HAS_ARG  | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_subtitle_codec },
2841
        "force subtitle codec ('copy' to copy stream)", "codec" },
2842
    { "stag",   OPT_SUBTITLE | HAS_ARG  | OPT_EXPERT  | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_old2new }
2843
        , "force subtitle tag/fourcc", "fourcc/tag" },
2844
    { "fix_sub_duration", OPT_BOOL | OPT_EXPERT | OPT_SUBTITLE | OPT_SPEC | OPT_INPUT, { .off = OFFSET(fix_sub_duration) },
2845
        "fix subtitles duration" },
2846
    { "canvas_size", OPT_SUBTITLE | HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT, { .off = OFFSET(canvas_sizes) },
2847
        "set canvas size (WxH or abbreviation)", "size" },
2848
 
2849
    /* grab options */
2850
    { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_video_channel },
2851
        "deprecated, use -channel", "channel" },
2852
    { "tvstd", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_video_standard },
2853
        "deprecated, use -standard", "standard" },
2854
    { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
2855
 
2856
    /* muxer options */
2857
    { "muxdelay",   OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_max_delay) },
2858
        "set the maximum demux-decode delay", "seconds" },
2859
    { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
2860
        "set the initial demux-decode delay", "seconds" },
2861
    { "override_ffserver", OPT_BOOL | OPT_EXPERT | OPT_OUTPUT, { &override_ffserver },
2862
        "override the options from ffserver", "" },
2863
 
2864
    { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
2865
        "A comma-separated list of bitstream filters", "bitstream_filters" },
2866
    { "absf", HAS_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_old2new },
2867
        "deprecated", "audio bitstream_filters" },
2868
    { "vbsf", OPT_VIDEO | HAS_ARG | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_old2new },
2869
        "deprecated", "video bitstream_filters" },
2870
 
2871
    { "apre", HAS_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT,    { .func_arg = opt_preset },
2872
        "set the audio options to the indicated preset", "preset" },
2873
    { "vpre", OPT_VIDEO | HAS_ARG | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT,    { .func_arg = opt_preset },
2874
        "set the video options to the indicated preset", "preset" },
2875
    { "spre", HAS_ARG | OPT_SUBTITLE | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_preset },
2876
        "set the subtitle options to the indicated preset", "preset" },
2877
    { "fpre", HAS_ARG | OPT_EXPERT| OPT_PERFILE | OPT_OUTPUT,                { .func_arg = opt_preset },
2878
        "set options from indicated preset file", "filename" },
2879
    /* data codec support */
2880
    { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
2881
        "force data codec ('copy' to copy stream)", "codec" },
2882
    { "dn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(data_disable) },
2883
        "disable data" },
2884
 
2885
    { NULL, },
2886
};