aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2014-01-25 14:31:06 -0500
committerPaul Gilbert2014-01-25 14:31:06 -0500
commit0f9cfc373f8d6e0097a9558abed25be8dcd938fc (patch)
tree467fc91b704964068a939c1015f8ac89a63c0576 /engines
parent3e12562654d1b94365c695bbf6585af63ad71a4c (diff)
downloadscummvm-rg350-0f9cfc373f8d6e0097a9558abed25be8dcd938fc.tar.gz
scummvm-rg350-0f9cfc373f8d6e0097a9558abed25be8dcd938fc.tar.bz2
scummvm-rg350-0f9cfc373f8d6e0097a9558abed25be8dcd938fc.zip
VOYEUR: Refactored RL2 decoder to better load audio on the fly
Diffstat (limited to 'engines')
-rw-r--r--engines/voyeur/animation.cpp98
-rw-r--r--engines/voyeur/animation.h34
2 files changed, 86 insertions, 46 deletions
diff --git a/engines/voyeur/animation.cpp b/engines/voyeur/animation.cpp
index 7c0d21a74f..af4c989bb3 100644
--- a/engines/voyeur/animation.cpp
+++ b/engines/voyeur/animation.cpp
@@ -31,8 +31,13 @@
namespace Video {
+// Number of audio frames to keep audio track topped up when playing back video
+#define SOUND_FRAMES_READAHEAD 3
+
RL2Decoder::RL2Decoder(Audio::Mixer::SoundType soundType) : _soundType(soundType) {
_paletteStart = 0;
+ _fileStream = nullptr;
+ _soundFrameNumber = -1;
}
RL2Decoder::~RL2Decoder() {
@@ -55,6 +60,7 @@ bool RL2Decoder::loadStream(Common::SeekableReadStream *stream) {
close();
// Load basic file information
+ _fileStream = stream;
_header.load(stream);
_paletteStart = 0;
@@ -74,6 +80,15 @@ bool RL2Decoder::loadStream(Common::SeekableReadStream *stream) {
// Create a video track
addTrack(new RL2VideoTrack(_header, audioTrack, stream));
+ // Load the offset/sizes of the video's audio data
+ //_soundFrames.reserve(header._numFrames);
+ for (int frameNumber = 0; frameNumber < _header._numFrames; ++frameNumber) {
+ int offset = _header._frameOffsets[frameNumber];
+ int size = _header._frameSoundSizes[frameNumber];
+
+ _soundFrames.push_back(SoundFrame(offset, size));
+ }
+
return true;
}
@@ -107,6 +122,43 @@ RL2Decoder::RL2VideoTrack *RL2Decoder::getVideoTrack() {
return (RL2VideoTrack *)track;
}
+RL2Decoder::RL2AudioTrack *RL2Decoder::getAudioTrack() {
+ Track *track = getTrack(0);
+ assert(track);
+
+ return (RL2AudioTrack *)track;
+}
+
+void RL2Decoder::readNextPacket() {
+ int frameNumber = getCurFrame();
+ RL2AudioTrack *audioTrack = getAudioTrack();
+
+ // Handle queueing sound data
+ if (_soundFrameNumber == -1)
+ _soundFrameNumber = frameNumber;
+
+ while (audioTrack->numQueuedStreams() < SOUND_FRAMES_READAHEAD &&
+ (_soundFrameNumber < (int)_soundFrames.size())) {
+ _fileStream->seek(_soundFrames[_soundFrameNumber]._offset);
+ audioTrack->queueSound(_fileStream, _soundFrames[_soundFrameNumber]._size);
+ ++_soundFrameNumber;
+ }
+}
+
+void RL2Decoder::close() {
+ VideoDecoder::close();
+ delete _fileStream;
+ _fileStream = nullptr;
+ _soundFrameNumber = -1;
+}
+
+/*------------------------------------------------------------------------*/
+
+RL2Decoder::SoundFrame::SoundFrame(int offset, int size) {
+ _offset = offset;
+ _size = size;
+}
+
/*------------------------------------------------------------------------*/
RL2Decoder::RL2FileHeader::RL2FileHeader() {
@@ -173,6 +225,7 @@ RL2Decoder::RL2VideoTrack::RL2VideoTrack(const RL2FileHeader &header, RL2AudioTr
int fps = (header._soundRate > 0) ? header._rate / header._defSoundSize : 11025 / 1103;
_frameDelay = 1000 / fps;
+ // Set up surfaces
_surface = new Graphics::Surface();
_surface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
@@ -190,9 +243,6 @@ RL2Decoder::RL2VideoTrack::RL2VideoTrack(const RL2FileHeader &header, RL2AudioTr
}
RL2Decoder::RL2VideoTrack::~RL2VideoTrack() {
- // Free the file stream
- delete _fileStream;
-
// Free surfaces
_surface->free();
delete _surface;
@@ -386,22 +436,8 @@ Graphics::Surface *RL2Decoder::RL2VideoTrack::getBackSurface() {
RL2Decoder::RL2AudioTrack::RL2AudioTrack(const RL2FileHeader &header, Common::SeekableReadStream *stream, Audio::Mixer::SoundType soundType):
_header(header), _soundType(soundType) {
- _audStream = createAudioStream();
-
- // Add all the sound data for all the frames at once to avoid stuttering
- for (int frameNumber = 0; frameNumber < header._numFrames; ++frameNumber) {
- int offset = _header._frameOffsets[frameNumber];
- int size = _header._frameSoundSizes[frameNumber];
-
- byte *data = (byte *)malloc(size);
- stream->seek(offset);
- stream->read(data, size);
- Common::MemoryReadStream *memoryStream = new Common::MemoryReadStream(data, size,
- DisposeAfterUse::YES);
-
- _audStream->queueAudioStream(Audio::makeRawStream(memoryStream, _header._rate,
- Audio::FLAG_UNSIGNED, DisposeAfterUse::YES), DisposeAfterUse::YES);
- }
+ // Create audio straem for the audio track
+ _audStream = Audio::makeQueuingAudioStream(_header._rate, _header._channels == 2);
}
RL2Decoder::RL2AudioTrack::~RL2AudioTrack() {
@@ -409,30 +445,20 @@ RL2Decoder::RL2AudioTrack::~RL2AudioTrack() {
}
void RL2Decoder::RL2AudioTrack::queueSound(Common::SeekableReadStream *stream, int size) {
- if (_audStream) {
- // Queue the sound data
- byte *data = (byte *)malloc(size);
- stream->read(data, size);
- Common::MemoryReadStream *memoryStream = new Common::MemoryReadStream(data, size,
- DisposeAfterUse::YES);
-
- _audStream->queueAudioStream(Audio::makeRawStream(memoryStream, _header._rate,
- Audio::FLAG_UNSIGNED, DisposeAfterUse::YES), DisposeAfterUse::YES);
- // _audioTrack->queueSound(_fileStream, _header._frameSoundSizes[_curFrame]);
+ // Queue the sound data
+ byte *data = (byte *)malloc(size);
+ stream->read(data, size);
+ Common::MemoryReadStream *memoryStream = new Common::MemoryReadStream(data, size,
+ DisposeAfterUse::YES);
- } else {
- delete stream;
- }
+ _audStream->queueAudioStream(Audio::makeRawStream(memoryStream, _header._rate,
+ Audio::FLAG_UNSIGNED, DisposeAfterUse::YES), DisposeAfterUse::YES);
}
Audio::AudioStream *RL2Decoder::RL2AudioTrack::getAudioStream() const {
return _audStream;
}
-Audio::QueuingAudioStream *RL2Decoder::RL2AudioTrack::createAudioStream() {
- return Audio::makeQueuingAudioStream(_header._rate, _header._channels == 2);
-}
-
} // End of namespace Video
/*------------------------------------------------------------------------*/
diff --git a/engines/voyeur/animation.h b/engines/voyeur/animation.h
index d5e1f9fd6f..0caac9f25d 100644
--- a/engines/voyeur/animation.h
+++ b/engines/voyeur/animation.h
@@ -26,6 +26,7 @@
#include "video/video_decoder.h"
#include "audio/audiostream.h"
#include "audio/mixer.h"
+#include "common/array.h"
#include "common/list.h"
#include "common/rect.h"
#include "common/stream.h"
@@ -73,24 +74,30 @@ private:
bool isValid() const;
};
+ class SoundFrame {
+ public:
+ int _offset;
+ int _size;
+
+ SoundFrame(int offset, int size);
+ };
+
class RL2AudioTrack : public AudioTrack {
+ private:
+ Audio::Mixer::SoundType _soundType;
+ const RL2FileHeader &_header;
+ Audio::QueuingAudioStream *_audStream;
+ protected:
+ Audio::AudioStream *getAudioStream() const;
public:
RL2AudioTrack(const RL2FileHeader &header, Common::SeekableReadStream *stream,
Audio::Mixer::SoundType soundType);
~RL2AudioTrack();
- void queueSound(Common::SeekableReadStream *stream, int size);
Audio::Mixer::SoundType getSoundType() const { return _soundType; }
+ int numQueuedStreams() const { return _audStream->numQueuedStreams(); }
- protected:
- Audio::AudioStream *getAudioStream() const;
-
- private:
- Audio::Mixer::SoundType _soundType;
- const RL2FileHeader &_header;
-
- Audio::QueuingAudioStream *_audStream;
- Audio::QueuingAudioStream *createAudioStream();
+ void queueSound(Common::SeekableReadStream *stream, int size);
};
class RL2VideoTrack : public VideoTrack {
@@ -144,9 +151,12 @@ private:
};
private:
+ Common::SeekableReadStream *_fileStream;
Audio::Mixer::SoundType _soundType;
RL2FileHeader _header;
int _paletteStart;
+ Common::Array<SoundFrame> _soundFrames;
+ int _soundFrameNumber;
public:
RL2Decoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
virtual ~RL2Decoder();
@@ -155,10 +165,14 @@ public:
bool loadFile(const Common::String &file, bool palFlag = false);
bool loadVideo(int videoId);
+ virtual void readNextPacket();
+ virtual void close();
+
const Common::List<Common::Rect> *getDirtyRects() const;
void clearDirtyRects();
void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
RL2VideoTrack *getVideoTrack();
+ RL2AudioTrack *getAudioTrack();
int getPaletteStart() const { return _paletteStart; }
int getPaletteCount() const { return _header._colorCount; }
};