rbouqueau / gpac

GPAC mirror from the SourceForge Subversion
GNU Lesser General Public License v2.1
0 stars 1 forks source link

[Bug] MP4Box crashes parsing m4v file [sf#332] #332

Open rbouqueau opened 10 years ago

rbouqueau commented 10 years ago

Reported by pbhenson on 2014-09-18 19:16 UTC I have an MP4 video that MP4Box is not happy with:

$ MP4Box -noprog -add test-in.m4v test-out.m4v -new Segmentation fault

mp4info doesn't like it too much either, although it at least doesn't crash:

$ mp4info test-in.m4v mp4info version 2.0.0 test-in.m4v: ReadChildAtoms: "test-in.m4v": In atom edts missing child atom elst ReadChildAtoms: "test-in.m4v": In atom stbl missing child atom stsd ReadChildAtoms: "test-in.m4v": In atom stbl missing child atom stts ReadChildAtoms: "test-in.m4v": In atom stbl missing child atom stsz ReadChildAtoms: "test-in.m4v": In atom stbl missing child atom stsc MP4Track: invalid track (src/mp4track.cpp,235) Track Type Info 2 audio MPEG-4 AAC LC, 225.442 secs, 256 kbps, 44100 Hz 1 video H264 Baseline@3, 225.425 secs, 1485 kbps, 640x320 @ 29.970057 fps ReadChildAtoms: "test-in.m4v": In atom edts missing child atom elst ReadChildAtoms: "test-in.m4v": In atom stbl missing child atom stsd ReadChildAtoms: "test-in.m4v": In atom stbl missing child atom stts ReadChildAtoms: "test-in.m4v": In atom stbl missing child atom stsz ReadChildAtoms: "test-in.m4v": In atom stbl missing child atom stsc MP4Track: invalid track (src/mp4track.cpp,235)

Debugging it:

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7856a3c in gf_isom_check_sample_desc (trak=0x6b6970) at isomedia/box_code_base.c:6210 6210 while ((a = (GF_UnknownBox*)gf_list_enum(trak->Media->information->sampleTable->SampleDescription->other_boxes, &i))) {

(gdb) print trak->Media->information->sampleTable->SampleDescription $3 = (GF_SampleDescriptionBox *) 0x0

It seems the bad tracks result in a NULL which is eventually dereferenced 8-/.

For fun, I tried adding:

    if (!trak->Media->information->sampleTable->SampleDescription)
                    return;

To see if I could make it just skip the bad tracks and process the good ones. Another crash:

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7847ead in edts_Size (s=0x7f8260) at isomedia/box_code_base.c:938 938 if (! gf_list_count(ptr->editList->entryList)) {

(gdb) print ptr->editList $1 = (GF_EditListBox *) 0x0

So I tweaked that to:

    if (!ptr->editList || !gf_list_count(ptr->editList->entryList)) {

Another crash:

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7847e34 in edts_Write (s=0x7f8260, bs=0x85dd90) at isomedia/box_code_base.c:923

Another tweak:

    if (!ptr->editList || !gf_list_count(ptr->editList->entryList)) {

Until finally it doesn't crash, but it doesn't work either:

$ MP4Box -noprog -add test-in.m4v test-out.m4v -new Error importing test-in.m4v: IsoMedia File is truncated

I gave up here for now. I'm using the latest svn as of today:

$ svn info URL: svn://svn.code.sf.net/p/gpac/code/trunk/gpac Repository Root: svn://svn.code.sf.net/p/gpac/code Repository UUID: 63c20433-aa62-49bd-875c-5a186b69a8fb Revision: 5426

mplayer plays this video perfectly:

$ mplayer test-in.m4v MPlayer 1.1-4.7.3 (C) 2000-2012 MPlayer Team MMX2 supported but disabled

Playing test-in.m4v. libavformat version 54.63.104 (external) libavformat file format detected. [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f359f4cb1a0]stream 0, timescale not set [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f359f4cb1a0]max_analyze_duration 5000000 reached at 5015510 microseconds [lavf] stream 0: audio (aac), -aid 0, -alang eng [lavf] stream 1: video (h264), -vid 0 [lavf] stream 3: video (mjpeg), -vid 1 VIDEO: [H264] 640x320 24bpp 29.970 fps 1485.0 kbps (181.3 kbyte/s) Clip info: major_brand: M4V minor_version: 0 compatible_brands: M4V mp42isom

Load subtitles in ./

Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family libavcodec version 54.92.100 (external)

Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264)

Opening audio decoder: [ffmpeg] FFmpeg/libavcodec audio decoders AUDIO: 44100 Hz, 2 ch, floatle, 251.0 kbit/8.89% (ratio: 31380->352800)

Selected audio codec: [ffaac] afm: ffmpeg (FFmpeg AAC (MPEG-2/MPEG-4 Audio))

[AO_ALSA] Format floatle is not supported by hardware, trying default. AO: [alsa] 44100Hz 2ch s16le (2 bytes per sample) Starting playback...

This is a copyrighted video so I can't post it, but I can provide it privately if somebody would like to look at it. While there may or may not be something goofy about it, at the very least MP4Box shouldn't crash. And ideally it could pull the valid tracks out and ignore whatever garbage it doesn't like. There are quite a few videos like this, so I don't think it's a case of corruption, although it might be a case of a commercial vendor not having the spec quite right.

Thanks...

rbouqueau commented 10 years ago

Commented by pbhenson on 2014-09-19 01:26 UTC So I tried repackaging it with ffmpeg:

$ ffmpeg -i test-in.m4v -vcodec copy -acodec copy test-out.m4v [mov,mp4,m4a,3gp,3g2,mj2 @ 0x1b6adc0] stream 0, timescale not set [mov,mp4,m4a,3gp,3g2,mj2 @ 0x1b6adc0] max_analyze_duration 5000000 reached at 5015510 microseconds
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test-in.m4v': Metadata: major_brand : M4V minor_version : 0 compatible_brands: M4V mp42isom Duration: 00:03:45.43, start: 0.000000, bitrate: 1778 kb/s Stream #0:0(eng): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 251 kb/s Metadata: creation_time : 2008-11-13 14:54:12 handler_name : ?Apple Sound Media Handler Stream #0:1(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x320, 1485 kb/s, 29.97 fps, 29.97 tbr, 2997 tbn, 5994 tbc Metadata: creation_time : 2008-11-13 14:54:12 handler_name : ?Apple Video Media Handler Stream #0:2(eng): Data: none Metadata: creation_time : 2008-11-13 14:54:17 handler_name : ?Time Code Media Handler Stream #0:3: Video: mjpeg, yuvj420p, 640x320 [SAR 72:72 DAR 2:1], 90k tbr, 90k tbn, 90k tbc Output #0, ipod, to 'test-out.m4v': Metadata: major_brand : M4V minor_version : 0 compatible_brands: M4V mp42isom Stream #0:0(eng): Video: h264 (avc1 / 0x31637661), yuv420p, 640x320, q=2-31, 1485 kb/s, 29.97 fps, 11988 tbn, 2997 tbc Metadata: creation_time : 2008-11-13 14:54:12 handler_name : ?Apple Video Media Handler Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, 251 kb/s Metadata: creation_time : 2008-11-13 14:54:12 handler_name : ?Apple Sound Media Handler Stream mapping: Stream #0:1 -> #0:0 (copy) Stream #0:0 -> #0:1 (copy)

The resultant file still gave warnings from mp4info, but it no longer says "invalid track":

$ mp4info test-out.m4v mp4info version 2.0.0 test-out.m4v: ReadChildAtoms: "test-out.m4v": In stik atom, extra 1 bytes at end of atom ReadChildAtoms: "test-out.m4v": In atom stik missing child atom data ReadChildAtoms: "test-out.m4v": In pgap atom, extra 1 bytes at end of atom ReadChildAtoms: "test-out.m4v": In atom pgap missing child atom data Track Type Info 1 video H264 Baseline@3, 225.425 secs, 1485 kbps, 640x320 @ 29.970057 fps 2 audio MPEG-4 AAC LC, 225.442 secs, 251 kbps, 44100 Hz ReadChildAtoms: "test-out.m4v": In stik atom, extra 1 bytes at end of atom ReadChildAtoms: "test-out.m4v": In atom stik missing child atom data ReadChildAtoms: "test-out.m4v": In pgap atom, extra 1 bytes at end of atom ReadChildAtoms: "test-out.m4v": In atom pgap missing child atom data

And MP4Box successfully copies out the content (with a few warnings):

$ MP4Box -noprog -add test-out.m4v test-out-2.m4v -new
[iso file] Box "pgap" size 9 invalid (read 12) [iso file] Box "pgap" size 9 invalid (read 12) IsoMedia import - track ID 1 - Video (size 640 x 320) [iso file] Box "pgap" size 9 invalid (read 12) IsoMedia import - track ID 2 - Audio (SR 44100 - 2 channels) Setting up iTunes/iPod file... Saving test-out-2.m4v: 0.500 secs Interleaving

And results in a file mp4info is happy with:

$ mp4info test-out-2.m4v mp4info version 2.0.0 test-out-2.m4v: Track Type Info 1 video H264 Baseline@3, 225.425 secs, 1485 kbps, 640x320 @ 29.970057 fps 2 audio MPEG-4 AAC LC, 225.442 secs, 251 kbps, 44100 Hz

So it looks like at least I have a workaround; ffmpeg cleans it up enough for MP4Box to deal with, and I can get a nice fully clean file in the end... As far as I can tell, the end result plays clean with no corruption or other noticible problems.

rbouqueau commented 10 years ago

Commented by jeanlf on 2014-09-19 06:07 UTC Could you send your file by pm, I'll have a look at it

rbouqueau commented 10 years ago

Commented by jeanlf on 2014-09-22 12:01 UTC This should now be fixed on SVN, could you check it out ?

rbouqueau commented 10 years ago

Commented by pbhenson on 2014-09-22 21:20 UTC Ok, I updated to the latest svn and it works now:

$ MP4Box -add test.m4v test-new.m4v -new [iso file] Track with no sample description box ! [iso file] Track with no sample description box ! IsoMedia import test.m4v - track ID 2 - Audio (SR 44100 - 2 channels) [iso file] Track with no sample description box !
IsoMedia import test.m4v - track ID 1 - Video (size 640 x 320) [iso file] Track with no sample description box !
IsoMedia import test.m4v - track ID 3 - media type "tmcd:...." Setting up iTunes/iPod file... Saving test-new.m4v: 0.500 secs Interleaving

Given the new warning, I guess the problem was a track with no sample description box :)?

Thanks much for the quick response and turn around on a fix.