ref: 4e4702c945707858222f49ffe4bc4ac7f5c17ae1
parent: edd3ce5805803f3121dd05fe5a929f8976ab2f72
author: lieff <[email protected]>
date: Thu Feb 27 20:31:04 EST 2020
mp3dec_ex: do not decode empty frame with vbrtag, if it's valid, but there no frames flag, just skip it.
--- a/minimp3_ex.h
+++ b/minimp3_ex.h
@@ -191,7 +191,7 @@
return 0;
int flags = tag[7];
if (!((flags & FRAMES_FLAG)))
- return 0;
+ return -1;
tag += 8;
*frames = (uint32_t)(tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3];
tag += 4;
@@ -308,7 +308,8 @@
frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
frame_info.frame_bytes = frame_size;
samples = hdr_frame_samples(hdr)*frame_info.channels;
- if (mp3dec_check_vbrtag(hdr, frame_size, &frames, &delay, &padding))
+ int ret = mp3dec_check_vbrtag(hdr, frame_size, &frames, &delay, &padding);
+ if (ret > 0)
{
padding *= frame_info.channels;
to_skip = delay*frame_info.channels;
@@ -319,6 +320,9 @@
detected_samples -= padding;
if (!detected_samples)
return 0;
+ }
+ if (ret)
+ {
if (io)
{
consumed += frame_size;
@@ -552,7 +556,10 @@
dec->start_offset = dec->offset = offset;
dec->end_offset = offset + buf_size;
dec->free_format_bytes = free_format_bytes; /* should not change */
- if (mp3dec_check_vbrtag(frame, frame_size, &frames, &delay, &padding))
+ int ret = mp3dec_check_vbrtag(frame, frame_size, &frames, &delay, &padding);
+ if (ret)
+ dec->start_offset = dec->offset = offset + frame_size;
+ if (ret > 0)
{
padding *= info->channels;
dec->start_delay = dec->to_skip = delay*info->channels;
@@ -562,10 +569,10 @@
if (padding > 0 && dec->samples >= (uint64_t)padding)
dec->samples -= padding;
dec->detected_samples = dec->samples;
- dec->start_offset = dec->offset = offset + frame_size;
dec->vbr_tag_found = 1;
return MP3D_E_USER;
- }
+ } else if (ret < 0)
+ return 0;
}
if (dec->index.num_frames + 1 > dec->index.capacity)
{
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -95,6 +95,10 @@
[[ "$(./minimp3 -m 8 -s 1 -e 5 vectors/l3-nonstandard-vbrtag-only.bit)" != "error: mp3dec_ex_seek()=-3 failed" ]] && echo fail && exit 1 || echo pass
[[ "$(./minimp3 -m 6 -s 1 -f 2 vectors/l3-nonstandard-sin1k0db_lame_vbrtag.bit)" != "error: mp3dec_ex_seek()=-2 failed" ]] && echo fail && exit 1 || echo pass
[[ "$(./minimp3 vectors/l3-nonstandard-vbrtag-empty.bit)" != "rate=0 samples=0 max_diff=0 PSNR=99.000000" ]] && echo fail && exit 1 || echo pass
+# Currently vbrtag with no frames flag treated as no vbrtag, not sure if any software produce such files.
+# Delay and padding usage can be implemented if such software/files exists.
+[[ "$(./minimp3 vectors/l3-nonstandard-vbrtag-noframes.bit)" != "rate=44100 samples=0 max_diff=0 PSNR=99.000000" ]] && echo fail && exit 1 || echo pass
+[[ "$(./minimp3 -m 6 vectors/l3-nonstandard-vbrtag-noframes.bit)" != "rate=44100 samples=0 max_diff=0 PSNR=99.000000" ]] && echo fail && exit 1 || echo pass
set -e
./minimp3 -m 6 -s 215 -b vectors/l3-sin1k0db.bit vectors/l3-sin1k0db.pcm
binary files /dev/null b/vectors/l3-nonstandard-vbrtag-noframes.bit differ