1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Research In Motion
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3 as published by the Free Software
21** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30//TESTED_COMPONENT=plugins/declarative/multimedia
31
32#include "private/qdeclarativevideooutput_p.h"
33#include <QtCore/qobject.h>
34#include <QtTest/qtest.h>
35#include <QtQml/qqmlengine.h>
36#include <QtQml/qqmlcomponent.h>
37#include <QtQuick/qquickitem.h>
38#include <QtQuick/qquickview.h>
39#include <QtMultimedia/qmediaobject.h>
40#include <QtMultimedia/qmediaservice.h>
41#include <QtMultimedia/qvideowindowcontrol.h>
42
43Q_DECLARE_METATYPE(QDeclarativeVideoOutput::FillMode)
44
45class SourceObject : public QObject
46{
47 Q_OBJECT
48 Q_PROPERTY(QObject *mediaObject READ mediaObject CONSTANT)
49public:
50 explicit SourceObject(QMediaObject *mediaObject, QObject *parent = 0)
51 : QObject(parent), m_mediaObject(mediaObject)
52 {}
53
54 QObject *mediaObject() const
55 { return m_mediaObject; }
56
57private:
58 QMediaObject *m_mediaObject;
59};
60
61class QtTestWindowControl : public QVideoWindowControl
62{
63public:
64 QtTestWindowControl()
65 : m_winId(0)
66 , m_repaintCount(0)
67 , m_brightness(0)
68 , m_contrast(0)
69 , m_hue(0)
70 , m_saturation(0)
71 , m_aspectRatioMode(Qt::KeepAspectRatio)
72 , m_fullScreen(0)
73 {
74 }
75
76 WId winId() const { return m_winId; }
77 void setWinId(WId id) { m_winId = id; }
78
79 QRect displayRect() const { return m_displayRect; }
80 void setDisplayRect(const QRect &rect) { m_displayRect = rect; }
81
82 bool isFullScreen() const { return m_fullScreen; }
83 void setFullScreen(bool fullScreen) { emit fullScreenChanged(fullScreen: m_fullScreen = fullScreen); }
84
85 int repaintCount() const { return m_repaintCount; }
86 void setRepaintCount(int count) { m_repaintCount = count; }
87 void repaint() { ++m_repaintCount; }
88
89 QSize nativeSize() const { return m_nativeSize; }
90 void setNativeSize(const QSize &size) { m_nativeSize = size; emit nativeSizeChanged(); }
91
92 Qt::AspectRatioMode aspectRatioMode() const { return m_aspectRatioMode; }
93 void setAspectRatioMode(Qt::AspectRatioMode mode) { m_aspectRatioMode = mode; }
94
95 int brightness() const { return m_brightness; }
96 void setBrightness(int brightness) { emit brightnessChanged(brightness: m_brightness = brightness); }
97
98 int contrast() const { return m_contrast; }
99 void setContrast(int contrast) { emit contrastChanged(contrast: m_contrast = contrast); }
100
101 int hue() const { return m_hue; }
102 void setHue(int hue) { emit hueChanged(hue: m_hue = hue); }
103
104 int saturation() const { return m_saturation; }
105 void setSaturation(int saturation) { emit saturationChanged(saturation: m_saturation = saturation); }
106
107private:
108 WId m_winId;
109 int m_repaintCount;
110 int m_brightness;
111 int m_contrast;
112 int m_hue;
113 int m_saturation;
114 Qt::AspectRatioMode m_aspectRatioMode;
115 QRect m_displayRect;
116 QSize m_nativeSize;
117 bool m_fullScreen;
118};
119
120class QtTestVideoService : public QMediaService
121{
122 Q_OBJECT
123public:
124 QtTestVideoService(QtTestWindowControl *window)
125 : QMediaService(0)
126 , windowControl(window)
127 {}
128
129 QMediaControl *requestControl(const char *name)
130 {
131 if (qstrcmp(str1: name, QVideoWindowControl_iid) == 0)
132 return windowControl;
133 return 0;
134 }
135
136 void releaseControl(QMediaControl *control)
137 {
138 Q_ASSERT(control);
139 }
140
141 QtTestWindowControl *windowControl;
142};
143
144class QtTestVideoObject : public QMediaObject
145{
146 Q_OBJECT
147public:
148 explicit QtTestVideoObject(QtTestVideoService *service):
149 QMediaObject(0, service)
150 {
151 }
152};
153
154class tst_QDeclarativeVideoOutputWindow : public QObject
155{
156 Q_OBJECT
157public:
158 tst_QDeclarativeVideoOutputWindow()
159 : QObject(0)
160 , m_service(new QtTestVideoService(&m_windowControl))
161 , m_videoObject(m_service)
162 , m_sourceObject(&m_videoObject)
163 {
164 }
165
166 ~tst_QDeclarativeVideoOutputWindow()
167 {
168 }
169
170public slots:
171 void initTestCase();
172 void cleanupTestCase();
173
174private slots:
175 void winId();
176 void nativeSize();
177 void aspectRatio();
178 void geometryChange();
179 void resetCanvas();
180
181private:
182 QQmlEngine m_engine;
183 QQuickItem *m_videoItem;
184 QScopedPointer<QQuickItem> m_rootItem;
185 QtTestWindowControl m_windowControl;
186 QtTestVideoService *m_service;
187 QtTestVideoObject m_videoObject;
188 SourceObject m_sourceObject;
189 QQuickView m_view;
190};
191
192void tst_QDeclarativeVideoOutputWindow::initTestCase()
193{
194 qRegisterMetaType<QDeclarativeVideoOutput::FillMode>();
195
196 QQmlComponent component(&m_engine);
197 component.loadUrl(url: QUrl("qrc:/main.qml"));
198
199 m_rootItem.reset(other: qobject_cast<QQuickItem *>(object: component.create()));
200 m_videoItem = m_rootItem->findChild<QQuickItem *>(aName: "videoOutput");
201 QVERIFY(m_videoItem);
202 m_rootItem->setParentItem(m_view.contentItem());
203 m_videoItem->setProperty(name: "source", value: QVariant::fromValue<QObject *>(value: &m_sourceObject));
204
205 m_windowControl.setNativeSize(QSize(400, 200));
206 m_view.resize(w: 200, h: 200);
207 m_view.show();
208}
209
210void tst_QDeclarativeVideoOutputWindow::cleanupTestCase()
211{
212 // Make sure that QDeclarativeVideoOutput doesn't segfault when it is being destroyed after
213 // the service is already gone
214 delete m_service;
215 m_service = 0;
216 m_view.setSource(QUrl());
217 m_rootItem.reset();
218}
219
220void tst_QDeclarativeVideoOutputWindow::winId()
221{
222 QCOMPARE(m_windowControl.winId(), m_view.winId());
223}
224
225void tst_QDeclarativeVideoOutputWindow::nativeSize()
226{
227 QCOMPARE(m_videoItem->implicitWidth(), qreal(400.0f));
228 QCOMPARE(m_videoItem->implicitHeight(), qreal(200.0f));
229}
230
231void tst_QDeclarativeVideoOutputWindow::aspectRatio()
232{
233 const QRect expectedDisplayRect(25, 50, 150, 100);
234 int oldRepaintCount = m_windowControl.repaintCount();
235 m_videoItem->setProperty(name: "fillMode", value: QDeclarativeVideoOutput::Stretch);
236 QTRY_COMPARE(m_windowControl.aspectRatioMode(), Qt::IgnoreAspectRatio);
237 QCOMPARE(m_windowControl.displayRect(), expectedDisplayRect);
238 QVERIFY(m_windowControl.repaintCount() > oldRepaintCount);
239
240 oldRepaintCount = m_windowControl.repaintCount();
241 m_videoItem->setProperty(name: "fillMode", value: QDeclarativeVideoOutput::PreserveAspectFit);
242 QTRY_COMPARE(m_windowControl.aspectRatioMode(), Qt::KeepAspectRatio);
243 QCOMPARE(m_windowControl.displayRect(), expectedDisplayRect);
244 QVERIFY(m_windowControl.repaintCount() > oldRepaintCount);
245
246 oldRepaintCount = m_windowControl.repaintCount();
247 m_videoItem->setProperty(name: "fillMode", value: QDeclarativeVideoOutput::PreserveAspectCrop);
248 QTRY_COMPARE(m_windowControl.aspectRatioMode(), Qt::KeepAspectRatioByExpanding);
249 QCOMPARE(m_windowControl.displayRect(), expectedDisplayRect);
250 QVERIFY(m_windowControl.repaintCount() > oldRepaintCount);
251}
252
253void tst_QDeclarativeVideoOutputWindow::geometryChange()
254{
255 m_videoItem->setWidth(50);
256 QTRY_COMPARE(m_windowControl.displayRect(), QRect(25, 50, 50, 100));
257
258 m_videoItem->setX(30);
259 QTRY_COMPARE(m_windowControl.displayRect(), QRect(30, 50, 50, 100));
260}
261
262void tst_QDeclarativeVideoOutputWindow::resetCanvas()
263{
264 m_rootItem->setParentItem(0);
265 QCOMPARE((int)m_windowControl.winId(), 0);
266}
267
268
269QTEST_MAIN(tst_QDeclarativeVideoOutputWindow)
270
271#include "tst_qdeclarativevideooutput_window.moc"
272

source code of qtmultimedia/tests/auto/integration/qdeclarativevideooutput_window/tst_qdeclarativevideooutput_window.cpp