[FFmpeg-devel] [PATCH/RFC]av_codec_get_tag() cannot work for Matroska (Ticket 8)
Carl Eugen Hoyos
cehoyos at ag.or.at
Wed Aug 24 14:37:33 CEST 2011
Hi!
ffmpeg.c sets codec_tag for the output stream in the stream copy case if
codec_tag was set by the demuxer, and no default codec_tag for the codec can
be found in the muxers' list of codec_tags using av_codec_get_tag (and also if
no such list was defined and also if the codec_tag is known to be correct).
(line 2231 - 2235)
The ts demuxer always sets codec_tag, it was discussed here before that this
is intended (third party applications may like the value).
Matroska cannot provide a codec_tags list compatible with av_codec_get_tag and
therefore provides the wav (and the bmp) list.
Some codecs that work in Matroska are not listed in the wav (and bmp) list,
making stream copy impossible if a codec_tag was set because the set codec_tag
is rejected later (it is for example not set for TrueHD, so it is possible
that only the EAC3 in ts case - at least for some samples - triggers) in
avformat_write_header() / validate_codec_tag().
Attached is a try to fix this by adding the missing audio codec_tags (I will
do similar for subtitles and video if needed), I would be glad if a simpler
solution is possible like not to try to validate the codec_tag for matroska.
Carl Eugen
-------------- next part --------------
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 0910da5..0bc995f 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -1214,6 +1214,25 @@ static int mkv_query_codec(enum CodecID codec_id, int std_compliance)
return 0;
}
+/* The following tags are not listed in ff_codec_wav_tags,
+ * so av_codec_get_id() and av_codec_get_tag() would incorrectly fail
+ * if they are not listed here. */
+const AVCodecTag missing_audio_tags[] = {
+ { CODEC_ID_EAC3, 0xFFFFFFFF },
+ { CODEC_ID_MLP, 0xFFFFFFFF },
+ { CODEC_ID_PCM_S16BE, 0xFFFFFFFF },
+ { CODEC_ID_PCM_S24BE, 0xFFFFFFFF },
+ { CODEC_ID_PCM_S32BE, 0xFFFFFFFF },
+ { CODEC_ID_QDM2, 0xFFFFFFFF },
+ { CODEC_ID_RA_144, 0xFFFFFFFF },
+ { CODEC_ID_RA_288, 0xFFFFFFFF },
+ { CODEC_ID_COOK, 0xFFFFFFFF },
+ { CODEC_ID_TRUEHD, 0xFFFFFFFF },
+ { CODEC_ID_TTA, 0xFFFFFFFF },
+ { CODEC_ID_WAVPACK, 0xFFFFFFFF },
+ { CODEC_ID_NONE, 0xFFFFFFFF }
+};
+
#if CONFIG_MATROSKA_MUXER
AVOutputFormat ff_matroska_muxer = {
.name = "matroska",
@@ -1235,7 +1254,7 @@ AVOutputFormat ff_matroska_muxer = {
.write_packet = mkv_write_packet,
.write_trailer = mkv_write_trailer,
.flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
- .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, 0},
+ .codec_tag = (const AVCodecTag* const []){ff_codec_bmp_tags, ff_codec_wav_tags, missing_audio_tags, 0},
.subtitle_codec = CODEC_ID_SSA,
.query_codec = mkv_query_codec,
};
@@ -1274,6 +1293,6 @@ AVOutputFormat ff_matroska_audio_muxer = {
.write_packet = mkv_write_packet,
.write_trailer = mkv_write_trailer,
.flags = AVFMT_GLOBALHEADER,
- .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, 0},
+ .codec_tag = (const AVCodecTag* const []){ff_codec_wav_tags, missing_audio_tags, 0},
};
#endif
-------------- next part --------------
diff --git a/libavformat/utils.c b/libavformat/utils.c
index ef1de94..8fac96e 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2986,7 +2986,7 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
break;
}
- if(s->oformat->codec_tag){
+ if(s->oformat->codec_tag && strcmp(s->oformat->name, "matroska")){
if(st->codec->codec_tag && st->codec->codec_id == CODEC_ID_RAWVIDEO && av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id) == 0 && !validate_codec_tag(s, st)){
//the current rawvideo encoding system ends up setting the wrong codec_tag for avi, we override it here
st->codec->codec_tag= 0;
More information about the ffmpeg-devel
mailing list