stephenyin / mp4v2

Automatically exported from code.google.com/p/mp4v2
Other
0 stars 0 forks source link

MP4Read fails in ReadAtom attempting to allocate memory (450MB) #136

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Issue MP4Read on file badread.mp4 (download from 
http://www.danhinsley.com/downloads/badread.mp4)

What is the expected output? What do you see instead?
Expect it to open the file, but it fails when executing

pAtom->AddProperty(new MP4BytesProperty(*pAtom, "data", dataSize)); 

in ReadChildAtoms->ReadAtom.

The problem is the atom has a type of "" and a datasize of 0, so MP4V2 assumes 
it goes to the end of the file, which is another 450MB, so when it tries to 
allocate that much memory it fails.

Media Players (iTunes, QT Player) will play the file OK, so while I'm sure 
there's something non-standard in the file, if QT can play it, MP4V2 should be 
able to read it.

I can debug into this if that helps.  I can also build the dll to try out 
possible fixes.

Original issue reported on code.google.com by danahins...@gmail.com on 1 Aug 2012 at 8:32

GoogleCodeExporter commented 9 years ago
Perhaps a similar problem.  I've uploaded a file to the same place called 
badwrite.mp4.  This one has two atoms at the end of the file with a length of 
0x1941a469, when there are really only 138 bytes left in the file.  They also 
have non-standard name a<weird character>F starting at offset 0xFEEEE87.  So 
this file reads OK, but when you write it, it puts this extra space as junk at 
the end of the file and makes it unplayable.

If I patch the file so that the length of the bogus atom is 138, then I can 
read and tag it OK.  But if I trace into MP4V2 and change dataSize to 138 after 
the read in MP4Atom::ReadAtom, it still screws up the file.  So somewhere in 
the write path it's still finding this value.  Note that media players can play 
the untagged file OK, and even AtomicParsley and read it OK.

So in both these cases, media players can recover from a bad atom, but MP4V2 
either dies in reading (bad) or makes the file unplayable after tagging (worse).

I'm more than willing to try and pursue this, if someone could provide a little 
help.

Dan

Original comment by MetaXMov...@gmail.com on 16 Aug 2012 at 12:35

GoogleCodeExporter commented 9 years ago
The above comment was from me, I was logged into a different account that I 
have by mistake.

Dan

Original comment by danahins...@gmail.com on 16 Aug 2012 at 12:36

GoogleCodeExporter commented 9 years ago
Any one have a chance to look at this, or even point me in the right direction 
on debugging it myself?

Original comment by danahins...@gmail.com on 19 Aug 2012 at 10:25

GoogleCodeExporter commented 9 years ago
dl'ing file now, i'll see if I can reproduce.

Original comment by kid...@gmail.com on 1 Oct 2012 at 2:32

GoogleCodeExporter commented 9 years ago
Sorry, been stupid busy and neglecting this project.  My bad

I attempted to repo with that file and had no luck with trunk--could you give 
me a command line that reproduces using the command line tools?  Admittedly I 
was on OSX, so possibly that's a factor, but mp4info gives me:

Jeremys-Mac-mini:mp4v2 kidjan$ ./mp4info /Users/kidjan/Downloads/badread.mp4 
/Users/kidjan/SourceControl/svn/mp4v2/.libs/mp4info version trunk-r497
/Users/kidjan/Downloads/badread.mp4:
ReadAtom: "/Users/kidjan/Downloads/badread.mp4": atom type  is suspect
Track   Type    Info
1   video   H264 High@3.1, 3257.674 secs, 998 kbps, 720x402 @ 23.976003 fps
2   audio   MPEG-4 AAC LC, 3257.621 secs, 124 kbps, 48000 Hz
ReadAtom: "/Users/kidjan/Downloads/badread.mp4": atom type  is suspect
 Encoded with: muxer

...and mp4trackdump works fine with either audio/video track. 

Original comment by kid...@gmail.com on 18 Nov 2012 at 7:13

GoogleCodeExporter commented 9 years ago
I'm seriously confused.  I sync'ed, rebuilt and then ran mp4file -dump and it 
works fine.  Then I tried from my program again (MetaX for Windows) and the 
following code:

            filePtr = MP4Read(SafeUTF8GetBytes(s))
            If filePtr = IntPtr.Zero Then
                LogError(s & " could not be opened.")
                Return Nothing
            End If

gets a 0 back from MP4Read.  Looking at the code for mp4file, it seems to call 
MP4Read in a similar fashion.  For completeness, the function SafeUTF8GetBytes 
is:

    Friend Function SafeUTF8GetBytes(ByVal s As String) As Byte()
        If s Is Nothing Then
            Return Nothing
        Else
            Return System.Text.Encoding.UTF8.GetBytes(s)
        End If
    End Function

This code works fine with other files, so it doesn't seem like it could be the 
way I'm passing in the filename.

It fails in mp4util.cpp in function MP4Malloc with a value of over 450MB with a 
stack trace of:

>   libmp4v2.dll!mp4v2::impl::MP4Malloc(unsigned int size)  Line 58 C++
    libmp4v2.dll!mp4v2::impl::MP4Calloc(unsigned int size)  Line 65 + 0xf bytes C++
    libmp4v2.dll!mp4v2::impl::MP4BytesProperty::MP4BytesProperty(mp4v2::impl::MP4Atom & parentAtom, const char * name, unsigned int valueSize, unsigned int defaultValueSize)  Line 495 + 0x9 bytes C++
    libmp4v2.dll!mp4v2::impl::MP4Atom::ReadAtom(mp4v2::impl::MP4File & file, mp4v2::impl::MP4Atom * pParentAtom)  Line 188 + 0x31 bytes C++
    libmp4v2.dll!mp4v2::impl::MP4Atom::ReadChildAtoms()  Line 429 + 0x10 bytes  C++
    libmp4v2.dll!mp4v2::impl::MP4Atom::Read()  Line 238 C++
    libmp4v2.dll!mp4v2::impl::MP4File::ReadFromFile()  Line 429 + 0x15 bytes    C++
    libmp4v2.dll!mp4v2::impl::MP4File::Read(const char * name, const MP4FileProvider_s * provider)  Line 97 C++
    libmp4v2.dll!MP4Read(const char * fileName)  Line 103   C++

I'm pretty befuddled by this.  I'm going to work on this some more, but thought 
I'd go ahead and post this first.

Dan

Original comment by danahins...@gmail.com on 18 Nov 2012 at 10:28

GoogleCodeExporter commented 9 years ago
OK, I've done some more research and there are at least a couple of things 
going on here.  The first is (probably) not anything mp4v2 can fix.  I can call 
MP4Read on the file in question and read it, as long as I don't call the 
openfiledialog from .Net first.  I ran into a similar problem a while back (I 
think openfiledialog is bringing in a C Runtime that has a memory management 
issue under some circumstances).  So I'll mark this down as a Windows weirdness.

But when I try to add the artist tag with mp4tags, then read it with mp4file, 
it fails.  Also after writing the tag, the file won't play either.

So maybe you can see what's going on using this scenario?

Dan

Original comment by danahins...@gmail.com on 19 Nov 2012 at 9:20

GoogleCodeExporter commented 9 years ago
I've collected several files that get corrupted when tagged with:

mp4tags -a "artist"

They're in http://www.danhinsley.com/downloads/MP4V2 Test Data.

For each file there's the untagged, uncorrupted file, a corresponding .dmp that 
is the output of

mp4file --dump

And there's a file error.txt which shows the output of the mp4tags command.

So clearly there are some internal flaws with these (one clear offender is the 
Hauppauge video capture app, which created a couple of them), however, you can 
use Freemake to "convert" the file (mp4 to mp4) and then they can be tagged 
correctly.

So whatever is wrong with the files, media players and Freemake handle, but 
MP4V2 doesn't.

Anything I can do to help figure this out, I'd be glad to do.

Dan

Original comment by danahins...@gmail.com on 22 Nov 2012 at 10:18

GoogleCodeExporter commented 9 years ago
Thought I'd check in and see if anyone had a chance to look at this.

Original comment by danahins...@gmail.com on 19 Dec 2012 at 5:17