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


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