From ce6eb341215b5624eac7df9f148b64fd8941288c Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko <phcoder@google.com> Date: Tue, 20 Oct 2020 23:12:11 +0200 Subject: [PATCH] VIDEO: uplift 3do movie decoder from sherlock engine The format is generic to 3DO and is also used by plumbers. I think it's also accelerated on 3DO so probably is used by a lot of 3DO titles --- engines/sherlock/module.mk | 1 - engines/sherlock/scalpel/scalpel.cpp | 4 +- engines/sherlock/scalpel/scalpel_talk.cpp | 1 - .../3do_decoder.cpp | 56 +++++++++---------- .../movie_decoder.h => video/3do_decoder.h | 15 +++-- video/module.mk | 1 + 6 files changed, 42 insertions(+), 36 deletions(-) rename engines/sherlock/scalpel/3do/movie_decoder.cpp => video/3do_decoder.cpp (84%) rename engines/sherlock/scalpel/3do/movie_decoder.h => video/3do_decoder.h (93%) diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 265053a0809..e2b2e652454 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -2,7 +2,6 @@ MODULE := engines/sherlock MODULE_OBJS = \ scalpel/scalpel.o \ - scalpel/3do/movie_decoder.o \ scalpel/3do/scalpel_3do_screen.o \ scalpel/drivers/adlib.o \ scalpel/drivers/mt32.o \ diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 351d55a436d..3469372d378 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -34,7 +34,7 @@ #include "sherlock/sherlock.h" #include "sherlock/music.h" #include "sherlock/animation.h" -#include "sherlock/scalpel/3do/movie_decoder.h" +#include "video/3do_decoder.h" namespace Sherlock { @@ -1272,7 +1272,7 @@ void ScalpelEngine::showScummVMRestoreDialog() { bool ScalpelEngine::play3doMovie(const Common::String &filename, const Common::Point &pos, bool isPortrait) { Scalpel3DOScreen &screen = *(Scalpel3DOScreen *)_screen; - Scalpel3DOMovieDecoder *videoDecoder = new Scalpel3DOMovieDecoder(); + Video::ThreeDOMovieDecoder *videoDecoder = new Video::ThreeDOMovieDecoder(); Graphics::ManagedSurface tempSurface; Common::Point framePos(pos.x, pos.y); diff --git a/engines/sherlock/scalpel/scalpel_talk.cpp b/engines/sherlock/scalpel/scalpel_talk.cpp index f1460fd01d6..55cf8207262 100644 --- a/engines/sherlock/scalpel/scalpel_talk.cpp +++ b/engines/sherlock/scalpel/scalpel_talk.cpp @@ -30,7 +30,6 @@ #include "sherlock/scalpel/scalpel_user_interface.h" #include "sherlock/scalpel/scalpel.h" #include "sherlock/screen.h" -#include "sherlock/scalpel/3do/movie_decoder.h" namespace Sherlock { diff --git a/engines/sherlock/scalpel/3do/movie_decoder.cpp b/video/3do_decoder.cpp similarity index 84% rename from engines/sherlock/scalpel/3do/movie_decoder.cpp rename to video/3do_decoder.cpp index d14c46e56b2..ab6df337fd4 100644 --- a/engines/sherlock/scalpel/3do/movie_decoder.cpp +++ b/video/3do_decoder.cpp @@ -27,7 +27,7 @@ #include "audio/audiostream.h" #include "audio/decoders/3do.h" -#include "sherlock/scalpel/3do/movie_decoder.h" +#include "video/3do_decoder.h" #include "image/codecs/cinepak.h" // for Test-Code @@ -40,19 +40,19 @@ #include "graphics/pixelformat.h" #include "graphics/surface.h" -namespace Sherlock { +namespace Video { -Scalpel3DOMovieDecoder::Scalpel3DOMovieDecoder() +ThreeDOMovieDecoder::ThreeDOMovieDecoder() : _stream(0), _videoTrack(0), _audioTrack(0) { _streamVideoOffset = 0; _streamAudioOffset = 0; } -Scalpel3DOMovieDecoder::~Scalpel3DOMovieDecoder() { +ThreeDOMovieDecoder::~ThreeDOMovieDecoder() { close(); } -bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { +bool ThreeDOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { uint32 videoSubType = 0; uint32 videoCodecTag = 0; uint32 videoHeight = 0; @@ -92,7 +92,7 @@ bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { case MKTAG('F', 'H', 'D', 'R'): // FILM header found if (_videoTrack) { - warning("Sherlock 3DO movie: Multiple FILM headers found"); + warning("3DO movie: Multiple FILM headers found"); close(); return false; } @@ -111,7 +111,7 @@ bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { break; default: - warning("Sherlock 3DO movie: Unknown subtype inside FILM packet"); + warning("3DO movie: Unknown subtype inside FILM packet"); close(); return false; } @@ -128,7 +128,7 @@ bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { // Bail if we already have a track if (_audioTrack) { - warning("Sherlock 3DO movie: Multiple SNDS headers found"); + warning("3DO movie: Multiple SNDS headers found"); close(); return false; } @@ -154,7 +154,7 @@ bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { // Audio data break; default: - warning("Sherlock 3DO movie: Unknown subtype inside FILM packet"); + warning("3DO movie: Unknown subtype inside FILM packet"); close(); return false; } @@ -173,7 +173,7 @@ bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { break; default: - warning("Unknown chunk-tag '%s' inside Sherlock 3DO movie", tag2str(chunkTag)); + warning("Unknown chunk-tag '%s' inside 3DO movie", tag2str(chunkTag)); close(); return false; } @@ -197,7 +197,7 @@ bool Scalpel3DOMovieDecoder::loadStream(Common::SeekableReadStream *stream) { return true; } -void Scalpel3DOMovieDecoder::close() { +void ThreeDOMovieDecoder::close() { Video::VideoDecoder::close(); delete _stream; _stream = 0; @@ -206,7 +206,7 @@ void Scalpel3DOMovieDecoder::close() { // We try to at least decode 1 frame // and also try to get at least 0.5 seconds of audio queued up -void Scalpel3DOMovieDecoder::readNextPacket() { +void ThreeDOMovieDecoder::readNextPacket() { uint32 currentMovieTime = getTime(); uint32 wantedAudioQueued = currentMovieTime + 500; // always try to be 0.500 seconds in front of movie time @@ -300,7 +300,7 @@ void Scalpel3DOMovieDecoder::readNextPacket() { break; default: - error("Sherlock 3DO movie: Unknown subtype inside FILM packet"); + error("3DO movie: Unknown subtype inside FILM packet"); break; } break; @@ -332,7 +332,7 @@ void Scalpel3DOMovieDecoder::readNextPacket() { break; default: - error("Sherlock 3DO movie: Unknown subtype inside SNDS packet"); + error("3DO movie: Unknown subtype inside SNDS packet"); break; } break; @@ -349,7 +349,7 @@ void Scalpel3DOMovieDecoder::readNextPacket() { break; default: - error("Unknown chunk-tag '%s' inside Sherlock 3DO movie", tag2str(chunkTag)); + error("Unknown chunk-tag '%s' inside 3DO movie", tag2str(chunkTag)); } // Always seek to end of chunk @@ -362,7 +362,7 @@ void Scalpel3DOMovieDecoder::readNextPacket() { } } -Scalpel3DOMovieDecoder::StreamVideoTrack::StreamVideoTrack(uint32 width, uint32 height, uint32 codecTag, uint32 frameCount) { +ThreeDOMovieDecoder::StreamVideoTrack::StreamVideoTrack(uint32 width, uint32 height, uint32 codecTag, uint32 frameCount) { _width = width; _height = height; _frameCount = frameCount; @@ -373,27 +373,27 @@ Scalpel3DOMovieDecoder::StreamVideoTrack::StreamVideoTrack(uint32 width, uint32 if (codecTag == MKTAG('c', 'v', 'i', 'd')) _codec = new Image::CinepakDecoder(); else - error("Unsupported Sherlock 3DO movie video codec tag '%s'", tag2str(codecTag)); + error("Unsupported 3DO movie video codec tag '%s'", tag2str(codecTag)); } -Scalpel3DOMovieDecoder::StreamVideoTrack::~StreamVideoTrack() { +ThreeDOMovieDecoder::StreamVideoTrack::~StreamVideoTrack() { delete _codec; } -bool Scalpel3DOMovieDecoder::StreamVideoTrack::endOfTrack() const { +bool ThreeDOMovieDecoder::StreamVideoTrack::endOfTrack() const { return getCurFrame() >= getFrameCount() - 1; } -Graphics::PixelFormat Scalpel3DOMovieDecoder::StreamVideoTrack::getPixelFormat() const { +Graphics::PixelFormat ThreeDOMovieDecoder::StreamVideoTrack::getPixelFormat() const { return _codec->getPixelFormat(); } -void Scalpel3DOMovieDecoder::StreamVideoTrack::decodeFrame(Common::SeekableReadStream *stream, uint32 videoTimeStamp) { +void ThreeDOMovieDecoder::StreamVideoTrack::decodeFrame(Common::SeekableReadStream *stream, uint32 videoTimeStamp) { _surface = _codec->decodeFrame(*stream); _curFrame++; } -Scalpel3DOMovieDecoder::StreamAudioTrack::StreamAudioTrack(uint32 codecTag, uint32 sampleRate, uint32 channels, Audio::Mixer::SoundType soundType) : +ThreeDOMovieDecoder::StreamAudioTrack::StreamAudioTrack(uint32 codecTag, uint32 sampleRate, uint32 channels, Audio::Mixer::SoundType soundType) : AudioTrack(soundType) { switch (codecTag) { case MKTAG('A','D','P','4'): @@ -402,7 +402,7 @@ Scalpel3DOMovieDecoder::StreamAudioTrack::StreamAudioTrack(uint32 codecTag, uint break; default: - error("Unsupported Sherlock 3DO movie audio codec tag '%s'", tag2str(codecTag)); + error("Unsupported 3DO movie audio codec tag '%s'", tag2str(codecTag)); } _totalAudioQueued = 0; // currently 0 milliseconds queued @@ -417,7 +417,7 @@ Scalpel3DOMovieDecoder::StreamAudioTrack::StreamAudioTrack(uint32 codecTag, uint _stereo = true; break; default: - error("Unsupported Sherlock 3DO movie audio channels %d", channels); + error("Unsupported 3DO movie audio channels %d", channels); } _audioStream = Audio::makeQueuingAudioStream(sampleRate, _stereo); @@ -427,13 +427,13 @@ Scalpel3DOMovieDecoder::StreamAudioTrack::StreamAudioTrack(uint32 codecTag, uint memset(&_SDX2_PersistentSpace, 0, sizeof(_SDX2_PersistentSpace)); } -Scalpel3DOMovieDecoder::StreamAudioTrack::~StreamAudioTrack() { +ThreeDOMovieDecoder::StreamAudioTrack::~StreamAudioTrack() { delete _audioStream; // free(_ADP4_PersistentSpace); // free(_SDX2_PersistentSpace); } -void Scalpel3DOMovieDecoder::StreamAudioTrack::queueAudio(Common::SeekableReadStream *stream, uint32 size) { +void ThreeDOMovieDecoder::StreamAudioTrack::queueAudio(Common::SeekableReadStream *stream, uint32 size) { Common::SeekableReadStream *compressedAudioStream = 0; Audio::RewindableAudioStream *audioStream = 0; uint32 audioLengthMSecs = 0; @@ -460,8 +460,8 @@ void Scalpel3DOMovieDecoder::StreamAudioTrack::queueAudio(Common::SeekableReadSt } } -Audio::AudioStream *Scalpel3DOMovieDecoder::StreamAudioTrack::getAudioStream() const { +Audio::AudioStream *ThreeDOMovieDecoder::StreamAudioTrack::getAudioStream() const { return _audioStream; } -} // End of namespace Sherlock +} // End of namespace Video diff --git a/engines/sherlock/scalpel/3do/movie_decoder.h b/video/3do_decoder.h similarity index 93% rename from engines/sherlock/scalpel/3do/movie_decoder.h rename to video/3do_decoder.h index b54c424315c..e03bd8a1ed7 100644 --- a/engines/sherlock/scalpel/3do/movie_decoder.h +++ b/video/3do_decoder.h @@ -39,12 +39,19 @@ namespace Image { class Codec; } -namespace Sherlock { +namespace Video { -class Scalpel3DOMovieDecoder : public Video::VideoDecoder { +/** + * Decoder for 3DO videos. + * + * Video decoder used in engines: + * - sherlock + * - plumbers + */ +class ThreeDOMovieDecoder : public Video::VideoDecoder { public: - Scalpel3DOMovieDecoder(); - ~Scalpel3DOMovieDecoder() override; + ThreeDOMovieDecoder(); + ~ThreeDOMovieDecoder() override; bool loadStream(Common::SeekableReadStream *stream) override; void close() override; diff --git a/video/module.mk b/video/module.mk index c1fb79256ee..875b141672e 100644 --- a/video/module.mk +++ b/video/module.mk @@ -1,6 +1,7 @@ MODULE := video MODULE_OBJS := \ + 3do_decoder.o \ avi_decoder.o \ coktel_decoder.o \ dxa_decoder.o \