diff --git a/ffmpeg.c b/ffmpeg.c index 698fea4997..b836448606 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2968,6 +2968,37 @@ static int transcode_init(void) } } } + + if (ost->disposition) { + static const AVOption opts[] = { + { "disposition" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, + { "default" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEFAULT }, .unit = "flags" }, + { "dub" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DUB }, .unit = "flags" }, + { "original" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ORIGINAL }, .unit = "flags" }, + { "comment" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_COMMENT }, .unit = "flags" }, + { "lyrics" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_LYRICS }, .unit = "flags" }, + { "karaoke" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_KARAOKE }, .unit = "flags" }, + { "forced" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_FORCED }, .unit = "flags" }, + { "hearing_impaired" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_HEARING_IMPAIRED }, .unit = "flags" }, + { "visual_impaired" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_VISUAL_IMPAIRED }, .unit = "flags" }, + { "clean_effects" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CLEAN_EFFECTS }, .unit = "flags" }, + { "captions" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, .unit = "flags" }, + { "descriptions" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, .unit = "flags" }, + { "metadata" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, .unit = "flags" }, + { NULL }, + }; + static const AVClass class = { + .class_name = "", + .item_name = av_default_item_name, + .option = opts, + .version = LIBAVUTIL_VERSION_INT, + }; + const AVClass *pclass = &class; + + ret = av_opt_eval_flags(&pclass, &opts[0], ost->disposition, &ost->st->disposition); + if (ret < 0) + goto dump_format; + } } /* open each encoder */ @@ -3879,6 +3910,7 @@ static int transcode(void) } av_freep(&ost->forced_kf_pts); av_freep(&ost->apad); + av_freep(&ost->disposition); av_dict_free(&ost->encoder_opts); av_dict_free(&ost->swr_opts); av_dict_free(&ost->resample_opts); diff --git a/ffmpeg.h b/ffmpeg.h index 0ad1e37267..cb425b324a 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -206,6 +206,8 @@ typedef struct OptionsContext { int nb_apad; SpecifierOpt *discard; int nb_discard; + SpecifierOpt *disposition; + int nb_disposition; } OptionsContext; typedef struct InputFilter { @@ -430,6 +432,7 @@ typedef struct OutputStream { const char *attachment_filename; int copy_initial_nonkeyframes; int copy_prior_start; + char *disposition; int keep_pix_fmt; diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 9fe54fffbf..c5e38967fa 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -1186,6 +1186,9 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale; } + MATCH_PER_STREAM_OPT(disposition, str, ost->disposition, oc, st); + ost->disposition = av_strdup(ost->disposition); + if (oc->oformat->flags & AVFMT_GLOBALHEADER) ost->enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; @@ -2937,6 +2940,9 @@ const OptionDef options[] = { { "discard", OPT_STRING | HAS_ARG | OPT_SPEC | OPT_INPUT, { .off = OFFSET(discard) }, "discard", "" }, + { "disposition", OPT_STRING | HAS_ARG | OPT_SPEC | + OPT_OUTPUT, { .off = OFFSET(disposition) }, + "disposition", "" }, /* video options */ { "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },