shithub: mp3dec

Download patch

ref: 78184ecef579fafd9fe2a6c13cf1c40063ba5ab0
parent: fb9083c5f8e0aea1059585f22366e14f9bf5b0a0
author: lieff <[email protected]>
date: Mon Feb 3 19:36:26 EST 2020

support precise seek with cut-ed mp3 files + test random seeks

--- a/minimp3_ex.h
+++ b/minimp3_ex.h
@@ -277,7 +277,13 @@
     idx_frame = &dec->index.frames[dec->index.num_frames++];
     idx_frame->offset = offset;
     idx_frame->sample = dec->samples;
-    dec->samples += hdr_frame_samples(frame)*info->channels;
+    if (!dec->buffer_samples && dec->index.num_frames < 256)
+    {   /* for some cutted mp3 frames, bit-reservoir not filled and decoding can't be started from first frames */
+        /* try to decode up to 255 first frames till samples starts to decode */
+        dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, frame, frame_size, dec->buffer, info);
+        dec->samples += dec->buffer_samples*info->channels;
+    } else
+        dec->samples += hdr_frame_samples(frame)*info->channels;
     return 0;
 }
 
@@ -290,6 +296,8 @@
     mp3dec_init(&dec->mp3d);
     if (mp3dec_iterate_buf(dec->file.buffer, dec->file.size, mp3dec_load_index, dec) > 0 && !dec->index.frames && !dec->vbr_tag_found)
         return MP3D_E_MEMORY;
+    mp3dec_init(&dec->mp3d);
+    dec->buffer_samples = 0;
     return 0;
 }
 
@@ -335,6 +343,7 @@
     if (!dec->index.frames && dec->vbr_tag_found)
     {   /* no index created yet (vbr tag used to calculate track length) */
         dec->samples = 0;
+        dec->buffer_samples = 0;
         if (mp3dec_iterate_buf(dec->file.buffer, dec->file.size, mp3dec_load_index, dec) > 0 && !dec->index.frames)
             return MP3D_E_MEMORY;
     }
@@ -368,6 +377,12 @@
     }
     dec->offset = dec->index.frames[i].offset;
     dec->to_skip = position - dec->index.frames[i].sample;
+    while ((i + 1) < dec->index.num_frames && !dec->index.frames[i].sample && !dec->index.frames[i + 1].sample)
+    {   /* skip not decodable first frames */
+        const uint8_t *hdr = dec->file.buffer + dec->index.frames[i].offset;
+        dec->to_skip += hdr_frame_samples(hdr)*dec->info.channels;
+        i++;
+    }
 do_exit:
     dec->buffer_samples  = 0;
     dec->buffer_consumed = 0;
--- a/minimp3_test.c
+++ b/minimp3_test.c
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <math.h>
 #include <string.h>
+#include <time.h>
 #if defined(_MSC_VER)
     #define strcasecmp(str1, str2) _strnicmp(str1, str2, strlen(str2))
 #else
@@ -121,7 +122,8 @@
         info.channels = dec.info.channels;
         if (position < 0)
         {
-            position = (uint64_t)info.samples*rand()/RAND_MAX;
+            srand(time(0));
+            position = info.samples ? (uint64_t)(info.samples - 1)*rand()/RAND_MAX : 0;
             printf("info: seek to %d/%d\n", position, (int)info.samples);
         }
         if (position)
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -14,7 +14,7 @@
 scripts/test_mode.sh 1 0
 
 echo testing stream mode...
-scripts/test_mode.sh 2 0
+scripts/test_mode.sh 2 -1
 
 echo testing coverage x86 w sse...
 gcc -coverage -O0 -m32 -std=c89 -msse2 -DMINIMP3_TEST -DMINIMP3_NO_WAV -o minimp3 minimp3_test.c -lm