Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/minimp3/minimp3_ex.h
9903 views
1
#ifndef MINIMP3_EXT_H
2
#define MINIMP3_EXT_H
3
/*
4
https://github.com/lieff/minimp3
5
To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
6
This software is distributed without any warranty.
7
See <http://creativecommons.org/publicdomain/zero/1.0/>.
8
*/
9
#include <stddef.h>
10
#include "minimp3.h"
11
12
/* flags for mp3dec_ex_open_* functions */
13
#define MP3D_SEEK_TO_BYTE 0 /* mp3dec_ex_seek seeks to byte in stream */
14
#define MP3D_SEEK_TO_SAMPLE 1 /* mp3dec_ex_seek precisely seeks to sample using index (created during duration calculation scan or when mp3dec_ex_seek called) */
15
#define MP3D_DO_NOT_SCAN 2 /* do not scan whole stream for duration if vbrtag not found, mp3dec_ex_t::samples will be filled only if mp3dec_ex_t::vbr_tag_found == 1 */
16
#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
17
#define MP3D_ALLOW_MONO_STEREO_TRANSITION 4
18
#define MP3D_FLAGS_MASK 7
19
#else
20
#define MP3D_FLAGS_MASK 3
21
#endif
22
23
/* compile-time config */
24
#define MINIMP3_PREDECODE_FRAMES 2 /* frames to pre-decode and skip after seek (to fill internal structures) */
25
/*#define MINIMP3_SEEK_IDX_LINEAR_SEARCH*/ /* define to use linear index search instead of binary search on seek */
26
#define MINIMP3_IO_SIZE (128*1024) /* io buffer size for streaming functions, must be greater than MINIMP3_BUF_SIZE */
27
#define MINIMP3_BUF_SIZE (16*1024) /* buffer which can hold minimum 10 consecutive mp3 frames (~16KB) worst case */
28
/*#define MINIMP3_SCAN_LIMIT (256*1024)*/ /* how many bytes will be scanned to search first valid mp3 frame, to prevent stall on large non-mp3 files */
29
#define MINIMP3_ENABLE_RING 0 /* WIP enable hardware magic ring buffer if available, to make less input buffer memmove(s) in callback IO mode */
30
31
/* return error codes */
32
#define MP3D_E_PARAM -1
33
#define MP3D_E_MEMORY -2
34
#define MP3D_E_IOERROR -3
35
#define MP3D_E_USER -4 /* can be used to stop processing from callbacks without indicating specific error */
36
#define MP3D_E_DECODE -5 /* decode error which can't be safely skipped, such as sample rate, layer and channels change */
37
38
typedef struct
39
{
40
mp3d_sample_t *buffer;
41
size_t samples; /* channels included, byte size = samples*sizeof(mp3d_sample_t) */
42
int channels, hz, layer, avg_bitrate_kbps;
43
} mp3dec_file_info_t;
44
45
typedef struct
46
{
47
const uint8_t *buffer;
48
size_t size;
49
} mp3dec_map_info_t;
50
51
typedef struct
52
{
53
uint64_t sample;
54
uint64_t offset;
55
} mp3dec_frame_t;
56
57
typedef struct
58
{
59
mp3dec_frame_t *frames;
60
size_t num_frames, capacity;
61
} mp3dec_index_t;
62
63
typedef size_t (*MP3D_READ_CB)(void *buf, size_t size, void *user_data);
64
typedef int (*MP3D_SEEK_CB)(uint64_t position, void *user_data);
65
66
typedef struct
67
{
68
MP3D_READ_CB read;
69
void *read_data;
70
MP3D_SEEK_CB seek;
71
void *seek_data;
72
} mp3dec_io_t;
73
74
typedef struct
75
{
76
mp3dec_t mp3d;
77
mp3dec_map_info_t file;
78
mp3dec_io_t *io;
79
mp3dec_index_t index;
80
uint64_t offset, samples, detected_samples, cur_sample, start_offset, end_offset;
81
mp3dec_frame_info_t info;
82
mp3d_sample_t buffer[MINIMP3_MAX_SAMPLES_PER_FRAME];
83
size_t input_consumed, input_filled;
84
int is_file, flags, vbr_tag_found, indexes_built;
85
int free_format_bytes;
86
int buffer_samples, buffer_consumed, to_skip, start_delay;
87
int last_error;
88
} mp3dec_ex_t;
89
90
typedef int (*MP3D_ITERATE_CB)(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, uint64_t offset, mp3dec_frame_info_t *info);
91
typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offset, mp3dec_frame_info_t *info);
92
93
#ifdef __cplusplus
94
extern "C" {
95
#endif
96
97
/* detect mp3/mpa format */
98
int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size);
99
int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size);
100
/* decode whole buffer block */
101
int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
102
int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
103
/* iterate through frames */
104
int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
105
int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
106
/* streaming decoder with seeking capability */
107
int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int flags);
108
int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int flags);
109
void mp3dec_ex_close(mp3dec_ex_t *dec);
110
int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position);
111
size_t mp3dec_ex_read_frame(mp3dec_ex_t *dec, mp3d_sample_t **buf, mp3dec_frame_info_t *frame_info, size_t max_samples);
112
size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);
113
#ifndef MINIMP3_NO_STDIO
114
/* stdio versions of file detect, load, iterate and stream */
115
int mp3dec_detect(const char *file_name);
116
int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
117
int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
118
int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int flags);
119
#ifdef _WIN32
120
int mp3dec_detect_w(const wchar_t *file_name);
121
int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
122
int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
123
int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int flags);
124
#endif
125
#endif
126
127
#ifdef __cplusplus
128
}
129
#endif
130
#endif /*MINIMP3_EXT_H*/
131
132
#if defined(MINIMP3_IMPLEMENTATION) && !defined(_MINIMP3_EX_IMPLEMENTATION_GUARD)
133
#define _MINIMP3_EX_IMPLEMENTATION_GUARD
134
#include <limits.h>
135
#include "minimp3.h"
136
137
static void mp3dec_skip_id3v1(const uint8_t *buf, size_t *pbuf_size)
138
{
139
size_t buf_size = *pbuf_size;
140
#ifndef MINIMP3_NOSKIP_ID3V1
141
if (buf_size >= 128 && !memcmp(buf + buf_size - 128, "TAG", 3))
142
{
143
buf_size -= 128;
144
if (buf_size >= 227 && !memcmp(buf + buf_size - 227, "TAG+", 4))
145
buf_size -= 227;
146
}
147
#endif
148
#ifndef MINIMP3_NOSKIP_APEV2
149
if (buf_size > 32 && !memcmp(buf + buf_size - 32, "APETAGEX", 8))
150
{
151
buf_size -= 32;
152
const uint8_t *tag = buf + buf_size + 8 + 4;
153
uint32_t tag_size = (uint32_t)(tag[3] << 24) | (tag[2] << 16) | (tag[1] << 8) | tag[0];
154
if (buf_size >= tag_size)
155
buf_size -= tag_size;
156
}
157
#endif
158
*pbuf_size = buf_size;
159
}
160
161
static size_t mp3dec_skip_id3v2(const uint8_t *buf, size_t buf_size)
162
{
163
#define MINIMP3_ID3_DETECT_SIZE 10
164
#ifndef MINIMP3_NOSKIP_ID3V2
165
if (buf_size >= MINIMP3_ID3_DETECT_SIZE && !memcmp(buf, "ID3", 3) && !((buf[5] & 15) || (buf[6] & 0x80) || (buf[7] & 0x80) || (buf[8] & 0x80) || (buf[9] & 0x80)))
166
{
167
size_t id3v2size = (((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f)) + 10;
168
if ((buf[5] & 16))
169
id3v2size += 10; /* footer */
170
return id3v2size;
171
}
172
#endif
173
return 0;
174
}
175
176
static void mp3dec_skip_id3(const uint8_t **pbuf, size_t *pbuf_size)
177
{
178
uint8_t *buf = (uint8_t *)(*pbuf);
179
size_t buf_size = *pbuf_size;
180
size_t id3v2size = mp3dec_skip_id3v2(buf, buf_size);
181
if (id3v2size)
182
{
183
if (id3v2size >= buf_size)
184
id3v2size = buf_size;
185
buf += id3v2size;
186
buf_size -= id3v2size;
187
}
188
mp3dec_skip_id3v1(buf, &buf_size);
189
*pbuf = (const uint8_t *)buf;
190
*pbuf_size = buf_size;
191
}
192
193
static int mp3dec_check_vbrtag(const uint8_t *frame, int frame_size, uint32_t *frames, int *delay, int *padding)
194
{
195
static const char g_xing_tag[4] = { 'X', 'i', 'n', 'g' };
196
static const char g_info_tag[4] = { 'I', 'n', 'f', 'o' };
197
#define FRAMES_FLAG 1
198
#define BYTES_FLAG 2
199
#define TOC_FLAG 4
200
#define VBR_SCALE_FLAG 8
201
/* Side info offsets after header:
202
/ Mono Stereo
203
/ MPEG1 17 32
204
/ MPEG2 & 2.5 9 17*/
205
bs_t bs[1];
206
L3_gr_info_t gr_info[4];
207
bs_init(bs, frame + HDR_SIZE, frame_size - HDR_SIZE);
208
if (HDR_IS_CRC(frame))
209
get_bits(bs, 16);
210
if (L3_read_side_info(bs, gr_info, frame) < 0)
211
return 0; /* side info corrupted */
212
213
const uint8_t *tag = frame + HDR_SIZE + bs->pos/8;
214
if (memcmp(g_xing_tag, tag, 4) && memcmp(g_info_tag, tag, 4))
215
return 0;
216
int flags = tag[7];
217
if (!((flags & FRAMES_FLAG)))
218
return -1;
219
tag += 8;
220
*frames = (uint32_t)(tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3];
221
tag += 4;
222
if (flags & BYTES_FLAG)
223
tag += 4;
224
if (flags & TOC_FLAG)
225
tag += 100;
226
if (flags & VBR_SCALE_FLAG)
227
tag += 4;
228
*delay = *padding = 0;
229
if (*tag)
230
{ /* extension, LAME, Lavc, etc. Should be the same structure. */
231
tag += 21;
232
if (tag - frame + 14 >= frame_size)
233
return 0;
234
*delay = ((tag[0] << 4) | (tag[1] >> 4)) + (528 + 1);
235
*padding = (((tag[1] & 0xF) << 8) | tag[2]) - (528 + 1);
236
}
237
return 1;
238
}
239
240
int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size)
241
{
242
return mp3dec_detect_cb(0, (uint8_t *)buf, buf_size);
243
}
244
245
int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size)
246
{
247
if (!buf || (size_t)-1 == buf_size || (io && buf_size < MINIMP3_BUF_SIZE))
248
return MP3D_E_PARAM;
249
size_t filled = buf_size;
250
if (io)
251
{
252
if (io->seek(0, io->seek_data))
253
return MP3D_E_IOERROR;
254
filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data);
255
if (filled > MINIMP3_ID3_DETECT_SIZE)
256
return MP3D_E_IOERROR;
257
}
258
if (filled < MINIMP3_ID3_DETECT_SIZE)
259
return MP3D_E_USER; /* too small, can't be mp3/mpa */
260
if (mp3dec_skip_id3v2(buf, filled))
261
return 0; /* id3v2 tag is enough evidence */
262
if (io)
263
{
264
size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
265
if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
266
return MP3D_E_IOERROR;
267
filled += readed;
268
if (filled < MINIMP3_BUF_SIZE)
269
mp3dec_skip_id3v1(buf, &filled);
270
} else
271
{
272
mp3dec_skip_id3v1(buf, &filled);
273
if (filled > MINIMP3_BUF_SIZE)
274
filled = MINIMP3_BUF_SIZE;
275
}
276
int free_format_bytes, frame_size;
277
mp3d_find_frame(buf, filled, &free_format_bytes, &frame_size);
278
if (frame_size)
279
return 0; /* MAX_FRAME_SYNC_MATCHES consecutive frames found */
280
return MP3D_E_USER;
281
}
282
283
int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
284
{
285
return mp3dec_load_cb(dec, 0, (uint8_t *)buf, buf_size, info, progress_cb, user_data);
286
}
287
288
int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
289
{
290
if (!dec || !buf || !info || (size_t)-1 == buf_size || (io && buf_size < MINIMP3_BUF_SIZE))
291
return MP3D_E_PARAM;
292
uint64_t detected_samples = 0;
293
size_t orig_buf_size = buf_size;
294
int to_skip = 0;
295
mp3dec_frame_info_t frame_info;
296
memset(info, 0, sizeof(*info));
297
memset(&frame_info, 0, sizeof(frame_info));
298
299
/* skip id3 */
300
size_t filled = 0, consumed = 0;
301
int eof = 0, ret = 0;
302
if (io)
303
{
304
if (io->seek(0, io->seek_data))
305
return MP3D_E_IOERROR;
306
filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data);
307
if (filled > MINIMP3_ID3_DETECT_SIZE)
308
return MP3D_E_IOERROR;
309
if (MINIMP3_ID3_DETECT_SIZE != filled)
310
return 0;
311
size_t id3v2size = mp3dec_skip_id3v2(buf, filled);
312
if (id3v2size)
313
{
314
if (io->seek(id3v2size, io->seek_data))
315
return MP3D_E_IOERROR;
316
filled = io->read(buf, buf_size, io->read_data);
317
if (filled > buf_size)
318
return MP3D_E_IOERROR;
319
} else
320
{
321
size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
322
if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
323
return MP3D_E_IOERROR;
324
filled += readed;
325
}
326
if (filled < MINIMP3_BUF_SIZE)
327
mp3dec_skip_id3v1(buf, &filled);
328
} else
329
{
330
mp3dec_skip_id3((const uint8_t **)&buf, &buf_size);
331
if (!buf_size)
332
return 0;
333
}
334
/* try to make allocation size assumption by first frame or vbr tag */
335
mp3dec_init(dec);
336
int samples;
337
do
338
{
339
uint32_t frames;
340
int i, delay, padding, free_format_bytes = 0, frame_size = 0;
341
const uint8_t *hdr;
342
if (io)
343
{
344
if (!eof && filled - consumed < MINIMP3_BUF_SIZE)
345
{ /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
346
memmove(buf, buf + consumed, filled - consumed);
347
filled -= consumed;
348
consumed = 0;
349
size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
350
if (readed > (buf_size - filled))
351
return MP3D_E_IOERROR;
352
if (readed != (buf_size - filled))
353
eof = 1;
354
filled += readed;
355
if (eof)
356
mp3dec_skip_id3v1(buf, &filled);
357
}
358
i = mp3d_find_frame(buf + consumed, filled - consumed, &free_format_bytes, &frame_size);
359
consumed += i;
360
hdr = buf + consumed;
361
} else
362
{
363
i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size);
364
buf += i;
365
buf_size -= i;
366
hdr = buf;
367
}
368
if (i && !frame_size)
369
continue;
370
if (!frame_size)
371
return 0;
372
frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
373
frame_info.hz = hdr_sample_rate_hz(hdr);
374
frame_info.layer = 4 - HDR_GET_LAYER(hdr);
375
frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
376
frame_info.frame_bytes = frame_size;
377
samples = hdr_frame_samples(hdr)*frame_info.channels;
378
if (3 != frame_info.layer)
379
break;
380
ret = mp3dec_check_vbrtag(hdr, frame_size, &frames, &delay, &padding);
381
if (ret > 0)
382
{
383
padding *= frame_info.channels;
384
to_skip = delay*frame_info.channels;
385
detected_samples = samples*(uint64_t)frames;
386
if (detected_samples >= (uint64_t)to_skip)
387
detected_samples -= to_skip;
388
if (padding > 0 && detected_samples >= (uint64_t)padding)
389
detected_samples -= padding;
390
if (!detected_samples)
391
return 0;
392
}
393
if (ret)
394
{
395
if (io)
396
{
397
consumed += frame_size;
398
} else
399
{
400
buf += frame_size;
401
buf_size -= frame_size;
402
}
403
}
404
break;
405
} while(1);
406
size_t allocated = MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t);
407
if (detected_samples)
408
allocated += detected_samples*sizeof(mp3d_sample_t);
409
else
410
allocated += (buf_size/frame_info.frame_bytes)*samples*sizeof(mp3d_sample_t);
411
info->buffer = (mp3d_sample_t*)malloc(allocated);
412
if (!info->buffer)
413
return MP3D_E_MEMORY;
414
/* save info */
415
info->channels = frame_info.channels;
416
info->hz = frame_info.hz;
417
info->layer = frame_info.layer;
418
/* decode all frames */
419
size_t avg_bitrate_kbps = 0, frames = 0;
420
do
421
{
422
if ((allocated - info->samples*sizeof(mp3d_sample_t)) < MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t))
423
{
424
allocated *= 2;
425
mp3d_sample_t *alloc_buf = (mp3d_sample_t*)realloc(info->buffer, allocated);
426
if (!alloc_buf)
427
return MP3D_E_MEMORY;
428
info->buffer = alloc_buf;
429
}
430
if (io)
431
{
432
if (!eof && filled - consumed < MINIMP3_BUF_SIZE)
433
{ /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
434
memmove(buf, buf + consumed, filled - consumed);
435
filled -= consumed;
436
consumed = 0;
437
size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
438
if (readed != (buf_size - filled))
439
eof = 1;
440
filled += readed;
441
if (eof)
442
mp3dec_skip_id3v1(buf, &filled);
443
}
444
samples = mp3dec_decode_frame(dec, buf + consumed, filled - consumed, info->buffer + info->samples, &frame_info);
445
consumed += frame_info.frame_bytes;
446
} else
447
{
448
samples = mp3dec_decode_frame(dec, buf, MINIMP3_MIN(buf_size, (size_t)INT_MAX), info->buffer + info->samples, &frame_info);
449
buf += frame_info.frame_bytes;
450
buf_size -= frame_info.frame_bytes;
451
}
452
if (samples)
453
{
454
if (info->hz != frame_info.hz || info->layer != frame_info.layer)
455
{
456
ret = MP3D_E_DECODE;
457
break;
458
}
459
if (info->channels && info->channels != frame_info.channels)
460
{
461
#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
462
info->channels = 0; /* mark file with mono-stereo transition */
463
#else
464
ret = MP3D_E_DECODE;
465
break;
466
#endif
467
}
468
samples *= frame_info.channels;
469
if (to_skip)
470
{
471
size_t skip = MINIMP3_MIN(samples, to_skip);
472
to_skip -= skip;
473
samples -= skip;
474
memmove(info->buffer, info->buffer + skip, samples*sizeof(mp3d_sample_t));
475
}
476
info->samples += samples;
477
avg_bitrate_kbps += frame_info.bitrate_kbps;
478
frames++;
479
if (progress_cb)
480
{
481
ret = progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info);
482
if (ret)
483
break;
484
}
485
}
486
} while (frame_info.frame_bytes);
487
if (detected_samples && info->samples > detected_samples)
488
info->samples = detected_samples; /* cut padding */
489
/* reallocate to normal buffer size */
490
if (allocated != info->samples*sizeof(mp3d_sample_t))
491
{
492
mp3d_sample_t *alloc_buf = (mp3d_sample_t*)realloc(info->buffer, info->samples*sizeof(mp3d_sample_t));
493
if (!alloc_buf && info->samples)
494
return MP3D_E_MEMORY;
495
info->buffer = alloc_buf;
496
}
497
if (frames)
498
info->avg_bitrate_kbps = avg_bitrate_kbps/frames;
499
return ret;
500
}
501
502
int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
503
{
504
const uint8_t *orig_buf = buf;
505
if (!buf || (size_t)-1 == buf_size || !callback)
506
return MP3D_E_PARAM;
507
/* skip id3 */
508
mp3dec_skip_id3(&buf, &buf_size);
509
if (!buf_size)
510
return 0;
511
mp3dec_frame_info_t frame_info;
512
memset(&frame_info, 0, sizeof(frame_info));
513
do
514
{
515
int free_format_bytes = 0, frame_size = 0, ret;
516
int i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size);
517
buf += i;
518
buf_size -= i;
519
if (i && !frame_size)
520
continue;
521
if (!frame_size)
522
break;
523
const uint8_t *hdr = buf;
524
frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
525
frame_info.hz = hdr_sample_rate_hz(hdr);
526
frame_info.layer = 4 - HDR_GET_LAYER(hdr);
527
frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
528
frame_info.frame_bytes = frame_size;
529
530
if (callback)
531
{
532
ret = callback(user_data, hdr, frame_size, free_format_bytes, buf_size, hdr - orig_buf, &frame_info);
533
if (ret != 0)
534
return ret;
535
}
536
buf += frame_size;
537
buf_size -= frame_size;
538
} while (1);
539
return 0;
540
}
541
542
int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
543
{
544
if (!io || !buf || (size_t)-1 == buf_size || buf_size < MINIMP3_BUF_SIZE || !callback)
545
return MP3D_E_PARAM;
546
size_t filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data), consumed = 0;
547
uint64_t readed = 0;
548
mp3dec_frame_info_t frame_info;
549
int eof = 0;
550
memset(&frame_info, 0, sizeof(frame_info));
551
if (filled > MINIMP3_ID3_DETECT_SIZE)
552
return MP3D_E_IOERROR;
553
if (MINIMP3_ID3_DETECT_SIZE != filled)
554
return 0;
555
size_t id3v2size = mp3dec_skip_id3v2(buf, filled);
556
if (id3v2size)
557
{
558
if (io->seek(id3v2size, io->seek_data))
559
return MP3D_E_IOERROR;
560
filled = io->read(buf, buf_size, io->read_data);
561
if (filled > buf_size)
562
return MP3D_E_IOERROR;
563
readed += id3v2size;
564
} else
565
{
566
readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
567
if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
568
return MP3D_E_IOERROR;
569
filled += readed;
570
}
571
if (filled < MINIMP3_BUF_SIZE)
572
mp3dec_skip_id3v1(buf, &filled);
573
do
574
{
575
int free_format_bytes = 0, frame_size = 0, ret;
576
int i = mp3d_find_frame(buf + consumed, filled - consumed, &free_format_bytes, &frame_size);
577
if (i && !frame_size)
578
{
579
consumed += i;
580
continue;
581
}
582
if (!frame_size)
583
break;
584
const uint8_t *hdr = buf + consumed + i;
585
frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
586
frame_info.hz = hdr_sample_rate_hz(hdr);
587
frame_info.layer = 4 - HDR_GET_LAYER(hdr);
588
frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
589
frame_info.frame_bytes = frame_size;
590
591
readed += i;
592
if (callback)
593
{
594
ret = callback(user_data, hdr, frame_size, free_format_bytes, filled - consumed, readed, &frame_info);
595
if (ret != 0)
596
return ret;
597
}
598
readed += frame_size;
599
consumed += i + frame_size;
600
if (!eof && filled - consumed < MINIMP3_BUF_SIZE)
601
{ /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
602
memmove(buf, buf + consumed, filled - consumed);
603
filled -= consumed;
604
consumed = 0;
605
readed = io->read(buf + filled, buf_size - filled, io->read_data);
606
if (readed > (buf_size - filled))
607
return MP3D_E_IOERROR;
608
if (readed != (buf_size - filled))
609
eof = 1;
610
filled += readed;
611
if (eof)
612
mp3dec_skip_id3v1(buf, &filled);
613
}
614
} while (1);
615
return 0;
616
}
617
618
static int mp3dec_load_index(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, uint64_t offset, mp3dec_frame_info_t *info)
619
{
620
mp3dec_frame_t *idx_frame;
621
mp3dec_ex_t *dec = (mp3dec_ex_t *)user_data;
622
if (!dec->index.frames && !dec->start_offset)
623
{ /* detect VBR tag and try to avoid full scan */
624
uint32_t frames;
625
int delay, padding;
626
dec->info = *info;
627
dec->start_offset = dec->offset = offset;
628
dec->end_offset = offset + buf_size;
629
dec->free_format_bytes = free_format_bytes; /* should not change */
630
if (3 == dec->info.layer)
631
{
632
int ret = mp3dec_check_vbrtag(frame, frame_size, &frames, &delay, &padding);
633
if (ret)
634
dec->start_offset = dec->offset = offset + frame_size;
635
if (ret > 0)
636
{
637
padding *= info->channels;
638
dec->start_delay = dec->to_skip = delay*info->channels;
639
dec->samples = hdr_frame_samples(frame)*info->channels*(uint64_t)frames;
640
if (dec->samples >= (uint64_t)dec->start_delay)
641
dec->samples -= dec->start_delay;
642
if (padding > 0 && dec->samples >= (uint64_t)padding)
643
dec->samples -= padding;
644
dec->detected_samples = dec->samples;
645
dec->vbr_tag_found = 1;
646
return MP3D_E_USER;
647
} else if (ret < 0)
648
return 0;
649
}
650
}
651
if (dec->flags & MP3D_DO_NOT_SCAN)
652
return MP3D_E_USER;
653
if (dec->index.num_frames + 1 > dec->index.capacity)
654
{
655
if (!dec->index.capacity)
656
dec->index.capacity = 4096;
657
else
658
dec->index.capacity *= 2;
659
mp3dec_frame_t *alloc_buf = (mp3dec_frame_t *)realloc((void*)dec->index.frames, sizeof(mp3dec_frame_t)*dec->index.capacity);
660
if (!alloc_buf)
661
return MP3D_E_MEMORY;
662
dec->index.frames = alloc_buf;
663
}
664
idx_frame = &dec->index.frames[dec->index.num_frames++];
665
idx_frame->offset = offset;
666
idx_frame->sample = dec->samples;
667
if (!dec->buffer_samples && dec->index.num_frames < 256)
668
{ /* for some cutted mp3 frames, bit-reservoir not filled and decoding can't be started from first frames */
669
/* try to decode up to 255 first frames till samples starts to decode */
670
dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, frame, MINIMP3_MIN(buf_size, (size_t)INT_MAX), dec->buffer, info);
671
dec->samples += dec->buffer_samples*info->channels;
672
} else
673
dec->samples += hdr_frame_samples(frame)*info->channels;
674
return 0;
675
}
676
677
int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int flags)
678
{
679
if (!dec || !buf || (size_t)-1 == buf_size || (flags & (~MP3D_FLAGS_MASK)))
680
return MP3D_E_PARAM;
681
memset(dec, 0, sizeof(*dec));
682
dec->file.buffer = buf;
683
dec->file.size = buf_size;
684
dec->flags = flags;
685
mp3dec_init(&dec->mp3d);
686
int ret = mp3dec_iterate_buf(dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
687
if (ret && MP3D_E_USER != ret)
688
return ret;
689
mp3dec_init(&dec->mp3d);
690
dec->buffer_samples = 0;
691
dec->indexes_built = !(dec->vbr_tag_found || (flags & MP3D_DO_NOT_SCAN));
692
dec->flags &= (~MP3D_DO_NOT_SCAN);
693
return 0;
694
}
695
696
#ifndef MINIMP3_SEEK_IDX_LINEAR_SEARCH
697
static size_t mp3dec_idx_binary_search(mp3dec_index_t *idx, uint64_t position)
698
{
699
size_t end = idx->num_frames, start = 0, index = 0;
700
while (start <= end)
701
{
702
size_t mid = (start + end) / 2;
703
if (idx->frames[mid].sample >= position)
704
{ /* move left side. */
705
if (idx->frames[mid].sample == position)
706
return mid;
707
end = mid - 1;
708
} else
709
{ /* move to right side */
710
index = mid;
711
start = mid + 1;
712
if (start == idx->num_frames)
713
break;
714
}
715
}
716
return index;
717
}
718
#endif
719
720
int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position)
721
{
722
size_t i;
723
if (!dec)
724
return MP3D_E_PARAM;
725
if (!(dec->flags & MP3D_SEEK_TO_SAMPLE))
726
{
727
if (dec->io)
728
{
729
dec->offset = position;
730
} else
731
{
732
dec->offset = MINIMP3_MIN(position, dec->file.size);
733
}
734
dec->cur_sample = 0;
735
goto do_exit;
736
}
737
dec->cur_sample = position;
738
position += dec->start_delay;
739
if (0 == position)
740
{ /* optimize seek to zero, no index needed */
741
seek_zero:
742
dec->offset = dec->start_offset;
743
dec->to_skip = 0;
744
goto do_exit;
745
}
746
if (!dec->indexes_built)
747
{ /* no index created yet (vbr tag used to calculate track length or MP3D_DO_NOT_SCAN open flag used) */
748
dec->indexes_built = 1;
749
dec->samples = 0;
750
dec->buffer_samples = 0;
751
if (dec->io)
752
{
753
if (dec->io->seek(dec->start_offset, dec->io->seek_data))
754
return MP3D_E_IOERROR;
755
int ret = mp3dec_iterate_cb(dec->io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
756
if (ret && MP3D_E_USER != ret)
757
return ret;
758
} else
759
{
760
int ret = mp3dec_iterate_buf(dec->file.buffer + dec->start_offset, dec->file.size - dec->start_offset, mp3dec_load_index, dec);
761
if (ret && MP3D_E_USER != ret)
762
return ret;
763
}
764
for (i = 0; i < dec->index.num_frames; i++)
765
dec->index.frames[i].offset += dec->start_offset;
766
dec->samples = dec->detected_samples;
767
}
768
if (!dec->index.frames)
769
goto seek_zero; /* no frames in file - seek to zero */
770
#ifdef MINIMP3_SEEK_IDX_LINEAR_SEARCH
771
for (i = 0; i < dec->index.num_frames; i++)
772
{
773
if (dec->index.frames[i].sample >= position)
774
break;
775
}
776
#else
777
i = mp3dec_idx_binary_search(&dec->index, position);
778
#endif
779
if (i)
780
{
781
int to_fill_bytes = 511;
782
int skip_frames = MINIMP3_PREDECODE_FRAMES
783
#ifdef MINIMP3_SEEK_IDX_LINEAR_SEARCH
784
+ ((dec->index.frames[i].sample == position) ? 0 : 1)
785
#endif
786
;
787
i -= MINIMP3_MIN(i, (size_t)skip_frames);
788
if (3 == dec->info.layer)
789
{
790
while (i && to_fill_bytes)
791
{ /* make sure bit-reservoir is filled when we start decoding */
792
bs_t bs[1];
793
L3_gr_info_t gr_info[4];
794
int frame_bytes, frame_size;
795
const uint8_t *hdr;
796
if (dec->io)
797
{
798
hdr = dec->file.buffer;
799
if (dec->io->seek(dec->index.frames[i - 1].offset, dec->io->seek_data))
800
return MP3D_E_IOERROR;
801
size_t readed = dec->io->read((uint8_t *)hdr, HDR_SIZE, dec->io->read_data);
802
if (readed != HDR_SIZE)
803
return MP3D_E_IOERROR;
804
frame_size = hdr_frame_bytes(hdr, dec->free_format_bytes) + hdr_padding(hdr);
805
readed = dec->io->read((uint8_t *)hdr + HDR_SIZE, frame_size - HDR_SIZE, dec->io->read_data);
806
if (readed != (size_t)(frame_size - HDR_SIZE))
807
return MP3D_E_IOERROR;
808
bs_init(bs, hdr + HDR_SIZE, frame_size - HDR_SIZE);
809
} else
810
{
811
hdr = dec->file.buffer + dec->index.frames[i - 1].offset;
812
frame_size = hdr_frame_bytes(hdr, dec->free_format_bytes) + hdr_padding(hdr);
813
bs_init(bs, hdr + HDR_SIZE, frame_size - HDR_SIZE);
814
}
815
if (HDR_IS_CRC(hdr))
816
get_bits(bs, 16);
817
i--;
818
if (L3_read_side_info(bs, gr_info, hdr) < 0)
819
break; /* frame not decodable, we can start from here */
820
frame_bytes = (bs->limit - bs->pos)/8;
821
to_fill_bytes -= MINIMP3_MIN(to_fill_bytes, frame_bytes);
822
}
823
}
824
}
825
dec->offset = dec->index.frames[i].offset;
826
dec->to_skip = position - dec->index.frames[i].sample;
827
while ((i + 1) < dec->index.num_frames && !dec->index.frames[i].sample && !dec->index.frames[i + 1].sample)
828
{ /* skip not decodable first frames */
829
const uint8_t *hdr;
830
if (dec->io)
831
{
832
hdr = dec->file.buffer;
833
if (dec->io->seek(dec->index.frames[i].offset, dec->io->seek_data))
834
return MP3D_E_IOERROR;
835
size_t readed = dec->io->read((uint8_t *)hdr, HDR_SIZE, dec->io->read_data);
836
if (readed != HDR_SIZE)
837
return MP3D_E_IOERROR;
838
} else
839
hdr = dec->file.buffer + dec->index.frames[i].offset;
840
dec->to_skip += hdr_frame_samples(hdr)*dec->info.channels;
841
i++;
842
}
843
do_exit:
844
if (dec->io)
845
{
846
if (dec->io->seek(dec->offset, dec->io->seek_data))
847
return MP3D_E_IOERROR;
848
}
849
dec->buffer_samples = 0;
850
dec->buffer_consumed = 0;
851
dec->input_consumed = 0;
852
dec->input_filled = 0;
853
dec->last_error = 0;
854
mp3dec_init(&dec->mp3d);
855
return 0;
856
}
857
858
size_t mp3dec_ex_read_frame(mp3dec_ex_t *dec, mp3d_sample_t **buf, mp3dec_frame_info_t *frame_info, size_t max_samples)
859
{
860
if (!dec || !buf || !frame_info)
861
{
862
if (dec)
863
dec->last_error = MP3D_E_PARAM;
864
return 0;
865
}
866
if (dec->detected_samples && dec->cur_sample >= dec->detected_samples)
867
return 0; /* at end of stream */
868
if (dec->last_error)
869
return 0; /* error eof state, seek can reset it */
870
*buf = NULL;
871
uint64_t end_offset = dec->end_offset ? dec->end_offset : dec->file.size;
872
int eof = 0;
873
while (dec->buffer_consumed == dec->buffer_samples)
874
{
875
const uint8_t *dec_buf;
876
if (dec->io)
877
{
878
if (!eof && (dec->input_filled - dec->input_consumed) < MINIMP3_BUF_SIZE)
879
{ /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
880
memmove((uint8_t*)dec->file.buffer, (uint8_t*)dec->file.buffer + dec->input_consumed, dec->input_filled - dec->input_consumed);
881
dec->input_filled -= dec->input_consumed;
882
dec->input_consumed = 0;
883
size_t readed = dec->io->read((uint8_t*)dec->file.buffer + dec->input_filled, dec->file.size - dec->input_filled, dec->io->read_data);
884
if (readed > (dec->file.size - dec->input_filled))
885
{
886
dec->last_error = MP3D_E_IOERROR;
887
readed = 0;
888
}
889
if (readed != (dec->file.size - dec->input_filled))
890
eof = 1;
891
dec->input_filled += readed;
892
if (eof)
893
mp3dec_skip_id3v1((uint8_t*)dec->file.buffer, &dec->input_filled);
894
}
895
dec_buf = dec->file.buffer + dec->input_consumed;
896
if (!(dec->input_filled - dec->input_consumed))
897
return 0;
898
dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, dec_buf, dec->input_filled - dec->input_consumed, dec->buffer, frame_info);
899
dec->input_consumed += frame_info->frame_bytes;
900
} else
901
{
902
dec_buf = dec->file.buffer + dec->offset;
903
uint64_t buf_size = end_offset - dec->offset;
904
if (!buf_size)
905
return 0;
906
dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, dec_buf, MINIMP3_MIN(buf_size, (uint64_t)INT_MAX), dec->buffer, frame_info);
907
}
908
dec->buffer_consumed = 0;
909
if (dec->info.hz != frame_info->hz || dec->info.layer != frame_info->layer)
910
{
911
return_e_decode:
912
dec->last_error = MP3D_E_DECODE;
913
return 0;
914
}
915
if (dec->buffer_samples)
916
{
917
dec->buffer_samples *= frame_info->channels;
918
if (dec->to_skip)
919
{
920
size_t skip = MINIMP3_MIN(dec->buffer_samples, dec->to_skip);
921
dec->buffer_consumed += skip;
922
dec->to_skip -= skip;
923
}
924
if (
925
#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
926
!(dec->flags & MP3D_ALLOW_MONO_STEREO_TRANSITION) &&
927
#endif
928
dec->buffer_consumed != dec->buffer_samples && dec->info.channels != frame_info->channels)
929
{
930
goto return_e_decode;
931
}
932
} else if (dec->to_skip)
933
{ /* In mp3 decoding not always can start decode from any frame because of bit reservoir,
934
count skip samples for such frames */
935
int frame_samples = hdr_frame_samples(dec_buf)*frame_info->channels;
936
dec->to_skip -= MINIMP3_MIN(frame_samples, dec->to_skip);
937
}
938
dec->offset += frame_info->frame_bytes;
939
}
940
size_t out_samples = MINIMP3_MIN((size_t)(dec->buffer_samples - dec->buffer_consumed), max_samples);
941
if (dec->detected_samples)
942
{ /* count decoded samples to properly cut padding */
943
if (dec->cur_sample + out_samples >= dec->detected_samples)
944
out_samples = dec->detected_samples - dec->cur_sample;
945
}
946
dec->cur_sample += out_samples;
947
*buf = dec->buffer + dec->buffer_consumed;
948
dec->buffer_consumed += out_samples;
949
return out_samples;
950
}
951
952
size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples)
953
{
954
if (!dec || !buf)
955
{
956
if (dec)
957
dec->last_error = MP3D_E_PARAM;
958
return 0;
959
}
960
mp3dec_frame_info_t frame_info;
961
memset(&frame_info, 0, sizeof(frame_info));
962
size_t samples_requested = samples;
963
while (samples)
964
{
965
mp3d_sample_t *buf_frame = NULL;
966
size_t read_samples = mp3dec_ex_read_frame(dec, &buf_frame, &frame_info, samples);
967
if (!read_samples)
968
{
969
break;
970
}
971
memcpy(buf, buf_frame, read_samples * sizeof(mp3d_sample_t));
972
buf += read_samples;
973
samples -= read_samples;
974
}
975
return samples_requested - samples;
976
}
977
978
int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int flags)
979
{
980
if (!dec || !io || (flags & (~MP3D_FLAGS_MASK)))
981
return MP3D_E_PARAM;
982
memset(dec, 0, sizeof(*dec));
983
#ifdef MINIMP3_HAVE_RING
984
int ret;
985
if (ret = mp3dec_open_ring(&dec->file, MINIMP3_IO_SIZE))
986
return ret;
987
#else
988
dec->file.size = MINIMP3_IO_SIZE;
989
dec->file.buffer = (const uint8_t*)malloc(dec->file.size);
990
if (!dec->file.buffer)
991
return MP3D_E_MEMORY;
992
#endif
993
dec->flags = flags;
994
dec->io = io;
995
mp3dec_init(&dec->mp3d);
996
if (io->seek(0, io->seek_data))
997
return MP3D_E_IOERROR;
998
int ret = mp3dec_iterate_cb(io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
999
if (ret && MP3D_E_USER != ret)
1000
return ret;
1001
if (dec->io->seek(dec->start_offset, dec->io->seek_data))
1002
return MP3D_E_IOERROR;
1003
mp3dec_init(&dec->mp3d);
1004
dec->buffer_samples = 0;
1005
dec->indexes_built = !(dec->vbr_tag_found || (flags & MP3D_DO_NOT_SCAN));
1006
dec->flags &= (~MP3D_DO_NOT_SCAN);
1007
return 0;
1008
}
1009
1010
1011
#ifndef MINIMP3_NO_STDIO
1012
1013
#if defined(__linux__) || defined(__FreeBSD__)
1014
#include <errno.h>
1015
#include <sys/mman.h>
1016
#include <sys/types.h>
1017
#include <sys/stat.h>
1018
#include <unistd.h>
1019
#include <fcntl.h>
1020
#if !defined(_GNU_SOURCE)
1021
#include <sys/ipc.h>
1022
#include <sys/shm.h>
1023
#endif
1024
#if !defined(MAP_POPULATE) && defined(__linux__)
1025
#define MAP_POPULATE 0x08000
1026
#elif !defined(MAP_POPULATE)
1027
#define MAP_POPULATE 0
1028
#endif
1029
1030
static void mp3dec_close_file(mp3dec_map_info_t *map_info)
1031
{
1032
if (map_info->buffer && MAP_FAILED != map_info->buffer)
1033
munmap((void *)map_info->buffer, map_info->size);
1034
map_info->buffer = 0;
1035
map_info->size = 0;
1036
}
1037
1038
static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
1039
{
1040
if (!file_name)
1041
return MP3D_E_PARAM;
1042
int file;
1043
struct stat st;
1044
memset(map_info, 0, sizeof(*map_info));
1045
retry_open:
1046
file = open(file_name, O_RDONLY);
1047
if (file < 0 && (errno == EAGAIN || errno == EINTR))
1048
goto retry_open;
1049
if (file < 0 || fstat(file, &st) < 0)
1050
{
1051
close(file);
1052
return MP3D_E_IOERROR;
1053
}
1054
1055
map_info->size = st.st_size;
1056
retry_mmap:
1057
map_info->buffer = (const uint8_t *)mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, file, 0);
1058
if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1059
goto retry_mmap;
1060
close(file);
1061
if (MAP_FAILED == map_info->buffer)
1062
return MP3D_E_IOERROR;
1063
return 0;
1064
}
1065
1066
#if MINIMP3_ENABLE_RING && defined(__linux__) && defined(_GNU_SOURCE)
1067
#define MINIMP3_HAVE_RING
1068
static void mp3dec_close_ring(mp3dec_map_info_t *map_info)
1069
{
1070
#if defined(__linux__) && defined(_GNU_SOURCE)
1071
if (map_info->buffer && MAP_FAILED != map_info->buffer)
1072
munmap((void *)map_info->buffer, map_info->size*2);
1073
#else
1074
if (map_info->buffer)
1075
{
1076
shmdt(map_info->buffer);
1077
shmdt(map_info->buffer + map_info->size);
1078
}
1079
#endif
1080
map_info->buffer = 0;
1081
map_info->size = 0;
1082
}
1083
1084
static int mp3dec_open_ring(mp3dec_map_info_t *map_info, size_t size)
1085
{
1086
int memfd, page_size;
1087
#if defined(__linux__) && defined(_GNU_SOURCE)
1088
void *buffer;
1089
int res;
1090
#endif
1091
memset(map_info, 0, sizeof(*map_info));
1092
1093
#ifdef _SC_PAGESIZE
1094
page_size = sysconf(_SC_PAGESIZE);
1095
#else
1096
page_size = getpagesize();
1097
#endif
1098
map_info->size = (size + page_size - 1)/page_size*page_size;
1099
1100
#if defined(__linux__) && defined(_GNU_SOURCE)
1101
memfd = memfd_create("mp3_ring", 0);
1102
if (memfd < 0)
1103
return MP3D_E_MEMORY;
1104
1105
retry_ftruncate:
1106
res = ftruncate(memfd, map_info->size);
1107
if (res && (errno == EAGAIN || errno == EINTR))
1108
goto retry_ftruncate;
1109
if (res)
1110
goto error;
1111
1112
retry_mmap:
1113
map_info->buffer = (const uint8_t *)mmap(NULL, map_info->size*2, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
1114
if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1115
goto retry_mmap;
1116
if (MAP_FAILED == map_info->buffer || !map_info->buffer)
1117
goto error;
1118
retry_mmap2:
1119
buffer = mmap((void *)map_info->buffer, map_info->size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, memfd, 0);
1120
if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1121
goto retry_mmap2;
1122
if (MAP_FAILED == map_info->buffer || buffer != (void *)map_info->buffer)
1123
goto error;
1124
retry_mmap3:
1125
buffer = mmap((void *)map_info->buffer + map_info->size, map_info->size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, memfd, 0);
1126
if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1127
goto retry_mmap3;
1128
if (MAP_FAILED == map_info->buffer || buffer != (void *)(map_info->buffer + map_info->size))
1129
goto error;
1130
1131
close(memfd);
1132
return 0;
1133
error:
1134
close(memfd);
1135
mp3dec_close_ring(map_info);
1136
return MP3D_E_MEMORY;
1137
#else
1138
memfd = shmget(IPC_PRIVATE, map_info->size, IPC_CREAT | 0700);
1139
if (memfd < 0)
1140
return MP3D_E_MEMORY;
1141
retry_mmap:
1142
map_info->buffer = (const uint8_t *)mmap(NULL, map_info->size*2, PROT_NONE, MAP_PRIVATE, -1, 0);
1143
if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
1144
goto retry_mmap;
1145
if (MAP_FAILED == map_info->buffer)
1146
goto error;
1147
if (map_info->buffer != shmat(memfd, map_info->buffer, 0))
1148
goto error;
1149
if ((map_info->buffer + map_info->size) != shmat(memfd, map_info->buffer + map_info->size, 0))
1150
goto error;
1151
if (shmctl(memfd, IPC_RMID, NULL) < 0)
1152
return MP3D_E_MEMORY;
1153
return 0;
1154
error:
1155
shmctl(memfd, IPC_RMID, NULL);
1156
mp3dec_close_ring(map_info);
1157
return MP3D_E_MEMORY;
1158
#endif
1159
}
1160
#endif /*MINIMP3_ENABLE_RING*/
1161
#elif defined(_WIN32)
1162
#include <windows.h>
1163
1164
static void mp3dec_close_file(mp3dec_map_info_t *map_info)
1165
{
1166
if (map_info->buffer)
1167
UnmapViewOfFile(map_info->buffer);
1168
map_info->buffer = 0;
1169
map_info->size = 0;
1170
}
1171
1172
static int mp3dec_open_file_h(HANDLE file, mp3dec_map_info_t *map_info)
1173
{
1174
memset(map_info, 0, sizeof(*map_info));
1175
1176
HANDLE mapping = NULL;
1177
LARGE_INTEGER s;
1178
s.LowPart = GetFileSize(file, (DWORD*)&s.HighPart);
1179
if (s.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
1180
goto error;
1181
map_info->size = s.QuadPart;
1182
1183
mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
1184
if (!mapping)
1185
goto error;
1186
map_info->buffer = (const uint8_t*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, s.QuadPart);
1187
CloseHandle(mapping);
1188
if (!map_info->buffer)
1189
goto error;
1190
1191
CloseHandle(file);
1192
return 0;
1193
error:
1194
mp3dec_close_file(map_info);
1195
CloseHandle(file);
1196
return MP3D_E_IOERROR;
1197
}
1198
1199
static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
1200
{
1201
if (!file_name)
1202
return MP3D_E_PARAM;
1203
HANDLE file = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
1204
if (INVALID_HANDLE_VALUE == file)
1205
return MP3D_E_IOERROR;
1206
return mp3dec_open_file_h(file, map_info);
1207
}
1208
1209
static int mp3dec_open_file_w(const wchar_t *file_name, mp3dec_map_info_t *map_info)
1210
{
1211
if (!file_name)
1212
return MP3D_E_PARAM;
1213
HANDLE file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
1214
if (INVALID_HANDLE_VALUE == file)
1215
return MP3D_E_IOERROR;
1216
return mp3dec_open_file_h(file, map_info);
1217
}
1218
#else
1219
#include <stdio.h>
1220
1221
static void mp3dec_close_file(mp3dec_map_info_t *map_info)
1222
{
1223
if (map_info->buffer)
1224
free((void *)map_info->buffer);
1225
map_info->buffer = 0;
1226
map_info->size = 0;
1227
}
1228
1229
static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
1230
{
1231
if (!file_name)
1232
return MP3D_E_PARAM;
1233
memset(map_info, 0, sizeof(*map_info));
1234
FILE *file = fopen(file_name, "rb");
1235
if (!file)
1236
return MP3D_E_IOERROR;
1237
int res = MP3D_E_IOERROR;
1238
long size = -1;
1239
if (fseek(file, 0, SEEK_END))
1240
goto error;
1241
size = ftell(file);
1242
if (size < 0)
1243
goto error;
1244
map_info->size = (size_t)size;
1245
if (fseek(file, 0, SEEK_SET))
1246
goto error;
1247
map_info->buffer = (uint8_t *)malloc(map_info->size);
1248
if (!map_info->buffer)
1249
{
1250
res = MP3D_E_MEMORY;
1251
goto error;
1252
}
1253
if (fread((void *)map_info->buffer, 1, map_info->size, file) != map_info->size)
1254
goto error;
1255
fclose(file);
1256
return 0;
1257
error:
1258
mp3dec_close_file(map_info);
1259
fclose(file);
1260
return res;
1261
}
1262
#endif
1263
1264
static int mp3dec_detect_mapinfo(mp3dec_map_info_t *map_info)
1265
{
1266
int ret = mp3dec_detect_buf(map_info->buffer, map_info->size);
1267
mp3dec_close_file(map_info);
1268
return ret;
1269
}
1270
1271
static int mp3dec_load_mapinfo(mp3dec_t *dec, mp3dec_map_info_t *map_info, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
1272
{
1273
int ret = mp3dec_load_buf(dec, map_info->buffer, map_info->size, info, progress_cb, user_data);
1274
mp3dec_close_file(map_info);
1275
return ret;
1276
}
1277
1278
static int mp3dec_iterate_mapinfo(mp3dec_map_info_t *map_info, MP3D_ITERATE_CB callback, void *user_data)
1279
{
1280
int ret = mp3dec_iterate_buf(map_info->buffer, map_info->size, callback, user_data);
1281
mp3dec_close_file(map_info);
1282
return ret;
1283
}
1284
1285
static int mp3dec_ex_open_mapinfo(mp3dec_ex_t *dec, int flags)
1286
{
1287
int ret = mp3dec_ex_open_buf(dec, dec->file.buffer, dec->file.size, flags);
1288
dec->is_file = 1;
1289
if (ret)
1290
mp3dec_ex_close(dec);
1291
return ret;
1292
}
1293
1294
int mp3dec_detect(const char *file_name)
1295
{
1296
int ret;
1297
mp3dec_map_info_t map_info;
1298
if ((ret = mp3dec_open_file(file_name, &map_info)))
1299
return ret;
1300
return mp3dec_detect_mapinfo(&map_info);
1301
}
1302
1303
int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
1304
{
1305
int ret;
1306
mp3dec_map_info_t map_info;
1307
if ((ret = mp3dec_open_file(file_name, &map_info)))
1308
return ret;
1309
return mp3dec_load_mapinfo(dec, &map_info, info, progress_cb, user_data);
1310
}
1311
1312
int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data)
1313
{
1314
int ret;
1315
mp3dec_map_info_t map_info;
1316
if ((ret = mp3dec_open_file(file_name, &map_info)))
1317
return ret;
1318
return mp3dec_iterate_mapinfo(&map_info, callback, user_data);
1319
}
1320
1321
int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int flags)
1322
{
1323
int ret;
1324
if (!dec)
1325
return MP3D_E_PARAM;
1326
if ((ret = mp3dec_open_file(file_name, &dec->file)))
1327
return ret;
1328
return mp3dec_ex_open_mapinfo(dec, flags);
1329
}
1330
1331
void mp3dec_ex_close(mp3dec_ex_t *dec)
1332
{
1333
#ifdef MINIMP3_HAVE_RING
1334
if (dec->io)
1335
mp3dec_close_ring(&dec->file);
1336
#else
1337
if (dec->io && dec->file.buffer)
1338
free((void*)dec->file.buffer);
1339
#endif
1340
if (dec->is_file)
1341
mp3dec_close_file(&dec->file);
1342
if (dec->index.frames)
1343
free(dec->index.frames);
1344
memset(dec, 0, sizeof(*dec));
1345
}
1346
1347
#ifdef _WIN32
1348
int mp3dec_detect_w(const wchar_t *file_name)
1349
{
1350
int ret;
1351
mp3dec_map_info_t map_info;
1352
if ((ret = mp3dec_open_file_w(file_name, &map_info)))
1353
return ret;
1354
return mp3dec_detect_mapinfo(&map_info);
1355
}
1356
1357
int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
1358
{
1359
int ret;
1360
mp3dec_map_info_t map_info;
1361
if ((ret = mp3dec_open_file_w(file_name, &map_info)))
1362
return ret;
1363
return mp3dec_load_mapinfo(dec, &map_info, info, progress_cb, user_data);
1364
}
1365
1366
int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data)
1367
{
1368
int ret;
1369
mp3dec_map_info_t map_info;
1370
if ((ret = mp3dec_open_file_w(file_name, &map_info)))
1371
return ret;
1372
return mp3dec_iterate_mapinfo(&map_info, callback, user_data);
1373
}
1374
1375
int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int flags)
1376
{
1377
int ret;
1378
if ((ret = mp3dec_open_file_w(file_name, &dec->file)))
1379
return ret;
1380
return mp3dec_ex_open_mapinfo(dec, flags);
1381
}
1382
#endif
1383
#else /* MINIMP3_NO_STDIO */
1384
void mp3dec_ex_close(mp3dec_ex_t *dec)
1385
{
1386
#ifdef MINIMP3_HAVE_RING
1387
if (dec->io)
1388
mp3dec_close_ring(&dec->file);
1389
#else
1390
if (dec->io && dec->file.buffer)
1391
free((void*)dec->file.buffer);
1392
#endif
1393
if (dec->index.frames)
1394
free(dec->index.frames);
1395
memset(dec, 0, sizeof(*dec));
1396
}
1397
#endif
1398
1399
#endif /* MINIMP3_IMPLEMENTATION && !_MINIMP3_EX_IMPLEMENTATION_GUARD */
1400
1401