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>
This commit is contained in:
Andreas Rheinhardt 2024-03-19 21:40:54 +01:00
parent c6bc2d4fea
commit f4167842c1
38 changed files with 239 additions and 237 deletions

View File

@ -35,7 +35,7 @@ static int ac4_init(AVFormatContext *s)
{
AVCodecParameters *par = s->streams[0]->codecpar;
if (s->nb_streams != 1 || par->codec_id != AV_CODEC_ID_AC4) {
if (par->codec_id != AV_CODEC_ID_AC4) {
av_log(s, AV_LOG_ERROR, "Only one AC-4 stream can be muxed by the AC-4 muxer\n");
return AVERROR(EINVAL);
}
@ -95,6 +95,8 @@ const FFOutputFormat ff_ac4_muxer = {
.priv_data_size = sizeof(AC4Context),
.p.audio_codec = AV_CODEC_ID_AC4,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.init = ac4_init,
.write_packet = ac4_write_packet,
.p.priv_class = &ac4_muxer_class,

View File

@ -29,14 +29,8 @@ static int aea_write_header(AVFormatContext *s)
{
const AVDictionaryEntry *title_entry;
size_t title_length = 0;
AVStream *st;
AVStream *st = s->streams[0];
if (s->nb_streams > 1) {
av_log(s, AV_LOG_ERROR, "Got more than one stream to encode. This is not supported.\n");
return AVERROR(EINVAL);
}
st = s->streams[0];
if (st->codecpar->ch_layout.nb_channels != 1 && st->codecpar->ch_layout.nb_channels != 2) {
av_log(s, AV_LOG_ERROR, "Only maximum 2 channels are supported in the audio"
" stream, %d channels were found.\n", st->codecpar->ch_layout.nb_channels);
@ -108,7 +102,10 @@ const FFOutputFormat ff_aea_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("MD STUDIO audio"),
.p.extensions = "aea",
.p.audio_codec = AV_CODEC_ID_ATRAC1,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = aea_write_header,
.write_packet = ff_raw_write_packet,
.write_trailer = aea_write_trailer,

View File

@ -189,11 +189,6 @@ static int alp_write_init(AVFormatContext *s)
alp->type = ALP_TYPE_TUN;
}
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "Too many streams\n");
return AVERROR(EINVAL);
}
par = s->streams[0]->codecpar;
if (par->codec_id != AV_CODEC_ID_ADPCM_IMA_ALP) {
@ -298,7 +293,9 @@ const FFOutputFormat ff_alp_muxer = {
.p.extensions = "tun,pcm",
.p.audio_codec = AV_CODEC_ID_ADPCM_IMA_ALP,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.p.priv_class = &alp_muxer_class,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.init = alp_write_init,
.write_header = alp_write_header,
.write_packet = ff_raw_write_packet,

View File

@ -215,14 +215,7 @@ const FFInputFormat ff_apm_demuxer = {
#if CONFIG_APM_MUXER
static int apm_write_init(AVFormatContext *s)
{
AVCodecParameters *par;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "APM files have exactly one stream\n");
return AVERROR(EINVAL);
}
par = s->streams[0]->codecpar;
AVCodecParameters *par = s->streams[0]->codecpar;
if (par->codec_id != AV_CODEC_ID_ADPCM_IMA_APM) {
av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
@ -311,6 +304,8 @@ const FFOutputFormat ff_apm_muxer = {
.p.extensions = "apm",
.p.audio_codec = AV_CODEC_ID_ADPCM_IMA_APM,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.init = apm_write_init,
.write_header = apm_write_header,
.write_packet = ff_raw_write_packet,

View File

@ -84,9 +84,7 @@ static int apng_write_header(AVFormatContext *format_context)
APNGMuxContext *apng = format_context->priv_data;
AVCodecParameters *par = format_context->streams[0]->codecpar;
if (format_context->nb_streams != 1 ||
format_context->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ||
format_context->streams[0]->codecpar->codec_id != AV_CODEC_ID_APNG) {
if (format_context->streams[0]->codecpar->codec_id != AV_CODEC_ID_APNG) {
av_log(format_context, AV_LOG_ERROR,
"APNG muxer supports only a single video APNG stream.\n");
return AVERROR(EINVAL);
@ -315,6 +313,8 @@ const FFOutputFormat ff_apng_muxer = {
.priv_data_size = sizeof(APNGMuxContext),
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_APNG,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = apng_write_header,
.write_packet = apng_write_packet,
.write_trailer = apng_write_trailer,

View File

@ -288,14 +288,7 @@ const FFInputFormat ff_argo_asf_demuxer = {
static int argo_asf_write_init(AVFormatContext *s)
{
ArgoASFMuxContext *ctx = s->priv_data;
const AVCodecParameters *par;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "ASF files have exactly one stream\n");
return AVERROR(EINVAL);
}
par = s->streams[0]->codecpar;
const AVCodecParameters *par = s->streams[0]->codecpar;
if (par->codec_id != AV_CODEC_ID_ADPCM_ARGO) {
av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
@ -481,7 +474,9 @@ const FFOutputFormat ff_argo_asf_muxer = {
*/
.p.audio_codec = AV_CODEC_ID_ADPCM_ARGO,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.p.priv_class = &argo_asf_muxer_class,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.init = argo_asf_write_init,
.write_header = argo_asf_write_header,
.write_packet = argo_asf_write_packet,

View File

@ -269,14 +269,7 @@ const FFInputFormat ff_argo_cvg_demuxer = {
static int argo_cvg_write_init(AVFormatContext *s)
{
ArgoCVGMuxContext *ctx = s->priv_data;
const AVCodecParameters *par;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "CVG files have exactly one stream\n");
return AVERROR(EINVAL);
}
par = s->streams[0]->codecpar;
const AVCodecParameters *par = s->streams[0]->codecpar;
if (par->codec_id != AV_CODEC_ID_ADPCM_PSX) {
av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
@ -408,7 +401,9 @@ const FFOutputFormat ff_argo_cvg_muxer = {
.p.extensions = "cvg",
.p.audio_codec = AV_CODEC_ID_ADPCM_PSX,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.p.priv_class = &argo_cvg_muxer_class,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.init = argo_cvg_write_init,
.write_header = argo_cvg_write_header,
.write_packet = argo_cvg_write_packet,

View File

@ -50,7 +50,7 @@ static int write_header(AVFormatContext *s)
ASSContext *ass = s->priv_data;
AVCodecParameters *par = s->streams[0]->codecpar;
if (s->nb_streams != 1 || par->codec_id != AV_CODEC_ID_ASS) {
if (par->codec_id != AV_CODEC_ID_ASS) {
av_log(s, AV_LOG_ERROR, "Exactly one ASS/SSA stream is needed.\n");
return AVERROR(EINVAL);
}
@ -237,8 +237,11 @@ const FFOutputFormat ff_ass_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"),
.p.mime_type = "text/x-ass",
.p.extensions = "ass,ssa",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_ASS,
.p.flags = AVFMT_GLOBALHEADER | AVFMT_NOTIMESTAMPS | AVFMT_TS_NONSTRICT,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.p.priv_class = &ass_class,
.priv_data_size = sizeof(ASSContext),
.write_header = write_header,

View File

@ -49,16 +49,9 @@ static int ast_write_header(AVFormatContext *s)
{
ASTMuxContext *ast = s->priv_data;
AVIOContext *pb = s->pb;
AVCodecParameters *par;
AVCodecParameters *par = s->streams[0]->codecpar;
unsigned int codec_tag;
if (s->nb_streams == 1) {
par = s->streams[0]->codecpar;
} else {
av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
return AVERROR(EINVAL);
}
if (par->codec_id == AV_CODEC_ID_ADPCM_AFC) {
av_log(s, AV_LOG_ERROR, "muxing ADPCM AFC is not implemented\n");
return AVERROR_PATCHWELCOME;
@ -204,6 +197,8 @@ const FFOutputFormat ff_ast_muxer = {
.priv_data_size = sizeof(ASTMuxContext),
.p.audio_codec = AV_CODEC_ID_PCM_S16BE_PLANAR,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = ast_write_header,
.write_packet = ast_write_packet,
.write_trailer = ast_write_trailer,

View File

@ -291,11 +291,6 @@ static int au_write_header(AVFormatContext *s)
AVCodecParameters *par = s->streams[0]->codecpar;
AVBPrint annotations;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
return AVERROR(EINVAL);
}
par->codec_tag = ff_codec_get_tag(codec_au_tags, par->codec_id);
if (!par->codec_tag) {
av_log(s, AV_LOG_ERROR, "unsupported codec\n");
@ -346,7 +341,9 @@ const FFOutputFormat ff_au_muxer = {
.p.codec_tag = au_codec_tags,
.p.audio_codec = AV_CODEC_ID_PCM_S16BE,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.p.flags = AVFMT_NOTIMESTAMPS,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.priv_data_size = sizeof(AUContext),
.write_header = au_write_header,
.write_packet = ff_raw_write_packet,

View File

@ -118,11 +118,6 @@ static int caf_write_header(AVFormatContext *s)
int64_t chunk_size = 0;
int frame_size = par->frame_size, sample_rate = par->sample_rate;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "CAF files have exactly one stream\n");
return AVERROR(EINVAL);
}
switch (par->codec_id) {
case AV_CODEC_ID_AAC:
av_log(s, AV_LOG_ERROR, "muxing codec currently unsupported\n");
@ -284,6 +279,8 @@ const FFOutputFormat ff_caf_muxer = {
.priv_data_size = sizeof(CAFContext),
.p.audio_codec = AV_CODEC_ID_PCM_S16BE,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = caf_write_header,
.write_packet = caf_write_packet,
.write_trailer = caf_write_trailer,

View File

@ -85,11 +85,6 @@ static int write_header(AVFormatContext *s)
#endif
}
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "Only one stream is supported\n");
return AVERROR(EINVAL);
}
st = s->streams[0];
if (st->codecpar->ch_layout.nb_channels > 2) {
@ -182,6 +177,9 @@ const FFOutputFormat ff_chromaprint_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("Chromaprint"),
.priv_data_size = sizeof(ChromaprintMuxContext),
.p.audio_codec = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE),
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = write_header,
.write_packet = write_packet,
.write_trailer = write_trailer,

View File

@ -216,7 +216,7 @@ static int codec2_write_header(AVFormatContext *s)
{
AVStream *st;
if (s->nb_streams != 1 || s->streams[0]->codecpar->codec_id != AV_CODEC_ID_CODEC2) {
if (s->streams[0]->codecpar->codec_id != AV_CODEC_ID_CODEC2) {
av_log(s, AV_LOG_ERROR, ".c2 files must have exactly one codec2 stream\n");
return AVERROR(EINVAL);
}
@ -317,7 +317,9 @@ const FFOutputFormat ff_codec2_muxer = {
.p.extensions = "c2",
.p.audio_codec = AV_CODEC_ID_CODEC2,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.p.flags = AVFMT_NOTIMESTAMPS,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = codec2_write_header,
.write_packet = ff_raw_write_packet,
};

View File

@ -42,9 +42,7 @@ typedef struct GIFContext {
static int gif_write_header(AVFormatContext *s)
{
if (s->nb_streams != 1 ||
s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ||
s->streams[0]->codecpar->codec_id != AV_CODEC_ID_GIF) {
if (s->streams[0]->codecpar->codec_id != AV_CODEC_ID_GIF) {
av_log(s, AV_LOG_ERROR,
"GIF muxer supports only a single video GIF stream.\n");
return AVERROR(EINVAL);
@ -213,6 +211,8 @@ const FFOutputFormat ff_gif_muxer = {
.priv_data_size = sizeof(GIFContext),
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_GIF,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = gif_write_header,
.write_packet = gif_write_packet,
.write_trailer = gif_write_trailer,

View File

@ -33,13 +33,7 @@ static const char mode30_header[] = "#!iLBC30\n";
static int ilbc_write_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
AVCodecParameters *par;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "Unsupported number of streams\n");
return AVERROR(EINVAL);
}
par = s->streams[0]->codecpar;
AVCodecParameters *par = s->streams[0]->codecpar;
if (par->codec_id != AV_CODEC_ID_ILBC) {
av_log(s, AV_LOG_ERROR, "Unsupported codec\n");
@ -127,8 +121,11 @@ const FFOutputFormat ff_ilbc_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("iLBC storage"),
.p.mime_type = "audio/iLBC",
.p.extensions = "lbc",
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_ILBC,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.p.flags = AVFMT_NOTIMESTAMPS,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = ilbc_write_header,
.write_packet = ff_raw_write_packet,
};

View File

@ -32,11 +32,6 @@ static int ircam_write_header(AVFormatContext *s)
AVCodecParameters *par = s->streams[0]->codecpar;
uint32_t tag;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
return AVERROR(EINVAL);
}
tag = ff_codec_get_tag(ff_codec_ircam_le_tags, par->codec_id);
if (!tag) {
av_log(s, AV_LOG_ERROR, "unsupported codec\n");
@ -57,6 +52,8 @@ const FFOutputFormat ff_ircam_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("Berkeley/IRCAM/CARL Sound Format"),
.p.audio_codec = AV_CODEC_ID_PCM_S16LE,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = ircam_write_header,
.write_packet = ff_raw_write_packet,
.p.codec_tag = (const AVCodecTag *const []){ ff_codec_ircam_le_tags, 0 },

View File

@ -29,15 +29,9 @@ typedef struct IVFEncContext {
static int ivf_init(AVFormatContext *s)
{
AVCodecParameters *par;
AVCodecParameters *par = s->streams[0]->codecpar;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "Format supports only exactly one video stream\n");
return AVERROR(EINVAL);
}
par = s->streams[0]->codecpar;
if (par->codec_type != AVMEDIA_TYPE_VIDEO ||
!(par->codec_id == AV_CODEC_ID_AV1 ||
if (!(par->codec_id == AV_CODEC_ID_AV1 ||
par->codec_id == AV_CODEC_ID_VP8 ||
par->codec_id == AV_CODEC_ID_VP9)) {
av_log(s, AV_LOG_ERROR, "Currently only VP8, VP9 and AV1 are supported!\n");
@ -125,7 +119,9 @@ const FFOutputFormat ff_ivf_muxer = {
.p.extensions = "ivf",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_VP8,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.p.codec_tag = (const AVCodecTag* const []){ codec_ivf_tags, 0 },
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.priv_data_size = sizeof(IVFEncContext),
.init = ivf_init,
.write_header = ivf_write_header,

View File

@ -129,14 +129,7 @@ const FFInputFormat ff_kvag_demuxer = {
#if CONFIG_KVAG_MUXER
static int kvag_write_init(AVFormatContext *s)
{
AVCodecParameters *par;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "KVAG files have exactly one stream\n");
return AVERROR(EINVAL);
}
par = s->streams[0]->codecpar;
AVCodecParameters *par = s->streams[0]->codecpar;
if (par->codec_id != AV_CODEC_ID_ADPCM_IMA_SSI) {
av_log(s, AV_LOG_ERROR, "%s codec not supported\n",
@ -196,6 +189,8 @@ const FFOutputFormat ff_kvag_muxer = {
.p.extensions = "vag",
.p.audio_codec = AV_CODEC_ID_ADPCM_IMA_SSI,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.init = kvag_write_init,
.write_header = kvag_write_header,
.write_packet = ff_raw_write_packet,

View File

@ -37,12 +37,6 @@ static int lrc_write_header(AVFormatContext *s)
{
const AVDictionaryEntry *metadata_item;
if(s->nb_streams != 1 ||
s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
av_log(s, AV_LOG_ERROR,
"LRC supports only a single subtitle stream.\n");
return AVERROR(EINVAL);
}
if(s->streams[0]->codecpar->codec_id != AV_CODEC_ID_SUBRIP &&
s->streams[0]->codecpar->codec_id != AV_CODEC_ID_TEXT) {
av_log(s, AV_LOG_ERROR, "Unsupported subtitle codec: %s\n",
@ -131,7 +125,10 @@ const FFOutputFormat ff_lrc_muxer = {
.p.extensions = "lrc",
.p.flags = AVFMT_VARIABLE_FPS | AVFMT_GLOBALHEADER |
AVFMT_TS_NEGATIVE | AVFMT_TS_NONSTRICT,
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_SUBRIP,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.priv_data_size = 0,
.write_header = lrc_write_header,
.write_packet = lrc_write_packet,

View File

@ -29,7 +29,7 @@ static int microdvd_write_header(struct AVFormatContext *s)
AVCodecParameters *par = s->streams[0]->codecpar;
AVRational framerate = s->streams[0]->avg_frame_rate;
if (s->nb_streams != 1 || par->codec_id != AV_CODEC_ID_MICRODVD) {
if (par->codec_id != AV_CODEC_ID_MICRODVD) {
av_log(s, AV_LOG_ERROR, "Exactly one MicroDVD stream is needed.\n");
return -1;
}
@ -62,7 +62,10 @@ const FFOutputFormat ff_microdvd_muxer = {
.p.mime_type = "text/x-microdvd",
.p.extensions = "sub",
.p.flags = AVFMT_NOTIMESTAMPS,
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_MICRODVD,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = microdvd_write_header,
.write_packet = microdvd_write_packet,
};

View File

@ -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

View File

@ -36,6 +36,18 @@ struct AVDeviceInfoList;
* of the return value in case of flushing.
*/
#define FF_OFMT_FLAG_ALLOW_FLUSH (1 << 1)
/**
* If this flag is set, it indicates that for each codec type
* whose corresponding default codec (i.e. AVOutputFormat.audio_codec,
* AVOutputFormat.video_codec and AVOutputFormat.subtitle_codec)
* is set (i.e. != AV_CODEC_ID_NONE) only one stream of this type
* can be muxed. It furthermore indicates that no stream with
* a codec type that has no default codec or whose default codec
* is AV_CODEC_ID_NONE can be muxed.
* Both of these restrictions are checked generically before
* the actual muxer's init/write_header callbacks.
*/
#define FF_OFMT_FLAG_MAX_ONE_OF_EACH (1 << 2)
typedef struct FFOutputFormat {
/**

View File

@ -44,6 +44,25 @@ int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id,
codec_id == ofmt->audio_codec ||
codec_id == ofmt->subtitle_codec))
return 1;
else if (ffofmt(ofmt)->flags_internal & FF_OFMT_FLAG_MAX_ONE_OF_EACH) {
enum AVMediaType type = avcodec_get_type(codec_id);
switch (type) {
case AVMEDIA_TYPE_AUDIO:
if (ofmt->audio_codec == AV_CODEC_ID_NONE)
return 0;
break;
case AVMEDIA_TYPE_VIDEO:
if (ofmt->video_codec == AV_CODEC_ID_NONE)
return 0;
break;
case AVMEDIA_TYPE_SUBTITLE:
if (ofmt->subtitle_codec == AV_CODEC_ID_NONE)
return 0;
break;
default:
return 0;
}
}
}
return AVERROR_PATCHWELCOME;
}

View File

@ -34,28 +34,6 @@ int ff_raw_write_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
static int force_one_stream(AVFormatContext *s)
{
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "%s files have exactly one stream\n",
s->oformat->name);
return AVERROR(EINVAL);
}
if ( s->oformat->audio_codec != AV_CODEC_ID_NONE
&& s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) {
av_log(s, AV_LOG_ERROR, "%s files have exactly one audio stream\n",
s->oformat->name);
return AVERROR(EINVAL);
}
if ( s->oformat->video_codec != AV_CODEC_ID_NONE
&& s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
av_log(s, AV_LOG_ERROR, "%s files have exactly one video stream\n",
s->oformat->name);
return AVERROR(EINVAL);
}
return 0;
}
/* Note: Do not forget to add new entries to the Makefile as well. */
#if CONFIG_AC3_MUXER
@ -66,7 +44,8 @@ const FFOutputFormat ff_ac3_muxer = {
.p.extensions = "ac3",
.p.audio_codec = AV_CODEC_ID_AC3,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -98,7 +77,8 @@ const FFOutputFormat ff_adx_muxer = {
.p.extensions = "adx",
.p.audio_codec = AV_CODEC_ID_ADPCM_ADX,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.write_trailer = adx_write_trailer,
.p.flags = AVFMT_NOTIMESTAMPS,
@ -112,7 +92,8 @@ const FFOutputFormat ff_aptx_muxer = {
.p.extensions = "aptx",
.p.audio_codec = AV_CODEC_ID_APTX,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -125,7 +106,8 @@ const FFOutputFormat ff_aptx_hd_muxer = {
.p.extensions = "aptxhd",
.p.audio_codec = AV_CODEC_ID_APTX_HD,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -138,7 +120,8 @@ const FFOutputFormat ff_avs2_muxer = {
.p.extensions = "avs,avs2",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_AVS2,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -151,7 +134,8 @@ const FFOutputFormat ff_avs3_muxer = {
.p.extensions = "avs3",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_AVS3,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -165,7 +149,8 @@ const FFOutputFormat ff_cavsvideo_muxer = {
.p.extensions = "cavs",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_CAVS,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -177,7 +162,8 @@ const FFOutputFormat ff_codec2raw_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("raw codec2 muxer"),
.p.audio_codec = AV_CODEC_ID_CODEC2,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -185,6 +171,15 @@ const FFOutputFormat ff_codec2raw_muxer = {
#if CONFIG_DATA_MUXER
static av_cold int force_one_stream(AVFormatContext *s)
{
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "This muxer supports only one stream.\n");
return AVERROR(EINVAL);
}
return 0;
}
const FFOutputFormat ff_data_muxer = {
.p.name = "data",
.p.long_name = NULL_IF_CONFIG_SMALL("raw data"),
@ -201,7 +196,8 @@ const FFOutputFormat ff_dfpwm_muxer = {
.p.extensions = "dfpwm",
.p.audio_codec = AV_CODEC_ID_DFPWM,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -214,7 +210,8 @@ const FFOutputFormat ff_dirac_muxer = {
.p.extensions = "drc,vc2",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_DIRAC,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -227,7 +224,8 @@ const FFOutputFormat ff_dnxhd_muxer = {
.p.extensions = "dnxhd,dnxhr",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_DNXHD,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -241,7 +239,8 @@ const FFOutputFormat ff_dts_muxer = {
.p.extensions = "dts",
.p.audio_codec = AV_CODEC_ID_DTS,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -255,7 +254,8 @@ const FFOutputFormat ff_eac3_muxer = {
.p.extensions = "eac3,ec3",
.p.audio_codec = AV_CODEC_ID_EAC3,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -269,7 +269,8 @@ const FFOutputFormat ff_g722_muxer = {
.p.extensions = "g722",
.p.audio_codec = AV_CODEC_ID_ADPCM_G722,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -283,7 +284,8 @@ const FFOutputFormat ff_g723_1_muxer = {
.p.extensions = "tco,rco",
.p.audio_codec = AV_CODEC_ID_G723_1,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -295,7 +297,8 @@ const FFOutputFormat ff_g726_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("raw big-endian G.726 (\"left-justified\")"),
.p.audio_codec = AV_CODEC_ID_ADPCM_G726,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -307,7 +310,8 @@ const FFOutputFormat ff_g726le_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("raw little-endian G.726 (\"right-justified\")"),
.p.audio_codec = AV_CODEC_ID_ADPCM_G726LE,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -321,7 +325,8 @@ const FFOutputFormat ff_gsm_muxer = {
.p.extensions = "gsm",
.p.audio_codec = AV_CODEC_ID_GSM,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -335,7 +340,8 @@ const FFOutputFormat ff_h261_muxer = {
.p.extensions = "h261",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_H261,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -349,7 +355,8 @@ const FFOutputFormat ff_h263_muxer = {
.p.extensions = "h263",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_H263,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -371,7 +378,8 @@ const FFOutputFormat ff_h264_muxer = {
.p.extensions = "h264,264",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_H264,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.check_bitstream = h264_check_bitstream,
.p.flags = AVFMT_NOTIMESTAMPS,
@ -394,7 +402,8 @@ const FFOutputFormat ff_vvc_muxer = {
.p.extensions = "vvc,h266,266",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_VVC,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.check_bitstream = vvc_check_bitstream,
.p.flags = AVFMT_NOTIMESTAMPS,
@ -417,7 +426,8 @@ const FFOutputFormat ff_hevc_muxer = {
.p.extensions = "hevc,h265,265",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_HEVC,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.check_bitstream = hevc_check_bitstream,
.p.flags = AVFMT_NOTIMESTAMPS,
@ -431,7 +441,8 @@ const FFOutputFormat ff_evc_muxer = {
.p.extensions = "evc",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_EVC,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -444,7 +455,8 @@ const FFOutputFormat ff_m4v_muxer = {
.p.extensions = "m4v",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_MPEG4,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -458,7 +470,8 @@ const FFOutputFormat ff_mjpeg_muxer = {
.p.extensions = "mjpg,mjpeg",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_MJPEG,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -471,7 +484,8 @@ const FFOutputFormat ff_mlp_muxer = {
.p.extensions = "mlp",
.p.audio_codec = AV_CODEC_ID_MLP,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -485,7 +499,8 @@ const FFOutputFormat ff_mp2_muxer = {
.p.extensions = "mp2,m2a,mpa",
.p.audio_codec = AV_CODEC_ID_MP2,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -499,7 +514,8 @@ const FFOutputFormat ff_mpeg1video_muxer = {
.p.extensions = "mpg,mpeg,m1v",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_MPEG1VIDEO,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -512,7 +528,8 @@ const FFOutputFormat ff_mpeg2video_muxer = {
.p.extensions = "m2v",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_MPEG2VIDEO,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -531,7 +548,8 @@ const FFOutputFormat ff_obu_muxer = {
.p.extensions = "obu",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_AV1,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.check_bitstream = obu_check_bitstream,
.p.flags = AVFMT_NOTIMESTAMPS,
@ -545,6 +563,7 @@ const FFOutputFormat ff_rawvideo_muxer = {
.p.extensions = "yuv,rgb",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_RAWVIDEO,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -557,7 +576,9 @@ const FFOutputFormat ff_sbc_muxer = {
.p.mime_type = "audio/x-sbc",
.p.extensions = "sbc,msbc",
.p.audio_codec = AV_CODEC_ID_SBC,
.init = force_one_stream,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -570,7 +591,8 @@ const FFOutputFormat ff_truehd_muxer = {
.p.extensions = "thd",
.p.audio_codec = AV_CODEC_ID_TRUEHD,
.p.video_codec = AV_CODEC_ID_NONE,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};
@ -583,7 +605,8 @@ const FFOutputFormat ff_vc1_muxer = {
.p.extensions = "vc1",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_VC1,
.init = force_one_stream,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_packet = ff_raw_write_packet,
.p.flags = AVFMT_NOTIMESTAMPS,
};

View File

@ -84,10 +84,8 @@ static void rcwt_flush_cluster(AVFormatContext *avf)
static int rcwt_write_header(AVFormatContext *avf)
{
if (avf->nb_streams != 1 || avf->streams[0]->codecpar->codec_id != AV_CODEC_ID_EIA_608) {
av_log(avf, AV_LOG_ERROR,
"RCWT supports only one CC (608/708) stream, more than one stream was "
"provided or its codec type was not CC (608/708)\n");
if (avf->streams[0]->codecpar->codec_id != AV_CODEC_ID_EIA_608) {
av_log(avf, AV_LOG_ERROR, "RCWT supports only CC (608/708)\n");
return AVERROR(EINVAL);
}
@ -168,7 +166,10 @@ const FFOutputFormat ff_rcwt_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("RCWT (Raw Captions With Time)"),
.p.extensions = "bin",
.p.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_EIA_608,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.priv_data_size = sizeof(RCWTContext),
.write_header = rcwt_write_header,
.write_packet = rcwt_write_packet,

View File

@ -35,12 +35,6 @@ static int scc_write_header(AVFormatContext *avf)
{
SCCContext *scc = avf->priv_data;
if (avf->nb_streams != 1 ||
avf->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
av_log(avf, AV_LOG_ERROR,
"SCC supports only a single subtitles stream.\n");
return AVERROR(EINVAL);
}
if (avf->streams[0]->codecpar->codec_id != AV_CODEC_ID_EIA_608) {
av_log(avf, AV_LOG_ERROR,
"Unsupported subtitles codec: %s\n",
@ -117,7 +111,10 @@ const FFOutputFormat ff_scc_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("Scenarist Closed Captions"),
.p.extensions = "scc",
.p.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_EIA_608,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.priv_data_size = sizeof(SCCContext),
.write_header = scc_write_header,
.write_packet = scc_write_packet,

View File

@ -124,10 +124,6 @@ static int film_init(AVFormatContext *format_context)
for (int i = 0; i < format_context->nb_streams; i++) {
AVStream *st = format_context->streams[i];
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
if (film->audio_index > -1) {
av_log(format_context, AV_LOG_ERROR, "Sega FILM allows a maximum of one audio stream.\n");
return AVERROR(EINVAL);
}
if (get_audio_codec_id(st->codecpar->codec_id) < 0) {
av_log(format_context, AV_LOG_ERROR,
"Incompatible audio stream format.\n");
@ -137,10 +133,6 @@ static int film_init(AVFormatContext *format_context)
}
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (film->video_index > -1) {
av_log(format_context, AV_LOG_ERROR, "Sega FILM allows a maximum of one video stream.\n");
return AVERROR(EINVAL);
}
if (st->codecpar->codec_id != AV_CODEC_ID_CINEPAK &&
st->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO) {
av_log(format_context, AV_LOG_ERROR,
@ -287,6 +279,8 @@ const FFOutputFormat ff_segafilm_muxer = {
.priv_data_size = sizeof(FILMOutputContext),
.p.audio_codec = AV_CODEC_ID_PCM_S16BE_PLANAR,
.p.video_codec = AV_CODEC_ID_CINEPAK,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.init = film_init,
.write_trailer = film_write_header,
.write_packet = film_write_packet,

View File

@ -39,12 +39,6 @@ static int srt_write_header(AVFormatContext *avf)
{
SRTContext *srt = avf->priv_data;
if (avf->nb_streams != 1 ||
avf->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
av_log(avf, AV_LOG_ERROR,
"SRT supports only a single subtitles stream.\n");
return AVERROR(EINVAL);
}
if (avf->streams[0]->codecpar->codec_id != AV_CODEC_ID_TEXT &&
avf->streams[0]->codecpar->codec_id != AV_CODEC_ID_SUBRIP) {
av_log(avf, AV_LOG_ERROR,
@ -103,7 +97,10 @@ const FFOutputFormat ff_srt_muxer = {
.p.mime_type = "application/x-subrip",
.p.extensions = "srt",
.p.flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_SUBRIP,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.priv_data_size = sizeof(SRTContext),
.write_header = srt_write_header,
.write_packet = srt_write_packet,

View File

@ -74,12 +74,6 @@ static int sup_write_packet(AVFormatContext *s, AVPacket *pkt)
static int sup_write_header(AVFormatContext *s)
{
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "%s files have exactly one stream\n",
s->oformat->name);
return AVERROR(EINVAL);
}
avpriv_set_pts_info(s->streams[0], 32, 1, 90000);
return 0;
@ -90,8 +84,11 @@ const FFOutputFormat ff_sup_muxer = {
.p.long_name = NULL_IF_CONFIG_SMALL("raw HDMV Presentation Graphic Stream subtitles"),
.p.extensions = "sup",
.p.mime_type = "application/x-pgs",
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_HDMV_PGS_SUBTITLE,
.p.flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = sup_write_header,
.write_packet = sup_write_packet,
};

View File

@ -208,10 +208,6 @@ static int swf_write_header(AVFormatContext *s)
for(i=0;i<s->nb_streams;i++) {
AVCodecParameters *par = s->streams[i]->codecpar;
if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
if (swf->audio_par) {
av_log(s, AV_LOG_ERROR, "SWF muxer only supports 1 audio stream\n");
return AVERROR_INVALIDDATA;
}
if (par->codec_id == AV_CODEC_ID_MP3) {
swf->audio_par = par;
swf->audio_fifo = av_fifo_alloc2(AUDIO_FIFO_SIZE, 1, 0);
@ -222,10 +218,6 @@ static int swf_write_header(AVFormatContext *s)
return -1;
}
} else {
if (swf->video_par) {
av_log(s, AV_LOG_ERROR, "SWF muxer only supports 1 video stream\n");
return AVERROR_INVALIDDATA;
}
if (ff_codec_get_tag(ff_swf_codec_tags, par->codec_id) ||
par->codec_id == AV_CODEC_ID_PNG ||
par->codec_id == AV_CODEC_ID_MJPEG) {
@ -556,11 +548,13 @@ const FFOutputFormat ff_swf_muxer = {
.priv_data_size = sizeof(SWFEncContext),
.p.audio_codec = AV_CODEC_ID_MP3,
.p.video_codec = AV_CODEC_ID_FLV1,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.write_header = swf_write_header,
.write_packet = swf_write_packet,
.write_trailer = swf_write_trailer,
.deinit = swf_deinit,
.p.flags = AVFMT_TS_NONSTRICT,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
};
#endif
#if CONFIG_AVM2_MUXER
@ -571,10 +565,12 @@ const FFOutputFormat ff_avm2_muxer = {
.priv_data_size = sizeof(SWFEncContext),
.p.audio_codec = AV_CODEC_ID_MP3,
.p.video_codec = AV_CODEC_ID_FLV1,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.write_header = swf_write_header,
.write_packet = swf_write_packet,
.write_trailer = swf_write_trailer,
.deinit = swf_deinit,
.p.flags = AVFMT_TS_NONSTRICT,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
};
#endif

View File

@ -40,13 +40,7 @@ typedef struct TTAMuxContext {
static int tta_init(AVFormatContext *s)
{
TTAMuxContext *tta = s->priv_data;
AVCodecParameters *par;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "Only one stream is supported\n");
return AVERROR(EINVAL);
}
par = s->streams[0]->codecpar;
AVCodecParameters *par = s->streams[0]->codecpar;
if (par->codec_id != AV_CODEC_ID_TTA) {
av_log(s, AV_LOG_ERROR, "Unsupported codec\n");
@ -174,6 +168,8 @@ const FFOutputFormat ff_tta_muxer = {
.priv_data_size = sizeof(TTAMuxContext),
.p.audio_codec = AV_CODEC_ID_TTA,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.init = tta_init,
.deinit = tta_deinit,
.write_header = tta_write_header,

View File

@ -126,8 +126,7 @@ static int ttml_write_header(AVFormatContext *ctx)
TTMLMuxContext *ttml_ctx = ctx->priv_data;
ttml_ctx->document_written = 0;
if (ctx->nb_streams != 1 ||
ctx->streams[0]->codecpar->codec_id != AV_CODEC_ID_TTML) {
if (ctx->streams[0]->codecpar->codec_id != AV_CODEC_ID_TTML) {
av_log(ctx, AV_LOG_ERROR, "Exactly one TTML stream is required!\n");
return AVERROR(EINVAL);
}
@ -224,7 +223,10 @@ const FFOutputFormat ff_ttml_muxer = {
.priv_data_size = sizeof(TTMLMuxContext),
.p.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
AVFMT_TS_NONSTRICT,
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_TTML,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
.write_header = ttml_write_header,
.write_packet = ttml_write_packet,
.write_trailer = ttml_write_trailer,

View File

@ -304,11 +304,6 @@ static int wav_write_header(AVFormatContext *s)
AVIOContext *pb = s->pb;
int64_t fmt;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "WAVE files have exactly one stream\n");
return AVERROR(EINVAL);
}
if (wav->rf64 == RF64_ALWAYS) {
ffio_wfourcc(pb, "RF64");
avio_wl32(pb, -1); /* RF64 chunk size: use size in ds64 */
@ -516,6 +511,7 @@ const FFOutputFormat ff_wav_muxer = {
.priv_data_size = sizeof(WAVMuxContext),
.p.audio_codec = AV_CODEC_ID_PCM_S16LE,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.write_header = wav_write_header,
.write_packet = wav_write_packet,
.write_trailer = wav_write_trailer,
@ -523,22 +519,13 @@ const FFOutputFormat ff_wav_muxer = {
.p.flags = AVFMT_TS_NONSTRICT,
.p.codec_tag = ff_wav_codec_tags_list,
.p.priv_class = &wav_muxer_class,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
};
#endif /* CONFIG_WAV_MUXER */
#if CONFIG_W64_MUXER
#include "w64.h"
static av_cold int w64_init(AVFormatContext *ctx)
{
if (ctx->nb_streams != 1) {
av_log(ctx, AV_LOG_ERROR, "This muxer only supports a single stream.\n");
return AVERROR(EINVAL);
}
return 0;
}
static void start_guid(AVIOContext *pb, const uint8_t *guid, int64_t *pos)
{
*pos = avio_tell(pb);
@ -624,11 +611,12 @@ const FFOutputFormat ff_w64_muxer = {
.priv_data_size = sizeof(WAVMuxContext),
.p.audio_codec = AV_CODEC_ID_PCM_S16LE,
.p.video_codec = AV_CODEC_ID_NONE,
.init = w64_init,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.write_header = w64_write_header,
.write_packet = wav_write_packet,
.write_trailer = w64_write_trailer,
.p.flags = AVFMT_TS_NONSTRICT,
.p.codec_tag = ff_wav_codec_tags_list,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
};
#endif /* CONFIG_W64_MUXER */

View File

@ -42,10 +42,6 @@ static int webp_init(AVFormatContext *s)
w->last_pkt = ffformatcontext(s)->pkt;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "Only exactly 1 stream is supported\n");
return AVERROR(EINVAL);
}
st = s->streams[0];
if (st->codecpar->codec_id != AV_CODEC_ID_WEBP) {
av_log(s, AV_LOG_ERROR, "Only WebP is supported\n");
@ -230,9 +226,12 @@ const FFOutputFormat ff_webp_muxer = {
.p.extensions = "webp",
.priv_data_size = sizeof(WebpContext),
.p.video_codec = AV_CODEC_ID_WEBP,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.init = webp_init,
.write_packet = webp_write_packet,
.write_trailer = webp_write_trailer,
.p.priv_class = &webp_muxer_class,
.p.flags = AVFMT_VARIABLE_FPS,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
};

View File

@ -50,7 +50,7 @@ static int webvtt_write_header(AVFormatContext *ctx)
AVCodecParameters *par = ctx->streams[0]->codecpar;
AVIOContext *pb = ctx->pb;
if (ctx->nb_streams != 1 || par->codec_id != AV_CODEC_ID_WEBVTT) {
if (par->codec_id != AV_CODEC_ID_WEBVTT) {
av_log(ctx, AV_LOG_ERROR, "Exactly one WebVTT stream is needed.\n");
return AVERROR(EINVAL);
}
@ -109,7 +109,10 @@ const FFOutputFormat ff_webvtt_muxer = {
.p.extensions = "vtt",
.p.mime_type = "text/vtt",
.p.flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
.p.video_codec = AV_CODEC_ID_NONE,
.p.audio_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_WEBVTT,
.write_header = webvtt_write_header,
.write_packet = webvtt_write_packet,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
};

View File

@ -59,11 +59,6 @@ static int wsaud_write_init(AVFormatContext *ctx)
return AVERROR(EINVAL);
}
if (ctx->nb_streams != 1) {
av_log(ctx, AV_LOG_ERROR, "AUD files have exactly one stream\n");
return AVERROR(EINVAL);
}
return 0;
}
@ -133,8 +128,10 @@ const FFOutputFormat ff_wsaud_muxer = {
.priv_data_size = sizeof(AUDMuxContext),
.p.audio_codec = AV_CODEC_ID_ADPCM_IMA_WS,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.init = wsaud_write_init,
.write_header = wsaud_write_header,
.write_packet = wsaud_write_packet,
.write_trailer = wsaud_write_trailer,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
};

View File

@ -33,8 +33,7 @@ typedef struct WvMuxContext {
static av_cold int wv_init(AVFormatContext *ctx)
{
if (ctx->nb_streams > 1 ||
ctx->streams[0]->codecpar->codec_id != AV_CODEC_ID_WAVPACK) {
if (ctx->streams[0]->codecpar->codec_id != AV_CODEC_ID_WAVPACK) {
av_log(ctx, AV_LOG_ERROR, "This muxer only supports a single WavPack stream.\n");
return AVERROR(EINVAL);
}
@ -85,8 +84,10 @@ const FFOutputFormat ff_wv_muxer = {
.priv_data_size = sizeof(WvMuxContext),
.p.audio_codec = AV_CODEC_ID_WAVPACK,
.p.video_codec = AV_CODEC_ID_NONE,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.init = wv_init,
.write_packet = wv_write_packet,
.write_trailer = wv_write_trailer,
.p.flags = AVFMT_NOTIMESTAMPS,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
};

View File

@ -221,9 +221,6 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
static int yuv4_init(AVFormatContext *s)
{
if (s->nb_streams != 1)
return AVERROR(EIO);
if (s->streams[0]->codecpar->codec_id != AV_CODEC_ID_WRAPPED_AVFRAME &&
s->streams[0]->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO) {
av_log(s, AV_LOG_ERROR, "ERROR: Codec not supported.\n");
@ -297,7 +294,9 @@ const FFOutputFormat ff_yuv4mpegpipe_muxer = {
.p.extensions = "y4m",
.p.audio_codec = AV_CODEC_ID_NONE,
.p.video_codec = AV_CODEC_ID_WRAPPED_AVFRAME,
.p.subtitle_codec = AV_CODEC_ID_NONE,
.init = yuv4_init,
.write_header = yuv4_write_header,
.write_packet = yuv4_write_packet,
.flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH,
};