* Core Audio Format demuxer
*/
+#include <inttypes.h>
+
#include "avformat.h"
#include "internal.h"
-#include "riff.h"
#include "isom.h"
+#include "mov_chan.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/dict.h"
#include "caf.h"
-typedef struct {
+typedef struct CafContext {
int bytes_per_packet; ///< bytes in a packet, or 0 if variable
int frames_per_packet; ///< frames in a packet, or 0 if variable
int64_t num_bytes; ///< total number of bytes in stream
int64_t data_start; ///< data start position, in bytes
int64_t data_size; ///< raw data size, in bytes
-} CaffContext;
+} CafContext;
static int probe(AVProbeData *p)
{
static int read_desc_chunk(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
- CaffContext *caf = s->priv_data;
+ CafContext *caf = s->priv_data;
AVStream *st;
int flags;
if (size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
return -1;
- if (st->codec->codec_id == CODEC_ID_AAC) {
+ if (st->codec->codec_id == AV_CODEC_ID_AAC) {
/* The magic cookie format for AAC is an mp4 esds atom.
The lavc AAC decoder requires the data from the codec specific
description as extradata input. */
int strt, skip;
- MOVAtom atom;
strt = avio_tell(pb);
- ff_mov_read_esds(s, pb, atom);
+ ff_mov_read_esds(s, pb);
skip = size - (avio_tell(pb) - strt);
if (skip < 0 || !st->codec->extradata ||
- st->codec->codec_id != CODEC_ID_AAC) {
+ st->codec->codec_id != AV_CODEC_ID_AAC) {
av_log(s, AV_LOG_ERROR, "invalid AAC magic cookie\n");
return AVERROR_INVALIDDATA;
}
avio_skip(pb, skip);
- } else if (st->codec->codec_id == CODEC_ID_ALAC) {
+ } else if (st->codec->codec_id == AV_CODEC_ID_ALAC) {
#define ALAC_PREAMBLE 12
#define ALAC_HEADER 36
#define ALAC_NEW_KUKI 24
uint8_t preamble[12];
- if (size < ALAC_NEW_KUKI || size > ALAC_PREAMBLE + ALAC_HEADER) {
+ if (size < ALAC_NEW_KUKI) {
av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
avio_skip(pb, size);
return AVERROR_INVALIDDATA;
{
AVIOContext *pb = s->pb;
AVStream *st = s->streams[0];
- CaffContext *caf = s->priv_data;
- int64_t pos = 0, ccount;
- int num_packets, i;
+ CafContext *caf = s->priv_data;
+ int64_t pos = 0, ccount, num_packets;
+ int i;
ccount = avio_tell(pb);
st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb);
}
- if (avio_tell(pb) - ccount != size) {
+ if (avio_tell(pb) - ccount > size) {
av_log(s, AV_LOG_ERROR, "error reading packet table\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
+ avio_skip(pb, ccount + size - avio_tell(pb));
caf->num_bytes = pos;
return 0;
static int read_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
- CaffContext *caf = s->priv_data;
+ CafContext *caf = s->priv_data;
AVStream *st;
uint32_t tag = 0;
int found_data, ret;
found_data = 1;
break;
+ case MKBETAG('c','h','a','n'):
+ if ((ret = ff_mov_read_chan(s, s->pb, st, size)) < 0)
+ return ret;
+ break;
+
/* magic cookie chunk */
case MKBETAG('k','u','k','i'):
if (read_kuki_chunk(s, size))
default:
#define _(x) ((x) >= ' ' ? (x) : ' ')
- av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c)\n",
+ av_log(s, AV_LOG_WARNING,
+ "skipping CAF chunk: %08"PRIX32" (%"PRIu32"%"PRIu32"%"PRIu32"%"PRIu32")\n",
tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF));
#undef _
case MKBETAG('f','r','e','e'):
{
AVIOContext *pb = s->pb;
AVStream *st = s->streams[0];
- CaffContext *caf = s->priv_data;
+ CafContext *caf = s->priv_data;
int res, pkt_size = 0, pkt_frames = 0;
int64_t left = CAF_MAX_PKT_SIZE;
int64_t timestamp, int flags)
{
AVStream *st = s->streams[0];
- CaffContext *caf = s->priv_data;
+ CafContext *caf = s->priv_data;
int64_t pos, packet_cnt, frame_cnt;
timestamp = FFMAX(timestamp, 0);
AVInputFormat ff_caf_demuxer = {
.name = "caf",
- .long_name = NULL_IF_CONFIG_SMALL("Apple Core Audio Format"),
- .priv_data_size = sizeof(CaffContext),
+ .long_name = NULL_IF_CONFIG_SMALL("Apple CAF (Core Audio Format)"),
+ .priv_data_size = sizeof(CafContext),
.read_probe = probe,
.read_header = read_header,
.read_packet = read_packet,