ffmpeg / libavformat / ape.c @ 29a29043
History | View | Annotate | Download (14.6 KB)
1 |
/*
|
---|---|
2 |
* Monkey's Audio APE demuxer
|
3 |
* Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
|
4 |
* based upon libdemac from Dave Chapman.
|
5 |
*
|
6 |
* This file is part of Libav.
|
7 |
*
|
8 |
* Libav is free software; you can redistribute it and/or
|
9 |
* modify it under the terms of the GNU Lesser General Public
|
10 |
* License as published by the Free Software Foundation; either
|
11 |
* version 2.1 of the License, or (at your option) any later version.
|
12 |
*
|
13 |
* Libav is distributed in the hope that it will be useful,
|
14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
16 |
* Lesser General Public License for more details.
|
17 |
*
|
18 |
* You should have received a copy of the GNU Lesser General Public
|
19 |
* License along with Libav; if not, write to the Free Software
|
20 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21 |
*/
|
22 |
|
23 |
#include <stdio.h> |
24 |
|
25 |
#include "libavutil/intreadwrite.h" |
26 |
#include "avformat.h" |
27 |
#include "apetag.h" |
28 |
|
29 |
#define ENABLE_DEBUG 0 |
30 |
|
31 |
/* The earliest and latest file formats supported by this library */
|
32 |
#define APE_MIN_VERSION 3950 |
33 |
#define APE_MAX_VERSION 3990 |
34 |
|
35 |
#define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit [OBSOLETE] |
36 |
#define MAC_FORMAT_FLAG_CRC 2 // uses the new CRC32 error detection [OBSOLETE] |
37 |
#define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL 4 // uint32 nPeakLevel after the header [OBSOLETE] |
38 |
#define MAC_FORMAT_FLAG_24_BIT 8 // is 24-bit [OBSOLETE] |
39 |
#define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS 16 // has the number of seek elements after the peak level |
40 |
#define MAC_FORMAT_FLAG_CREATE_WAV_HEADER 32 // create the wave header on decompression (not stored) |
41 |
|
42 |
#define MAC_SUBFRAME_SIZE 4608 |
43 |
|
44 |
#define APE_EXTRADATA_SIZE 6 |
45 |
|
46 |
typedef struct { |
47 |
int64_t pos; |
48 |
int nblocks;
|
49 |
int size;
|
50 |
int skip;
|
51 |
int64_t pts; |
52 |
} APEFrame; |
53 |
|
54 |
typedef struct { |
55 |
/* Derived fields */
|
56 |
uint32_t junklength; |
57 |
uint32_t firstframe; |
58 |
uint32_t totalsamples; |
59 |
int currentframe;
|
60 |
APEFrame *frames; |
61 |
|
62 |
/* Info from Descriptor Block */
|
63 |
char magic[4]; |
64 |
int16_t fileversion; |
65 |
int16_t padding1; |
66 |
uint32_t descriptorlength; |
67 |
uint32_t headerlength; |
68 |
uint32_t seektablelength; |
69 |
uint32_t wavheaderlength; |
70 |
uint32_t audiodatalength; |
71 |
uint32_t audiodatalength_high; |
72 |
uint32_t wavtaillength; |
73 |
uint8_t md5[16];
|
74 |
|
75 |
/* Info from Header Block */
|
76 |
uint16_t compressiontype; |
77 |
uint16_t formatflags; |
78 |
uint32_t blocksperframe; |
79 |
uint32_t finalframeblocks; |
80 |
uint32_t totalframes; |
81 |
uint16_t bps; |
82 |
uint16_t channels; |
83 |
uint32_t samplerate; |
84 |
|
85 |
/* Seektable */
|
86 |
uint32_t *seektable; |
87 |
} APEContext; |
88 |
|
89 |
static int ape_probe(AVProbeData * p) |
90 |
{ |
91 |
if (p->buf[0] == 'M' && p->buf[1] == 'A' && p->buf[2] == 'C' && p->buf[3] == ' ') |
92 |
return AVPROBE_SCORE_MAX;
|
93 |
|
94 |
return 0; |
95 |
} |
96 |
|
97 |
static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx) |
98 |
{ |
99 |
#if ENABLE_DEBUG
|
100 |
int i;
|
101 |
|
102 |
av_log(s, AV_LOG_DEBUG, "Descriptor Block:\n\n");
|
103 |
av_log(s, AV_LOG_DEBUG, "magic = \"%c%c%c%c\"\n", ape_ctx->magic[0], ape_ctx->magic[1], ape_ctx->magic[2], ape_ctx->magic[3]); |
104 |
av_log(s, AV_LOG_DEBUG, "fileversion = %d\n", ape_ctx->fileversion);
|
105 |
av_log(s, AV_LOG_DEBUG, "descriptorlength = %d\n", ape_ctx->descriptorlength);
|
106 |
av_log(s, AV_LOG_DEBUG, "headerlength = %d\n", ape_ctx->headerlength);
|
107 |
av_log(s, AV_LOG_DEBUG, "seektablelength = %d\n", ape_ctx->seektablelength);
|
108 |
av_log(s, AV_LOG_DEBUG, "wavheaderlength = %d\n", ape_ctx->wavheaderlength);
|
109 |
av_log(s, AV_LOG_DEBUG, "audiodatalength = %d\n", ape_ctx->audiodatalength);
|
110 |
av_log(s, AV_LOG_DEBUG, "audiodatalength_high = %d\n", ape_ctx->audiodatalength_high);
|
111 |
av_log(s, AV_LOG_DEBUG, "wavtaillength = %d\n", ape_ctx->wavtaillength);
|
112 |
av_log(s, AV_LOG_DEBUG, "md5 = ");
|
113 |
for (i = 0; i < 16; i++) |
114 |
av_log(s, AV_LOG_DEBUG, "%02x", ape_ctx->md5[i]);
|
115 |
av_log(s, AV_LOG_DEBUG, "\n");
|
116 |
|
117 |
av_log(s, AV_LOG_DEBUG, "\nHeader Block:\n\n");
|
118 |
|
119 |
av_log(s, AV_LOG_DEBUG, "compressiontype = %d\n", ape_ctx->compressiontype);
|
120 |
av_log(s, AV_LOG_DEBUG, "formatflags = %d\n", ape_ctx->formatflags);
|
121 |
av_log(s, AV_LOG_DEBUG, "blocksperframe = %d\n", ape_ctx->blocksperframe);
|
122 |
av_log(s, AV_LOG_DEBUG, "finalframeblocks = %d\n", ape_ctx->finalframeblocks);
|
123 |
av_log(s, AV_LOG_DEBUG, "totalframes = %d\n", ape_ctx->totalframes);
|
124 |
av_log(s, AV_LOG_DEBUG, "bps = %d\n", ape_ctx->bps);
|
125 |
av_log(s, AV_LOG_DEBUG, "channels = %d\n", ape_ctx->channels);
|
126 |
av_log(s, AV_LOG_DEBUG, "samplerate = %d\n", ape_ctx->samplerate);
|
127 |
|
128 |
av_log(s, AV_LOG_DEBUG, "\nSeektable\n\n");
|
129 |
if ((ape_ctx->seektablelength / sizeof(uint32_t)) != ape_ctx->totalframes) { |
130 |
av_log(s, AV_LOG_DEBUG, "No seektable\n");
|
131 |
} else {
|
132 |
for (i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++) { |
133 |
if (i < ape_ctx->totalframes - 1) { |
134 |
av_log(s, AV_LOG_DEBUG, "%8d %d (%d bytes)\n", i, ape_ctx->seektable[i], ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]); |
135 |
} else {
|
136 |
av_log(s, AV_LOG_DEBUG, "%8d %d\n", i, ape_ctx->seektable[i]);
|
137 |
} |
138 |
} |
139 |
} |
140 |
|
141 |
av_log(s, AV_LOG_DEBUG, "\nFrames\n\n");
|
142 |
for (i = 0; i < ape_ctx->totalframes; i++) |
143 |
av_log(s, AV_LOG_DEBUG, "%8d %8lld %8d (%d samples)\n", i, ape_ctx->frames[i].pos, ape_ctx->frames[i].size, ape_ctx->frames[i].nblocks);
|
144 |
|
145 |
av_log(s, AV_LOG_DEBUG, "\nCalculated information:\n\n");
|
146 |
av_log(s, AV_LOG_DEBUG, "junklength = %d\n", ape_ctx->junklength);
|
147 |
av_log(s, AV_LOG_DEBUG, "firstframe = %d\n", ape_ctx->firstframe);
|
148 |
av_log(s, AV_LOG_DEBUG, "totalsamples = %d\n", ape_ctx->totalsamples);
|
149 |
#endif
|
150 |
} |
151 |
|
152 |
static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) |
153 |
{ |
154 |
AVIOContext *pb = s->pb; |
155 |
APEContext *ape = s->priv_data; |
156 |
AVStream *st; |
157 |
uint32_t tag; |
158 |
int i;
|
159 |
int total_blocks;
|
160 |
int64_t pts; |
161 |
|
162 |
/* TODO: Skip any leading junk such as id3v2 tags */
|
163 |
ape->junklength = 0;
|
164 |
|
165 |
tag = avio_rl32(pb); |
166 |
if (tag != MKTAG('M', 'A', 'C', ' ')) |
167 |
return -1; |
168 |
|
169 |
ape->fileversion = avio_rl16(pb); |
170 |
|
171 |
if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) {
|
172 |
av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10); |
173 |
return -1; |
174 |
} |
175 |
|
176 |
if (ape->fileversion >= 3980) { |
177 |
ape->padding1 = avio_rl16(pb); |
178 |
ape->descriptorlength = avio_rl32(pb); |
179 |
ape->headerlength = avio_rl32(pb); |
180 |
ape->seektablelength = avio_rl32(pb); |
181 |
ape->wavheaderlength = avio_rl32(pb); |
182 |
ape->audiodatalength = avio_rl32(pb); |
183 |
ape->audiodatalength_high = avio_rl32(pb); |
184 |
ape->wavtaillength = avio_rl32(pb); |
185 |
avio_read(pb, ape->md5, 16);
|
186 |
|
187 |
/* Skip any unknown bytes at the end of the descriptor.
|
188 |
This is for future compatibility */
|
189 |
if (ape->descriptorlength > 52) |
190 |
avio_skip(pb, ape->descriptorlength - 52);
|
191 |
|
192 |
/* Read header data */
|
193 |
ape->compressiontype = avio_rl16(pb); |
194 |
ape->formatflags = avio_rl16(pb); |
195 |
ape->blocksperframe = avio_rl32(pb); |
196 |
ape->finalframeblocks = avio_rl32(pb); |
197 |
ape->totalframes = avio_rl32(pb); |
198 |
ape->bps = avio_rl16(pb); |
199 |
ape->channels = avio_rl16(pb); |
200 |
ape->samplerate = avio_rl32(pb); |
201 |
} else {
|
202 |
ape->descriptorlength = 0;
|
203 |
ape->headerlength = 32;
|
204 |
|
205 |
ape->compressiontype = avio_rl16(pb); |
206 |
ape->formatflags = avio_rl16(pb); |
207 |
ape->channels = avio_rl16(pb); |
208 |
ape->samplerate = avio_rl32(pb); |
209 |
ape->wavheaderlength = avio_rl32(pb); |
210 |
ape->wavtaillength = avio_rl32(pb); |
211 |
ape->totalframes = avio_rl32(pb); |
212 |
ape->finalframeblocks = avio_rl32(pb); |
213 |
|
214 |
if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) {
|
215 |
avio_skip(pb, 4); /* Skip the peak level */ |
216 |
ape->headerlength += 4;
|
217 |
} |
218 |
|
219 |
if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) {
|
220 |
ape->seektablelength = avio_rl32(pb); |
221 |
ape->headerlength += 4;
|
222 |
ape->seektablelength *= sizeof(int32_t);
|
223 |
} else
|
224 |
ape->seektablelength = ape->totalframes * sizeof(int32_t);
|
225 |
|
226 |
if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT)
|
227 |
ape->bps = 8;
|
228 |
else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT) |
229 |
ape->bps = 24;
|
230 |
else
|
231 |
ape->bps = 16;
|
232 |
|
233 |
if (ape->fileversion >= 3950) |
234 |
ape->blocksperframe = 73728 * 4; |
235 |
else if (ape->fileversion >= 3900 || (ape->fileversion >= 3800 && ape->compressiontype >= 4000)) |
236 |
ape->blocksperframe = 73728;
|
237 |
else
|
238 |
ape->blocksperframe = 9216;
|
239 |
|
240 |
/* Skip any stored wav header */
|
241 |
if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER))
|
242 |
avio_skip(pb, ape->wavheaderlength); |
243 |
} |
244 |
|
245 |
if(!ape->totalframes){
|
246 |
av_log(s, AV_LOG_ERROR, "No frames in the file!\n");
|
247 |
return AVERROR(EINVAL);
|
248 |
} |
249 |
if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){ |
250 |
av_log(s, AV_LOG_ERROR, "Too many frames: %d\n", ape->totalframes);
|
251 |
return -1; |
252 |
} |
253 |
if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) { |
254 |
av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %d vs. %d\n",
|
255 |
ape->seektablelength / sizeof(*ape->seektable), ape->totalframes);
|
256 |
return AVERROR_INVALIDDATA;
|
257 |
} |
258 |
ape->frames = av_malloc(ape->totalframes * sizeof(APEFrame));
|
259 |
if(!ape->frames)
|
260 |
return AVERROR(ENOMEM);
|
261 |
ape->firstframe = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength; |
262 |
ape->currentframe = 0;
|
263 |
|
264 |
|
265 |
ape->totalsamples = ape->finalframeblocks; |
266 |
if (ape->totalframes > 1) |
267 |
ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1);
|
268 |
|
269 |
if (ape->seektablelength > 0) { |
270 |
ape->seektable = av_malloc(ape->seektablelength); |
271 |
for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++) |
272 |
ape->seektable[i] = avio_rl32(pb); |
273 |
} |
274 |
|
275 |
ape->frames[0].pos = ape->firstframe;
|
276 |
ape->frames[0].nblocks = ape->blocksperframe;
|
277 |
ape->frames[0].skip = 0; |
278 |
for (i = 1; i < ape->totalframes; i++) { |
279 |
ape->frames[i].pos = ape->seektable[i]; //ape->frames[i-1].pos + ape->blocksperframe;
|
280 |
ape->frames[i].nblocks = ape->blocksperframe; |
281 |
ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; |
282 |
ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; |
283 |
} |
284 |
ape->frames[ape->totalframes - 1].size = ape->finalframeblocks * 4; |
285 |
ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks;
|
286 |
|
287 |
for (i = 0; i < ape->totalframes; i++) { |
288 |
if(ape->frames[i].skip){
|
289 |
ape->frames[i].pos -= ape->frames[i].skip; |
290 |
ape->frames[i].size += ape->frames[i].skip; |
291 |
} |
292 |
ape->frames[i].size = (ape->frames[i].size + 3) & ~3; |
293 |
} |
294 |
|
295 |
|
296 |
ape_dumpinfo(s, ape); |
297 |
|
298 |
/* try to read APE tags */
|
299 |
if (!url_is_streamed(pb)) {
|
300 |
ff_ape_parse_tag(s); |
301 |
avio_seek(pb, 0, SEEK_SET);
|
302 |
} |
303 |
|
304 |
av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10, ape->compressiontype); |
305 |
|
306 |
/* now we are ready: build format streams */
|
307 |
st = av_new_stream(s, 0);
|
308 |
if (!st)
|
309 |
return -1; |
310 |
|
311 |
total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks; |
312 |
|
313 |
st->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
314 |
st->codec->codec_id = CODEC_ID_APE; |
315 |
st->codec->codec_tag = MKTAG('A', 'P', 'E', ' '); |
316 |
st->codec->channels = ape->channels; |
317 |
st->codec->sample_rate = ape->samplerate; |
318 |
st->codec->bits_per_coded_sample = ape->bps; |
319 |
st->codec->frame_size = MAC_SUBFRAME_SIZE; |
320 |
|
321 |
st->nb_frames = ape->totalframes; |
322 |
st->start_time = 0;
|
323 |
st->duration = total_blocks / MAC_SUBFRAME_SIZE; |
324 |
av_set_pts_info(st, 64, MAC_SUBFRAME_SIZE, ape->samplerate);
|
325 |
|
326 |
st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE); |
327 |
st->codec->extradata_size = APE_EXTRADATA_SIZE; |
328 |
AV_WL16(st->codec->extradata + 0, ape->fileversion);
|
329 |
AV_WL16(st->codec->extradata + 2, ape->compressiontype);
|
330 |
AV_WL16(st->codec->extradata + 4, ape->formatflags);
|
331 |
|
332 |
pts = 0;
|
333 |
for (i = 0; i < ape->totalframes; i++) { |
334 |
ape->frames[i].pts = pts; |
335 |
av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME); |
336 |
pts += ape->blocksperframe / MAC_SUBFRAME_SIZE; |
337 |
} |
338 |
|
339 |
return 0; |
340 |
} |
341 |
|
342 |
static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) |
343 |
{ |
344 |
int ret;
|
345 |
int nblocks;
|
346 |
APEContext *ape = s->priv_data; |
347 |
uint32_t extra_size = 8;
|
348 |
|
349 |
if (s->pb->eof_reached)
|
350 |
return AVERROR(EIO);
|
351 |
if (ape->currentframe > ape->totalframes)
|
352 |
return AVERROR(EIO);
|
353 |
|
354 |
avio_seek (s->pb, ape->frames[ape->currentframe].pos, SEEK_SET); |
355 |
|
356 |
/* Calculate how many blocks there are in this frame */
|
357 |
if (ape->currentframe == (ape->totalframes - 1)) |
358 |
nblocks = ape->finalframeblocks; |
359 |
else
|
360 |
nblocks = ape->blocksperframe; |
361 |
|
362 |
if (av_new_packet(pkt, ape->frames[ape->currentframe].size + extra_size) < 0) |
363 |
return AVERROR(ENOMEM);
|
364 |
|
365 |
AV_WL32(pkt->data , nblocks); |
366 |
AV_WL32(pkt->data + 4, ape->frames[ape->currentframe].skip);
|
367 |
ret = avio_read(s->pb, pkt->data + extra_size, ape->frames[ape->currentframe].size); |
368 |
|
369 |
pkt->pts = ape->frames[ape->currentframe].pts; |
370 |
pkt->stream_index = 0;
|
371 |
|
372 |
/* note: we need to modify the packet size here to handle the last
|
373 |
packet */
|
374 |
pkt->size = ret + extra_size; |
375 |
|
376 |
ape->currentframe++; |
377 |
|
378 |
return 0; |
379 |
} |
380 |
|
381 |
static int ape_read_close(AVFormatContext * s) |
382 |
{ |
383 |
APEContext *ape = s->priv_data; |
384 |
|
385 |
av_freep(&ape->frames); |
386 |
av_freep(&ape->seektable); |
387 |
return 0; |
388 |
} |
389 |
|
390 |
static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) |
391 |
{ |
392 |
AVStream *st = s->streams[stream_index]; |
393 |
APEContext *ape = s->priv_data; |
394 |
int index = av_index_search_timestamp(st, timestamp, flags);
|
395 |
|
396 |
if (index < 0) |
397 |
return -1; |
398 |
|
399 |
ape->currentframe = index; |
400 |
return 0; |
401 |
} |
402 |
|
403 |
AVInputFormat ff_ape_demuxer = { |
404 |
"ape",
|
405 |
NULL_IF_CONFIG_SMALL("Monkey's Audio"),
|
406 |
sizeof(APEContext),
|
407 |
ape_probe, |
408 |
ape_read_header, |
409 |
ape_read_packet, |
410 |
ape_read_close, |
411 |
ape_read_seek, |
412 |
.extensions = "ape,apl,mac"
|
413 |
}; |