[FFmpeg-cvslog] matroska: implement support for ALAC

Moritz Bunkus git at videolan.org
Thu Sep 20 19:59:06 CEST 2012


ffmpeg | branch: master | Moritz Bunkus <moritz at bunkus.org> | Fri Sep 14 22:26:14 2012 +0200| [8071dca3d595a4fc5f9b3ee9f667e2c3e4a35517] | committer: Luca Barbato

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 at gentoo.org>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8071dca3d595a4fc5f9b3ee9f667e2c3e4a35517
---

 libavformat/matroska.c    |    1 +
 libavformat/matroskadec.c |   13 +++++++++++++
 libavformat/matroskaenc.c |   10 ++++++++++
 3 files changed, 24 insertions(+)

diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index d2d07a8..652e4d0 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 ff2a6c2..69a8c7f 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 9d9c223..521f6b5 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) {



More information about the ffmpeg-cvslog mailing list