Ticket #8706: DXAOptimisations

File DXAOptimisations, 8.5 KB (added by SF/robinwatts, 14 years ago)

First version of the DXA optimisations

Line 
1Index: graphics/dxa_player.cpp
2===================================================================
3--- graphics/dxa_player.cpp (revision 27747)
4+++ graphics/dxa_player.cpp (working copy)
5@@ -32,6 +32,24 @@
6 #include <zlib.h>
7 #endif
8
9+static void scaleUpBy2(byte *dst, byte *src, uint16 width, uint16 h) {
10+ uint16 x;
11+
12+ while (h > 0)
13+ {
14+ for (x=width; x>0; x--)
15+ {
16+ register byte v;
17+ v = *src++;
18+ *dst++ = v;
19+ *dst++ = v;
20+ }
21+ memcpy(dst, dst-width*2, width*2);
22+ dst += width*2;
23+ h--;
24+ }
25+}
26+
27 namespace Graphics {
28
29 DXAPlayer::DXAPlayer() {
30@@ -41,7 +59,14 @@
31 _frameBuffer2 = 0;
32 _scaledBuffer = 0;
33 _drawBuffer = 0;
34+ _scaledBuffer2 = 0;
35
36+ _inBuffer = 0;
37+ _inBufferSize = 0;
38+
39+ _decompBuffer = 0;
40+ _decompBufferSize = 0;
41+
42 _width = 0;
43 _height = 0;
44
45@@ -53,6 +78,8 @@
46 _frameTicks = 0;
47
48 _scaleMode = S_NONE;
49+
50+ _scaling = 1;
51 }
52
53 DXAPlayer::~DXAPlayer() {
54@@ -61,13 +88,13 @@
55 int DXAPlayer::getWidth() {
56 if (!_fd)
57 return 0;
58- return _width;
59+ return _width*_scaling;
60 }
61
62 int DXAPlayer::getHeight() {
63 if (!_fd)
64 return 0;
65- return _height;
66+ return _height*_scaling;
67 }
68
69 int DXAPlayer::getCurFrame() {
70@@ -82,6 +109,26 @@
71 return _framesCount;
72 }
73
74+bool DXAPlayer::loadFile(const char *filename, uint16 maxWidth, uint16 maxHeight) {
75+ bool result = loadFile(filename);
76+
77+ if (result)
78+ {
79+ _scaling = MIN(maxWidth/_width, maxHeight/_height);
80+ if (_scaling < 1)
81+ _scaling = 1;
82+ if (_scaling > 2)
83+ _scaling = 2;
84+ if (_scaling >= 2)
85+ {
86+ _scaledBuffer2 = (uint8 *)malloc(_width*_height*_scaling*_scaling);
87+ if (!_scaledBuffer2) {
88+ _scaling = 1;
89+ }
90+ }
91+ }
92+ return result;
93+}
94 bool DXAPlayer::loadFile(const char *filename) {
95 uint32 tag;
96 int32 frameRate;
97@@ -129,6 +176,7 @@
98 debug(2, "flags 0x0%x framesCount %d width %d height %d rate %d ticks %d", flags, _framesCount, _width, _height, _framesPerSec, _frameTicks);
99
100 _frameSize = _width * _height;
101+ _decompBufferSize = _frameSize;
102 _frameBuffer1 = (uint8 *)malloc(_frameSize);
103 _frameBuffer2 = (uint8 *)malloc(_frameSize);
104 if (!_frameBuffer1 || !_frameBuffer2)
105@@ -157,6 +205,9 @@
106 free(_frameBuffer1);
107 free(_frameBuffer2);
108 free(_scaledBuffer);
109+ free(_scaledBuffer2);
110+ free(_inBuffer);
111+ free(_decompBuffer);
112 }
113
114 void DXAPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
115@@ -175,15 +226,11 @@
116
117 void DXAPlayer::decodeZlib(byte *data, int size, int totalSize) {
118 #ifdef USE_ZLIB
119- byte *temp = (byte *)malloc(size);
120- if (temp) {
121- memcpy(temp, data, size);
122-
123 z_stream d_stream;
124 d_stream.zalloc = (alloc_func)0;
125 d_stream.zfree = (free_func)0;
126 d_stream.opaque = (voidpf)0;
127- d_stream.next_in = temp;
128+ d_stream.next_in = _inBuffer;
129 d_stream.avail_in = size;
130 d_stream.total_in = size;
131 d_stream.next_out = data;
132@@ -191,8 +238,6 @@
133 inflateInit(&d_stream);
134 inflate(&d_stream, Z_FINISH);
135 inflateEnd(&d_stream);
136- free(temp);
137- }
138 #endif
139 }
140
141@@ -201,18 +246,24 @@
142
143 void DXAPlayer::decode12(byte *data, int size, int totalSize) {
144 #ifdef USE_ZLIB
145+ if (_decompBuffer == NULL)
146+ {
147+ free(_decompBuffer);
148+ _decompBuffer = (byte *)malloc(_decompBufferSize);
149+ if (_decompBuffer == NULL)
150+ return;
151+ }
152 /* decompress the input data */
153- decodeZlib(data, size, totalSize);
154+ decodeZlib(_decompBuffer, size, _decompBufferSize);
155
156- byte *dat = data;
157- byte *frame2 = (byte *)malloc(totalSize);
158+ byte *dat = _decompBuffer;
159
160- memcpy(frame2, _frameBuffer1, totalSize);
161+ memcpy(_frameBuffer2, _frameBuffer1, totalSize);
162
163 for (int by = 0; by < _height; by += BLOCKH) {
164 for (int bx = 0; bx < _width; bx += BLOCKW) {
165 byte type = *dat++;
166- byte *b2 = frame2 + bx + by * _width;
167+ byte *b2 = _frameBuffer1 + bx + by * _width;
168
169 switch (type) {
170 case 0:
171@@ -276,7 +327,7 @@
172 int my = mbyte & 0x07;
173 if (mbyte & 0x08)
174 my = -my;
175- byte *b1 = _frameBuffer1 + (bx+mx) + (by+my) * _width;
176+ byte *b1 = _frameBuffer2 + (bx+mx) + (by+my) * _width;
177 for (int yc = 0; yc < BLOCKH; yc++) {
178 memcpy(b2, b1, BLOCKW);
179 b1 += _width;
180@@ -291,9 +342,6 @@
181 }
182 }
183 }
184-
185- memcpy(data, frame2, totalSize);
186- free(frame2);
187 #endif
188 }
189
190@@ -301,20 +349,27 @@
191 #ifdef USE_ZLIB
192 uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf;
193
194+ if (_decompBuffer == NULL)
195+ {
196+ free(_decompBuffer);
197+ _decompBuffer = (byte *)malloc(_decompBufferSize);
198+ if (_decompBuffer == NULL)
199+ return;
200+ }
201+
202 /* decompress the input data */
203- decodeZlib(data, size, totalSize);
204+ decodeZlib(_decompBuffer, size, _decompBufferSize);
205
206- uint8 *frame2 = (uint8*)malloc(totalSize);
207- memcpy(frame2, _frameBuffer1, totalSize);
208+ memcpy(_frameBuffer2, _frameBuffer1, totalSize);
209
210 int codeSize = _width * _curHeight / 16;
211 int dataSize, motSize, maskSize;
212
213- dataSize = READ_BE_UINT32(&data[0]);
214- motSize = READ_BE_UINT32(&data[4]);
215- maskSize = READ_BE_UINT32(&data[8]);
216+ dataSize = READ_BE_UINT32(&_decompBuffer[0]);
217+ motSize = READ_BE_UINT32(&_decompBuffer[4]);
218+ maskSize = READ_BE_UINT32(&_decompBuffer[8]);
219
220- codeBuf = &data[12];
221+ codeBuf = &_decompBuffer[12];
222 dataBuf = &codeBuf[codeSize];
223 motBuf = &dataBuf[dataSize];
224 maskBuf = &motBuf[motSize];
225@@ -322,7 +377,7 @@
226 for (int by = 0; by < _curHeight; by += BLOCKH) {
227 for (int bx = 0; bx < _width; bx += BLOCKW) {
228 uint8 type = *codeBuf++;
229- uint8 *b2 = (uint8*)frame2 + bx + by * _width;
230+ uint8 *b2 = (uint8*)_frameBuffer1 + bx + by * _width;
231
232 switch (type) {
233 case 0:
234@@ -373,7 +428,7 @@
235 if (mbyte & 0x08)
236 my = -my;
237
238- uint8 *b1 = (uint8*)_frameBuffer1 + (bx+mx) + (by+my) * _width;
239+ uint8 *b1 = (uint8*)_frameBuffer2 + (bx+mx) + (by+my) * _width;
240 for (int yc = 0; yc < BLOCKH; yc++) {
241 memcpy(b2, b1, BLOCKW);
242 b1 += _width;
243@@ -389,7 +444,7 @@
244
245 for (int subBlock = 0; subBlock < 4; subBlock++) {
246 int sx = bx + subX[subBlock], sy = by + subY[subBlock];
247- b2 = (uint8*)frame2 + sx + sy * _width;
248+ b2 = (uint8*)_frameBuffer1 + sx + sy * _width;
249 switch (subMask & 0xC0) {
250 // 00: skip
251 case 0x00:
252@@ -417,7 +472,7 @@
253 if (mbyte & 0x08)
254 my = -my;
255
256- uint8 *b1 = (uint8*)_frameBuffer1 + (sx+mx) + (sy+my) * _width;
257+ uint8 *b1 = (uint8*)_frameBuffer2 + (sx+mx) + (sy+my) * _width;
258 for (int yc = 0; yc < BLOCKH / 2; yc++) {
259 memcpy(b2, b1, BLOCKW / 2);
260 b1 += _width;
261@@ -476,9 +531,6 @@
262 }
263 }
264 }
265-
266- memcpy(data, frame2, totalSize);
267- free(frame2);
268 #endif
269 }
270
271@@ -498,10 +550,21 @@
272 byte type = _fd->readByte();
273 uint32 size = _fd->readUint32BE();
274
275- _fd->read(_frameBuffer2, size);
276+ if ((_inBuffer == NULL) || (_inBufferSize < size))
277+ {
278+ free(_inBuffer);
279+ _inBuffer = (byte *)malloc(size);
280+ if (_inBuffer == NULL)
281+ return;
282+ _inBufferSize = size;
283+ }
284
285+ _fd->read(_inBuffer, size);
286+
287 switch (type) {
288 case 2:
289+ decodeZlib(_frameBuffer1, size, _frameSize);
290+ break;
291 case 3:
292 decodeZlib(_frameBuffer2, size, _frameSize);
293 break;
294@@ -514,8 +577,9 @@
295 default:
296 error("decodeFrame: Unknown compression type %d", type);
297 }
298+
299+ // RJW: What is type 4 ???
300 if (type == 2 || type == 4 || type == 12 || type == 13) {
301- memcpy(_frameBuffer1, _frameBuffer2, _frameSize);
302 } else {
303 for (int j = 0; j < _curHeight; ++j) {
304 for (int i = 0; i < _width; ++i) {
305@@ -545,6 +609,12 @@
306 _drawBuffer = _frameBuffer1;
307 break;
308 }
309+
310+ if (_scaling == 2) {
311+ /* Scale up here */
312+ scaleUpBy2(_scaledBuffer2, _drawBuffer, _width, _height);
313+ _drawBuffer = _scaledBuffer2;
314 }
315+}
316
317 } // End of namespace Graphics
318Index: graphics/dxa_player.h
319===================================================================
320--- graphics/dxa_player.h (revision 27747)
321+++ graphics/dxa_player.h (working copy)
322@@ -47,6 +47,11 @@
323 byte *_frameBuffer2;
324 byte *_scaledBuffer;
325 byte *_drawBuffer;
326+ byte *_scaledBuffer2;
327+ byte *_inBuffer;
328+ uint32 _inBufferSize;
329+ byte *_decompBuffer;
330+ uint32 _decompBufferSize;
331 uint16 _width;
332 uint16 _height, _curHeight;
333 uint16 _framesCount;
334@@ -56,6 +61,7 @@
335 uint16 _frameSkipped;
336 uint32 _frameTicks;
337 ScaleMode _scaleMode;
338+ uint32 _scaling;
339
340 public:
341 DXAPlayer();
342@@ -94,6 +100,14 @@
343 bool loadFile(const char *filename);
344
345 /**
346+ * Load a DXA encoded video file and setup scaling if required
347+ * @param filename the filename to load
348+ * @param maxWidth the maximum width available to the film
349+ * @param maxHeight the maximum height available to the film
350+ */
351+ bool loadFile(const char *filename, uint16 maxWidth, uint16 maxHeight);
352+
353+ /**
354 * Close a DXA encoded video file
355 */
356 void closeFile();