Mercurial > libavformat.hg
changeset 3189:f016d69a28b6 libavformat
IFF demuxer
Patch by Jai Menon (realityman <at> gmx.net)
author | vitor |
---|---|
date | Sun, 30 Mar 2008 19:17:01 +0000 |
parents | 87119f0c4736 |
children | 8b95e46003f8 |
files | Makefile allformats.c avformat.h iff.c |
diffstat | 4 files changed, 177 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Sun Mar 30 03:40:03 2008 +0000 +++ b/Makefile Sun Mar 30 19:17:01 2008 +0000 @@ -63,6 +63,7 @@ OBJS-$(CONFIG_H264_DEMUXER) += raw.o OBJS-$(CONFIG_H264_MUXER) += raw.o OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o +OBJS-$(CONFIG_IFF_DEMUXER) += iff.o OBJS-$(CONFIG_IMAGE2_DEMUXER) += img2.o OBJS-$(CONFIG_IMAGE2_MUXER) += img2.o OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER) += img2.o
--- a/allformats.c Sun Mar 30 03:40:03 2008 +0000 +++ b/allformats.c Sun Mar 30 19:17:01 2008 +0000 @@ -86,6 +86,7 @@ REGISTER_MUXDEMUX (H263, h263); REGISTER_MUXDEMUX (H264, h264); REGISTER_DEMUXER (IDCIN, idcin); + REGISTER_DEMUXER (IFF, iff); REGISTER_MUXDEMUX (IMAGE2, image2); REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe); REGISTER_DEMUXER (INGENIENT, ingenient);
--- a/avformat.h Sun Mar 30 03:40:03 2008 +0000 +++ b/avformat.h Sun Mar 30 19:17:01 2008 +0000 @@ -22,7 +22,7 @@ #define FFMPEG_AVFORMAT_H #define LIBAVFORMAT_VERSION_MAJOR 52 -#define LIBAVFORMAT_VERSION_MINOR 12 +#define LIBAVFORMAT_VERSION_MINOR 13 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iff.c Sun Mar 30 19:17:01 2008 +0000 @@ -0,0 +1,174 @@ +/* + * Iff (.iff) File Demuxer + * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net> + * + * 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 + */ + +/** + * @file iff.c + * iff file demuxer + * by Jaikrishnan Menon + * for more information on the .iff file format, visit: + * http://wiki.multimedia.cx/index.php?title=IFF + */ + +#include "avformat.h" + +#define ID_8SVX MKTAG('8','S','V','X') +#define ID_VHDR MKTAG('V','H','D','R') +#define ID_ATAK MKTAG('A','T','A','K') +#define ID_RLSE MKTAG('R','L','S','E') +#define ID_CHAN MKTAG('C','H','A','N') + +#define ID_FORM MKTAG('F','O','R','M') +#define ID_ANNO MKTAG('A','N','N','O') +#define ID_AUTH MKTAG('A','U','T','H') +#define ID_CHRS MKTAG('C','H','R','S') +#define ID_COPYRIGHT MKTAG('(','c',')',' ') +#define ID_CSET MKTAG('C','S','E','T') +#define ID_FVER MKTAG('F','V','E','R') +#define ID_NAME MKTAG('N','A','M','E') +#define ID_TEXT MKTAG('T','E','X','T') +#define ID_BODY MKTAG('B','O','D','Y') + +#define LEFT 2 +#define RIGHT 4 +#define STEREO 6 + +#define PACKET_SIZE 1024 + +typedef enum {COMP_NONE, COMP_FIB, COMP_EXP} svx8_compression_t; + +typedef struct { + uint32_t body_size; + uint32_t sent_bytes; + uint32_t audio_frame_count; +} IffDemuxContext; + +static int iff_probe(AVProbeData *p) +{ + const uint8_t *d = p->buf; + + if ( AV_RL32(d) == ID_FORM && + AV_RL32(d+8) == ID_8SVX) + return AVPROBE_SCORE_MAX; + return 0; +} + +static int iff_read_header(AVFormatContext *s, + AVFormatParameters *ap) +{ + IffDemuxContext *iff = s->priv_data; + ByteIOContext *pb = s->pb; + AVStream *st; + uint32_t chunk_id, data_size; + int padding, ret, done = 0; + + st = av_new_stream(s, 0); + if (!st) + return AVERROR(ENOMEM); + + st->codec->channels = 1; + url_fskip(pb, 12); + + while(!done && !url_feof(pb)) { + chunk_id = get_le32(pb); + data_size = get_be32(pb); + padding = data_size & 1; + + switch(chunk_id) { + case ID_VHDR: + url_fskip(pb, 12); + st->codec->sample_rate = get_be16(pb); + url_fskip(pb, 1); + st->codec->codec_tag = get_byte(pb); + url_fskip(pb, 4); + break; + + case ID_BODY: + iff->body_size = data_size; + done = 1; + break; + + case ID_CHAN: + st->codec->channels = (get_be32(pb) < 6) ? 1 : 2; + break; + + default: + url_fseek(pb, data_size + padding, SEEK_CUR); + break; + } + } + + if(!st->codec->sample_rate) + return AVERROR_INVALIDDATA; + + av_set_pts_info(st, 32, 1, st->codec->sample_rate); + st->codec->codec_type = CODEC_TYPE_AUDIO; + + switch(st->codec->codec_tag) { + case COMP_NONE: + st->codec->codec_id = CODEC_ID_PCM_S8; + break; + case COMP_FIB: + st->codec->codec_id = CODEC_ID_8SVX_FIB; + break; + case COMP_EXP: + st->codec->codec_id = CODEC_ID_8SVX_EXP; + break; + default: + av_log(s, AV_LOG_ERROR, "iff: unknown compression method\n"); + return -1; + } + + st->codec->bits_per_sample = 8; + st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_sample; + st->codec->block_align = st->codec->channels * st->codec->bits_per_sample; + + return 0; +} + +static int iff_read_packet(AVFormatContext *s, + AVPacket *pkt) +{ + IffDemuxContext *iff = s->priv_data; + ByteIOContext *pb = s->pb; + int ret; + + if(iff->sent_bytes > iff->body_size) + return AVERROR(EIO); + ret = av_get_packet(pb, pkt, PACKET_SIZE); + + if(iff->sent_bytes == 0) + pkt->flags |= PKT_FLAG_KEY; + + iff->sent_bytes += PACKET_SIZE; + pkt->stream_index = 0; + pkt->pts = iff->audio_frame_count; + iff->audio_frame_count += ret / s->streams[0]->codec->channels; + return ret; +} + +AVInputFormat iff_demuxer = { + "IFF", + "IFF format", + sizeof(IffDemuxContext), + iff_probe, + iff_read_header, + iff_read_packet, +};