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