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
sol.c
Go to the documentation of this file.
1
/*
2
* Sierra SOL demuxer
3
* Copyright Konstantin Shishkov
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
* Based on documents from Game Audio Player and own research
24
*/
25
26
#include "
libavutil/channel_layout.h
"
27
#include "
libavutil/intreadwrite.h
"
28
#include "
avformat.h
"
29
#include "
internal.h
"
30
#include "
pcm.h
"
31
32
/* if we don't know the size in advance */
33
#define AU_UNKNOWN_SIZE ((uint32_t)(~0))
34
35
static
int
sol_probe
(
AVProbeData
*p)
36
{
37
/* check file header */
38
uint16_t magic =
AV_RL32
(p->
buf
);
39
if
((magic == 0x0B8D || magic == 0x0C0D || magic == 0x0C8D) &&
40
p->
buf
[2] ==
'S'
&& p->
buf
[3] ==
'O'
&&
41
p->
buf
[4] ==
'L'
&& p->
buf
[5] == 0)
42
return
AVPROBE_SCORE_MAX
;
43
else
44
return
0;
45
}
46
47
#define SOL_DPCM 1
48
#define SOL_16BIT 4
49
#define SOL_STEREO 16
50
51
static
enum
AVCodecID
sol_codec_id
(
int
magic,
int
type
)
52
{
53
if
(magic == 0x0B8D)
54
{
55
if
(type &
SOL_DPCM
)
return
AV_CODEC_ID_SOL_DPCM
;
56
else
return
AV_CODEC_ID_PCM_U8
;
57
}
58
if
(type &
SOL_DPCM
)
59
{
60
if
(type &
SOL_16BIT
)
return
AV_CODEC_ID_SOL_DPCM
;
61
else
if
(magic == 0x0C8D)
return
AV_CODEC_ID_SOL_DPCM
;
62
else
return
AV_CODEC_ID_SOL_DPCM
;
63
}
64
if
(type &
SOL_16BIT
)
return
AV_CODEC_ID_PCM_S16LE
;
65
return
AV_CODEC_ID_PCM_U8
;
66
}
67
68
static
int
sol_codec_type
(
int
magic,
int
type
)
69
{
70
if
(magic == 0x0B8D)
return
1;
//SOL_DPCM_OLD;
71
if
(type &
SOL_DPCM
)
72
{
73
if
(type &
SOL_16BIT
)
return
3;
//SOL_DPCM_NEW16;
74
else
if
(magic == 0x0C8D)
return
1;
//SOL_DPCM_OLD;
75
else
return
2;
//SOL_DPCM_NEW8;
76
}
77
return
-1;
78
}
79
80
static
int
sol_channels
(
int
magic,
int
type
)
81
{
82
if
(magic == 0x0B8D || !(type &
SOL_STEREO
))
return
1;
83
return
2;
84
}
85
86
static
int
sol_read_header
(
AVFormatContext
*
s
)
87
{
88
unsigned
int
magic,
tag
;
89
AVIOContext
*pb = s->
pb
;
90
unsigned
int
id
, channels, rate,
type
;
91
enum
AVCodecID
codec;
92
AVStream
*st;
93
94
/* check ".snd" header */
95
magic =
avio_rl16
(pb);
96
tag =
avio_rl32
(pb);
97
if
(tag !=
MKTAG
(
'S'
,
'O'
,
'L'
, 0))
98
return
-1;
99
rate =
avio_rl16
(pb);
100
type =
avio_r8
(pb);
101
avio_skip
(pb, 4);
/* size */
102
if
(magic != 0x0B8D)
103
avio_r8
(pb);
/* newer SOLs contain padding byte */
104
105
codec =
sol_codec_id
(magic, type);
106
channels =
sol_channels
(magic, type);
107
108
if
(codec ==
AV_CODEC_ID_SOL_DPCM
)
109
id
=
sol_codec_type
(magic, type);
110
else
id
= 0;
111
112
/* now we are ready: build format streams */
113
st =
avformat_new_stream
(s, NULL);
114
if
(!st)
115
return
-1;
116
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
117
st->
codec
->
codec_tag
=
id
;
118
st->
codec
->
codec_id
= codec;
119
st->
codec
->
channels
= channels;
120
st->
codec
->
channel_layout
= channels == 1 ?
AV_CH_LAYOUT_MONO
:
121
AV_CH_LAYOUT_STEREO
;
122
st->
codec
->
sample_rate
= rate;
123
avpriv_set_pts_info
(st, 64, 1, rate);
124
return
0;
125
}
126
127
#define MAX_SIZE 4096
128
129
static
int
sol_read_packet
(
AVFormatContext
*
s
,
130
AVPacket
*
pkt
)
131
{
132
int
ret
;
133
134
if
(
url_feof
(s->
pb
))
135
return
AVERROR
(EIO);
136
ret=
av_get_packet
(s->
pb
, pkt,
MAX_SIZE
);
137
if
(ret < 0)
138
return
ret
;
139
pkt->
flags
&= ~
AV_PKT_FLAG_CORRUPT
;
140
pkt->
stream_index
= 0;
141
return
0;
142
}
143
144
AVInputFormat
ff_sol_demuxer
= {
145
.
name
=
"sol"
,
146
.long_name =
NULL_IF_CONFIG_SMALL
(
"Sierra SOL"
),
147
.read_probe =
sol_probe
,
148
.read_header =
sol_read_header
,
149
.read_packet =
sol_read_packet
,
150
.read_seek =
ff_pcm_read_seek
,
151
};
Generated on Sun Mar 23 2014 23:50:13 for FFmpeg by
1.8.2