diff options
author | clone2727 | 2013-07-05 15:28:06 -0700 |
---|---|---|
committer | clone2727 | 2013-07-05 15:28:06 -0700 |
commit | 279c9f78412d9053a60b53b70b5e770159a2aa92 (patch) | |
tree | 431fdb6ff27fa016dad730c526b89db54becc1f3 | |
parent | 2521449e79e6650a8663e0143d60d69239e58da8 (diff) | |
parent | 4ed1bc3a57e0160eb0b395c2a363151700216d04 (diff) | |
download | scummvm-rg350-279c9f78412d9053a60b53b70b5e770159a2aa92.tar.gz scummvm-rg350-279c9f78412d9053a60b53b70b5e770159a2aa92.tar.bz2 scummvm-rg350-279c9f78412d9053a60b53b70b5e770159a2aa92.zip |
Merge pull request #343 from clone2727/mpeg2-avi
Add back support for sword1/2 MPEG-2 cutscenes
-rwxr-xr-x | configure | 57 | ||||
-rw-r--r-- | engines/sword1/animation.cpp | 56 | ||||
-rw-r--r-- | engines/sword1/animation.h | 3 | ||||
-rw-r--r-- | engines/sword2/animation.cpp | 55 | ||||
-rw-r--r-- | engines/sword2/animation.h | 3 | ||||
-rw-r--r-- | video/avi_decoder.cpp | 68 | ||||
-rw-r--r-- | video/avi_decoder.h | 7 | ||||
-rw-r--r-- | video/codecs/mpeg.cpp | 107 | ||||
-rw-r--r-- | video/codecs/mpeg.h | 98 | ||||
-rw-r--r-- | video/module.mk | 5 |
10 files changed, 393 insertions, 66 deletions
@@ -113,6 +113,7 @@ _seq_midi=auto _sndio=auto _timidity=auto _zlib=auto +_mpeg2=auto _sparkle=auto _png=auto _theoradec=auto @@ -925,6 +926,9 @@ Optional Libraries: --with-zlib-prefix=DIR Prefix where zlib is installed (optional) --disable-zlib disable zlib (compression) support [autodetect] + --with-mpeg2-prefix=DIR Prefix where libmpeg2 is installed (optional) + --enable-mpeg2 enable mpeg2 codec for cutscenes [autodetect] + --with-opengl-prefix=DIR Prefix where OpenGL (ES) is installed (optional) --disable-opengl disable OpenGL (ES) support [autodetect] @@ -1005,6 +1009,8 @@ for ac_option in $@; do --disable-sparkle) _sparkle=no ;; --enable-nasm) _nasm=yes ;; --disable-nasm) _nasm=no ;; + --enable-mpeg2) _mpeg2=yes ;; + --disable-mpeg2) _mpeg2=no ;; --disable-png) _png=no ;; --enable-png) _png=yes ;; --disable-theoradec) _theoradec=no ;; @@ -1046,6 +1052,11 @@ for ac_option in $@; do FLUIDSYNTH_CFLAGS="-I$arg/include" FLUIDSYNTH_LIBS="-L$arg/lib" ;; + --with-mpeg2-prefix=*) + arg=`echo $ac_option | cut -d '=' -f 2` + MPEG2_CFLAGS="-I$arg/include" + MPEG2_LIBS="-L$arg/lib" + ;; --with-alsa-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` ALSA_CFLAGS="-I$arg/include" @@ -3456,6 +3467,52 @@ define_in_config_if_yes "$_zlib" 'USE_ZLIB' echo "$_zlib" # +# Check for LibMPEG2 +# +echocheck "libmpeg2 >= 0.4.0" +if test "$_mpeg2" = auto ; then + _mpeg2=no + cat > $TMPC << EOF +typedef signed $type_1_byte int8_t; +typedef signed $type_2_byte int16_t; +typedef signed $type_4_byte int32_t; + +typedef unsigned $type_1_byte uint8_t; +typedef unsigned $type_2_byte uint16_t; +typedef unsigned $type_4_byte uint32_t; + +extern "C" { +#include <mpeg2dec/mpeg2.h> +} + +int main(void) { + #if MPEG2_RELEASE < MPEG2_VERSION(0, 4, 0) + #error libmpeg2 version too low + #endif + + /* mpeg2_state_t first appears in 0.4.0 */ + mpeg2_state_t state; + + return 0; +} +EOF + + if test -n "$_host"; then + # don't execute while cross compiling + cc_check $MPEG2_CFLAGS $MPEG2_LIBS -lmpeg2 && _mpeg2=yes + else + cc_check_no_clean $MPEG2_CFLAGS $MPEG2_LIBS -lmpeg2 && $TMPO$HOSTEXEEXT && _mpeg2=yes + cc_check_clean + fi +fi +if test "$_mpeg2" = yes ; then + INCLUDES="$INCLUDES $MPEG2_CFLAGS" + LIBS="$LIBS $MPEG2_LIBS -lmpeg2" +fi +define_in_config_if_yes "$_mpeg2" 'USE_MPEG2' +echo "$_mpeg2" + +# # Check for Sparkle if updates support is enabled # echocheck "Sparkle" diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp index 206bd68b07..79ec060bc1 100644 --- a/engines/sword1/animation.cpp +++ b/engines/sword1/animation.cpp @@ -37,7 +37,14 @@ #include "gui/message.h" +#ifdef USE_MPEG2 +#include "video/avi_decoder.h" +#endif + +#ifdef USE_ZLIB #include "video/dxa_decoder.h" +#endif + #include "video/psx_decoder.h" #include "video/smk_decoder.h" @@ -176,27 +183,26 @@ bool MoviePlayer::load(uint32 id) { break; case kVideoDecoderPSX: filename = Common::String::format("%s.str", (_vm->_systemVars.isDemo) ? sequenceList[id] : sequenceListPSX[id]); + break; + case kVideoDecoderMP2: + filename = Common::String::format("%s.mp2", sequenceList[id]); + break; + } - // Need to switch to true color + // Need to switch to true color for PSX/MP2 videos + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) initGraphics(g_system->getWidth(), g_system->getHeight(), true, 0); - // Need to load here in case it fails in which case we'd need - // to go back to paletted mode - if (_decoder->loadFile(filename)) { - _decoder->start(); - return true; - } else { + if (!_decoder->loadFile(filename)) { + // Go back to 8bpp color + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) initGraphics(g_system->getWidth(), g_system->getHeight(), true); - return false; - } - break; - } - if (!_decoder->loadFile(filename)) return false; + } - // For DXA, also add the external sound file - if (_decoderType == kVideoDecoderDXA) + // For DXA/MP2, also add the external sound file + if (_decoderType == kVideoDecoderDXA || _decoderType == kVideoDecoderMP2) _decoder->addStreamFileTrack(sequenceList[id]); _decoder->start(); @@ -224,9 +230,9 @@ void MoviePlayer::play() { } void MoviePlayer::performPostProcessing(byte *screen) { - // TODO: We don't support the PSX stream videos yet + // TODO: We don't support displaying these in true color yet, // nor using the PSX fonts to display subtitles. - if (_vm->isPsx()) + if (_vm->isPsx() || _decoderType == kVideoDecoderMP2) return; if (!_movieTexts.empty()) { @@ -414,20 +420,19 @@ bool MoviePlayer::playVideo() { _vm->_system->delayMillis(10); } - if (_decoderType == kVideoDecoderPSX) { - // Need to jump back to paletted color + // Need to jump back to paletted color + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) initGraphics(g_system->getWidth(), g_system->getHeight(), true); - } return !_vm->shouldQuit() && !skipped; } uint32 MoviePlayer::getBlackColor() { - return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black; + return (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black; } uint32 MoviePlayer::findTextColor() { - if (_decoderType == kVideoDecoderPSX) { + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) { // We're in true color mode, so return the actual colors switch (_textColor) { case 1: @@ -547,9 +552,16 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan * filename = Common::String::format("%s.mp2", sequenceList[id]); if (Common::File::exists(filename)) { - GUI::MessageDialog dialog(_("MPEG2 cutscenes are no longer supported"), _("OK")); +#ifdef USE_MPEG2 + // HACK: Old ScummVM builds ignored the AVI frame rate field and forced the video + // to be played back at 12fps. + Video::VideoDecoder *aviDecoder = new Video::AVIDecoder(12); + return new MoviePlayer(vm, textMan, resMan, system, aviDecoder, kVideoDecoderMP2); +#else + GUI::MessageDialog dialog(_("MPEG-2 cutscenes found but ScummVM has been built without MPEG-2"), _("OK")); dialog.runModal(); return 0; +#endif } if (!vm->isPsx() || scumm_stricmp(sequenceList[id], "enddemo") != 0) { diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h index d0c61f5eb3..2c51a74f71 100644 --- a/engines/sword1/animation.h +++ b/engines/sword1/animation.h @@ -41,7 +41,8 @@ namespace Sword1 { enum DecoderType { kVideoDecoderDXA = 0, kVideoDecoderSMK = 1, - kVideoDecoderPSX = 2 + kVideoDecoderPSX = 2, + kVideoDecoderMP2 = 3 }; class MovieText { diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp index 00260f789a..713120ad43 100644 --- a/engines/sword2/animation.cpp +++ b/engines/sword2/animation.cpp @@ -42,7 +42,14 @@ #include "gui/message.h" +#ifdef USE_MPEG2 +#include "video/avi_decoder.h" +#endif + +#ifdef USE_ZLIB #include "video/dxa_decoder.h" +#endif + #include "video/smk_decoder.h" #include "video/psx_decoder.h" @@ -88,26 +95,26 @@ bool MoviePlayer::load(const char *name) { break; case kVideoDecoderPSX: filename = Common::String::format("%s.str", name); + break; + case kVideoDecoderMP2: + filename = Common::String::format("%s.mp2", name); + break; + } - // Need to switch to true color - initGraphics(640, 480, true, 0); + // Need to switch to true color for PSX/MP2 videos + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) + initGraphics(g_system->getWidth(), g_system->getHeight(), true, 0); - // Need to load here in case it fails in which case we'd need - // to go back to paletted mode - if (_decoder->loadFile(filename)) { - _decoder->start(); - return true; - } else { - initGraphics(640, 480, true); - return false; - } - } + if (!_decoder->loadFile(filename)) { + // Go back to 8bpp color + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) + initGraphics(g_system->getWidth(), g_system->getHeight(), true); - if (!_decoder->loadFile(filename)) return false; + } - // For DXA, also add the external sound file - if (_decoderType == kVideoDecoderDXA) + // For DXA/MP2, also add the external sound file + if (_decoderType == kVideoDecoderDXA || _decoderType == kVideoDecoderMP2) _decoder->addStreamFileTrack(name); _decoder->start(); @@ -136,10 +143,9 @@ void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadI _vm->_sound->stopSpeech(); } - if (_decoderType == kVideoDecoderPSX) { - // Need to jump back to paletted color + // Need to jump back to paletted color + if (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) initGraphics(640, 480, true); - } } void MoviePlayer::openTextObject(uint32 index) { @@ -378,11 +384,11 @@ bool MoviePlayer::playVideo() { } uint32 MoviePlayer::getBlackColor() { - return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black; + return (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black; } uint32 MoviePlayer::getWhiteColor() { - return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF) : _white; + return (_decoderType == kVideoDecoderPSX || _decoderType == kVideoDecoderMP2) ? g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF) : _white; } void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) { @@ -446,9 +452,16 @@ MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, OSystem *system filename = Common::String::format("%s.mp2", name); if (Common::File::exists(filename)) { - GUI::MessageDialog dialog(_("MPEG2 cutscenes are no longer supported"), _("OK")); +#ifdef USE_MPEG2 + // HACK: Old ScummVM builds ignored the AVI frame rate field and forced the video + // to be played back at 12fps. + Video::AVIDecoder *aviDecoder = new Video::AVIDecoder(12); + return new MoviePlayer(vm, system, aviDecoder, kVideoDecoderMP2); +#else + GUI::MessageDialog dialog(_("MPEG-2 cutscenes found but ScummVM has been built without MPEG-2 support"), _("OK")); dialog.runModal(); return NULL; +#endif } // The demo tries to play some cutscenes that aren't there, so make those warnings more discreet. diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h index b2a243b2ca..8669bdc8d8 100644 --- a/engines/sword2/animation.h +++ b/engines/sword2/animation.h @@ -40,7 +40,8 @@ namespace Sword2 { enum DecoderType { kVideoDecoderDXA = 0, kVideoDecoderSMK = 1, - kVideoDecoderPSX = 2 + kVideoDecoderPSX = 2, + kVideoDecoderMP2 = 3 }; struct MovieText { diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp index 6fe9c773b8..ff728a8437 100644 --- a/video/avi_decoder.cpp +++ b/video/avi_decoder.cpp @@ -36,6 +36,7 @@ // Video Codecs #include "video/codecs/cinepak.h" #include "video/codecs/indeo3.h" +#include "video/codecs/mpeg.h" #include "video/codecs/msvideo1.h" #include "video/codecs/msrle.h" #include "video/codecs/truemotion1.h" @@ -64,8 +65,8 @@ namespace Video { #define ID_VEDT MKTAG('v','e','d','t') #define ID_IDX1 MKTAG('i','d','x','1') #define ID_STRD MKTAG('s','t','r','d') -#define ID_00AM MKTAG('0','0','A','M') //#define ID_INFO MKTAG('I','N','F','O') +#define ID_ISFT MKTAG('I','S','F','T') // Codec tags #define ID_RLE MKTAG('R','L','E',' ') @@ -75,6 +76,7 @@ namespace Video { #define ID_CVID MKTAG('c','v','i','d') #define ID_IV32 MKTAG('i','v','3','2') #define ID_DUCK MKTAG('D','U','C','K') +#define ID_MPG2 MKTAG('m','p','g','2') static byte char2num(char c) { c = tolower((byte)c); @@ -89,17 +91,27 @@ static uint16 getStreamType(uint32 tag) { return tag & 0xffff; } -AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _soundType(soundType) { - _decodedHeader = false; - _fileStream = 0; - memset(&_ixInfo, 0, sizeof(_ixInfo)); - memset(&_header, 0, sizeof(_header)); +AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _frameRateOverride(0), _soundType(soundType) { + initCommon(); +} + +AVIDecoder::AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType) + : _frameRateOverride(frameRateOverride), _soundType(soundType) { + initCommon(); } AVIDecoder::~AVIDecoder() { close(); } +void AVIDecoder::initCommon() { + _decodedHeader = false; + _foundMovieList = false; + _fileStream = 0; + memset(&_ixInfo, 0, sizeof(_ixInfo)); + memset(&_header, 0, sizeof(_header)); +} + void AVIDecoder::runHandle(uint32 tag) { assert(_fileStream); if (_fileStream->eos()) @@ -137,6 +149,7 @@ void AVIDecoder::runHandle(uint32 tag) { case ID_STRD: // Extra stream info, safe to ignore case ID_VEDT: // Unknown, safe to ignore case ID_JUNK: // Alignment bytes, should be ignored + case ID_ISFT: // Metadata, safe to ignore { uint32 junkSize = _fileStream->readUint32LE(); _fileStream->skip(junkSize + (junkSize & 1)); // Alignment @@ -165,6 +178,13 @@ void AVIDecoder::handleList() { debug(0, "Found LIST of type %s", tag2str(listType)); + if (listType == ID_MOVI) { + // Found the 'movi' list + // We're done parsing everything + _foundMovieList = true; + return; + } + while ((_fileStream->pos() - curPos) < listSize) runHandle(_fileStream->readUint32BE()); @@ -203,6 +223,11 @@ void AVIDecoder::handleStreamHeader() { uint32 startPos = _fileStream->pos(); if (sHeader.streamType == ID_VIDS) { + if (_frameRateOverride != 0) { + sHeader.rate = _frameRateOverride.getNumerator(); + sHeader.scale = _frameRateOverride.getDenominator(); + } + BitmapInfoHeader bmInfo; bmInfo.size = _fileStream->readUint32LE(); bmInfo.width = _fileStream->readUint32LE(); @@ -263,26 +288,24 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) { _fileStream = stream; _decodedHeader = false; + _foundMovieList = false; // Read chunks until we have decoded the header - while (!_decodedHeader) + while (!_decodedHeader && _fileStream->pos() < _fileStream->size()) runHandle(_fileStream->readUint32BE()); - uint32 nextTag = _fileStream->readUint32BE(); - - // Throw out any JUNK section - if (nextTag == ID_JUNK) { - runHandle(ID_JUNK); - nextTag = _fileStream->readUint32BE(); + if (_fileStream->pos() >= _fileStream->size()) { + warning("Failed to find AVI header"); + return false; } - // Ignore the 'movi' LIST - if (nextTag == ID_LIST) { - _fileStream->readUint32BE(); // Skip size - if (_fileStream->readUint32BE() != ID_MOVI) - error("Expected 'movi' LIST"); - } else { - error("Expected 'movi' LIST"); + // Then read until we find the movie list + while (!_foundMovieList && _fileStream->pos() < _fileStream->size()) + runHandle(_fileStream->readUint32BE()); + + if (_fileStream->pos() >= _fileStream->size()) { + warning("Failed to find AVI 'movi' LIST"); + return false; } return true; @@ -294,6 +317,7 @@ void AVIDecoder::close() { delete _fileStream; _fileStream = 0; _decodedHeader = false; + _foundMovieList = false; delete[] _ixInfo.indices; memset(&_ixInfo, 0, sizeof(_ixInfo)); @@ -428,6 +452,10 @@ Codec *AVIDecoder::AVIVideoTrack::createCodec() { case ID_DUCK: return new TrueMotion1Decoder(_bmInfo.width, _bmInfo.height); #endif +#ifdef USE_MPEG2 + case ID_MPG2: + return new MPEGDecoder(); +#endif default: warning("Unknown/Unhandled compression format \'%s\'", tag2str(_vidsHeader.streamHandler)); } diff --git a/video/avi_decoder.h b/video/avi_decoder.h index 34a67f4c28..6082232464 100644 --- a/video/avi_decoder.h +++ b/video/avi_decoder.h @@ -52,10 +52,13 @@ class Codec; * * Video decoder used in engines: * - sci + * - sword1 + * - sword2 */ class AVIDecoder : public VideoDecoder { public: AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); + AVIDecoder(const Common::Rational &frameRateOverride, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); virtual ~AVIDecoder(); bool loadStream(Common::SeekableReadStream *stream); @@ -219,9 +222,11 @@ private: AVIHeader _header; Common::SeekableReadStream *_fileStream; - bool _decodedHeader; + bool _decodedHeader, _foundMovieList; Audio::Mixer::SoundType _soundType; + Common::Rational _frameRateOverride; + void initCommon(); void runHandle(uint32 tag); void handleList(); diff --git a/video/codecs/mpeg.cpp b/video/codecs/mpeg.cpp new file mode 100644 index 0000000000..cb3c63fcfc --- /dev/null +++ b/video/codecs/mpeg.cpp @@ -0,0 +1,107 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/debug.h" +#include "common/stream.h" +#include "common/system.h" +#include "common/textconsole.h" +#include "graphics/surface.h" +#include "graphics/yuv_to_rgb.h" + +#include "video/codecs/mpeg.h" + +namespace Video { + +MPEGDecoder::MPEGDecoder() : Codec() { + _pixelFormat = g_system->getScreenFormat(); + _surface = 0; + + _mpegDecoder = mpeg2_init(); + + if (!_mpegDecoder) + error("Could not initialize libmpeg2"); + + _mpegInfo = mpeg2_info(_mpegDecoder); +} + +MPEGDecoder::~MPEGDecoder() { + mpeg2_close(_mpegDecoder); + + if (_surface) { + _surface->free(); + delete _surface; + } +} + +const Graphics::Surface *MPEGDecoder::decodeImage(Common::SeekableReadStream *stream) { + uint32 framePeriod; + decodePacket(stream, framePeriod); + return _surface; +} + +bool MPEGDecoder::decodePacket(Common::SeekableReadStream *packet, uint32 &framePeriod, Graphics::Surface *dst) { + // Decode as much as we can out of this packet + uint32 size = 0xFFFFFFFF; + mpeg2_state_t state; + bool foundFrame = false; + framePeriod = 0; + + do { + state = mpeg2_parse(_mpegDecoder); + + switch (state) { + case STATE_BUFFER: + size = packet->read(_buffer, BUFFER_SIZE); + mpeg2_buffer(_mpegDecoder, _buffer, _buffer + size); + break; + case STATE_SLICE: + case STATE_END: + if (_mpegInfo->display_fbuf) { + foundFrame = true; + const mpeg2_sequence_t *sequence = _mpegInfo->sequence; + + framePeriod += sequence->frame_period; + + if (!dst) { + // If no destination is specified, use our internal storage + if (!_surface) { + _surface = new Graphics::Surface(); + _surface->create(sequence->picture_width, sequence->picture_height, _pixelFormat); + } + + dst = _surface; + } + + YUVToRGBMan.convert420(dst, Graphics::YUVToRGBManager::kScaleITU, _mpegInfo->display_fbuf->buf[0], + _mpegInfo->display_fbuf->buf[1], _mpegInfo->display_fbuf->buf[2], sequence->picture_width, + sequence->picture_height, sequence->width, sequence->chroma_width); + } + break; + default: + break; + } + } while (size != 0); + + return foundFrame; +} + +} // End of namespace Video diff --git a/video/codecs/mpeg.h b/video/codecs/mpeg.h new file mode 100644 index 0000000000..0082844537 --- /dev/null +++ b/video/codecs/mpeg.h @@ -0,0 +1,98 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifdef USE_MPEG2 + +#ifndef VIDEO_CODECS_MPEG_H +#define VIDEO_CODECS_MPEG_H + +#include "video/codecs/codec.h" +#include "graphics/pixelformat.h" + +#if defined(__PLAYSTATION2__) + typedef uint8 uint8_t; + typedef uint16 uint16_t; + typedef uint32 uint32_t; +#elif defined(_WIN32_WCE) + typedef signed char int8_t; + typedef signed short int16_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; +#elif defined(_MSC_VER) + typedef signed char int8_t; + typedef signed short int16_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + #if !defined(SDL_COMPILEDVERSION) || (SDL_COMPILEDVERSION < 1210) + typedef signed long int32_t; + typedef unsigned long uint32_t; + #endif +#else +# include <inttypes.h> +#endif + +extern "C" { + #include <mpeg2dec/mpeg2.h> +} + +namespace Common { +class SeekableReadStream; +} + +namespace Graphics { +struct Surface; +} + +namespace Video { + +// MPEG 1/2 video decoder + +class MPEGDecoder : public Codec { +public: + MPEGDecoder(); + ~MPEGDecoder(); + + // Codec interface + const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream); + Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; } + + // MPEGPSDecoder call + bool decodePacket(Common::SeekableReadStream *packet, uint32 &framePeriod, Graphics::Surface *dst = 0); + +private: + Graphics::PixelFormat _pixelFormat; + Graphics::Surface *_surface; + + enum { + BUFFER_SIZE = 4096 + }; + + byte _buffer[BUFFER_SIZE]; + mpeg2dec_t *_mpegDecoder; + const mpeg2_info_t *_mpegInfo; +}; + +} // End of namespace Video + +#endif // VIDEO_CODECS_MPEG_H + +#endif // USE_MPEG2 diff --git a/video/module.mk b/video/module.mk index 287e14ce18..a491947aaf 100644 --- a/video/module.mk +++ b/video/module.mk @@ -31,5 +31,10 @@ MODULE_OBJS += \ theora_decoder.o endif +ifdef USE_MPEG2 +MODULE_OBJS += \ + codecs/mpeg.o +endif + # Include common rules include $(srcdir)/rules.mk |