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