ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

coktel_decoder.h

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 // Currently, only GOB and SCI32 games play IMDs and VMDs, so skip compiling if GOB and SCI32 is disabled.
00024 #if !(defined(ENABLE_GOB) || defined(ENABLE_SCI32) || defined(DYNAMIC_MODULES))
00025 
00026 // Do not compile the CoktelDecoder code
00027 
00028 #else
00029 
00030 #ifndef VIDEO_COKTELDECODER_H
00031 #define VIDEO_COKTELDECODER_H
00032 
00033 #include "common/list.h"
00034 #include "common/array.h"
00035 #include "common/rational.h"
00036 #include "common/str.h"
00037 
00038 #include "graphics/surface.h"
00039 
00040 #include "video/video_decoder.h"
00041 
00042 #include "audio/mixer.h"
00043 
00044 namespace Common {
00045 struct Rect;
00046 class MemoryReadWriteStream;
00047 class SeekableReadStream;
00048 }
00049 namespace Audio {
00050 class QueuingAudioStream;
00051 }
00052 
00053 namespace Graphics {
00054 struct PixelFormat;
00055 }
00056 
00057 namespace Image {
00058 class Codec;
00059 }
00060 
00061 namespace Video {
00062 
00070 class CoktelDecoder {
00071 public:
00072     struct State {
00074         uint32 flags;
00076         uint16 speechId;
00077 
00078         State();
00079     };
00080 
00081     CoktelDecoder(Audio::Mixer *mixer,
00082             Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
00083     virtual ~CoktelDecoder();
00084 
00086     virtual bool reloadStream(Common::SeekableReadStream *stream) = 0;
00087 
00088     virtual bool seek(int32 frame, int whence = SEEK_SET, bool restart = false) = 0;
00089 
00091     void setSurfaceMemory(void *mem, uint16 width, uint16 height, uint8 bpp);
00093     void setSurfaceMemory();
00094 
00095     const Graphics::Surface *getSurface() const;
00096 
00098     virtual void setXY(uint16 x, uint16 y);
00100     void setXY();
00101 
00103     void setFrameRate(Common::Rational frameRate);
00105     Common::Rational getFrameRate() const;
00106 
00108     uint16 getDefaultX() const;
00110     uint16 getDefaultY() const;
00111 
00113     const Common::List<Common::Rect> &getDirtyRects() const;
00114 
00115     bool hasPalette() const;
00116     virtual bool hasVideo() const;
00117 
00118     bool hasSound()       const;
00119     bool isSoundEnabled() const;
00120     bool isSoundPlaying() const;
00121 
00122     void enableSound();
00123     void disableSound();
00124     void finishSound();
00125 
00126     virtual void colorModeChanged();
00127 
00129     virtual bool getFrameCoords(int16 frame, int16 &x, int16 &y, int16 &width, int16 &height);
00130 
00132     virtual bool hasEmbeddedFiles() const;
00133 
00135     virtual bool hasEmbeddedFile(const Common::String &fileName) const;
00136 
00138     virtual Common::SeekableReadStream *getEmbeddedFile(const Common::String &fileName) const;
00139 
00141     virtual int32 getSubtitleIndex() const;
00142 
00144     virtual bool isPaletted() const;
00145 
00150     int getCurFrame() const;
00151 
00156     virtual const Graphics::Surface *decodeNextFrame() = 0;
00157 
00162     virtual bool loadStream(Common::SeekableReadStream *stream) = 0;
00163 
00165     virtual bool isVideoLoaded() const = 0;
00166 
00168     bool endOfVideo() const;
00169 
00171     void close();
00172 
00174     Audio::Mixer::SoundType getSoundType() const;
00176     Audio::AudioStream *getAudioStream() const;
00177 
00178     uint16 getWidth()  const;
00179     uint16 getHeight() const;
00180     virtual Graphics::PixelFormat getPixelFormat() const = 0;
00181 
00182     uint32 getFrameCount() const;
00183 
00184     const byte *getPalette();
00185     bool  hasDirtyPalette() const;
00186 
00187     uint32 getTimeToNextFrame() const;
00188     uint32 getStaticTimeToNextFrame() const;
00189 
00190     void pauseVideo(bool pause);
00191 
00192 protected:
00193     enum SoundStage {
00194         kSoundNone     = 0, 
00195         kSoundLoaded   = 1, 
00196         kSoundPlaying  = 2, 
00197         kSoundFinished = 3  
00198     };
00199 
00200     enum Features {
00201         kFeaturesNone        = 0x0000,
00202         kFeaturesPalette     = 0x0008, 
00203         kFeaturesDataSize    = 0x0020, 
00204         kFeaturesSound       = 0x0040, 
00205         kFeaturesFrameCoords = 0x0080, 
00206         kFeaturesStdCoords   = 0x0100, 
00207         kFeaturesFramePos    = 0x0200, 
00208         kFeaturesVideo       = 0x0400  
00209     };
00210 
00211     Audio::Mixer *_mixer;
00212     Audio::Mixer::SoundType _soundType;
00213 
00214     uint16 _width;
00215     uint16 _height;
00216 
00217     uint16 _x;
00218     uint16 _y;
00219 
00220     uint16 _defaultX;
00221     uint16 _defaultY;
00222 
00223     uint32 _features;
00224 
00225      int32 _curFrame;
00226     uint32 _frameCount;
00227 
00228     uint32 _startTime;
00229 
00230     byte _palette[768];
00231     bool _paletteDirty;
00232 
00233     bool    _ownSurface;
00234     Graphics::Surface _surface;
00235 
00236     Common::List<Common::Rect> _dirtyRects;
00237 
00238     Common::Rational _frameRate;
00239 
00240     // Current sound state
00241     bool       _hasSound;
00242     bool       _soundEnabled;
00243     SoundStage _soundStage;
00244 
00245     Audio::QueuingAudioStream *_audioStream;
00246     Audio::SoundHandle _audioHandle;
00247 
00248     bool evaluateSeekFrame(int32 &frame, int whence) const;
00249 
00250     // Surface management
00251     bool hasSurface();
00252     void createSurface();
00253     void freeSurface();
00254 
00255     // Decompression
00256     uint32 deLZ77(byte *dest, const byte *src, uint32 srcSize, uint32 destSize);
00257     void deRLE(byte *&destPtr, const byte *&srcPtr, int16 destLen, int16 srcLen);
00258 
00259     // Block rendering
00260     void renderBlockWhole   (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
00261     void renderBlockWhole4X (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
00262     void renderBlockWhole2Y (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
00263     void renderBlockSparse  (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
00264     void renderBlockSparse2Y(Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
00265     void renderBlockRLE     (Graphics::Surface &dstSurf, const byte *src, Common::Rect &rect);
00266 
00267     // Sound helper functions
00268     inline void unsignedToSigned(byte *buffer, int length);
00269 
00270 private:
00271     uint32 _pauseStartTime;
00272     bool   _isPaused;
00273 };
00274 
00275 class PreIMDDecoder : public CoktelDecoder {
00276 public:
00277     PreIMDDecoder(uint16 width, uint16 height, Audio::Mixer *mixer,
00278             Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
00279     ~PreIMDDecoder();
00280 
00281     bool reloadStream(Common::SeekableReadStream *stream);
00282 
00283     bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
00284 
00285     bool loadStream(Common::SeekableReadStream *stream);
00286     void close();
00287 
00288     bool isVideoLoaded() const;
00289 
00290     const Graphics::Surface *decodeNextFrame();
00291 
00292     Graphics::PixelFormat getPixelFormat() const;
00293 
00294 private:
00295     Common::SeekableReadStream *_stream;
00296 
00297     // Buffer for processed frame data
00298     byte  *_videoBuffer;
00299     uint32 _videoBufferSize;
00300 
00301     // Frame decoding
00302     void processFrame();
00303     void renderFrame();
00304 };
00305 
00306 class IMDDecoder : public CoktelDecoder {
00307 public:
00308     IMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
00309     ~IMDDecoder();
00310 
00311     bool reloadStream(Common::SeekableReadStream *stream);
00312 
00313     bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
00314 
00315     void setXY(uint16 x, uint16 y);
00316 
00317     bool loadStream(Common::SeekableReadStream *stream);
00318     void close();
00319 
00320     bool isVideoLoaded() const;
00321 
00322     const Graphics::Surface *decodeNextFrame();
00323 
00324     Graphics::PixelFormat getPixelFormat() const;
00325 
00326 private:
00327     enum Command {
00328         kCommandNextSound   = 0xFF00,
00329         kCommandStartSound  = 0xFF01,
00330 
00331         kCommandBreak       = 0xFFF0,
00332         kCommandBreakSkip0  = 0xFFF1,
00333         kCommandBreakSkip16 = 0xFFF2,
00334         kCommandBreakSkip32 = 0xFFF3,
00335         kCommandBreakMask   = 0xFFF8,
00336 
00337         kCommandPalette     = 0xFFF4,
00338         kCommandVideoData   = 0xFFFC,
00339 
00340         kCommandJump        = 0xFFFD
00341     };
00342 
00343     struct Coord {
00344         int16 left;
00345         int16 top;
00346         int16 right;
00347         int16 bottom;
00348     };
00349 
00350     Common::SeekableReadStream *_stream;
00351 
00352     byte _version;
00353 
00354     // Standard coordinates gives by the header
00355     int16 _stdX;
00356     int16 _stdY;
00357     int16 _stdWidth;
00358     int16 _stdHeight;
00359 
00360     uint32 _flags;
00361 
00362     uint32  _firstFramePos; 
00363     uint32 *_framePos;      
00364     Coord  *_frameCoords;   
00365 
00366     uint32 _videoBufferSize;   
00367     byte  *_videoBuffer[2];    
00368     uint32 _videoBufferLen[2]; 
00369 
00370     // Sound properties
00371     uint16 _soundFlags;
00372      int16 _soundFreq;
00373      int16 _soundSliceSize;
00374      int16 _soundSlicesCount;
00375 
00376     // Loading helper functions
00377     bool loadCoordinates();
00378     bool loadFrameTableOffsets(uint32 &framePosPos, uint32 &frameCoordsPos);
00379     bool assessVideoProperties();
00380     bool assessAudioProperties();
00381     bool loadFrameTables(uint32 framePosPos, uint32 frameCoordsPos);
00382 
00383     // Frame decoding
00384     void processFrame();
00385     Common::Rect calcFrameCoords(uint32 frame);
00386 
00387     // Video
00388     bool renderFrame(Common::Rect &rect);
00389 
00390     // Sound
00391     void nextSoundSlice(bool hasNextCmd);
00392     bool initialSoundSlice(bool hasNextCmd);
00393     void emptySoundSlice(bool hasNextCmd);
00394 };
00395 
00396 class VMDDecoder : public CoktelDecoder {
00397 friend class AdvancedVMDDecoder;
00398 
00399 public:
00400     VMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
00401     ~VMDDecoder();
00402 
00403     bool reloadStream(Common::SeekableReadStream *stream);
00404 
00405     bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
00406 
00407     void setXY(uint16 x, uint16 y);
00408 
00409     void colorModeChanged();
00410 
00411     bool getFrameCoords(int16 frame, int16 &x, int16 &y, int16 &width, int16 &height);
00412 
00413     bool hasEmbeddedFiles() const;
00414     bool hasEmbeddedFile(const Common::String &fileName) const;
00415     Common::SeekableReadStream *getEmbeddedFile(const Common::String &fileName) const;
00416 
00417     int32 getSubtitleIndex() const;
00418 
00419     bool hasVideo() const;
00420     bool isPaletted() const;
00421 
00422     bool loadStream(Common::SeekableReadStream *stream);
00423     void close();
00424 
00425     bool isVideoLoaded() const;
00426 
00427     const Graphics::Surface *decodeNextFrame();
00428 
00429     Graphics::PixelFormat getPixelFormat() const;
00430 
00431 protected:
00432     void setAutoStartSound(bool autoStartSound);
00433 
00434 private:
00435     enum PartType {
00436         kPartTypeSeparator = 0,
00437         kPartTypeAudio     = 1,
00438         kPartTypeVideo     = 2,
00439         kPartTypeFile      = 3,
00440         kPartType4         = 4,
00441         kPartTypeSubtitle  = 5
00442     };
00443 
00444     enum AudioFormat {
00445         kAudioFormat8bitRaw    = 0,
00446         kAudioFormat16bitDPCM  = 1,
00447         kAudioFormat16bitADPCM = 2
00448     };
00449 
00450     struct File {
00451         Common::String name;
00452 
00453         uint32 offset;
00454         uint32 size;
00455         uint32 realSize;
00456 
00457         File();
00458     };
00459 
00460     struct Part {
00461         PartType type;
00462         byte     field_1;
00463         byte     field_E;
00464         uint32   size;
00465         int16    left;
00466         int16    top;
00467         int16    right;
00468         int16    bottom;
00469         uint16   id;
00470         byte     flags;
00471 
00472         Part();
00473     };
00474 
00475     struct Frame {
00476         uint32 offset;
00477         Part  *parts;
00478 
00479         Frame();
00480         ~Frame();
00481     };
00482 
00483     Common::SeekableReadStream *_stream;
00484 
00485     byte   _version;
00486     uint32 _flags;
00487 
00488     uint32 _frameInfoOffset;
00489     uint16 _partsPerFrame;
00490     Frame *_frames;
00491 
00492     Common::Array<File> _files;
00493 
00494     // Sound properties
00495     uint16 _soundFlags;
00496     int16  _soundFreq;
00497     int16  _soundSliceSize;
00498     int16  _soundSlicesCount;
00499     byte   _soundBytesPerSample;
00500     byte   _soundStereo; // (0: mono, 1: old-style stereo, 2: new-style stereo)
00501     uint32 _soundHeaderSize;
00502     uint32 _soundDataSize;
00503     uint32 _soundLastFilledFrame;
00504     AudioFormat _audioFormat;
00505     bool   _autoStartSound;
00506 
00516     Common::MemoryReadWriteStream *_oldStereoBuffer;
00517 
00518     // Video properties
00519     bool   _hasVideo;
00520     uint32 _videoCodec;
00521     byte   _blitMode;
00522     byte   _bytesPerPixel;
00523 
00524     uint32  _firstFramePos; 
00525 
00526     uint32 _videoBufferSize;   
00527     byte  *_videoBuffer[3];    
00528     uint32 _videoBufferLen[3]; 
00529 
00530     Graphics::Surface _8bppSurface[3]; 
00531 
00532     bool _externalCodec;
00533     Image::Codec *_codec;
00534 
00535     int32 _subtitle;
00536 
00537     bool _isPaletted;
00538 
00539     // Loading helper functions
00540     bool assessVideoProperties();
00541     bool assessAudioProperties();
00542     bool openExternalCodec();
00543     bool readFrameTable(int &numFiles);
00544     bool readFiles();
00545 
00546     // Frame decoding
00547     void processFrame();
00548 
00549     // Video
00550     bool renderFrame(Common::Rect &rect);
00551     bool getRenderRects(const Common::Rect &rect,
00552             Common::Rect &realRect, Common::Rect &fakeRect);
00553     void blit16(const Graphics::Surface &srcSurf, Common::Rect &rect);
00554     void blit24(const Graphics::Surface &srcSurf, Common::Rect &rect);
00555 
00556     // Sound
00557     void emptySoundSlice  (uint32 size);
00558     void filledSoundSlice (uint32 size);
00559     void filledSoundSlices(uint32 size, uint32 mask);
00560     void createAudioStream();
00561 
00562     uint8 evaluateMask(uint32 mask, bool *fillInfo, uint8 &max);
00563 
00564     // Generating audio streams
00565     Audio::AudioStream *create8bitRaw   (Common::SeekableReadStream *stream);
00566     Audio::AudioStream *create16bitDPCM (Common::SeekableReadStream *stream);
00567     Audio::AudioStream *create16bitADPCM(Common::SeekableReadStream *stream);
00568 
00569     bool getPartCoords(int16 frame, PartType type, int16 &x, int16 &y, int16 &width, int16 &height);
00570 };
00571 
00576 class AdvancedVMDDecoder : public VideoDecoder {
00577 public:
00578     AdvancedVMDDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
00579     ~AdvancedVMDDecoder();
00580 
00581     bool loadStream(Common::SeekableReadStream *stream);
00582     void close();
00583 
00584     void setSurfaceMemory(void *mem, uint16 width, uint16 height, uint8 bpp);
00585 
00586 private:
00587     class VMDVideoTrack : public FixedRateVideoTrack {
00588     public:
00589         VMDVideoTrack(VMDDecoder *decoder);
00590 
00591         uint16 getWidth() const;
00592         uint16 getHeight() const;
00593         Graphics::PixelFormat getPixelFormat() const;
00594         int getCurFrame() const;
00595         int getFrameCount() const;
00596         const Graphics::Surface *decodeNextFrame();
00597         const byte *getPalette() const;
00598         bool hasDirtyPalette() const;
00599 
00600     protected:
00601         Common::Rational getFrameRate() const;
00602 
00603     private:
00604         VMDDecoder *_decoder;
00605     };
00606 
00607     class VMDAudioTrack : public AudioTrack {
00608     public:
00609         VMDAudioTrack(VMDDecoder *decoder);
00610 
00611     protected:
00612         virtual Audio::AudioStream *getAudioStream() const;
00613 
00614     private:
00615         VMDDecoder *_decoder;
00616     };
00617 
00618     VMDDecoder    *_decoder;
00619     VMDVideoTrack *_videoTrack;
00620     VMDAudioTrack *_audioTrack;
00621 };
00622 
00623 } // End of namespace Video
00624 
00625 #endif // VIDEO_COKTELDECODER_H
00626 
00627 #endif // Engine and dynamic plugins guard


Generated on Sat Mar 16 2019 05:01:21 for ResidualVM by doxygen 1.7.1
curved edge   curved edge