Possible bug in scalefactor calculation
Robert Kausch via Lame-dev <[email protected]> Mon, 6 Jul 2020 23:03:42 +0200
| Newsgroups | gmane.comp.audio.mp3.lame |
|---|---|
| Message-ID | <[email protected]> |
Hi all, I've received a few crash reports involving LAME through Windows Error Reporting (WER). This has never been actively reported by any user and I have no way to reproduce it, only the stack trace from the WER log: 0: _wassert in mingw-w64-crt/misc/wassert.c:54 1: assert in mingw-w64-crt/misc/wassert.c:31 2: long_block_constrain in vbrquantize.c:869 3: VBR_encode_frame in vbrquantize.c:1306 4: VBR_new_iteration_loop in quantize.c:1685 Turns out I have asserts enabled in my Windows release builds, otherwise this would not have come up. An assert is triggered in long_block_constrain, checking that vbrsf[n] is larger or equal to vbrsfmin[n]. This is the same issue as reported in https://sourceforge.net/p/lame/bugs/490/. Only difference is that there it was triggered in short_block_constrain. The scalefactors are computed in block_sf(), so for this assert to trigger, block_sf must somehow put a higher value in vbrsfmin[] than in vbrsf[] for one slot. Looking at the code in block_sf(), I find one possible explanation: - At least 2 iterations of the while loop are necessary: - 1st iteration: - vbrsfmin[0] = m1 = 128 - if (sfb < psymax && w > 2) -> yes - if (energy_above_cutoff[sfb]) -> yes - vbrsf[0] = m2 = 128 - m_o = 128 - 2nd iteration: - vbrsfmin[1] = m1 = 129 - if (sfb < psymax && w > 2) -> yes - if (energy_above_cutoff[sfb]) -> no - vbrsf[1] = m2 = 255 - After the while loop, m_o is checked - if (m_o > -1) -> yes - if (vbrsf[0] == 255) -> no - if (vbrsf[1] == 255) -> yes - vbrsf[1] = m_o = 128 This would leave vbrsf[1] as 128 while vbrsfmin[1] is 129, triggering the assert in long_block_constrain. I'm not a codec guy, so I'm not sure if any of the above makes sense. Maybe this situation is supposed to be impossible to occur for other reasons. Looking at the code, I cannot find another way the assert might be triggered, but maybe someone with more codec experience can find a better explanation. Attached is a proposed patch, but again, I'm not sure if this is the correct way to fix this. Maybe this issue goes deeper and a more elaborate fix is required. Anyway, would be great if this could be investigated/fixed. Cheers, Robert -- ---- Robert Kausch [email protected] _______________________________________________ Lame-dev mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/lame-dev
lame-vbrqsf.patch
(text/plain, 508 B)
diff -Naur lame-3.100/libmp3lame/vbrquantize.c lame-3.100-patched/libmp3lame/vbrquantize.c
--- lame-3.100/libmp3lame/vbrquantize.c 2012-02-07 12:36:35 +0000
+++ lame-3.100-patched/libmp3lame/vbrquantize.c 2020-07-06 20:32:38 +0000
@@ -478,6 +478,9 @@
for (sfb = 0; sfb < SFBMAX; ++sfb) {
if (vbrsf[sfb] == 255) {
vbrsf[sfb] = m_o;
+ if (vbrsfmin[sfb] > m_o) {
+ vbrsfmin[sfb] = m_o;
+ }
}
}
}