~ubuntu-branches/ubuntu/trusty/gst-libav1.0/trusty-proposed

« back to all changes in this revision

Viewing changes to gst-libs/ext/libav/libavformat/cafdec.c

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2013-09-24 17:07:00 UTC
  • mfrom: (1.1.17) (7.1.9 experimental)
  • Revision ID: package-import@ubuntu.com-20130924170700-4dg62s3pwl0pdakz
Tags: 1.2.0-1
* New upstream stable release:
  + debian/control:
    - Build depend on GStreamer and gst-plugins-base >= 1.2.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 
28
28
#include "avformat.h"
29
29
#include "internal.h"
30
 
#include "riff.h"
31
30
#include "isom.h"
 
31
#include "mov_chan.h"
32
32
#include "libavutil/intreadwrite.h"
33
33
#include "libavutil/intfloat.h"
34
34
#include "libavutil/dict.h"
102
102
    if (size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
103
103
        return -1;
104
104
 
105
 
    if (st->codec->codec_id == CODEC_ID_AAC) {
 
105
    if (st->codec->codec_id == AV_CODEC_ID_AAC) {
106
106
        /* The magic cookie format for AAC is an mp4 esds atom.
107
107
           The lavc AAC decoder requires the data from the codec specific
108
108
           description as extradata input. */
113
113
        ff_mov_read_esds(s, pb, atom);
114
114
        skip = size - (avio_tell(pb) - strt);
115
115
        if (skip < 0 || !st->codec->extradata ||
116
 
            st->codec->codec_id != CODEC_ID_AAC) {
 
116
            st->codec->codec_id != AV_CODEC_ID_AAC) {
117
117
            av_log(s, AV_LOG_ERROR, "invalid AAC magic cookie\n");
118
118
            return AVERROR_INVALIDDATA;
119
119
        }
120
120
        avio_skip(pb, skip);
121
 
    } else if (st->codec->codec_id == CODEC_ID_ALAC) {
 
121
    } else if (st->codec->codec_id == AV_CODEC_ID_ALAC) {
122
122
#define ALAC_PREAMBLE 12
123
123
#define ALAC_HEADER   36
124
 
        if (size < ALAC_PREAMBLE + ALAC_HEADER) {
 
124
#define ALAC_NEW_KUKI 24
 
125
        uint8_t preamble[12];
 
126
        if (size < ALAC_NEW_KUKI) {
125
127
            av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
126
128
            avio_skip(pb, size);
127
129
            return AVERROR_INVALIDDATA;
128
130
        }
129
 
        avio_skip(pb, ALAC_PREAMBLE);
 
131
        avio_read(pb, preamble, ALAC_PREAMBLE);
 
132
 
130
133
        st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE);
131
134
        if (!st->codec->extradata)
132
135
            return AVERROR(ENOMEM);
133
 
        avio_read(pb, st->codec->extradata, ALAC_HEADER);
 
136
 
 
137
        /* For the old style cookie, we skip 12 bytes, then read 36 bytes.
 
138
         * The new style cookie only contains the last 24 bytes of what was
 
139
         * 36 bytes in the old style cookie, so we fabricate the first 12 bytes
 
140
         * in that case to maintain compatibility. */
 
141
        if (!memcmp(&preamble[4], "frmaalac", 8)) {
 
142
            if (size < ALAC_PREAMBLE + ALAC_HEADER) {
 
143
                av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
 
144
                av_freep(&st->codec->extradata);
 
145
                return AVERROR_INVALIDDATA;
 
146
            }
 
147
            avio_read(pb, st->codec->extradata, ALAC_HEADER);
 
148
            avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER);
 
149
        } else {
 
150
            AV_WB32(st->codec->extradata, 36);
 
151
            memcpy(&st->codec->extradata[4], "alac", 4);
 
152
            AV_WB32(&st->codec->extradata[8], 0);
 
153
            memcpy(&st->codec->extradata[12], preamble, 12);
 
154
            avio_read(pb, &st->codec->extradata[24], ALAC_NEW_KUKI - 12);
 
155
            avio_skip(pb, size - ALAC_NEW_KUKI);
 
156
        }
134
157
        st->codec->extradata_size = ALAC_HEADER;
135
 
        avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER);
136
158
    } else {
137
159
        st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
138
160
        if (!st->codec->extradata)
150
172
    AVIOContext *pb = s->pb;
151
173
    AVStream *st      = s->streams[0];
152
174
    CaffContext *caf  = s->priv_data;
153
 
    int64_t pos = 0, ccount;
154
 
    int num_packets, i;
 
175
    int64_t pos = 0, ccount, num_packets;
 
176
    int i;
155
177
 
156
178
    ccount = avio_tell(pb);
157
179
 
170
192
        st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb);
171
193
    }
172
194
 
173
 
    if (avio_tell(pb) - ccount != size) {
 
195
    if (avio_tell(pb) - ccount > size) {
174
196
        av_log(s, AV_LOG_ERROR, "error reading packet table\n");
175
 
        return -1;
 
197
        return AVERROR_INVALIDDATA;
176
198
    }
 
199
    avio_skip(pb, ccount + size - avio_tell(pb));
177
200
 
178
201
    caf->num_bytes = pos;
179
202
    return 0;
194
217
    }
195
218
}
196
219
 
197
 
static int read_header(AVFormatContext *s,
198
 
                       AVFormatParameters *ap)
 
220
static int read_header(AVFormatContext *s)
199
221
{
200
222
    AVIOContext *pb = s->pb;
201
223
    CaffContext *caf  = s->priv_data;
244
266
            found_data = 1;
245
267
            break;
246
268
 
 
269
        case MKBETAG('c','h','a','n'):
 
270
            if ((ret = ff_mov_read_chan(s, s->pb, st, size)) < 0)
 
271
                return ret;
 
272
            break;
 
273
 
247
274
        /* magic cookie chunk */
248
275
        case MKBETAG('k','u','k','i'):
249
276
            if (read_kuki_chunk(s, size))
359
386
{
360
387
    AVStream *st = s->streams[0];
361
388
    CaffContext *caf = s->priv_data;
362
 
    int64_t pos;
 
389
    int64_t pos, packet_cnt, frame_cnt;
363
390
 
364
391
    timestamp = FFMAX(timestamp, 0);
365
392
 
368
395
        pos = caf->bytes_per_packet * timestamp / caf->frames_per_packet;
369
396
        if (caf->data_size > 0)
370
397
            pos = FFMIN(pos, caf->data_size);
371
 
        caf->packet_cnt = pos / caf->bytes_per_packet;
372
 
        caf->frame_cnt  = caf->frames_per_packet * caf->packet_cnt;
 
398
        packet_cnt = pos / caf->bytes_per_packet;
 
399
        frame_cnt  = caf->frames_per_packet * packet_cnt;
373
400
    } else if (st->nb_index_entries) {
374
 
        caf->packet_cnt = av_index_search_timestamp(st, timestamp, flags);
375
 
        caf->frame_cnt  = st->index_entries[caf->packet_cnt].timestamp;
376
 
        pos             = st->index_entries[caf->packet_cnt].pos;
 
401
        packet_cnt = av_index_search_timestamp(st, timestamp, flags);
 
402
        frame_cnt  = st->index_entries[packet_cnt].timestamp;
 
403
        pos        = st->index_entries[packet_cnt].pos;
377
404
    } else {
378
405
        return -1;
379
406
    }
380
407
 
381
 
    avio_seek(s->pb, pos + caf->data_start, SEEK_SET);
 
408
    if (avio_seek(s->pb, pos + caf->data_start, SEEK_SET) < 0)
 
409
        return -1;
 
410
 
 
411
    caf->packet_cnt = packet_cnt;
 
412
    caf->frame_cnt  = frame_cnt;
 
413
 
382
414
    return 0;
383
415
}
384
416
 
385
417
AVInputFormat ff_caf_demuxer = {
386
418
    .name           = "caf",
387
 
    .long_name      = NULL_IF_CONFIG_SMALL("Apple Core Audio Format"),
 
419
    .long_name      = NULL_IF_CONFIG_SMALL("Apple CAF (Core Audio Format)"),
388
420
    .priv_data_size = sizeof(CaffContext),
389
421
    .read_probe     = probe,
390
422
    .read_header    = read_header,
391
423
    .read_packet    = read_packet,
392
424
    .read_seek      = read_seek,
393
 
    .codec_tag = (const AVCodecTag*[]){ff_codec_caf_tags, 0},
 
425
    .codec_tag      = (const AVCodecTag* const []){ ff_codec_caf_tags, 0 },
394
426
};