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);