X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=fftools%2Fffmpeg_opt.c;h=807e783422f8ff97ba33740ca61f5b4a9b8b3f8f;hb=b917218c35d240d9266c163103353e51facb0cae;hp=aa315ea08a79e72aa39fbd7ba928ffd117916a36;hpb=5d7788f9e86275dac4edd9a38bba0bda565c0dac;p=ffmpeg diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index aa315ea08a7..807e783422f 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -46,52 +46,55 @@ #define SPECIFIER_OPT_FMT_str "%s" #define SPECIFIER_OPT_FMT_i "%i" -#define SPECIFIER_OPT_FMT_i64 "%"PRId64"d" -#define SPECIFIER_OPT_FMT_ui64 "%"PRIu64"d" +#define SPECIFIER_OPT_FMT_i64 "%"PRId64 +#define SPECIFIER_OPT_FMT_ui64 "%"PRIu64 #define SPECIFIER_OPT_FMT_f "%f" #define SPECIFIER_OPT_FMT_dbl "%lf" -static const char *opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL}; -static const char *opt_name_audio_channels[] = {"ac", NULL}; -static const char *opt_name_audio_sample_rate[] = {"ar", NULL}; -static const char *opt_name_frame_rates[] = {"r", NULL}; -static const char *opt_name_frame_sizes[] = {"s", NULL}; -static const char *opt_name_frame_pix_fmts[] = {"pix_fmt", NULL}; -static const char *opt_name_ts_scale[] = {"itsscale", NULL}; -static const char *opt_name_hwaccels[] = {"hwaccel", NULL}; -static const char *opt_name_hwaccel_devices[] = {"hwaccel_device", NULL}; -static const char *opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL}; -static const char *opt_name_autorotate[] = {"autorotate", NULL}; -static const char *opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL}; -static const char *opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL}; -static const char *opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL}; -static const char *opt_name_sample_fmts[] = {"sample_fmt", NULL}; -static const char *opt_name_qscale[] = {"q", "qscale", NULL}; -static const char *opt_name_forced_key_frames[] = {"forced_key_frames", NULL}; -static const char *opt_name_force_fps[] = {"force_fps", NULL}; -static const char *opt_name_frame_aspect_ratios[] = {"aspect", NULL}; -static const char *opt_name_rc_overrides[] = {"rc_override", NULL}; -static const char *opt_name_intra_matrices[] = {"intra_matrix", NULL}; -static const char *opt_name_inter_matrices[] = {"inter_matrix", NULL}; -static const char *opt_name_chroma_intra_matrices[] = {"chroma_intra_matrix", NULL}; -static const char *opt_name_top_field_first[] = {"top", NULL}; -static const char *opt_name_presets[] = {"pre", "apre", "vpre", "spre", NULL}; -static const char *opt_name_copy_initial_nonkeyframes[] = {"copyinkfr", NULL}; -static const char *opt_name_copy_prior_start[] = {"copypriorss", NULL}; -static const char *opt_name_filters[] = {"filter", "af", "vf", NULL}; -static const char *opt_name_filter_scripts[] = {"filter_script", NULL}; -static const char *opt_name_reinit_filters[] = {"reinit_filter", NULL}; -static const char *opt_name_fix_sub_duration[] = {"fix_sub_duration", NULL}; -static const char *opt_name_canvas_sizes[] = {"canvas_size", NULL}; -static const char *opt_name_pass[] = {"pass", NULL}; -static const char *opt_name_passlogfiles[] = {"passlogfile", NULL}; -static const char *opt_name_max_muxing_queue_size[] = {"max_muxing_queue_size", NULL}; -static const char *opt_name_guess_layout_max[] = {"guess_layout_max", NULL}; -static const char *opt_name_apad[] = {"apad", NULL}; -static const char *opt_name_discard[] = {"discard", NULL}; -static const char *opt_name_disposition[] = {"disposition", NULL}; -static const char *opt_name_time_bases[] = {"time_base", NULL}; -static const char *opt_name_enc_time_bases[] = {"enc_time_base", NULL}; +static const char *const opt_name_codec_names[] = {"c", "codec", "acodec", "vcodec", "scodec", "dcodec", NULL}; +static const char *const opt_name_audio_channels[] = {"ac", NULL}; +static const char *const opt_name_audio_sample_rate[] = {"ar", NULL}; +static const char *const opt_name_frame_rates[] = {"r", NULL}; +static const char *const opt_name_max_frame_rates[] = {"fpsmax", NULL}; +static const char *const opt_name_frame_sizes[] = {"s", NULL}; +static const char *const opt_name_frame_pix_fmts[] = {"pix_fmt", NULL}; +static const char *const opt_name_ts_scale[] = {"itsscale", NULL}; +static const char *const opt_name_hwaccels[] = {"hwaccel", NULL}; +static const char *const opt_name_hwaccel_devices[] = {"hwaccel_device", NULL}; +static const char *const opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL}; +static const char *const opt_name_autorotate[] = {"autorotate", NULL}; +static const char *const opt_name_autoscale[] = {"autoscale", NULL}; +static const char *const opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL}; +static const char *const opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL}; +static const char *const opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL}; +static const char *const opt_name_sample_fmts[] = {"sample_fmt", NULL}; +static const char *const opt_name_qscale[] = {"q", "qscale", NULL}; +static const char *const opt_name_forced_key_frames[] = {"forced_key_frames", NULL}; +static const char *const opt_name_force_fps[] = {"force_fps", NULL}; +static const char *const opt_name_frame_aspect_ratios[] = {"aspect", NULL}; +static const char *const opt_name_rc_overrides[] = {"rc_override", NULL}; +static const char *const opt_name_intra_matrices[] = {"intra_matrix", NULL}; +static const char *const opt_name_inter_matrices[] = {"inter_matrix", NULL}; +static const char *const opt_name_chroma_intra_matrices[] = {"chroma_intra_matrix", NULL}; +static const char *const opt_name_top_field_first[] = {"top", NULL}; +static const char *const opt_name_presets[] = {"pre", "apre", "vpre", "spre", NULL}; +static const char *const opt_name_copy_initial_nonkeyframes[] = {"copyinkfr", NULL}; +static const char *const opt_name_copy_prior_start[] = {"copypriorss", NULL}; +static const char *const opt_name_filters[] = {"filter", "af", "vf", NULL}; +static const char *const opt_name_filter_scripts[] = {"filter_script", NULL}; +static const char *const opt_name_reinit_filters[] = {"reinit_filter", NULL}; +static const char *const opt_name_fix_sub_duration[] = {"fix_sub_duration", NULL}; +static const char *const opt_name_canvas_sizes[] = {"canvas_size", NULL}; +static const char *const opt_name_pass[] = {"pass", NULL}; +static const char *const opt_name_passlogfiles[] = {"passlogfile", NULL}; +static const char *const opt_name_max_muxing_queue_size[] = {"max_muxing_queue_size", NULL}; +static const char *const opt_name_muxing_queue_data_threshold[] = {"muxing_queue_data_threshold", NULL}; +static const char *const opt_name_guess_layout_max[] = {"guess_layout_max", NULL}; +static const char *const opt_name_apad[] = {"apad", NULL}; +static const char *const opt_name_discard[] = {"discard", NULL}; +static const char *const opt_name_disposition[] = {"disposition", NULL}; +static const char *const opt_name_time_bases[] = {"time_base", NULL}; +static const char *const opt_name_enc_time_bases[] = {"enc_time_base", NULL}; #define WARN_MULTIPLE_OPT_USAGE(name, type, so, st)\ {\ @@ -139,7 +142,6 @@ const HWAccel hwaccels[] = { #endif { 0 }, }; -AVBufferRef *hw_device_ctx; HWDevice *filter_hw_device; char *vstats_filename; @@ -172,6 +174,8 @@ float max_error_rate = 2.0/3; int filter_nbthreads = 0; int filter_complex_nbthreads = 0; int vstats_version = 2; +int auto_conversion_filters = 1; +int64_t stats_period = 500000; static int intra_only = 0; @@ -228,19 +232,17 @@ static void init_options(OptionsContext *o) o->limit_filesize = UINT64_MAX; o->chapters_input_file = INT_MAX; o->accurate_seek = 1; + o->thread_queue_size = -1; } static int show_hwaccels(void *optctx, const char *opt, const char *arg) { enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE; - int i; printf("Hardware acceleration methods:\n"); while ((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE) printf("%s\n", av_hwdevice_get_type_name(type)); - for (i = 0; hwaccels[i].name; i++) - printf("%s\n", hwaccels[i].name); printf("\n"); return 0; } @@ -266,8 +268,9 @@ static AVDictionary *strip_specifiers(AVDictionary *dict) static int opt_abort_on(void *optctx, const char *opt, const char *arg) { static const AVOption opts[] = { - { "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, - { "empty_output" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT }, .unit = "flags" }, + { "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, + { "empty_output" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT }, .unit = "flags" }, + { "empty_output_stream", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM }, .unit = "flags" }, { NULL }, }; static const AVClass class = { @@ -281,6 +284,21 @@ static int opt_abort_on(void *optctx, const char *opt, const char *arg) return av_opt_eval_flags(&pclass, &opts[0], arg, &abort_on_flags); } +static int opt_stats_period(void *optctx, const char *opt, const char *arg) +{ + int64_t user_stats_period = parse_time_or_die(opt, arg, 1); + + if (user_stats_period <= 0) { + av_log(NULL, AV_LOG_ERROR, "stats_period %s must be positive.\n", arg); + return AVERROR(EINVAL); + } + + stats_period = user_stats_period; + av_log(NULL, AV_LOG_INFO, "ffmpeg stats and -progress period set to %s.\n", arg); + + return 0; +} + static int opt_sameq(void *optctx, const char *opt, const char *arg) { av_log(NULL, AV_LOG_ERROR, "Option '%s' was removed. " @@ -539,21 +557,15 @@ static int opt_sdp_file(void *optctx, const char *opt, const char *arg) #if CONFIG_VAAPI static int opt_vaapi_device(void *optctx, const char *opt, const char *arg) { - HWDevice *dev; const char *prefix = "vaapi:"; char *tmp; int err; tmp = av_asprintf("%s%s", prefix, arg); if (!tmp) return AVERROR(ENOMEM); - err = hw_device_init_from_string(tmp, &dev); + err = hw_device_init_from_string(tmp, NULL); av_free(tmp); - if (err < 0) - return err; - hw_device_ctx = av_buffer_ref(dev->device_ref); - if (!hw_device_ctx) - return AVERROR(ENOMEM); - return 0; + return err; } #endif @@ -754,13 +766,13 @@ static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int e return codec; } -static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st) +static const AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st) { char *codec_name = NULL; MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st); if (codec_name) { - AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0); + const AVCodec *codec = find_codec_or_die(codec_name, st->codecpar->codec_type, 0); st->codecpar->codec_id = codec->id; return codec; } else @@ -856,15 +868,6 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) case AVMEDIA_TYPE_VIDEO: if(!ist->dec) ist->dec = avcodec_find_decoder(par->codec_id); -#if FF_API_LOWRES - if (st->codec->lowres) { - ist->dec_ctx->lowres = st->codec->lowres; - ist->dec_ctx->width = st->codec->width; - ist->dec_ctx->height = st->codec->height; - ist->dec_ctx->coded_width = st->codec->coded_width; - ist->dec_ctx->coded_height = st->codec->coded_height; - } -#endif // avformat_find_stream_info() doesn't set this for us anymore. ist->dec_ctx->framerate = st->avg_frame_rate; @@ -936,8 +939,6 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) AV_HWDEVICE_TYPE_NONE) av_log(NULL, AV_LOG_FATAL, "%s ", av_hwdevice_get_type_name(type)); - for (i = 0; hwaccels[i].name; i++) - av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name); av_log(NULL, AV_LOG_FATAL, "\n"); exit_program(1); } @@ -1279,8 +1280,11 @@ static int open_input_file(OptionsContext *o, const char *filename) f->loop = o->loop; f->duration = 0; f->time_base = (AVRational){ 1, 1 }; + f->pkt = av_packet_alloc(); + if (!f->pkt) + exit_program(1); #if HAVE_THREADS - f->thread_queue_size = o->thread_queue_size > 0 ? o->thread_queue_size : 8; + f->thread_queue_size = o->thread_queue_size; #endif /* check if all codec options have been used */ @@ -1473,6 +1477,8 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc); MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); + ost->autoscale = 1; + MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st); if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) { do { buf = get_line(s); @@ -1540,54 +1546,12 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st); MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st); - while (bsfs && *bsfs) { - const AVBitStreamFilter *filter; - char *bsf, *bsf_options_str, *bsf_name; - - bsf = av_get_token(&bsfs, ","); - if (!bsf) - exit_program(1); - bsf_name = av_strtok(bsf, "=", &bsf_options_str); - if (!bsf_name) - exit_program(1); - - filter = av_bsf_get_by_name(bsf_name); - if (!filter) { - av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf_name); - exit_program(1); - } - - ost->bsf_ctx = av_realloc_array(ost->bsf_ctx, - ost->nb_bitstream_filters + 1, - sizeof(*ost->bsf_ctx)); - if (!ost->bsf_ctx) - exit_program(1); - - ret = av_bsf_alloc(filter, &ost->bsf_ctx[ost->nb_bitstream_filters]); + if (bsfs && *bsfs) { + ret = av_bsf_list_parse_str(bsfs, &ost->bsf_ctx); if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n"); + av_log(NULL, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret)); exit_program(1); } - - ost->nb_bitstream_filters++; - - if (bsf_options_str && filter->priv_class) { - const AVOption *opt = av_opt_next(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, NULL); - const char * shorthand[2] = {NULL}; - - if (opt) - shorthand[0] = opt->name; - - ret = av_opt_set_from_string(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, bsf_options_str, shorthand, "=", ":"); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error parsing options for bitstream filter %s\n", bsf_name); - exit_program(1); - } - } - av_freep(&bsf); - - if (*bsfs) - bsfs++; } MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st); @@ -1610,7 +1574,12 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->max_muxing_queue_size = 128; MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ost->max_muxing_queue_size, oc, st); - ost->max_muxing_queue_size *= sizeof(AVPacket); + ost->max_muxing_queue_size *= sizeof(ost->pkt); + + ost->muxing_queue_data_size = 0; + + ost->muxing_queue_data_threshold = 50*1024*1024; + MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, ost->muxing_queue_data_threshold, oc, st); if (oc->oformat->flags & AVFMT_GLOBALHEADER) ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; @@ -1723,7 +1692,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in AVStream *st; OutputStream *ost; AVCodecContext *video_enc; - char *frame_rate = NULL, *frame_aspect_ratio = NULL; + char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL; ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index); st = ost->st; @@ -1734,8 +1703,21 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate); exit_program(1); } - if (frame_rate && video_sync_method == VSYNC_PASSTHROUGH) - av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r can produce invalid output files\n"); + + MATCH_PER_STREAM_OPT(max_frame_rates, str, max_frame_rate, oc, st); + if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, max_frame_rate) < 0) { + av_log(NULL, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate); + exit_program(1); + } + + if (frame_rate && max_frame_rate) { + av_log(NULL, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n"); + exit_program(1); + } + + if ((frame_rate || max_frame_rate) && + video_sync_method == VSYNC_PASSTHROUGH) + av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r/-fpsmax can produce invalid output files\n"); MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st); if (frame_aspect_ratio) { @@ -1750,8 +1732,6 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st); MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st); - if (o->nb_filters > 1) - av_log(NULL, AV_LOG_ERROR, "Only '-vf %s' read, ignoring remaining -vf options: Use ',' to separate filters\n", ost->filters); if (!ost->stream_copy) { const char *p = NULL; @@ -1933,8 +1913,6 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, in MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st); MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st); - if (o->nb_filters > 1) - av_log(NULL, AV_LOG_ERROR, "Only '-af %s' read, ignoring remaining -af options: Use ',' to separate filters\n", ost->filters); if (!ost->stream_copy) { char *sample_fmt = NULL; @@ -2262,22 +2240,23 @@ static int open_output_file(OptionsContext *o, const char *filename) /* video: highest resolution */ if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) { - int area = 0, idx = -1; + int best_score = 0, idx = -1; int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0); for (i = 0; i < nb_input_streams; i++) { - int new_area; + int score; ist = input_streams[i]; - new_area = ist->st->codecpar->width * ist->st->codecpar->height + 100000000*!!ist->st->codec_info_nb_frames + score = ist->st->codecpar->width * ist->st->codecpar->height + + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS) + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT); if (ist->user_set_discard == AVDISCARD_ALL) continue; if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) - new_area = 1; + score = 1; if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && - new_area > area) { + score > best_score) { if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) continue; - area = new_area; + best_score = score; idx = i; } } @@ -2441,12 +2420,14 @@ loop_end: o->attachments[i]); exit_program(1); } - if (!(attachment = av_malloc(len))) { - av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n", + if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE || + !(attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) { + av_log(NULL, AV_LOG_FATAL, "Attachment %s too large.\n", o->attachments[i]); exit_program(1); } avio_read(pb, attachment, len); + memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE); ost = new_attachment_stream(o, oc, -1); ost->stream_copy = 0; @@ -2677,6 +2658,9 @@ loop_end: if(o->recording_time != INT64_MAX) av_dict_set(&oc->metadata, "duration", NULL, 0); av_dict_set(&oc->metadata, "creation_time", NULL, 0); + av_dict_set(&oc->metadata, "company_name", NULL, 0); + av_dict_set(&oc->metadata, "product_name", NULL, 0); + av_dict_set(&oc->metadata, "product_version", NULL, 0); } if (!o->metadata_streams_manual) for (i = of->ost_index; i < nb_output_streams; i++) { @@ -3596,8 +3580,12 @@ const OptionDef options[] = { "create a complex filtergraph", "graph_description" }, { "filter_complex_script", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex_script }, "read complex filtergraph description from a file", "filename" }, + { "auto_conversion_filters", OPT_BOOL | OPT_EXPERT, { &auto_conversion_filters }, + "enable automatic conversion filters globally" }, { "stats", OPT_BOOL, { &print_stats }, "print progress report during encoding", }, + { "stats_period", HAS_ARG | OPT_EXPERT, { .func_arg = opt_stats_period }, + "set the period at which ffmpeg updates stats and -progress output", "time" }, { "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT | OPT_OUTPUT, { .func_arg = opt_attach }, "add an attachment to the output file", "filename" }, @@ -3609,7 +3597,7 @@ const OptionDef options[] = { { "debug_ts", OPT_BOOL | OPT_EXPERT, { &debug_ts }, "print timestamp debugging info" }, { "max_error_rate", HAS_ARG | OPT_FLOAT, { &max_error_rate }, - "ratio of errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success.", "maximum error rate" }, + "ratio of decoding errors (0.0: no errors, 1.0: 100% errors) above which ffmpeg returns an error instead of success.", "maximum error rate" }, { "discard", OPT_STRING | HAS_ARG | OPT_SPEC | OPT_INPUT, { .off = OFFSET(discard) }, "discard", "" }, @@ -3628,6 +3616,9 @@ const OptionDef options[] = { { "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_rates) }, "set frame rate (Hz value, fraction or abbreviation)", "rate" }, + { "fpsmax", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC | + OPT_OUTPUT, { .off = OFFSET(max_frame_rates) }, + "set max frame rate (Hz value, fraction or abbreviation)", "rate" }, { "s", OPT_VIDEO | HAS_ARG | OPT_SUBTITLE | OPT_STRING | OPT_SPEC | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_sizes) }, "set frame size (WxH or abbreviation)", "size" }, @@ -3719,6 +3710,9 @@ const OptionDef options[] = { { "autorotate", HAS_ARG | OPT_BOOL | OPT_SPEC | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(autorotate) }, "automatically insert correct rotate filters" }, + { "autoscale", HAS_ARG | OPT_BOOL | OPT_SPEC | + OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(autoscale) }, + "automatically insert a scale filter at the end of the filter graph" }, /* audio options */ { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames }, @@ -3805,6 +3799,8 @@ const OptionDef options[] = { { "max_muxing_queue_size", HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(max_muxing_queue_size) }, "maximum number of packets that can be buffered while waiting for all streams to initialize", "packets" }, + { "muxing_queue_data_threshold", HAS_ARG | OPT_INT | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(muxing_queue_data_threshold) }, + "set the threshold after which max_muxing_queue_size is taken into account", "bytes" }, /* data codec support */ { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },