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 <qabstractvideosurface.h> |
34 | #include <qvideosurfaceformat.h> |
35 | |
36 | class tst_QAbstractVideoSurface : public QObject |
37 | { |
38 | Q_OBJECT |
39 | public: |
40 | tst_QAbstractVideoSurface(); |
41 | ~tst_QAbstractVideoSurface(); |
42 | |
43 | public slots: |
44 | void initTestCase(); |
45 | void cleanupTestCase(); |
46 | void init(); |
47 | void cleanup(); |
48 | |
49 | private slots: |
50 | void setError(); |
51 | void isFormatSupported_data(); |
52 | void isFormatSupported(); |
53 | void nearestFormat_data(); |
54 | void nearestFormat(); |
55 | void start_data(); |
56 | void start(); |
57 | void nativeResolution(); |
58 | void supportedFormatsChanged(); |
59 | }; |
60 | |
61 | using SupportedFormatMap = QMultiMap<QAbstractVideoBuffer::HandleType, QVideoFrame::PixelFormat>; |
62 | |
63 | Q_DECLARE_METATYPE(SupportedFormatMap) |
64 | |
65 | class QtTestVideoSurface : public QAbstractVideoSurface |
66 | { |
67 | Q_OBJECT |
68 | public: |
69 | explicit QtTestVideoSurface(QObject *parent = 0) : QAbstractVideoSurface(parent) {} |
70 | explicit QtTestVideoSurface(SupportedFormatMap formats, QObject *parent = 0) |
71 | : QAbstractVideoSurface(parent), supportedFormats(formats) {} |
72 | |
73 | QList<QVideoFrame::PixelFormat> supportedPixelFormats( |
74 | QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const |
75 | { |
76 | return supportedFormats.values(akey: handleType); |
77 | } |
78 | |
79 | bool present(const QVideoFrame &) { return false; } |
80 | |
81 | using QAbstractVideoSurface::setError; |
82 | |
83 | /* adding protected setNativeResolution*/ |
84 | using QAbstractVideoSurface::setNativeResolution; |
85 | |
86 | /* fun to generate supportedFormatsChanged signal */ |
87 | QList<QVideoFrame::PixelFormat> supportedPixelFormatsChange(QList<QVideoFrame::PixelFormat> formats) |
88 | { |
89 | supportedFormats.insert(akey: QAbstractVideoBuffer::NoHandle, avalue: QVideoFrame::Format_RGB32); |
90 | QList<QVideoFrame::PixelFormat> supportedFormats = supportedPixelFormats(); |
91 | if (supportedFormats.count() != formats.count()) { |
92 | emit supportedFormatsChanged(); |
93 | } |
94 | return supportedFormats; |
95 | } |
96 | |
97 | private: |
98 | SupportedFormatMap supportedFormats; |
99 | }; |
100 | |
101 | tst_QAbstractVideoSurface::tst_QAbstractVideoSurface() |
102 | { |
103 | } |
104 | |
105 | tst_QAbstractVideoSurface::~tst_QAbstractVideoSurface() |
106 | { |
107 | } |
108 | |
109 | void tst_QAbstractVideoSurface::initTestCase() |
110 | { |
111 | } |
112 | |
113 | void tst_QAbstractVideoSurface::cleanupTestCase() |
114 | { |
115 | } |
116 | |
117 | void tst_QAbstractVideoSurface::init() |
118 | { |
119 | } |
120 | |
121 | void tst_QAbstractVideoSurface::cleanup() |
122 | { |
123 | } |
124 | |
125 | void tst_QAbstractVideoSurface::setError() |
126 | { |
127 | qRegisterMetaType<QAbstractVideoSurface::Error>(); |
128 | |
129 | QtTestVideoSurface surface; |
130 | |
131 | QCOMPARE(surface.error(), QAbstractVideoSurface::NoError); |
132 | QTest::ignoreMessage(type: QtDebugMsg, message: "NoError" ); |
133 | qDebug() << QAbstractVideoSurface::NoError; |
134 | |
135 | surface.setError(QAbstractVideoSurface::StoppedError); |
136 | QCOMPARE(surface.error(), QAbstractVideoSurface::StoppedError); |
137 | QTest::ignoreMessage(type: QtDebugMsg, message: "StoppedError" ); |
138 | qDebug() << QAbstractVideoSurface::StoppedError; |
139 | |
140 | surface.setError(QAbstractVideoSurface::ResourceError); |
141 | QCOMPARE(surface.error(), QAbstractVideoSurface::ResourceError); |
142 | QTest::ignoreMessage(type: QtDebugMsg, message: "ResourceError" ); |
143 | qDebug() << QAbstractVideoSurface::ResourceError; |
144 | |
145 | surface.setError(QAbstractVideoSurface::NoError); |
146 | QCOMPARE(surface.error(), QAbstractVideoSurface::NoError); |
147 | QTest::ignoreMessage(type: QtDebugMsg, message: "NoError" ); |
148 | qDebug() << QAbstractVideoSurface::NoError; |
149 | |
150 | surface.setError(QAbstractVideoSurface::UnsupportedFormatError); |
151 | QCOMPARE(surface.error(), QAbstractVideoSurface::UnsupportedFormatError); |
152 | QTest::ignoreMessage(type: QtDebugMsg, message: "UnsupportedFormatError" ); |
153 | qDebug() << QAbstractVideoSurface::UnsupportedFormatError; |
154 | |
155 | surface.setError(QAbstractVideoSurface::IncorrectFormatError); |
156 | QCOMPARE(surface.error(), QAbstractVideoSurface::IncorrectFormatError); |
157 | QTest::ignoreMessage(type: QtDebugMsg, message: "IncorrectFormatError" ); |
158 | qDebug() << QAbstractVideoSurface::IncorrectFormatError; |
159 | } |
160 | |
161 | void tst_QAbstractVideoSurface::isFormatSupported_data() |
162 | { |
163 | QTest::addColumn<SupportedFormatMap>(name: "supportedFormats" ); |
164 | QTest::addColumn<QVideoSurfaceFormat>(name: "format" ); |
165 | QTest::addColumn<bool>(name: "supported" ); |
166 | |
167 | SupportedFormatMap formats; |
168 | |
169 | QTest::newRow(dataTag: "no formats: rgb32" ) |
170 | << formats |
171 | << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_RGB32) |
172 | << false; |
173 | QTest::newRow(dataTag: "no formats: yv12" ) |
174 | << formats |
175 | << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_YV12) |
176 | << false; |
177 | QTest::newRow(dataTag: "no formats: rgb32 gl" ) |
178 | << formats |
179 | << QVideoSurfaceFormat( |
180 | QSize(800, 600), |
181 | QVideoFrame::Format_RGB32, |
182 | QAbstractVideoBuffer::GLTextureHandle) |
183 | << false; |
184 | QTest::newRow(dataTag: "no formats: rgb24 gl" ) |
185 | << formats |
186 | << QVideoSurfaceFormat( |
187 | QSize(800, 600), |
188 | QVideoFrame::Format_RGB24, |
189 | QAbstractVideoBuffer::GLTextureHandle) |
190 | << false; |
191 | |
192 | formats.insert(akey: QAbstractVideoBuffer::NoHandle, avalue: QVideoFrame::Format_RGB32); |
193 | formats.insert(akey: QAbstractVideoBuffer::NoHandle, avalue: QVideoFrame::Format_RGB24); |
194 | formats.insert(akey: QAbstractVideoBuffer::NoHandle, avalue: QVideoFrame::Format_YUV444); |
195 | formats.insert(akey: QAbstractVideoBuffer::GLTextureHandle, avalue: QVideoFrame::Format_RGB32); |
196 | |
197 | QTest::newRow(dataTag: "supported: rgb32" ) |
198 | << formats |
199 | << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_RGB32) |
200 | << true; |
201 | QTest::newRow(dataTag: "supported: rgb24" ) |
202 | << formats |
203 | << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_RGB24) |
204 | << true; |
205 | QTest::newRow(dataTag: "unsupported: yv12" ) |
206 | << formats |
207 | << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_YV12) |
208 | << false; |
209 | QTest::newRow(dataTag: "supported: rgb32 gl" ) |
210 | << formats |
211 | << QVideoSurfaceFormat( |
212 | QSize(800, 600), |
213 | QVideoFrame::Format_RGB32, |
214 | QAbstractVideoBuffer::GLTextureHandle) |
215 | << true; |
216 | QTest::newRow(dataTag: "unsupported: rgb24 gl" ) |
217 | << formats |
218 | << QVideoSurfaceFormat( |
219 | QSize(800, 600), |
220 | QVideoFrame::Format_RGB24, |
221 | QAbstractVideoBuffer::GLTextureHandle) |
222 | << false; |
223 | QTest::newRow(dataTag: "unsupported: yv12 gl" ) |
224 | << formats |
225 | << QVideoSurfaceFormat( |
226 | QSize(800, 600), |
227 | QVideoFrame::Format_YV12, |
228 | QAbstractVideoBuffer::GLTextureHandle) |
229 | << false; |
230 | |
231 | formats.insert(akey: QAbstractVideoBuffer::NoHandle, avalue: QVideoFrame::Format_YV12); |
232 | formats.insert(akey: QAbstractVideoBuffer::GLTextureHandle, avalue: QVideoFrame::Format_RGB24); |
233 | |
234 | QTest::newRow(dataTag: "supported: yv12" ) |
235 | << formats |
236 | << QVideoSurfaceFormat(QSize(800, 600), QVideoFrame::Format_YV12) |
237 | << true; |
238 | QTest::newRow(dataTag: "supported: rgb24 gl" ) |
239 | << formats |
240 | << QVideoSurfaceFormat( |
241 | QSize(800, 600), |
242 | QVideoFrame::Format_RGB24, |
243 | QAbstractVideoBuffer::GLTextureHandle) |
244 | << true; |
245 | } |
246 | |
247 | void tst_QAbstractVideoSurface::isFormatSupported() |
248 | { |
249 | QFETCH(SupportedFormatMap, supportedFormats); |
250 | QFETCH(QVideoSurfaceFormat, format); |
251 | QFETCH(bool, supported); |
252 | |
253 | QtTestVideoSurface surface(supportedFormats); |
254 | |
255 | QCOMPARE(surface.isFormatSupported(format), supported); |
256 | } |
257 | |
258 | void tst_QAbstractVideoSurface::nearestFormat_data() |
259 | { |
260 | isFormatSupported_data(); |
261 | } |
262 | |
263 | void tst_QAbstractVideoSurface::nearestFormat() |
264 | { |
265 | QFETCH(SupportedFormatMap, supportedFormats); |
266 | QFETCH(QVideoSurfaceFormat, format); |
267 | QFETCH(bool, supported); |
268 | |
269 | QtTestVideoSurface surface(supportedFormats); |
270 | |
271 | QCOMPARE(surface.nearestFormat(format) == format, supported); |
272 | } |
273 | |
274 | void tst_QAbstractVideoSurface::start_data() |
275 | { |
276 | QTest::addColumn<QVideoSurfaceFormat>(name: "format" ); |
277 | |
278 | QTest::newRow(dataTag: "rgb32" ) << QVideoSurfaceFormat( |
279 | QSize(800, 600), |
280 | QVideoFrame::Format_RGB32); |
281 | QTest::newRow(dataTag: "yv12" ) << QVideoSurfaceFormat( |
282 | QSize(800, 600), |
283 | QVideoFrame::Format_YV12); |
284 | QTest::newRow(dataTag: "rgb32 gl" ) << QVideoSurfaceFormat( |
285 | QSize(800, 600), |
286 | QVideoFrame::Format_RGB32, |
287 | QAbstractVideoBuffer::GLTextureHandle); |
288 | } |
289 | |
290 | void tst_QAbstractVideoSurface::start() |
291 | { |
292 | QFETCH(QVideoSurfaceFormat, format); |
293 | |
294 | QtTestVideoSurface surface; |
295 | surface.setError(QAbstractVideoSurface::ResourceError); |
296 | |
297 | QSignalSpy formatSpy(&surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat))); |
298 | QSignalSpy activeSpy(&surface, SIGNAL(activeChanged(bool))); |
299 | |
300 | QVERIFY(!surface.isActive()); |
301 | QCOMPARE(surface.surfaceFormat(), QVideoSurfaceFormat()); |
302 | |
303 | QVERIFY(surface.start(format)); |
304 | |
305 | QVERIFY(surface.isActive()); |
306 | QCOMPARE(surface.surfaceFormat(), format); |
307 | |
308 | QCOMPARE(formatSpy.count(), 1); |
309 | QCOMPARE(qvariant_cast<QVideoSurfaceFormat>(formatSpy.last().at(0)), format); |
310 | |
311 | QCOMPARE(activeSpy.count(), 1); |
312 | QCOMPARE(activeSpy.last().at(0).toBool(), true); |
313 | |
314 | // Starting twice won't change active |
315 | // XXX should this also not emit surfaceFormatChanged? |
316 | QVERIFY(surface.start(format)); |
317 | QCOMPARE(activeSpy.count(), 1); |
318 | QVERIFY(surface.isActive()); |
319 | |
320 | // error() is reset on a successful start. |
321 | QCOMPARE(surface.error(), QAbstractVideoSurface::NoError); |
322 | |
323 | surface.stop(); |
324 | |
325 | QVERIFY(!surface.isActive()); |
326 | QCOMPARE(surface.surfaceFormat(), QVideoSurfaceFormat()); |
327 | |
328 | QCOMPARE(formatSpy.count(), 3); |
329 | QCOMPARE(qvariant_cast<QVideoSurfaceFormat>(formatSpy.last().at(0)), QVideoSurfaceFormat()); |
330 | |
331 | QCOMPARE(activeSpy.count(), 2); |
332 | QCOMPARE(activeSpy.last().at(0).toBool(), false); |
333 | |
334 | // Stopping a stopped surface shouldn't hurt |
335 | surface.stop(); |
336 | |
337 | QVERIFY(!surface.isActive()); |
338 | QCOMPARE(surface.surfaceFormat(), QVideoSurfaceFormat()); |
339 | |
340 | QCOMPARE(formatSpy.count(), 3); |
341 | QCOMPARE(qvariant_cast<QVideoSurfaceFormat>(formatSpy.last().at(0)), QVideoSurfaceFormat()); |
342 | |
343 | QCOMPARE(activeSpy.count(), 2); |
344 | QCOMPARE(activeSpy.last().at(0).toBool(), false); |
345 | } |
346 | |
347 | // Test nativeResolution property |
348 | void tst_QAbstractVideoSurface::nativeResolution() |
349 | { |
350 | QtTestVideoSurface surface; |
351 | QSignalSpy spy(&surface, SIGNAL(nativeResolutionChanged(QSize))); |
352 | QSize size1 = surface.nativeResolution(); |
353 | QVERIFY(size1.width() == -1); |
354 | QVERIFY(size1.height() == -1); |
355 | QVERIFY(spy.count() == 0); |
356 | |
357 | QSize res(100,150); |
358 | surface.setNativeResolution(res); |
359 | QVERIFY(spy.count() == 1); |
360 | |
361 | QSize size2 = qvariant_cast<QSize>(v: spy.at(i: 0).at(i: 0)); |
362 | QVERIFY(size2.width() == 100); |
363 | QVERIFY(size2.height() == 150); |
364 | |
365 | // Setting again should not emit |
366 | surface.setNativeResolution(res); |
367 | QVERIFY(spy.count() == 1); |
368 | |
369 | size2 = qvariant_cast<QSize>(v: spy.at(i: 0).at(i: 0)); |
370 | QVERIFY(size2.width() == 100); |
371 | QVERIFY(size2.height() == 150); |
372 | |
373 | spy.clear(); |
374 | } |
375 | |
376 | // QAbstractVideoSurface's supported Formats Changed Signal |
377 | void tst_QAbstractVideoSurface::supportedFormatsChanged() |
378 | { |
379 | SupportedFormatMap formatMap; |
380 | formatMap.insert(akey: QAbstractVideoBuffer::NoHandle, avalue: QVideoFrame::Format_RGB24); |
381 | QtTestVideoSurface surface(formatMap); |
382 | QSignalSpy spy(&surface, SIGNAL(supportedFormatsChanged())); |
383 | QList<QVideoFrame::PixelFormat> formats = surface.supportedPixelFormats(); |
384 | QVERIFY(formats.count() == 1); |
385 | QVERIFY(spy.count() == 0); |
386 | |
387 | // user defined implementation for generation of supportedFormatsChanged signal |
388 | QList<QVideoFrame::PixelFormat> newFormats = surface.supportedPixelFormatsChange(formats); |
389 | QVERIFY(newFormats.count() == (formats.count() + 1)); |
390 | QVERIFY(spy.count() == 1); |
391 | spy.clear(); |
392 | } |
393 | |
394 | QTEST_MAIN(tst_QAbstractVideoSurface) |
395 | |
396 | #include "tst_qabstractvideosurface.moc" |
397 | |