diff options
Diffstat (limited to 'libavformat/flacdec.c')
-rw-r--r-- | libavformat/flacdec.c | 169 |
1 files changed, 21 insertions, 148 deletions
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 9737095bbb..8384076b3d 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -2,160 +2,32 @@ * Raw FLAC demuxer * Copyright (c) 2001 Fabrice Bellard * - * 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 */ #include "libavcodec/flac.h" #include "avformat.h" -#include "id3v2.h" +#include "flacdec.h" #include "internal.h" #include "rawdec.h" #include "oggdec.h" #include "vorbiscomment.h" #include "libavcodec/bytestream.h" -static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) -{ - const CodecMime *mime = ff_id3v2_mime_tags; - enum AVCodecID id = AV_CODEC_ID_NONE; - AVBufferRef *data = NULL; - uint8_t mimetype[64], *desc = NULL; - AVIOContext *pb = NULL; - AVStream *st; - int type, width, height; - int len, ret = 0; - - pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL); - if (!pb) - return AVERROR(ENOMEM); - - /* read the picture type */ - type = avio_rb32(pb); - if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) { - av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type); - if (s->error_recognition & AV_EF_EXPLODE) { - ret = AVERROR_INVALIDDATA; - goto fail; - } - type = 0; - } - - /* picture mimetype */ - len = avio_rb32(pb); - if (len <= 0 || - avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) { - av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached " - "picture.\n"); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR_INVALIDDATA; - goto fail; - } - mimetype[len] = 0; - - while (mime->id != AV_CODEC_ID_NONE) { - if (!strncmp(mime->str, mimetype, sizeof(mimetype))) { - id = mime->id; - break; - } - mime++; - } - if (id == AV_CODEC_ID_NONE) { - av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n", - mimetype); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR_INVALIDDATA; - goto fail; - } - - /* picture description */ - len = avio_rb32(pb); - if (len > 0) { - if (!(desc = av_malloc(len + 1))) { - ret = AVERROR(ENOMEM); - goto fail; - } - - if (avio_read(pb, desc, len) != len) { - av_log(s, AV_LOG_ERROR, "Error reading attached picture description.\n"); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR(EIO); - goto fail; - } - desc[len] = 0; - } - - /* picture metadata */ - width = avio_rb32(pb); - height = avio_rb32(pb); - avio_skip(pb, 8); - - /* picture data */ - len = avio_rb32(pb); - if (len <= 0) { - av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR_INVALIDDATA; - goto fail; - } - if (!(data = av_buffer_alloc(len))) { - ret = AVERROR(ENOMEM); - goto fail; - } - if (avio_read(pb, data->data, len) != len) { - av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n"); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR(EIO); - goto fail; - } - - st = avformat_new_stream(s, NULL); - if (!st) { - ret = AVERROR(ENOMEM); - goto fail; - } - - av_init_packet(&st->attached_pic); - st->attached_pic.buf = data; - st->attached_pic.data = data->data; - st->attached_pic.size = len; - st->attached_pic.stream_index = st->index; - st->attached_pic.flags |= AV_PKT_FLAG_KEY; - - st->disposition |= AV_DISPOSITION_ATTACHED_PIC; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = id; - st->codec->width = width; - st->codec->height = height; - av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0); - if (desc) - av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL); - - av_freep(&pb); - - return 0; - -fail: - av_buffer_unref(&data); - av_freep(&desc); - av_freep(&pb); - return ret; - -} - static int flac_read_header(AVFormatContext *s) { int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0; @@ -166,7 +38,7 @@ static int flac_read_header(AVFormatContext *s) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_FLAC; - st->need_parsing = AVSTREAM_PARSE_FULL; + st->need_parsing = AVSTREAM_PARSE_FULL_RAW; /* the parameters will be extracted from the compressed bitstream */ /* if fLaC marker is not found, assume there is no header */ @@ -176,7 +48,7 @@ static int flac_read_header(AVFormatContext *s) } /* process metadata blocks */ - while (!s->pb->eof_reached && !metadata_last) { + while (!url_feof(s->pb) && !metadata_last) { avio_read(s->pb, header, 4); avpriv_flac_parse_block_header(header, &metadata_last, &metadata_type, &metadata_size); @@ -191,8 +63,7 @@ static int flac_read_header(AVFormatContext *s) return AVERROR(ENOMEM); } if (avio_read(s->pb, buffer, metadata_size) != metadata_size) { - av_freep(&buffer); - return AVERROR(EIO); + RETURN_ERROR(AVERROR(EIO)); } break; /* skip metadata block for unsupported types */ @@ -206,12 +77,10 @@ static int flac_read_header(AVFormatContext *s) FLACStreaminfo si; /* STREAMINFO can only occur once */ if (found_streaminfo) { - av_freep(&buffer); - return AVERROR_INVALIDDATA; + RETURN_ERROR(AVERROR_INVALIDDATA); } if (metadata_size != FLAC_STREAMINFO_SIZE) { - av_freep(&buffer); - return AVERROR_INVALIDDATA; + RETURN_ERROR(AVERROR_INVALIDDATA); } found_streaminfo = 1; st->codec->extradata = buffer; @@ -233,26 +102,27 @@ static int flac_read_header(AVFormatContext *s) const uint8_t *offset; int i, chapters, track, ti; if (metadata_size < 431) - return AVERROR_INVALIDDATA; + RETURN_ERROR(AVERROR_INVALIDDATA); offset = buffer + 395; chapters = bytestream_get_byte(&offset) - 1; if (chapters <= 0) - return AVERROR_INVALIDDATA; + RETURN_ERROR(AVERROR_INVALIDDATA); for (i = 0; i < chapters; i++) { if (offset + 36 - buffer > metadata_size) - return AVERROR_INVALIDDATA; + RETURN_ERROR(AVERROR_INVALIDDATA); start = bytestream_get_be64(&offset); track = bytestream_get_byte(&offset); bytestream_get_buffer(&offset, isrc, 12); isrc[12] = 0; offset += 14; ti = bytestream_get_byte(&offset); - if (ti <= 0) return AVERROR_INVALIDDATA; + if (ti <= 0) RETURN_ERROR(AVERROR_INVALIDDATA); offset += ti * 12; avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc); } + av_freep(&buffer); } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) { - ret = parse_picture(s, buffer, metadata_size); + ret = ff_flac_parse_picture(s, buffer, metadata_size); av_freep(&buffer); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n"); @@ -261,8 +131,7 @@ static int flac_read_header(AVFormatContext *s) } else { /* STREAMINFO must be the first block */ if (!found_streaminfo) { - av_freep(&buffer); - return AVERROR_INVALIDDATA; + RETURN_ERROR(AVERROR_INVALIDDATA); } /* process supported blocks other than STREAMINFO */ if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) { @@ -275,6 +144,10 @@ static int flac_read_header(AVFormatContext *s) } return 0; + +fail: + av_free(buffer); + return ret; } static int flac_probe(AVProbeData *p) |