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