1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Core Audio Format demuxer
3cabdff1aSopenharmony_ci * Copyright (c) 2007 Justin Ruggles
4cabdff1aSopenharmony_ci * Copyright (c) 2009 Peter Ross
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * This file is part of FFmpeg.
7cabdff1aSopenharmony_ci *
8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
12cabdff1aSopenharmony_ci *
13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16cabdff1aSopenharmony_ci * Lesser General Public License for more details.
17cabdff1aSopenharmony_ci *
18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21cabdff1aSopenharmony_ci */
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci/**
24cabdff1aSopenharmony_ci * @file
25cabdff1aSopenharmony_ci * Core Audio Format demuxer
26cabdff1aSopenharmony_ci */
27cabdff1aSopenharmony_ci
28cabdff1aSopenharmony_ci#include <inttypes.h>
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_ci#include "avformat.h"
31cabdff1aSopenharmony_ci#include "demux.h"
32cabdff1aSopenharmony_ci#include "internal.h"
33cabdff1aSopenharmony_ci#include "isom.h"
34cabdff1aSopenharmony_ci#include "mov_chan.h"
35cabdff1aSopenharmony_ci#include "libavcodec/flac.h"
36cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h"
37cabdff1aSopenharmony_ci#include "libavutil/intfloat.h"
38cabdff1aSopenharmony_ci#include "libavutil/dict.h"
39cabdff1aSopenharmony_ci#include "caf.h"
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_citypedef struct CafContext {
42cabdff1aSopenharmony_ci    int bytes_per_packet;           ///< bytes in a packet, or 0 if variable
43cabdff1aSopenharmony_ci    int frames_per_packet;          ///< frames in a packet, or 0 if variable
44cabdff1aSopenharmony_ci    int64_t num_bytes;              ///< total number of bytes in stream
45cabdff1aSopenharmony_ci
46cabdff1aSopenharmony_ci    int64_t packet_cnt;             ///< packet counter
47cabdff1aSopenharmony_ci    int64_t frame_cnt;              ///< frame counter
48cabdff1aSopenharmony_ci
49cabdff1aSopenharmony_ci    int64_t data_start;             ///< data start position, in bytes
50cabdff1aSopenharmony_ci    int64_t data_size;              ///< raw data size, in bytes
51cabdff1aSopenharmony_ci} CafContext;
52cabdff1aSopenharmony_ci
53cabdff1aSopenharmony_cistatic int probe(const AVProbeData *p)
54cabdff1aSopenharmony_ci{
55cabdff1aSopenharmony_ci    if (AV_RB32(p->buf) == MKBETAG('c','a','f','f') && AV_RB16(&p->buf[4]) == 1)
56cabdff1aSopenharmony_ci        return AVPROBE_SCORE_MAX;
57cabdff1aSopenharmony_ci    return 0;
58cabdff1aSopenharmony_ci}
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_ci/** Read audio description chunk */
61cabdff1aSopenharmony_cistatic int read_desc_chunk(AVFormatContext *s)
62cabdff1aSopenharmony_ci{
63cabdff1aSopenharmony_ci    AVIOContext *pb = s->pb;
64cabdff1aSopenharmony_ci    CafContext *caf = s->priv_data;
65cabdff1aSopenharmony_ci    AVStream *st;
66cabdff1aSopenharmony_ci    int flags;
67cabdff1aSopenharmony_ci
68cabdff1aSopenharmony_ci    /* new audio stream */
69cabdff1aSopenharmony_ci    st = avformat_new_stream(s, NULL);
70cabdff1aSopenharmony_ci    if (!st)
71cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_ci    /* parse format description */
74cabdff1aSopenharmony_ci    st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
75cabdff1aSopenharmony_ci    st->codecpar->sample_rate = av_clipd(av_int2double(avio_rb64(pb)), 0, INT_MAX);
76cabdff1aSopenharmony_ci    st->codecpar->codec_tag   = avio_rl32(pb);
77cabdff1aSopenharmony_ci    flags = avio_rb32(pb);
78cabdff1aSopenharmony_ci    caf->bytes_per_packet  = avio_rb32(pb);
79cabdff1aSopenharmony_ci    st->codecpar->block_align = caf->bytes_per_packet;
80cabdff1aSopenharmony_ci    caf->frames_per_packet = avio_rb32(pb);
81cabdff1aSopenharmony_ci    st->codecpar->ch_layout.nb_channels = avio_rb32(pb);
82cabdff1aSopenharmony_ci    st->codecpar->bits_per_coded_sample = avio_rb32(pb);
83cabdff1aSopenharmony_ci
84cabdff1aSopenharmony_ci    if (caf->bytes_per_packet < 0 || caf->frames_per_packet < 0 || st->codecpar->ch_layout.nb_channels < 0)
85cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
86cabdff1aSopenharmony_ci
87cabdff1aSopenharmony_ci    /* calculate bit rate for constant size packets */
88cabdff1aSopenharmony_ci    if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) {
89cabdff1aSopenharmony_ci        st->codecpar->bit_rate = (uint64_t)st->codecpar->sample_rate * (uint64_t)caf->bytes_per_packet * 8
90cabdff1aSopenharmony_ci                                 / (uint64_t)caf->frames_per_packet;
91cabdff1aSopenharmony_ci    } else {
92cabdff1aSopenharmony_ci        st->codecpar->bit_rate = 0;
93cabdff1aSopenharmony_ci    }
94cabdff1aSopenharmony_ci
95cabdff1aSopenharmony_ci    /* determine codec */
96cabdff1aSopenharmony_ci    if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
97cabdff1aSopenharmony_ci        st->codecpar->codec_id = ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample, (flags ^ 0x2) | 0x4);
98cabdff1aSopenharmony_ci    else
99cabdff1aSopenharmony_ci        st->codecpar->codec_id = ff_codec_get_id(ff_codec_caf_tags, st->codecpar->codec_tag);
100cabdff1aSopenharmony_ci    return 0;
101cabdff1aSopenharmony_ci}
102cabdff1aSopenharmony_ci
103cabdff1aSopenharmony_ci/** Read magic cookie chunk */
104cabdff1aSopenharmony_cistatic int read_kuki_chunk(AVFormatContext *s, int64_t size)
105cabdff1aSopenharmony_ci{
106cabdff1aSopenharmony_ci    AVIOContext *pb = s->pb;
107cabdff1aSopenharmony_ci    AVStream *st      = s->streams[0];
108cabdff1aSopenharmony_ci    int ret;
109cabdff1aSopenharmony_ci
110cabdff1aSopenharmony_ci    if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
111cabdff1aSopenharmony_ci        return -1;
112cabdff1aSopenharmony_ci
113cabdff1aSopenharmony_ci    if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
114cabdff1aSopenharmony_ci        /* The magic cookie format for AAC is an mp4 esds atom.
115cabdff1aSopenharmony_ci           The lavc AAC decoder requires the data from the codec specific
116cabdff1aSopenharmony_ci           description as extradata input. */
117cabdff1aSopenharmony_ci        int strt, skip;
118cabdff1aSopenharmony_ci
119cabdff1aSopenharmony_ci        strt = avio_tell(pb);
120cabdff1aSopenharmony_ci        ff_mov_read_esds(s, pb);
121cabdff1aSopenharmony_ci        skip = size - (avio_tell(pb) - strt);
122cabdff1aSopenharmony_ci        if (skip < 0 || !st->codecpar->extradata ||
123cabdff1aSopenharmony_ci            st->codecpar->codec_id != AV_CODEC_ID_AAC) {
124cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "invalid AAC magic cookie\n");
125cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
126cabdff1aSopenharmony_ci        }
127cabdff1aSopenharmony_ci        avio_skip(pb, skip);
128cabdff1aSopenharmony_ci    } else if (st->codecpar->codec_id == AV_CODEC_ID_ALAC) {
129cabdff1aSopenharmony_ci#define ALAC_PREAMBLE 12
130cabdff1aSopenharmony_ci#define ALAC_HEADER   36
131cabdff1aSopenharmony_ci#define ALAC_NEW_KUKI 24
132cabdff1aSopenharmony_ci        uint8_t preamble[12];
133cabdff1aSopenharmony_ci        if (size < ALAC_NEW_KUKI) {
134cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
135cabdff1aSopenharmony_ci            avio_skip(pb, size);
136cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
137cabdff1aSopenharmony_ci        }
138cabdff1aSopenharmony_ci        if (avio_read(pb, preamble, ALAC_PREAMBLE) != ALAC_PREAMBLE) {
139cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "failed to read preamble\n");
140cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
141cabdff1aSopenharmony_ci        }
142cabdff1aSopenharmony_ci
143cabdff1aSopenharmony_ci        if ((ret = ff_alloc_extradata(st->codecpar, ALAC_HEADER)) < 0)
144cabdff1aSopenharmony_ci            return ret;
145cabdff1aSopenharmony_ci
146cabdff1aSopenharmony_ci        /* For the old style cookie, we skip 12 bytes, then read 36 bytes.
147cabdff1aSopenharmony_ci         * The new style cookie only contains the last 24 bytes of what was
148cabdff1aSopenharmony_ci         * 36 bytes in the old style cookie, so we fabricate the first 12 bytes
149cabdff1aSopenharmony_ci         * in that case to maintain compatibility. */
150cabdff1aSopenharmony_ci        if (!memcmp(&preamble[4], "frmaalac", 8)) {
151cabdff1aSopenharmony_ci            if (size < ALAC_PREAMBLE + ALAC_HEADER) {
152cabdff1aSopenharmony_ci                av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
153cabdff1aSopenharmony_ci                av_freep(&st->codecpar->extradata);
154cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
155cabdff1aSopenharmony_ci            }
156cabdff1aSopenharmony_ci            if (avio_read(pb, st->codecpar->extradata, ALAC_HEADER) != ALAC_HEADER) {
157cabdff1aSopenharmony_ci                av_log(s, AV_LOG_ERROR, "failed to read kuki header\n");
158cabdff1aSopenharmony_ci                av_freep(&st->codecpar->extradata);
159cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
160cabdff1aSopenharmony_ci            }
161cabdff1aSopenharmony_ci            avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER);
162cabdff1aSopenharmony_ci        } else {
163cabdff1aSopenharmony_ci            AV_WB32(st->codecpar->extradata, 36);
164cabdff1aSopenharmony_ci            memcpy(&st->codecpar->extradata[4], "alac", 4);
165cabdff1aSopenharmony_ci            AV_WB32(&st->codecpar->extradata[8], 0);
166cabdff1aSopenharmony_ci            memcpy(&st->codecpar->extradata[12], preamble, 12);
167cabdff1aSopenharmony_ci            if (avio_read(pb, &st->codecpar->extradata[24], ALAC_NEW_KUKI - 12) != ALAC_NEW_KUKI - 12) {
168cabdff1aSopenharmony_ci                av_log(s, AV_LOG_ERROR, "failed to read new kuki header\n");
169cabdff1aSopenharmony_ci                av_freep(&st->codecpar->extradata);
170cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
171cabdff1aSopenharmony_ci            }
172cabdff1aSopenharmony_ci            avio_skip(pb, size - ALAC_NEW_KUKI);
173cabdff1aSopenharmony_ci        }
174cabdff1aSopenharmony_ci    } else if (st->codecpar->codec_id == AV_CODEC_ID_FLAC) {
175cabdff1aSopenharmony_ci        int last, type, flac_metadata_size;
176cabdff1aSopenharmony_ci        uint8_t buf[4];
177cabdff1aSopenharmony_ci        /* The magic cookie format for FLAC consists mostly of an mp4 dfLa atom. */
178cabdff1aSopenharmony_ci        if (size < (16 + FLAC_STREAMINFO_SIZE)) {
179cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "invalid FLAC magic cookie\n");
180cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
181cabdff1aSopenharmony_ci        }
182cabdff1aSopenharmony_ci        /* Check cookie version. */
183cabdff1aSopenharmony_ci        if (avio_r8(pb) != 0) {
184cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "unknown FLAC magic cookie\n");
185cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
186cabdff1aSopenharmony_ci        }
187cabdff1aSopenharmony_ci        avio_rb24(pb); /* Flags */
188cabdff1aSopenharmony_ci        /* read dfLa fourcc */
189cabdff1aSopenharmony_ci        if (avio_read(pb, buf, 4) != 4) {
190cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "failed to read FLAC magic cookie\n");
191cabdff1aSopenharmony_ci            return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
192cabdff1aSopenharmony_ci        }
193cabdff1aSopenharmony_ci        if (memcmp(buf, "dfLa", 4)) {
194cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "invalid FLAC magic cookie\n");
195cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
196cabdff1aSopenharmony_ci        }
197cabdff1aSopenharmony_ci        /* Check dfLa version. */
198cabdff1aSopenharmony_ci        if (avio_r8(pb) != 0) {
199cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "unknown dfLa version\n");
200cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
201cabdff1aSopenharmony_ci        }
202cabdff1aSopenharmony_ci        avio_rb24(pb); /* Flags */
203cabdff1aSopenharmony_ci        if (avio_read(pb, buf, sizeof(buf)) != sizeof(buf)) {
204cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "failed to read FLAC metadata block header\n");
205cabdff1aSopenharmony_ci            return pb->error < 0 ? pb->error : AVERROR_INVALIDDATA;
206cabdff1aSopenharmony_ci        }
207cabdff1aSopenharmony_ci        flac_parse_block_header(buf, &last, &type, &flac_metadata_size);
208cabdff1aSopenharmony_ci        if (type != FLAC_METADATA_TYPE_STREAMINFO || flac_metadata_size != FLAC_STREAMINFO_SIZE) {
209cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "STREAMINFO must be first FLACMetadataBlock\n");
210cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
211cabdff1aSopenharmony_ci        }
212cabdff1aSopenharmony_ci        ret = ff_get_extradata(s, st->codecpar, pb, FLAC_STREAMINFO_SIZE);
213cabdff1aSopenharmony_ci        if (ret < 0)
214cabdff1aSopenharmony_ci            return ret;
215cabdff1aSopenharmony_ci        if (!last)
216cabdff1aSopenharmony_ci            av_log(s, AV_LOG_WARNING, "non-STREAMINFO FLACMetadataBlock(s) ignored\n");
217cabdff1aSopenharmony_ci    } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) {
218cabdff1aSopenharmony_ci        // The data layout for Opus is currently unknown, so we do not export
219cabdff1aSopenharmony_ci        // extradata at all. Multichannel streams are not supported.
220cabdff1aSopenharmony_ci        if (st->codecpar->ch_layout.nb_channels > 2) {
221cabdff1aSopenharmony_ci            avpriv_request_sample(s, "multichannel Opus in CAF");
222cabdff1aSopenharmony_ci            return AVERROR_PATCHWELCOME;
223cabdff1aSopenharmony_ci        }
224cabdff1aSopenharmony_ci        avio_skip(pb, size);
225cabdff1aSopenharmony_ci    } else if ((ret = ff_get_extradata(s, st->codecpar, pb, size)) < 0) {
226cabdff1aSopenharmony_ci        return ret;
227cabdff1aSopenharmony_ci    }
228cabdff1aSopenharmony_ci
229cabdff1aSopenharmony_ci    return 0;
230cabdff1aSopenharmony_ci}
231cabdff1aSopenharmony_ci
232cabdff1aSopenharmony_ci/** Read packet table chunk */
233cabdff1aSopenharmony_cistatic int read_pakt_chunk(AVFormatContext *s, int64_t size)
234cabdff1aSopenharmony_ci{
235cabdff1aSopenharmony_ci    AVIOContext *pb = s->pb;
236cabdff1aSopenharmony_ci    AVStream *st      = s->streams[0];
237cabdff1aSopenharmony_ci    CafContext *caf   = s->priv_data;
238cabdff1aSopenharmony_ci    int64_t pos = 0, ccount, num_packets;
239cabdff1aSopenharmony_ci    int i;
240cabdff1aSopenharmony_ci    int ret;
241cabdff1aSopenharmony_ci
242cabdff1aSopenharmony_ci    ccount = avio_tell(pb);
243cabdff1aSopenharmony_ci
244cabdff1aSopenharmony_ci    num_packets = avio_rb64(pb);
245cabdff1aSopenharmony_ci    if (num_packets < 0 || INT32_MAX / sizeof(AVIndexEntry) < num_packets)
246cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
247cabdff1aSopenharmony_ci
248cabdff1aSopenharmony_ci    st->nb_frames  = avio_rb64(pb); /* valid frames */
249cabdff1aSopenharmony_ci    st->nb_frames += avio_rb32(pb); /* priming frames */
250cabdff1aSopenharmony_ci    st->nb_frames += avio_rb32(pb); /* remainder frames */
251cabdff1aSopenharmony_ci
252cabdff1aSopenharmony_ci    if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) {
253cabdff1aSopenharmony_ci        st->duration = caf->frames_per_packet * num_packets;
254cabdff1aSopenharmony_ci        pos          = caf-> bytes_per_packet * num_packets;
255cabdff1aSopenharmony_ci    } else {
256cabdff1aSopenharmony_ci        st->duration = 0;
257cabdff1aSopenharmony_ci        for (i = 0; i < num_packets; i++) {
258cabdff1aSopenharmony_ci            if (avio_feof(pb))
259cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
260cabdff1aSopenharmony_ci            ret = av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME);
261cabdff1aSopenharmony_ci            if (ret < 0)
262cabdff1aSopenharmony_ci                return ret;
263cabdff1aSopenharmony_ci            pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb);
264cabdff1aSopenharmony_ci            st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb);
265cabdff1aSopenharmony_ci        }
266cabdff1aSopenharmony_ci    }
267cabdff1aSopenharmony_ci
268cabdff1aSopenharmony_ci    if (avio_tell(pb) - ccount > size) {
269cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "error reading packet table\n");
270cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
271cabdff1aSopenharmony_ci    }
272cabdff1aSopenharmony_ci    avio_seek(pb, ccount + size, SEEK_SET);
273cabdff1aSopenharmony_ci
274cabdff1aSopenharmony_ci    caf->num_bytes = pos;
275cabdff1aSopenharmony_ci    return 0;
276cabdff1aSopenharmony_ci}
277cabdff1aSopenharmony_ci
278cabdff1aSopenharmony_ci/** Read information chunk */
279cabdff1aSopenharmony_cistatic void read_info_chunk(AVFormatContext *s, int64_t size)
280cabdff1aSopenharmony_ci{
281cabdff1aSopenharmony_ci    AVIOContext *pb = s->pb;
282cabdff1aSopenharmony_ci    unsigned int i;
283cabdff1aSopenharmony_ci    unsigned int nb_entries = avio_rb32(pb);
284cabdff1aSopenharmony_ci    for (i = 0; i < nb_entries && !avio_feof(pb); i++) {
285cabdff1aSopenharmony_ci        char key[32];
286cabdff1aSopenharmony_ci        char value[1024];
287cabdff1aSopenharmony_ci        avio_get_str(pb, INT_MAX, key, sizeof(key));
288cabdff1aSopenharmony_ci        avio_get_str(pb, INT_MAX, value, sizeof(value));
289cabdff1aSopenharmony_ci        if (!*key)
290cabdff1aSopenharmony_ci            continue;
291cabdff1aSopenharmony_ci        av_dict_set(&s->metadata, key, value, 0);
292cabdff1aSopenharmony_ci    }
293cabdff1aSopenharmony_ci}
294cabdff1aSopenharmony_ci
295cabdff1aSopenharmony_cistatic int read_header(AVFormatContext *s)
296cabdff1aSopenharmony_ci{
297cabdff1aSopenharmony_ci    AVIOContext *pb = s->pb;
298cabdff1aSopenharmony_ci    CafContext *caf = s->priv_data;
299cabdff1aSopenharmony_ci    AVStream *st;
300cabdff1aSopenharmony_ci    uint32_t tag = 0;
301cabdff1aSopenharmony_ci    int found_data, ret;
302cabdff1aSopenharmony_ci    int64_t size, pos;
303cabdff1aSopenharmony_ci
304cabdff1aSopenharmony_ci    avio_skip(pb, 8); /* magic, version, file flags */
305cabdff1aSopenharmony_ci
306cabdff1aSopenharmony_ci    /* audio description chunk */
307cabdff1aSopenharmony_ci    if (avio_rb32(pb) != MKBETAG('d','e','s','c')) {
308cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "desc chunk not present\n");
309cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
310cabdff1aSopenharmony_ci    }
311cabdff1aSopenharmony_ci    size = avio_rb64(pb);
312cabdff1aSopenharmony_ci    if (size != 32)
313cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
314cabdff1aSopenharmony_ci
315cabdff1aSopenharmony_ci    ret = read_desc_chunk(s);
316cabdff1aSopenharmony_ci    if (ret)
317cabdff1aSopenharmony_ci        return ret;
318cabdff1aSopenharmony_ci    st = s->streams[0];
319cabdff1aSopenharmony_ci
320cabdff1aSopenharmony_ci    /* parse each chunk */
321cabdff1aSopenharmony_ci    found_data = 0;
322cabdff1aSopenharmony_ci    while (!avio_feof(pb)) {
323cabdff1aSopenharmony_ci
324cabdff1aSopenharmony_ci        /* stop at data chunk if seeking is not supported or
325cabdff1aSopenharmony_ci           data chunk size is unknown */
326cabdff1aSopenharmony_ci        if (found_data && (caf->data_size < 0 || !(pb->seekable & AVIO_SEEKABLE_NORMAL)))
327cabdff1aSopenharmony_ci            break;
328cabdff1aSopenharmony_ci
329cabdff1aSopenharmony_ci        tag  = avio_rb32(pb);
330cabdff1aSopenharmony_ci        size = avio_rb64(pb);
331cabdff1aSopenharmony_ci        pos  = avio_tell(pb);
332cabdff1aSopenharmony_ci        if (avio_feof(pb))
333cabdff1aSopenharmony_ci            break;
334cabdff1aSopenharmony_ci
335cabdff1aSopenharmony_ci        switch (tag) {
336cabdff1aSopenharmony_ci        case MKBETAG('d','a','t','a'):
337cabdff1aSopenharmony_ci            avio_skip(pb, 4); /* edit count */
338cabdff1aSopenharmony_ci            caf->data_start = avio_tell(pb);
339cabdff1aSopenharmony_ci            caf->data_size  = size < 0 ? -1 : size - 4;
340cabdff1aSopenharmony_ci            if (caf->data_size > 0 && (pb->seekable & AVIO_SEEKABLE_NORMAL))
341cabdff1aSopenharmony_ci                avio_skip(pb, caf->data_size);
342cabdff1aSopenharmony_ci            found_data = 1;
343cabdff1aSopenharmony_ci            break;
344cabdff1aSopenharmony_ci
345cabdff1aSopenharmony_ci        case MKBETAG('c','h','a','n'):
346cabdff1aSopenharmony_ci            if ((ret = ff_mov_read_chan(s, s->pb, st, size)) < 0)
347cabdff1aSopenharmony_ci                return ret;
348cabdff1aSopenharmony_ci            break;
349cabdff1aSopenharmony_ci
350cabdff1aSopenharmony_ci        /* magic cookie chunk */
351cabdff1aSopenharmony_ci        case MKBETAG('k','u','k','i'):
352cabdff1aSopenharmony_ci            if (read_kuki_chunk(s, size))
353cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
354cabdff1aSopenharmony_ci            break;
355cabdff1aSopenharmony_ci
356cabdff1aSopenharmony_ci        /* packet table chunk */
357cabdff1aSopenharmony_ci        case MKBETAG('p','a','k','t'):
358cabdff1aSopenharmony_ci            if (read_pakt_chunk(s, size))
359cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
360cabdff1aSopenharmony_ci            break;
361cabdff1aSopenharmony_ci
362cabdff1aSopenharmony_ci        case MKBETAG('i','n','f','o'):
363cabdff1aSopenharmony_ci            read_info_chunk(s, size);
364cabdff1aSopenharmony_ci            break;
365cabdff1aSopenharmony_ci
366cabdff1aSopenharmony_ci        default:
367cabdff1aSopenharmony_ci            av_log(s, AV_LOG_WARNING,
368cabdff1aSopenharmony_ci                   "skipping CAF chunk: %08"PRIX32" (%s), size %"PRId64"\n",
369cabdff1aSopenharmony_ci                   tag, av_fourcc2str(av_bswap32(tag)), size);
370cabdff1aSopenharmony_ci        case MKBETAG('f','r','e','e'):
371cabdff1aSopenharmony_ci            if (size < 0 && found_data)
372cabdff1aSopenharmony_ci                goto found_data;
373cabdff1aSopenharmony_ci            if (size < 0)
374cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
375cabdff1aSopenharmony_ci            break;
376cabdff1aSopenharmony_ci        }
377cabdff1aSopenharmony_ci
378cabdff1aSopenharmony_ci        if (size > 0 && (pb->seekable & AVIO_SEEKABLE_NORMAL)) {
379cabdff1aSopenharmony_ci            if (pos > INT64_MAX - size)
380cabdff1aSopenharmony_ci                return AVERROR_INVALIDDATA;
381cabdff1aSopenharmony_ci            avio_seek(pb, pos + size, SEEK_SET);
382cabdff1aSopenharmony_ci        }
383cabdff1aSopenharmony_ci    }
384cabdff1aSopenharmony_ci
385cabdff1aSopenharmony_ci    if (!found_data)
386cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
387cabdff1aSopenharmony_ci
388cabdff1aSopenharmony_cifound_data:
389cabdff1aSopenharmony_ci    if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) {
390cabdff1aSopenharmony_ci        if (caf->data_size > 0 && caf->data_size / caf->bytes_per_packet < INT64_MAX / caf->frames_per_packet)
391cabdff1aSopenharmony_ci            st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet;
392cabdff1aSopenharmony_ci    } else if (ffstream(st)->nb_index_entries && st->duration > 0) {
393cabdff1aSopenharmony_ci        if (st->codecpar->sample_rate && caf->data_size / st->duration > INT64_MAX / st->codecpar->sample_rate / 8) {
394cabdff1aSopenharmony_ci            av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %d * 8 * %"PRId64"\n",
395cabdff1aSopenharmony_ci                   st->codecpar->sample_rate, caf->data_size / st->duration);
396cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
397cabdff1aSopenharmony_ci        }
398cabdff1aSopenharmony_ci        st->codecpar->bit_rate = st->codecpar->sample_rate * 8LL *
399cabdff1aSopenharmony_ci                                 (caf->data_size / st->duration);
400cabdff1aSopenharmony_ci    } else {
401cabdff1aSopenharmony_ci        av_log(s, AV_LOG_ERROR, "Missing packet table. It is required when "
402cabdff1aSopenharmony_ci                                "block size or frame size are variable.\n");
403cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
404cabdff1aSopenharmony_ci    }
405cabdff1aSopenharmony_ci
406cabdff1aSopenharmony_ci    avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
407cabdff1aSopenharmony_ci    st->start_time = 0;
408cabdff1aSopenharmony_ci
409cabdff1aSopenharmony_ci    /* position the stream at the start of data */
410cabdff1aSopenharmony_ci    if (caf->data_size >= 0)
411cabdff1aSopenharmony_ci        avio_seek(pb, caf->data_start, SEEK_SET);
412cabdff1aSopenharmony_ci
413cabdff1aSopenharmony_ci    return 0;
414cabdff1aSopenharmony_ci}
415cabdff1aSopenharmony_ci
416cabdff1aSopenharmony_ci#define CAF_MAX_PKT_SIZE 4096
417cabdff1aSopenharmony_ci
418cabdff1aSopenharmony_cistatic int read_packet(AVFormatContext *s, AVPacket *pkt)
419cabdff1aSopenharmony_ci{
420cabdff1aSopenharmony_ci    AVIOContext *pb = s->pb;
421cabdff1aSopenharmony_ci    AVStream *st      = s->streams[0];
422cabdff1aSopenharmony_ci    FFStream *const sti = ffstream(st);
423cabdff1aSopenharmony_ci    CafContext *caf   = s->priv_data;
424cabdff1aSopenharmony_ci    int res, pkt_size = 0, pkt_frames = 0;
425cabdff1aSopenharmony_ci    int64_t left      = CAF_MAX_PKT_SIZE;
426cabdff1aSopenharmony_ci
427cabdff1aSopenharmony_ci    if (avio_feof(pb))
428cabdff1aSopenharmony_ci        return AVERROR_EOF;
429cabdff1aSopenharmony_ci
430cabdff1aSopenharmony_ci    /* don't read past end of data chunk */
431cabdff1aSopenharmony_ci    if (caf->data_size > 0) {
432cabdff1aSopenharmony_ci        left = (caf->data_start + caf->data_size) - avio_tell(pb);
433cabdff1aSopenharmony_ci        if (!left)
434cabdff1aSopenharmony_ci            return AVERROR_EOF;
435cabdff1aSopenharmony_ci        if (left < 0)
436cabdff1aSopenharmony_ci            return AVERROR(EIO);
437cabdff1aSopenharmony_ci    }
438cabdff1aSopenharmony_ci
439cabdff1aSopenharmony_ci    pkt_frames = caf->frames_per_packet;
440cabdff1aSopenharmony_ci    pkt_size   = caf->bytes_per_packet;
441cabdff1aSopenharmony_ci
442cabdff1aSopenharmony_ci    if (pkt_size > 0 && pkt_frames == 1) {
443cabdff1aSopenharmony_ci        pkt_size   = (CAF_MAX_PKT_SIZE / pkt_size) * pkt_size;
444cabdff1aSopenharmony_ci        pkt_size   = FFMIN(pkt_size, left);
445cabdff1aSopenharmony_ci        pkt_frames = pkt_size / caf->bytes_per_packet;
446cabdff1aSopenharmony_ci    } else if (sti->nb_index_entries) {
447cabdff1aSopenharmony_ci        if (caf->packet_cnt < sti->nb_index_entries - 1) {
448cabdff1aSopenharmony_ci            pkt_size   = sti->index_entries[caf->packet_cnt + 1].pos       - sti->index_entries[caf->packet_cnt].pos;
449cabdff1aSopenharmony_ci            pkt_frames = sti->index_entries[caf->packet_cnt + 1].timestamp - sti->index_entries[caf->packet_cnt].timestamp;
450cabdff1aSopenharmony_ci        } else if (caf->packet_cnt == sti->nb_index_entries - 1) {
451cabdff1aSopenharmony_ci            pkt_size   = caf->num_bytes - sti->index_entries[caf->packet_cnt].pos;
452cabdff1aSopenharmony_ci            pkt_frames = st->duration   - sti->index_entries[caf->packet_cnt].timestamp;
453cabdff1aSopenharmony_ci        } else {
454cabdff1aSopenharmony_ci            return AVERROR(EIO);
455cabdff1aSopenharmony_ci        }
456cabdff1aSopenharmony_ci    }
457cabdff1aSopenharmony_ci
458cabdff1aSopenharmony_ci    if (pkt_size == 0 || pkt_frames == 0 || pkt_size > left)
459cabdff1aSopenharmony_ci        return AVERROR(EIO);
460cabdff1aSopenharmony_ci
461cabdff1aSopenharmony_ci    res = av_get_packet(pb, pkt, pkt_size);
462cabdff1aSopenharmony_ci    if (res < 0)
463cabdff1aSopenharmony_ci        return res;
464cabdff1aSopenharmony_ci
465cabdff1aSopenharmony_ci    pkt->size           = res;
466cabdff1aSopenharmony_ci    pkt->stream_index   = 0;
467cabdff1aSopenharmony_ci    pkt->dts = pkt->pts = caf->frame_cnt;
468cabdff1aSopenharmony_ci
469cabdff1aSopenharmony_ci    caf->packet_cnt++;
470cabdff1aSopenharmony_ci    caf->frame_cnt += pkt_frames;
471cabdff1aSopenharmony_ci
472cabdff1aSopenharmony_ci    return 0;
473cabdff1aSopenharmony_ci}
474cabdff1aSopenharmony_ci
475cabdff1aSopenharmony_cistatic int read_seek(AVFormatContext *s, int stream_index,
476cabdff1aSopenharmony_ci                     int64_t timestamp, int flags)
477cabdff1aSopenharmony_ci{
478cabdff1aSopenharmony_ci    AVStream *st = s->streams[0];
479cabdff1aSopenharmony_ci    FFStream *const sti = ffstream(st);
480cabdff1aSopenharmony_ci    CafContext *caf = s->priv_data;
481cabdff1aSopenharmony_ci    int64_t pos, packet_cnt, frame_cnt;
482cabdff1aSopenharmony_ci
483cabdff1aSopenharmony_ci    timestamp = FFMAX(timestamp, 0);
484cabdff1aSopenharmony_ci
485cabdff1aSopenharmony_ci    if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) {
486cabdff1aSopenharmony_ci        /* calculate new byte position based on target frame position */
487cabdff1aSopenharmony_ci        pos = caf->bytes_per_packet * (timestamp / caf->frames_per_packet);
488cabdff1aSopenharmony_ci        if (caf->data_size > 0)
489cabdff1aSopenharmony_ci            pos = FFMIN(pos, caf->data_size);
490cabdff1aSopenharmony_ci        packet_cnt = pos / caf->bytes_per_packet;
491cabdff1aSopenharmony_ci        frame_cnt  = caf->frames_per_packet * packet_cnt;
492cabdff1aSopenharmony_ci    } else if (sti->nb_index_entries) {
493cabdff1aSopenharmony_ci        packet_cnt = av_index_search_timestamp(st, timestamp, flags);
494cabdff1aSopenharmony_ci        frame_cnt  = sti->index_entries[packet_cnt].timestamp;
495cabdff1aSopenharmony_ci        pos        = sti->index_entries[packet_cnt].pos;
496cabdff1aSopenharmony_ci    } else {
497cabdff1aSopenharmony_ci        return -1;
498cabdff1aSopenharmony_ci    }
499cabdff1aSopenharmony_ci
500cabdff1aSopenharmony_ci    if (avio_seek(s->pb, pos + caf->data_start, SEEK_SET) < 0)
501cabdff1aSopenharmony_ci        return -1;
502cabdff1aSopenharmony_ci
503cabdff1aSopenharmony_ci    caf->packet_cnt = packet_cnt;
504cabdff1aSopenharmony_ci    caf->frame_cnt  = frame_cnt;
505cabdff1aSopenharmony_ci
506cabdff1aSopenharmony_ci    return 0;
507cabdff1aSopenharmony_ci}
508cabdff1aSopenharmony_ci
509cabdff1aSopenharmony_ciconst AVInputFormat ff_caf_demuxer = {
510cabdff1aSopenharmony_ci    .name           = "caf",
511cabdff1aSopenharmony_ci    .long_name      = NULL_IF_CONFIG_SMALL("Apple CAF (Core Audio Format)"),
512cabdff1aSopenharmony_ci    .priv_data_size = sizeof(CafContext),
513cabdff1aSopenharmony_ci    .read_probe     = probe,
514cabdff1aSopenharmony_ci    .read_header    = read_header,
515cabdff1aSopenharmony_ci    .read_packet    = read_packet,
516cabdff1aSopenharmony_ci    .read_seek      = read_seek,
517cabdff1aSopenharmony_ci    .codec_tag      = ff_caf_codec_tags_list,
518cabdff1aSopenharmony_ci};
519