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

avi_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 #ifndef VIDEO_AVI_DECODER_H
00024 #define VIDEO_AVI_DECODER_H
00025 
00026 #include "common/array.h"
00027 #include "common/rational.h"
00028 #include "common/rect.h"
00029 #include "common/str.h"
00030 
00031 #include "video/video_decoder.h"
00032 #include "audio/mixer.h"
00033 
00034 namespace Audio {
00035 class AudioStream;
00036 class PacketizedAudioStream;
00037 }
00038 
00039 namespace Common {
00040 class SeekableReadStream;
00041 }
00042 
00043 namespace Graphics {
00044 struct PixelFormat;
00045 }
00046 
00047 namespace Image {
00048 class Codec;
00049 }
00050 
00051 namespace Video {
00052 
00063 class AVIDecoder : public VideoDecoder {
00064 public:
00065     AVIDecoder();
00066     AVIDecoder(const Common::Rational &frameRateOverride);
00067     virtual ~AVIDecoder();
00068 
00069     bool loadStream(Common::SeekableReadStream *stream);
00070     void close();
00071     uint16 getWidth() const { return _header.width; }
00072     uint16 getHeight() const { return _header.height; }
00073 
00074     bool rewind();
00075     bool isRewindable() const { return true; }
00076     bool isSeekable() const;
00077 
00093     virtual const Graphics::Surface *decodeNextFrame();
00094 
00098     const Graphics::Surface *decodeNextTransparency();
00099 protected:
00100     // VideoDecoder API
00101     void readNextPacket();
00102     bool seekIntern(const Audio::Timestamp &time);
00103     bool supportsAudioTrackSwitching() const { return true; }
00104     AudioTrack *getAudioTrack(int index);
00105 
00114     void addTrack(Track *track, bool isExternal = false);
00115 
00116     struct BitmapInfoHeader {
00117         uint32 size;
00118         uint32 width;
00119         uint32 height;
00120         uint16 planes;
00121         uint16 bitCount;
00122         uint32 compression;
00123         uint32 sizeImage;
00124         uint32 xPelsPerMeter;
00125         uint32 yPelsPerMeter;
00126         uint32 clrUsed;
00127         uint32 clrImportant;
00128     };
00129 
00130     struct WaveFormat {
00131         uint16 tag;
00132         uint16 channels;
00133         uint32 samplesPerSec;
00134         uint32 avgBytesPerSec;
00135         uint16 blockAlign;
00136     };
00137 
00138     struct PCMWaveFormat : public WaveFormat {
00139         uint16 size;
00140     };
00141 
00142     struct WaveFormatEX : public WaveFormat {
00143         uint16 bitsPerSample;
00144         uint16 size;
00145     };
00146 
00147     struct OldIndex {
00148         uint32 id;
00149         uint32 flags;
00150         uint32 offset;
00151         uint32 size;
00152     };
00153 
00154     // Index Flags
00155     enum IndexFlags {
00156         AVIIF_INDEX = 0x10
00157     };
00158 
00159     struct AVIHeader {
00160         uint32 size;
00161         uint32 microSecondsPerFrame;
00162         uint32 maxBytesPerSecond;
00163         uint32 padding;
00164         uint32 flags;
00165         uint32 totalFrames;
00166         uint32 initialFrames;
00167         uint32 streams;
00168         uint32 bufferSize;
00169         uint32 width;
00170         uint32 height;
00171     };
00172 
00173     // Flags from the AVIHeader
00174     enum AVIFlags {
00175         AVIF_HASINDEX = 0x00000010,
00176         AVIF_MUSTUSEINDEX = 0x00000020,
00177         AVIF_ISINTERLEAVED = 0x00000100,
00178         AVIF_TRUSTCKTYPE = 0x00000800,
00179         AVIF_WASCAPTUREFILE = 0x00010000,
00180         AVIF_WASCOPYRIGHTED = 0x00020000
00181     };
00182 
00183     struct AVIStreamHeader {
00184         uint32 size;
00185         uint32 streamType;
00186         uint32 streamHandler;
00187         uint32 flags;
00188         uint16 priority;
00189         uint16 language;
00190         uint32 initialFrames;
00191         uint32 scale;
00192         uint32 rate;
00193         uint32 start;
00194         uint32 length;
00195         uint32 bufferSize;
00196         uint32 quality;
00197         uint32 sampleSize;
00198         Common::Rect frame;
00199         Common::String name;
00200     };
00201 
00202     class AVIVideoTrack : public FixedRateVideoTrack {
00203     public:
00204         AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader, byte *initialPalette = 0);
00205         ~AVIVideoTrack();
00206 
00207         void decodeFrame(Common::SeekableReadStream *stream);
00208         void forceTrackEnd();
00209 
00210         uint16 getWidth() const { return _bmInfo.width; }
00211         uint16 getHeight() const { return _bmInfo.height; }
00212         uint16 getBitCount() const { return _bmInfo.bitCount; }
00213         Graphics::PixelFormat getPixelFormat() const;
00214         int getCurFrame() const { return _curFrame; }
00215         int getFrameCount() const { return _frameCount; }
00216         Common::String &getName() { return _vidsHeader.name; }
00217         const Graphics::Surface *decodeNextFrame() { return _lastFrame; }
00218 
00219         const byte *getPalette() const;
00220         bool hasDirtyPalette() const;
00221         void setCurFrame(int frame) { _curFrame = frame; }
00222         void loadPaletteFromChunk(Common::SeekableReadStream *chunk);
00223         void useInitialPalette();
00224         bool canDither() const;
00225         void setDither(const byte *palette);
00226 
00227         bool isTruemotion1() const;
00228         void forceDimensions(uint16 width, uint16 height);
00229 
00230         bool isRewindable() const { return true; }
00231         bool rewind();
00232 
00241         virtual bool setReverse(bool reverse);
00242 
00246         virtual bool isReversed() const { return _reversed; }
00247 
00251         virtual bool endOfTrack() const;
00252 
00256         Common::Rational getFrameRate() const { return Common::Rational(_vidsHeader.rate, _vidsHeader.scale); }
00257 
00261         void setFrameRate(const Common::Rational &r) {
00262             _vidsHeader.rate = r.getNumerator();
00263             _vidsHeader.scale = r.getDenominator();
00264         }
00265     private:
00266         AVIStreamHeader _vidsHeader;
00267         BitmapInfoHeader _bmInfo;
00268         byte _palette[3 * 256];
00269         byte *_initialPalette;
00270         mutable bool _dirtyPalette;
00271         int _frameCount, _curFrame;
00272         bool _reversed;
00273 
00274         Image::Codec *_videoCodec;
00275         const Graphics::Surface *_lastFrame;
00276         Image::Codec *createCodec();
00277     };
00278 
00279     class AVIAudioTrack : public AudioTrack {
00280     public:
00281         AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType);
00282         ~AVIAudioTrack();
00283 
00284         virtual void createAudioStream();
00285         virtual void queueSound(Common::SeekableReadStream *stream);
00286         void skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime);
00287         virtual void resetStream();
00288         uint32 getCurChunk() const { return _curChunk; }
00289         Common::String &getName() { return _audsHeader.name; }
00290         void setCurChunk(uint32 chunk) { _curChunk = chunk; }
00291 
00292         bool isRewindable() const { return true; }
00293         bool rewind();
00294 
00295     protected:
00296         Audio::AudioStream *getAudioStream() const { return _audioStream; }
00297 
00298         // Audio Codecs
00299         enum {
00300             kWaveFormatNone = 0,
00301             kWaveFormatPCM = 1,
00302             kWaveFormatMSADPCM = 2,
00303             kWaveFormatMSIMAADPCM = 17,
00304             kWaveFormatMP3 = 85,
00305             kWaveFormatDK3 = 98     // rogue format number
00306         };
00307 
00308         AVIStreamHeader _audsHeader;
00309         PCMWaveFormat _wvInfo;
00310         Audio::AudioStream *_audioStream;
00311         Audio::PacketizedAudioStream *_packetStream;
00312         uint32 _curChunk;
00313     };
00314 
00315     struct TrackStatus {
00316         TrackStatus();
00317 
00318         Track *track;
00319         uint32 index;
00320         uint32 chunkSearchOffset;
00321     };
00322 
00323     class IndexEntries : public Common::Array<OldIndex> {
00324     public:
00325         OldIndex *find(uint index, uint frameNumber);
00326     };
00327 
00328     AVIHeader _header;
00329 
00330     void readOldIndex(uint32 size);
00331     IndexEntries _indexEntries;
00332 
00333     Common::SeekableReadStream *_fileStream;
00334     bool _decodedHeader;
00335     bool _foundMovieList;
00336     uint32 _movieListStart, _movieListEnd;
00337 
00338     Common::Rational _frameRateOverride;
00339 
00340     int _videoTrackCounter, _audioTrackCounter;
00341     Track *_lastAddedTrack;
00342 
00343     void initCommon();
00344 
00345     bool parseNextChunk();
00346     void skipChunk(uint32 size);
00347     void handleList(uint32 listSize);
00348     void handleStreamHeader(uint32 size);
00349     void readStreamName(uint32 size);
00350     uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; }
00351     static byte getStreamIndex(uint32 tag);
00352     void checkTruemotion1();
00353     uint getVideoTrackOffset(uint trackIndex, uint frameNumber = 0);
00354 
00355     void handleNextPacket(TrackStatus& status);
00356     bool shouldQueueAudio(TrackStatus& status);
00357     void seekTransparencyFrame(int frame);
00358 
00359     Common::Array<TrackStatus> _videoTracks, _audioTracks;
00360     TrackStatus _transparencyTrack;
00361 public:
00362     virtual AVIAudioTrack *createAudioTrack(AVIStreamHeader sHeader, PCMWaveFormat wvInfo);
00363 
00370     virtual bool seekToFrame(uint frame);
00371 };
00372 
00373 } // End of namespace Video
00374 
00375 #endif


Generated on Sat Apr 20 2019 05:02:00 for ResidualVM by doxygen 1.7.1
curved edge   curved edge