aboutsummaryrefslogtreecommitdiff
path: root/graphics/video/avi_decoder.cpp
diff options
context:
space:
mode:
authorMatthew Hoops2010-05-18 14:17:24 +0000
committerMatthew Hoops2010-05-18 14:17:24 +0000
commit11cbdd03180a655b2b23ee4a13f1a00a1d782b3c (patch)
tree5b0d84211308ea37a2fa2f7017d6f96314f3c6fb /graphics/video/avi_decoder.cpp
parentf3892a506b2f935bae0be6319394c503c786d368 (diff)
downloadscummvm-rg350-11cbdd03180a655b2b23ee4a13f1a00a1d782b3c.tar.gz
scummvm-rg350-11cbdd03180a655b2b23ee4a13f1a00a1d782b3c.tar.bz2
scummvm-rg350-11cbdd03180a655b2b23ee4a13f1a00a1d782b3c.zip
Committing the rest of the VideoDecoder Rewrite from patch #2963496.
svn-id: r49079
Diffstat (limited to 'graphics/video/avi_decoder.cpp')
-rw-r--r--graphics/video/avi_decoder.cpp110
1 files changed, 31 insertions, 79 deletions
diff --git a/graphics/video/avi_decoder.cpp b/graphics/video/avi_decoder.cpp
index 1e0fb389b3..944c9700bd 100644
--- a/graphics/video/avi_decoder.cpp
+++ b/graphics/video/avi_decoder.cpp
@@ -23,7 +23,6 @@
*
*/
-#include "common/archive.h"
#include "common/endian.h"
#include "common/file.h"
#include "common/stream.h"
@@ -49,6 +48,7 @@ AviDecoder::AviDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) :
_audStream = NULL;
_fileStream = NULL;
_audHandle = new Audio::SoundHandle();
+ _dirtyPalette = false;
memset(_palette, 0, sizeof(_palette));
memset(&_wvInfo, 0, sizeof(PCMWAVEFORMAT));
memset(&_bmInfo, 0, sizeof(BITMAPINFOHEADER));
@@ -58,7 +58,7 @@ AviDecoder::AviDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) :
}
AviDecoder::~AviDecoder() {
- closeFile();
+ close();
delete _audHandle;
}
@@ -190,7 +190,7 @@ void AviDecoder::handleStreamHeader() {
/*_palette[i * 4 + 3] = */_fileStream->readByte();
}
- setPalette(_palette);
+ _dirtyPalette = true;
}
} else if (sHeader.streamType == ID_AUDS) {
_audsHeader = sHeader;
@@ -204,24 +204,16 @@ void AviDecoder::handleStreamHeader() {
}
}
-bool AviDecoder::loadFile(const char *fileName) {
- closeFile();
-
- _fileStream = SearchMan.createReadStreamForMember(fileName);
- if (!_fileStream)
- return false;
+bool AviDecoder::load(Common::SeekableReadStream &stream) {
+ close();
+ _fileStream = &stream;
_decodedHeader = false;
- // Seek to the first frame
- _videoInfo.currentFrame = -1;
// Read chunks until we have decoded the header
while (!_decodedHeader)
runHandle(_fileStream->readUint32BE());
- _videoFrameBuffer = new byte[_header.width * _header.height];
- memset(_videoFrameBuffer, 0, _header.width * _header.height);
-
uint32 nextTag = _fileStream->readUint32BE();
// Throw out any JUNK section
@@ -247,34 +239,24 @@ bool AviDecoder::loadFile(const char *fileName) {
_mixer->playStream(_soundType, _audHandle, _audStream);
debug (0, "Frames = %d, Dimensions = %d x %d", _header.totalFrames, _header.width, _header.height);
- debug (0, "Frame Rate = %d", getFrameRate());
+ debug (0, "Frame Rate = %d", _vidsHeader.rate / _vidsHeader.scale);
if ((_audsHeader.scale != 0) && (_header.flags & AVIF_ISINTERLEAVED))
debug (0, "Sound Rate = %d", AUDIO_RATE);
debug (0, "Video Codec = \'%s\'", tag2str(_vidsHeader.streamHandler));
- _videoInfo.firstframeOffset = _fileStream->pos();
- _videoInfo.width = _header.width;
- _videoInfo.height = _header.height;
- _videoInfo.frameCount = _header.totalFrames;
- // Our frameDelay is calculated in 1/100 ms, so we convert it here
- _videoInfo.frameDelay = _header.microSecondsPerFrame / 10;
-
if (!_videoCodec)
return false;
return true;
}
-void AviDecoder::closeFile() {
+void AviDecoder::close() {
if (!_fileStream)
return;
delete _fileStream;
_fileStream = 0;
- delete[] _videoFrameBuffer;
- _videoFrameBuffer = 0;
-
// Deinitialize sound
_mixer->stopHandle(*_audHandle);
_audStream = 0;
@@ -293,14 +275,26 @@ void AviDecoder::closeFile() {
memset(&_vidsHeader, 0, sizeof(AVIStreamHeader));
memset(&_audsHeader, 0, sizeof(AVIStreamHeader));
memset(&_ixInfo, 0, sizeof(AVIOLDINDEX));
+
+ reset();
}
-Surface *AviDecoder::getNextFrame() {
+uint32 AviDecoder::getElapsedTime() const {
+ if (_audStream)
+ return _mixer->getSoundElapsedTime(*_audHandle);
+
+ return VideoDecoder::getElapsedTime();
+}
+
+Surface *AviDecoder::decodeNextFrame() {
uint32 nextTag = _fileStream->readUint32BE();
if (_fileStream->eos())
return NULL;
+ if (_curFrame == -1)
+ _startTime = g_system->getMillis();
+
if (nextTag == ID_LIST) {
// A list of audio/video chunks
uint32 listSize = _fileStream->readUint32LE() - 4;
@@ -312,7 +306,7 @@ Surface *AviDecoder::getNextFrame() {
// Decode chunks in the list and see if we get a frame
Surface *frame = NULL;
while (_fileStream->pos() < startPos + (int32)listSize) {
- Surface *temp = getNextFrame();
+ Surface *temp = decodeNextFrame();
if (temp)
frame = temp;
}
@@ -335,7 +329,7 @@ Surface *AviDecoder::getNextFrame() {
} else if (getStreamType(nextTag) == 'dc' || getStreamType(nextTag) == 'id' ||
getStreamType(nextTag) == 'AM' || getStreamType(nextTag) == '32') {
// Compressed Frame
- _videoInfo.currentFrame++;
+ _curFrame++;
uint32 chunkSize = _fileStream->readUint32LE();
if (chunkSize == 0) // Keep last frame on screen
@@ -364,7 +358,7 @@ Surface *AviDecoder::getNextFrame() {
_fileStream->readByte(); // Flags that don't serve us any purpose
}
- setPalette(_palette);
+ _dirtyPalette = true;
// No alignment necessary. It's always even.
} else if (nextTag == ID_JUNK) {
@@ -372,56 +366,11 @@ Surface *AviDecoder::getNextFrame() {
} else if (nextTag == ID_IDX1) {
runHandle(ID_IDX1);
} else
- error ("Tag = \'%s\', %d", tag2str(nextTag), _fileStream->pos());
+ error("Tag = \'%s\', %d", tag2str(nextTag), _fileStream->pos());
return NULL;
}
-bool AviDecoder::decodeNextFrame() {
- Surface *surface = NULL;
-
- int32 curFrame = _videoInfo.currentFrame;
-
- while (!surface && !endOfVideo() && !_fileStream->eos())
- surface = getNextFrame();
-
- if (curFrame == _videoInfo.currentFrame) {
- warning("No video frame found");
- _videoInfo.currentFrame++;
- }
-
- if (surface)
- memcpy(_videoFrameBuffer, surface->pixels, _header.width * _header.height);
-
- if (_videoInfo.currentFrame == 0)
- _videoInfo.startTime = g_system->getMillis();
-
- return !endOfVideo();
-}
-
-int32 AviDecoder::getAudioLag() {
- if (!_fileStream)
- return 0;
-
- int32 frameDelay = getFrameDelay();
- int32 videoTime = (_videoInfo.currentFrame + 1) * frameDelay;
- int32 audioTime;
-
- if (!_audStream) {
- /* No audio.
- Calculate the lag by how much time has gone by since the first frame
- and how much time *should* have passed.
- */
-
- audioTime = (g_system->getMillis() - _videoInfo.startTime) * 100;
- } else {
- const Audio::Timestamp ts = _mixer->getElapsedTime(*_audHandle);
- audioTime = ts.convertToFramerate(100000).totalNumberOfFrames();
- }
-
- return videoTime - audioTime;
-}
-
Codec *AviDecoder::createCodec() {
switch (_vidsHeader.streamHandler) {
case ID_CRAM:
@@ -437,11 +386,14 @@ Codec *AviDecoder::createCodec() {
return NULL;
}
-Audio::QueuingAudioStream *AviDecoder::createAudioStream() {
+PixelFormat AviDecoder::getPixelFormat() const {
+ assert(_videoCodec);
+ return _videoCodec->getPixelFormat();
+}
- if (_wvInfo.tag == AVI_WAVE_FORMAT_PCM) {
+Audio::QueuingAudioStream *AviDecoder::createAudioStream() {
+ if (_wvInfo.tag == AVI_WAVE_FORMAT_PCM)
return Audio::makeQueuingAudioStream(AUDIO_RATE, false);
- }
if (_wvInfo.tag != 0) // No sound
warning ("Unsupported AVI audio format %d", _wvInfo.tag);