ScummVM API documentation
smk_decoder.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  *
21  * This file is dual-licensed.
22  * In addition to the GPLv3 license mentioned above, MojoTouch has
23  * non-exclusively licensed this code on March 23th, 2024, to be used in
24  * closed-source products.
25  * Therefore, any contributions (commits) to it will also be dual-licensed.
26  *
27  */
28 
29 #ifndef VIDEO_SMK_PLAYER_H
30 #define VIDEO_SMK_PLAYER_H
31 
32 #include "common/bitarray.h"
33 #include "common/bitstream.h"
34 #include "common/rational.h"
35 #include "common/rect.h"
36 #include "graphics/pixelformat.h"
37 #include "graphics/surface.h"
38 #include "video/video_decoder.h"
39 #include "audio/mixer.h"
40 
41 namespace Audio {
42 class QueuingAudioStream;
43 }
44 
45 namespace Common {
46 class SeekableReadStream;
47 }
48 
49 namespace Video {
50 
51 class BigHuffmanTree;
52 
53 // Because the maximum number of bits read from a bitstream is 16, and the data is 8-bit, the container only
54 // needs to hold up to 23 bits at any given time. As such, we use a bitstream with a 32-bit container to
55 // avoid the overhead of 64-bit maths on systems that don't support it natively.
57 
75 class SmackerDecoder : public VideoDecoder {
76 public:
78  virtual ~SmackerDecoder();
79 
80  virtual bool loadStream(Common::SeekableReadStream *stream);
81  void close();
82  void forceSeekToFrame(uint frame);
83  bool rewind();
84 
85  Common::Rational getFrameRate() const;
86 
87  virtual const Common::Rect *getNextDirtyRect();
88 
89 protected:
90  void readNextPacket();
91  bool supportsAudioTrackSwitching() const { return true; }
92  AudioTrack *getAudioTrack(int index);
93 
94  virtual void handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize);
95 
96  virtual uint32 getSignatureVersion(uint32 signature) const;
97 
99  public:
100  SmackerVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 version);
102 
103  bool isRewindable() const { return true; }
104  bool rewind() { _curFrame = -1; return true; }
105 
106  uint16 getWidth() const;
107  uint16 getHeight() const;
108  Graphics::PixelFormat getPixelFormat() const;
109  int getCurFrame() const { return _curFrame; }
110  int getFrameCount() const { return _frameCount; }
111  const Graphics::Surface *decodeNextFrame() { return _surface; }
112  const byte *getPalette() const { _dirtyPalette = false; return _palette; }
113  bool hasDirtyPalette() const { return _dirtyPalette; }
114 
115  void readTrees(SmackerBitStream &bs, uint32 mMapSize, uint32 mClrSize, uint32 fullSize, uint32 typeSize);
116  void increaseCurFrame() { _curFrame++; }
117  void decodeFrame(SmackerBitStream &bs);
118  void unpackPalette(Common::SeekableReadStream *stream);
119 
120  Common::Rational getFrameRate() const { return _frameRate; }
121 
122  const Common::Rect *getNextDirtyRect();
123 
124  protected:
125  Graphics::Surface *_surface;
126 
127  private:
128  Common::Rational _frameRate;
129  uint32 _flags, _version;
130 
131  byte _palette[3 * 256];
132  mutable bool _dirtyPalette;
133 
134  int _curFrame;
135  uint32 _frameCount;
136 
137  BigHuffmanTree *_MMapTree;
138  BigHuffmanTree *_MClrTree;
139  BigHuffmanTree *_FullTree;
140  BigHuffmanTree *_TypeTree;
141 
142  Common::BitArray _dirtyBlocks;
143  Common::Rect _lastDirtyRect;
144 
145  // Possible runs of blocks
146  static uint getBlockRun(int index) { return (index <= 58) ? index + 1 : 128 << (index - 59); }
147  };
148 
149  virtual SmackerVideoTrack *createVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 version) const;
150 
151  Common::SeekableReadStream *_fileStream;
152 
153  enum AudioCompression {
154  kCompressionNone,
155  kCompressionDPCM,
156  kCompressionRDFT,
157  kCompressionDCT
158  };
159 
160  struct AudioInfo {
161  AudioCompression compression;
162  bool hasAudio;
163  bool is16Bits;
164  bool isStereo;
165  uint32 sampleRate;
166  };
167 
168  struct {
169  uint32 signature;
170  uint32 flags;
171  uint32 audioSize[7];
172  uint32 treesSize;
173  uint32 mMapSize;
174  uint32 mClrSize;
175  uint32 fullSize;
176  uint32 typeSize;
177  AudioInfo audioInfo[7];
178  uint32 dummy;
179  } _header;
180 
181  uint32 *_frameSizes;
182 
183 private:
184 
185  class SmackerAudioTrack : public AudioTrack {
186  public:
187  SmackerAudioTrack(const AudioInfo &audioInfo, Audio::Mixer::SoundType soundType);
188  ~SmackerAudioTrack();
189 
190  bool isRewindable() const { return true; }
191  bool rewind();
192 
193  void queueCompressedBuffer(byte *buffer, uint32 bufferSize, uint32 unpackedSize);
194  void queuePCM(byte *buffer, uint32 bufferSize);
195 
196  protected:
197  Audio::AudioStream *getAudioStream() const;
198 
199  private:
200  Audio::QueuingAudioStream *_audioStream;
201  AudioInfo _audioInfo;
202  };
203 
204  class SmackerEmptyTrack : public Track {
205  VideoDecoder::Track::TrackType getTrackType() const { return VideoDecoder::Track::kTrackTypeNone; }
206 
207  bool endOfTrack() const { return true; }
208 
209  bool isSeekable() const { return true; }
210  bool seek(const Audio::Timestamp &time) { return true; }
211  };
212 
213 protected:
214  // The FrameTypes section of a Smacker file contains an array of bytes, where
215  // the 8 bits of each byte describe the contents of the corresponding frame.
216  // The highest 7 bits correspond to audio frames (bit 7 is track 6, bit 6 track 5
217  // and so on), so there can be up to 7 different audio tracks. When the lowest bit
218  // (bit 0) is set, it denotes a frame that contains a palette record
219  byte *_frameTypes;
220 
221 private:
222  uint32 _firstFrameStart;
223 };
224 
225 } // End of namespace Video
226 
227 #endif
Definition: video_decoder.h:476
Definition: surface.h:66
Definition: video_decoder.h:664
Definition: pixelformat.h:138
Definition: video_decoder.h:689
Definition: rect.h:144
Definition: timestamp.h:83
Definition: stream.h:745
Definition: smk_decoder.h:75
Definition: rational.h:40
SoundType
Definition: mixer.h:62
Definition: smk_decoder.h:98
Definition: video_decoder.h:52
Definition: smk_decoder.h:160
Definition: bitstream.h:55
Definition: algorithm.h:29
TrackType
Definition: video_decoder.h:484
Definition: bitarray.h:29
Definition: audiostream.h:50
Definition: audiostream.h:370
bool supportsAudioTrackSwitching() const
Definition: smk_decoder.h:91
Definition: avi_frames.h:36
Definition: system.h:37