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 Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qgstreamervideowidget_p.h"
41#include "qgstutils_p.h"
42
43#include <QtCore/qcoreevent.h>
44#include <QtCore/qdebug.h>
45#include <QtGui/qpainter.h>
46
47QT_BEGIN_NAMESPACE
48
49class QGstreamerVideoWidget : public QWidget
50{
51public:
52 QGstreamerVideoWidget(QWidget *parent = 0)
53 :QWidget(parent)
54 {
55 setSizePolicy(hor: QSizePolicy::Expanding, ver: QSizePolicy::Expanding);
56 QPalette palette;
57 palette.setColor(acr: QPalette::Window, acolor: Qt::black);
58 setPalette(palette);
59 }
60
61 virtual ~QGstreamerVideoWidget() {}
62
63 QSize sizeHint() const override
64 {
65 return m_nativeSize;
66 }
67
68 void setNativeSize( const QSize &size)
69 {
70 if (size != m_nativeSize) {
71 m_nativeSize = size;
72 if (size.isEmpty())
73 setMinimumSize(minw: 0,minh: 0);
74 else
75 setMinimumSize(minw: 160,minh: 120);
76
77 updateGeometry();
78 }
79 }
80
81 void paint_helper()
82 {
83 QPainter painter(this);
84 painter.fillRect(rect(), palette().window());
85 }
86
87protected:
88 void paintEvent(QPaintEvent *) override
89 {
90 paint_helper();
91 }
92
93 QSize m_nativeSize;
94};
95
96QGstreamerVideoWidgetControl::QGstreamerVideoWidgetControl(QObject *parent, const QByteArray &elementName)
97 : QVideoWidgetControl(parent)
98 , m_videoOverlay(this, !elementName.isEmpty() ? elementName : qgetenv(varName: "QT_GSTREAMER_WIDGET_VIDEOSINK"))
99{
100 connect(sender: &m_videoOverlay, signal: &QGstreamerVideoOverlay::activeChanged,
101 receiver: this, slot: &QGstreamerVideoWidgetControl::onOverlayActiveChanged);
102 connect(sender: &m_videoOverlay, signal: &QGstreamerVideoOverlay::nativeVideoSizeChanged,
103 receiver: this, slot: &QGstreamerVideoWidgetControl::onNativeVideoSizeChanged);
104 connect(sender: &m_videoOverlay, signal: &QGstreamerVideoOverlay::brightnessChanged,
105 receiver: this, slot: &QGstreamerVideoWidgetControl::brightnessChanged);
106 connect(sender: &m_videoOverlay, signal: &QGstreamerVideoOverlay::contrastChanged,
107 receiver: this, slot: &QGstreamerVideoWidgetControl::contrastChanged);
108 connect(sender: &m_videoOverlay, signal: &QGstreamerVideoOverlay::hueChanged,
109 receiver: this, slot: &QGstreamerVideoWidgetControl::hueChanged);
110 connect(sender: &m_videoOverlay, signal: &QGstreamerVideoOverlay::saturationChanged,
111 receiver: this, slot: &QGstreamerVideoWidgetControl::saturationChanged);
112}
113
114QGstreamerVideoWidgetControl::~QGstreamerVideoWidgetControl()
115{
116 delete m_widget;
117}
118
119void QGstreamerVideoWidgetControl::createVideoWidget()
120{
121 if (m_widget)
122 return;
123
124 m_widget = new QGstreamerVideoWidget;
125
126 m_widget->installEventFilter(filterObj: this);
127 m_videoOverlay.setWindowHandle(m_windowId = m_widget->winId());
128}
129
130GstElement *QGstreamerVideoWidgetControl::videoSink()
131{
132 return m_videoOverlay.videoSink();
133}
134
135void QGstreamerVideoWidgetControl::setVideoSink(GstElement *sink)
136{
137 m_videoOverlay.setVideoSink(sink);
138}
139
140void QGstreamerVideoWidgetControl::onOverlayActiveChanged()
141{
142 updateWidgetAttributes();
143}
144
145void QGstreamerVideoWidgetControl::stopRenderer()
146{
147 m_stopped = true;
148 updateWidgetAttributes();
149 m_widget->setNativeSize(QSize());
150}
151
152void QGstreamerVideoWidgetControl::onNativeVideoSizeChanged()
153{
154 const QSize &size = m_videoOverlay.nativeVideoSize();
155
156 if (size.isValid())
157 m_stopped = false;
158
159 if (m_widget)
160 m_widget->setNativeSize(size);
161}
162
163bool QGstreamerVideoWidgetControl::eventFilter(QObject *object, QEvent *e)
164{
165 if (m_widget && object == m_widget) {
166 if (e->type() == QEvent::ParentChange || e->type() == QEvent::Show || e->type() == QEvent::WinIdChange) {
167 WId newWId = m_widget->winId();
168 if (newWId != m_windowId)
169 m_videoOverlay.setWindowHandle(m_windowId = newWId);
170 }
171
172 if (e->type() == QEvent::Paint) {
173 // Update overlay by new size if any.
174 if (QGstUtils::useOpenGL())
175 m_videoOverlay.setRenderRectangle(QRect(0, 0, m_widget->width(), m_widget->height()));
176 if (m_videoOverlay.isActive())
177 m_videoOverlay.expose(); // triggers a repaint of the last frame
178 else
179 m_widget->paint_helper(); // paints the black background
180
181 return true;
182 }
183 }
184
185 return false;
186}
187
188void QGstreamerVideoWidgetControl::updateWidgetAttributes()
189{
190 // When frames are being rendered (sink is active), we need the WA_PaintOnScreen attribute to
191 // be set in order to avoid flickering when the widget is repainted (for example when resized).
192 // We need to clear that flag when the the sink is inactive to allow the widget to paint its
193 // background, otherwise some garbage will be displayed.
194 if (m_videoOverlay.isActive() && !m_stopped) {
195 m_widget->setAttribute(Qt::WA_NoSystemBackground, on: true);
196 m_widget->setAttribute(Qt::WA_PaintOnScreen, on: true);
197 } else {
198 m_widget->setAttribute(Qt::WA_NoSystemBackground, on: false);
199 m_widget->setAttribute(Qt::WA_PaintOnScreen, on: false);
200 m_widget->update();
201 }
202}
203
204bool QGstreamerVideoWidgetControl::processSyncMessage(const QGstreamerMessage &message)
205{
206 return m_videoOverlay.processSyncMessage(message);
207}
208
209bool QGstreamerVideoWidgetControl::processBusMessage(const QGstreamerMessage &message)
210{
211 return m_videoOverlay.processBusMessage(message);
212}
213
214QWidget *QGstreamerVideoWidgetControl::videoWidget()
215{
216 createVideoWidget();
217 return m_widget;
218}
219
220Qt::AspectRatioMode QGstreamerVideoWidgetControl::aspectRatioMode() const
221{
222 return m_videoOverlay.aspectRatioMode();
223}
224
225void QGstreamerVideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode mode)
226{
227 m_videoOverlay.setAspectRatioMode(mode);
228}
229
230bool QGstreamerVideoWidgetControl::isFullScreen() const
231{
232 return m_fullScreen;
233}
234
235void QGstreamerVideoWidgetControl::setFullScreen(bool fullScreen)
236{
237 emit fullScreenChanged(fullScreen: m_fullScreen = fullScreen);
238}
239
240int QGstreamerVideoWidgetControl::brightness() const
241{
242 return m_videoOverlay.brightness();
243}
244
245void QGstreamerVideoWidgetControl::setBrightness(int brightness)
246{
247 m_videoOverlay.setBrightness(brightness);
248}
249
250int QGstreamerVideoWidgetControl::contrast() const
251{
252 return m_videoOverlay.contrast();
253}
254
255void QGstreamerVideoWidgetControl::setContrast(int contrast)
256{
257 m_videoOverlay.setContrast(contrast);
258}
259
260int QGstreamerVideoWidgetControl::hue() const
261{
262 return m_videoOverlay.hue();
263}
264
265void QGstreamerVideoWidgetControl::setHue(int hue)
266{
267 m_videoOverlay.setHue(hue);
268}
269
270int QGstreamerVideoWidgetControl::saturation() const
271{
272 return m_videoOverlay.saturation();
273}
274
275void QGstreamerVideoWidgetControl::setSaturation(int saturation)
276{
277 m_videoOverlay.setSaturation(saturation);
278}
279
280QT_END_NAMESPACE
281

source code of qtmultimedia/src/gsttools/qgstreamervideowidget.cpp