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>
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},
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);
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) {