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