diff options
author | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2024-03-19 21:40:54 +0100 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2024-03-22 23:57:19 +0100 |
commit | f4167842c12ad0e406a2bed4c2bb17084b184710 (patch) | |
tree | c7230409284fe0232e5f9cee586edfc0763f599c /libavformat/mux.c | |
parent | c6bc2d4fea99bfc0ad125897f61d205d78d0a8c1 (diff) | |
download | ffmpeg-f4167842c12ad0e406a2bed4c2bb17084b184710.tar.gz |
avformat/mux: Add flag for "not more than one stream of each type"
More exactly: Not more than one stream of each type for which
a default codec (i.e. AVOutputFormat.(audio|video|subtitle)_codec)
is set; for those types for which no such codec is set (or for
which no designated default codec in AVOutputFormat exists at all)
no streams are permitted.
Given that with this flag set the default codecs become more important,
they are now set explicitly to AV_CODEC_ID_NONE for "unset";
the earlier code relied on AV_CODEC_ID_NONE being equal to zero,
so that default static initialization set it accordingly;
but this is not how one is supposed to use an enum.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavformat/mux.c')
-rw-r--r-- | libavformat/mux.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/libavformat/mux.c b/libavformat/mux.c index a2cae97397..134c2875b6 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -188,6 +188,12 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) AVDictionary *tmp = NULL; const FFOutputFormat *of = ffofmt(s->oformat); AVDictionaryEntry *e; + static const unsigned default_codec_offsets[] = { + [AVMEDIA_TYPE_VIDEO] = offsetof(AVOutputFormat, video_codec), + [AVMEDIA_TYPE_AUDIO] = offsetof(AVOutputFormat, audio_codec), + [AVMEDIA_TYPE_SUBTITLE] = offsetof(AVOutputFormat, subtitle_codec), + }; + unsigned nb_type[FF_ARRAY_ELEMS(default_codec_offsets)] = { 0 }; int ret = 0; if (options) @@ -262,6 +268,23 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) } break; } + if (of->flags_internal & FF_OFMT_FLAG_MAX_ONE_OF_EACH) { + enum AVCodecID default_codec_id = AV_CODEC_ID_NONE; + unsigned nb; + if ((unsigned)par->codec_type < FF_ARRAY_ELEMS(default_codec_offsets)) { + nb = ++nb_type[par->codec_type]; + if (default_codec_offsets[par->codec_type]) + default_codec_id = *(const enum AVCodecID*)((const char*)of + default_codec_offsets[par->codec_type]); + } + if (default_codec_id == AV_CODEC_ID_NONE || nb > 1) { + const char *type = av_get_media_type_string(par->codec_type); + av_log(s, AV_LOG_ERROR, "%s muxer does not support %s stream of type %s\n", + of->p.name, default_codec_id == AV_CODEC_ID_NONE ? "any" : "more than one", + type ? type : "unknown"); + ret = AVERROR(EINVAL); + goto fail; + } + } #if FF_API_AVSTREAM_SIDE_DATA FF_DISABLE_DEPRECATION_WARNINGS |