shithub: mp3dec

Download patch

ref: 7bdfc8bd3cbb70e0b29556298c620587e38506f2
parent: 871dd9cdd6859b5725ac4560fe2b3613846a4234
author: lieff <lieff@users.noreply.github.com>
date: Sun Sep 6 18:38:24 EDT 2020

minimp3_ex: add MP3D_ALLOW_MONO_STEREO_TRANSITION mp3dec_ex_open_* flag
when MINIMP3_ALLOW_MONO_STEREO_TRANSITION enabled.

--- a/minimp3_ex.h
+++ b/minimp3_ex.h
@@ -12,6 +12,12 @@
 #define MP3D_SEEK_TO_BYTE   0      /* mp3dec_ex_seek seeks to byte in stream */
 #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) */
 #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 */
+#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
+#define MP3D_ALLOW_MONO_STEREO_TRANSITION  4
+#define MP3D_FLAGS_MASK 7
+#else
+#define MP3D_FLAGS_MASK 3
+#endif
 
 /* compile-time config */
 #define MINIMP3_PREDECODE_FRAMES 2 /* frames to pre-decode and skip after seek (to fill internal structures) */
@@ -665,7 +671,7 @@
 
 int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int flags)
 {
-    if (!dec || !buf || (size_t)-1 == buf_size || (flags & (~3)))
+    if (!dec || !buf || (size_t)-1 == buf_size || (flags & (~MP3D_FLAGS_MASK)))
         return MP3D_E_PARAM;
     memset(dec, 0, sizeof(*dec));
     dec->file.buffer = buf;
@@ -852,15 +858,15 @@
             dec->last_error = MP3D_E_PARAM;
         return 0;
     }
+    if (dec->detected_samples && dec->cur_sample >= dec->detected_samples)
+        return 0; /* at end of stream */
+    if (dec->last_error)
+        return 0; /* error eof state, seek can reset it */
     *buf = NULL;
     uint64_t end_offset = dec->end_offset ? dec->end_offset : dec->file.size;
     int eof = 0;
     mp3dec_frame_info_t frame_info;
     memset(&frame_info, 0, sizeof(frame_info));
-    if (dec->detected_samples && dec->cur_sample >= dec->detected_samples)
-        return 0; /* at end of stream */
-    if (dec->last_error)
-        return 0; /* error eof state, seek can reset it */
     while (dec->buffer_consumed == dec->buffer_samples)
     {
         const uint8_t *dec_buf;
@@ -897,12 +903,9 @@
             dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, dec_buf, MINIMP3_MIN(buf_size, (uint64_t)INT_MAX), dec->buffer, &frame_info);
         }
         dec->buffer_consumed = 0;
-        if (dec->info.hz != frame_info.hz || dec->info.layer != frame_info.layer
-#ifndef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
-            || dec->info.channels != frame_info.channels
-#endif
-            )
+        if (dec->info.hz != frame_info.hz || dec->info.layer != frame_info.layer)
         {
+return_e_decode:
             dec->last_error = MP3D_E_DECODE;
             return 0;
         }
@@ -915,6 +918,14 @@
                 dec->buffer_consumed += skip;
                 dec->to_skip -= skip;
             }
+            if (
+#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
+                !(dec->flags & MP3D_ALLOW_MONO_STEREO_TRANSITION) &&
+#endif
+                dec->buffer_consumed != dec->buffer_samples && dec->info.channels != frame_info.channels)
+            {
+                goto return_e_decode;
+            }
         } else if (dec->to_skip)
         {   /* In mp3 decoding not always can start decode from any frame because of bit reservoir,
                count skip samples for such frames */
@@ -1281,7 +1292,7 @@
 
 int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int flags)
 {
-    if (!dec || !io || (flags & (~3)))
+    if (!dec || !io || (flags & (~MP3D_FLAGS_MASK)))
         return MP3D_E_PARAM;
     memset(dec, 0, sizeof(*dec));
 #ifdef MINIMP3_HAVE_RING
--- a/minimp3_test.c
+++ b/minimp3_test.c
@@ -241,7 +241,7 @@
         size_t readed;
         if (MODE_STREAM == mode)
         {
-            res = mp3dec_ex_open(&dec, input_file_name, seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE);
+            res = mp3dec_ex_open(&dec, input_file_name, (seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE) | MP3D_ALLOW_MONO_STEREO_TRANSITION);
         } else if (MODE_STREAM_BUF == mode)
         {
             int size = 0;
@@ -248,12 +248,12 @@
             FILE *file = fopen(input_file_name, "rb");
             buf = preload(file, &size);
             fclose(file);
-            res = buf ? mp3dec_ex_open_buf(&dec, buf, size, seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE) : MP3D_E_IOERROR;
+            res = buf ? mp3dec_ex_open_buf(&dec, buf, size, (seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE) | MP3D_ALLOW_MONO_STEREO_TRANSITION) : MP3D_E_IOERROR;
         } else if (MODE_STREAM_CB == mode)
         {
             FILE *file = fopen(input_file_name, "rb");
             io.read_data = io.seek_data = file;
-            res = file ? mp3dec_ex_open_cb(&dec, &io, seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE) : MP3D_E_IOERROR;
+            res = file ? mp3dec_ex_open_cb(&dec, &io, (seek_to_byte ? MP3D_SEEK_TO_BYTE : MP3D_SEEK_TO_SAMPLE) | MP3D_ALLOW_MONO_STEREO_TRANSITION) : MP3D_E_IOERROR;
         }
         if (res)
         {
@@ -512,7 +512,7 @@
     ASSERT(MP3D_E_PARAM == ret);
     ret = mp3dec_ex_open_buf(&dec, buf, (size_t)-1, MP3D_SEEK_TO_SAMPLE);
     ASSERT(MP3D_E_PARAM == ret);
-    ret = mp3dec_ex_open_buf(&dec, buf, size, MP3D_SEEK_TO_SAMPLE | (1 << 2));
+    ret = mp3dec_ex_open_buf(&dec, buf, size, MP3D_SEEK_TO_SAMPLE | (MP3D_FLAGS_MASK + 1));
     ASSERT(MP3D_E_PARAM == ret);
     ret = mp3dec_ex_open_buf(&dec, buf, 0, MP3D_SEEK_TO_SAMPLE);
     ASSERT(0 == ret);
@@ -524,7 +524,7 @@
     ASSERT(MP3D_E_PARAM == ret);
     ret = mp3dec_ex_open_cb(&dec, 0, MP3D_SEEK_TO_SAMPLE);
     ASSERT(MP3D_E_PARAM == ret);
-    ret = mp3dec_ex_open_cb(&dec, &io, MP3D_SEEK_TO_SAMPLE | (1 << 2));
+    ret = mp3dec_ex_open_cb(&dec, &io, MP3D_SEEK_TO_SAMPLE | (MP3D_FLAGS_MASK + 1));
     ASSERT(MP3D_E_PARAM == ret);
 
     ret = mp3dec_ex_seek(0, 0);
@@ -566,7 +566,7 @@
     ASSERT(MP3D_E_PARAM == ret);
     ret = mp3dec_ex_open(&dec, 0, MP3D_SEEK_TO_SAMPLE);
     ASSERT(MP3D_E_PARAM == ret);
-    ret = mp3dec_ex_open(&dec, input_file_name, MP3D_SEEK_TO_SAMPLE | (1 << 2));
+    ret = mp3dec_ex_open(&dec, input_file_name, MP3D_SEEK_TO_SAMPLE | (MP3D_FLAGS_MASK + 1));
     ASSERT(MP3D_E_PARAM == ret);
     ret = mp3dec_ex_open(&dec, "not_foud", MP3D_SEEK_TO_SAMPLE);
     ASSERT(MP3D_E_IOERROR == ret);