ScummVM API documentation
bink_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
22// Based on eos' Bink decoder which is in turn
23// based quite heavily on the Bink decoder found in FFmpeg.
24// Many thanks to Kostya Shishkov for doing the hard work.
25
26#include "common/scummsys.h"
27
28#ifdef USE_BINK
29
30#ifndef VIDEO_BINK_DECODER_H
31#define VIDEO_BINK_DECODER_H
32
33#include "common/array.h"
34#include "common/bitstream.h"
35#include "common/rational.h"
36
37#include "video/video_decoder.h"
38
39#include "graphics/surface.h"
40
41namespace Audio {
42class AudioStream;
43class QueuingAudioStream;
44}
45
46namespace Common {
47class SeekableReadStream;
48template <class BITSTREAM>
49class Huffman;
50}
51
52namespace Math {
53class RDFT;
54class DCT;
55}
56
57namespace Graphics {
58struct Surface;
59}
60
61namespace Video {
62
69class BinkDecoder : public VideoDecoder {
70public:
71 BinkDecoder();
72 ~BinkDecoder();
73
74 bool loadStream(Common::SeekableReadStream *stream) override;
75 void close() override;
76
77 Common::Rational getFrameRate();
78
79protected:
80 void readNextPacket() override;
81 bool supportsAudioTrackSwitching() const override { return true; }
82 AudioTrack *getAudioTrack(int index) override;
83 bool seekIntern(const Audio::Timestamp &time) override;
84 uint32 findKeyFrame(uint32 frame) const;
85
86private:
87 static const int kAudioChannelsMax = 2;
88 static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11);
89
90 enum AudioCodec {
91 kAudioCodecDCT,
92 kAudioCodecRDFT
93 };
94
96 struct AudioInfo {
97 uint16 flags;
98
99 uint32 sampleRate;
100 uint8 channels;
101
102 uint32 outSampleRate;
103 uint8 outChannels;
104
105 AudioCodec codec;
106
107 uint32 sampleCount;
108
110
111 bool first;
112
113 uint32 frameLen;
114 uint32 overlapLen;
115
116 uint32 blockSize;
117
118 uint32 bandCount;
119 uint32 *bands;
120
121 float root;
122
123 float coeffs[16 * kAudioBlockSizeMax];
124 int16 prevCoeffs[kAudioBlockSizeMax];
125
126 float *coeffsPtr[kAudioChannelsMax];
127
128 Math::RDFT *rdft;
129 Math::DCT *dct;
130
131 AudioInfo();
132 ~AudioInfo();
133 };
134
136 struct VideoFrame {
137 bool keyFrame;
138
139 uint32 offset;
140 uint32 size;
141
143
144 VideoFrame();
145 ~VideoFrame();
146 };
147
148 class BinkVideoTrack : public FixedRateVideoTrack {
149 public:
150 BinkVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id);
151 ~BinkVideoTrack();
152
153 uint16 getWidth() const override { return _width; }
154 uint16 getHeight() const override{ return _height; }
155 Graphics::PixelFormat getPixelFormat() const override { return _pixelFormat; }
156 bool setOutputPixelFormat(const Graphics::PixelFormat &format) override {
157 if (format.bytesPerPixel != 2 && format.bytesPerPixel != 4)
158 return false;
159 _pixelFormat = format;
160 return true;
161 }
162
163 int getCurFrame() const override { return _curFrame; }
164 int getFrameCount() const override { return _frameCount; }
165 const Graphics::Surface *decodeNextFrame() override { return _surface; }
166 bool isSeekable() const override{ return true; }
167 bool seek(const Audio::Timestamp &time) override { return true; }
168 bool rewind() override;
169 void setCurFrame(uint32 frame) { _curFrame = frame; }
170
172 void decodePacket(VideoFrame &frame);
173
174 Common::Rational getFrameRate() const override { return _frameRate; }
175
176 private:
178 struct DecodeContext {
179 VideoFrame *video;
180
181 uint32 planeIdx;
182
183 uint32 blockX;
184 uint32 blockY;
185
186 byte *dest;
187 byte *prev;
188
189 byte *destStart, *destEnd;
190 byte *prevStart, *prevEnd;
191
192 uint32 pitch;
193
194 int coordMap[64];
195 int coordScaledMap1[64];
196 int coordScaledMap2[64];
197 int coordScaledMap3[64];
198 int coordScaledMap4[64];
199 };
200
202 enum Source {
203 kSourceBlockTypes = 0,
204 kSourceSubBlockTypes ,
205 kSourceColors ,
206 kSourcePattern ,
207 kSourceXOff ,
208 kSourceYOff ,
209 kSourceIntraDC ,
210 kSourceInterDC ,
211 kSourceRun ,
212
213 kSourceMAX
214 };
215
217 enum BlockType {
218 kBlockSkip = 0,
219 kBlockScaled ,
220 kBlockMotion ,
221 kBlockRun ,
222 kBlockResidue ,
223 kBlockIntra ,
224 kBlockFill ,
225 kBlockInter ,
226 kBlockPattern ,
227 kBlockRaw
228 };
229
231 struct Huffman {
232 int index;
233 byte symbols[16];
234 };
235
237 struct Bundle {
238 int countLengths[2];
239 int countLength;
240
241 Huffman huffman;
242
243 byte *data;
244 byte *dataEnd;
245
246 byte *curDec;
247 byte *curPtr;
248 };
249
250 int _curFrame;
251 int _frameCount;
252
253 Graphics::Surface *_surface;
254 Graphics::PixelFormat _pixelFormat;
255 uint16 _width;
256 uint16 _height;
257 int _surfaceWidth;
258 int _surfaceHeight;
259
260 uint32 _id;
261
262 bool _hasAlpha;
263 bool _swapPlanes;
264
265 Common::Rational _frameRate;
266
267 Bundle _bundles[kSourceMAX];
268
270
272 Huffman _colHighHuffman[16];
274 int _colLastVal;
275
276 uint32 _yBlockWidth;
277 uint32 _yBlockHeight;
278 uint32 _uvBlockWidth;
279 uint32 _uvBlockHeight;
280
281 byte *_curPlanes[4];
282 byte *_oldPlanes[4];
283
285 void initBundles();
287 void deinitBundles();
288
290 void initHuffman();
291
293 void decodePlane(VideoFrame &video, int planeIdx, bool isChroma);
294
296 void readBundle(VideoFrame &video, Source source);
297
299 void readHuffman(VideoFrame &video, Huffman &huffman);
301 void mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size);
302
304 byte getHuffmanSymbol(VideoFrame &video, Huffman &huffman);
305
307 int32 getBundleValue(Source source);
309 uint32 readBundleCount(VideoFrame &video, Bundle &bundle);
310
311 // Handle the block types
312 void blockSkip (DecodeContext &ctx);
313 void blockScaledSkip (DecodeContext &ctx);
314 void blockScaledRun (DecodeContext &ctx);
315 void blockScaledIntra (DecodeContext &ctx);
316 void blockScaledFill (DecodeContext &ctx);
317 void blockScaledPattern(DecodeContext &ctx);
318 void blockScaledRaw (DecodeContext &ctx);
319 void blockScaled (DecodeContext &ctx);
320 void blockMotion (DecodeContext &ctx);
321 void blockRun (DecodeContext &ctx);
322 void blockResidue (DecodeContext &ctx);
323 void blockIntra (DecodeContext &ctx);
324 void blockFill (DecodeContext &ctx);
325 void blockInter (DecodeContext &ctx);
326 void blockPattern (DecodeContext &ctx);
327 void blockRaw (DecodeContext &ctx);
328
329 // Read the bundles
330 void readRuns (VideoFrame &video, Bundle &bundle);
331 void readMotionValues(VideoFrame &video, Bundle &bundle);
332 void readBlockTypes (VideoFrame &video, Bundle &bundle);
333 void readPatterns (VideoFrame &video, Bundle &bundle);
334 void readColors (VideoFrame &video, Bundle &bundle);
335 template<int startBits, bool hasSign>
336 void readDCS (VideoFrame &video, Bundle &bundle);
337 void readDCTCoeffs (VideoFrame &video, int32 *block, bool isIntra);
338 void readResidue (VideoFrame &video, int16 *block, int masksCount);
339
340 // Bink video IDCT
341 void IDCT(int32 *block);
342 void IDCTPut(DecodeContext &ctx, int32 *block);
343 void IDCTAdd(DecodeContext &ctx, int32 *block);
344 };
345
346 class BinkAudioTrack : public AudioTrack {
347 public:
348 BinkAudioTrack(AudioInfo &audio, Audio::Mixer::SoundType soundType);
349 ~BinkAudioTrack();
350
352 void decodePacket();
353
354 bool seek(const Audio::Timestamp &time) override;
355 bool isSeekable() const override { return true; }
356 void skipSamples(const Audio::Timestamp &length);
357 int getRate();
358
359 protected:
360 Audio::AudioStream *getAudioStream() const override;
361
362 private:
363 AudioInfo *_audioInfo;
364 Audio::QueuingAudioStream *_audioStream;
365
366 float getFloat();
367
369 void audioBlock(int16 *out);
371 void audioBlockDCT();
373 void audioBlockRDFT();
374
375 void readAudioCoeffs(float *coeffs);
376
377 static void floatToInt16Interleave(int16 *dst, const float **src, uint32 length, uint8 channels);
378 };
379
381
382 Common::Array<AudioInfo> _audioTracks;
384
385 void initAudioTrack(AudioInfo &audio);
386};
387
388} // End of namespace Video
389
390#endif // VIDEO_BINK_DECODER_H
391
392#endif // USE_BINK
Definition: audiostream.h:50
SoundType
Definition: mixer.h:73
Definition: audiostream.h:370
Definition: timestamp.h:83
Definition: array.h:52
Definition: bitstream.h:55
Definition: huffman.h:60
Definition: rational.h:40
Definition: stream.h:745
Definition: system.h:39
Definition: algorithm.h:29
Definition: formatinfo.h:28
Definition: pixelformat.h:138
Definition: surface.h:67