ref: 9eea8134f8214f970ce761b97c4f4fc534f87301
parent: fe9d954e72f315aa4caa4f490fe2b7a4fea1b416
author: lieff <lieff@users.noreply.github.com>
date: Sun Jan 26 19:23:23 EST 2020
Support index binary search on seek.
--- a/minimp3_ex.h
+++ b/minimp3_ex.h
@@ -12,6 +12,7 @@
#define MP3D_SEEK_TO_SAMPLE 1
#define MINIMP3_PREDECODE_FRAMES 2 /* frames to pre-decode and skip after seek (to fill internal structures) */
+/*#define MINIMP3_SEEK_IDX_LINEAR_SEARCH*/ /* define to use linear index search instead of binary search on seek */
#define MP3D_E_MEMORY -1
@@ -290,6 +291,30 @@
return 0;
}
+#ifndef MINIMP3_SEEK_IDX_LINEAR_SEARCH
+static size_t mp3dec_idx_binary_search(mp3dec_index_t *idx, uint64_t position)
+{
+ size_t end = idx->num_frames, start = 0, index = 0;
+ while (start <= end)
+ {
+ size_t mid = (start + end) / 2;
+ if (idx->frames[mid].sample >= position)
+ { /* move left side. */
+ if (idx->frames[mid].sample == position)
+ return mid;
+ end = mid - 1;
+ } else
+ { /* move to right side */
+ index = mid;
+ start = mid + 1;
+ if (start == idx->num_frames)
+ break;
+ }
+ }
+ return index;
+}
+#endif
+
int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position)
{
size_t i;
@@ -313,15 +338,23 @@
}
if (!dec->index.frames)
goto seek_zero; /* no frames in file - seek to zero */
+#ifdef MINIMP3_SEEK_IDX_LINEAR_SEARCH
for (i = 0; i < dec->index.num_frames; i++)
{
if (dec->index.frames[i].sample >= position)
break;
}
+#else
+ i = mp3dec_idx_binary_search(&dec->index, position);
+#endif
if (i)
{
int to_fill_bytes = 511;
- int skip_frames = MINIMP3_PREDECODE_FRAMES + ((dec->index.frames[i].sample == position) ? 0 : 1);
+ int skip_frames = MINIMP3_PREDECODE_FRAMES
+#ifdef MINIMP3_SEEK_IDX_LINEAR_SEARCH
+ + ((dec->index.frames[i].sample == position) ? 0 : 1)
+#endif
+ ;
i -= MINIMP3_MIN(i, (size_t)skip_frames);
while (i && to_fill_bytes)
{ /* make sure bit-reservoir is filled when we start decoding */