summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Bunkus <moritz@bunkus.org>2012-09-14 22:26:14 +0200
committerLuca Barbato <lu_zero@gentoo.org>2012-09-19 20:34:14 +0200
commit8071dca3d595a4fc5f9b3ee9f667e2c3e4a35517 (patch)
tree95c59a49002c12171dde2bf8132ff69cd015fe43
parent870e75524aa0d00ebcd1d15589c8d29b84af1565 (diff)
matroska: implement support for ALAC
Support Matroska native formatting. On demuxing reconstruct the 36-bytes QuickTime atom that the ALAC decoder expects by prepending the "atom size", "tag" and "tag version" fields missing from the Matroska's CodecPrivate element. On muxing remove the initial 12 bytes 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: Luca Barbato <lu_zero@gentoo.org>
-rw-r--r--libavformat/matroska.c1
-rw-r--r--libavformat/matroskadec.c13
-rw-r--r--libavformat/matroskaenc.c10
3 files changed, 24 insertions, 0 deletions
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index d2d07a8eca..652e4d0b03 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -24,6 +24,7 @@
const CodecTags ff_mkv_codec_tags[]={
{"A_AAC" , AV_CODEC_ID_AAC},
{"A_AC3" , AV_CODEC_ID_AC3},
+ {"A_ALAC" , AV_CODEC_ID_ALAC},
{"A_DTS" , AV_CODEC_ID_DTS},
{"A_EAC3" , AV_CODEC_ID_EAC3},
{"A_FLAC" , AV_CODEC_ID_FLAC},
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index ff2a6c29dc..69a8c7f06e 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1528,6 +1528,19 @@ static int matroska_read_header(AVFormatContext *s)
extradata_size = 5;
} else
extradata_size = 2;
+ } else if (codec_id == AV_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 + FF_INPUT_BUFFER_PADDING_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 == AV_CODEC_ID_TTA) {
extradata_size = 30;
extradata = av_mallocz(extradata_size);
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 9d9c223dbb..521f6b5c1a 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -475,6 +475,16 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo
ret = ff_flac_write_header(dyn_cp, codec, 1);
else if (codec->codec_id == AV_CODEC_ID_H264)
ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size);
+ else if (codec->codec_id == AV_CODEC_ID_ALAC) {
+ if (codec->extradata_size < 36) {
+ av_log(s, AV_LOG_ERROR,
+ "Invalid extradata found, ALAC expects a 36-byte "
+ "QuickTime atom.");
+ ret = AVERROR_INVALIDDATA;
+ } else
+ avio_write(dyn_cp, codec->extradata + 12,
+ codec->extradata_size - 12);
+ }
else if (codec->extradata_size)
avio_write(dyn_cp, codec->extradata, codec->extradata_size);
} else if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {