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