diff options
author | Kamil Zbróg | 2013-11-26 18:53:03 +0000 |
---|---|---|
committer | Kamil Zbróg | 2013-11-26 18:53:03 +0000 |
commit | 15bb1c61eda48f09253ccb8d2a42ccad59f3b00a (patch) | |
tree | c2f5ac2907225730c6f1cdaa000f549ef7951183 /video | |
parent | 446c57d281e592653c9935c896d33334d23f0519 (diff) | |
parent | e1afc7d0d777dad4b7ca0a58f0bb0324b24f9584 (diff) | |
download | scummvm-rg350-15bb1c61eda48f09253ccb8d2a42ccad59f3b00a.tar.gz scummvm-rg350-15bb1c61eda48f09253ccb8d2a42ccad59f3b00a.tar.bz2 scummvm-rg350-15bb1c61eda48f09253ccb8d2a42ccad59f3b00a.zip |
Merge remote-tracking branch 'sync/master' into prince-malik
Conflicts:
engines/configure.engines
engines/engines.mk
engines/plugins_table.h
Diffstat (limited to 'video')
-rw-r--r-- | video/avi_decoder.cpp | 84 | ||||
-rw-r--r-- | video/avi_decoder.h | 8 | ||||
-rw-r--r-- | video/codecs/mpeg.h | 2 |
3 files changed, 80 insertions, 14 deletions
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index aee2d88988..36fe83fa19 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -69,6 +69,7 @@ namespace Video { #define ID_ISFT MKTAG('I','S','F','T') #define ID_DISP MKTAG('D','I','S','P') #define ID_PRMI MKTAG('P','R','M','I') +#define ID_STRN MKTAG('s','t','r','n') // Codec tags #define ID_RLE MKTAG('R','L','E',' ') @@ -109,6 +110,7 @@ void AVIDecoder::initCommon() { _decodedHeader = false; _foundMovieList = false; _movieListStart = 0; + _movieListEnd = 0; _fileStream = 0; memset(&_header, 0, sizeof(_header)); } @@ -155,19 +157,11 @@ bool AVIDecoder::parseNextChunk() { case ID_JUNK: // Alignment bytes, should be ignored case ID_ISFT: // Metadata, safe to ignore case ID_DISP: // Metadata, should be safe to ignore + case ID_STRN: // Metadata, safe to ignore skipChunk(size); break; case ID_IDX1: - debug(0, "%d Indices", size / 16); - for (uint32 i = 0; i < size / 16; i++) { - OldIndex indexEntry; - indexEntry.id = _fileStream->readUint32BE(); - indexEntry.flags = _fileStream->readUint32LE(); - indexEntry.offset = _fileStream->readUint32LE() + _movieListStart - 4; // Adjust to absolute - indexEntry.size = _fileStream->readUint32LE(); - _indexEntries.push_back(indexEntry); - debug(0, "Index %d == Tag \'%s\', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags); - } + readOldIndex(size); break; default: error("Unknown tag \'%s\' found", tag2str(tag)); @@ -193,6 +187,7 @@ void AVIDecoder::handleList(uint32 listSize) { // We found the movie block _foundMovieList = true; _movieListStart = curPos; + _movieListEnd = _movieListStart + listSize + (listSize & 1); _fileStream->skip(listSize); return; case ID_HDRL: // Header List @@ -353,17 +348,27 @@ void AVIDecoder::close() { _decodedHeader = false; _foundMovieList = false; _movieListStart = 0; + _movieListEnd = 0; _indexEntries.clear(); memset(&_header, 0, sizeof(_header)); } void AVIDecoder::readNextPacket() { + if ((uint32)_fileStream->pos() >= _movieListEnd) { + // Ugh, reached the end premature. + forceVideoEnd(); + return; + } + uint32 nextTag = _fileStream->readUint32BE(); uint32 size = _fileStream->readUint32LE(); - if (_fileStream->eos()) + if (_fileStream->eos()) { + // Also premature end. + forceVideoEnd(); return; + } if (nextTag == ID_LIST) { // A list of audio/video chunks @@ -621,6 +626,59 @@ byte AVIDecoder::getStreamIndex(uint32 tag) const { return strtol(string, 0, 16); } +void AVIDecoder::readOldIndex(uint32 size) { + uint32 entryCount = size / 16; + + debug(0, "Old Index: %d entries", entryCount); + + if (entryCount == 0) + return; + + // Read the first index separately + OldIndex firstEntry; + firstEntry.id = _fileStream->readUint32BE(); + firstEntry.flags = _fileStream->readUint32LE(); + firstEntry.offset = _fileStream->readUint32LE(); + firstEntry.size = _fileStream->readUint32LE(); + + // Check if the offset is already absolute + // If it's absolute, the offset will equal the start of the movie list + bool isAbsolute = firstEntry.offset == _movieListStart; + + debug(1, "Old index is %s", isAbsolute ? "absolute" : "relative"); + + if (!isAbsolute) + firstEntry.offset += _movieListStart - 4; + + debug(0, "Index 0: Tag '%s', Offset = %d, Size = %d (Flags = %d)", tag2str(firstEntry.id), firstEntry.offset, firstEntry.size, firstEntry.flags); + _indexEntries.push_back(firstEntry); + + for (uint32 i = 1; i < entryCount; i++) { + OldIndex indexEntry; + indexEntry.id = _fileStream->readUint32BE(); + indexEntry.flags = _fileStream->readUint32LE(); + indexEntry.offset = _fileStream->readUint32LE(); + indexEntry.size = _fileStream->readUint32LE(); + + // Adjust to absolute, if necessary + if (!isAbsolute) + indexEntry.offset += _movieListStart - 4; + + _indexEntries.push_back(indexEntry); + debug(0, "Index %d: Tag '%s', Offset = %d, Size = %d (Flags = %d)", i, tag2str(indexEntry.id), indexEntry.offset, indexEntry.size, indexEntry.flags); + } +} + +void AVIDecoder::forceVideoEnd() { + // Horrible AVI video has a premature end + // Force the frame to be the last frame + debug(0, "Forcing end of AVI video"); + + for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++) + if ((*it)->getTrackType() == Track::kTrackTypeVideo) + ((AVIVideoTrack *)*it)->forceTrackEnd(); +} + AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette) : _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader), _initialPalette(initialPalette) { _videoCodec = createCodec(); @@ -723,6 +781,10 @@ Codec *AVIDecoder::AVIVideoTrack::createCodec() { return 0; } +void AVIDecoder::AVIVideoTrack::forceTrackEnd() { + _curFrame = _frameCount - 1; +} + AVIDecoder::AVIAudioTrack::AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType) : _audsHeader(streamHeader), _wvInfo(waveFormat), _soundType(soundType) { _audStream = createAudioStream(); diff --git a/video/avi_decoder.h b/video/avi_decoder.h index 3bf443a95b..882cce30de 100644 --- a/video/avi_decoder.h +++ b/video/avi_decoder.h @@ -166,6 +166,7 @@ protected: ~AVIVideoTrack(); void decodeFrame(Common::SeekableReadStream *stream); + void forceTrackEnd(); uint16 getWidth() const { return _bmInfo.width; } uint16 getHeight() const { return _bmInfo.height; } @@ -230,13 +231,15 @@ protected: Audio::QueuingAudioStream *createAudioStream(); }; - Common::Array<OldIndex> _indexEntries; AVIHeader _header; + void readOldIndex(uint32 size); + Common::Array<OldIndex> _indexEntries; + Common::SeekableReadStream *_fileStream; bool _decodedHeader; bool _foundMovieList; - uint32 _movieListStart; + uint32 _movieListStart, _movieListEnd; Audio::Mixer::SoundType _soundType; Common::Rational _frameRateOverride; @@ -248,6 +251,7 @@ protected: void handleStreamHeader(uint32 size); uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; } byte getStreamIndex(uint32 tag) const; + void forceVideoEnd(); public: virtual AVIAudioTrack *createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo); diff --git a/video/codecs/mpeg.h b/video/codecs/mpeg.h index 0082844537..3560f4b8b7 100644 --- a/video/codecs/mpeg.h +++ b/video/codecs/mpeg.h @@ -37,7 +37,7 @@ typedef signed short int16_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) || defined (__SYMBIAN32__) typedef signed char int8_t; typedef signed short int16_t; typedef unsigned char uint8_t; |