2 * ISS (.iss) file demuxer
3 * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * @file libavformat/iss.c
24 * Funcom ISS file demuxer
25 * @author Jaikrishnan Menon
26 * for more information on the .iss file format, visit:
27 * http://wiki.multimedia.cx/index.php?title=FunCom_ISS
31 #include "libavutil/avstring.h"
33 #define ISS_SIG "IMA_ADPCM_Sound"
34 #define ISS_SIG_LEN 15
35 #define MAX_TOKEN_SIZE 20
42 static void get_token(ByteIOContext
*s
, char *buf
, int maxlen
)
47 while ((c
= get_byte(s
))) {
57 buf
[i
] = 0; /* Ensure null terminated, but may be truncated */
60 static int iss_probe(AVProbeData
*p
)
62 if (strncmp(p
->buf
, ISS_SIG
, ISS_SIG_LEN
))
65 return AVPROBE_SCORE_MAX
;
68 static av_cold
int iss_read_header(AVFormatContext
*s
, AVFormatParameters
*ap
)
70 IssDemuxContext
*iss
= s
->priv_data
;
71 ByteIOContext
*pb
= s
->pb
;
73 char token
[MAX_TOKEN_SIZE
];
74 int stereo
, rate_divisor
;
76 get_token(pb
, token
, sizeof(token
)); //"IMA_ADPCM_Sound"
77 get_token(pb
, token
, sizeof(token
)); //packet size
78 sscanf(token
, "%d", &iss
->packet_size
);
79 get_token(pb
, token
, sizeof(token
)); //File ID
80 get_token(pb
, token
, sizeof(token
)); //out size
81 get_token(pb
, token
, sizeof(token
)); //stereo
82 sscanf(token
, "%d", &stereo
);
83 get_token(pb
, token
, sizeof(token
)); //Unknown1
84 get_token(pb
, token
, sizeof(token
)); //RateDivisor
85 sscanf(token
, "%d", &rate_divisor
);
86 get_token(pb
, token
, sizeof(token
)); //Unknown2
87 get_token(pb
, token
, sizeof(token
)); //Version ID
88 get_token(pb
, token
, sizeof(token
)); //Size
90 iss
->sample_start_pos
= url_ftell(pb
);
92 st
= av_new_stream(s
, 0);
94 return AVERROR(ENOMEM
);
95 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
96 st
->codec
->codec_id
= CODEC_ID_ADPCM_IMA_ISS
;
97 st
->codec
->channels
= stereo
? 2 : 1;
98 st
->codec
->sample_rate
= 44100;
100 st
->codec
->sample_rate
/= rate_divisor
;
101 st
->codec
->bits_per_coded_sample
= 4;
102 st
->codec
->bit_rate
= st
->codec
->channels
* st
->codec
->sample_rate
103 * st
->codec
->bits_per_coded_sample
;
104 st
->codec
->block_align
= iss
->packet_size
;
105 av_set_pts_info(st
, 32, 1, st
->codec
->sample_rate
);
110 static int iss_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
112 IssDemuxContext
*iss
= s
->priv_data
;
113 int ret
= av_get_packet(s
->pb
, pkt
, iss
->packet_size
);
115 if(ret
!= iss
->packet_size
)
118 pkt
->stream_index
= 0;
119 pkt
->pts
= url_ftell(s
->pb
) - iss
->sample_start_pos
;
120 if(s
->streams
[0]->codec
->channels
> 0)
121 pkt
->pts
/= s
->streams
[0]->codec
->channels
*2;
125 AVInputFormat iss_demuxer
= {
127 NULL_IF_CONFIG_SMALL("Funcom ISS format"),
128 sizeof(IssDemuxContext
),