Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
iss.c
Go to the documentation of this file.
1
/*
2
* ISS (.iss) file demuxer
3
* Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
4
*
5
* This file is part of Libav.
6
*
7
* Libav 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.
11
*
12
* Libav 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.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
29
#include "
avformat.h
"
30
#include "
internal.h
"
31
#include "
libavutil/avstring.h
"
32
33
#define ISS_SIG "IMA_ADPCM_Sound"
34
#define ISS_SIG_LEN 15
35
#define MAX_TOKEN_SIZE 20
36
37
typedef
struct
{
38
int
packet_size
;
39
int
sample_start_pos
;
40
}
IssDemuxContext
;
41
42
static
void
get_token
(
AVIOContext
*s,
char
*buf,
int
maxlen)
43
{
44
int
i = 0;
45
char
c;
46
47
while
((c =
avio_r8
(s))) {
48
if
(c ==
' '
)
49
break
;
50
if
(i < maxlen-1)
51
buf[i++] = c;
52
}
53
54
if
(!c)
55
avio_r8
(s);
56
57
buf[i] = 0;
/* Ensure null terminated, but may be truncated */
58
}
59
60
static
int
iss_probe
(
AVProbeData
*p)
61
{
62
if
(strncmp(p->
buf
,
ISS_SIG
,
ISS_SIG_LEN
))
63
return
0;
64
65
return
AVPROBE_SCORE_MAX
;
66
}
67
68
static
av_cold
int
iss_read_header
(
AVFormatContext
*s,
AVFormatParameters
*ap)
69
{
70
IssDemuxContext
*iss = s->
priv_data
;
71
AVIOContext
*pb = s->
pb
;
72
AVStream
*st;
73
char
token[
MAX_TOKEN_SIZE
];
74
int
stereo, rate_divisor;
75
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
89
90
iss->
sample_start_pos
=
avio_tell
(pb);
91
92
st =
avformat_new_stream
(s,
NULL
);
93
if
(!st)
94
return
AVERROR
(ENOMEM);
95
st->
codec
->
codec_type
=
AVMEDIA_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;
99
if
(rate_divisor > 0)
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
avpriv_set_pts_info
(st, 32, 1, st->
codec
->
sample_rate
);
106
107
return
0;
108
}
109
110
static
int
iss_read_packet
(
AVFormatContext
*s,
AVPacket
*pkt)
111
{
112
IssDemuxContext
*iss = s->
priv_data
;
113
int
ret =
av_get_packet
(s->
pb
, pkt, iss->
packet_size
);
114
115
if
(ret != iss->
packet_size
)
116
return
AVERROR
(EIO);
117
118
pkt->
stream_index
= 0;
119
pkt->
pts
=
avio_tell
(s->
pb
) - iss->
sample_start_pos
;
120
if
(s->
streams
[0]->
codec
->
channels
> 0)
121
pkt->
pts
/= s->
streams
[0]->
codec
->
channels
*2;
122
return
0;
123
}
124
125
AVInputFormat
ff_iss_demuxer
= {
126
.
name
=
"ISS"
,
127
.long_name =
NULL_IF_CONFIG_SMALL
(
"Funcom ISS format"
),
128
.priv_data_size =
sizeof
(
IssDemuxContext
),
129
.
read_probe
=
iss_probe
,
130
.
read_header
=
iss_read_header
,
131
.
read_packet
=
iss_read_packet
,
132
};
133