2 * avconv option parsing
4 * This file is part of Libav.
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.
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.
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
26 #include "libavformat/avformat.h"
28 #include "libavcodec/avcodec.h"
30 #include "libavfilter/avfilter.h"
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"
44 #define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"
46 #define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
49 for (i = 0; i < o->nb_ ## name; i++) {\
50 char *spec = o->name[i].specifier;\
51 if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
52 outvar = o->name[i].u.type;\
58 const HWAccel hwaccels[] = {
60 { "vdpau", vdpau_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU },
63 { "dxva2", dxva2_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD },
66 { "vda", vda_init, HWACCEL_VDA, AV_PIX_FMT_VDA },
69 { "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV },
72 { "vaapi", vaapi_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI },
76 int hwaccel_lax_profile_check = 0;
77 AVBufferRef *hw_device_ctx;
79 char *vstats_filename;
81 float audio_drift_threshold = 0.1;
82 float dts_delta_threshold = 10;
84 int audio_volume = 256;
85 int audio_sync_method = 0;
86 int video_sync_method = VSYNC_AUTO;
92 int exit_on_error = 0;
96 static int file_overwrite = 0;
97 static int file_skip = 0;
98 static int video_discard = 0;
99 static int intra_dc_precision = 8;
100 static int using_stdin = 0;
101 static int input_sync;
103 static void uninit_options(OptionsContext *o)
105 const OptionDef *po = options;
108 /* all OPT_SPEC and OPT_STRING can be freed in generic way */
110 void *dst = (uint8_t*)o + po->u.off;
112 if (po->flags & OPT_SPEC) {
113 SpecifierOpt **so = dst;
114 int i, *count = (int*)(so + 1);
115 for (i = 0; i < *count; i++) {
116 av_freep(&(*so)[i].specifier);
117 if (po->flags & OPT_STRING)
118 av_freep(&(*so)[i].u.str);
122 } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
127 for (i = 0; i < o->nb_stream_maps; i++)
128 av_freep(&o->stream_maps[i].linklabel);
129 av_freep(&o->stream_maps);
130 av_freep(&o->meta_data_maps);
131 av_freep(&o->streamid_map);
134 static void init_options(OptionsContext *o)
136 memset(o, 0, sizeof(*o));
138 o->mux_max_delay = 0.7;
139 o->start_time = AV_NOPTS_VALUE;
140 o->recording_time = INT64_MAX;
141 o->limit_filesize = UINT64_MAX;
142 o->chapters_input_file = INT_MAX;
143 o->accurate_seek = 1;
146 /* return a copy of the input with the stream specifiers removed from the keys */
147 static AVDictionary *strip_specifiers(AVDictionary *dict)
149 AVDictionaryEntry *e = NULL;
150 AVDictionary *ret = NULL;
152 while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
153 char *p = strchr(e->key, ':');
157 av_dict_set(&ret, e->key, e->value, 0);
164 static double parse_frame_aspect_ratio(const char *arg)
171 p = strchr(arg, ':');
173 x = strtol(arg, &end, 10);
175 y = strtol(end + 1, &end, 10);
177 ar = (double)x / (double)y;
179 ar = strtod(arg, NULL);
182 av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n");
188 static int show_hwaccels(void *optctx, const char *opt, const char *arg)
192 printf("Supported hardware acceleration:\n");
193 for (i = 0; i < FF_ARRAY_ELEMS(hwaccels) - 1; i++) {
194 printf("%s\n", hwaccels[i].name);
200 static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
202 OptionsContext *o = optctx;
203 return parse_option(o, "codec:a", arg, options);
206 static int opt_video_codec(void *optctx, const char *opt, const char *arg)
208 OptionsContext *o = optctx;
209 return parse_option(o, "codec:v", arg, options);
212 static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
214 OptionsContext *o = optctx;
215 return parse_option(o, "codec:s", arg, options);
218 static int opt_data_codec(void *optctx, const char *opt, const char *arg)
220 OptionsContext *o = optctx;
221 return parse_option(o, "codec:d", arg, options);
224 static int opt_map(void *optctx, const char *opt, const char *arg)
226 OptionsContext *o = optctx;
228 int i, negative = 0, file_idx;
229 int sync_file_idx = -1, sync_stream_idx;
237 map = av_strdup(arg);
239 return AVERROR(ENOMEM);
241 /* parse sync stream first, just pick first matching stream */
242 if (sync = strchr(map, ',')) {
244 sync_file_idx = strtol(sync + 1, &sync, 0);
245 if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
246 av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
251 for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
252 if (check_stream_specifier(input_files[sync_file_idx]->ctx,
253 input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
257 if (i == input_files[sync_file_idx]->nb_streams) {
258 av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
259 "match any streams.\n", arg);
266 /* this mapping refers to lavfi output */
267 const char *c = map + 1;
268 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
269 m = &o->stream_maps[o->nb_stream_maps - 1];
270 m->linklabel = av_get_token(&c, "]");
272 av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
276 file_idx = strtol(map, &p, 0);
277 if (file_idx >= nb_input_files || file_idx < 0) {
278 av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
282 /* disable some already defined maps */
283 for (i = 0; i < o->nb_stream_maps; i++) {
284 m = &o->stream_maps[i];
285 if (file_idx == m->file_index &&
286 check_stream_specifier(input_files[m->file_index]->ctx,
287 input_files[m->file_index]->ctx->streams[m->stream_index],
288 *p == ':' ? p + 1 : p) > 0)
292 for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
293 if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
294 *p == ':' ? p + 1 : p) <= 0)
296 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
297 m = &o->stream_maps[o->nb_stream_maps - 1];
299 m->file_index = file_idx;
302 if (sync_file_idx >= 0) {
303 m->sync_file_index = sync_file_idx;
304 m->sync_stream_index = sync_stream_idx;
306 m->sync_file_index = file_idx;
307 m->sync_stream_index = i;
313 av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
321 static int opt_attach(void *optctx, const char *opt, const char *arg)
323 OptionsContext *o = optctx;
324 GROW_ARRAY(o->attachments, o->nb_attachments);
325 o->attachments[o->nb_attachments - 1] = arg;
330 static int opt_vaapi_device(void *optctx, const char *opt, const char *arg)
333 err = vaapi_device_init(arg);
341 * Parse a metadata specifier passed as 'arg' parameter.
342 * @param arg metadata string to parse
343 * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
344 * @param index for type c/p, chapter/program index is written here
345 * @param stream_spec for type s, the stream specifier is written here
347 static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
355 if (*(++arg) && *arg != ':') {
356 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
359 *stream_spec = *arg == ':' ? arg + 1 : "";
364 *index = strtol(++arg, NULL, 0);
367 av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
374 static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
376 AVDictionary **meta_in = NULL;
377 AVDictionary **meta_out;
379 char type_in, type_out;
380 const char *istream_spec = NULL, *ostream_spec = NULL;
381 int idx_in = 0, idx_out = 0;
383 parse_meta_type(inspec, &type_in, &idx_in, &istream_spec);
384 parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
386 if (type_in == 'g' || type_out == 'g')
387 o->metadata_global_manual = 1;
388 if (type_in == 's' || type_out == 's')
389 o->metadata_streams_manual = 1;
390 if (type_in == 'c' || type_out == 'c')
391 o->metadata_chapters_manual = 1;
393 /* ic is NULL when just disabling automatic mappings */
397 #define METADATA_CHECK_INDEX(index, nb_elems, desc)\
398 if ((index) < 0 || (index) >= (nb_elems)) {\
399 av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
404 #define SET_DICT(type, meta, context, index)\
407 meta = &context->metadata;\
410 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
411 meta = &context->chapters[index]->metadata;\
414 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
415 meta = &context->programs[index]->metadata;\
418 break; /* handled separately below */ \
419 default: av_assert0(0);\
422 SET_DICT(type_in, meta_in, ic, idx_in);
423 SET_DICT(type_out, meta_out, oc, idx_out);
425 /* for input streams choose first matching stream */
426 if (type_in == 's') {
427 for (i = 0; i < ic->nb_streams; i++) {
428 if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
429 meta_in = &ic->streams[i]->metadata;
435 av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
440 if (type_out == 's') {
441 for (i = 0; i < oc->nb_streams; i++) {
442 if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
443 meta_out = &oc->streams[i]->metadata;
444 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
449 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
454 static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
456 const AVCodecDescriptor *desc;
457 const char *codec_string = encoder ? "encoder" : "decoder";
461 avcodec_find_encoder_by_name(name) :
462 avcodec_find_decoder_by_name(name);
464 if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
465 codec = encoder ? avcodec_find_encoder(desc->id) :
466 avcodec_find_decoder(desc->id);
468 av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
469 codec_string, codec->name, desc->name);
473 av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
476 if (codec->type != type) {
477 av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
483 static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
485 char *codec_name = NULL;
487 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
489 AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0);
490 st->codecpar->codec_id = codec->id;
493 return avcodec_find_decoder(st->codecpar->codec_id);
496 /* Add all the streams from the given input file to the global
497 * list of input streams. */
498 static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
502 for (i = 0; i < ic->nb_streams; i++) {
503 AVStream *st = ic->streams[i];
504 AVCodecParameters *par = st->codecpar;
505 InputStream *ist = av_mallocz(sizeof(*ist));
506 char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
507 char *hwaccel_output_format = NULL;
508 char *codec_tag = NULL;
514 GROW_ARRAY(input_streams, nb_input_streams);
515 input_streams[nb_input_streams - 1] = ist;
518 ist->file_index = nb_input_files;
520 st->discard = AVDISCARD_ALL;
522 ist->min_pts = INT64_MAX;
523 ist->max_pts = INT64_MIN;
526 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
529 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
531 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
533 uint32_t tag = strtol(codec_tag, &next, 0);
535 tag = AV_RL32(codec_tag);
536 st->codecpar->codec_tag = tag;
539 ist->dec = choose_decoder(o, ic, st);
540 ist->decoder_opts = filter_codec_opts(o->g->codec_opts, par->codec_id, ic, st, ist->dec);
542 ist->dec_ctx = avcodec_alloc_context3(ist->dec);
544 av_log(NULL, AV_LOG_ERROR, "Error allocating the decoder context.\n");
548 ret = avcodec_parameters_to_context(ist->dec_ctx, par);
550 av_log(NULL, AV_LOG_ERROR, "Error initializing the decoder context.\n");
554 switch (par->codec_type) {
555 case AVMEDIA_TYPE_VIDEO:
556 MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
557 if (framerate && av_parse_video_rate(&ist->framerate,
559 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
564 MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
566 if (!strcmp(hwaccel, "none"))
567 ist->hwaccel_id = HWACCEL_NONE;
568 else if (!strcmp(hwaccel, "auto"))
569 ist->hwaccel_id = HWACCEL_AUTO;
572 for (i = 0; hwaccels[i].name; i++) {
573 if (!strcmp(hwaccels[i].name, hwaccel)) {
574 ist->hwaccel_id = hwaccels[i].id;
579 if (!ist->hwaccel_id) {
580 av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
582 av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
583 for (i = 0; hwaccels[i].name; i++)
584 av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
585 av_log(NULL, AV_LOG_FATAL, "\n");
591 MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
592 if (hwaccel_device) {
593 ist->hwaccel_device = av_strdup(hwaccel_device);
594 if (!ist->hwaccel_device)
598 MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
599 hwaccel_output_format, ic, st);
600 if (hwaccel_output_format) {
601 ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
602 if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
603 av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
604 "format: %s", hwaccel_output_format);
607 ist->hwaccel_output_format = AV_PIX_FMT_NONE;
610 ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
613 case AVMEDIA_TYPE_AUDIO:
614 guess_input_channel_layout(ist);
616 case AVMEDIA_TYPE_DATA:
617 case AVMEDIA_TYPE_SUBTITLE:
618 case AVMEDIA_TYPE_ATTACHMENT:
619 case AVMEDIA_TYPE_UNKNOWN:
627 static void assert_file_overwrite(const char *filename)
629 if (file_overwrite && file_skip) {
630 fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
634 if (!file_overwrite &&
635 (!strchr(filename, ':') || filename[1] == ':' ||
636 av_strstart(filename, "file:", NULL))) {
637 if (avio_check(filename, 0) == 0) {
638 if (!using_stdin && !file_skip) {
639 fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
642 fprintf(stderr, "Not overwriting - exiting\n");
647 fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
654 static void dump_attachment(AVStream *st, const char *filename)
657 AVIOContext *out = NULL;
658 AVDictionaryEntry *e;
660 if (!st->codecpar->extradata_size) {
661 av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
662 nb_input_files - 1, st->index);
665 if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
668 av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
669 "in stream #%d:%d.\n", nb_input_files - 1, st->index);
673 assert_file_overwrite(filename);
675 if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
676 av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
681 avio_write(out, st->codecpar->extradata, st->codecpar->extradata_size);
686 static int open_input_file(OptionsContext *o, const char *filename)
690 AVInputFormat *file_iformat = NULL;
695 AVDictionary *unused_opts = NULL;
696 AVDictionaryEntry *e = NULL;
697 int orig_nb_streams; // number of streams before avformat_find_stream_info
700 if (!(file_iformat = av_find_input_format(o->format))) {
701 av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
706 if (!strcmp(filename, "-"))
709 using_stdin |= !strncmp(filename, "pipe:", 5) ||
710 !strcmp(filename, "/dev/stdin");
712 /* get default parameters from command line */
713 ic = avformat_alloc_context();
715 print_error(filename, AVERROR(ENOMEM));
718 if (o->nb_audio_sample_rate) {
719 snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
720 av_dict_set(&o->g->format_opts, "sample_rate", buf, 0);
722 if (o->nb_audio_channels) {
723 /* because we set audio_channels based on both the "ac" and
724 * "channel_layout" options, we need to check that the specified
725 * demuxer actually has the "channels" option before setting it */
726 if (file_iformat && file_iformat->priv_class &&
727 av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
728 AV_OPT_SEARCH_FAKE_OBJ)) {
729 snprintf(buf, sizeof(buf), "%d",
730 o->audio_channels[o->nb_audio_channels - 1].u.i);
731 av_dict_set(&o->g->format_opts, "channels", buf, 0);
734 if (o->nb_frame_rates) {
735 /* set the format-level framerate option;
736 * this is important for video grabbers, e.g. x11 */
737 if (file_iformat && file_iformat->priv_class &&
738 av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
739 AV_OPT_SEARCH_FAKE_OBJ)) {
740 av_dict_set(&o->g->format_opts, "framerate",
741 o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
744 if (o->nb_frame_sizes) {
745 av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
747 if (o->nb_frame_pix_fmts)
748 av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
750 ic->flags |= AVFMT_FLAG_NONBLOCK;
751 ic->interrupt_callback = int_cb;
753 /* open the input file with generic Libav function */
754 err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
756 print_error(filename, err);
759 assert_avoptions(o->g->format_opts);
761 /* apply forced codec ids */
762 for (i = 0; i < ic->nb_streams; i++)
763 choose_decoder(o, ic, ic->streams[i]);
765 /* Set AVCodecContext options for avformat_find_stream_info */
766 opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
767 orig_nb_streams = ic->nb_streams;
769 /* If not enough info to get the stream parameters, we decode the
770 first frames to get it. (used in mpeg case for example) */
771 ret = avformat_find_stream_info(ic, opts);
773 av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
774 avformat_close_input(&ic);
778 timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
779 /* add the stream start time */
780 if (ic->start_time != AV_NOPTS_VALUE)
781 timestamp += ic->start_time;
783 /* if seeking requested, we execute it */
784 if (o->start_time != AV_NOPTS_VALUE) {
785 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
787 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
788 filename, (double)timestamp / AV_TIME_BASE);
792 /* update the current parameters so that they match the one of the input stream */
793 add_input_streams(o, ic);
795 /* dump the file content */
796 av_dump_format(ic, nb_input_files, filename, 0);
798 GROW_ARRAY(input_files, nb_input_files);
799 f = av_mallocz(sizeof(*f));
802 input_files[nb_input_files - 1] = f;
805 f->ist_index = nb_input_streams - ic->nb_streams;
806 f->start_time = o->start_time;
807 f->recording_time = o->recording_time;
808 f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
809 f->nb_streams = ic->nb_streams;
810 f->rate_emu = o->rate_emu;
811 f->accurate_seek = o->accurate_seek;
814 f->time_base = (AVRational){ 1, 1 };
816 /* check if all codec options have been used */
817 unused_opts = strip_specifiers(o->g->codec_opts);
818 for (i = f->ist_index; i < nb_input_streams; i++) {
820 while ((e = av_dict_get(input_streams[i]->decoder_opts, "", e,
821 AV_DICT_IGNORE_SUFFIX)))
822 av_dict_set(&unused_opts, e->key, NULL, 0);
826 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
827 const AVClass *class = avcodec_get_class();
828 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
829 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
832 if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
833 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
834 "input file #%d (%s) is not a decoding option.\n", e->key,
835 option->help ? option->help : "", nb_input_files - 1,
840 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
841 "input file #%d (%s) has not been used for any stream. The most "
842 "likely reason is either wrong type (e.g. a video option with "
843 "no video streams) or that it is a private option of some decoder "
844 "which was not actually used for any stream.\n", e->key,
845 option->help ? option->help : "", nb_input_files - 1, filename);
847 av_dict_free(&unused_opts);
849 for (i = 0; i < o->nb_dump_attachment; i++) {
852 for (j = 0; j < ic->nb_streams; j++) {
853 AVStream *st = ic->streams[j];
855 if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
856 dump_attachment(st, o->dump_attachment[i].u.str);
860 for (i = 0; i < orig_nb_streams; i++)
861 av_dict_free(&opts[i]);
867 static uint8_t *get_line(AVIOContext *s)
873 if (avio_open_dyn_buf(&line) < 0) {
874 av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
878 while ((c = avio_r8(s)) && c != '\n')
881 avio_close_dyn_buf(line, &buf);
886 static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
890 const char *base[3] = { getenv("AVCONV_DATADIR"),
895 for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) {
899 snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
900 i != 1 ? "" : "/.avconv", codec_name, preset_name);
901 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
904 snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
905 i != 1 ? "" : "/.avconv", preset_name);
906 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
912 static int choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
914 enum AVMediaType type = ost->st->codecpar->codec_type;
915 char *codec_name = NULL;
917 if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) {
918 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
920 ost->st->codecpar->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
921 NULL, ost->st->codecpar->codec_type);
922 ost->enc = avcodec_find_encoder(ost->st->codecpar->codec_id);
924 av_log(NULL, AV_LOG_FATAL, "Automatic encoder selection failed for "
925 "output stream #%d:%d. Default encoder for format %s is "
926 "probably disabled. Please choose an encoder manually.\n",
927 ost->file_index, ost->index, s->oformat->name);
928 return AVERROR_ENCODER_NOT_FOUND;
930 } else if (!strcmp(codec_name, "copy"))
931 ost->stream_copy = 1;
933 ost->enc = find_codec_or_die(codec_name, ost->st->codecpar->codec_type, 1);
934 ost->st->codecpar->codec_id = ost->enc->id;
937 ost->encoding_needed = !ost->stream_copy;
939 /* no encoding supported for other media types */
940 ost->stream_copy = 1;
941 ost->encoding_needed = 0;
947 static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
950 AVStream *st = avformat_new_stream(oc, NULL);
951 int idx = oc->nb_streams - 1, ret = 0;
952 const char *bsfs = NULL;
953 char *next, *codec_tag = NULL;
957 av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
961 if (oc->nb_streams - 1 < o->nb_streamid_map)
962 st->id = o->streamid_map[oc->nb_streams - 1];
964 GROW_ARRAY(output_streams, nb_output_streams);
965 if (!(ost = av_mallocz(sizeof(*ost))))
967 output_streams[nb_output_streams - 1] = ost;
969 ost->file_index = nb_output_files - 1;
972 st->codecpar->codec_type = type;
974 ret = choose_encoder(o, oc, ost);
976 av_log(NULL, AV_LOG_FATAL, "Error selecting an encoder for stream "
977 "%d:%d\n", ost->file_index, ost->index);
981 ost->enc_ctx = avcodec_alloc_context3(ost->enc);
983 av_log(NULL, AV_LOG_ERROR, "Error allocating the encoding context.\n");
986 ost->enc_ctx->codec_type = type;
989 AVIOContext *s = NULL;
990 char *buf = NULL, *arg = NULL, *preset = NULL;
992 ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
994 MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
995 if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
998 if (!buf[0] || buf[0] == '#') {
1002 if (!(arg = strchr(buf, '='))) {
1003 av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
1007 av_dict_set(&ost->encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE);
1009 } while (!s->eof_reached);
1013 av_log(NULL, AV_LOG_FATAL,
1014 "Preset %s specified for stream %d:%d, but could not be opened.\n",
1015 preset, ost->file_index, ost->index);
1019 ost->encoder_opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
1022 ost->max_frames = INT64_MAX;
1023 MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
1025 MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st);
1026 while (bsfs && *bsfs) {
1027 const AVBitStreamFilter *filter;
1030 bsf = av_get_token(&bsfs, ",");
1034 filter = av_bsf_get_by_name(bsf);
1036 av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
1041 ost->bitstream_filters = av_realloc_array(ost->bitstream_filters,
1042 ost->nb_bitstream_filters + 1,
1043 sizeof(*ost->bitstream_filters));
1044 if (!ost->bitstream_filters)
1047 ost->bitstream_filters[ost->nb_bitstream_filters++] = filter;
1052 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
1054 uint32_t tag = strtol(codec_tag, &next, 0);
1056 tag = AV_RL32(codec_tag);
1057 ost->enc_ctx->codec_tag = tag;
1060 MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
1062 ost->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE;
1063 ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale;
1066 ost->max_muxing_queue_size = 128;
1067 MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st);
1068 ost->max_muxing_queue_size *= sizeof(AVPacket);
1070 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1071 ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1073 av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
1075 av_dict_copy(&ost->resample_opts, o->g->resample_opts, 0);
1077 ost->pix_fmts[0] = ost->pix_fmts[1] = AV_PIX_FMT_NONE;
1078 ost->last_mux_dts = AV_NOPTS_VALUE;
1080 ost->muxing_queue = av_fifo_alloc(8 * sizeof(AVPacket));
1081 if (!ost->muxing_queue)
1087 static void parse_matrix_coeffs(uint16_t *dest, const char *str)
1090 const char *p = str;
1097 av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
1104 /* read file contents into a string */
1105 static uint8_t *read_file(const char *filename)
1107 AVIOContext *pb = NULL;
1108 AVIOContext *dyn_buf = NULL;
1109 int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
1110 uint8_t buf[1024], *str;
1113 av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
1117 ret = avio_open_dyn_buf(&dyn_buf);
1122 while ((ret = avio_read(pb, buf, sizeof(buf))) > 0)
1123 avio_write(dyn_buf, buf, ret);
1124 avio_w8(dyn_buf, 0);
1127 ret = avio_close_dyn_buf(dyn_buf, &str);
1133 static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
1136 AVStream *st = ost->st;
1137 char *filter = NULL, *filter_script = NULL;
1139 MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
1140 MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
1142 if (filter_script && filter) {
1143 av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
1144 "output stream #%d:%d.\n", nb_output_files, st->index);
1149 return read_file(filter_script);
1151 return av_strdup(filter);
1153 return av_strdup(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ?
1157 static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
1161 AVCodecContext *video_enc;
1162 char *frame_aspect_ratio = NULL;
1164 ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
1166 video_enc = ost->enc_ctx;
1168 MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
1169 if (frame_aspect_ratio)
1170 ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio);
1172 if (!ost->stream_copy) {
1173 const char *p = NULL;
1174 char *frame_rate = NULL, *frame_size = NULL;
1175 char *frame_pix_fmt = NULL;
1176 char *intra_matrix = NULL, *inter_matrix = NULL;
1180 MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
1181 if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
1182 av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
1186 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
1187 if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
1188 av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
1192 MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
1193 if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
1194 av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
1197 st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
1199 MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
1201 if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
1202 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
1205 parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
1207 MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
1209 if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
1210 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
1213 parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
1216 MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
1217 for (i = 0; p; i++) {
1219 int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
1221 av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
1224 video_enc->rc_override =
1225 av_realloc(video_enc->rc_override,
1226 sizeof(RcOverride) * (i + 1));
1227 if (!video_enc->rc_override) {
1228 av_log(NULL, AV_LOG_FATAL, "Could not (re)allocate memory for rc_override.\n");
1231 video_enc->rc_override[i].start_frame = start;
1232 video_enc->rc_override[i].end_frame = end;
1234 video_enc->rc_override[i].qscale = q;
1235 video_enc->rc_override[i].quality_factor = 1.0;
1238 video_enc->rc_override[i].qscale = 0;
1239 video_enc->rc_override[i].quality_factor = -q/100.0;
1244 video_enc->rc_override_count = i;
1245 video_enc->intra_dc_precision = intra_dc_precision - 8;
1248 MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
1251 video_enc->flags |= AV_CODEC_FLAG_PASS1;
1253 video_enc->flags |= AV_CODEC_FLAG_PASS2;
1257 MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
1258 if (ost->logfile_prefix &&
1259 !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
1263 char logfilename[1024];
1266 snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
1267 ost->logfile_prefix ? ost->logfile_prefix :
1268 DEFAULT_PASS_LOGFILENAME_PREFIX,
1270 if (!strcmp(ost->enc->name, "libx264")) {
1271 av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
1273 if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
1274 f = fopen(logfilename, "wb");
1276 av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
1277 logfilename, strerror(errno));
1282 char *logbuffer = read_file(logfilename);
1285 av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
1289 video_enc->stats_in = logbuffer;
1294 MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
1295 if (ost->forced_keyframes)
1296 ost->forced_keyframes = av_strdup(ost->forced_keyframes);
1298 MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
1300 ost->top_field_first = -1;
1301 MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
1304 ost->avfilter = get_ost_filters(o, oc, ost);
1308 MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
1314 static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
1318 AVCodecContext *audio_enc;
1320 ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO);
1323 audio_enc = ost->enc_ctx;
1324 audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
1326 if (!ost->stream_copy) {
1327 char *sample_fmt = NULL;
1329 MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
1331 MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
1333 (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
1334 av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
1338 MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
1340 ost->avfilter = get_ost_filters(o, oc, ost);
1348 static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
1352 ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
1353 if (!ost->stream_copy) {
1354 av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
1361 static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc)
1363 OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
1364 ost->stream_copy = 1;
1369 static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
1372 AVCodecContext *subtitle_enc;
1374 ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE);
1375 subtitle_enc = ost->enc_ctx;
1377 subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
1382 /* arg format is "output-stream-index:streamid-value". */
1383 static int opt_streamid(void *optctx, const char *opt, const char *arg)
1385 OptionsContext *o = optctx;
1390 av_strlcpy(idx_str, arg, sizeof(idx_str));
1391 p = strchr(idx_str, ':');
1393 av_log(NULL, AV_LOG_FATAL,
1394 "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
1399 idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
1400 o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
1401 o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
1405 static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
1407 AVFormatContext *is = ifile->ctx;
1408 AVFormatContext *os = ofile->ctx;
1412 tmp = av_realloc(os->chapters, sizeof(*os->chapters) * (is->nb_chapters + os->nb_chapters));
1414 return AVERROR(ENOMEM);
1417 for (i = 0; i < is->nb_chapters; i++) {
1418 AVChapter *in_ch = is->chapters[i], *out_ch;
1419 int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
1420 int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
1421 AV_TIME_BASE_Q, in_ch->time_base);
1422 int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
1423 av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
1426 if (in_ch->end < ts_off)
1428 if (rt != INT64_MAX && in_ch->start > rt + ts_off)
1431 out_ch = av_mallocz(sizeof(AVChapter));
1433 return AVERROR(ENOMEM);
1435 out_ch->id = in_ch->id;
1436 out_ch->time_base = in_ch->time_base;
1437 out_ch->start = FFMAX(0, in_ch->start - ts_off);
1438 out_ch->end = FFMIN(rt, in_ch->end - ts_off);
1441 av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
1443 os->chapters[os->nb_chapters++] = out_ch;
1448 static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
1449 AVFormatContext *oc)
1453 switch (ofilter->type) {
1454 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1455 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1457 av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
1462 ost->source_index = -1;
1463 ost->filter = ofilter;
1466 ofilter->format = -1;
1468 if (ost->stream_copy) {
1469 av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
1470 "which is fed from a complex filtergraph. Filtering and streamcopy "
1471 "cannot be used together.\n", ost->file_index, ost->index);
1475 avfilter_inout_free(&ofilter->out_tmp);
1478 static int init_complex_filters(void)
1482 for (i = 0; i < nb_filtergraphs; i++) {
1483 ret = init_complex_filtergraph(filtergraphs[i]);
1490 static int open_output_file(OptionsContext *o, const char *filename)
1492 AVFormatContext *oc;
1494 AVOutputFormat *file_oformat;
1498 AVDictionary *unused_opts = NULL;
1499 AVDictionaryEntry *e = NULL;
1501 GROW_ARRAY(output_files, nb_output_files);
1502 of = av_mallocz(sizeof(*of));
1505 output_files[nb_output_files - 1] = of;
1507 of->ost_index = nb_output_streams;
1508 of->recording_time = o->recording_time;
1509 of->start_time = o->start_time;
1510 of->limit_filesize = o->limit_filesize;
1511 of->shortest = o->shortest;
1512 av_dict_copy(&of->opts, o->g->format_opts, 0);
1514 if (!strcmp(filename, "-"))
1517 oc = avformat_alloc_context();
1519 print_error(filename, AVERROR(ENOMEM));
1523 if (o->recording_time != INT64_MAX)
1524 oc->duration = o->recording_time;
1527 file_oformat = av_guess_format(o->format, NULL, NULL);
1528 if (!file_oformat) {
1529 av_log(NULL, AV_LOG_FATAL, "Requested output format '%s' is not a suitable output format\n", o->format);
1533 file_oformat = av_guess_format(NULL, filename, NULL);
1534 if (!file_oformat) {
1535 av_log(NULL, AV_LOG_FATAL, "Unable to find a suitable output format for '%s'\n",
1541 oc->oformat = file_oformat;
1542 oc->interrupt_callback = int_cb;
1543 av_strlcpy(oc->filename, filename, sizeof(oc->filename));
1545 /* create streams for all unlabeled output pads */
1546 for (i = 0; i < nb_filtergraphs; i++) {
1547 FilterGraph *fg = filtergraphs[i];
1548 for (j = 0; j < fg->nb_outputs; j++) {
1549 OutputFilter *ofilter = fg->outputs[j];
1551 if (!ofilter->out_tmp || ofilter->out_tmp->name)
1554 switch (ofilter->type) {
1555 case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break;
1556 case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break;
1557 case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
1559 init_output_filter(ofilter, o, oc);
1563 if (!o->nb_stream_maps) {
1564 /* pick the "best" stream of each type */
1565 #define NEW_STREAM(type, index)\
1567 ost = new_ ## type ## _stream(o, oc);\
1568 ost->source_index = index;\
1569 ost->sync_ist = input_streams[index];\
1570 input_streams[index]->discard = 0;\
1571 input_streams[index]->st->discard = AVDISCARD_NONE;\
1574 /* video: highest resolution */
1575 if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
1576 int area = 0, idx = -1;
1577 for (i = 0; i < nb_input_streams; i++) {
1578 ist = input_streams[i];
1579 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
1580 ist->st->codecpar->width * ist->st->codecpar->height > area) {
1581 area = ist->st->codecpar->width * ist->st->codecpar->height;
1585 NEW_STREAM(video, idx);
1588 /* audio: most channels */
1589 if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
1590 int channels = 0, idx = -1;
1591 for (i = 0; i < nb_input_streams; i++) {
1592 ist = input_streams[i];
1593 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
1594 ist->st->codecpar->channels > channels) {
1595 channels = ist->st->codecpar->channels;
1599 NEW_STREAM(audio, idx);
1602 /* subtitles: pick first */
1603 if (!o->subtitle_disable && oc->oformat->subtitle_codec != AV_CODEC_ID_NONE) {
1604 for (i = 0; i < nb_input_streams; i++)
1605 if (input_streams[i]->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1606 NEW_STREAM(subtitle, i);
1610 /* do something with data? */
1612 for (i = 0; i < o->nb_stream_maps; i++) {
1613 StreamMap *map = &o->stream_maps[i];
1618 if (map->linklabel) {
1620 OutputFilter *ofilter = NULL;
1623 for (j = 0; j < nb_filtergraphs; j++) {
1624 fg = filtergraphs[j];
1625 for (k = 0; k < fg->nb_outputs; k++) {
1626 AVFilterInOut *out = fg->outputs[k]->out_tmp;
1627 if (out && !strcmp(out->name, map->linklabel)) {
1628 ofilter = fg->outputs[k];
1635 av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
1636 "in any defined filter graph.\n", map->linklabel);
1639 init_output_filter(ofilter, o, oc);
1641 ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
1642 switch (ist->st->codecpar->codec_type) {
1643 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1644 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1645 case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
1646 case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break;
1647 case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
1649 av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
1650 map->file_index, map->stream_index);
1654 ost->source_index = input_files[map->file_index]->ist_index + map->stream_index;
1655 ost->sync_ist = input_streams[input_files[map->sync_file_index]->ist_index +
1656 map->sync_stream_index];
1658 ist->st->discard = AVDISCARD_NONE;
1663 /* handle attached files */
1664 for (i = 0; i < o->nb_attachments; i++) {
1666 uint8_t *attachment;
1670 if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
1671 av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
1675 if ((len = avio_size(pb)) <= 0) {
1676 av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
1680 if (!(attachment = av_malloc(len))) {
1681 av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
1685 avio_read(pb, attachment, len);
1687 ost = new_attachment_stream(o, oc);
1688 ost->stream_copy = 0;
1689 ost->source_index = -1;
1690 ost->attachment_filename = o->attachments[i];
1691 ost->st->codecpar->extradata = attachment;
1692 ost->st->codecpar->extradata_size = len;
1694 p = strrchr(o->attachments[i], '/');
1695 av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
1699 if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
1700 av_dump_format(oc, nb_output_files - 1, oc->filename, 1);
1701 av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", nb_output_files - 1);
1705 /* check if all codec options have been used */
1706 unused_opts = strip_specifiers(o->g->codec_opts);
1707 for (i = of->ost_index; i < nb_output_streams; i++) {
1709 while ((e = av_dict_get(output_streams[i]->encoder_opts, "", e,
1710 AV_DICT_IGNORE_SUFFIX)))
1711 av_dict_set(&unused_opts, e->key, NULL, 0);
1715 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
1716 const AVClass *class = avcodec_get_class();
1717 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
1718 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1721 if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
1722 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
1723 "output file #%d (%s) is not an encoding option.\n", e->key,
1724 option->help ? option->help : "", nb_output_files - 1,
1729 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
1730 "output file #%d (%s) has not been used for any stream. The most "
1731 "likely reason is either wrong type (e.g. a video option with "
1732 "no video streams) or that it is a private option of some encoder "
1733 "which was not actually used for any stream.\n", e->key,
1734 option->help ? option->help : "", nb_output_files - 1, filename);
1736 av_dict_free(&unused_opts);
1738 /* set the decoding_needed flags and create simple filtergraphs */
1739 for (i = of->ost_index; i < nb_output_streams; i++) {
1740 OutputStream *ost = output_streams[i];
1742 if (ost->encoding_needed && ost->source_index >= 0) {
1743 InputStream *ist = input_streams[ost->source_index];
1744 ist->decoding_needed = 1;
1746 if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
1747 ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
1748 err = init_simple_filtergraph(ist, ost);
1750 av_log(NULL, AV_LOG_ERROR,
1751 "Error initializing a simple filtergraph between streams "
1752 "%d:%d->%d:%d\n", ist->file_index, ost->source_index,
1753 nb_output_files - 1, ost->st->index);
1760 * We want CFR output if and only if one of those is true:
1761 * 1) user specified output framerate with -r
1762 * 2) user specified -vsync cfr
1763 * 3) output format is CFR and the user didn't force vsync to
1764 * something else than CFR
1766 * in such a case, set ost->frame_rate
1768 if (ost->encoding_needed && ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
1769 int format_cfr = !(oc->oformat->flags & (AVFMT_NOTIMESTAMPS | AVFMT_VARIABLE_FPS));
1770 int need_cfr = !!ost->frame_rate.num;
1772 if (video_sync_method == VSYNC_CFR ||
1773 (video_sync_method == VSYNC_AUTO && format_cfr))
1776 if (need_cfr && !ost->frame_rate.num) {
1777 InputStream *ist = ost->source_index >= 0 ? input_streams[ost->source_index] : NULL;
1779 if (ist && ist->framerate.num)
1780 ost->frame_rate = ist->framerate;
1781 else if (ist && ist->st->avg_frame_rate.num)
1782 ost->frame_rate = ist->st->avg_frame_rate;
1784 av_log(NULL, AV_LOG_WARNING, "Constant framerate requested "
1785 "for the output stream #%d:%d, but no information "
1786 "about the input framerate is available. Falling "
1787 "back to a default value of 25fps. Use the -r option "
1788 "if you want a different framerate.\n",
1789 ost->file_index, ost->index);
1790 ost->frame_rate = (AVRational){ 25, 1 };
1794 if (need_cfr && ost->enc->supported_framerates && !ost->force_fps) {
1795 int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
1796 ost->frame_rate = ost->enc->supported_framerates[idx];
1800 /* set the filter output constraints */
1802 OutputFilter *f = ost->filter;
1804 switch (ost->enc_ctx->codec_type) {
1805 case AVMEDIA_TYPE_VIDEO:
1806 f->frame_rate = ost->frame_rate;
1807 f->width = ost->enc_ctx->width;
1808 f->height = ost->enc_ctx->height;
1809 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
1810 f->format = ost->enc_ctx->pix_fmt;
1811 } else if (ost->enc->pix_fmts) {
1813 while (ost->enc->pix_fmts[count] != AV_PIX_FMT_NONE)
1815 f->formats = av_mallocz_array(count + 1, sizeof(*f->formats));
1818 memcpy(f->formats, ost->enc->pix_fmts, (count + 1) * sizeof(*f->formats));
1821 case AVMEDIA_TYPE_AUDIO:
1822 if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
1823 f->format = ost->enc_ctx->sample_fmt;
1824 } else if (ost->enc->sample_fmts) {
1826 while (ost->enc->sample_fmts[count] != AV_SAMPLE_FMT_NONE)
1828 f->formats = av_mallocz_array(count + 1, sizeof(*f->formats));
1831 memcpy(f->formats, ost->enc->sample_fmts, (count + 1) * sizeof(*f->formats));
1833 if (ost->enc_ctx->sample_rate) {
1834 f->sample_rate = ost->enc_ctx->sample_rate;
1835 } else if (ost->enc->supported_samplerates) {
1837 while (ost->enc->supported_samplerates[count])
1839 f->sample_rates = av_mallocz_array(count + 1, sizeof(*f->sample_rates));
1840 if (!f->sample_rates)
1842 memcpy(f->sample_rates, ost->enc->supported_samplerates,
1843 (count + 1) * sizeof(*f->sample_rates));
1845 if (ost->enc_ctx->channels) {
1846 f->channel_layout = av_get_default_channel_layout(ost->enc_ctx->channels);
1847 } else if (ost->enc->channel_layouts) {
1849 while (ost->enc->channel_layouts[count])
1851 f->channel_layouts = av_mallocz_array(count + 1, sizeof(*f->channel_layouts));
1852 if (!f->channel_layouts)
1854 memcpy(f->channel_layouts, ost->enc->channel_layouts,
1855 (count + 1) * sizeof(*f->channel_layouts));
1863 /* check filename in case of an image number is expected */
1864 if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
1865 if (!av_filename_number_test(oc->filename)) {
1866 print_error(oc->filename, AVERROR(EINVAL));
1871 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
1872 /* test if it already exists to avoid losing precious files */
1873 assert_file_overwrite(filename);
1876 if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
1877 &oc->interrupt_callback,
1879 print_error(filename, err);
1884 if (o->mux_preload) {
1886 snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
1887 av_dict_set(&of->opts, "preload", buf, 0);
1889 oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
1890 oc->flags |= AVFMT_FLAG_NONBLOCK;
1893 for (i = 0; i < o->nb_metadata_map; i++) {
1895 int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
1897 if (in_file_index >= nb_input_files) {
1898 av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
1901 copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
1902 in_file_index >= 0 ?
1903 input_files[in_file_index]->ctx : NULL, o);
1907 if (o->chapters_input_file >= nb_input_files) {
1908 if (o->chapters_input_file == INT_MAX) {
1909 /* copy chapters from the first input file that has them*/
1910 o->chapters_input_file = -1;
1911 for (i = 0; i < nb_input_files; i++)
1912 if (input_files[i]->ctx->nb_chapters) {
1913 o->chapters_input_file = i;
1917 av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
1918 o->chapters_input_file);
1922 if (o->chapters_input_file >= 0)
1923 copy_chapters(input_files[o->chapters_input_file], of,
1924 !o->metadata_chapters_manual);
1926 /* copy global metadata by default */
1927 if (!o->metadata_global_manual && nb_input_files)
1928 av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
1929 AV_DICT_DONT_OVERWRITE);
1930 if (!o->metadata_streams_manual)
1931 for (i = of->ost_index; i < nb_output_streams; i++) {
1933 if (output_streams[i]->source_index < 0) /* this is true e.g. for attached files */
1935 ist = input_streams[output_streams[i]->source_index];
1936 av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
1939 /* process manually set metadata */
1940 for (i = 0; i < o->nb_metadata; i++) {
1943 const char *stream_spec;
1944 int index = 0, j, ret;
1946 val = strchr(o->metadata[i].u.str, '=');
1948 av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
1949 o->metadata[i].u.str);
1954 parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
1956 for (j = 0; j < oc->nb_streams; j++) {
1957 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
1958 av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
1969 if (index < 0 || index >= oc->nb_chapters) {
1970 av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
1973 m = &oc->chapters[index]->metadata;
1976 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
1979 av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
1986 static int opt_target(void *optctx, const char *opt, const char *arg)
1988 OptionsContext *o = optctx;
1989 enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
1990 static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
1992 if (!strncmp(arg, "pal-", 4)) {
1995 } else if (!strncmp(arg, "ntsc-", 5)) {
1998 } else if (!strncmp(arg, "film-", 5)) {
2002 /* Try to determine PAL/NTSC by peeking in the input files */
2003 if (nb_input_files) {
2005 for (j = 0; j < nb_input_files; j++) {
2006 for (i = 0; i < input_files[j]->nb_streams; i++) {
2007 AVStream *st = input_files[j]->ctx->streams[i];
2008 if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
2010 fr = st->time_base.den * 1000 / st->time_base.num;
2014 } else if ((fr == 29970) || (fr == 23976)) {
2019 if (norm != UNKNOWN)
2023 if (norm != UNKNOWN)
2024 av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
2027 if (norm == UNKNOWN) {
2028 av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
2029 av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
2030 av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
2034 if (!strcmp(arg, "vcd")) {
2035 opt_video_codec(o, "c:v", "mpeg1video");
2036 opt_audio_codec(o, "c:a", "mp2");
2037 parse_option(o, "f", "vcd", options);
2039 parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
2040 parse_option(o, "r", frame_rates[norm], options);
2041 opt_default(NULL, "g", norm == PAL ? "15" : "18");
2043 opt_default(NULL, "b", "1150000");
2044 opt_default(NULL, "maxrate", "1150000");
2045 opt_default(NULL, "minrate", "1150000");
2046 opt_default(NULL, "bufsize", "327680"); // 40*1024*8;
2048 opt_default(NULL, "b:a", "224000");
2049 parse_option(o, "ar", "44100", options);
2050 parse_option(o, "ac", "2", options);
2052 opt_default(NULL, "packetsize", "2324");
2053 opt_default(NULL, "muxrate", "3528"); // 2352 * 75 / 50;
2055 /* We have to offset the PTS, so that it is consistent with the SCR.
2056 SCR starts at 36000, but the first two packs contain only padding
2057 and the first pack from the other stream, respectively, may also have
2058 been written before.
2059 So the real data starts at SCR 36000+3*1200. */
2060 o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
2061 } else if (!strcmp(arg, "svcd")) {
2063 opt_video_codec(o, "c:v", "mpeg2video");
2064 opt_audio_codec(o, "c:a", "mp2");
2065 parse_option(o, "f", "svcd", options);
2067 parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
2068 parse_option(o, "r", frame_rates[norm], options);
2069 opt_default(NULL, "g", norm == PAL ? "15" : "18");
2071 opt_default(NULL, "b", "2040000");
2072 opt_default(NULL, "maxrate", "2516000");
2073 opt_default(NULL, "minrate", "0"); // 1145000;
2074 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
2075 opt_default(NULL, "scan_offset", "1");
2078 opt_default(NULL, "b:a", "224000");
2079 parse_option(o, "ar", "44100", options);
2081 opt_default(NULL, "packetsize", "2324");
2083 } else if (!strcmp(arg, "dvd")) {
2085 opt_video_codec(o, "c:v", "mpeg2video");
2086 opt_audio_codec(o, "c:a", "ac3");
2087 parse_option(o, "f", "dvd", options);
2089 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
2090 parse_option(o, "r", frame_rates[norm], options);
2091 opt_default(NULL, "g", norm == PAL ? "15" : "18");
2093 opt_default(NULL, "b", "6000000");
2094 opt_default(NULL, "maxrate", "9000000");
2095 opt_default(NULL, "minrate", "0"); // 1500000;
2096 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
2098 opt_default(NULL, "packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
2099 opt_default(NULL, "muxrate", "25200"); // from mplex project: data_rate = 1260000. mux_rate = data_rate / 50
2101 opt_default(NULL, "b:a", "448000");
2102 parse_option(o, "ar", "48000", options);
2104 } else if (!strncmp(arg, "dv", 2)) {
2106 parse_option(o, "f", "dv", options);
2108 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
2109 parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
2110 norm == PAL ? "yuv420p" : "yuv411p", options);
2111 parse_option(o, "r", frame_rates[norm], options);
2113 parse_option(o, "ar", "48000", options);
2114 parse_option(o, "ac", "2", options);
2117 av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
2118 return AVERROR(EINVAL);
2121 av_dict_copy(&o->g->codec_opts, codec_opts, 0);
2122 av_dict_copy(&o->g->format_opts, format_opts, 0);
2127 static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
2129 av_free (vstats_filename);
2130 vstats_filename = av_strdup (arg);
2134 static int opt_vstats(void *optctx, const char *opt, const char *arg)
2137 time_t today2 = time(NULL);
2138 struct tm *today = localtime(&today2);
2140 if (!today) { // maybe tomorrow
2141 av_log(NULL, AV_LOG_FATAL, "Unable to get current time.\n");
2145 snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
2147 return opt_vstats_file(NULL, opt, filename);
2150 static int opt_video_frames(void *optctx, const char *opt, const char *arg)
2152 OptionsContext *o = optctx;
2153 return parse_option(o, "frames:v", arg, options);
2156 static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
2158 OptionsContext *o = optctx;
2159 return parse_option(o, "frames:a", arg, options);
2162 static int opt_data_frames(void *optctx, const char *opt, const char *arg)
2164 OptionsContext *o = optctx;
2165 return parse_option(o, "frames:d", arg, options);
2168 static int opt_video_tag(void *optctx, const char *opt, const char *arg)
2170 OptionsContext *o = optctx;
2171 return parse_option(o, "tag:v", arg, options);
2174 static int opt_audio_tag(void *optctx, const char *opt, const char *arg)
2176 OptionsContext *o = optctx;
2177 return parse_option(o, "tag:a", arg, options);
2180 static int opt_subtitle_tag(void *optctx, const char *opt, const char *arg)
2182 OptionsContext *o = optctx;
2183 return parse_option(o, "tag:s", arg, options);
2186 static int opt_video_filters(void *optctx, const char *opt, const char *arg)
2188 OptionsContext *o = optctx;
2189 return parse_option(o, "filter:v", arg, options);
2192 static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
2194 OptionsContext *o = optctx;
2195 return parse_option(o, "filter:a", arg, options);
2198 static int opt_vsync(void *optctx, const char *opt, const char *arg)
2200 if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR;
2201 else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR;
2202 else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
2204 if (video_sync_method == VSYNC_AUTO)
2205 video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
2209 static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
2211 OptionsContext *o = optctx;
2212 char layout_str[32];
2215 int ret, channels, ac_str_size;
2218 layout = av_get_channel_layout(arg);
2220 av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
2221 return AVERROR(EINVAL);
2223 snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
2224 ret = opt_default(NULL, opt, layout_str);
2228 /* set 'ac' option based on channel layout */
2229 channels = av_get_channel_layout_nb_channels(layout);
2230 snprintf(layout_str, sizeof(layout_str), "%d", channels);
2231 stream_str = strchr(opt, ':');
2232 ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
2233 ac_str = av_mallocz(ac_str_size);
2235 return AVERROR(ENOMEM);
2236 av_strlcpy(ac_str, "ac", 3);
2238 av_strlcat(ac_str, stream_str, ac_str_size);
2239 ret = parse_option(o, ac_str, layout_str, options);
2245 static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
2247 OptionsContext *o = optctx;
2248 return parse_option(o, "q:a", arg, options);
2251 static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
2253 GROW_ARRAY(filtergraphs, nb_filtergraphs);
2254 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
2255 return AVERROR(ENOMEM);
2256 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
2257 filtergraphs[nb_filtergraphs - 1]->graph_desc = av_strdup(arg);
2258 if (!filtergraphs[nb_filtergraphs - 1]->graph_desc)
2259 return AVERROR(ENOMEM);
2263 static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
2265 uint8_t *graph_desc = read_file(arg);
2267 return AVERROR(EINVAL);
2269 GROW_ARRAY(filtergraphs, nb_filtergraphs);
2270 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
2271 return AVERROR(ENOMEM);
2272 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
2273 filtergraphs[nb_filtergraphs - 1]->graph_desc = graph_desc;
2277 void show_help_default(const char *opt, const char *arg)
2279 /* per-file options have at least one of those set */
2280 const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
2281 int show_advanced = 0, show_avoptions = 0;
2284 if (!strcmp(opt, "long"))
2286 else if (!strcmp(opt, "full"))
2287 show_advanced = show_avoptions = 1;
2289 av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
2294 printf("Getting help:\n"
2295 " -h -- print basic options\n"
2296 " -h long -- print more options\n"
2297 " -h full -- print all options (including all format and codec specific options, very long)\n"
2298 " -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter\n"
2299 " See man %s for detailed description of the options.\n"
2300 "\n", program_name);
2302 show_help_options(options, "Print help / information / capabilities:",
2305 show_help_options(options, "Global options (affect whole program "
2306 "instead of just one file:",
2307 0, per_file | OPT_EXIT | OPT_EXPERT, 0);
2309 show_help_options(options, "Advanced global options:", OPT_EXPERT,
2310 per_file | OPT_EXIT, 0);
2312 show_help_options(options, "Per-file main options:", 0,
2313 OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
2314 OPT_EXIT, per_file);
2316 show_help_options(options, "Advanced per-file options:",
2317 OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
2319 show_help_options(options, "Video options:",
2320 OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
2322 show_help_options(options, "Advanced Video options:",
2323 OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
2325 show_help_options(options, "Audio options:",
2326 OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
2328 show_help_options(options, "Advanced Audio options:",
2329 OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
2330 show_help_options(options, "Subtitle options:",
2331 OPT_SUBTITLE, 0, 0);
2334 if (show_avoptions) {
2335 int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
2336 show_help_children(avcodec_get_class(), flags);
2337 show_help_children(avformat_get_class(), flags);
2338 show_help_children(sws_get_class(), flags);
2339 show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM);
2343 void show_usage(void)
2345 printf("Hyper fast Audio and Video encoder\n");
2346 printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
2355 static const OptionGroupDef groups[] = {
2356 [GROUP_OUTFILE] = { "output file", NULL, OPT_OUTPUT },
2357 [GROUP_INFILE] = { "input file", "i", OPT_INPUT },
2360 static int open_files(OptionGroupList *l, const char *inout,
2361 int (*open_file)(OptionsContext*, const char*))
2365 for (i = 0; i < l->nb_groups; i++) {
2366 OptionGroup *g = &l->groups[i];
2372 ret = parse_optgroup(&o, g);
2374 av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
2375 "%s.\n", inout, g->arg);
2379 av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
2380 ret = open_file(&o, g->arg);
2383 av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
2387 av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
2393 int avconv_parse_options(int argc, char **argv)
2395 OptionParseContext octx;
2399 memset(&octx, 0, sizeof(octx));
2401 /* split the commandline into an internal representation */
2402 ret = split_commandline(&octx, argc, argv, options, groups,
2403 FF_ARRAY_ELEMS(groups));
2405 av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
2409 /* apply global options */
2410 ret = parse_optgroup(NULL, &octx.global_opts);
2412 av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
2416 /* open input files */
2417 ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
2419 av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
2423 /* create the complex filtergraphs */
2424 ret = init_complex_filters();
2426 av_log(NULL, AV_LOG_FATAL, "Error initializing complex filters.\n");
2430 /* open output files */
2431 ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
2433 av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
2438 uninit_parse_context(&octx);
2440 av_strerror(ret, error, sizeof(error));
2441 av_log(NULL, AV_LOG_FATAL, "%s\n", error);
2446 #define OFFSET(x) offsetof(OptionsContext, x)
2447 const OptionDef options[] = {
2449 #include "cmdutils_common_opts.h"
2450 { "f", HAS_ARG | OPT_STRING | OPT_OFFSET |
2451 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(format) },
2452 "force format", "fmt" },
2453 { "y", OPT_BOOL, { &file_overwrite },
2454 "overwrite output files" },
2455 { "n", OPT_BOOL, { &file_skip },
2456 "never overwrite output files" },
2457 { "c", HAS_ARG | OPT_STRING | OPT_SPEC |
2458 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
2459 "codec name", "codec" },
2460 { "codec", HAS_ARG | OPT_STRING | OPT_SPEC |
2461 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
2462 "codec name", "codec" },
2463 { "pre", HAS_ARG | OPT_STRING | OPT_SPEC |
2464 OPT_OUTPUT, { .off = OFFSET(presets) },
2465 "preset name", "preset" },
2466 { "map", HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2467 OPT_OUTPUT, { .func_arg = opt_map },
2468 "set input stream mapping",
2469 "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
2470 { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC |
2471 OPT_OUTPUT, { .off = OFFSET(metadata_map) },
2472 "set metadata information of outfile from infile",
2473 "outfile[,metadata]:infile[,metadata]" },
2474 { "map_chapters", HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
2475 OPT_OUTPUT, { .off = OFFSET(chapters_input_file) },
2476 "set chapters mapping", "input_file_index" },
2477 { "t", HAS_ARG | OPT_TIME | OPT_OFFSET |
2478 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(recording_time) },
2479 "record or transcode \"duration\" seconds of audio/video",
2481 { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
2482 "set the limit file size in bytes", "limit_size" },
2483 { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET |
2484 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time) },
2485 "set the start time offset", "time_off" },
2486 { "accurate_seek", OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
2487 OPT_INPUT, { .off = OFFSET(accurate_seek) },
2488 "enable/disable accurate seeking with -ss" },
2489 { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET |
2490 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(input_ts_offset) },
2491 "set the input ts offset", "time_off" },
2492 { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC |
2493 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(ts_scale) },
2494 "set the input ts scale", "scale" },
2495 { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
2496 "add metadata", "string=string" },
2497 { "dframes", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2498 OPT_OUTPUT, { .func_arg = opt_data_frames },
2499 "set the number of data frames to record", "number" },
2500 { "benchmark", OPT_BOOL | OPT_EXPERT, { &do_benchmark },
2501 "add timings for benchmarking" },
2502 { "timelimit", HAS_ARG | OPT_EXPERT, { .func_arg = opt_timelimit },
2503 "set max runtime in seconds", "limit" },
2504 { "dump", OPT_BOOL | OPT_EXPERT, { &do_pkt_dump },
2505 "dump each input packet" },
2506 { "hex", OPT_BOOL | OPT_EXPERT, { &do_hex_dump },
2507 "when dumping packets, also dump the payload" },
2508 { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2509 OPT_INPUT, { .off = OFFSET(rate_emu) },
2510 "read input at native frame rate", "" },
2511 { "target", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_target },
2512 "specify target file type (\"vcd\", \"svcd\", \"dvd\","
2513 " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
2514 { "vsync", HAS_ARG | OPT_EXPERT, { opt_vsync },
2515 "video sync method", "" },
2516 { "async", HAS_ARG | OPT_INT | OPT_EXPERT, { &audio_sync_method },
2517 "audio sync method", "" },
2518 { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &audio_drift_threshold },
2519 "audio drift threshold", "threshold" },
2520 { "copyts", OPT_BOOL | OPT_EXPERT, { ©_ts },
2521 "copy timestamps" },
2522 { "copytb", OPT_BOOL | OPT_EXPERT, { ©_tb },
2523 "copy input stream time base when stream copying" },
2524 { "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2525 OPT_OUTPUT, { .off = OFFSET(shortest) },
2526 "finish encoding within shortest input" },
2527 { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &dts_delta_threshold },
2528 "timestamp discontinuity delta threshold", "threshold" },
2529 { "xerror", OPT_BOOL | OPT_EXPERT, { &exit_on_error },
2530 "exit on error", "error" },
2531 { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2532 OPT_OUTPUT, { .off = OFFSET(copy_initial_nonkeyframes) },
2533 "copy initial non-keyframes" },
2534 { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
2535 "set the number of frames to record", "number" },
2536 { "tag", OPT_STRING | HAS_ARG | OPT_SPEC |
2537 OPT_EXPERT | OPT_OUTPUT | OPT_INPUT, { .off = OFFSET(codec_tags) },
2538 "force codec tag/fourcc", "fourcc/tag" },
2539 { "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2540 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
2541 "use fixed quality scale (VBR)", "q" },
2542 { "qscale", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2543 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
2544 "use fixed quality scale (VBR)", "q" },
2545 { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
2546 "set stream filterchain", "filter_list" },
2547 { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) },
2548 "read stream filtergraph description from a file", "filename" },
2549 { "filter_complex", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex },
2550 "create a complex filtergraph", "graph_description" },
2551 { "filter_complex_script", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex_script },
2552 "read complex filtergraph description from a file", "filename" },
2553 { "stats", OPT_BOOL, { &print_stats },
2554 "print progress report during encoding", },
2555 { "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2556 OPT_OUTPUT, { .func_arg = opt_attach },
2557 "add an attachment to the output file", "filename" },
2558 { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |
2559 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(dump_attachment) },
2560 "extract an attachment into a file", "filename" },
2561 { "loop", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_INPUT |
2562 OPT_OFFSET, { .off = OFFSET(loop) }, "set number of times input stream shall be looped", "loop count" },
2565 { "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
2566 "set the number of video frames to record", "number" },
2567 { "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2568 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_rates) },
2569 "set frame rate (Hz value, fraction or abbreviation)", "rate" },
2570 { "s", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2571 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_sizes) },
2572 "set frame size (WxH or abbreviation)", "size" },
2573 { "aspect", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2574 OPT_OUTPUT, { .off = OFFSET(frame_aspect_ratios) },
2575 "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
2576 { "pix_fmt", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2577 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_pix_fmts) },
2578 "set pixel format", "format" },
2579 { "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(video_disable) },
2581 { "vdt", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &video_discard },
2582 "discard threshold", "n" },
2583 { "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2584 OPT_OUTPUT, { .off = OFFSET(rc_overrides) },
2585 "rate control override for specific intervals", "override" },
2586 { "vcodec", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_INPUT |
2587 OPT_OUTPUT, { .func_arg = opt_video_codec },
2588 "force video codec ('copy' to copy stream)", "codec" },
2589 { "pass", OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT | OPT_OUTPUT, { .off = OFFSET(pass) },
2590 "select the pass number (1 or 2)", "n" },
2591 { "passlogfile", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
2592 OPT_OUTPUT, { .off = OFFSET(passlogfiles) },
2593 "select two pass log file name prefix", "prefix" },
2594 { "vstats", OPT_VIDEO | OPT_EXPERT , { &opt_vstats },
2595 "dump video coding statistics to file" },
2596 { "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { opt_vstats_file },
2597 "dump video coding statistics to file", "file" },
2598 { "vf", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_filters },
2599 "video filters", "filter list" },
2600 { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2601 OPT_OUTPUT, { .off = OFFSET(intra_matrices) },
2602 "specify intra matrix coeffs", "matrix" },
2603 { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2604 OPT_OUTPUT, { .off = OFFSET(inter_matrices) },
2605 "specify inter matrix coeffs", "matrix" },
2606 { "top", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_INT| OPT_SPEC |
2607 OPT_OUTPUT, { .off = OFFSET(top_field_first) },
2608 "top=1/bottom=0/auto=-1 field first", "" },
2609 { "dc", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &intra_dc_precision },
2610 "intra_dc_precision", "precision" },
2611 { "vtag", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2612 OPT_OUTPUT, { .func_arg = opt_video_tag },
2613 "force video tag/fourcc", "fourcc/tag" },
2614 { "qphist", OPT_VIDEO | OPT_BOOL | OPT_EXPERT , { &qp_hist },
2615 "show QP histogram" },
2616 { "force_fps", OPT_VIDEO | OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2617 OPT_OUTPUT, { .off = OFFSET(force_fps) },
2618 "force the selected framerate, disable the best supported framerate selection" },
2619 { "streamid", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2620 OPT_OUTPUT, { .func_arg = opt_streamid },
2621 "set the value of an outfile streamid", "streamIndex:value" },
2622 { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2623 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(forced_key_frames) },
2624 "force key frames at specified timestamps", "timestamps" },
2625 { "hwaccel", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2626 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccels) },
2627 "use HW accelerated decoding", "hwaccel name" },
2628 { "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2629 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) },
2630 "select a device for HW acceleration", "devicename" },
2631 { "hwaccel_output_format", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2632 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_output_formats) },
2633 "select output format used with HW accelerated decoding", "format" },
2635 { "hwaccels", OPT_EXIT, { .func_arg = show_hwaccels },
2636 "show available HW acceleration methods" },
2637 { "autorotate", HAS_ARG | OPT_BOOL | OPT_SPEC |
2638 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(autorotate) },
2639 "automatically insert correct rotate filters" },
2640 { "hwaccel_lax_profile_check", OPT_BOOL | OPT_EXPERT, { &hwaccel_lax_profile_check},
2641 "attempt to decode anyway if HW accelerated decoder's supported profiles do not exactly match the stream" },
2644 { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
2645 "set the number of audio frames to record", "number" },
2646 { "aq", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_qscale },
2647 "set audio quality (codec-specific)", "quality", },
2648 { "ar", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2649 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_sample_rate) },
2650 "set audio sampling rate (in Hz)", "rate" },
2651 { "ac", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2652 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_channels) },
2653 "set number of audio channels", "channels" },
2654 { "an", OPT_AUDIO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(audio_disable) },
2656 { "acodec", OPT_AUDIO | HAS_ARG | OPT_PERFILE |
2657 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_audio_codec },
2658 "force audio codec ('copy' to copy stream)", "codec" },
2659 { "atag", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2660 OPT_OUTPUT, { .func_arg = opt_audio_tag },
2661 "force audio tag/fourcc", "fourcc/tag" },
2662 { "vol", OPT_AUDIO | HAS_ARG | OPT_INT, { &audio_volume },
2663 "change audio volume (256=normal)" , "volume" },
2664 { "sample_fmt", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_SPEC |
2665 OPT_STRING | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(sample_fmts) },
2666 "set sample format", "format" },
2667 { "channel_layout", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2668 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_channel_layout },
2669 "set channel layout", "layout" },
2670 { "af", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_filters },
2671 "audio filters", "filter list" },
2673 /* subtitle options */
2674 { "sn", OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(subtitle_disable) },
2675 "disable subtitle" },
2676 { "scodec", OPT_SUBTITLE | HAS_ARG | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_subtitle_codec },
2677 "force subtitle codec ('copy' to copy stream)", "codec" },
2678 { "stag", OPT_SUBTITLE | HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_subtitle_tag }
2679 , "force subtitle tag/fourcc", "fourcc/tag" },
2682 { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
2685 { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_max_delay) },
2686 "set the maximum demux-decode delay", "seconds" },
2687 { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
2688 "set the initial demux-decode delay", "seconds" },
2690 { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
2691 "A comma-separated list of bitstream filters", "bitstream_filters" },
2693 { "max_muxing_queue_size", HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(max_muxing_queue_size) },
2694 "maximum number of packets that can be buffered while waiting for all streams to initialize", "packets" },
2696 /* data codec support */
2697 { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
2698 "force data codec ('copy' to copy stream)", "codec" },
2701 { "vaapi_device", HAS_ARG | OPT_EXPERT, { .func_arg = opt_vaapi_device },
2702 "set VAAPI hardware device (DRM path or X11 display name)", "device" },