drewnoakes / metadata-extractor-dotnet

Extracts Exif, IPTC, XMP, ICC and other metadata from image, video and audio files
Other
941 stars 167 forks source link

TimeSpan overflow in QuickTimeMetadataReader (with bad MP4 file) #269

Open kirk-marple opened 4 years ago

kirk-marple commented 4 years ago

Ran across this recently, and just wanted to post this for awareness.

In ReadMetadata, if the timeScale comes back as zero (because of bad header data), this can cause a divide by zero error, and overflow creating the TimeSpan.FromSeconds.

I have a file from 2017, taken on a Samsung Android phone. I'm guessing they had a bug in their MP4 writer back then.

The created and modified dates that are parsed are bogus (like 1908 for created date).

Line 249: directory.Set(QuickTimeMovieHeaderDirectory.TagCreated, _epoch.AddTicks(TimeSpan.TicksPerSecond a.Reader.GetUInt32())); directory.Set(QuickTimeMovieHeaderDirectory.TagModified, _epoch.AddTicks(TimeSpan.TicksPerSecond a.Reader.GetUInt32())); var timeScale = a.Reader.GetUInt32(); directory.Set(QuickTimeMovieHeaderDirectory.TagTimeScale, timeScale); directory.Set(QuickTimeMovieHeaderDirectory.TagDuration, TimeSpan.FromSeconds(a.Reader.GetUInt32() / (double)timeScale));

image

Here's the MediaInfo output from it:

General Complete name : C:\Users\kirk\Pictures\Austin\20161126_132809.mp4 Format : MPEG-4 Format profile : Base Media / Version 2 Codec ID : mp42 (isom/mp42) File size : 9.13 MiB Duration : 9 s 380 ms Overall bit rate mode : Variable Overall bit rate : 8 166 kb/s Tagged date : UTC 2016-11-27 01:07:53 xyz : +30.2627-097.9380/

Video ID : 1 Format : AVC Format/Info : Advanced Video Codec Format profile : High@L4 Format settings : CABAC / 1 Ref Frames Format settings, CABAC : Yes Format settings, Reference frames : 1 frame Format settings, GOP : M=1, N=60 Codec ID : avc1 Codec ID/Info : Advanced Video Coding Duration : 9 s 333 ms Bit rate : 8 010 kb/s Maximum bit rate : 9 410 kb/s Width : 1 080 pixels Height : 1 920 pixels Display aspect ratio : 0.563 Frame rate mode : Constant Frame rate : 30.000 FPS Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Scan type : Progressive Bits/(Pixel*Frame) : 0.129 Stream size : 8.91 MiB (98%) Tagged date : UTC 2016-11-27 01:07:54 Color range : Limited Color primaries : BT.709 Transfer characteristics : BT.709 Matrix coefficients : BT.709 Codec configuration box : avcC

Audio ID : 2 Format : AAC LC Format/Info : Advanced Audio Codec Low Complexity Codec ID : mp4a-40-2 Duration : 9 s 380 ms Bit rate mode : Variable Bit rate : 192 kb/s Maximum bit rate : 203 kb/s Channel(s) : 2 channels Channel layout : L R Sampling rate : 44.1 kHz Frame rate : 43.066 FPS (1024 SPF) Compression mode : Lossy Stream size : 220 KiB (2%) Title : IsoMedia File Produced by Google, 5-11-2011 Language : English Encoded date : UTC 2016-11-27 01:07:53 Tagged date : UTC 2016-11-27 01:07:54

drewnoakes commented 4 years ago

Hey Kirk. Are you able to provide that sample file?

drewnoakes commented 4 years ago

I believe that PR fixes it, but cannot verify that the resulting duration value makes any sense. It'd be great to have a test file.

kirk-marple commented 4 years ago

@drewnoakes Here you go. Enjoy the tortoises :)

20161126_132809.zip

drewnoakes commented 4 years ago

270 fixed the exception, but the resulting value is garbage:

[QuickTime Movie Header - 0x0006] Duration = 41239.01:07:53

Java produces more sensible values here. We should compare the behaviour of both to understand the difference.