While the Apple spec says that a zero length top level atoms indicates that it takes up the rest of the file, all players (including iTunes) correctly play a file that has an atom with 0 length and a type of all 0's. However Mp4V2 will corrupt a file like this when tagging.
I've done quite a bit of debugging and have found that if you take the 8 bytes of 0's and turn then into a free atom with datasize of 0, then MP4V2 will tag it correctly. But when I try to "force" this in ReadAtom by checking in the if dataSize == 0 leg for a type of all 0's as well, and then setting the dataSize to 0 and the type to free, it still trashes the file (I've debugged through this function both with the patched file and without, and it appears to me to be doing the same thing, but something upstream from the call, or downstream from the write, must still be confused).
I've uploaded the file to
http://www.danhinsley.com/downloads/MP4V2 Test Data/test1.mp4. The structure of the file before the write is:
i.
Moov atom @x20 for 0x227d57
ii.
Free atom at 0x227d77 for 0xb4969
iii.
2 words of 0’s at 0x2dc630
iv.
Mdat atom at 0x2dc6e8 for 1b3b3f25 (goes to end
of file)
and after
i.
Free atom at 0x20 for 0x227d57
ii.
Free atom at 0x227d77 for b4969
iii.
2 words of 0’s at 0x2dc6e0
iv.
Mdat atom at 0x2dc6e8 for 1b3b3f25
v.
Mdat atom at 0x1b69060d for 0x1f
vi.
Moov atom at 0x1b69062c for 0x228003 (goes to
end of file)What I tried to do is replace the if (dataSize == 0) with:
if (dataSize == 0) {
// extends to EOF
if ((int32_t) *type == 0) {
// even though it doesn't match the spec, some files have two 32 bit words of
// 0's as a top level atom. These should just be turned into a zero size free atom and skipped
dataSize = 8; // so it will turn into 0 after hdrsize subtracted
type[0] = 'f';
type[1] = 'r';
type[2] = 'e';
type[3] = 'e';
} else {
dataSize = file.GetSize() - pos;
}
}
Now when I debug through with the patched and unpatched file, it looks to me that they have the same behavior. I'm thinking there must be something in the write leg, but I can't see where to go from here.
If anyone can give me any tips, I'll be glad to try to finish debugging this and provide a patch.
Thanks,
Dan