| @@ -81,7 +81,7 @@ extern "C" { · 80 unmodified lines |
| 81 | #endif | 81 | #endif |
| 82 | | 82 | |
| 83 | /* decode whole buffer block */ | 83 | /* decode whole buffer block */ |
| 84 | void 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); | 84 | 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); |
| 85 | 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); | 85 | 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); |
| 86 | /* iterate through frames */ | 86 | /* iterate through frames */ |
| 87 | size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data); | 87 | size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data); |
| @@ -134,8 +134,9 @@ static void mp3dec_skip_id3v1(const uint8_t *buf, size_t *pbuf_size) · 46 unmodified lines |
| 134 | | 134 | |
| 135 | static size_t mp3dec_skip_id3v2(const uint8_t *buf, size_t buf_size) | 135 | static size_t mp3dec_skip_id3v2(const uint8_t *buf, size_t buf_size) |
| 136 | { | 136 | { |
| | 137 | #define MINIMP3_ID3_DETECT_SIZE 10 |
| 137 | #ifndef MINIMP3_NOSKIP_ID3V2 | 138 | #ifndef MINIMP3_NOSKIP_ID3V2 |
| 138 | if (buf_size >= 10 && !memcmp(buf, "ID3", 3) && !((buf[5] & 15) || (buf[6] & 0x80) || (buf[7] & 0x80) || (buf[8] & 0x80) || (buf[9] & 0x80))) | 139 | 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))) |
| 139 | { | 140 | { |
| 140 | size_t id3v2size = (((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f)) + 10; | 141 | size_t id3v2size = (((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f)) + 10; |
| 141 | if ((buf[5] & 16)) | 142 | if ((buf[5] & 16)) |
| @@ -210,7 +211,12 @@ static int mp3dec_check_vbrtag(const uint8_t *frame, int frame_size, uint32_t *f · 68 unmodified lines |
| 210 | return 1; | 211 | return 1; |
| 211 | } | 212 | } |
| 212 | | 213 | |
| 213 | void 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) | 214 | 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) |
| | 215 | { |
| | 216 | return mp3dec_load_cb(dec, 0, (uint8_t *)buf, buf_size, info, progress_cb, user_data); |
| | 217 | } |
| | 218 | |
| | 219 | 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) |
| 214 | { | 220 | { |
| 215 | uint64_t detected_samples = 0; | 221 | uint64_t detected_samples = 0; |
| 216 | size_t orig_buf_size = buf_size; | 222 | size_t orig_buf_size = buf_size; |
| @@ -218,24 +224,64 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 1 unmodified line |
| 218 | mp3dec_frame_info_t frame_info; | 224 | mp3dec_frame_info_t frame_info; |
| 219 | memset(info, 0, sizeof(*info)); | 225 | memset(info, 0, sizeof(*info)); |
| 220 | memset(&frame_info, 0, sizeof(frame_info)); | 226 | memset(&frame_info, 0, sizeof(frame_info)); |
| | 227 | |
| 221 | /* skip id3 */ | 228 | /* skip id3 */ |
| 222 | mp3dec_skip_id3(&buf, &buf_size); | 229 | size_t filled, consumed; |
| 223 | if (!buf_size) | 230 | int eof; |
| 224 | return; | 231 | if (io) |
| | 232 | { |
| | 233 | io->seek(0, io->seek_data); |
| | 234 | filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data), consumed = 0, eof = 0; |
| | 235 | if (MINIMP3_ID3_DETECT_SIZE != filled) |
| | 236 | return 0; |
| | 237 | size_t id3v2size = mp3dec_skip_id3v2(buf, filled); |
| | 238 | if (id3v2size) |
| | 239 | { |
| | 240 | io->seek(id3v2size, io->seek_data); |
| | 241 | filled = io->read(buf, buf_size, io->read_data); |
| | 242 | } else |
| | 243 | filled += io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data); |
| | 244 | if (filled < MINIMP3_BUF_SIZE) |
| | 245 | mp3dec_skip_id3v1(buf, &filled); |
| | 246 | } else |
| | 247 | { |
| | 248 | mp3dec_skip_id3((const uint8_t **)&buf, &buf_size); |
| | 249 | if (!buf_size) |
| | 250 | return 0; |
| | 251 | } |
| 225 | /* try to make allocation size assumption by first frame or vbr tag */ | 252 | /* try to make allocation size assumption by first frame or vbr tag */ |
| 226 | mp3dec_init(dec); | 253 | mp3dec_init(dec); |
| 227 | int samples; | 254 | int samples; |
| 228 | do | 255 | do |
| 229 | { | 256 | { |
| 230 | uint32_t frames; | 257 | uint32_t frames; |
| 231 | int delay, padding, free_format_bytes = 0, frame_size = 0; | 258 | int i, delay, padding, free_format_bytes = 0, frame_size = 0; |
| 232 | int i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size); | 259 | if (io) |
| 233 | buf += i; | 260 | { |
| 234 | buf_size -= i; | 261 | if (!eof && filled - consumed < MINIMP3_BUF_SIZE) |
| | 262 | { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */ |
| | 263 | memmove(buf, buf + consumed, filled - consumed); |
| | 264 | filled -= consumed; |
| | 265 | consumed = 0; |
| | 266 | size_t readed = io->read(buf + filled, buf_size - filled, io->read_data); |
| | 267 | if (readed != (buf_size - filled)) |
| | 268 | eof = 1; |
| | 269 | filled += readed; |
| | 270 | if (eof) |
| | 271 | mp3dec_skip_id3v1(buf, &filled); |
| | 272 | } |
| | 273 | i = mp3d_find_frame(buf + consumed, filled - consumed, &free_format_bytes, &frame_size); |
| | 274 | consumed += i; |
| | 275 | } else |
| | 276 | { |
| | 277 | i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size); |
| | 278 | buf += i; |
| | 279 | buf_size -= i; |
| | 280 | } |
| 235 | if (i && !frame_size) | 281 | if (i && !frame_size) |
| 236 | continue; | 282 | continue; |
| 237 | if (!frame_size) | 283 | if (!frame_size) |
| 238 | return; | 284 | return 0; |
| 239 | const uint8_t *hdr = buf; | 285 | const uint8_t *hdr = buf; |
| 240 | frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2; | 286 | frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2; |
| 241 | frame_info.hz = hdr_sample_rate_hz(hdr); | 287 | frame_info.hz = hdr_sample_rate_hz(hdr); |
| @@ -253,9 +299,15 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 11 unmodified lines |
| 253 | if (padding > 0 && detected_samples >= (uint64_t)padding) | 299 | if (padding > 0 && detected_samples >= (uint64_t)padding) |
| 254 | detected_samples -= padding; | 300 | detected_samples -= padding; |
| 255 | if (!detected_samples) | 301 | if (!detected_samples) |
| 256 | return; | 302 | return 0; |
| 257 | buf += frame_size; | 303 | if (io) |
| 258 | buf_size -= frame_size; | 304 | { |
| | 305 | consumed += frame_size; |
| | 306 | } else |
| | 307 | { |
| | 308 | buf += frame_size; |
| | 309 | buf_size -= frame_size; |
| | 310 | } |
| 259 | } | 311 | } |
| 260 | break; | 312 | break; |
| 261 | } while(1); | 313 | } while(1); |
| @@ -266,14 +318,13 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 4 unmodified lines |
| 266 | allocated += (buf_size/frame_info.frame_bytes)*samples*sizeof(mp3d_sample_t); | 318 | allocated += (buf_size/frame_info.frame_bytes)*samples*sizeof(mp3d_sample_t); |
| 267 | info->buffer = (mp3d_sample_t*)malloc(allocated); | 319 | info->buffer = (mp3d_sample_t*)malloc(allocated); |
| 268 | if (!info->buffer) | 320 | if (!info->buffer) |
| 269 | return; | 321 | return MP3D_E_MEMORY; |
| 270 | /* save info */ | 322 | /* save info */ |
| 271 | info->channels = frame_info.channels; | 323 | info->channels = frame_info.channels; |
| 272 | info->hz = frame_info.hz; | 324 | info->hz = frame_info.hz; |
| 273 | info->layer = frame_info.layer; | 325 | info->layer = frame_info.layer; |
| 274 | /* decode all frames */ | 326 | /* decode all frames */ |
| 275 | size_t avg_bitrate_kbps = 0, frames = 0; | 327 | size_t avg_bitrate_kbps = 0, frames = 0; |
| 276 | int frame_bytes; | | |
| 277 | do | 328 | do |
| 278 | { | 329 | { |
| 279 | if ((allocated - info->samples*sizeof(mp3d_sample_t)) < MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t)) | 330 | if ((allocated - info->samples*sizeof(mp3d_sample_t)) < MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t)) |
| @@ -281,10 +332,28 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 1 unmodified line |
| 281 | allocated *= 2; | 332 | allocated *= 2; |
| 282 | info->buffer = (mp3d_sample_t*)realloc(info->buffer, allocated); | 333 | info->buffer = (mp3d_sample_t*)realloc(info->buffer, allocated); |
| 283 | } | 334 | } |
| 284 | samples = mp3dec_decode_frame(dec, buf, MINIMP3_MIN(buf_size, (size_t)INT_MAX), info->buffer + info->samples, &frame_info); | 335 | if (io) |
| 285 | frame_bytes = frame_info.frame_bytes; | 336 | { |
| 286 | buf += frame_bytes; | 337 | if (!eof && filled - consumed < MINIMP3_BUF_SIZE) |
| 287 | buf_size -= frame_bytes; | 338 | { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */ |
| | 339 | memmove(buf, buf + consumed, filled - consumed); |
| | 340 | filled -= consumed; |
| | 341 | consumed = 0; |
| | 342 | size_t readed = io->read(buf + filled, buf_size - filled, io->read_data); |
| | 343 | if (readed != (buf_size - filled)) |
| | 344 | eof = 1; |
| | 345 | filled += readed; |
| | 346 | if (eof) |
| | 347 | mp3dec_skip_id3v1(buf, &filled); |
| | 348 | } |
| | 349 | samples = mp3dec_decode_frame(dec, buf + consumed, filled - consumed, info->buffer + info->samples, &frame_info); |
| | 350 | consumed += frame_info.frame_bytes; |
| | 351 | } else |
| | 352 | { |
| | 353 | samples = mp3dec_decode_frame(dec, buf, MINIMP3_MIN(buf_size, (size_t)INT_MAX), info->buffer + info->samples, &frame_info); |
| | 354 | buf += frame_info.frame_bytes; |
| | 355 | buf_size -= frame_info.frame_bytes; |
| | 356 | } |
| 288 | if (samples) | 357 | if (samples) |
| 289 | { | 358 | { |
| 290 | if (info->hz != frame_info.hz || info->layer != frame_info.layer) | 359 | if (info->hz != frame_info.hz || info->layer != frame_info.layer) |
| @@ -309,7 +378,7 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 18 unmodified lines |
| 309 | if (progress_cb) | 378 | if (progress_cb) |
| 310 | progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info); | 379 | progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info); |
| 311 | } | 380 | } |
| 312 | } while (frame_bytes); | 381 | } while (frame_info.frame_bytes); |
| 313 | if (detected_samples && info->samples > detected_samples) | 382 | if (detected_samples && info->samples > detected_samples) |
| 314 | info->samples = detected_samples; /* cut padding */ | 383 | info->samples = detected_samples; /* cut padding */ |
| 315 | /* reallocate to normal buffer size */ | 384 | /* reallocate to normal buffer size */ |
| @@ -317,6 +386,7 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 1 unmodified line |
| 317 | info->buffer = (mp3d_sample_t*)realloc(info->buffer, info->samples*sizeof(mp3d_sample_t)); | 386 | info->buffer = (mp3d_sample_t*)realloc(info->buffer, info->samples*sizeof(mp3d_sample_t)); |
| 318 | if (frames) | 387 | if (frames) |
| 319 | info->avg_bitrate_kbps = avg_bitrate_kbps/frames; | 388 | info->avg_bitrate_kbps = avg_bitrate_kbps/frames; |
| | 389 | return 0; |
| 320 | } | 390 | } |
| 321 | | 391 | |
| 322 | size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data) | 392 | size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data) |
| @@ -363,11 +433,13 @@ uint64_t mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ · 40 unmodified lines |
| 363 | if (buf_size < MINIMP3_BUF_SIZE) | 433 | if (buf_size < MINIMP3_BUF_SIZE) |
| 364 | return 0; | 434 | return 0; |
| 365 | io->seek(0, io->seek_data); | 435 | io->seek(0, io->seek_data); |
| 366 | size_t filled = io->read(buf, 10, io->read_data), consumed = 0; | 436 | size_t filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data), consumed = 0; |
| 367 | uint64_t readed = 0, frames = 0; | 437 | uint64_t readed = 0, frames = 0; |
| 368 | mp3dec_frame_info_t frame_info; | 438 | mp3dec_frame_info_t frame_info; |
| 369 | int eof = 0; | 439 | int eof = 0; |
| 370 | memset(&frame_info, 0, sizeof(frame_info)); | 440 | memset(&frame_info, 0, sizeof(frame_info)); |
| | 441 | if (MINIMP3_ID3_DETECT_SIZE != filled) |
| | 442 | return 0; |
| 371 | size_t id3v2size = mp3dec_skip_id3v2(buf, filled); | 443 | size_t id3v2size = mp3dec_skip_id3v2(buf, filled); |
| 372 | if (id3v2size) | 444 | if (id3v2size) |
| 373 | { | 445 | { |
| @@ -375,7 +447,7 @@ uint64_t mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ · 1 unmodified line |
| 375 | filled = io->read(buf, buf_size, io->read_data); | 447 | filled = io->read(buf, buf_size, io->read_data); |
| 376 | readed += id3v2size; | 448 | readed += id3v2size; |
| 377 | } else | 449 | } else |
| 378 | filled += io->read(buf + 10, buf_size - 10, io->read_data); | 450 | filled += io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data); |
| 379 | if (filled < MINIMP3_BUF_SIZE) | 451 | if (filled < MINIMP3_BUF_SIZE) |
| 380 | mp3dec_skip_id3v1(buf, &filled); | 452 | mp3dec_skip_id3v1(buf, &filled); |
| 381 | do | 453 | do |