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 
76 class SmackerDecoder : public VideoDecoder {
77 public:
79  virtual ~SmackerDecoder();
80 
81  virtual bool loadStream(Common::SeekableReadStream *stream);
82  void close();
83  const Graphics::Surface *forceSeekToFrame(uint frame);
84  bool rewind();
85 
86  Common::Rational getFrameRate() const;
87 
88  virtual const Common::Rect *getNextDirtyRect();
89 
90 protected:
91  void readNextPacket();
92  bool supportsAudioTrackSwitching() const { return true; }
93  AudioTrack *getAudioTrack(int index);
94 
95  virtual void handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize);
96 
97  virtual uint32 getSignatureVersion(uint32 signature) const;
98 
100  public:
101  SmackerVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 version);
103 
104  bool isRewindable() const { return true; }
105  bool rewind() { _curFrame = -1; return true; }
106 
107  uint16 getWidth() const;
108  uint16 getHeight() const;
109  Graphics::PixelFormat getPixelFormat() const;
110  int getCurFrame() const { return _curFrame; }
111  int getFrameCount() const { return _frameCount; }
112  const Graphics::Surface *decodeNextFrame() { return _surface; }
113  const byte *getPalette() const { _dirtyPalette = false; return _palette; }
114  bool hasDirtyPalette() const { return _dirtyPalette; }
115 
116  void readTrees(SmackerBitStream &bs, uint32 mMapSize, uint32 mClrSize, uint32 fullSize, uint32 typeSize);
117  void increaseCurFrame() { _curFrame++; }
118  void decodeFrame(SmackerBitStream &bs);
119  void unpackPalette(Common::SeekableReadStream *stream);
120 
121  Common::Rational getFrameRate() const { return _frameRate; }
122 
123  const Common::Rect *getNextDirtyRect();
124 
125  protected:
126  Graphics::Surface *_surface;
127 
128  private:
129  Common::Rational _frameRate;
130  uint32 _flags, _version;
131 
132  byte _palette[3 * 256];
133  mutable bool _dirtyPalette;
134 
135  int _curFrame;
136  uint32 _frameCount;
137 
138  BigHuffmanTree *_MMapTree;
139  BigHuffmanTree *_MClrTree;
140  BigHuffmanTree *_FullTree;
141  BigHuffmanTree *_TypeTree;
142 
143  Common::BitArray _dirtyBlocks;
144  Common::Rect _lastDirtyRect;
145 
146  // Possible runs of blocks
147  static uint getBlockRun(int index) { return (index <= 58) ? index + 1 : 128 << (index - 59); }
148  };
149 
150  virtual SmackerVideoTrack *createVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 version) const;
151 
152  Common::SeekableReadStream *_fileStream;
153 
154  enum AudioCompression {
155  kCompressionNone,
156  kCompressionDPCM,
157  kCompressionRDFT,
158  kCompressionDCT
159  };
160 
161  struct AudioInfo {
162  AudioCompression compression;
163  bool hasAudio;
164  bool is16Bits;
165  bool isStereo;
166  uint32 sampleRate;
167  };
168 
169  struct {
170  uint32 signature;
171  uint32 flags;
172  uint32 audioSize[7];
173  uint32 treesSize;
174  uint32 mMapSize;
175  uint32 mClrSize;
176  uint32 fullSize;
177  uint32 typeSize;
178  AudioInfo audioInfo[7];
179  uint32 dummy;
180  } _header;
181 
182  uint32 *_frameSizes;
183 
184 private:
185 
186  class SmackerAudioTrack : public AudioTrack {
187  public:
188  SmackerAudioTrack(const AudioInfo &audioInfo, Audio::Mixer::SoundType soundType);
189  ~SmackerAudioTrack();
190 
191  bool isRewindable() const { return true; }
192  bool rewind();
193 
194  void queueCompressedBuffer(byte *buffer, uint32 bufferSize, uint32 unpackedSize);
195  void queuePCM(byte *buffer, uint32 bufferSize);
196 
197  protected:
198  Audio::AudioStream *getAudioStream() const;
199 
200  private:
201  Audio::QueuingAudioStream *_audioStream;
202  AudioInfo _audioInfo;
203  };
204 
205  class SmackerEmptyTrack : public Track {
206  VideoDecoder::Track::TrackType getTrackType() const { return VideoDecoder::Track::kTrackTypeNone; }
207 
208  bool endOfTrack() const { return true; }
209 
210  bool isSeekable() const { return true; }
211  bool seek(const Audio::Timestamp &time) { return true; }
212  };
213 
214 protected:
215  // The FrameTypes section of a Smacker file contains an array of bytes, where
216  // the 8 bits of each byte describe the contents of the corresponding frame.
217  // The highest 7 bits correspond to audio frames (bit 7 is track 6, bit 6 track 5
218  // and so on), so there can be up to 7 different audio tracks. When the lowest bit
219  // (bit 0) is set, it denotes a frame that contains a palette record
220  byte *_frameTypes;
221 
222 private:
223  uint32 _firstFrameStart;
224 };
225 
226 } // End of namespace Video
227 
228 #endif
Definition: video_decoder.h:493
Definition: surface.h:67
Definition: video_decoder.h:686
Definition: pixelformat.h:138
Definition: video_decoder.h:711
Definition: rect.h:144
Definition: timestamp.h:83
Definition: stream.h:745
Definition: smk_decoder.h:76
Definition: rational.h:40
SoundType
Definition: mixer.h:62
Definition: smk_decoder.h:99
Definition: video_decoder.h:53
Definition: smk_decoder.h:161
Definition: bitstream.h:55
Definition: algorithm.h:29
TrackType
Definition: video_decoder.h:501
Definition: bitarray.h:29
Definition: audiostream.h:50
Definition: audiostream.h:370
bool supportsAudioTrackSwitching() const
Definition: smk_decoder.h:92
Definition: avi_frames.h:36
Definition: system.h:38