ScummVM API documentation
qt_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//
23// Partially based on ffmpeg code.
24//
25// Copyright (c) 2001 Fabrice Bellard.
26// First version by Francois Revol revol@free.fr
27// Seek function by Gael Chardon gael.dev@4now.net
28//
29
30#ifndef VIDEO_QT_DECODER_H
31#define VIDEO_QT_DECODER_H
32
33#include "audio/decoders/quicktime_intern.h"
34#include "common/keyboard.h"
35#include "common/scummsys.h"
36
37#include "graphics/palette.h"
38#include "graphics/transform_tools.h"
39
40#include "video/video_decoder.h"
41
42namespace Common {
43class Archive;
44class Rational;
45}
46
47namespace Graphics {
48class Cursor;
49struct PixelFormat;
50}
51
52namespace Image {
53class Codec;
54}
55
56namespace Video {
57
67public:
69 virtual ~QuickTimeDecoder();
70
71 bool loadFile(const Common::Path &filename) override;
72 bool loadStream(Common::SeekableReadStream *stream) override;
73 void close() override;
74 uint16 getWidth() const override { return _width; }
75 uint16 getHeight() const override { return _height; }
77 Audio::Timestamp getDuration() const override { return Audio::Timestamp(0, _duration, _timeScale); }
78
79 void enableEditListBoundsCheckQuirk(bool enable) { _enableEditListBoundsCheckQuirk = enable; }
80 Common::String getAliasPath();
81
83 // QTVR stuff
85 void setTargetSize(uint16 w, uint16 h);
86 void setOrigin(int left, int top) { _origin = Common::Point(left, top); }
87
88 void handleMouseMove(int16 x, int16 y);
89 void handleMouseButton(bool isDown, int16 x = -1, int16 y = -1, bool repeat = false);
90 void handleKey(Common::KeyState &state, bool down, bool repeat = false);
91 void handleQuit();
92
93 Common::Point getLastClick() { return _mouseDrag; }
94
95 float getPanAngle() const { return _panAngle; }
96 void setPanAngle(float panAngle);
97 float getTiltAngle() const { return _tiltAngle; }
98 void setTiltAngle(float tiltAngle);
99 float getFOV() const { return _fov; }
100 float getHFOV() const { return _hfov; }
101 bool setFOV(float fov);
102 int getCurrentNodeID() { return _currentSample == -1 ? 0 : _panoTrack->panoSamples[_currentSample].hdr.nodeID; }
103 Common::String getCurrentNodeName();
104
105 int getCurrentRow() { return _nextVideoTrack->getCurFrame() / _nav.columns; }
106 void setCurrentRow(int row);
107 int getCurrentColumn() { return _nextVideoTrack->getCurFrame() % _nav.columns; }
108 void setCurrentColumn(int column);
109
110 int getZoomState() { return _zoomState; }
111
112 const PanoHotSpot *getRolloverHotspot() { return _rolloverHotspot; }
113 int getRolloverHotspotID() { return _rolloverHotspotID; }
114 const PanoHotSpot *getClickedHotspot() { return _clickedHotspot; }
115 int getClickedHotspotID() { return _clickedHotspotID; }
116 Common::Point getPanLoc(int16 x, int16 y);
117 Graphics::FloatPoint getPanAngles(int16 x, int16 y);
118
119 Common::String getHotSpotName(int id);
120 void setClickedHotSpot(int id);
121 const PanoHotSpot *getHotSpotByID(int id);
122 const PanoNavigation *getHotSpotNavByID(int id);
123
124 void nudge(const Common::String &direction);
125
126 bool isVR() const { return _isVR; }
127 QTVRType getQTVRType() const { return _qtvrType; }
128
129 int getWarpMode() const { return _warpMode; }
130 void setWarpMode(int warpMode);
131 float getQuality() const { return _quality; }
132 void setQuality(float quality);
133 Common::String getTransitionMode() const { return _transitionMode == kTransitionModeNormal ? "normal" : "swing"; }
134 void setTransitionMode(Common::String mode);
135 float getTransitionSpeed() const { return _transitionSpeed; }
136 void setTransitionSpeed(float speed);
137 Common::String getUpdateMode() const;
138 void setUpdateMode(Common::String mode);
139
140 void renderHotspots(bool mode);
141
142 struct NodeData {
143 uint32 nodeID;
144
145 float defHPan;
146 float defVPan;
147 float defZoom;
148
149 float minHPan;
150 float minVPan;
151 float maxHPan;
152 float maxVPan;
153 float minZoom;
154
155 Common::String name;
156 };
157
158 NodeData getNodeData(uint32 nodeID);
159 void goToNode(uint32 nodeID);
160
161protected:
162 Common::QuickTimeParser::SampleDesc *readSampleDesc(Common::QuickTimeParser::Track *track, uint32 format, uint32 descSize) override;
163 Common::QuickTimeParser::SampleDesc *readPanoSampleDesc(Common::QuickTimeParser::Track *track, uint32 format, uint32 descSize);
164
165private:
166 void init();
167
168 void updateAudioBuffer();
169
170 void handleObjectMouseMove(int16 x, int16 y);
171 void handleObjectMouseButton(bool isDown, int16 x, int16 y, bool repeat);
172 void handlePanoMouseMove(int16 x, int16 y);
173 void handlePanoMouseButton(bool isDown, int16 x, int16 y, bool repeat);
174
175 void handleObjectKey(Common::KeyState &state, bool down, bool repeat);
176 void handlePanoKey(Common::KeyState &state, bool down, bool repeat);
177
178 void closeQTVR();
179 void updateAngles();
180 void lookupHotspot(int16 x, int16 y);
181 void updateQTVRCursor(int16 x, int16 y);
182 void setCursor(int curId);
183 void cleanupCursors();
184 void computeInteractivityZones();
185
186 uint16 _width, _height;
187 // _origin is the top left corner point of the panorama video being played
188 // by director engine or whichever engine is using QTVR decoder currently
189 // decoder handles swing transitions (in QTVR xtra) internally
190 // Hence, it needs to know where to blit the projected panorama during transition
191 Common::Point _origin;
192
193public:
194 int _currentSample = -1;
195 Common::Point _prevMouse;
196 bool _isMouseButtonDown = false;
197 Common::Point _mouseDrag;
198
199 bool _isKeyDown = false;
200 Common::KeyState _lastKey;
201
202 enum {
203 kZoomNone,
204 kZoomQuestion,
205 kZoomIn,
206 kZoomOut,
207 kZoomLimit,
208
209 kTransitionModeNormal,
210 kTransitionModeSwing,
211
212 kUpdateModeNormal,
213 kUpdateModeUpdateBoth,
214 kUpdateModeOffscreenOnly,
215 kUpdateModeFromOffscreen,
216 kUpdateModeDirectToScreen,
217 };
218
219private:
220 Common::Rect _curBbox;
221
222 int _currentQTVRCursor = -1;
223 Common::Archive *_dataBundle = nullptr;
224 Graphics::Cursor **_cursorCache = nullptr;
225 int _cursorDirMap[256];
226
227 bool _isVR = false;
228
229 uint8 _warpMode = 2; // (2 | 1 | 0) for 2-d, 1-d or no warping
230 float _quality = 0.0f;
231 int _transitionMode = kTransitionModeNormal;
232 float _transitionSpeed = 1.0f;
233 int _updateMode = kUpdateModeNormal;
234
235 float _panAngle = 0.0f;
236 float _tiltAngle = 0.0f;
237 float _fov = 56.0f;
238 float _hfov = 56.0f;
239 int _zoomState = kZoomNone;
240
241 const PanoHotSpot *_rolloverHotspot = nullptr;
242 int _rolloverHotspotID = 0;
243 const PanoHotSpot *_clickedHotspot = nullptr;
244 int _clickedHotspotID = 0;
245 bool _renderHotspots = false;
246
247 Graphics::Surface *_scaledSurface;
248 void scaleSurface(const Graphics::Surface *src, Graphics::Surface *dst,
249 const Common::Rational &scaleFactorX, const Common::Rational &scaleFactorY);
250
251 bool _enableEditListBoundsCheckQuirk;
252
253 bool _cursorDirty;
254 Common::Point _cursorPos;
255
256 class VideoSampleDesc : public Common::QuickTimeParser::SampleDesc {
257 public:
258 VideoSampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag);
259 ~VideoSampleDesc();
260
261 void initCodec();
262
263 // TODO: Make private in the long run
264 uint16 _bitsPerSample;
265 char _codecName[32];
266 uint16 _colorTableId;
267 Graphics::Palette _palette;
268 Image::Codec *_videoCodec;
269 };
270
271 // The AudioTrackHandler is currently just a wrapper around some
272 // QuickTimeDecoder functions.
273 class AudioTrackHandler : public SeekableAudioTrack {
274 public:
275 AudioTrackHandler(QuickTimeDecoder *decoder, QuickTimeAudioTrack *audioTrack);
276
277 void updateBuffer();
278
279 protected:
280 Audio::SeekableAudioStream *getSeekableAudioStream() const override;
281
282 private:
283 QuickTimeDecoder *_decoder;
284 QuickTimeAudioTrack *_audioTrack;
285 };
286
287 class PanoSampleDesc : public Common::QuickTimeParser::SampleDesc {
288 public:
289 PanoSampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag);
290 ~PanoSampleDesc();
291
292 int16 _majorVersion; // must be zero, also observed to be 1
293 int16 _minorVersion; // must be zero, also observed to be 1
294
295 int32 _sceneTrackID; // ID of video track that contains panoramic scene
296 int32 _loResSceneTrackID; // ID of video track that contains low res panoramic scene
297 byte _reserved3[4 * 6]; // must be zero
298 int32 _hotSpotTrackID; // ID of video track that contains hotspot image
299 byte _reserved4[4 * 9]; // must be zero
300
301 float _hPanStart; // horizontal pan range start angle (e.g. 0)
302 float _hPanEnd; // horizontal pan range end angle (e.g. 360)
303 float _vPanTop; // vertical pan range top angle (e.g. 42.5)
304 float _vPanBottom; // vertical pan range bottom angle (e.g. -42.5)
305 float _minimumZoom; // minimum zoom angle (e.g. 5; use 0 for default)
306 float _maximumZoom; // maximum zoom angle (e.g. 65; use 0 for default)
307
308 // info for the highest res version of scene track
309 uint32 _sceneSizeX; // pixel width of the panorama (e.g. 768)
310 uint32 _sceneSizeY; // pixel height of the panorama (e.g. 2496)
311 uint32 _numFrames; // number of diced frames (e.g. 24)
312 int16 _reserved5; // must be zero
313 int16 _sceneNumFramesX; // diced frames wide (e.g. 1)
314 int16 _sceneNumFramesY; // diced frames high (e.g. 24)
315 int16 _sceneColorDepth; // bit depth of the scene track (e.g. 32)
316
317 // info for the highest rest version of hotSpot track
318 int32 _hotSpotSizeX; // pixel width of the hot spot panorama (e.g. 768)
319 int32 _hotSpotSizeY; // pixel height of the hot spot panorama (e.g. 2496)
320 int16 _reserved6; // must be zero
321 int16 _hotSpotNumFramesX; // diced frames wide (e.g. 1)
322 int16 _hotSpotNumFramesY; // diced frames high (e.g. 24)
323 int16 _hotSpotColorDepth; // must be 8
324 };
325
326 // The VideoTrackHandler is the bridge between the time of playback
327 // and the media for the given track. It calculates when to start
328 // tracks and at what rate to play the media using the edit list.
329 class VideoTrackHandler : public VideoTrack {
330 public:
331 VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent);
332 ~VideoTrackHandler();
333
334 bool endOfTrack() const override;
335 bool isSeekable() const override { return true; }
336 bool seek(const Audio::Timestamp &time) override;
337 Audio::Timestamp getDuration() const override;
338
339 uint16 getWidth() const override;
340 uint16 getHeight() const override;
341 Graphics::PixelFormat getPixelFormat() const override;
342 bool setOutputPixelFormat(const Graphics::PixelFormat &format) override;
343 int getCurFrame() const override { return _curFrame; }
344 void setCurFrame(int32 curFrame) { _curFrame = curFrame; }
345 int getFrameCount() const override;
346 uint32 getNextFrameStartTime() const override; // milliseconds
347 const Graphics::Surface *decodeNextFrame() override;
348 Audio::Timestamp getFrameTime(uint frame) const override;
349 const byte *getPalette() const override;
350 bool hasDirtyPalette() const override { return _dirtyPalette; }
351 bool setReverse(bool reverse) override;
352 bool isReversed() const override { return _reversed; }
353 bool canDither() const override;
354 void setDither(const byte *palette) override;
355
356 Common::Rational getScaledWidth() const;
357 Common::Rational getScaledHeight() const;
358
359 const Graphics::Surface *bufferNextFrame();
360
361 private:
362 QuickTimeDecoder *_decoder;
364 uint32 _curEdit;
365 int32 _curFrame;
366 int32 _delayedFrameToBufferTo;
367 uint32 _nextFrameStartTime; // media time
368 Graphics::Surface *_scaledSurface;
369 int32 _durationOverride; // media time
370 const byte *_curPalette;
371 mutable bool _dirtyPalette;
372 bool _reversed;
373
374 Common::SeekableReadStream *getNextFramePacket(uint32 &descId);
375 uint32 getCurFrameDuration(); // media time
376 uint32 findKeyFrame(uint32 frame) const;
377 bool isEmptyEdit() const;
378 void enterNewEditListEntry(bool bufferFrames, bool intializingTrack = false);
379 uint32 getRateAdjustedFrameTime() const; // media time
380 uint32 getCurEditTimeOffset() const; // media time
381 uint32 getCurEditTrackDuration() const; // media time
382 bool atLastEdit() const;
383 bool endOfCurEdit() const;
384 void checkEditListBounds();
385 };
386
387 class PanoTrackHandler : public VideoTrack {
388 public:
389 PanoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent);
390 ~PanoTrackHandler();
391
392 bool endOfTrack() const override { return false; }
393 uint16 getWidth() const override;
394 uint16 getHeight() const override;
395 int getCurFrame() const override { return 1; }
396 uint32 getNextFrameStartTime() const override { return 0; }
397 Graphics::PixelFormat getPixelFormat() const override;
398 const Graphics::Surface *decodeNextFrame() override;
399
400 Common::Rational getScaledWidth() const;
401 Common::Rational getScaledHeight() const;
402
403 void initPanorama();
404 void constructPanorama();
405 Graphics::Surface *constructMosaic(VideoTrackHandler *track, uint w, uint h, Common::String fname);
406
407 Common::Point projectPoint(int16 x, int16 y);
408
409 void setDirty() { _dirty = true; }
410
411 private:
412 QuickTimeDecoder *_decoder;
414
415 void projectPanorama(uint8 scaleFactor, float fov, float hfov, float panAngle, float tiltAngle);
416 void swingTransitionHandler();
417 void boxAverage(Graphics::Surface *sourceSurface, uint8 scaleFactor);
418 Graphics::Surface* upscalePanorama(Graphics::Surface *sourceSurface, int8 level);
419
420 const Graphics::Surface *bufferNextFrame();
421
422 public:
423 Graphics::Surface *_constructedPano;
424 Graphics::Surface *_upscaledConstructedPano;
425 Graphics::Surface *_constructedHotspots;
426 Graphics::Surface *_projectedPano;
427 Graphics::Surface *_planarProjection;
428
429 // Current upscale level (0 or 1 or 2) of _upscaledConstructedPanorama compared to _constructedPano
430 // level 0 means that constructedPano was just contructed and hasn't been upscaled yet
431 // level 1 means only upscaled height (2x pixels)
432 // level 2 means upscaled height and width (4x pixels)
433 uint8 _upscaleLevel = 0;
434
435 // Defining these to make the swing transition happen
436 // which requires storing the previous point during every change in FOV, Pan Angle and Tilt Angle
437 // If swing transition is called, this will be the start point of the transition
438 float _currentFOV = 0;
439 float _currentHFOV = 0;
440 float _currentPanAngle = 0;
441 float _currentTiltAngle = 0;
442
443 private:
444 bool _isPanoConstructed;
445 bool _dirty;
446 };
447};
448
449} // End of namespace Video
450
451#endif
Definition: quicktime_intern.h:47
Definition: audiostream.h:212
Definition: timestamp.h:83
Definition: archive.h:141
Definition: path.h:52
Definition: quicktime.h:134
Definition: rational.h:40
Definition: stream.h:745
Definition: str.h:59
Definition: cursor.h:42
Simple class for handling a palette data.
Definition: palette.h:61
Definition: codec.h:57
Definition: qt_decoder.h:66
bool loadFile(const Common::Path &filename) override
Audio::Timestamp getDuration() const override
Definition: qt_decoder.h:77
void close() override
uint16 getWidth() const override
Definition: qt_decoder.h:74
uint16 getHeight() const override
Definition: qt_decoder.h:75
bool loadStream(Common::SeekableReadStream *stream) override
const Graphics::Surface * decodeNextFrame() override
virtual int getCurFrame() const =0
Definition: video_decoder.h:53
bool seek(const Audio::Timestamp &time)
Graphics::PixelFormat getPixelFormat() const
bool hasDirtyPalette() const
Definition: video_decoder.h:337
bool setReverse(bool reverse)
const byte * getPalette()
virtual bool isSeekable() const
bool setOutputPixelFormat(const Graphics::PixelFormat &format)
int getCurFrame() const
uint32 getFrameCount() const
Definition: algorithm.h:29
Definition: formatinfo.h:28
Definition: keyboard.h:294
Definition: rect.h:144
Definition: quicktime.h:300
Definition: rect.h:536
Definition: atari-cursor.h:35
Definition: transform_tools.h:32
Definition: pixelformat.h:138
Definition: surface.h:67
Definition: qt_decoder.h:142