1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | //TESTED_COMPONENT=src/multimedia |
30 | |
31 | #include <QtTest/QtTest> |
32 | |
33 | #include <qvideoframe.h> |
34 | #include "private/qmemoryvideobuffer_p.h" |
35 | #include <QtGui/QImage> |
36 | #include <QtCore/QPointer> |
37 | #include <QtMultimedia/private/qtmultimedia-config_p.h> |
38 | |
39 | // Adds an enum, and the stringized version |
40 | #define ADD_ENUM_TEST(x) \ |
41 | QTest::newRow(#x) \ |
42 | << QVideoFrame::x \ |
43 | << QString(QLatin1String(#x)); |
44 | |
45 | |
46 | class tst_QVideoFrame : public QObject |
47 | { |
48 | Q_OBJECT |
49 | public: |
50 | tst_QVideoFrame(); |
51 | ~tst_QVideoFrame(); |
52 | |
53 | public slots: |
54 | void initTestCase(); |
55 | void cleanupTestCase(); |
56 | void init(); |
57 | void cleanup(); |
58 | |
59 | private slots: |
60 | void create_data(); |
61 | void create(); |
62 | void createInvalid_data(); |
63 | void createInvalid(); |
64 | void createFromBuffer_data(); |
65 | void createFromBuffer(); |
66 | void createFromImage_data(); |
67 | void createFromImage(); |
68 | void createFromIncompatibleImage(); |
69 | void createNull(); |
70 | void destructor(); |
71 | void copy_data(); |
72 | void copy(); |
73 | void assign_data(); |
74 | void assign(); |
75 | void map_data(); |
76 | void map(); |
77 | void mapImage_data(); |
78 | void mapImage(); |
79 | void mapPlanes_data(); |
80 | void mapPlanes(); |
81 | void imageDetach(); |
82 | void formatConversion_data(); |
83 | void formatConversion(); |
84 | |
85 | void metadata(); |
86 | |
87 | void isMapped(); |
88 | void isReadable(); |
89 | void isWritable(); |
90 | |
91 | void image_data(); |
92 | void image(); |
93 | |
94 | void emptyData(); |
95 | }; |
96 | |
97 | Q_DECLARE_METATYPE(QImage::Format) |
98 | |
99 | class QtTestVideoBuffer : public QObject, public QAbstractVideoBuffer |
100 | { |
101 | Q_OBJECT |
102 | public: |
103 | QtTestVideoBuffer() |
104 | : QAbstractVideoBuffer(NoHandle) {} |
105 | explicit QtTestVideoBuffer(QAbstractVideoBuffer::HandleType type) |
106 | : QAbstractVideoBuffer(type) {} |
107 | |
108 | MapMode mapMode() const { return NotMapped; } |
109 | |
110 | uchar *map(MapMode, int *, int *) { return 0; } |
111 | void unmap() {} |
112 | }; |
113 | |
114 | class QtTestPlanarVideoBuffer : public QAbstractPlanarVideoBuffer |
115 | { |
116 | public: |
117 | QtTestPlanarVideoBuffer() |
118 | : QAbstractPlanarVideoBuffer(NoHandle), m_planeCount(0), m_mapMode(NotMapped) {} |
119 | explicit QtTestPlanarVideoBuffer(QAbstractVideoBuffer::HandleType type) |
120 | : QAbstractPlanarVideoBuffer(type), m_planeCount(0), m_mapMode(NotMapped) {} |
121 | |
122 | MapMode mapMode() const { return m_mapMode; } |
123 | |
124 | int map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]) { |
125 | m_mapMode = mode; |
126 | if (numBytes) |
127 | *numBytes = m_numBytes; |
128 | for (int i = 0; i < m_planeCount; ++i) { |
129 | data[i] = m_data[i]; |
130 | bytesPerLine[i] = m_bytesPerLine[i]; |
131 | } |
132 | return m_planeCount; |
133 | } |
134 | void unmap() { m_mapMode = NotMapped; } |
135 | |
136 | uchar *m_data[4]; |
137 | int m_bytesPerLine[4]; |
138 | int m_planeCount; |
139 | int m_numBytes; |
140 | MapMode m_mapMode; |
141 | }; |
142 | |
143 | tst_QVideoFrame::tst_QVideoFrame() |
144 | { |
145 | } |
146 | |
147 | tst_QVideoFrame::~tst_QVideoFrame() |
148 | { |
149 | } |
150 | |
151 | void tst_QVideoFrame::initTestCase() |
152 | { |
153 | } |
154 | |
155 | void tst_QVideoFrame::cleanupTestCase() |
156 | { |
157 | } |
158 | |
159 | void tst_QVideoFrame::init() |
160 | { |
161 | } |
162 | |
163 | void tst_QVideoFrame::cleanup() |
164 | { |
165 | } |
166 | |
167 | void tst_QVideoFrame::create_data() |
168 | { |
169 | QTest::addColumn<QSize>(name: "size" ); |
170 | QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat" ); |
171 | QTest::addColumn<int>(name: "bytes" ); |
172 | QTest::addColumn<int>(name: "bytesPerLine" ); |
173 | |
174 | QTest::newRow(dataTag: "64x64 ARGB32" ) |
175 | << QSize(64, 64) |
176 | << QVideoFrame::Format_ARGB32 |
177 | << 16384 |
178 | << 256; |
179 | QTest::newRow(dataTag: "32x256 YUV420P" ) |
180 | << QSize(32, 256) |
181 | << QVideoFrame::Format_YUV420P |
182 | << 13288 |
183 | << 32; |
184 | } |
185 | |
186 | void tst_QVideoFrame::create() |
187 | { |
188 | QFETCH(QSize, size); |
189 | QFETCH(QVideoFrame::PixelFormat, pixelFormat); |
190 | QFETCH(int, bytes); |
191 | QFETCH(int, bytesPerLine); |
192 | |
193 | QVideoFrame frame(bytes, size, bytesPerLine, pixelFormat); |
194 | |
195 | QVERIFY(frame.isValid()); |
196 | QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle); |
197 | QCOMPARE(frame.handle(), QVariant()); |
198 | QCOMPARE(frame.pixelFormat(), pixelFormat); |
199 | QCOMPARE(frame.size(), size); |
200 | QCOMPARE(frame.width(), size.width()); |
201 | QCOMPARE(frame.height(), size.height()); |
202 | QCOMPARE(frame.fieldType(), QVideoFrame::ProgressiveFrame); |
203 | QCOMPARE(frame.startTime(), qint64(-1)); |
204 | QCOMPARE(frame.endTime(), qint64(-1)); |
205 | } |
206 | |
207 | void tst_QVideoFrame::createInvalid_data() |
208 | { |
209 | QTest::addColumn<QSize>(name: "size" ); |
210 | QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat" ); |
211 | QTest::addColumn<int>(name: "bytes" ); |
212 | QTest::addColumn<int>(name: "bytesPerLine" ); |
213 | |
214 | QTest::newRow(dataTag: "64x64 ARGB32 0 size" ) |
215 | << QSize(64, 64) |
216 | << QVideoFrame::Format_ARGB32 |
217 | << 0 |
218 | << 45; |
219 | QTest::newRow(dataTag: "32x256 YUV420P negative size" ) |
220 | << QSize(32, 256) |
221 | << QVideoFrame::Format_YUV420P |
222 | << -13288 |
223 | << 32; |
224 | } |
225 | |
226 | void tst_QVideoFrame::createInvalid() |
227 | { |
228 | QFETCH(QSize, size); |
229 | QFETCH(QVideoFrame::PixelFormat, pixelFormat); |
230 | QFETCH(int, bytes); |
231 | QFETCH(int, bytesPerLine); |
232 | |
233 | QVideoFrame frame(bytes, size, bytesPerLine, pixelFormat); |
234 | |
235 | QVERIFY(!frame.isValid()); |
236 | QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle); |
237 | QCOMPARE(frame.handle(), QVariant()); |
238 | QCOMPARE(frame.pixelFormat(), pixelFormat); |
239 | QCOMPARE(frame.size(), size); |
240 | QCOMPARE(frame.width(), size.width()); |
241 | QCOMPARE(frame.height(), size.height()); |
242 | QCOMPARE(frame.fieldType(), QVideoFrame::ProgressiveFrame); |
243 | QCOMPARE(frame.startTime(), qint64(-1)); |
244 | QCOMPARE(frame.endTime(), qint64(-1)); |
245 | } |
246 | |
247 | void tst_QVideoFrame::createFromBuffer_data() |
248 | { |
249 | QTest::addColumn<QAbstractVideoBuffer::HandleType>(name: "handleType" ); |
250 | QTest::addColumn<QSize>(name: "size" ); |
251 | QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat" ); |
252 | |
253 | QTest::newRow(dataTag: "64x64 ARGB32 no handle" ) |
254 | << QAbstractVideoBuffer::NoHandle |
255 | << QSize(64, 64) |
256 | << QVideoFrame::Format_ARGB32; |
257 | QTest::newRow(dataTag: "64x64 ARGB32 gl handle" ) |
258 | << QAbstractVideoBuffer::GLTextureHandle |
259 | << QSize(64, 64) |
260 | << QVideoFrame::Format_ARGB32; |
261 | QTest::newRow(dataTag: "64x64 ARGB32 user handle" ) |
262 | << QAbstractVideoBuffer::UserHandle |
263 | << QSize(64, 64) |
264 | << QVideoFrame::Format_ARGB32; |
265 | } |
266 | |
267 | void tst_QVideoFrame::createFromBuffer() |
268 | { |
269 | QFETCH(QAbstractVideoBuffer::HandleType, handleType); |
270 | QFETCH(QSize, size); |
271 | QFETCH(QVideoFrame::PixelFormat, pixelFormat); |
272 | |
273 | QVideoFrame frame(new QtTestVideoBuffer(handleType), size, pixelFormat); |
274 | |
275 | QVERIFY(frame.isValid()); |
276 | QCOMPARE(frame.handleType(), handleType); |
277 | QCOMPARE(frame.pixelFormat(), pixelFormat); |
278 | QCOMPARE(frame.size(), size); |
279 | QCOMPARE(frame.width(), size.width()); |
280 | QCOMPARE(frame.height(), size.height()); |
281 | QCOMPARE(frame.fieldType(), QVideoFrame::ProgressiveFrame); |
282 | QCOMPARE(frame.startTime(), qint64(-1)); |
283 | QCOMPARE(frame.endTime(), qint64(-1)); |
284 | } |
285 | |
286 | void tst_QVideoFrame::createFromImage_data() |
287 | { |
288 | QTest::addColumn<QSize>(name: "size" ); |
289 | QTest::addColumn<QImage::Format>(name: "imageFormat" ); |
290 | QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat" ); |
291 | |
292 | QTest::newRow(dataTag: "64x64 RGB32" ) |
293 | << QSize(64, 64) |
294 | << QImage::Format_RGB32 |
295 | << QVideoFrame::Format_RGB32; |
296 | QTest::newRow(dataTag: "12x45 RGB16" ) |
297 | << QSize(12, 45) |
298 | << QImage::Format_RGB16 |
299 | << QVideoFrame::Format_RGB565; |
300 | QTest::newRow(dataTag: "19x46 ARGB32_Premultiplied" ) |
301 | << QSize(19, 46) |
302 | << QImage::Format_ARGB32_Premultiplied |
303 | << QVideoFrame::Format_ARGB32_Premultiplied; |
304 | } |
305 | |
306 | void tst_QVideoFrame::createFromImage() |
307 | { |
308 | QFETCH(QSize, size); |
309 | QFETCH(QImage::Format, imageFormat); |
310 | QFETCH(QVideoFrame::PixelFormat, pixelFormat); |
311 | |
312 | const QImage image(size.width(), size.height(), imageFormat); |
313 | |
314 | QVideoFrame frame(image); |
315 | |
316 | QVERIFY(frame.isValid()); |
317 | QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle); |
318 | QCOMPARE(frame.pixelFormat(), pixelFormat); |
319 | QCOMPARE(frame.size(), size); |
320 | QCOMPARE(frame.width(), size.width()); |
321 | QCOMPARE(frame.height(), size.height()); |
322 | QCOMPARE(frame.fieldType(), QVideoFrame::ProgressiveFrame); |
323 | QCOMPARE(frame.startTime(), qint64(-1)); |
324 | QCOMPARE(frame.endTime(), qint64(-1)); |
325 | } |
326 | |
327 | void tst_QVideoFrame::createFromIncompatibleImage() |
328 | { |
329 | const QImage image(64, 64, QImage::Format_Mono); |
330 | |
331 | QVideoFrame frame(image); |
332 | |
333 | QVERIFY(!frame.isValid()); |
334 | QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle); |
335 | QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_Invalid); |
336 | QCOMPARE(frame.size(), QSize(64, 64)); |
337 | QCOMPARE(frame.width(), 64); |
338 | QCOMPARE(frame.height(), 64); |
339 | QCOMPARE(frame.fieldType(), QVideoFrame::ProgressiveFrame); |
340 | QCOMPARE(frame.startTime(), qint64(-1)); |
341 | QCOMPARE(frame.endTime(), qint64(-1)); |
342 | } |
343 | |
344 | void tst_QVideoFrame::createNull() |
345 | { |
346 | // Default ctor |
347 | { |
348 | QVideoFrame frame; |
349 | |
350 | QVERIFY(!frame.isValid()); |
351 | QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle); |
352 | QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_Invalid); |
353 | QCOMPARE(frame.size(), QSize()); |
354 | QCOMPARE(frame.width(), -1); |
355 | QCOMPARE(frame.height(), -1); |
356 | QCOMPARE(frame.fieldType(), QVideoFrame::ProgressiveFrame); |
357 | QCOMPARE(frame.startTime(), qint64(-1)); |
358 | QCOMPARE(frame.endTime(), qint64(-1)); |
359 | QCOMPARE(frame.mapMode(), QAbstractVideoBuffer::NotMapped); |
360 | QVERIFY(!frame.map(QAbstractVideoBuffer::ReadOnly)); |
361 | QVERIFY(!frame.map(QAbstractVideoBuffer::ReadWrite)); |
362 | QVERIFY(!frame.map(QAbstractVideoBuffer::WriteOnly)); |
363 | QCOMPARE(frame.isMapped(), false); |
364 | frame.unmap(); // Shouldn't crash |
365 | QCOMPARE(frame.isReadable(), false); |
366 | QCOMPARE(frame.isWritable(), false); |
367 | } |
368 | |
369 | // Null buffer (shouldn't crash) |
370 | { |
371 | QVideoFrame frame(0, QSize(1024,768), QVideoFrame::Format_ARGB32); |
372 | QVERIFY(!frame.isValid()); |
373 | QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle); |
374 | QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_ARGB32); |
375 | QCOMPARE(frame.size(), QSize(1024, 768)); |
376 | QCOMPARE(frame.width(), 1024); |
377 | QCOMPARE(frame.height(), 768); |
378 | QCOMPARE(frame.fieldType(), QVideoFrame::ProgressiveFrame); |
379 | QCOMPARE(frame.startTime(), qint64(-1)); |
380 | QCOMPARE(frame.endTime(), qint64(-1)); |
381 | QCOMPARE(frame.mapMode(), QAbstractVideoBuffer::NotMapped); |
382 | QVERIFY(!frame.map(QAbstractVideoBuffer::ReadOnly)); |
383 | QVERIFY(!frame.map(QAbstractVideoBuffer::ReadWrite)); |
384 | QVERIFY(!frame.map(QAbstractVideoBuffer::WriteOnly)); |
385 | QCOMPARE(frame.isMapped(), false); |
386 | frame.unmap(); // Shouldn't crash |
387 | QCOMPARE(frame.isReadable(), false); |
388 | QCOMPARE(frame.isWritable(), false); |
389 | } |
390 | } |
391 | |
392 | void tst_QVideoFrame::destructor() |
393 | { |
394 | QPointer<QtTestVideoBuffer> buffer = new QtTestVideoBuffer; |
395 | |
396 | { |
397 | QVideoFrame frame(buffer, QSize(4, 1), QVideoFrame::Format_ARGB32); |
398 | } |
399 | |
400 | QVERIFY(buffer.isNull()); |
401 | } |
402 | |
403 | void tst_QVideoFrame::copy_data() |
404 | { |
405 | QTest::addColumn<QAbstractVideoBuffer::HandleType>(name: "handleType" ); |
406 | QTest::addColumn<QSize>(name: "size" ); |
407 | QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat" ); |
408 | QTest::addColumn<QVideoFrame::FieldType>(name: "fieldType" ); |
409 | QTest::addColumn<qint64>(name: "startTime" ); |
410 | QTest::addColumn<qint64>(name: "endTime" ); |
411 | |
412 | QTest::newRow(dataTag: "64x64 ARGB32" ) |
413 | << QAbstractVideoBuffer::GLTextureHandle |
414 | << QSize(64, 64) |
415 | << QVideoFrame::Format_ARGB32 |
416 | << QVideoFrame::TopField |
417 | << qint64(63641740) |
418 | << qint64(63641954); |
419 | QTest::newRow(dataTag: "64x64 ARGB32" ) |
420 | << QAbstractVideoBuffer::GLTextureHandle |
421 | << QSize(64, 64) |
422 | << QVideoFrame::Format_ARGB32 |
423 | << QVideoFrame::BottomField |
424 | << qint64(63641740) |
425 | << qint64(63641954); |
426 | QTest::newRow(dataTag: "32x256 YUV420P" ) |
427 | << QAbstractVideoBuffer::UserHandle |
428 | << QSize(32, 256) |
429 | << QVideoFrame::Format_YUV420P |
430 | << QVideoFrame::InterlacedFrame |
431 | << qint64(12345) |
432 | << qint64(12389); |
433 | QTest::newRow(dataTag: "1052x756 ARGB32" ) |
434 | << QAbstractVideoBuffer::NoHandle |
435 | << QSize(1052, 756) |
436 | << QVideoFrame::Format_ARGB32 |
437 | << QVideoFrame::ProgressiveFrame |
438 | << qint64(12345) |
439 | << qint64(12389); |
440 | QTest::newRow(dataTag: "32x256 YUV420P" ) |
441 | << QAbstractVideoBuffer::UserHandle |
442 | << QSize(32, 256) |
443 | << QVideoFrame::Format_YUV420P |
444 | << QVideoFrame::InterlacedFrame |
445 | << qint64(12345) |
446 | << qint64(12389); |
447 | } |
448 | |
449 | void tst_QVideoFrame::copy() |
450 | { |
451 | QFETCH(QAbstractVideoBuffer::HandleType, handleType); |
452 | QFETCH(QSize, size); |
453 | QFETCH(QVideoFrame::PixelFormat, pixelFormat); |
454 | QFETCH(QVideoFrame::FieldType, fieldType); |
455 | QFETCH(qint64, startTime); |
456 | QFETCH(qint64, endTime); |
457 | |
458 | QPointer<QtTestVideoBuffer> buffer = new QtTestVideoBuffer(handleType); |
459 | |
460 | { |
461 | QVideoFrame frame(buffer, size, pixelFormat); |
462 | frame.setFieldType(QVideoFrame::FieldType(fieldType)); |
463 | frame.setStartTime(startTime); |
464 | frame.setEndTime(endTime); |
465 | |
466 | QVERIFY(frame.isValid()); |
467 | QCOMPARE(frame.handleType(), handleType); |
468 | QCOMPARE(frame.pixelFormat(), pixelFormat); |
469 | QCOMPARE(frame.size(), size); |
470 | QCOMPARE(frame.width(), size.width()); |
471 | QCOMPARE(frame.height(), size.height()); |
472 | QCOMPARE(frame.fieldType(), fieldType); |
473 | QCOMPARE(frame.startTime(), startTime); |
474 | QCOMPARE(frame.endTime(), endTime); |
475 | |
476 | { |
477 | QVideoFrame otherFrame(frame); |
478 | |
479 | QVERIFY(!buffer.isNull()); |
480 | |
481 | QVERIFY(otherFrame.isValid()); |
482 | QCOMPARE(otherFrame.handleType(), handleType); |
483 | QCOMPARE(otherFrame.pixelFormat(), pixelFormat); |
484 | QCOMPARE(otherFrame.size(), size); |
485 | QCOMPARE(otherFrame.width(), size.width()); |
486 | QCOMPARE(otherFrame.height(), size.height()); |
487 | QCOMPARE(otherFrame.fieldType(), fieldType); |
488 | QCOMPARE(otherFrame.startTime(), startTime); |
489 | QCOMPARE(otherFrame.endTime(), endTime); |
490 | |
491 | otherFrame.setEndTime(-1); |
492 | |
493 | QVERIFY(!buffer.isNull()); |
494 | |
495 | QVERIFY(otherFrame.isValid()); |
496 | QCOMPARE(otherFrame.handleType(), handleType); |
497 | QCOMPARE(otherFrame.pixelFormat(), pixelFormat); |
498 | QCOMPARE(otherFrame.size(), size); |
499 | QCOMPARE(otherFrame.width(), size.width()); |
500 | QCOMPARE(otherFrame.height(), size.height()); |
501 | QCOMPARE(otherFrame.fieldType(), fieldType); |
502 | QCOMPARE(otherFrame.startTime(), startTime); |
503 | QCOMPARE(otherFrame.endTime(), qint64(-1)); |
504 | } |
505 | |
506 | QVERIFY(!buffer.isNull()); |
507 | |
508 | QVERIFY(frame.isValid()); |
509 | QCOMPARE(frame.handleType(), handleType); |
510 | QCOMPARE(frame.pixelFormat(), pixelFormat); |
511 | QCOMPARE(frame.size(), size); |
512 | QCOMPARE(frame.width(), size.width()); |
513 | QCOMPARE(frame.height(), size.height()); |
514 | QCOMPARE(frame.fieldType(), fieldType); |
515 | QCOMPARE(frame.startTime(), startTime); |
516 | QCOMPARE(frame.endTime(), qint64(-1)); // Explicitly shared. |
517 | } |
518 | |
519 | QVERIFY(buffer.isNull()); |
520 | } |
521 | |
522 | void tst_QVideoFrame::assign_data() |
523 | { |
524 | QTest::addColumn<QAbstractVideoBuffer::HandleType>(name: "handleType" ); |
525 | QTest::addColumn<QSize>(name: "size" ); |
526 | QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat" ); |
527 | QTest::addColumn<QVideoFrame::FieldType>(name: "fieldType" ); |
528 | QTest::addColumn<qint64>(name: "startTime" ); |
529 | QTest::addColumn<qint64>(name: "endTime" ); |
530 | |
531 | QTest::newRow(dataTag: "64x64 ARGB32" ) |
532 | << QAbstractVideoBuffer::GLTextureHandle |
533 | << QSize(64, 64) |
534 | << QVideoFrame::Format_ARGB32 |
535 | << QVideoFrame::TopField |
536 | << qint64(63641740) |
537 | << qint64(63641954); |
538 | QTest::newRow(dataTag: "32x256 YUV420P" ) |
539 | << QAbstractVideoBuffer::UserHandle |
540 | << QSize(32, 256) |
541 | << QVideoFrame::Format_YUV420P |
542 | << QVideoFrame::InterlacedFrame |
543 | << qint64(12345) |
544 | << qint64(12389); |
545 | } |
546 | |
547 | void tst_QVideoFrame::assign() |
548 | { |
549 | QFETCH(QAbstractVideoBuffer::HandleType, handleType); |
550 | QFETCH(QSize, size); |
551 | QFETCH(QVideoFrame::PixelFormat, pixelFormat); |
552 | QFETCH(QVideoFrame::FieldType, fieldType); |
553 | QFETCH(qint64, startTime); |
554 | QFETCH(qint64, endTime); |
555 | |
556 | QPointer<QtTestVideoBuffer> buffer = new QtTestVideoBuffer(handleType); |
557 | |
558 | QVideoFrame frame; |
559 | { |
560 | QVideoFrame otherFrame(buffer, size, pixelFormat); |
561 | otherFrame.setFieldType(fieldType); |
562 | otherFrame.setStartTime(startTime); |
563 | otherFrame.setEndTime(endTime); |
564 | |
565 | frame = otherFrame; |
566 | |
567 | QVERIFY(!buffer.isNull()); |
568 | |
569 | QVERIFY(otherFrame.isValid()); |
570 | QCOMPARE(otherFrame.handleType(), handleType); |
571 | QCOMPARE(otherFrame.pixelFormat(), pixelFormat); |
572 | QCOMPARE(otherFrame.size(), size); |
573 | QCOMPARE(otherFrame.width(), size.width()); |
574 | QCOMPARE(otherFrame.height(), size.height()); |
575 | QCOMPARE(otherFrame.fieldType(), fieldType); |
576 | QCOMPARE(otherFrame.startTime(), startTime); |
577 | QCOMPARE(otherFrame.endTime(), endTime); |
578 | |
579 | otherFrame.setStartTime(-1); |
580 | |
581 | QVERIFY(!buffer.isNull()); |
582 | |
583 | QVERIFY(otherFrame.isValid()); |
584 | QCOMPARE(otherFrame.handleType(), handleType); |
585 | QCOMPARE(otherFrame.pixelFormat(), pixelFormat); |
586 | QCOMPARE(otherFrame.size(), size); |
587 | QCOMPARE(otherFrame.width(), size.width()); |
588 | QCOMPARE(otherFrame.height(), size.height()); |
589 | QCOMPARE(otherFrame.fieldType(), fieldType); |
590 | QCOMPARE(otherFrame.startTime(), qint64(-1)); |
591 | QCOMPARE(otherFrame.endTime(), endTime); |
592 | } |
593 | |
594 | QVERIFY(!buffer.isNull()); |
595 | |
596 | QVERIFY(frame.isValid()); |
597 | QCOMPARE(frame.handleType(), handleType); |
598 | QCOMPARE(frame.pixelFormat(), pixelFormat); |
599 | QCOMPARE(frame.size(), size); |
600 | QCOMPARE(frame.width(), size.width()); |
601 | QCOMPARE(frame.height(), size.height()); |
602 | QCOMPARE(frame.fieldType(), fieldType); |
603 | QCOMPARE(frame.startTime(), qint64(-1)); |
604 | QCOMPARE(frame.endTime(), endTime); |
605 | |
606 | frame = QVideoFrame(); |
607 | |
608 | QVERIFY(buffer.isNull()); |
609 | |
610 | QVERIFY(!frame.isValid()); |
611 | QCOMPARE(frame.handleType(), QAbstractVideoBuffer::NoHandle); |
612 | QCOMPARE(frame.pixelFormat(), QVideoFrame::Format_Invalid); |
613 | QCOMPARE(frame.size(), QSize()); |
614 | QCOMPARE(frame.width(), -1); |
615 | QCOMPARE(frame.height(), -1); |
616 | QCOMPARE(frame.fieldType(), QVideoFrame::ProgressiveFrame); |
617 | QCOMPARE(frame.startTime(), qint64(-1)); |
618 | QCOMPARE(frame.endTime(), qint64(-1)); |
619 | } |
620 | |
621 | void tst_QVideoFrame::map_data() |
622 | { |
623 | QTest::addColumn<QSize>(name: "size" ); |
624 | QTest::addColumn<int>(name: "mappedBytes" ); |
625 | QTest::addColumn<int>(name: "bytesPerLine" ); |
626 | QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat" ); |
627 | QTest::addColumn<QAbstractVideoBuffer::MapMode>(name: "mode" ); |
628 | |
629 | QTest::newRow(dataTag: "read-only" ) |
630 | << QSize(64, 64) |
631 | << 16384 |
632 | << 256 |
633 | << QVideoFrame::Format_ARGB32 |
634 | << QAbstractVideoBuffer::ReadOnly; |
635 | |
636 | QTest::newRow(dataTag: "write-only" ) |
637 | << QSize(64, 64) |
638 | << 16384 |
639 | << 256 |
640 | << QVideoFrame::Format_ARGB32 |
641 | << QAbstractVideoBuffer::WriteOnly; |
642 | |
643 | QTest::newRow(dataTag: "read-write" ) |
644 | << QSize(64, 64) |
645 | << 16384 |
646 | << 256 |
647 | << QVideoFrame::Format_ARGB32 |
648 | << QAbstractVideoBuffer::ReadWrite; |
649 | } |
650 | |
651 | void tst_QVideoFrame::map() |
652 | { |
653 | QFETCH(QSize, size); |
654 | QFETCH(int, mappedBytes); |
655 | QFETCH(int, bytesPerLine); |
656 | QFETCH(QVideoFrame::PixelFormat, pixelFormat); |
657 | QFETCH(QAbstractVideoBuffer::MapMode, mode); |
658 | |
659 | QVideoFrame frame(mappedBytes, size, bytesPerLine, pixelFormat); |
660 | |
661 | QVERIFY(!frame.bits()); |
662 | QCOMPARE(frame.mappedBytes(), 0); |
663 | QCOMPARE(frame.bytesPerLine(), 0); |
664 | QCOMPARE(frame.mapMode(), QAbstractVideoBuffer::NotMapped); |
665 | |
666 | QVERIFY(frame.map(mode)); |
667 | |
668 | // Mapping multiple times is allowed in ReadOnly mode |
669 | if (mode == QAbstractVideoBuffer::ReadOnly) { |
670 | const uchar *bits = frame.bits(); |
671 | |
672 | QVERIFY(frame.map(QAbstractVideoBuffer::ReadOnly)); |
673 | QVERIFY(frame.isMapped()); |
674 | QCOMPARE(frame.bits(), bits); |
675 | |
676 | frame.unmap(); |
677 | //frame should still be mapped after the first nested unmap |
678 | QVERIFY(frame.isMapped()); |
679 | QCOMPARE(frame.bits(), bits); |
680 | |
681 | //re-mapping in Write or ReadWrite modes should fail |
682 | QVERIFY(!frame.map(QAbstractVideoBuffer::WriteOnly)); |
683 | QVERIFY(!frame.map(QAbstractVideoBuffer::ReadWrite)); |
684 | } else { |
685 | // Mapping twice in ReadWrite or WriteOnly modes should fail, but leave it mapped (and the mode is ignored) |
686 | QVERIFY(!frame.map(mode)); |
687 | QVERIFY(!frame.map(QAbstractVideoBuffer::ReadOnly)); |
688 | } |
689 | |
690 | QVERIFY(frame.bits()); |
691 | QCOMPARE(frame.mappedBytes(), mappedBytes); |
692 | QCOMPARE(frame.bytesPerLine(), bytesPerLine); |
693 | QCOMPARE(frame.mapMode(), mode); |
694 | |
695 | frame.unmap(); |
696 | |
697 | QVERIFY(!frame.bits()); |
698 | QCOMPARE(frame.mappedBytes(), 0); |
699 | QCOMPARE(frame.bytesPerLine(), 0); |
700 | QCOMPARE(frame.mapMode(), QAbstractVideoBuffer::NotMapped); |
701 | } |
702 | |
703 | void tst_QVideoFrame::mapImage_data() |
704 | { |
705 | QTest::addColumn<QSize>(name: "size" ); |
706 | QTest::addColumn<QImage::Format>(name: "format" ); |
707 | QTest::addColumn<QAbstractVideoBuffer::MapMode>(name: "mode" ); |
708 | |
709 | QTest::newRow(dataTag: "read-only" ) |
710 | << QSize(64, 64) |
711 | << QImage::Format_ARGB32 |
712 | << QAbstractVideoBuffer::ReadOnly; |
713 | |
714 | QTest::newRow(dataTag: "write-only" ) |
715 | << QSize(15, 106) |
716 | << QImage::Format_RGB32 |
717 | << QAbstractVideoBuffer::WriteOnly; |
718 | |
719 | QTest::newRow(dataTag: "read-write" ) |
720 | << QSize(23, 111) |
721 | << QImage::Format_RGB16 |
722 | << QAbstractVideoBuffer::ReadWrite; |
723 | } |
724 | |
725 | void tst_QVideoFrame::mapImage() |
726 | { |
727 | QFETCH(QSize, size); |
728 | QFETCH(QImage::Format, format); |
729 | QFETCH(QAbstractVideoBuffer::MapMode, mode); |
730 | |
731 | QImage image(size.width(), size.height(), format); |
732 | |
733 | QVideoFrame frame(image); |
734 | |
735 | QVERIFY(!frame.bits()); |
736 | QCOMPARE(frame.mappedBytes(), 0); |
737 | QCOMPARE(frame.bytesPerLine(), 0); |
738 | QCOMPARE(frame.mapMode(), QAbstractVideoBuffer::NotMapped); |
739 | |
740 | QVERIFY(frame.map(mode)); |
741 | |
742 | QVERIFY(frame.bits()); |
743 | QCOMPARE(qsizetype(frame.mappedBytes()), image.sizeInBytes()); |
744 | QCOMPARE(frame.bytesPerLine(), image.bytesPerLine()); |
745 | QCOMPARE(frame.mapMode(), mode); |
746 | |
747 | frame.unmap(); |
748 | |
749 | QVERIFY(!frame.bits()); |
750 | QCOMPARE(frame.mappedBytes(), 0); |
751 | QCOMPARE(frame.bytesPerLine(), 0); |
752 | QCOMPARE(frame.mapMode(), QAbstractVideoBuffer::NotMapped); |
753 | } |
754 | |
755 | void tst_QVideoFrame::mapPlanes_data() |
756 | { |
757 | QTest::addColumn<QVideoFrame>(name: "frame" ); |
758 | QTest::addColumn<QList<int> >(name: "strides" ); |
759 | QTest::addColumn<QList<int> >(name: "offsets" ); |
760 | |
761 | static uchar bufferData[1024]; |
762 | |
763 | QtTestPlanarVideoBuffer *planarBuffer = new QtTestPlanarVideoBuffer; |
764 | planarBuffer->m_data[0] = bufferData; |
765 | planarBuffer->m_data[1] = bufferData + 512; |
766 | planarBuffer->m_data[2] = bufferData + 765; |
767 | planarBuffer->m_bytesPerLine[0] = 64; |
768 | planarBuffer->m_bytesPerLine[1] = 36; |
769 | planarBuffer->m_bytesPerLine[2] = 36; |
770 | planarBuffer->m_planeCount = 3; |
771 | planarBuffer->m_numBytes = sizeof(bufferData); |
772 | |
773 | QTest::newRow(dataTag: "Planar" ) |
774 | << QVideoFrame(planarBuffer, QSize(64, 64), QVideoFrame::Format_YUV420P) |
775 | << (QList<int>() << 64 << 36 << 36) |
776 | << (QList<int>() << 512 << 765); |
777 | QTest::newRow(dataTag: "Format_YUV420P" ) |
778 | << QVideoFrame(8096, QSize(60, 64), 64, QVideoFrame::Format_YUV420P) |
779 | << (QList<int>() << 64 << 62 << 62) |
780 | << (QList<int>() << 4096 << 6080); |
781 | QTest::newRow(dataTag: "Format_YV12" ) |
782 | << QVideoFrame(8096, QSize(60, 64), 64, QVideoFrame::Format_YV12) |
783 | << (QList<int>() << 64 << 62 << 62) |
784 | << (QList<int>() << 4096 << 6080); |
785 | QTest::newRow(dataTag: "Format_NV12" ) |
786 | << QVideoFrame(8096, QSize(60, 64), 64, QVideoFrame::Format_NV12) |
787 | << (QList<int>() << 64 << 64) |
788 | << (QList<int>() << 4096); |
789 | QTest::newRow(dataTag: "Format_NV21" ) |
790 | << QVideoFrame(8096, QSize(60, 64), 64, QVideoFrame::Format_NV21) |
791 | << (QList<int>() << 64 << 64) |
792 | << (QList<int>() << 4096); |
793 | QTest::newRow(dataTag: "Format_IMC2" ) |
794 | << QVideoFrame(8096, QSize(60, 64), 64, QVideoFrame::Format_IMC2) |
795 | << (QList<int>() << 64 << 64) |
796 | << (QList<int>() << 4096); |
797 | QTest::newRow(dataTag: "Format_IMC4" ) |
798 | << QVideoFrame(8096, QSize(60, 64), 64, QVideoFrame::Format_IMC4) |
799 | << (QList<int>() << 64 << 64) |
800 | << (QList<int>() << 4096); |
801 | QTest::newRow(dataTag: "Format_IMC1" ) |
802 | << QVideoFrame(8096, QSize(60, 64), 64, QVideoFrame::Format_IMC1) |
803 | << (QList<int>() << 64 << 64 << 64) |
804 | << (QList<int>() << 4096 << 6144); |
805 | QTest::newRow(dataTag: "Format_IMC3" ) |
806 | << QVideoFrame(8096, QSize(60, 64), 64, QVideoFrame::Format_IMC3) |
807 | << (QList<int>() << 64 << 64 << 64) |
808 | << (QList<int>() << 4096 << 6144); |
809 | QTest::newRow(dataTag: "Format_ARGB32" ) |
810 | << QVideoFrame(8096, QSize(60, 64), 256, QVideoFrame::Format_ARGB32) |
811 | << (QList<int>() << 256) |
812 | << (QList<int>()); |
813 | } |
814 | |
815 | void tst_QVideoFrame::mapPlanes() |
816 | { |
817 | QFETCH(QVideoFrame, frame); |
818 | QFETCH(QList<int>, strides); |
819 | QFETCH(QList<int>, offsets); |
820 | |
821 | QCOMPARE(strides.count(), offsets.count() + 1); |
822 | |
823 | QCOMPARE(frame.map(QAbstractVideoBuffer::ReadOnly), true); |
824 | QCOMPARE(frame.planeCount(), strides.count()); |
825 | |
826 | QVERIFY(strides.count() > 0); |
827 | QCOMPARE(frame.bytesPerLine(0), strides.at(0)); |
828 | QVERIFY(frame.bits(0)); |
829 | |
830 | if (strides.count() > 1) { |
831 | QCOMPARE(frame.bytesPerLine(1), strides.at(1)); |
832 | QCOMPARE(int(frame.bits(1) - frame.bits(0)), offsets.at(0)); |
833 | } |
834 | if (strides.count() > 2) { |
835 | QCOMPARE(frame.bytesPerLine(2), strides.at(2)); |
836 | QCOMPARE(int(frame.bits(2) - frame.bits(0)), offsets.at(1)); |
837 | } |
838 | if (strides.count() > 3) { |
839 | QCOMPARE(frame.bytesPerLine(3), strides.at(3)); |
840 | QCOMPARE(int(frame.bits(3) - frame.bits(0)), offsets.at(0)); |
841 | } |
842 | |
843 | frame.unmap(); |
844 | } |
845 | |
846 | void tst_QVideoFrame::imageDetach() |
847 | { |
848 | const uint red = qRgb(r: 255, g: 0, b: 0); |
849 | const uint blue = qRgb(r: 0, g: 0, b: 255); |
850 | |
851 | QImage image(8, 8, QImage::Format_RGB32); |
852 | |
853 | image.fill(pixel: red); |
854 | QCOMPARE(image.pixel(4, 4), red); |
855 | |
856 | QVideoFrame frame(image); |
857 | |
858 | QVERIFY(frame.map(QAbstractVideoBuffer::ReadWrite)); |
859 | |
860 | QImage frameImage(frame.bits(), 8, 8, frame.bytesPerLine(), QImage::Format_RGB32); |
861 | |
862 | QCOMPARE(frameImage.pixel(4, 4), red); |
863 | |
864 | frameImage.fill(pixel: blue); |
865 | QCOMPARE(frameImage.pixel(4, 4), blue); |
866 | |
867 | // Original image has detached and is therefore unchanged. |
868 | QCOMPARE(image.pixel(4, 4), red); |
869 | } |
870 | |
871 | void tst_QVideoFrame::formatConversion_data() |
872 | { |
873 | QTest::addColumn<QImage::Format>(name: "imageFormat" ); |
874 | QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat" ); |
875 | |
876 | QTest::newRow(dataTag: "QImage::Format_RGB32 | QVideoFrame::Format_RGB32" ) |
877 | << QImage::Format_RGB32 |
878 | << QVideoFrame::Format_RGB32; |
879 | QTest::newRow(dataTag: "QImage::Format_ARGB32 | QVideoFrame::Format_ARGB32" ) |
880 | << QImage::Format_ARGB32 |
881 | << QVideoFrame::Format_ARGB32; |
882 | QTest::newRow(dataTag: "QImage::Format_ARGB32_Premultiplied | QVideoFrame::Format_ARGB32_Premultiplied" ) |
883 | << QImage::Format_ARGB32_Premultiplied |
884 | << QVideoFrame::Format_ARGB32_Premultiplied; |
885 | QTest::newRow(dataTag: "QImage::Format_RGB16 | QVideoFrame::Format_RGB565" ) |
886 | << QImage::Format_RGB16 |
887 | << QVideoFrame::Format_RGB565; |
888 | QTest::newRow(dataTag: "QImage::Format_ARGB8565_Premultiplied | QVideoFrame::Format_ARGB8565_Premultiplied" ) |
889 | << QImage::Format_ARGB8565_Premultiplied |
890 | << QVideoFrame::Format_ARGB8565_Premultiplied; |
891 | QTest::newRow(dataTag: "QImage::Format_RGB555 | QVideoFrame::Format_RGB555" ) |
892 | << QImage::Format_RGB555 |
893 | << QVideoFrame::Format_RGB555; |
894 | QTest::newRow(dataTag: "QImage::Format_RGB888 | QVideoFrame::Format_RGB24" ) |
895 | << QImage::Format_RGB888 |
896 | << QVideoFrame::Format_RGB24; |
897 | |
898 | QTest::newRow(dataTag: "QImage::Format_MonoLSB" ) |
899 | << QImage::Format_MonoLSB |
900 | << QVideoFrame::Format_Invalid; |
901 | QTest::newRow(dataTag: "QImage::Format_Indexed8" ) |
902 | << QImage::Format_Indexed8 |
903 | << QVideoFrame::Format_Invalid; |
904 | QTest::newRow(dataTag: "QImage::Format_ARGB6666_Premultiplied" ) |
905 | << QImage::Format_ARGB6666_Premultiplied |
906 | << QVideoFrame::Format_Invalid; |
907 | QTest::newRow(dataTag: "QImage::Format_ARGB8555_Premultiplied" ) |
908 | << QImage::Format_ARGB8555_Premultiplied |
909 | << QVideoFrame::Format_Invalid; |
910 | QTest::newRow(dataTag: "QImage::Format_RGB666" ) |
911 | << QImage::Format_RGB666 |
912 | << QVideoFrame::Format_Invalid; |
913 | QTest::newRow(dataTag: "QImage::Format_RGB444" ) |
914 | << QImage::Format_RGB444 |
915 | << QVideoFrame::Format_Invalid; |
916 | QTest::newRow(dataTag: "QImage::Format_ARGB4444_Premultiplied" ) |
917 | << QImage::Format_ARGB4444_Premultiplied |
918 | << QVideoFrame::Format_Invalid; |
919 | |
920 | QTest::newRow(dataTag: "QVideoFrame::Format_BGRA32" ) |
921 | << QImage::Format_Invalid |
922 | << QVideoFrame::Format_BGRA32; |
923 | QTest::newRow(dataTag: "QVideoFrame::Format_BGRA32_Premultiplied" ) |
924 | << QImage::Format_Invalid |
925 | << QVideoFrame::Format_BGRA32_Premultiplied; |
926 | QTest::newRow(dataTag: "QVideoFrame::Format_BGR32" ) |
927 | << QImage::Format_Invalid |
928 | << QVideoFrame::Format_BGR32; |
929 | QTest::newRow(dataTag: "QVideoFrame::Format_BGR24" ) |
930 | << QImage::Format_Invalid |
931 | << QVideoFrame::Format_BGR24; |
932 | QTest::newRow(dataTag: "QVideoFrame::Format_BGR565" ) |
933 | << QImage::Format_Invalid |
934 | << QVideoFrame::Format_BGR565; |
935 | QTest::newRow(dataTag: "QVideoFrame::Format_BGR555" ) |
936 | << QImage::Format_Invalid |
937 | << QVideoFrame::Format_BGR555; |
938 | QTest::newRow(dataTag: "QVideoFrame::Format_BGRA5658_Premultiplied" ) |
939 | << QImage::Format_Invalid |
940 | << QVideoFrame::Format_BGRA5658_Premultiplied; |
941 | QTest::newRow(dataTag: "QVideoFrame::Format_AYUV444" ) |
942 | << QImage::Format_Invalid |
943 | << QVideoFrame::Format_AYUV444; |
944 | QTest::newRow(dataTag: "QVideoFrame::Format_AYUV444_Premultiplied" ) |
945 | << QImage::Format_Invalid |
946 | << QVideoFrame::Format_AYUV444_Premultiplied; |
947 | QTest::newRow(dataTag: "QVideoFrame::Format_YUV444" ) |
948 | << QImage::Format_Invalid |
949 | << QVideoFrame::Format_YUV444; |
950 | QTest::newRow(dataTag: "QVideoFrame::Format_YUV420P" ) |
951 | << QImage::Format_Invalid |
952 | << QVideoFrame::Format_YUV420P; |
953 | QTest::newRow(dataTag: "QVideoFrame::Format_YV12" ) |
954 | << QImage::Format_Invalid |
955 | << QVideoFrame::Format_YV12; |
956 | QTest::newRow(dataTag: "QVideoFrame::Format_UYVY" ) |
957 | << QImage::Format_Invalid |
958 | << QVideoFrame::Format_UYVY; |
959 | QTest::newRow(dataTag: "QVideoFrame::Format_YUYV" ) |
960 | << QImage::Format_Invalid |
961 | << QVideoFrame::Format_YUYV; |
962 | QTest::newRow(dataTag: "QVideoFrame::Format_NV12" ) |
963 | << QImage::Format_Invalid |
964 | << QVideoFrame::Format_NV12; |
965 | QTest::newRow(dataTag: "QVideoFrame::Format_NV21" ) |
966 | << QImage::Format_Invalid |
967 | << QVideoFrame::Format_NV21; |
968 | QTest::newRow(dataTag: "QVideoFrame::Format_IMC1" ) |
969 | << QImage::Format_Invalid |
970 | << QVideoFrame::Format_IMC1; |
971 | QTest::newRow(dataTag: "QVideoFrame::Format_IMC2" ) |
972 | << QImage::Format_Invalid |
973 | << QVideoFrame::Format_IMC2; |
974 | QTest::newRow(dataTag: "QVideoFrame::Format_IMC3" ) |
975 | << QImage::Format_Invalid |
976 | << QVideoFrame::Format_IMC3; |
977 | QTest::newRow(dataTag: "QVideoFrame::Format_IMC4" ) |
978 | << QImage::Format_Invalid |
979 | << QVideoFrame::Format_IMC4; |
980 | QTest::newRow(dataTag: "QVideoFrame::Format_Y8" ) |
981 | << QImage::Format_Invalid |
982 | << QVideoFrame::Format_Y8; |
983 | QTest::newRow(dataTag: "QVideoFrame::Format_Y16" ) |
984 | << QImage::Format_Invalid |
985 | << QVideoFrame::Format_Y16; |
986 | QTest::newRow(dataTag: "QVideoFrame::Format_Jpeg" ) |
987 | << QImage::Format_Invalid |
988 | << QVideoFrame::Format_Jpeg; |
989 | QTest::newRow(dataTag: "QVideoFrame::Format_CameraRaw" ) |
990 | << QImage::Format_Invalid |
991 | << QVideoFrame::Format_CameraRaw; |
992 | QTest::newRow(dataTag: "QVideoFrame::Format_AdobeDng" ) |
993 | << QImage::Format_Invalid |
994 | << QVideoFrame::Format_AdobeDng; |
995 | QTest::newRow(dataTag: "QVideoFrame::Format_User" ) |
996 | << QImage::Format_Invalid |
997 | << QVideoFrame::Format_User; |
998 | QTest::newRow(dataTag: "QVideoFrame::Format_User + 1" ) |
999 | << QImage::Format_Invalid |
1000 | << QVideoFrame::PixelFormat(QVideoFrame::Format_User + 1); |
1001 | } |
1002 | |
1003 | void tst_QVideoFrame::formatConversion() |
1004 | { |
1005 | QFETCH(QImage::Format, imageFormat); |
1006 | QFETCH(QVideoFrame::PixelFormat, pixelFormat); |
1007 | |
1008 | QCOMPARE(QVideoFrame::pixelFormatFromImageFormat(imageFormat) == pixelFormat, |
1009 | imageFormat != QImage::Format_Invalid); |
1010 | |
1011 | QCOMPARE(QVideoFrame::imageFormatFromPixelFormat(pixelFormat) == imageFormat, |
1012 | pixelFormat != QVideoFrame::Format_Invalid); |
1013 | } |
1014 | |
1015 | void tst_QVideoFrame::metadata() |
1016 | { |
1017 | // Simple metadata test |
1018 | QVideoFrame f; |
1019 | |
1020 | QCOMPARE(f.availableMetaData(), QVariantMap()); |
1021 | f.setMetaData(key: "frob" , value: QVariant("string" )); |
1022 | f.setMetaData(key: "bar" , value: QVariant(42)); |
1023 | QCOMPARE(f.metaData("frob" ), QVariant("string" )); |
1024 | QCOMPARE(f.metaData("bar" ), QVariant(42)); |
1025 | |
1026 | QVariantMap map; |
1027 | map.insert(key: "frob" , value: QVariant("string" )); |
1028 | map.insert(key: "bar" , value: QVariant(42)); |
1029 | |
1030 | QCOMPARE(f.availableMetaData(), map); |
1031 | |
1032 | f.setMetaData(key: "frob" , value: QVariant(56)); |
1033 | QCOMPARE(f.metaData("frob" ), QVariant(56)); |
1034 | |
1035 | f.setMetaData(key: "frob" , value: QVariant()); |
1036 | QCOMPARE(f.metaData("frob" ), QVariant()); |
1037 | |
1038 | QCOMPARE(f.availableMetaData().count(), 1); |
1039 | |
1040 | f.setMetaData(key: "frob" , value: QVariant("" )); // empty but not null |
1041 | QCOMPARE(f.availableMetaData().count(), 2); |
1042 | } |
1043 | |
1044 | #define TEST_MAPPED(frame, mode) \ |
1045 | do { \ |
1046 | QVERIFY(frame.bits()); \ |
1047 | QVERIFY(frame.isMapped()); \ |
1048 | QCOMPARE(frame.mappedBytes(), 16384); \ |
1049 | QCOMPARE(frame.bytesPerLine(), 256); \ |
1050 | QCOMPARE(frame.mapMode(), mode); \ |
1051 | } while (0) |
1052 | |
1053 | #define TEST_UNMAPPED(frame) \ |
1054 | do { \ |
1055 | QVERIFY(!frame.bits()); \ |
1056 | QVERIFY(!frame.isMapped()); \ |
1057 | QCOMPARE(frame.mappedBytes(), 0); \ |
1058 | QCOMPARE(frame.bytesPerLine(), 0); \ |
1059 | QCOMPARE(frame.mapMode(), QAbstractVideoBuffer::NotMapped); \ |
1060 | } while (0) |
1061 | |
1062 | void tst_QVideoFrame::isMapped() |
1063 | { |
1064 | QVideoFrame frame(16384, QSize(64, 64), 256, QVideoFrame::Format_ARGB32); |
1065 | const QVideoFrame& constFrame(frame); |
1066 | |
1067 | TEST_UNMAPPED(frame); |
1068 | TEST_UNMAPPED(constFrame); |
1069 | |
1070 | QVERIFY(frame.map(QAbstractVideoBuffer::ReadOnly)); |
1071 | TEST_MAPPED(frame, QAbstractVideoBuffer::ReadOnly); |
1072 | TEST_MAPPED(constFrame, QAbstractVideoBuffer::ReadOnly); |
1073 | frame.unmap(); |
1074 | TEST_UNMAPPED(frame); |
1075 | TEST_UNMAPPED(constFrame); |
1076 | |
1077 | QVERIFY(frame.map(QAbstractVideoBuffer::WriteOnly)); |
1078 | TEST_MAPPED(frame, QAbstractVideoBuffer::WriteOnly); |
1079 | TEST_MAPPED(constFrame, QAbstractVideoBuffer::WriteOnly); |
1080 | frame.unmap(); |
1081 | TEST_UNMAPPED(frame); |
1082 | TEST_UNMAPPED(constFrame); |
1083 | |
1084 | QVERIFY(frame.map(QAbstractVideoBuffer::ReadWrite)); |
1085 | TEST_MAPPED(frame, QAbstractVideoBuffer::ReadWrite); |
1086 | TEST_MAPPED(constFrame, QAbstractVideoBuffer::ReadWrite); |
1087 | frame.unmap(); |
1088 | TEST_UNMAPPED(frame); |
1089 | TEST_UNMAPPED(constFrame); |
1090 | } |
1091 | |
1092 | void tst_QVideoFrame::isReadable() |
1093 | { |
1094 | QVideoFrame frame(16384, QSize(64, 64), 256, QVideoFrame::Format_ARGB32); |
1095 | |
1096 | QVERIFY(!frame.isMapped()); |
1097 | QVERIFY(!frame.isReadable()); |
1098 | |
1099 | QVERIFY(frame.map(QAbstractVideoBuffer::ReadOnly)); |
1100 | QVERIFY(frame.isMapped()); |
1101 | QVERIFY(frame.isReadable()); |
1102 | frame.unmap(); |
1103 | |
1104 | QVERIFY(frame.map(QAbstractVideoBuffer::WriteOnly)); |
1105 | QVERIFY(frame.isMapped()); |
1106 | QVERIFY(!frame.isReadable()); |
1107 | frame.unmap(); |
1108 | |
1109 | QVERIFY(frame.map(QAbstractVideoBuffer::ReadWrite)); |
1110 | QVERIFY(frame.isMapped()); |
1111 | QVERIFY(frame.isReadable()); |
1112 | frame.unmap(); |
1113 | } |
1114 | |
1115 | void tst_QVideoFrame::isWritable() |
1116 | { |
1117 | QVideoFrame frame(16384, QSize(64, 64), 256, QVideoFrame::Format_ARGB32); |
1118 | |
1119 | QVERIFY(!frame.isMapped()); |
1120 | QVERIFY(!frame.isWritable()); |
1121 | |
1122 | QVERIFY(frame.map(QAbstractVideoBuffer::ReadOnly)); |
1123 | QVERIFY(frame.isMapped()); |
1124 | QVERIFY(!frame.isWritable()); |
1125 | frame.unmap(); |
1126 | |
1127 | QVERIFY(frame.map(QAbstractVideoBuffer::WriteOnly)); |
1128 | QVERIFY(frame.isMapped()); |
1129 | QVERIFY(frame.isWritable()); |
1130 | frame.unmap(); |
1131 | |
1132 | QVERIFY(frame.map(QAbstractVideoBuffer::ReadWrite)); |
1133 | QVERIFY(frame.isMapped()); |
1134 | QVERIFY(frame.isWritable()); |
1135 | frame.unmap(); |
1136 | } |
1137 | |
1138 | void tst_QVideoFrame::image_data() |
1139 | { |
1140 | QTest::addColumn<QSize>(name: "size" ); |
1141 | QTest::addColumn<QVideoFrame::PixelFormat>(name: "pixelFormat" ); |
1142 | QTest::addColumn<int>(name: "bytes" ); |
1143 | QTest::addColumn<int>(name: "bytesPerLine" ); |
1144 | QTest::addColumn<QImage::Format>(name: "imageFormat" ); |
1145 | |
1146 | QTest::newRow(dataTag: "64x64 ARGB32" ) |
1147 | << QSize(64, 64) |
1148 | << QVideoFrame::Format_ARGB32 |
1149 | << 16384 |
1150 | << 256 |
1151 | << QImage::Format_ARGB32; |
1152 | |
1153 | QTest::newRow(dataTag: "64x64 ARGB32_Premultiplied" ) |
1154 | << QSize(64, 64) |
1155 | << QVideoFrame::Format_ARGB32_Premultiplied |
1156 | << 16384 |
1157 | << 256 |
1158 | << QImage::Format_ARGB32_Premultiplied; |
1159 | |
1160 | QTest::newRow(dataTag: "64x64 RGB32" ) |
1161 | << QSize(64, 64) |
1162 | << QVideoFrame::Format_RGB32 |
1163 | << 16384 |
1164 | << 256 |
1165 | << QImage::Format_RGB32; |
1166 | |
1167 | QTest::newRow(dataTag: "64x64 RGB24" ) |
1168 | << QSize(64, 64) |
1169 | << QVideoFrame::Format_RGB24 |
1170 | << 16384 |
1171 | << 192 |
1172 | << QImage::Format_RGB888; |
1173 | |
1174 | QTest::newRow(dataTag: "64x64 RGB565" ) |
1175 | << QSize(64, 64) |
1176 | << QVideoFrame::Format_RGB565 |
1177 | << 16384 |
1178 | << 128 |
1179 | << QImage::Format_RGB16; |
1180 | |
1181 | QTest::newRow(dataTag: "64x64 RGB555" ) |
1182 | << QSize(64, 64) |
1183 | << QVideoFrame::Format_RGB555 |
1184 | << 16384 |
1185 | << 128 |
1186 | << QImage::Format_RGB555; |
1187 | |
1188 | QTest::newRow(dataTag: "64x64 BGRA32" ) |
1189 | << QSize(64, 64) |
1190 | << QVideoFrame::Format_BGRA32 |
1191 | << 16384 |
1192 | << 256 |
1193 | << QImage::Format_ARGB32; |
1194 | |
1195 | QTest::newRow(dataTag: "64x64 BGRA32_Premultiplied" ) |
1196 | << QSize(64, 64) |
1197 | << QVideoFrame::Format_BGRA32_Premultiplied |
1198 | << 16384 |
1199 | << 256 |
1200 | << QImage::Format_ARGB32; |
1201 | |
1202 | QTest::newRow(dataTag: "64x64 BGR32" ) |
1203 | << QSize(64, 64) |
1204 | << QVideoFrame::Format_BGR32 |
1205 | << 16384 |
1206 | << 256 |
1207 | << QImage::Format_ARGB32; |
1208 | |
1209 | QTest::newRow(dataTag: "64x64 BGR24" ) |
1210 | << QSize(64, 64) |
1211 | << QVideoFrame::Format_BGR24 |
1212 | << 16384 |
1213 | << 256 |
1214 | << QImage::Format_ARGB32; |
1215 | |
1216 | QTest::newRow(dataTag: "64x64 BGR565" ) |
1217 | << QSize(64, 64) |
1218 | << QVideoFrame::Format_BGR565 |
1219 | << 16384 |
1220 | << 256 |
1221 | << QImage::Format_ARGB32; |
1222 | |
1223 | QTest::newRow(dataTag: "64x64 BGR555" ) |
1224 | << QSize(64, 64) |
1225 | << QVideoFrame::Format_BGR555 |
1226 | << 16384 |
1227 | << 256 |
1228 | << QImage::Format_ARGB32; |
1229 | #if !QT_CONFIG(directshow) |
1230 | QTest::newRow(dataTag: "64x64 AYUV444" ) |
1231 | << QSize(64, 64) |
1232 | << QVideoFrame::Format_AYUV444 |
1233 | << 16384 |
1234 | << 256 |
1235 | << QImage::Format_ARGB32; |
1236 | |
1237 | QTest::newRow(dataTag: "64x64 YUV444" ) |
1238 | << QSize(64, 64) |
1239 | << QVideoFrame::Format_YUV444 |
1240 | << 16384 |
1241 | << 256 |
1242 | << QImage::Format_ARGB32; |
1243 | |
1244 | QTest::newRow(dataTag: "64x64 YUV420P" ) |
1245 | << QSize(64, 64) |
1246 | << QVideoFrame::Format_YUV420P |
1247 | << 18432 |
1248 | << 256 |
1249 | << QImage::Format_ARGB32; |
1250 | |
1251 | QTest::newRow(dataTag: "64x64 YV12" ) |
1252 | << QSize(64, 64) |
1253 | << QVideoFrame::Format_YV12 |
1254 | << 18432 |
1255 | << 256 |
1256 | << QImage::Format_ARGB32; |
1257 | |
1258 | QTest::newRow(dataTag: "64x64 UYVY" ) |
1259 | << QSize(64, 64) |
1260 | << QVideoFrame::Format_UYVY |
1261 | << 16384 |
1262 | << 256 |
1263 | << QImage::Format_ARGB32; |
1264 | |
1265 | QTest::newRow(dataTag: "64x64 YUYV" ) |
1266 | << QSize(64, 64) |
1267 | << QVideoFrame::Format_YUYV |
1268 | << 16384 |
1269 | << 256 |
1270 | << QImage::Format_ARGB32; |
1271 | |
1272 | QTest::newRow(dataTag: "64x64 NV12" ) |
1273 | << QSize(64, 64) |
1274 | << QVideoFrame::Format_NV12 |
1275 | << 24576 |
1276 | << 256 |
1277 | << QImage::Format_ARGB32; |
1278 | |
1279 | QTest::newRow(dataTag: "64x64 NV21" ) |
1280 | << QSize(64, 64) |
1281 | << QVideoFrame::Format_NV21 |
1282 | << 24576 |
1283 | << 256 |
1284 | << QImage::Format_ARGB32; |
1285 | #endif |
1286 | } |
1287 | |
1288 | void tst_QVideoFrame::image() |
1289 | { |
1290 | QFETCH(QSize, size); |
1291 | QFETCH(QVideoFrame::PixelFormat, pixelFormat); |
1292 | QFETCH(int, bytes); |
1293 | QFETCH(int, bytesPerLine); |
1294 | QFETCH(QImage::Format, imageFormat); |
1295 | |
1296 | QVideoFrame frame(bytes, size, bytesPerLine, pixelFormat); |
1297 | QImage img = frame.image(); |
1298 | |
1299 | QVERIFY(!img.isNull()); |
1300 | QCOMPARE(img.format(), imageFormat); |
1301 | QCOMPARE(img.size(), size); |
1302 | QCOMPARE(img.bytesPerLine(), bytesPerLine); |
1303 | } |
1304 | |
1305 | void tst_QVideoFrame::emptyData() |
1306 | { |
1307 | QByteArray data(nullptr, 0); |
1308 | QVideoFrame f(new QMemoryVideoBuffer(data, 600), |
1309 | QSize(800, 600), |
1310 | QVideoFrame::Format_ARGB32); |
1311 | QVERIFY(!f.map(QAbstractVideoBuffer::ReadOnly)); |
1312 | } |
1313 | |
1314 | QTEST_MAIN(tst_QVideoFrame) |
1315 | |
1316 | #include "tst_qvideoframe.moc" |
1317 | |