Mercurial > libavformat.hg
changeset 4244:f7c35963d089 libavformat
added demuxer for FunCom ISS audio files,
extended ADPCM decoder by ISS specific IMA variant
author | stefang |
---|---|
date | Sat, 17 Jan 2009 20:08:43 +0000 |
parents | 964903243e66 |
children | a2a190f1bb9d |
files | Makefile allformats.c avformat.h iss.c |
diffstat | 4 files changed, 133 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Sat Jan 17 12:21:01 2009 +0000 +++ b/Makefile Sat Jan 17 20:08:43 2009 +0000 @@ -78,6 +78,7 @@ OBJS-$(CONFIG_INGENIENT_DEMUXER) += raw.o OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o OBJS-$(CONFIG_IPOD_MUXER) += movenc.o riff.o isom.o avc.o +OBJS-$(CONFIG_ISS_DEMUXER) += iss.o OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o OBJS-$(CONFIG_M4V_DEMUXER) += raw.o OBJS-$(CONFIG_M4V_MUXER) += raw.o
--- a/allformats.c Sat Jan 17 12:21:01 2009 +0000 +++ b/allformats.c Sat Jan 17 20:08:43 2009 +0000 @@ -101,6 +101,7 @@ REGISTER_DEMUXER (INGENIENT, ingenient); REGISTER_DEMUXER (IPMOVIE, ipmovie); REGISTER_MUXER (IPOD, ipod); + REGISTER_DEMUXER (ISS, iss); REGISTER_DEMUXER (LMLM4, lmlm4); REGISTER_MUXDEMUX (M4V, m4v); REGISTER_MUXDEMUX (MATROSKA, matroska);
--- a/avformat.h Sat Jan 17 12:21:01 2009 +0000 +++ b/avformat.h Sat Jan 17 20:08:43 2009 +0000 @@ -22,7 +22,7 @@ #define AVFORMAT_AVFORMAT_H #define LIBAVFORMAT_VERSION_MAJOR 52 -#define LIBAVFORMAT_VERSION_MINOR 23 +#define LIBAVFORMAT_VERSION_MINOR 24 #define LIBAVFORMAT_VERSION_MICRO 1 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iss.c Sat Jan 17 20:08:43 2009 +0000 @@ -0,0 +1,130 @@ +/* + * ISS (.iss) 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 iss.c + * Funcom ISS file demuxer + * @author Jaikrishnan Menon + * for more information on the .iss file format, visit: + * http://wiki.multimedia.cx/index.php?title=FunCom_ISS + */ + +#include "avformat.h" +#include "libavutil/avstring.h" + +#define ISS_SIG "IMA_ADPCM_Sound" +#define ISS_SIG_LEN 15 +#define MAX_TOKEN_SIZE 20 + +typedef struct { + int packet_size; + int sample_start_pos; +} IssDemuxContext; + +static void get_token(ByteIOContext *s, char *buf, int maxlen) +{ + int i = 0; + char c; + + while ((c = get_byte(s))) { + if(c == ' ') + break; + if (i < maxlen-1) + buf[i++] = c; + } + + buf[i] = 0; /* Ensure null terminated, but may be truncated */ +} + +static int iss_probe(AVProbeData *p) +{ + if (strncmp(p->buf, ISS_SIG, ISS_SIG_LEN)) + return 0; + + return AVPROBE_SCORE_MAX; +} + +static av_cold int iss_read_header(AVFormatContext *s, AVFormatParameters *ap) +{ + IssDemuxContext *iss = s->priv_data; + ByteIOContext *pb = s->pb; + AVStream *st; + char token[MAX_TOKEN_SIZE]; + int stereo, rate_divisor; + + get_token(pb, token, sizeof(token)); //"IMA_ADPCM_Sound" + get_token(pb, token, sizeof(token)); //packet size + sscanf(token, "%d", &iss->packet_size); + get_token(pb, token, sizeof(token)); //File ID + get_token(pb, token, sizeof(token)); //out size + get_token(pb, token, sizeof(token)); //stereo + sscanf(token, "%d", &stereo); + get_token(pb, token, sizeof(token)); //Unknown1 + get_token(pb, token, sizeof(token)); //RateDivisor + sscanf(token, "%d", &rate_divisor); + get_token(pb, token, sizeof(token)); //Unknown2 + get_token(pb, token, sizeof(token)); //Version ID + get_token(pb, token, sizeof(token)); //Size + + iss->sample_start_pos = url_ftell(pb); + + st = av_new_stream(s, 0); + if (!st) + return AVERROR(ENOMEM); + st->codec->codec_type = CODEC_TYPE_AUDIO; + st->codec->codec_id = CODEC_ID_ADPCM_IMA_ISS; + st->codec->channels = stereo ? 2 : 1; + st->codec->sample_rate = 44100; + if(rate_divisor > 0) + st->codec->sample_rate /= rate_divisor; + st->codec->bits_per_coded_sample = 4; + st->codec->bit_rate = st->codec->channels * st->codec->sample_rate + * st->codec->bits_per_coded_sample; + st->codec->block_align = iss->packet_size; + av_set_pts_info(st, 32, 1, st->codec->sample_rate); + + return 0; +} + +static int iss_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + IssDemuxContext *iss = s->priv_data; + int ret = av_get_packet(s->pb, pkt, iss->packet_size); + + if(ret < 0) + return ret; + + pkt->stream_index = 0; + pkt->pts = url_ftell(s->pb) - iss->sample_start_pos; + if(s->streams[0]->codec->channels > 0) + pkt->pts /= s->streams[0]->codec->channels*2; + return 0; +} + +AVInputFormat iss_demuxer = { + "ISS", + NULL_IF_CONFIG_SMALL("Funcom ISS format"), + sizeof(IssDemuxContext), + iss_probe, + iss_read_header, + iss_read_packet, +}; +