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 Fri Dec 5 2014 04:42:14 for FFmpeg by
1.8.2