Today, a good friend reported something like a bug in MPlayer’s LAME encoder filter. He said that mpgtx, a MPEG audio/video cut and merge program, pretended that the resulting MP3 files are invalid. Some quick investigation revealed that the files indeed started with a chunk of zero bytes, not with a correct MP3 frame. This doesn’t happen with files produced by the standard command-line LAME frontend, so the problem had to be on my side. After digging through the API documentation, the friend who reported the bug found the following:
void lame_mp3_tags_fid(lame_global_flags *,FILE* fid);
This adds a valid mp3 frame which contains information about the bitstream some players may find usefull. It is used for CBR,ABR and VBR. The routine will attempt to rewind the output stream to the beginning. […] If the rewind fails and the tag was not disabled, the first mp3 frame in the bitstream will be all 0’s.
OK, so maybe I just missed this point in the documentation, I thought. I checked against the
lame.h file, but what I found the is almost contradictory to the statement above:
lame_mp3_tags_fidwill append a Xing VBR tag to the mp3 file with file pointer
fid. These calls perform forward and backwards seeks, so make sure
fidis a real file. Make sure
lame_encode_flushhas been called, and all mp3 data has been written to the file before calling this function.
Now it was clear to me why I didn’t use the function — I don’t care a shit about this new-age MP3 pseudo-tag stuff, so I just left out the tag-specific stuff. Adding a
lame_mp3_tags_fid call after finishing processing expectedly fixed the zero-bytes problem: The files started with
ff a0 90 ... which looks — to the experienced eye — like a MPEG Audio sync marker.
But the trouble with mpgtx didn’t stop until we used
lame_set_bWriteVbrTag(this->lame, 0) in the encoder setup code to disable all that superfluous tagging stuff, at least for the CBR case. VBR wasn’t working, though — until we set bWriteVbrTag=0 for VBR as well. This produces files that can be processed with mpgtx, but the time display is totally broken. But this seems to be the best solution for now …
Side note: The LAME developers seem to be uncomfortable with the VBR tag mechanism, too. This is the only explanation I have for the inconsistent documentation, accompanied by the following funny comment regarding the
this variable must have been added by a Hungarian notation Windows programmer
Update (2006-02-15): We finally found the reason why the tagging process was flawed: LAME tries to re-read parts of the file when writing its tags, so the file mode
wb+ instead of just
wb is required in
fopen(). Sigh. Now everything works fine, and we’re really thinking about submitting the patch to the MPlayer dev team.