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

bink_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 // Based on eos' Bink decoder which is in turn
00024 // based quite heavily on the Bink decoder found in FFmpeg.
00025 // Many thanks to Kostya Shishkov for doing the hard work.
00026 
00027 #include "common/scummsys.h"
00028 
00029 #ifdef USE_BINK
00030 
00031 #ifndef VIDEO_BINK_DECODER_H
00032 #define VIDEO_BINK_DECODER_H
00033 
00034 #include "common/array.h"
00035 #include "common/bitstream.h"
00036 #include "common/rational.h"
00037 #include "graphics/surface.h" // ResidualVM specific
00038 
00039 #include "video/video_decoder.h"
00040 
00041 #include "graphics/surface.h"
00042 
00043 namespace Audio {
00044 class AudioStream;
00045 class QueuingAudioStream;
00046 }
00047 
00048 namespace Common {
00049 class SeekableReadStream;
00050 template <class BITSTREAM>
00051 class Huffman;
00052 
00053 class RDFT;
00054 class DCT;
00055 }
00056 
00057 namespace Graphics {
00058 struct Surface;
00059 }
00060 
00061 namespace Video {
00062 
00069 class BinkDecoder : public VideoDecoder {
00070 public:
00071     BinkDecoder();
00072     ~BinkDecoder();
00073 
00074     bool loadStream(Common::SeekableReadStream *stream);
00075     void close();
00076 
00077     // ResidualVM-specific:
00078     Common::Rational getFrameRate();
00079 protected:
00080     void readNextPacket();
00081     bool supportsAudioTrackSwitching() const { return true; }
00082     AudioTrack *getAudioTrack(int index);
00083 
00084     // ResidualVM-specific:
00085     bool seekIntern(const Audio::Timestamp &time);
00086     uint32 findKeyFrame(uint32 frame) const;
00087 
00088 private:
00089     static const int kAudioChannelsMax  = 2;
00090     static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11);
00091 
00092     enum AudioCodec {
00093         kAudioCodecDCT,
00094         kAudioCodecRDFT
00095     };
00096 
00098     struct AudioInfo {
00099         uint16 flags;
00100 
00101         uint32 sampleRate;
00102         uint8  channels;
00103 
00104         uint32 outSampleRate;
00105         uint8  outChannels;
00106 
00107         AudioCodec codec;
00108 
00109         uint32 sampleCount;
00110 
00111         Common::BitStream32LELSB *bits;
00112 
00113         bool first;
00114 
00115         uint32 frameLen;
00116         uint32 overlapLen;
00117 
00118         uint32 blockSize;
00119 
00120         uint32  bandCount;
00121         uint32 *bands;
00122 
00123         float root;
00124 
00125         float coeffs[16 * kAudioBlockSizeMax];
00126         int16 prevCoeffs[kAudioBlockSizeMax];
00127 
00128         float *coeffsPtr[kAudioChannelsMax];
00129 
00130         Common::RDFT *rdft;
00131         Common::DCT  *dct;
00132 
00133         AudioInfo();
00134         ~AudioInfo();
00135     };
00136 
00138     struct VideoFrame {
00139         bool keyFrame;
00140 
00141         uint32 offset;
00142         uint32 size;
00143 
00144         Common::BitStream32LELSB *bits;
00145 
00146         VideoFrame();
00147         ~VideoFrame();
00148     };
00149 
00150     class BinkVideoTrack : public FixedRateVideoTrack {
00151     public:
00152         BinkVideoTrack(uint32 width, uint32 height, const Graphics::PixelFormat &format, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id);
00153         ~BinkVideoTrack();
00154 
00155         uint16 getWidth() const { return _surface.w; }
00156         uint16 getHeight() const { return _surface.h; }
00157         Graphics::PixelFormat getPixelFormat() const { return _surface.format; }
00158         int getCurFrame() const { return _curFrame; }
00159         int getFrameCount() const { return _frameCount; }
00160         const Graphics::Surface *decodeNextFrame() { return &_surface; }
00161 // ResidualVM-specific:
00162         bool isSeekable() const { return true; }
00163         bool seek(const Audio::Timestamp &time) { return true; }
00164         bool rewind() override;
00165         void setCurFrame(uint32 frame) { _curFrame = frame; }
00166 // End of ResidualVM-specific
00167 
00169         void decodePacket(VideoFrame &frame);
00170 
00171     public: // ResidualVM
00172         Common::Rational getFrameRate() const { return _frameRate; }
00173 
00174     private:
00176         struct DecodeContext {
00177             VideoFrame *video;
00178 
00179             uint32 planeIdx;
00180 
00181             uint32 blockX;
00182             uint32 blockY;
00183 
00184             byte *dest;
00185             byte *prev;
00186 
00187             byte *destStart, *destEnd;
00188             byte *prevStart, *prevEnd;
00189 
00190             uint32 pitch;
00191 
00192             int coordMap[64];
00193             int coordScaledMap1[64];
00194             int coordScaledMap2[64];
00195             int coordScaledMap3[64];
00196             int coordScaledMap4[64];
00197         };
00198 
00200         enum Source {
00201             kSourceBlockTypes    = 0, 
00202             kSourceSubBlockTypes    , 
00203             kSourceColors           , 
00204             kSourcePattern          , 
00205             kSourceXOff             , 
00206             kSourceYOff             , 
00207             kSourceIntraDC          , 
00208             kSourceInterDC          , 
00209             kSourceRun              , 
00210 
00211             kSourceMAX
00212         };
00213 
00215         enum BlockType {
00216             kBlockSkip    = 0,  
00217             kBlockScaled     ,  
00218             kBlockMotion     ,  
00219             kBlockRun        ,  
00220             kBlockResidue    ,  
00221             kBlockIntra      ,  
00222             kBlockFill       ,  
00223             kBlockInter      ,  
00224             kBlockPattern    ,  
00225             kBlockRaw           
00226         };
00227 
00229         struct Huffman {
00230             int  index;       
00231             byte symbols[16]; 
00232         };
00233 
00235         struct Bundle {
00236             int countLengths[2]; 
00237             int countLength;     
00238 
00239             Huffman huffman; 
00240 
00241             byte *data;    
00242             byte *dataEnd; 
00243 
00244             byte *curDec; 
00245             byte *curPtr; 
00246         };
00247 
00248         int _curFrame;
00249         int _frameCount;
00250 
00251         Graphics::Surface _surface;
00252         int _surfaceWidth; 
00253         int _surfaceHeight; 
00254 
00255         uint32 _id; 
00256 
00257         bool _hasAlpha;   
00258         bool _swapPlanes; 
00259 
00260         Common::Rational _frameRate;
00261 
00262         Bundle _bundles[kSourceMAX]; 
00263 
00264         Common::Huffman<Common::BitStream32LELSB> *_huffman[16]; 
00265 
00267         Huffman _colHighHuffman[16];
00269         int _colLastVal;
00270 
00271         uint32 _yBlockWidth;   
00272         uint32 _yBlockHeight;  
00273         uint32 _uvBlockWidth;  
00274         uint32 _uvBlockHeight; 
00275 
00276         byte *_curPlanes[4]; 
00277         byte *_oldPlanes[4]; 
00278 
00280         void initBundles();
00282         void deinitBundles();
00283 
00285         void initHuffman();
00286 
00288         void decodePlane(VideoFrame &video, int planeIdx, bool isChroma);
00289 
00291         void readBundle(VideoFrame &video, Source source);
00292 
00294         void readHuffman(VideoFrame &video, Huffman &huffman);
00296         void mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size);
00297 
00299         byte getHuffmanSymbol(VideoFrame &video, Huffman &huffman);
00300 
00302         int32 getBundleValue(Source source);
00304         uint32 readBundleCount(VideoFrame &video, Bundle &bundle);
00305 
00306         // Handle the block types
00307         void blockSkip         (DecodeContext &ctx);
00308         void blockScaledSkip   (DecodeContext &ctx);
00309         void blockScaledRun    (DecodeContext &ctx);
00310         void blockScaledIntra  (DecodeContext &ctx);
00311         void blockScaledFill   (DecodeContext &ctx);
00312         void blockScaledPattern(DecodeContext &ctx);
00313         void blockScaledRaw    (DecodeContext &ctx);
00314         void blockScaled       (DecodeContext &ctx);
00315         void blockMotion       (DecodeContext &ctx);
00316         void blockRun          (DecodeContext &ctx);
00317         void blockResidue      (DecodeContext &ctx);
00318         void blockIntra        (DecodeContext &ctx);
00319         void blockFill         (DecodeContext &ctx);
00320         void blockInter        (DecodeContext &ctx);
00321         void blockPattern      (DecodeContext &ctx);
00322         void blockRaw          (DecodeContext &ctx);
00323 
00324         // Read the bundles
00325         void readRuns        (VideoFrame &video, Bundle &bundle);
00326         void readMotionValues(VideoFrame &video, Bundle &bundle);
00327         void readBlockTypes  (VideoFrame &video, Bundle &bundle);
00328         void readPatterns    (VideoFrame &video, Bundle &bundle);
00329         void readColors      (VideoFrame &video, Bundle &bundle);
00330         void readDCS         (VideoFrame &video, Bundle &bundle, int startBits, bool hasSign);
00331         void readDCTCoeffs   (VideoFrame &video, int32 *block, bool isIntra);
00332         void readResidue     (VideoFrame &video, int16 *block, int masksCount);
00333 
00334         // Bink video IDCT
00335         void IDCT(int32 *block);
00336         void IDCTPut(DecodeContext &ctx, int32 *block);
00337         void IDCTAdd(DecodeContext &ctx, int32 *block);
00338     };
00339 
00340     class BinkAudioTrack : public AudioTrack {
00341     public:
00342         BinkAudioTrack(AudioInfo &audio, Audio::Mixer::SoundType soundType);
00343         ~BinkAudioTrack();
00344 
00346         void decodePacket();
00347 
00348         bool seek(const Audio::Timestamp &time);  // ResidualVM-specific
00349         bool isSeekable() const { return true; }  // ResidualVM-specific
00350         void skipSamples(const Audio::Timestamp &length);  // ResidualVM-specific
00351         int getRate(); // ResidualVM-specific
00352     protected:
00353         Audio::AudioStream *getAudioStream() const;
00354 
00355     private:
00356         AudioInfo *_audioInfo;
00357         Audio::QueuingAudioStream *_audioStream;
00358 
00359         float getFloat();
00360 
00362         void audioBlock(int16 *out);
00364         void audioBlockDCT();
00366         void audioBlockRDFT();
00367 
00368         void readAudioCoeffs(float *coeffs);
00369 
00370         static void floatToInt16Interleave(int16 *dst, const float **src, uint32 length, uint8 channels);
00371     };
00372 
00373     Common::SeekableReadStream *_bink;
00374 
00375     Common::Array<AudioInfo> _audioTracks; 
00376     Common::Array<VideoFrame> _frames;      
00377 
00378     void initAudioTrack(AudioInfo &audio);
00379 };
00380 
00381 } // End of namespace Video
00382 
00383 #endif // VIDEO_BINK_DECODER_H
00384 
00385 #endif // USE_BINK


Generated on Sat May 25 2019 05:00:39 for ResidualVM by doxygen 1.7.1
curved edge   curved edge