From 8992cb1d0d07edc33d274f6d7924ecdf6f83d994 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Thu, 5 Sep 2013 17:57:22 +0100 Subject: making act segmenter --- ffmpeg/libavformat/iss.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 ffmpeg/libavformat/iss.c (limited to 'ffmpeg/libavformat/iss.c') diff --git a/ffmpeg/libavformat/iss.c b/ffmpeg/libavformat/iss.c new file mode 100644 index 0000000..e4335b4 --- /dev/null +++ b/ffmpeg/libavformat/iss.c @@ -0,0 +1,144 @@ +/* + * ISS (.iss) file demuxer + * Copyright (c) 2008 Jaikrishnan Menon + * + * 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 + * Funcom ISS file demuxer + * @author Jaikrishnan Menon + * @see http://wiki.multimedia.cx/index.php?title=FunCom_ISS + */ + +#include "libavutil/channel_layout.h" +#include "avformat.h" +#include "internal.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(AVIOContext *s, char *buf, int maxlen) +{ + int i = 0; + char c; + + while ((c = avio_r8(s))) { + if(c == ' ') + break; + if (i < maxlen-1) + buf[i++] = c; + } + + if(!c) + avio_r8(s); + + 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) +{ + IssDemuxContext *iss = s->priv_data; + AVIOContext *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 + + if (iss->packet_size <= 0) { + av_log(s, AV_LOG_ERROR, "packet_size %d is invalid\n", iss->packet_size); + return AVERROR_INVALIDDATA; + } + + iss->sample_start_pos = avio_tell(pb); + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_ISS; + if (stereo) { + st->codec->channels = 2; + st->codec->channel_layout = AV_CH_LAYOUT_STEREO; + } else { + st->codec->channels = 1; + st->codec->channel_layout = AV_CH_LAYOUT_MONO; + } + 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; + avpriv_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 != iss->packet_size) + return AVERROR(EIO); + + pkt->stream_index = 0; + pkt->pts = avio_tell(s->pb) - iss->sample_start_pos; + if(s->streams[0]->codec->channels > 0) + pkt->pts /= s->streams[0]->codec->channels*2; + return 0; +} + +AVInputFormat ff_iss_demuxer = { + .name = "iss", + .long_name = NULL_IF_CONFIG_SMALL("Funcom ISS"), + .priv_data_size = sizeof(IssDemuxContext), + .read_probe = iss_probe, + .read_header = iss_read_header, + .read_packet = iss_read_packet, +}; -- cgit v1.2.3