diff options
author | Paul Gilbert | 2014-01-25 14:31:06 -0500 |
---|---|---|
committer | Paul Gilbert | 2014-01-25 14:31:06 -0500 |
commit | 0f9cfc373f8d6e0097a9558abed25be8dcd938fc (patch) | |
tree | 467fc91b704964068a939c1015f8ac89a63c0576 /engines | |
parent | 3e12562654d1b94365c695bbf6585af63ad71a4c (diff) | |
download | scummvm-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.cpp | 98 | ||||
-rw-r--r-- | engines/voyeur/animation.h | 34 |
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; } }; |