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
(type &
SOL_DPCM
)
54
return
AV_CODEC_ID_SOL_DPCM
;
55
56
if
(magic == 0x0B8D)
57
return
AV_CODEC_ID_PCM_U8
;
58
59
if
(type &
SOL_16BIT
)
60
return
AV_CODEC_ID_PCM_S16LE
;
61
62
return
AV_CODEC_ID_PCM_U8
;
63
}
64
65
static
int
sol_codec_type
(
int
magic,
int
type
)
66
{
67
if
(magic == 0x0B8D)
return
1;
//SOL_DPCM_OLD;
68
if
(type &
SOL_DPCM
)
69
{
70
if
(type &
SOL_16BIT
)
return
3;
//SOL_DPCM_NEW16;
71
else
if
(magic == 0x0C8D)
return
1;
//SOL_DPCM_OLD;
72
else
return
2;
//SOL_DPCM_NEW8;
73
}
74
return
-1;
75
}
76
77
static
int
sol_channels
(
int
magic,
int
type
)
78
{
79
if
(magic == 0x0B8D || !(type &
SOL_STEREO
))
return
1;
80
return
2;
81
}
82
83
static
int
sol_read_header
(
AVFormatContext
*
s
)
84
{
85
unsigned
int
magic,
tag
;
86
AVIOContext
*pb = s->
pb
;
87
unsigned
int
id
, channels, rate,
type
;
88
enum
AVCodecID
codec;
89
AVStream
*st;
90
91
/* check ".snd" header */
92
magic =
avio_rl16
(pb);
93
tag =
avio_rl32
(pb);
94
if
(tag !=
MKTAG
(
'S'
,
'O'
,
'L'
, 0))
95
return
-1;
96
rate =
avio_rl16
(pb);
97
type =
avio_r8
(pb);
98
avio_skip
(pb, 4);
/* size */
99
if
(magic != 0x0B8D)
100
avio_r8
(pb);
/* newer SOLs contain padding byte */
101
102
codec =
sol_codec_id
(magic, type);
103
channels =
sol_channels
(magic, type);
104
105
if
(codec ==
AV_CODEC_ID_SOL_DPCM
)
106
id
=
sol_codec_type
(magic, type);
107
else
id
= 0;
108
109
/* now we are ready: build format streams */
110
st =
avformat_new_stream
(s,
NULL
);
111
if
(!st)
112
return
-1;
113
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
114
st->
codec
->
codec_tag
=
id
;
115
st->
codec
->
codec_id
= codec;
116
st->
codec
->
channels
= channels;
117
st->
codec
->
channel_layout
= channels == 1 ?
AV_CH_LAYOUT_MONO
:
118
AV_CH_LAYOUT_STEREO
;
119
st->
codec
->
sample_rate
= rate;
120
avpriv_set_pts_info
(st, 64, 1, rate);
121
return
0;
122
}
123
124
#define MAX_SIZE 4096
125
126
static
int
sol_read_packet
(
AVFormatContext
*
s
,
127
AVPacket
*
pkt
)
128
{
129
int
ret
;
130
131
if
(
avio_feof
(s->
pb
))
132
return
AVERROR
(EIO);
133
ret=
av_get_packet
(s->
pb
, pkt,
MAX_SIZE
);
134
if
(ret < 0)
135
return
ret
;
136
pkt->
flags
&= ~
AV_PKT_FLAG_CORRUPT
;
137
pkt->
stream_index
= 0;
138
return
0;
139
}
140
141
AVInputFormat
ff_sol_demuxer
= {
142
.
name
=
"sol"
,
143
.long_name =
NULL_IF_CONFIG_SMALL
(
"Sierra SOL"
),
144
.read_probe =
sol_probe
,
145
.read_header =
sol_read_header
,
146
.read_packet =
sol_read_packet
,
147
.read_seek =
ff_pcm_read_seek
,
148
};
Generated on Sun Mar 8 2015 02:35:12 for FFmpeg by
1.8.2