Joshua Haberman wrote:
Currently Audacity uses a 64k input buffer when reading mp3s with libmad. This has worked great for the most part, but I've received a report that one particular mp3 will put Audacity into an infinite loop upon import. Since a trace revealed that the input callback was looping endlessly, I suspected that the buffer wasn't big enough to hold an entire frame, and the input callback was sending libmad the same partial frame over and over.
This sounds like the problem I encountered. The final frame of the mp3 file is truncated, so my input buffering routine returns that which mad_header_decode() hasn't consumed -- the truncated frame. mad_header_decode() indicates the partial frame held in the buffer isn't enough to decode via returning MAD_ERROR_BUFLEN which normally means it wants more input. And normally the partial frame would be copied from the tail of the input buffer to the buffer head and would be followed by the continuation of the frame from the mp3 file. But in this error case we are at the end of the file. And the process loops until otherwise terminated.
I found two ways to work around this nit. One is to pad out the buffer with enough data to hold the balance of the worst case truncated frame. Or have your decoder recognize two consecutive returns from mad_header_decode() where MAD_ERROR_BUFLEN is the return value at the same file offset and terminate the process at that point.
I suggested that this user double the input buffer size, and that fixed the problem.
That shouldn't have remedied the problem I describe above.
Earlier when I asked you about this issue, you said mp3 frames are relatively small (around 418 bytes) so I'm very surprised that 64k wasn't big enough to hold an entire frame. Can you think of any other reason why increasing the buffer size would solve this problem?
If you were seeing this problem because of a corrupt final frame, it is possible the input routine is incorrectly reporting the true (corrupt) data size for some reason in the case of the larger buffer.
Is there a maximum size for mp3 frames that I could safely set as the buffer size, or would I have to dynamically size the buffer to be completely safe?
Except for this nit, mad_header_decode() should work with as small as a 418 byte (+ 8 byte pad) buffer. All it wants is enough room to guarantee it wont over-read the buffer memory in the process of decoding the frame irrespective of what type of frame (valid or corrupt) is thrown at it.
-john