diff options
Diffstat (limited to 'libavformat/cafdec.c')
-rw-r--r-- | libavformat/cafdec.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index 7966225ea9..a8edbca039 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -3,20 +3,20 @@ * Copyright (c) 2007 Justin Ruggles * Copyright (c) 2009 Peter Ross * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -71,7 +71,7 @@ static int read_desc_chunk(AVFormatContext *s) /* parse format description */ st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->sample_rate = av_int2double(avio_rb64(pb)); - st->codec->codec_tag = avio_rb32(pb); + st->codec->codec_tag = avio_rl32(pb); flags = avio_rb32(pb); caf->bytes_per_packet = avio_rb32(pb); st->codec->block_align = caf->bytes_per_packet; @@ -88,7 +88,7 @@ static int read_desc_chunk(AVFormatContext *s) } /* determine codec */ - if (st->codec->codec_tag == MKBETAG('l','p','c','m')) + if (st->codec->codec_tag == MKTAG('l','p','c','m')) st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, (flags ^ 0x2) | 0x4); else st->codec->codec_id = ff_codec_get_id(ff_codec_caf_tags, st->codec->codec_tag); @@ -132,8 +132,7 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size) } avio_read(pb, preamble, ALAC_PREAMBLE); - st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) + if (ff_alloc_extradata(st->codec, ALAC_HEADER)) return AVERROR(ENOMEM); /* For the old style cookie, we skip 12 bytes, then read 36 bytes. @@ -156,13 +155,9 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size) avio_read(pb, &st->codec->extradata[24], ALAC_NEW_KUKI - 12); avio_skip(pb, size - ALAC_NEW_KUKI); } - st->codec->extradata_size = ALAC_HEADER; } else { - st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) + if (ff_get_extradata(st->codec, pb, size) < 0) return AVERROR(ENOMEM); - avio_read(pb, st->codec->extradata, size); - st->codec->extradata_size = size; } return 0; @@ -213,7 +208,7 @@ static void read_info_chunk(AVFormatContext *s, int64_t size) for (i = 0; i < nb_entries; i++) { char key[32]; char value[1024]; - avio_get_str(pb, INT_MAX, key, sizeof(key)); + avio_get_str(pb, INT_MAX, key, sizeof(key)); avio_get_str(pb, INT_MAX, value, sizeof(value)); av_dict_set(&s->metadata, key, value, 0); } @@ -226,7 +221,7 @@ static int read_header(AVFormatContext *s) AVStream *st; uint32_t tag = 0; int found_data, ret; - int64_t size; + int64_t size, pos; avio_skip(pb, 8); /* magic, version, file flags */ @@ -246,7 +241,7 @@ static int read_header(AVFormatContext *s) /* parse each chunk */ found_data = 0; - while (!pb->eof_reached) { + while (!url_feof(pb)) { /* stop at data chunk if seeking is not supported or data chunk size is unknown */ @@ -255,7 +250,8 @@ static int read_header(AVFormatContext *s) tag = avio_rb32(pb); size = avio_rb64(pb); - if (pb->eof_reached) + pos = avio_tell(pb); + if (url_feof(pb)) break; switch (tag) { @@ -292,15 +288,20 @@ static int read_header(AVFormatContext *s) default: #define _(x) ((x) >= ' ' ? (x) : ' ') av_log(s, AV_LOG_WARNING, - "skipping CAF chunk: %08"PRIX32" (%"PRIu8"%"PRIu8"%"PRIu8"%"PRIu8")\n", - tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF)); + "skipping CAF chunk: %08"PRIX32" (%c%c%c%c), size %"PRId64"\n", + tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF), size); #undef _ case MKBETAG('f','r','e','e'): if (size < 0) return AVERROR_INVALIDDATA; - avio_skip(pb, size); break; } + + if (size > 0) { + if (pos > INT64_MAX - size) + return AVERROR_INVALIDDATA; + avio_skip(pb, FFMAX(0, pos + size - avio_tell(pb))); + } } if (!found_data) @@ -309,7 +310,7 @@ static int read_header(AVFormatContext *s) if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) { if (caf->data_size > 0) st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet; - } else if (st->nb_index_entries) { + } else if (st->nb_index_entries && st->duration > 0) { st->codec->bit_rate = st->codec->sample_rate * caf->data_size * 8 / st->duration; } else { @@ -338,13 +339,15 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) int res, pkt_size = 0, pkt_frames = 0; int64_t left = CAF_MAX_PKT_SIZE; - if (pb->eof_reached) - return AVERROR(EIO); + if (url_feof(pb)) + return AVERROR_EOF; /* don't read past end of data chunk */ if (caf->data_size > 0) { left = (caf->data_start + caf->data_size) - avio_tell(pb); - if (left <= 0) + if (!left) + return AVERROR_EOF; + if (left < 0) return AVERROR(EIO); } @@ -395,7 +398,7 @@ static int read_seek(AVFormatContext *s, int stream_index, if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) { /* calculate new byte position based on target frame position */ - pos = caf->bytes_per_packet * timestamp / caf->frames_per_packet; + pos = caf->bytes_per_packet * (timestamp / caf->frames_per_packet); if (caf->data_size > 0) pos = FFMIN(pos, caf->data_size); packet_cnt = pos / caf->bytes_per_packet; |