aboutsummaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
authorMatthew Hoops2013-11-25 20:32:53 -0500
committerMatthew Hoops2013-11-25 20:32:53 -0500
commit6fb6ffd77ba93cc46a2674b8ee94ab3f7d9966fa (patch)
treefa2b39b5db3ad8d8d729983dade581e21f53da5b /video
parentfa350f9c1f9acd2e36fedceb7520b2723d3ff604 (diff)
downloadscummvm-rg350-6fb6ffd77ba93cc46a2674b8ee94ab3f7d9966fa.tar.gz
scummvm-rg350-6fb6ffd77ba93cc46a2674b8ee94ab3f7d9966fa.tar.bz2
scummvm-rg350-6fb6ffd77ba93cc46a2674b8ee94ab3f7d9966fa.zip
VIDEO: Handle prematurely ending AVI videos
Diffstat (limited to 'video')
-rw-r--r--video/avi_decoder.cpp28
-rw-r--r--video/avi_decoder.h4
2 files changed, 30 insertions, 2 deletions
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index 41102f019d..db8538e5a2 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -110,6 +110,7 @@ void AVIDecoder::initCommon() {
_decodedHeader = false;
_foundMovieList = false;
_movieListStart = 0;
+ _movieListEnd = 0;
_fileStream = 0;
memset(&_header, 0, sizeof(_header));
}
@@ -186,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
@@ -346,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
@@ -656,6 +668,16 @@ void AVIDecoder::readOldIndex(uint32 size) {
}
}
+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();
@@ -758,6 +780,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 9f28196177..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; }
@@ -238,7 +239,7 @@ protected:
Common::SeekableReadStream *_fileStream;
bool _decodedHeader;
bool _foundMovieList;
- uint32 _movieListStart;
+ uint32 _movieListStart, _movieListEnd;
Audio::Mixer::SoundType _soundType;
Common::Rational _frameRateOverride;
@@ -250,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);