FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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 FFmpeg.
6
*
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.
11
*
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.
16
*
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
20
*/
21
22
/**
23
* @file
24
* Funcom ISS file demuxer
25
* @author Jaikrishnan Menon
26
* @see http://wiki.multimedia.cx/index.php?title=FunCom_ISS
27
*/
28
29
#include "
libavutil/channel_layout.h
"
30
#include "
avformat.h
"
31
#include "
internal.h
"
32
#include "
libavutil/avstring.h
"
33
34
#define ISS_SIG "IMA_ADPCM_Sound"
35
#define ISS_SIG_LEN 15
36
#define MAX_TOKEN_SIZE 20
37
38
typedef
struct
{
39
int
packet_size
;
40
int
sample_start_pos
;
41
}
IssDemuxContext
;
42
43
static
void
get_token
(
AVIOContext
*
s
,
char
*
buf
,
int
maxlen)
44
{
45
int
i = 0;
46
char
c
;
47
48
while
((c =
avio_r8
(s))) {
49
if
(c ==
' '
)
50
break
;
51
if
(i < maxlen-1)
52
buf[i++] =
c
;
53
}
54
55
if
(!c)
56
avio_r8
(s);
57
58
buf[i] = 0;
/* Ensure null terminated, but may be truncated */
59
}
60
61
static
int
iss_probe
(
AVProbeData
*p)
62
{
63
if
(strncmp(p->
buf
,
ISS_SIG
,
ISS_SIG_LEN
))
64
return
0;
65
66
return
AVPROBE_SCORE_MAX
;
67
}
68
69
static
av_cold
int
iss_read_header
(
AVFormatContext
*
s
)
70
{
71
IssDemuxContext
*iss = s->
priv_data
;
72
AVIOContext
*pb = s->
pb
;
73
AVStream
*st;
74
char
token[
MAX_TOKEN_SIZE
];
75
int
stereo, rate_divisor;
76
77
get_token
(pb, token,
sizeof
(token));
//"IMA_ADPCM_Sound"
78
get_token
(pb, token,
sizeof
(token));
//packet size
79
sscanf(token,
"%d"
, &iss->
packet_size
);
80
get_token
(pb, token,
sizeof
(token));
//File ID
81
get_token
(pb, token,
sizeof
(token));
//out size
82
get_token
(pb, token,
sizeof
(token));
//stereo
83
sscanf(token,
"%d"
, &stereo);
84
get_token
(pb, token,
sizeof
(token));
//Unknown1
85
get_token
(pb, token,
sizeof
(token));
//RateDivisor
86
sscanf(token,
"%d"
, &rate_divisor);
87
get_token
(pb, token,
sizeof
(token));
//Unknown2
88
get_token
(pb, token,
sizeof
(token));
//Version ID
89
get_token
(pb, token,
sizeof
(token));
//Size
90
91
if
(iss->
packet_size
<= 0) {
92
av_log
(s,
AV_LOG_ERROR
,
"packet_size %d is invalid\n"
, iss->
packet_size
);
93
return
AVERROR_INVALIDDATA
;
94
}
95
96
iss->
sample_start_pos
=
avio_tell
(pb);
97
98
st =
avformat_new_stream
(s, NULL);
99
if
(!st)
100
return
AVERROR
(ENOMEM);
101
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
102
st->
codec
->
codec_id
=
AV_CODEC_ID_ADPCM_IMA_ISS
;
103
if
(stereo) {
104
st->
codec
->
channels
= 2;
105
st->
codec
->
channel_layout
=
AV_CH_LAYOUT_STEREO
;
106
}
else
{
107
st->
codec
->
channels
= 1;
108
st->
codec
->
channel_layout
=
AV_CH_LAYOUT_MONO
;
109
}
110
st->
codec
->
sample_rate
= 44100;
111
if
(rate_divisor > 0)
112
st->
codec
->
sample_rate
/= rate_divisor;
113
st->
codec
->
bits_per_coded_sample
= 4;
114
st->
codec
->
bit_rate
= st->
codec
->
channels
* st->
codec
->
sample_rate
115
* st->
codec
->
bits_per_coded_sample
;
116
st->
codec
->
block_align
= iss->
packet_size
;
117
avpriv_set_pts_info
(st, 32, 1, st->
codec
->
sample_rate
);
118
119
return
0;
120
}
121
122
static
int
iss_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
123
{
124
IssDemuxContext
*iss = s->
priv_data
;
125
int
ret
=
av_get_packet
(s->
pb
, pkt, iss->
packet_size
);
126
127
if
(ret != iss->
packet_size
)
128
return
AVERROR
(EIO);
129
130
pkt->
stream_index
= 0;
131
pkt->
pts
=
avio_tell
(s->
pb
) - iss->
sample_start_pos
;
132
if
(s->
streams
[0]->
codec
->
channels
> 0)
133
pkt->
pts
/= s->
streams
[0]->
codec
->
channels
*2;
134
return
0;
135
}
136
137
AVInputFormat
ff_iss_demuxer
= {
138
.
name
=
"iss"
,
139
.long_name =
NULL_IF_CONFIG_SMALL
(
"Funcom ISS"
),
140
.priv_data_size =
sizeof
(
IssDemuxContext
),
141
.
read_probe
=
iss_probe
,
142
.
read_header
=
iss_read_header
,
143
.
read_packet
=
iss_read_packet
,
144
};
Generated on Wed Jul 10 2013 23:48:12 for FFmpeg by
1.8.2