diff options
author | Martin Kiewitz | 2015-06-03 19:47:01 +0200 |
---|---|---|
committer | Martin Kiewitz | 2015-06-03 19:47:01 +0200 |
commit | 626244394a6a54a5ffb2ac6ef0b3a578ee1c3cc9 (patch) | |
tree | 0aa6a8b8f717fbb1814eefa7c16434404e902b2b /engines | |
parent | 08b81e38f3df177d67cf290b07b2bc4b041dfc34 (diff) | |
download | scummvm-rg350-626244394a6a54a5ffb2ac6ef0b3a578ee1c3cc9.tar.gz scummvm-rg350-626244394a6a54a5ffb2ac6ef0b3a578ee1c3cc9.tar.bz2 scummvm-rg350-626244394a6a54a5ffb2ac6ef0b3a578ee1c3cc9.zip |
SHERLOCK: 3do movie player non-FFR thx clone2727
sherlock seems to only use a fixed frame rate
but we now support dynamic frame rate timing
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sherlock/scalpel/3do/movie_decoder.cpp | 57 | ||||
-rw-r--r-- | engines/sherlock/scalpel/3do/movie_decoder.h | 17 |
2 files changed, 31 insertions, 43 deletions
diff --git a/engines/sherlock/scalpel/3do/movie_decoder.cpp b/engines/sherlock/scalpel/3do/movie_decoder.cpp index 4f4b9f563d..857e010dda 100644 --- a/engines/sherlock/scalpel/3do/movie_decoder.cpp +++ b/engines/sherlock/scalpel/3do/movie_decoder.cpp @@ -51,15 +51,11 @@ Scalpel3DOMovieDecoder::~Scalpel3DOMovieDecoder() { } bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { - bool videoHeaderFound = false; uint32 videoSubType = 0; - uint32 videoTimeStamp = 0; uint32 videoCodecTag = 0; uint32 videoHeight = 0; uint32 videoWidth = 0; - uint32 videoFrameRate = 0; uint32 videoFrameCount = 0; - uint32 videoFrameNr = 0; uint32 audioSubType = 0; uint32 audioCodecTag = 0; uint32 audioChannels = 0; @@ -93,14 +89,14 @@ bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { switch (tag) { case MKTAG('F','I','L','M'): { // See if this is a FILM header - videoTimeStamp = _stream->readUint32BE(); + _stream->skip(4); // time stamp (based on 240 per second) _stream->skip(4); // Unknown 0x00000000 videoSubType = _stream->readUint32BE(); switch (videoSubType) { case MKTAG('F', 'H', 'D', 'R'): // FILM header found - if (videoHeaderFound) { + if (_videoTrack) { warning("Sherlock 3DO movie: Multiple FILM headers found"); close(); return false; @@ -111,33 +107,12 @@ bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { videoWidth = _stream->readUint32BE(); _stream->skip(4); // time scale videoFrameCount = _stream->readUint32BE(); - videoHeaderFound = true; + + _videoTrack = new StreamVideoTrack(videoWidth, videoHeight, videoCodecTag, videoFrameCount); + addTrack(_videoTrack); break; case MKTAG('F', 'R', 'M', 'E'): - if (!_videoTrack) { - if (!videoFrameNr) { - // first frame, we expect timestamp to be 0 - assert(videoTimeStamp == 0); - - } else { - // second frame found, we expect timestamp to be larger than 0 - assert(videoTimeStamp); - // Framerate shouldn't be known at the moment - assert(videoFrameRate == 0); - - if (!videoHeaderFound) { - error("Sherlock 3DO movie: no FILM header found before FILM frame"); - } - - // 3DO clock time for movies runs at 240Hz - videoFrameRate = 240 / videoTimeStamp; - - _videoTrack = new StreamVideoTrack(videoWidth, videoHeight, videoCodecTag, videoFrameCount, videoFrameRate); - addTrack(_videoTrack); - } - videoFrameNr++; - } break; default: @@ -228,6 +203,7 @@ void Scalpel3DOMovieDecoder::close() { void Scalpel3DOMovieDecoder::readNextPacket() { uint32 videoSubType = 0; + uint32 videoTimeStamp = 0; uint32 videoFrameSize = 0; uint32 audioSubType = 0; uint32 audioSampleBytes = 0; @@ -246,7 +222,7 @@ void Scalpel3DOMovieDecoder::readNextPacket() { switch (tag) { case MKTAG('F','I','L','M'): - _stream->readUint32BE(); // looks like frame * 16? + videoTimeStamp = _stream->readUint32BE(); _stream->skip(4); // Unknown videoSubType = _stream->readUint32BE(); @@ -261,7 +237,7 @@ void Scalpel3DOMovieDecoder::readNextPacket() { // If we previously found one, this is just to get the time offset of the next one /* uint32 frmeSize = */ _stream->readUint32BE(); videoFrameSize = _stream->readUint32BE(); - _videoTrack->decodeFrame(_stream->readStream(videoFrameSize)); + _videoTrack->decodeFrame(_stream->readStream(videoFrameSize), videoTimeStamp); gotVideo = true; break; @@ -311,12 +287,12 @@ void Scalpel3DOMovieDecoder::readNextPacket() { } } -Scalpel3DOMovieDecoder::StreamVideoTrack::StreamVideoTrack(uint32 width, uint32 height, uint32 codecTag, uint32 frameCount, uint32 frameRate) { +Scalpel3DOMovieDecoder::StreamVideoTrack::StreamVideoTrack(uint32 width, uint32 height, uint32 codecTag, uint32 frameCount) { _width = width; _height = height; _frameCount = frameCount; - _frameRate = frameRate; _curFrame = -1; + _nextFrameStartTime = 0; // Create the Cinepak decoder, if we're using it if (codecTag == MKTAG('c', 'v', 'i', 'd')) @@ -329,13 +305,24 @@ Scalpel3DOMovieDecoder::StreamVideoTrack::~StreamVideoTrack() { delete _codec; } +bool Scalpel3DOMovieDecoder::StreamVideoTrack::endOfTrack() const { + return getCurFrame() >= getFrameCount() - 1; +} + Graphics::PixelFormat Scalpel3DOMovieDecoder::StreamVideoTrack::getPixelFormat() const { return _codec->getPixelFormat(); } -void Scalpel3DOMovieDecoder::StreamVideoTrack::decodeFrame(Common::SeekableReadStream *stream) { +void Scalpel3DOMovieDecoder::StreamVideoTrack::decodeFrame(Common::SeekableReadStream *stream, uint32 videoTimeStamp) { + uint32 currentFrameStartTime = 0; + _surface = _codec->decodeFrame(*stream); _curFrame++; + + // Calculate next frame time + currentFrameStartTime = videoTimeStamp * 1000 / 240; + assert(currentFrameStartTime >= _nextFrameStartTime); + _nextFrameStartTime = currentFrameStartTime; } #define STREAMAUDIO_STEPSIZETABLE_MAX 88 diff --git a/engines/sherlock/scalpel/3do/movie_decoder.h b/engines/sherlock/scalpel/3do/movie_decoder.h index 6ee41693eb..be5a834414 100644 --- a/engines/sherlock/scalpel/3do/movie_decoder.h +++ b/engines/sherlock/scalpel/3do/movie_decoder.h @@ -51,31 +51,32 @@ protected: void readNextPacket(); private: - class StreamVideoTrack : public FixedRateVideoTrack { + class StreamVideoTrack : public VideoTrack { public: - StreamVideoTrack(uint32 width, uint32 height, uint32 codecTag, uint32 frameCount, uint32 frameRate); + StreamVideoTrack(uint32 width, uint32 height, uint32 codecTag, uint32 frameCount); ~StreamVideoTrack(); + bool endOfTrack() const; + uint16 getWidth() const { return _width; } uint16 getHeight() const { return _height; } Graphics::PixelFormat getPixelFormat() const; int getCurFrame() const { return _curFrame; } int getFrameCount() const { return _frameCount; } + uint32 getNextFrameStartTime() const { return _nextFrameStartTime; } const Graphics::Surface *decodeNextFrame() { return _surface; } - void decodeFrame(Common::SeekableReadStream *stream); - - protected: - Common::Rational getFrameRate() const { return _frameRate; } + void decodeFrame(Common::SeekableReadStream *stream, uint32 videoTimeStamp); private: const Graphics::Surface *_surface; - uint32 _frameRate; + int _curFrame; uint32 _frameCount; + uint32 _nextFrameStartTime; + Image::Codec *_codec; uint16 _width, _height; - int _curFrame; }; class StreamAudioTrack : public AudioTrack { |