• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/iss.c

Go to the documentation of this file.
00001 /*
00002  * ISS (.iss) file demuxer
00003  * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00030 #include "avformat.h"
00031 #include "libavutil/avstring.h"
00032 
00033 #define ISS_SIG "IMA_ADPCM_Sound"
00034 #define ISS_SIG_LEN 15
00035 #define MAX_TOKEN_SIZE 20
00036 
00037 typedef struct {
00038     int packet_size;
00039     int sample_start_pos;
00040 } IssDemuxContext;
00041 
00042 static void get_token(ByteIOContext *s, char *buf, int maxlen)
00043 {
00044     int i = 0;
00045     char c;
00046 
00047     while ((c = get_byte(s))) {
00048         if(c == ' ')
00049             break;
00050         if (i < maxlen-1)
00051             buf[i++] = c;
00052     }
00053 
00054     if(!c)
00055         get_byte(s);
00056 
00057     buf[i] = 0; /* Ensure null terminated, but may be truncated */
00058 }
00059 
00060 static int iss_probe(AVProbeData *p)
00061 {
00062     if (strncmp(p->buf, ISS_SIG, ISS_SIG_LEN))
00063         return 0;
00064 
00065     return AVPROBE_SCORE_MAX;
00066 }
00067 
00068 static av_cold int iss_read_header(AVFormatContext *s, AVFormatParameters *ap)
00069 {
00070     IssDemuxContext *iss = s->priv_data;
00071     ByteIOContext *pb = s->pb;
00072     AVStream *st;
00073     char token[MAX_TOKEN_SIZE];
00074     int stereo, rate_divisor;
00075 
00076     get_token(pb, token, sizeof(token)); //"IMA_ADPCM_Sound"
00077     get_token(pb, token, sizeof(token)); //packet size
00078     sscanf(token, "%d", &iss->packet_size);
00079     get_token(pb, token, sizeof(token)); //File ID
00080     get_token(pb, token, sizeof(token)); //out size
00081     get_token(pb, token, sizeof(token)); //stereo
00082     sscanf(token, "%d", &stereo);
00083     get_token(pb, token, sizeof(token)); //Unknown1
00084     get_token(pb, token, sizeof(token)); //RateDivisor
00085     sscanf(token, "%d", &rate_divisor);
00086     get_token(pb, token, sizeof(token)); //Unknown2
00087     get_token(pb, token, sizeof(token)); //Version ID
00088     get_token(pb, token, sizeof(token)); //Size
00089 
00090     iss->sample_start_pos = url_ftell(pb);
00091 
00092     st = av_new_stream(s, 0);
00093     if (!st)
00094         return AVERROR(ENOMEM);
00095     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00096     st->codec->codec_id = CODEC_ID_ADPCM_IMA_ISS;
00097     st->codec->channels = stereo ? 2 : 1;
00098     st->codec->sample_rate = 44100;
00099     if(rate_divisor > 0)
00100          st->codec->sample_rate /= rate_divisor;
00101     st->codec->bits_per_coded_sample = 4;
00102     st->codec->bit_rate = st->codec->channels * st->codec->sample_rate
00103                                       * st->codec->bits_per_coded_sample;
00104     st->codec->block_align = iss->packet_size;
00105     av_set_pts_info(st, 32, 1, st->codec->sample_rate);
00106 
00107     return 0;
00108 }
00109 
00110 static int iss_read_packet(AVFormatContext *s, AVPacket *pkt)
00111 {
00112     IssDemuxContext *iss = s->priv_data;
00113     int ret = av_get_packet(s->pb, pkt, iss->packet_size);
00114 
00115     if(ret != iss->packet_size)
00116         return AVERROR(EIO);
00117 
00118     pkt->stream_index = 0;
00119     pkt->pts = url_ftell(s->pb) - iss->sample_start_pos;
00120     if(s->streams[0]->codec->channels > 0)
00121         pkt->pts /= s->streams[0]->codec->channels*2;
00122     return 0;
00123 }
00124 
00125 AVInputFormat iss_demuxer = {
00126     "ISS",
00127     NULL_IF_CONFIG_SMALL("Funcom ISS format"),
00128     sizeof(IssDemuxContext),
00129     iss_probe,
00130     iss_read_header,
00131     iss_read_packet,
00132 };
00133 

Generated on Fri Sep 16 2011 17:17:48 for FFmpeg by  doxygen 1.7.1