summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Bunkus <moritz@bunkus.org>2012-08-05 16:25:48 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-08-05 17:59:12 +0200
commitbc3b4220296e24e2cdd1213208a470853fcb76c3 (patch)
tree8f9252f1fb0648d52f802ddaa1d756b99461c9d3
parentd106ffd942e2e1837d8b100161cb1df1aa7b617a (diff)
matroskadec: Implement support for ALAC
This patch implements support reading ALAC from Matroska files. The only non-trivial thing about it is that only the ALAC magic cookie is stored in Matroska's CodecPrivate element but not the "atom size", "tag" and "tag version" fields that FFMPEG's ALAC decoder expects. However, those are trivial to re-create. Sample files are available: http://www.bunkus.org/videotools/mkvtoolnix/samples/alac/alac-in-matroska.mka and the CoreAudio file it was created from with today's mkvmerge: http://www.bunkus.org/videotools/mkvtoolnix/samples/alac/alac-in-matroska-source.caf Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavformat/matroska.c1
-rw-r--r--libavformat/matroskadec.c12
2 files changed, 13 insertions, 0 deletions
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index 5e9a6cade3..ea91ed7494 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -24,6 +24,7 @@
const CodecTags ff_mkv_codec_tags[]={
{"A_AAC" , CODEC_ID_AAC},
{"A_AC3" , CODEC_ID_AC3},
+ {"A_ALAC" , CODEC_ID_ALAC},
{"A_DTS" , CODEC_ID_DTS},
{"A_EAC3" , CODEC_ID_EAC3},
{"A_FLAC" , CODEC_ID_FLAC},
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 2c954afa05..0f1808773b 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1580,6 +1580,18 @@ static int matroska_read_header(AVFormatContext *s)
&& (track->codec_priv.data != NULL)) {
fourcc = AV_RL32(track->codec_priv.data);
codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc);
+ } else if (codec_id == CODEC_ID_ALAC && track->codec_priv.size) {
+ /* Only ALAC's magic cookie is stored in Matroska's track headers.
+ Create the "atom size", "tag", and "tag version" fields the
+ decoder expects manually. */
+ extradata_size = 12 + track->codec_priv.size;
+ extradata = av_mallocz(extradata_size);
+ if (extradata == NULL)
+ return AVERROR(ENOMEM);
+ AV_WB32(extradata, extradata_size);
+ memcpy(&extradata[4], "alac", 4);
+ AV_WB32(&extradata[8], 0);
+ memcpy(&extradata[12], track->codec_priv.data, track->codec_priv.size);
} else if (codec_id == CODEC_ID_PCM_S16BE) {
switch (track->audio.bitdepth) {
case 8: codec_id = CODEC_ID_PCM_U8; break;