diff options
author | Matthew Hoops | 2011-01-05 18:06:46 +0000 |
---|---|---|
committer | Matthew Hoops | 2011-01-05 18:06:46 +0000 |
commit | 4e05e450c381b6deb9999ec4122c4d9028d510e2 (patch) | |
tree | fe89b74f28d0be1f469ee7e788f04d60782b9904 /graphics | |
parent | 0a8189fd41e3995ba866967b57ea1a0c25b8e94d (diff) | |
download | scummvm-rg350-4e05e450c381b6deb9999ec4122c4d9028d510e2.tar.gz scummvm-rg350-4e05e450c381b6deb9999ec4122c4d9028d510e2.tar.bz2 scummvm-rg350-4e05e450c381b6deb9999ec4122c4d9028d510e2.zip |
VIDEO: Mirror QuickTime's mishandling of its own mdat atoms
While the specs say that the 'mdat' ("media data") atom is required in all QuickTime files, QuickTime makes no check if the atom is actually present. This allows for some videos with typos in the atom tag in them to play in QuickTime anyway. The offsets in the 'stco' atom are only used instead.
This will fix a video in DS2 Mac and a music file in IHNM Mac (although this is not needed for either just yet).
svn-id: r55125
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/video/qt_decoder.cpp | 52 | ||||
-rw-r--r-- | graphics/video/qt_decoder.h | 4 |
2 files changed, 14 insertions, 42 deletions
diff --git a/graphics/video/qt_decoder.cpp b/graphics/video/qt_decoder.cpp index 40ae8f6667..553f23d396 100644 --- a/graphics/video/qt_decoder.cpp +++ b/graphics/video/qt_decoder.cpp @@ -308,7 +308,7 @@ bool QuickTimeDecoder::loadFile(const Common::String &filename) { if (!_resFork->open(filename) || !_resFork->hasDataFork()) return false; - _foundMOOV = _foundMDAT = false; + _foundMOOV = false; _numStreams = 0; _partial = 0; _videoStreamIndex = _audioStreamIndex = -1; @@ -337,7 +337,7 @@ bool QuickTimeDecoder::loadFile(const Common::String &filename) { _fd = _resFork->getDataFork(); - if (readDefault(atom) < 0 || !_foundMOOV || !_foundMDAT) + if (readDefault(atom) < 0 || !_foundMOOV) return false; init(); @@ -346,7 +346,7 @@ bool QuickTimeDecoder::loadFile(const Common::String &filename) { bool QuickTimeDecoder::load(Common::SeekableReadStream *stream) { _fd = stream; - _foundMOOV = _foundMDAT = false; + _foundMOOV = false; _numStreams = 0; _partial = 0; _videoStreamIndex = _audioStreamIndex = -1; @@ -354,7 +354,7 @@ bool QuickTimeDecoder::load(Common::SeekableReadStream *stream) { MOVatom atom = { 0, 0, 0xffffffff }; - if (readDefault(atom) < 0 || !_foundMOOV || !_foundMDAT) { + if (readDefault(atom) < 0 || !_foundMOOV) { _fd = 0; return false; } @@ -364,12 +364,9 @@ bool QuickTimeDecoder::load(Common::SeekableReadStream *stream) { } void QuickTimeDecoder::init() { - // some cleanup : make sure we are on the mdat atom - if ((uint32)_fd->pos() != _mdatOffset) - _fd->seek(_mdatOffset, SEEK_SET); - + // Remove non-Video/Audio streams for (uint32 i = 0; i < _numStreams;) { - if (_streams[i]->codec_type == CODEC_TYPE_MOV_OTHER) {// not audio, not video, delete + if (_streams[i]->codec_type == CODEC_TYPE_MOV_OTHER) { delete _streams[i]; for (uint32 j = i + 1; j < _numStreams; j++) _streams[j - 1] = _streams[j]; @@ -378,6 +375,7 @@ void QuickTimeDecoder::init() { i++; } + // Adjust time/duration for (uint32 i = 0; i < _numStreams; i++) { MOVStreamContext *sc = _streams[i]; @@ -395,6 +393,7 @@ void QuickTimeDecoder::init() { _audioStreamIndex = i; } + // Initialize audio, if present if (_audioStreamIndex >= 0) { STSDEntry *entry = &_streams[_audioStreamIndex]->stsdEntries[0]; @@ -410,6 +409,7 @@ void QuickTimeDecoder::init() { } } + // Initialize video, if present if (_videoStreamIndex >= 0) { for (uint32 i = 0; i < _streams[_videoStreamIndex]->stsdEntryCount; i++) { STSDEntry *entry = &_streams[_videoStreamIndex]->stsdEntries[i]; @@ -431,7 +431,7 @@ void QuickTimeDecoder::initParseTable() { { &QuickTimeDecoder::readDefault, MKID_BE('edts') }, { &QuickTimeDecoder::readELST, MKID_BE('elst') }, { &QuickTimeDecoder::readHDLR, MKID_BE('hdlr') }, - { &QuickTimeDecoder::readMDAT, MKID_BE('mdat') }, + { &QuickTimeDecoder::readDefault, MKID_BE('mdat') }, { &QuickTimeDecoder::readMDHD, MKID_BE('mdhd') }, { &QuickTimeDecoder::readDefault, MKID_BE('mdia') }, { &QuickTimeDecoder::readDefault, MKID_BE('minf') }, @@ -538,14 +538,9 @@ int QuickTimeDecoder::readMOOV(MOVatom atom) { if (readDefault(atom) < 0) return -1; - // we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' - // so we don't parse the whole file if over a network + // We parsed the 'moov' atom, so we don't need anything else _foundMOOV = true; - - if(_foundMDAT) - return 1; // found both, just go - - return 0; // now go for mdat + return 1; } int QuickTimeDecoder::readCMOV(MOVatom atom) { @@ -664,24 +659,6 @@ int QuickTimeDecoder::readTRAK(MOVatom atom) { return readDefault(atom); } -// this atom contains actual media data -int QuickTimeDecoder::readMDAT(MOVatom atom) { - if (atom.size == 0) // wrong one (MP4) - return 0; - - _foundMDAT = true; - - _mdatOffset = atom.offset; - _mdatSize = atom.size; - - if (_foundMOOV) - return 1; // found both, just go - - _fd->seek(atom.size, SEEK_CUR); - - return 0; // now go for moov -} - int QuickTimeDecoder::readTKHD(MOVatom atom) { MOVStreamContext *st = _streams[_numStreams - 1]; byte version = _fd->readByte(); @@ -1068,8 +1045,7 @@ int QuickTimeDecoder::readSTSZ(MOVatom atom) { } static uint32 ff_gcd(uint32 a, uint32 b) { - if(b) return ff_gcd(b, a%b); - else return a; + return b ? ff_gcd(b, a % b) : a; } int QuickTimeDecoder::readSTTS(MOVatom atom) { @@ -1134,7 +1110,7 @@ int QuickTimeDecoder::readSTCO(MOVatom atom) { for (uint32 i = 0; i < _numStreams; i++) { MOVStreamContext *sc2 = _streams[i]; - if(sc2 && sc2->chunk_offsets){ + if (sc2 && sc2->chunk_offsets) { uint32 first = sc2->chunk_offsets[0]; uint32 last = sc2->chunk_offsets[sc2->chunk_count - 1]; diff --git a/graphics/video/qt_decoder.h b/graphics/video/qt_decoder.h index 144340d6a7..8492d25d73 100644 --- a/graphics/video/qt_decoder.h +++ b/graphics/video/qt_decoder.h @@ -213,11 +213,8 @@ private: const ParseTable *_parseTable; bool _foundMOOV; - bool _foundMDAT; uint32 _timeScale; uint32 _duration; - uint32 _mdatOffset; - uint32 _mdatSize; MOVStreamContext *_partial; uint32 _numStreams; int _ni; @@ -261,7 +258,6 @@ private: int readLeaf(MOVatom atom); int readELST(MOVatom atom); int readHDLR(MOVatom atom); - int readMDAT(MOVatom atom); int readMDHD(MOVatom atom); int readMOOV(MOVatom atom); int readMVHD(MOVatom atom); |