00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include "avformat.h"
00029 #include "internal.h"
00030 #include "riff.h"
00031 #include "isom.h"
00032 #include "mov_chan.h"
00033 #include "libavutil/intreadwrite.h"
00034 #include "libavutil/intfloat.h"
00035 #include "libavutil/dict.h"
00036 #include "caf.h"
00037
00038 typedef struct {
00039 int bytes_per_packet;
00040 int frames_per_packet;
00041 int64_t num_bytes;
00042
00043 int64_t packet_cnt;
00044 int64_t frame_cnt;
00045
00046 int64_t data_start;
00047 int64_t data_size;
00048 } CaffContext;
00049
00050 static int probe(AVProbeData *p)
00051 {
00052 if (AV_RB32(p->buf) == MKBETAG('c','a','f','f') && AV_RB16(&p->buf[4]) == 1)
00053 return AVPROBE_SCORE_MAX;
00054 return 0;
00055 }
00056
00058 static int read_desc_chunk(AVFormatContext *s)
00059 {
00060 AVIOContext *pb = s->pb;
00061 CaffContext *caf = s->priv_data;
00062 AVStream *st;
00063 int flags;
00064
00065
00066 st = avformat_new_stream(s, NULL);
00067 if (!st)
00068 return AVERROR(ENOMEM);
00069
00070
00071 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00072 st->codec->sample_rate = av_int2double(avio_rb64(pb));
00073 st->codec->codec_tag = avio_rl32(pb);
00074 flags = avio_rb32(pb);
00075 caf->bytes_per_packet = avio_rb32(pb);
00076 st->codec->block_align = caf->bytes_per_packet;
00077 caf->frames_per_packet = avio_rb32(pb);
00078 st->codec->channels = avio_rb32(pb);
00079 st->codec->bits_per_coded_sample = avio_rb32(pb);
00080
00081
00082 if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) {
00083 st->codec->bit_rate = (uint64_t)st->codec->sample_rate * (uint64_t)caf->bytes_per_packet * 8
00084 / (uint64_t)caf->frames_per_packet;
00085 } else {
00086 st->codec->bit_rate = 0;
00087 }
00088
00089
00090 if (st->codec->codec_tag == MKTAG('l','p','c','m'))
00091 st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, (flags ^ 0x2) | 0x4);
00092 else
00093 st->codec->codec_id = ff_codec_get_id(ff_codec_caf_tags, st->codec->codec_tag);
00094 return 0;
00095 }
00096
00098 static int read_kuki_chunk(AVFormatContext *s, int64_t size)
00099 {
00100 AVIOContext *pb = s->pb;
00101 AVStream *st = s->streams[0];
00102
00103 if (size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
00104 return -1;
00105
00106 if (st->codec->codec_id == AV_CODEC_ID_AAC) {
00107
00108
00109
00110 int strt, skip;
00111 MOVAtom atom;
00112
00113 strt = avio_tell(pb);
00114 ff_mov_read_esds(s, pb, atom);
00115 skip = size - (avio_tell(pb) - strt);
00116 if (skip < 0 || !st->codec->extradata ||
00117 st->codec->codec_id != AV_CODEC_ID_AAC) {
00118 av_log(s, AV_LOG_ERROR, "invalid AAC magic cookie\n");
00119 return AVERROR_INVALIDDATA;
00120 }
00121 avio_skip(pb, skip);
00122 } else if (st->codec->codec_id == AV_CODEC_ID_ALAC) {
00123 #define ALAC_PREAMBLE 12
00124 #define ALAC_HEADER 36
00125 #define ALAC_NEW_KUKI 24
00126 uint8_t preamble[12];
00127 if (size < ALAC_NEW_KUKI) {
00128 av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
00129 avio_skip(pb, size);
00130 return AVERROR_INVALIDDATA;
00131 }
00132 avio_read(pb, preamble, ALAC_PREAMBLE);
00133
00134 st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE);
00135 if (!st->codec->extradata)
00136 return AVERROR(ENOMEM);
00137
00138
00139
00140
00141
00142 if (!memcmp(&preamble[4], "frmaalac", 8)) {
00143 if (size < ALAC_PREAMBLE + ALAC_HEADER) {
00144 av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
00145 av_freep(&st->codec->extradata);
00146 return AVERROR_INVALIDDATA;
00147 }
00148 avio_read(pb, st->codec->extradata, ALAC_HEADER);
00149 avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER);
00150 } else {
00151 AV_WB32(st->codec->extradata, 36);
00152 memcpy(&st->codec->extradata[4], "alac", 4);
00153 AV_WB32(&st->codec->extradata[8], 0);
00154 memcpy(&st->codec->extradata[12], preamble, 12);
00155 avio_read(pb, &st->codec->extradata[24], ALAC_NEW_KUKI - 12);
00156 avio_skip(pb, size - ALAC_NEW_KUKI);
00157 }
00158 st->codec->extradata_size = ALAC_HEADER;
00159 } else {
00160 st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
00161 if (!st->codec->extradata)
00162 return AVERROR(ENOMEM);
00163 avio_read(pb, st->codec->extradata, size);
00164 st->codec->extradata_size = size;
00165 }
00166
00167 return 0;
00168 }
00169
00171 static int read_pakt_chunk(AVFormatContext *s, int64_t size)
00172 {
00173 AVIOContext *pb = s->pb;
00174 AVStream *st = s->streams[0];
00175 CaffContext *caf = s->priv_data;
00176 int64_t pos = 0, ccount, num_packets;
00177 int i;
00178
00179 ccount = avio_tell(pb);
00180
00181 num_packets = avio_rb64(pb);
00182 if (num_packets < 0 || INT32_MAX / sizeof(AVIndexEntry) < num_packets)
00183 return AVERROR_INVALIDDATA;
00184
00185 st->nb_frames = avio_rb64(pb);
00186 st->nb_frames += avio_rb32(pb);
00187 st->nb_frames += avio_rb32(pb);
00188
00189 st->duration = 0;
00190 for (i = 0; i < num_packets; i++) {
00191 av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME);
00192 pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb);
00193 st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb);
00194 }
00195
00196 if (avio_tell(pb) - ccount > size) {
00197 av_log(s, AV_LOG_ERROR, "error reading packet table\n");
00198 return AVERROR_INVALIDDATA;
00199 }
00200 avio_skip(pb, ccount + size - avio_tell(pb));
00201
00202 caf->num_bytes = pos;
00203 return 0;
00204 }
00205
00207 static void read_info_chunk(AVFormatContext *s, int64_t size)
00208 {
00209 AVIOContext *pb = s->pb;
00210 unsigned int i;
00211 unsigned int nb_entries = avio_rb32(pb);
00212 for (i = 0; i < nb_entries; i++) {
00213 char key[32];
00214 char value[1024];
00215 avio_get_str(pb, INT_MAX, key, sizeof(key));
00216 avio_get_str(pb, INT_MAX, value, sizeof(value));
00217 av_dict_set(&s->metadata, key, value, 0);
00218 }
00219 }
00220
00221 static int read_header(AVFormatContext *s)
00222 {
00223 AVIOContext *pb = s->pb;
00224 CaffContext *caf = s->priv_data;
00225 AVStream *st;
00226 uint32_t tag = 0;
00227 int found_data, ret;
00228 int64_t size;
00229
00230 avio_skip(pb, 8);
00231
00232
00233 if (avio_rb32(pb) != MKBETAG('d','e','s','c')) {
00234 av_log(s, AV_LOG_ERROR, "desc chunk not present\n");
00235 return AVERROR_INVALIDDATA;
00236 }
00237 size = avio_rb64(pb);
00238 if (size != 32)
00239 return AVERROR_INVALIDDATA;
00240
00241 ret = read_desc_chunk(s);
00242 if (ret)
00243 return ret;
00244 st = s->streams[0];
00245
00246
00247 found_data = 0;
00248 while (!url_feof(pb)) {
00249
00250
00251
00252 if (found_data && (caf->data_size < 0 || !pb->seekable))
00253 break;
00254
00255 tag = avio_rb32(pb);
00256 size = avio_rb64(pb);
00257 if (url_feof(pb))
00258 break;
00259
00260 switch (tag) {
00261 case MKBETAG('d','a','t','a'):
00262 avio_skip(pb, 4);
00263 caf->data_start = avio_tell(pb);
00264 caf->data_size = size < 0 ? -1 : size - 4;
00265 if (caf->data_size > 0 && pb->seekable)
00266 avio_skip(pb, caf->data_size);
00267 found_data = 1;
00268 break;
00269
00270 case MKBETAG('c','h','a','n'):
00271 if ((ret = ff_mov_read_chan(s, s->pb, st, size)) < 0)
00272 return ret;
00273 break;
00274
00275
00276 case MKBETAG('k','u','k','i'):
00277 if (read_kuki_chunk(s, size))
00278 return AVERROR_INVALIDDATA;
00279 break;
00280
00281
00282 case MKBETAG('p','a','k','t'):
00283 if (read_pakt_chunk(s, size))
00284 return AVERROR_INVALIDDATA;
00285 break;
00286
00287 case MKBETAG('i','n','f','o'):
00288 read_info_chunk(s, size);
00289 break;
00290
00291 default:
00292 #define _(x) ((x) >= ' ' ? (x) : ' ')
00293 av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c), size %"PRId64"\n",
00294 tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF), size);
00295 #undef _
00296 case MKBETAG('f','r','e','e'):
00297 if (size < 0)
00298 return AVERROR_INVALIDDATA;
00299 avio_skip(pb, size);
00300 break;
00301 }
00302 }
00303
00304 if (!found_data)
00305 return AVERROR_INVALIDDATA;
00306
00307 if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) {
00308 if (caf->data_size > 0)
00309 st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet;
00310 } else if (st->nb_index_entries) {
00311 st->codec->bit_rate = st->codec->sample_rate * caf->data_size * 8 /
00312 st->duration;
00313 } else {
00314 av_log(s, AV_LOG_ERROR, "Missing packet table. It is required when "
00315 "block size or frame size are variable.\n");
00316 return AVERROR_INVALIDDATA;
00317 }
00318
00319 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00320 st->start_time = 0;
00321
00322
00323 if (caf->data_size >= 0)
00324 avio_seek(pb, caf->data_start, SEEK_SET);
00325
00326 return 0;
00327 }
00328
00329 #define CAF_MAX_PKT_SIZE 4096
00330
00331 static int read_packet(AVFormatContext *s, AVPacket *pkt)
00332 {
00333 AVIOContext *pb = s->pb;
00334 AVStream *st = s->streams[0];
00335 CaffContext *caf = s->priv_data;
00336 int res, pkt_size = 0, pkt_frames = 0;
00337 int64_t left = CAF_MAX_PKT_SIZE;
00338
00339 if (url_feof(pb))
00340 return AVERROR(EIO);
00341
00342
00343 if (caf->data_size > 0) {
00344 left = (caf->data_start + caf->data_size) - avio_tell(pb);
00345 if (left <= 0)
00346 return AVERROR(EIO);
00347 }
00348
00349 pkt_frames = caf->frames_per_packet;
00350 pkt_size = caf->bytes_per_packet;
00351
00352 if (pkt_size > 0 && pkt_frames == 1) {
00353 pkt_size = (CAF_MAX_PKT_SIZE / pkt_size) * pkt_size;
00354 pkt_size = FFMIN(pkt_size, left);
00355 pkt_frames = pkt_size / caf->bytes_per_packet;
00356 } else if (st->nb_index_entries) {
00357 if (caf->packet_cnt < st->nb_index_entries - 1) {
00358 pkt_size = st->index_entries[caf->packet_cnt + 1].pos - st->index_entries[caf->packet_cnt].pos;
00359 pkt_frames = st->index_entries[caf->packet_cnt + 1].timestamp - st->index_entries[caf->packet_cnt].timestamp;
00360 } else if (caf->packet_cnt == st->nb_index_entries - 1) {
00361 pkt_size = caf->num_bytes - st->index_entries[caf->packet_cnt].pos;
00362 pkt_frames = st->duration - st->index_entries[caf->packet_cnt].timestamp;
00363 } else {
00364 return AVERROR(EIO);
00365 }
00366 }
00367
00368 if (pkt_size == 0 || pkt_frames == 0 || pkt_size > left)
00369 return AVERROR(EIO);
00370
00371 res = av_get_packet(pb, pkt, pkt_size);
00372 if (res < 0)
00373 return res;
00374
00375 pkt->size = res;
00376 pkt->stream_index = 0;
00377 pkt->dts = pkt->pts = caf->frame_cnt;
00378
00379 caf->packet_cnt++;
00380 caf->frame_cnt += pkt_frames;
00381
00382 return 0;
00383 }
00384
00385 static int read_seek(AVFormatContext *s, int stream_index,
00386 int64_t timestamp, int flags)
00387 {
00388 AVStream *st = s->streams[0];
00389 CaffContext *caf = s->priv_data;
00390 int64_t pos, packet_cnt, frame_cnt;
00391
00392 timestamp = FFMAX(timestamp, 0);
00393
00394 if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) {
00395
00396 pos = caf->bytes_per_packet * timestamp / caf->frames_per_packet;
00397 if (caf->data_size > 0)
00398 pos = FFMIN(pos, caf->data_size);
00399 packet_cnt = pos / caf->bytes_per_packet;
00400 frame_cnt = caf->frames_per_packet * packet_cnt;
00401 } else if (st->nb_index_entries) {
00402 packet_cnt = av_index_search_timestamp(st, timestamp, flags);
00403 frame_cnt = st->index_entries[packet_cnt].timestamp;
00404 pos = st->index_entries[packet_cnt].pos;
00405 } else {
00406 return -1;
00407 }
00408
00409 if (avio_seek(s->pb, pos + caf->data_start, SEEK_SET) < 0)
00410 return -1;
00411
00412 caf->packet_cnt = packet_cnt;
00413 caf->frame_cnt = frame_cnt;
00414
00415 return 0;
00416 }
00417
00418 AVInputFormat ff_caf_demuxer = {
00419 .name = "caf",
00420 .long_name = NULL_IF_CONFIG_SMALL("Apple CAF (Core Audio Format)"),
00421 .priv_data_size = sizeof(CaffContext),
00422 .read_probe = probe,
00423 .read_header = read_header,
00424 .read_packet = read_packet,
00425 .read_seek = read_seek,
00426 .codec_tag = (const AVCodecTag* const []){ ff_codec_caf_tags, 0 },
00427 };