From 1e5bbbfcf303ec3db0c7db30b85855e2e5358aec Mon Sep 17 00:00:00 2001 From: James Almer Date: Tue, 9 Jul 2013 02:39:09 -0300 Subject: lavf/flacdec: Share the function to parse cover art blocks Signed-off-by: James Almer Signed-off-by: Michael Niedermayer --- libavformat/Makefile | 1 + libavformat/flacdec.c | 130 +------------------------------------ libavformat/flacdec.h | 31 +++++++++ libavformat/flacdec_picture.c | 148 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+), 128 deletions(-) create mode 100644 libavformat/flacdec.h create mode 100644 libavformat/flacdec_picture.c (limited to 'libavformat') diff --git a/libavformat/Makefile b/libavformat/Makefile index 11e1a69e13..2a6173c153 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -134,6 +134,7 @@ OBJS-$(CONFIG_FFMETADATA_MUXER) += ffmetaenc.o OBJS-$(CONFIG_FILMSTRIP_DEMUXER) += filmstripdec.o OBJS-$(CONFIG_FILMSTRIP_MUXER) += filmstripenc.o OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o rawdec.o \ + flacdec_picture.o \ oggparsevorbis.o \ vorbiscomment.o OBJS-$(CONFIG_FLAC_MUXER) += flacenc.o flacenc_header.o \ diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 7caa7a7516..8384076b3d 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -21,139 +21,13 @@ #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" -#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0) - -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) { - RETURN_ERROR(AVERROR_INVALIDDATA); - } - 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))) { - RETURN_ERROR(AVERROR(ENOMEM)); - } - - 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))) { - RETURN_ERROR(AVERROR(ENOMEM)); - } - 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) { - RETURN_ERROR(AVERROR(ENOMEM)); - } - - 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; @@ -248,7 +122,7 @@ static int flac_read_header(AVFormatContext *s) } 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"); diff --git a/libavformat/flacdec.h b/libavformat/flacdec.h new file mode 100644 index 0000000000..dff0660311 --- /dev/null +++ b/libavformat/flacdec.h @@ -0,0 +1,31 @@ +/* + * Raw FLAC demuxer + * Copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * 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. + * + * 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_FLACDEC_H +#define AVFORMAT_FLACDEC_H + +#include "avformat.h" + +#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0) + +int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size); + +#endif /* AVFORMAT_FLACDEC_H */ diff --git a/libavformat/flacdec_picture.c b/libavformat/flacdec_picture.c new file mode 100644 index 0000000000..3c4fa6e6f8 --- /dev/null +++ b/libavformat/flacdec_picture.c @@ -0,0 +1,148 @@ +/* + * Raw FLAC demuxer + * Copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * 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. + * + * 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" +#include "flacdec.h" +#include "id3v2.h" +#include "internal.h" + +int ff_flac_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) { + RETURN_ERROR(AVERROR_INVALIDDATA); + } + 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))) { + RETURN_ERROR(AVERROR(ENOMEM)); + } + + 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))) { + RETURN_ERROR(AVERROR(ENOMEM)); + } + 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) { + RETURN_ERROR(AVERROR(ENOMEM)); + } + + 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; +} -- cgit v1.2.3