Fixing MP4/M4A File Stucture [closed]
Question
I'm having an issue with tagging MP4/M4A files. The tagging operation goes A-OK. Well, I had an issue with the stco atom, but I fixed that. But now, when I play the MP4 file, mplayer gives me an error:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x29db0a0] wrong sample count
However, the file does play.
Does anybody know what I'm missing? Here's what I do in order to add my tag atoms to the MP4 file. I have a feeling I'm not updating a certain atom just like the stco atom needed to be updated with the new absolute file position references.
- Read in up to the 'moov' atom
- Update 'moov's size to include the size of my tags (which are non-existent prior to the operation)
- Write out all data (including updated 'moov' size) to the new file
- Read in up to the 'stco' atom and the 4 bytes following (version and flag info that doesn't need to be changed).
- Write out 'stco' header to the new file
- Read in, process, and read out each 4-byte absolute file location to move them up by the size of the udta atom I'm going to be adding. Write each updated 4-byte location to the new file.
- Write out the 'udta' atom (which directly follow 'stco') the new file.
- Copy the remainder of the input file (the 'mdat' atom) to the new file.
Here's an AtomicParsley dump of the file structure:
Atom ftyp @ 0 of size: 36, ends @ 36
Atom moov @ 36 of size: 61886, ends @ 61922
Atom mvhd @ 44 of size: 108, ends @ 152
Atom iods @ 152 of size: 33, ends @ 185
Atom trak @ 185 of size: 32935, ends @ 33120
Atom tkhd @ 193 of size: 92, ends @ 285
Atom mdia @ 285 of size: 32835, ends @ 33120
Atom mdhd @ 293 of size: 32, ends @ 325
Atom hdlr @ 325 of size: 37, ends @ 362
Atom minf @ 362 of size: 32758, ends @ 33120
Atom smhd @ 370 of size: 16, ends @ 386
Atom dinf @ 386 of size: 36, ends @ 422
Atom dref @ 394 of size: 28, ends @ 422
Atom stbl @ 422 of size: 32698, ends @ 33120
Atom stts @ 430 of size: 24, ends @ 454
Atom stsd @ 454 of size: 106, ends @ 560
Atom mp4a @ 470 of size: 90, ends @ 560
Atom esds @ 506 of size: 54, ends @ 560
Atom stsz @ 560 of size: 29548, ends @ 30108
Atom stsc @ 30108 of size: 40, ends @ 30148
Atom stco @ 30148 of size: 2972, ends @ 33120
Atom udta @ 33120 of size: 28802, ends @ 61922
Atom meta @ 33128 of size: 28794, ends @ 61922
Atom hdlr @ 33140 of size: 34, ends @ 33174
Atom ilst @ 33174 of size: 28748, ends @ 61922
Atom ©ART @ 33182 of size: 33, ends @ 33215
Atom data @ 33190 of size: 25, ends @ 33215
Atom ©nam @ 33215 of size: 77, ends @ 33292
Atom data @ 33223 of size: 69, ends @ 33292
Atom ©alb @ 33292 of size: 34, ends @ 33326
Atom data @ 33300 of size: 26, ends @ 33326
Atom covr @ 33326 of size: 28596, ends @ 61922
Atom data @ 33334 of size: 28588, ends @ 61922
Atom mdat @ 61922 of size: 2742564, ends @ 2804486
Solution
Dang, another stupid question I guess. I was yet another ID-ten-T programming error. When I processed the 'stco' atom I only read in 12 bytes (size, atom name, version, flags) and forgot to read in the 'total entries' 4-byte section. So, what happened was I ended up adding the size of the 'udta' atom to the 'total entries' block, which caused the FFmpeg error. I was able to figure this out by looking at the FFmpeg source and the double-checking the structure of 'stco'.