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
wvdec.c
Go to the documentation of this file.
1
/*
2
* WavPack demuxer
3
* Copyright (c) 2006,2011 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
#include "
libavutil/channel_layout.h
"
23
#include "
libavutil/intreadwrite.h
"
24
#include "
libavutil/dict.h
"
25
#include "
avformat.h
"
26
#include "
internal.h
"
27
#include "
apetag.h
"
28
#include "
id3v1.h
"
29
#include "
wv.h
"
30
31
enum
WV_FLAGS
{
32
WV_MONO
= 0x0004,
33
WV_HYBRID
= 0x0008,
34
WV_JOINT
= 0x0010,
35
WV_CROSSD
= 0x0020,
36
WV_HSHAPE
= 0x0040,
37
WV_FLOAT
= 0x0080,
38
WV_INT32
= 0x0100,
39
WV_HBR
= 0x0200,
40
WV_HBAL
= 0x0400,
41
WV_MCINIT
= 0x0800,
42
WV_MCEND
= 0x1000,
43
};
44
45
static
const
int
wv_rates
[16] = {
46
6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000,
47
32000, 44100, 48000, 64000, 88200, 96000, 192000, -1
48
};
49
50
typedef
struct
{
51
uint8_t
block_header[
WV_HEADER_SIZE
];
52
WvHeader
header
;
53
int
rate
, chan, bpp;
54
uint32_t
chmask
;
55
int
multichannel
;
56
int
block_parsed
;
57
int64_t
pos
;
58
59
int64_t
apetag_start
;
60
}
WVContext
;
61
62
static
int
wv_probe
(
AVProbeData
*p)
63
{
64
/* check file header */
65
if
(p->
buf_size
<= 32)
66
return
0;
67
if
(
AV_RL32
(&p->
buf
[0]) ==
MKTAG
(
'w'
,
'v'
,
'p'
,
'k'
) &&
68
AV_RL32
(&p->
buf
[4]) >= 24 &&
69
AV_RL32
(&p->
buf
[4]) <=
WV_BLOCK_LIMIT
&&
70
AV_RL16
(&p->
buf
[8]) >= 0x402 &&
71
AV_RL16
(&p->
buf
[8]) <= 0x410)
72
return
AVPROBE_SCORE_MAX
;
73
else
74
return
0;
75
}
76
77
static
int
wv_read_block_header
(
AVFormatContext
*ctx,
AVIOContext
*pb)
78
{
79
WVContext
*wc = ctx->
priv_data
;
80
int
ret
;
81
int
rate, bpp, chan;
82
uint32_t chmask,
flags
;
83
84
wc->
pos
=
avio_tell
(pb);
85
86
/* don't return bogus packets with the ape tag data */
87
if
(wc->
apetag_start
&& wc->
pos
>= wc->
apetag_start
)
88
return
AVERROR_EOF
;
89
90
ret =
avio_read
(pb, wc->
block_header
,
WV_HEADER_SIZE
);
91
if
(ret !=
WV_HEADER_SIZE
)
92
return
(ret < 0) ? ret :
AVERROR_EOF
;
93
94
ret =
ff_wv_parse_header
(&wc->
header
, wc->
block_header
);
95
if
(ret < 0) {
96
av_log
(ctx,
AV_LOG_ERROR
,
"Invalid block header.\n"
);
97
return
ret
;
98
}
99
100
if
(wc->
header
.
version
< 0x402 || wc->
header
.
version
> 0x410) {
101
av_log
(ctx,
AV_LOG_ERROR
,
"Unsupported version %03X\n"
, wc->
header
.
version
);
102
return
AVERROR_PATCHWELCOME
;
103
}
104
105
/* Blocks with zero samples don't contain actual audio information
106
* and should be ignored */
107
if
(!wc->
header
.
samples
)
108
return
0;
109
// parse flags
110
flags = wc->
header
.
flags
;
111
bpp = ((flags & 3) + 1) << 3;
112
chan = 1 + !(flags &
WV_MONO
);
113
chmask = flags &
WV_MONO
?
AV_CH_LAYOUT_MONO
:
AV_CH_LAYOUT_STEREO
;
114
rate =
wv_rates
[(flags >> 23) & 0xF];
115
wc->
multichannel
= !(wc->
header
.
initial
&& wc->
header
.
final
);
116
if
(wc->
multichannel
) {
117
chan = wc->
chan
;
118
chmask = wc->
chmask
;
119
}
120
if
((rate == -1 || !chan) && !wc->
block_parsed
) {
121
int64_t block_end =
avio_tell
(pb) + wc->
header
.
blocksize
;
122
if
(!pb->
seekable
) {
123
av_log
(ctx,
AV_LOG_ERROR
,
124
"Cannot determine additional parameters\n"
);
125
return
AVERROR_INVALIDDATA
;
126
}
127
while
(
avio_tell
(pb) < block_end && !
avio_feof
(pb)) {
128
int
id
,
size
;
129
id
=
avio_r8
(pb);
130
size = (
id
& 0x80) ?
avio_rl24
(pb) :
avio_r8
(pb);
131
size <<= 1;
132
if
(
id
& 0x40)
133
size--;
134
switch
(
id
& 0x3F) {
135
case
0xD:
136
if
(size <= 1) {
137
av_log
(ctx,
AV_LOG_ERROR
,
138
"Insufficient channel information\n"
);
139
return
AVERROR_INVALIDDATA
;
140
}
141
chan =
avio_r8
(pb);
142
switch
(size - 2) {
143
case
0:
144
chmask =
avio_r8
(pb);
145
break
;
146
case
1:
147
chmask =
avio_rl16
(pb);
148
break
;
149
case
2:
150
chmask =
avio_rl24
(pb);
151
break
;
152
case
3:
153
chmask =
avio_rl32
(pb);
154
break
;
155
case
5:
156
avio_skip
(pb, 1);
157
chan |= (
avio_r8
(pb) & 0xF) << 8;
158
chmask =
avio_rl24
(pb);
159
break
;
160
default
:
161
av_log
(ctx,
AV_LOG_ERROR
,
162
"Invalid channel info size %d\n"
, size);
163
return
AVERROR_INVALIDDATA
;
164
}
165
break
;
166
case
0x27:
167
rate =
avio_rl24
(pb);
168
break
;
169
default
:
170
avio_skip
(pb, size);
171
}
172
if
(
id
& 0x40)
173
avio_skip
(pb, 1);
174
}
175
if
(rate == -1) {
176
av_log
(ctx,
AV_LOG_ERROR
,
177
"Cannot determine custom sampling rate\n"
);
178
return
AVERROR_INVALIDDATA
;
179
}
180
avio_seek
(pb, block_end - wc->
header
.
blocksize
, SEEK_SET);
181
}
182
if
(!wc->
bpp
)
183
wc->
bpp
= bpp;
184
if
(!wc->
chan
)
185
wc->
chan
= chan;
186
if
(!wc->
chmask
)
187
wc->
chmask
= chmask;
188
if
(!wc->
rate
)
189
wc->
rate
= rate;
190
191
if
(flags && bpp != wc->
bpp
) {
192
av_log
(ctx,
AV_LOG_ERROR
,
193
"Bits per sample differ, this block: %i, header block: %i\n"
,
194
bpp, wc->
bpp
);
195
return
AVERROR_INVALIDDATA
;
196
}
197
if
(flags && !wc->
multichannel
&& chan != wc->
chan
) {
198
av_log
(ctx,
AV_LOG_ERROR
,
199
"Channels differ, this block: %i, header block: %i\n"
,
200
chan, wc->
chan
);
201
return
AVERROR_INVALIDDATA
;
202
}
203
if
(flags && rate != -1 && rate != wc->
rate
) {
204
av_log
(ctx,
AV_LOG_ERROR
,
205
"Sampling rate differ, this block: %i, header block: %i\n"
,
206
rate, wc->
rate
);
207
return
AVERROR_INVALIDDATA
;
208
}
209
return
0;
210
}
211
212
static
int
wv_read_header
(
AVFormatContext
*
s
)
213
{
214
AVIOContext
*pb = s->
pb
;
215
WVContext
*wc = s->
priv_data
;
216
AVStream
*st;
217
int
ret
;
218
219
wc->
block_parsed
= 0;
220
for
(;;) {
221
if
((ret =
wv_read_block_header
(s, pb)) < 0)
222
return
ret
;
223
if
(!wc->
header
.
samples
)
224
avio_skip
(pb, wc->
header
.
blocksize
);
225
else
226
break
;
227
}
228
229
/* now we are ready: build format streams */
230
st =
avformat_new_stream
(s, NULL);
231
if
(!st)
232
return
AVERROR
(ENOMEM);
233
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
234
st->
codec
->
codec_id
=
AV_CODEC_ID_WAVPACK
;
235
st->
codec
->
channels
= wc->
chan
;
236
st->
codec
->
channel_layout
= wc->
chmask
;
237
st->
codec
->
sample_rate
= wc->
rate
;
238
st->
codec
->
bits_per_coded_sample
= wc->
bpp
;
239
avpriv_set_pts_info
(st, 64, 1, wc->
rate
);
240
st->
start_time
= 0;
241
if
(wc->
header
.
total_samples
!= 0xFFFFFFFFu)
242
st->
duration
= wc->
header
.
total_samples
;
243
244
if
(s->
pb
->
seekable
) {
245
int64_t cur =
avio_tell
(s->
pb
);
246
wc->
apetag_start
=
ff_ape_parse_tag
(s);
247
if
(!
av_dict_get
(s->
metadata
,
""
, NULL,
AV_DICT_IGNORE_SUFFIX
))
248
ff_id3v1_read
(s);
249
avio_seek
(s->
pb
, cur, SEEK_SET);
250
}
251
252
return
0;
253
}
254
255
static
int
wv_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
256
{
257
WVContext
*wc = s->
priv_data
;
258
int
ret
;
259
int
off;
260
int64_t pos;
261
uint32_t block_samples;
262
263
if
(
avio_feof
(s->
pb
))
264
return
AVERROR_EOF
;
265
if
(wc->
block_parsed
) {
266
if
((ret =
wv_read_block_header
(s, s->
pb
)) < 0)
267
return
ret
;
268
}
269
270
pos = wc->
pos
;
271
if
(
av_new_packet
(pkt, wc->
header
.
blocksize
+
WV_HEADER_SIZE
) < 0)
272
return
AVERROR
(ENOMEM);
273
memcpy(pkt->
data
, wc->
block_header
,
WV_HEADER_SIZE
);
274
ret =
avio_read
(s->
pb
, pkt->
data
+
WV_HEADER_SIZE
, wc->
header
.
blocksize
);
275
if
(ret != wc->
header
.
blocksize
) {
276
av_free_packet
(pkt);
277
return
AVERROR
(EIO);
278
}
279
while
(!(wc->
header
.
flags
&
WV_FLAG_FINAL_BLOCK
)) {
280
if
((ret =
wv_read_block_header
(s, s->
pb
)) < 0) {
281
av_free_packet
(pkt);
282
return
ret
;
283
}
284
285
off = pkt->
size
;
286
if
((ret =
av_grow_packet
(pkt,
WV_HEADER_SIZE
+ wc->
header
.
blocksize
)) < 0) {
287
av_free_packet
(pkt);
288
return
ret
;
289
}
290
memcpy(pkt->
data
+ off, wc->
block_header
,
WV_HEADER_SIZE
);
291
292
ret =
avio_read
(s->
pb
, pkt->
data
+ off +
WV_HEADER_SIZE
, wc->
header
.
blocksize
);
293
if
(ret != wc->
header
.
blocksize
) {
294
av_free_packet
(pkt);
295
return
(ret < 0) ? ret :
AVERROR_EOF
;
296
}
297
}
298
pkt->
stream_index
= 0;
299
wc->
block_parsed
= 1;
300
pkt->
pts
= wc->
header
.
block_idx
;
301
block_samples = wc->
header
.
samples
;
302
if
(block_samples > INT32_MAX)
303
av_log
(s,
AV_LOG_WARNING
,
304
"Too many samples in block: %"
PRIu32
"\n"
, block_samples);
305
else
306
pkt->
duration
= block_samples;
307
308
av_add_index_entry
(s->
streams
[0], pos, pkt->
pts
, 0, 0,
AVINDEX_KEYFRAME
);
309
return
0;
310
}
311
312
static
int
wv_read_seek
(
AVFormatContext
*
s
,
int
stream_index,
313
int64_t timestamp,
int
flags
)
314
{
315
AVStream
*st = s->
streams
[stream_index];
316
WVContext
*wc = s->
priv_data
;
317
AVPacket
pkt1, *
pkt
= &pkt1;
318
int
ret
;
319
int
index
=
av_index_search_timestamp
(st, timestamp, flags);
320
int64_t pos, pts;
321
322
/* if found, seek there */
323
if
(index >= 0 &&
324
timestamp <= st->index_entries[st->
nb_index_entries
- 1].timestamp) {
325
wc->
block_parsed
= 1;
326
avio_seek
(s->
pb
, st->
index_entries
[index].
pos
, SEEK_SET);
327
return
0;
328
}
329
/* if timestamp is out of bounds, return error */
330
if
(timestamp < 0 || timestamp >= s->
duration
)
331
return
AVERROR
(EINVAL);
332
333
pos =
avio_tell
(s->
pb
);
334
do
{
335
ret =
av_read_frame
(s, pkt);
336
if
(ret < 0) {
337
avio_seek
(s->
pb
, pos, SEEK_SET);
338
return
ret
;
339
}
340
pts = pkt->
pts
;
341
av_free_packet
(pkt);
342
}
while
(pts < timestamp);
343
return
0;
344
}
345
346
AVInputFormat
ff_wv_demuxer
= {
347
.
name
=
"wv"
,
348
.long_name =
NULL_IF_CONFIG_SMALL
(
"WavPack"
),
349
.priv_data_size =
sizeof
(
WVContext
),
350
.
read_probe
=
wv_probe
,
351
.
read_header
=
wv_read_header
,
352
.
read_packet
=
wv_read_packet
,
353
.
read_seek
=
wv_read_seek
,
354
};
Generated on Sun Sep 14 2014 18:56:16 for FFmpeg by
1.8.2