Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qgstreamervideooverlay.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtGui/qguiapplication.h>
7#include "qgstutils_p.h"
8#include "qgst_p.h"
11
12#include <gst/video/videooverlay.h>
13
14#include <QtMultimedia/private/qtmultimediaglobal_p.h>
15
17
19{
20 const char *qtPlatform;
21 const char *gstreamerElement;
22};
23
24// Ordered by descending priority
25static constexpr ElementMap elementMap[] =
26{
27 { "xcb", "xvimagesink" },
28 { "xcb", "ximagesink" },
29
30 // wayland
31 { "wayland", "waylandsink" }
32};
33
35{
36 GstStateChangeReturn ret = element.setState(GST_STATE_READY);
37 if (ret == GST_STATE_CHANGE_SUCCESS) {
38 element.setState(GST_STATE_NULL);
39 return true;
40 }
41
42 return false;
43}
44
46{
48
49 // First, try some known video sinks, depending on the Qt platform plugin in use.
50 for (auto i : elementMap) {
51 if (platform != QLatin1String(i.qtPlatform))
52 continue;
53 QGstElement choice(i.gstreamerElement, i.gstreamerElement);
54 if (choice.isNull())
55 continue;
56
58 return choice;
59 }
60
61 // We need a native window ID to use the GstVideoOverlay interface.
62 // Bail out if the Qt platform plugin in use cannot provide a sensible WId.
63 if (platform != QLatin1String("xcb") && platform != QLatin1String("wayland"))
64 return {};
65
66 QGstElement choice;
67 // If none of the known video sinks are available, try to find one that implements the
68 // GstVideoOverlay interface and has autoplugging rank.
69 GList *list = qt_gst_video_sinks();
70 for (GList *item = list; item != nullptr; item = item->next) {
71 GstElementFactory *f = GST_ELEMENT_FACTORY(item->data);
72
73 if (!gst_element_factory_has_interface(f, "GstVideoOverlay"))
74 continue;
75
76 choice = QGstElement(gst_element_factory_create(f, nullptr));
77 if (choice.isNull())
78 continue;
79
81 break;
82 choice = {};
83 }
84
85 gst_plugin_feature_list_free(list);
86 if (choice.isNull())
87 qWarning() << "Could not find a valid windowed video sink";
88
89 return choice;
90}
91
95 , m_gstreamerVideoSink(parent)
96{
98 if (!elementName.isEmpty())
99 sink = QGstElement(elementName.constData(), nullptr);
100 else
102
104}
105
107{
108 if (!m_videoSink.isNull()) {
109 QGstPad pad = m_videoSink.staticPad("sink");
110 removeProbeFromPad(pad.pad());
111 }
112}
113
115{
116 return m_videoSink;
117}
118
120{
121 if (sink.isNull())
122 return;
123
124 m_videoSink = sink;
125
126 QGstPad pad = m_videoSink.staticPad("sink");
127 addProbeToPad(pad.pad());
128
129 auto *klass = G_OBJECT_GET_CLASS(m_videoSink.object());
130 m_hasForceAspectRatio = g_object_class_find_property(klass, "force-aspect-ratio");
131 m_hasFullscreen = g_object_class_find_property(klass, "fullscreen");
132}
133
135{
136 return m_nativeVideoSize;
137}
138
140{
141 m_windowId = id;
142
143 if (!m_videoSink.isNull() && GST_IS_VIDEO_OVERLAY(m_videoSink.object())) {
144 applyRenderRect();
145
146 // Properties need to be reset when changing the winId.
147 setAspectRatioMode(m_aspectRatioMode);
148 setFullScreen(m_fullScreen);
149 applyRenderRect();
150 }
151}
152
154{
155 renderRect = rect;
156 applyRenderRect();
157}
158
159void QGstreamerVideoOverlay::applyRenderRect()
160{
161 if (!m_windowId)
162 return;
163
164 int x = -1;
165 int y = -1;
166 int w = -1;
167 int h = -1;
168
169 if (!renderRect.isEmpty()) {
170 x = renderRect.x();
171 y = renderRect.y();
172 w = renderRect.width();
173 h = renderRect.height();
174 QSize scaledVideo = m_nativeVideoSize.scaled(w, h, m_aspectRatioMode);
175 x += (w - scaledVideo.width())/2;
176 y += (h - scaledVideo.height())/2;
177 w = scaledVideo.width();
178 h = scaledVideo.height();
179 }
180
181 if (!m_videoSink.isNull() && GST_IS_VIDEO_OVERLAY(m_videoSink.object()))
182 gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(m_videoSink.object()), x, y, w, h);
183}
184
186{
188 if (size != m_nativeVideoSize) {
189 m_nativeVideoSize = size;
190 m_gstreamerVideoSink->setNativeSize(m_nativeVideoSize);
191 applyRenderRect();
192 }
193}
194
196{
197 m_aspectRatioMode = mode;
198 if (m_hasForceAspectRatio)
199 m_videoSink.set("force-aspect-ratio", (mode == Qt::KeepAspectRatio));
200}
201
203{
204 m_fullScreen = fullscreen;
205 if (m_hasFullscreen)
206 m_videoSink.set("fullscreen", fullscreen);
207}
208
210{
211 if (!gst_is_video_overlay_prepare_window_handle_message(message.rawMessage()))
212 return false;
213 gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink.object()), m_windowId);
214 return true;
215}
216
218
219#include "moc_qgstreamervideooverlay_p.cpp"
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
QVariant data(int key) const
Returns this item's custom data for the key key as a QVariant.
@ NeedsRef
Definition qgst_p.h:163
QGstStructure at(int index) const
Definition qgst_p.h:201
GstStateChangeReturn setState(GstState state)
Definition qgst_p.h:462
QGstPad staticPad(const char *name) const
Definition qgst_p.h:443
bool isNull() const
Definition qgst_p.h:288
void set(const char *property, const char *str)
Definition qgst_p.h:290
GstObject * object() const
Definition qgst_p.h:315
GstPad * pad() const
Definition qgst_p.h:344
Q_MULTIMEDIA_EXPORT QSize resolution() const
void removeProbeFromPad(GstPad *pad)
void addProbeToPad(GstPad *pad, bool downstream=true)
void setAspectRatioMode(Qt::AspectRatioMode mode)
QGstreamerVideoOverlay(QGstreamerVideoSink *parent=0, const QByteArray &elementName=QByteArray())
void setRenderRectangle(const QRect &rect)
bool processSyncMessage(const QGstreamerMessage &message) override
void probeCaps(GstCaps *caps) override
void setFullScreen(bool fullscreen)
QString platformName
The name of the underlying platform plugin.
\inmodule QtCore
Definition qobject.h:90
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr bool isEmpty() const noexcept
Returns true if the rectangle is empty, otherwise returns false.
Definition qrect.h:166
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:238
constexpr int x() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:184
constexpr int width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:235
constexpr int y() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:187
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
QSize scaled(int w, int h, Qt::AspectRatioMode mode) const noexcept
Definition qsize.h:150
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
rect
[4]
Combined button and popup list for selecting options.
AspectRatioMode
@ KeepAspectRatio
static QGstElement findBestVideoSink()
static bool qt_gst_element_is_functioning(QGstElement element)
static constexpr ElementMap elementMap[]
GList * qt_gst_video_sinks()
#define qWarning
Definition qlogging.h:162
return ret
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint id
[7]
GLfloat GLfloat f
GLuint GLsizei const GLchar * message
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLenum GLboolean sink
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
QT_BEGIN_NAMESPACE Platform platform()
QList< int > list
[14]
QGraphicsItem * item
const char * gstreamerElement
const char * qtPlatform
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent