diff options
| author | Paul Gilbert | 2014-01-25 18:46:26 -0500 | 
|---|---|---|
| committer | Paul Gilbert | 2014-01-25 18:46:26 -0500 | 
| commit | ee26919e9074b46155e5a8013f623c6b892779df (patch) | |
| tree | ed5f58d8862a69d0cdde2594ae15cb21848a087c | |
| parent | 0f9cfc373f8d6e0097a9558abed25be8dcd938fc (diff) | |
| download | scummvm-rg350-ee26919e9074b46155e5a8013f623c6b892779df.tar.gz scummvm-rg350-ee26919e9074b46155e5a8013f623c6b892779df.tar.bz2 scummvm-rg350-ee26919e9074b46155e5a8013f623c6b892779df.zip  | |
VOYEUR: Simply RL2 video decoder, and add proper seeking support
| -rw-r--r-- | engines/voyeur/animation.cpp | 34 | ||||
| -rw-r--r-- | engines/voyeur/animation.h | 17 | ||||
| -rw-r--r-- | engines/voyeur/voyeur.cpp | 2 | 
3 files changed, 35 insertions, 18 deletions
diff --git a/engines/voyeur/animation.cpp b/engines/voyeur/animation.cpp index af4c989bb3..f1126e50bb 100644 --- a/engines/voyeur/animation.cpp +++ b/engines/voyeur/animation.cpp @@ -81,7 +81,7 @@ bool RL2Decoder::loadStream(Common::SeekableReadStream *stream) {  	addTrack(new RL2VideoTrack(_header, audioTrack, stream));  	// Load the offset/sizes of the video's audio data -	//_soundFrames.reserve(header._numFrames); +	_soundFrames.reserve(_header._numFrames);  	for (int frameNumber = 0; frameNumber < _header._numFrames; ++frameNumber) {  		int offset = _header._frameOffsets[frameNumber];  		int size = _header._frameSoundSizes[frameNumber]; @@ -145,6 +145,15 @@ void RL2Decoder::readNextPacket() {  	}  } +bool RL2Decoder::seek(const Audio::Timestamp &where) { +	// TODO: Ideally, I need a way to clear the audio track's QueuingAudioStream when +	// a seek is done. Otherwise, as current, seeking can only be done correctly when +	// the video is first loaded. + +	_soundFrameNumber = -1; +	return VideoDecoder::seek(where); +} +  void RL2Decoder::close() {  	VideoDecoder::close();  	delete _fileStream; @@ -215,16 +224,16 @@ bool RL2Decoder::RL2FileHeader::isValid() const {  	return _signature == MKTAG('R','L','V','2') || _signature != MKTAG('R','L','V','3');  } +double RL2Decoder::RL2FileHeader::getFrameRate() const { +	return (_soundRate > 0) ? _rate / _defSoundSize : 11025 / 1103; +} +  /*------------------------------------------------------------------------*/  RL2Decoder::RL2VideoTrack::RL2VideoTrack(const RL2FileHeader &header, RL2AudioTrack *audioTrack,   		Common::SeekableReadStream *stream):   		_header(header), _audioTrack(audioTrack), _fileStream(stream) { -	// Calculate the frame rate -	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()); @@ -239,7 +248,7 @@ RL2Decoder::RL2VideoTrack::RL2VideoTrack(const RL2FileHeader &header, RL2AudioTr  	_dirtyPalette = header._colorCount > 0;  	_curFrame = 0; -	_nextFrameStartTime = 0; +	_initialFrame = true;  }  RL2Decoder::RL2VideoTrack::~RL2VideoTrack() { @@ -261,10 +270,13 @@ bool RL2Decoder::RL2VideoTrack::endOfTrack() const {  	return getCurFrame() >= getFrameCount();  } -bool RL2Decoder::RL2VideoTrack::rewind() { -	_curFrame = 0; -	_nextFrameStartTime = 0; +bool RL2Decoder::RL2VideoTrack::seek(const Audio::Timestamp &time) { +	int frame = time.totalNumberOfFrames(); + +	if (frame < 0 || frame >= _header._numFrames) +		return false; +	_curFrame = frame;  	return true;  } @@ -281,7 +293,7 @@ Graphics::PixelFormat RL2Decoder::RL2VideoTrack::getPixelFormat() const {  }  const Graphics::Surface *RL2Decoder::RL2VideoTrack::decodeNextFrame() { -	if (_curFrame == 0 && _hasBackFrame) { +	if (_initialFrame && _hasBackFrame) {  		// Read in the initial background frame  		_fileStream->seek(0x324);  		rl2DecodeFrameWithoutTransparency(0); @@ -289,6 +301,7 @@ const Graphics::Surface *RL2Decoder::RL2VideoTrack::decodeNextFrame() {  		Common::copy((byte *)_surface->getPixels(), (byte *)_surface->getPixels() + (320 * 200),   			(byte *)_backSurface->getPixels());  		_dirtyRects.push_back(Common::Rect(0, 0, _surface->w, _surface->h)); +		_initialFrame = false;  	}  	// Move to the next frame data @@ -306,7 +319,6 @@ const Graphics::Surface *RL2Decoder::RL2VideoTrack::decodeNextFrame() {  	}  	_curFrame++; -	_nextFrameStartTime += _frameDelay;  	return _surface;  } diff --git a/engines/voyeur/animation.h b/engines/voyeur/animation.h index 0caac9f25d..bfa9c8c8ae 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 "audio/timestamp.h"  #include "common/array.h"  #include "common/list.h"  #include "common/rect.h" @@ -72,6 +73,7 @@ private:  		~RL2FileHeader();  		void load(Common::SeekableReadStream *stream);  		bool isValid() const; +		double getFrameRate() const;  	};  	class SoundFrame { @@ -96,19 +98,19 @@ private:  		Audio::Mixer::SoundType getSoundType() const { return _soundType; }  		int numQueuedStreams() const { return _audStream->numQueuedStreams(); } +		virtual bool isSeekable() const { return true; } +		virtual bool seek(const Audio::Timestamp &time) { return true; }  		void queueSound(Common::SeekableReadStream *stream, int size);  	}; -	class RL2VideoTrack : public VideoTrack { +	class RL2VideoTrack : public FixedRateVideoTrack {  	public:  		RL2VideoTrack(const RL2FileHeader &header, RL2AudioTrack *audioTrack,   			Common::SeekableReadStream *stream);  		~RL2VideoTrack();  		bool endOfTrack() const; -		bool isRewindable() const { return true; } -		bool rewind();  		uint16 getWidth() const;  		uint16 getHeight() const; @@ -117,7 +119,6 @@ private:  		Graphics::PixelFormat getPixelFormat() const;  		int getCurFrame() const { return _curFrame; }  		int getFrameCount() const { return _header._numFrames; } -		uint32 getNextFrameStartTime() const { return _nextFrameStartTime; }  		const Graphics::Surface *decodeNextFrame();  		const byte *getPalette() const { _dirtyPalette = false; return _header._palette; }  		int getPaletteCount() const { return _header._colorCount; } @@ -126,6 +127,9 @@ private:  		void clearDirtyRects() { _dirtyRects.clear(); }  		void copyDirtyRectsToBuffer(uint8 *dst, uint pitch); +		virtual Common::Rational getFrameRate() const { return _header.getFrameRate(); } +		virtual bool isSeekable() const { return true; } +		virtual bool seek(const Audio::Timestamp &time);  	private:  		Common::SeekableReadStream *_fileStream;  		const RL2FileHeader &_header; @@ -136,11 +140,10 @@ private:  		mutable bool _dirtyPalette; +		bool _initialFrame;  		int _curFrame;  		uint32 _videoBase;  		uint32 *_frameOffsets; -		uint32 _frameDelay; -		uint32 _nextFrameStartTime;  		Common::List<Common::Rect> _dirtyRects; @@ -167,6 +170,7 @@ public:  	virtual void readNextPacket();  	virtual void close(); +	virtual bool seek(const Audio::Timestamp &where);  	const Common::List<Common::Rect> *getDirtyRects() const;  	void clearDirtyRects(); @@ -175,6 +179,7 @@ public:  	RL2AudioTrack *getAudioTrack();  	int getPaletteStart() const { return _paletteStart; }  	int getPaletteCount() const { return _header._colorCount; } +	const RL2FileHeader &getHeader() { return _header; }  };  } // End of namespace Video diff --git a/engines/voyeur/voyeur.cpp b/engines/voyeur/voyeur.cpp index 72f568ba82..490d35e345 100644 --- a/engines/voyeur/voyeur.cpp +++ b/engines/voyeur/voyeur.cpp @@ -558,7 +558,7 @@ void VoyeurEngine::playAVideoDuration(int videoId, int duration) {  	decoder.loadVideo(videoId);  	decoder.start(); -	decoder.seek(Audio::Timestamp(_voy._vocSecondsOffset * 1000)); +	decoder.seek(Audio::Timestamp(_voy._vocSecondsOffset * 1000, decoder.getHeader().getFrameRate()));  	int endFrame = decoder.getCurFrame() + totalFrames;   	while (!shouldQuit() && !decoder.endOfVideo() && !_eventsManager._mouseClicked &&  | 
