It seems Apple's reference implementation gives incorrect magic cookie on little endian host.
In function ALACEncoder::GetMagicCookie():
theChannelLayout.mChannelLayoutTag = ALACChannelLayoutTags[theConfig.numChannels - 1];
--snip---
memcpy(theCookiePointer, &theChannelLayout, sizeof(ALACAudioChannelLayout));
In the upper line, mChannelLayoutTag is set without endian conversion, then it's just copied to the magic cookie buffer.
Probably this is not what they meant, since ALACSpecificConfig part is converted to big-endian.
I'm not seeing this; in the source, the mChannelLayoutTag is only set if the number of channels is > 2. For a stereo bitstream, there's no layout tag. But ffmpeg is still reading the header incorrectly, I think --
(from libavformat/cafdec.c:read_kuki_chunk()):
} else if (st->codec->codec_id == CODEC_ID_ALAC) {
#define ALAC_PREAMBLE 12
#define ALAC_HEADER 36
if (size < ALAC_PREAMBLE + ALAC_HEADER) {
av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
avio_skip(pb, size);
return AVERROR_INVALIDDATA;
}
I don't think those numbers are correct: the ALAC_PREAMBLE, (which I take to mean 'k' 'u' 'k' 'i' 00 00 00 00 00 00 00 18) is twelve bytes long; and ALAC_HEADER? Is this supposed to be the contents of the kuki chunk? Because that's a static size of sizeof(ALACSpecificConfig) for mono and stereo tracks, which is … 24 bytes. I'm not seeing where this 48 byte minimum size requirement is coming from? Regardless, this is a variable size -- if there are more than two channels, the size of the cookie payload is variable. I think this ffmpeg code is just wrong. Investigating further.