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
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 //
24 // Heavily based on ffmpeg code.
25 //
26 // Copyright (c) 2001 Fabrice Bellard.
27 // First version by Francois Revol revol@free.fr
28 // Seek function by Gael Chardon gael.dev@4now.net
29 //
30 
31 #ifndef COMMON_QUICKTIME_H
32 #define COMMON_QUICKTIME_H
33 
34 #include "common/array.h"
35 #include "common/scummsys.h"
36 #include "common/path.h"
37 #include "common/stream.h"
38 #include "common/rational.h"
39 #include "common/types.h"
40 
41 namespace Common {
42 	class MacResManager;
43 
44 /**
45  * @defgroup common_quicktime Quicktime file parser
46  * @ingroup common
47  *
48  * @brief Parser for QuickTime/MPEG-4 files.
49  *
50  * @details File parser used in engines:
51  *          - groovie
52  *          - mohawk
53  *          - sci
54  * @{
55  */
56 
57 class QuickTimeParser {
58 public:
59 	QuickTimeParser();
60 	virtual ~QuickTimeParser();
61 
62 	/**
63 	 * Load a QuickTime file
64 	 * @param filename	the filename to load
65 	 */
66 	bool parseFile(const Path &filename);
67 
68 	/**
69 	 * Load a QuickTime file from a SeekableReadStream
70 	 * @param stream	the stream to load
71 	 * @param disposeFileHandle whether to delete the stream after use
72 	 */
73 	bool parseStream(SeekableReadStream *stream, DisposeAfterUse::Flag disposeFileHandle = DisposeAfterUse::YES);
74 
75 	/**
76 	 * Close a QuickTime file
77 	 */
78 	void close();
79 
80 	/**
81 	 * Set the beginning offset of the video so we can modify the offsets in the stco
82 	 * atom of videos inside the Mohawk archives
83 	 * @param offset the beginning offset of the video
84 	 */
setChunkBeginOffset(uint32 offset)85 	void setChunkBeginOffset(uint32 offset) { _beginOffset = offset; }
86 
87 	/** Find out if this parser has an open file handle */
isOpen()88 	bool isOpen() const { return _fd != nullptr; }
89 
90 protected:
91 	// This is the file handle from which data is read from. It can be the actual file handle or a decompressed stream.
92 	SeekableReadStream *_fd;
93 
94 	struct TimeToSampleEntry {
95 		int count;
96 		int duration; // media time
97 	};
98 
99 	struct SampleToChunkEntry {
100 		uint32 first;
101 		uint32 count;
102 		uint32 id;
103 	};
104 
105 	struct EditListEntry {
106 		uint32 trackDuration; // movie time
107 		uint32 timeOffset;    // movie time
108 		int32 mediaTime;      // media time
109 		Rational mediaRate;
110 	};
111 
112 	struct Track;
113 
114 	class SampleDesc {
115 	public:
116 		SampleDesc(Track *parentTrack, uint32 codecTag);
117 		virtual ~SampleDesc();
118 
getCodecTag()119 		uint32 getCodecTag() const { return _codecTag; }
120 
121 		SeekableReadStream *_extraData;
122 		byte _objectTypeMP4;
123 
124 	protected:
125 		Track *_parentTrack;
126 		uint32 _codecTag;
127 	};
128 
129 	enum CodecType {
130 		CODEC_TYPE_MOV_OTHER,
131 		CODEC_TYPE_VIDEO,
132 		CODEC_TYPE_AUDIO,
133 		CODEC_TYPE_MIDI
134 	};
135 
136 	struct Track {
137 		Track();
138 		~Track();
139 
140 		uint32 chunkCount;
141 		uint32 *chunkOffsets;
142 		int timeToSampleCount;
143 		TimeToSampleEntry *timeToSample;
144 		uint32 sampleToChunkCount;
145 		SampleToChunkEntry *sampleToChunk;
146 		uint32 sampleSize;
147 		uint32 sampleCount;
148 		uint32 *sampleSizes;
149 		uint32 keyframeCount;
150 		uint32 *keyframes;
151 		int32 timeScale; // media time
152 
153 		uint16 width;
154 		uint16 height;
155 		CodecType codecType;
156 
157 		Array<SampleDesc *> sampleDescs;
158 
159 		Common::Array<EditListEntry> editList;
160 
161 		uint32 frameCount;    // from stts
162 		uint32 duration;      // movie time
163 		uint32 mediaDuration; // media time
164 		Rational scaleFactorX;
165 		Rational scaleFactorY;
166 	};
167 
168 	virtual SampleDesc *readSampleDesc(Track *track, uint32 format, uint32 descSize) = 0;
169 
170 	uint32 _timeScale;      // movie time
171 	uint32 _duration;       // movie time
172 	Rational _scaleFactorX;
173 	Rational _scaleFactorY;
174 	Array<Track *> _tracks;
175 
176 	void init();
177 
178 private:
179 	struct Atom {
180 		uint32 type;
181 		uint32 offset;
182 		uint32 size;
183 	};
184 
185 	struct ParseTable {
186 		int (QuickTimeParser::*func)(Atom atom);
187 		uint32 type;
188 	};
189 
190 	DisposeAfterUse::Flag _disposeFileHandle;
191 	const ParseTable *_parseTable;
192 	uint32 _beginOffset;
193 	MacResManager *_resFork;
194 	bool _foundMOOV;
195 
196 	void initParseTable();
197 
198 	int readDefault(Atom atom);
199 	int readLeaf(Atom atom);
200 	int readELST(Atom atom);
201 	int readHDLR(Atom atom);
202 	int readMDHD(Atom atom);
203 	int readMOOV(Atom atom);
204 	int readMVHD(Atom atom);
205 	int readTKHD(Atom atom);
206 	int readTRAK(Atom atom);
207 	int readSTCO(Atom atom);
208 	int readSTSC(Atom atom);
209 	int readSTSD(Atom atom);
210 	int readSTSS(Atom atom);
211 	int readSTSZ(Atom atom);
212 	int readSTTS(Atom atom);
213 	int readCMOV(Atom atom);
214 	int readWAVE(Atom atom);
215 	int readESDS(Atom atom);
216 	int readSMI(Atom atom);
217 };
218 
219 /** @} */
220 
221 } // End of namespace Common
222 
223 #endif
224