diff options
author | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2022-05-06 15:23:34 +0200 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2022-05-10 07:28:54 +0200 |
commit | b9f6d416ecbed36fbe1b819d1099f71ba2936ddd (patch) | |
tree | e59b719db78da0b35b89bf9d61f9b95a0b38c1f3 /libavformat/options.c | |
parent | 7547f135485623e00844d2ad40debb5b048e6b5d (diff) |
avformat/utils: Move stream_options, avformat_new_stream to options.c
This is the appropriate place given that AVStream is about to
become an AVOpt-enabled struct.
Also move av_disposition_(to|from)_string, as these are tied
to the disposition stream option.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavformat/options.c')
-rw-r--r-- | libavformat/options.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/libavformat/options.c b/libavformat/options.c index 2d55d3ad6e..14ae55e3fd 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -21,8 +21,12 @@ #include "avio_internal.h" #include "internal.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/codec_par.h" + #include "libavutil/avassert.h" #include "libavutil/internal.h" +#include "libavutil/intmath.h" #include "libavutil/opt.h" /** @@ -188,3 +192,150 @@ const AVClass *avformat_get_class(void) { return &av_format_context_class; } + +static const AVOption stream_options[] = { + { "disposition", NULL, offsetof(AVStream, disposition), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, + .flags = AV_OPT_FLAG_ENCODING_PARAM, .unit = "disposition" }, + { "default", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEFAULT }, .unit = "disposition" }, + { "dub", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DUB }, .unit = "disposition" }, + { "original", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ORIGINAL }, .unit = "disposition" }, + { "comment", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_COMMENT }, .unit = "disposition" }, + { "lyrics", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_LYRICS }, .unit = "disposition" }, + { "karaoke", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_KARAOKE }, .unit = "disposition" }, + { "forced", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_FORCED }, .unit = "disposition" }, + { "hearing_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_HEARING_IMPAIRED }, .unit = "disposition" }, + { "visual_impaired", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_VISUAL_IMPAIRED }, .unit = "disposition" }, + { "clean_effects", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CLEAN_EFFECTS }, .unit = "disposition" }, + { "attached_pic", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_ATTACHED_PIC }, .unit = "disposition" }, + { "timed_thumbnails", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_TIMED_THUMBNAILS }, .unit = "disposition" }, + { "captions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_CAPTIONS }, .unit = "disposition" }, + { "descriptions", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DESCRIPTIONS }, .unit = "disposition" }, + { "metadata", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_METADATA }, .unit = "disposition" }, + { "dependent", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_DEPENDENT }, .unit = "disposition" }, + { "still_image", .type = AV_OPT_TYPE_CONST, { .i64 = AV_DISPOSITION_STILL_IMAGE }, .unit = "disposition" }, + { NULL } +}; + +static const AVClass stream_class = { + .class_name = "AVStream", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, + .option = stream_options, +}; + +const AVClass *av_stream_get_class(void) +{ + return &stream_class; +} + +AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) +{ + FFFormatContext *const si = ffformatcontext(s); + FFStream *sti; + AVStream *st; + AVStream **streams; + + if (s->nb_streams >= s->max_streams) { + av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter" + " (%d), see the documentation if you wish to increase it\n", + s->max_streams); + return NULL; + } + streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams)); + if (!streams) + return NULL; + s->streams = streams; + + sti = av_mallocz(sizeof(*sti)); + if (!sti) + return NULL; + st = &sti->pub; + +#if FF_API_AVSTREAM_CLASS + st->av_class = &stream_class; +#endif + + st->codecpar = avcodec_parameters_alloc(); + if (!st->codecpar) + goto fail; + + sti->avctx = avcodec_alloc_context3(NULL); + if (!sti->avctx) + goto fail; + + if (s->iformat) { + sti->info = av_mallocz(sizeof(*sti->info)); + if (!sti->info) + goto fail; + +#if FF_API_R_FRAME_RATE + sti->info->last_dts = AV_NOPTS_VALUE; +#endif + sti->info->fps_first_dts = AV_NOPTS_VALUE; + sti->info->fps_last_dts = AV_NOPTS_VALUE; + + /* default pts setting is MPEG-like */ + avpriv_set_pts_info(st, 33, 1, 90000); + /* we set the current DTS to 0 so that formats without any timestamps + * but durations get some timestamps, formats with some unknown + * timestamps have their first few packets buffered and the + * timestamps corrected before they are returned to the user */ + sti->cur_dts = RELATIVE_TS_BASE; + } else { + sti->cur_dts = AV_NOPTS_VALUE; + } + + st->index = s->nb_streams; + st->start_time = AV_NOPTS_VALUE; + st->duration = AV_NOPTS_VALUE; + sti->first_dts = AV_NOPTS_VALUE; + sti->probe_packets = s->max_probe_packets; + sti->pts_wrap_reference = AV_NOPTS_VALUE; + sti->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; + + sti->last_IP_pts = AV_NOPTS_VALUE; + sti->last_dts_for_order_check = AV_NOPTS_VALUE; + for (int i = 0; i < MAX_REORDER_DELAY + 1; i++) + sti->pts_buffer[i] = AV_NOPTS_VALUE; + + st->sample_aspect_ratio = (AVRational) { 0, 1 }; + + sti->inject_global_side_data = si->inject_global_side_data; + + sti->need_context_update = 1; + + s->streams[s->nb_streams++] = st; + return st; +fail: + ff_free_stream(&st); + return NULL; +} + +static int option_is_disposition(const AVOption *opt) +{ + return opt->type == AV_OPT_TYPE_CONST && + opt->unit && !strcmp(opt->unit, "disposition"); +} + +int av_disposition_from_string(const char *disp) +{ + for (const AVOption *opt = stream_options; opt->name; opt++) + if (option_is_disposition(opt) && !strcmp(disp, opt->name)) + return opt->default_val.i64; + return AVERROR(EINVAL); +} + +const char *av_disposition_to_string(int disposition) +{ + int val; + + if (disposition <= 0) + return NULL; + + val = 1 << ff_ctz(disposition); + for (const AVOption *opt = stream_options; opt->name; opt++) + if (option_is_disposition(opt) && opt->default_val.i64 == val) + return opt->name; + + return NULL; +} |