10#if QT_CONFIG(gstreamer_gl)
11#include <QGuiApplication>
12#include <QtGui/qopenglcontext.h>
14#include <qpa/qplatformnativeinterface.h>
15#include <gst/gl/gstglconfig.h>
17#if GST_GL_HAVE_WINDOW_X11 && __has_include("X11/Xlib-xcb.h")
18# include <gst/gl/x11/gstgldisplay_x11.h>
20#if GST_GL_HAVE_PLATFORM_EGL
21# include <gst/gl/egl/gstgldisplay_egl.h>
23# include <EGL/eglext.h>
25#if GST_GL_HAVE_WINDOW_WAYLAND && __has_include("wayland-client.h")
26# include <gst/gl/wayland/gstgldisplay_wayland.h>
30#include <QtCore/qdebug.h>
32#include <QtCore/qloggingcategory.h>
41 sinkBin =
QGstBin(
"videoSinkBin");
50 auto imxVideoConvert =
QGstElement(
"imxvideoconvert_g2d");
52 if (!imxVideoConvert.isNull())
53 gstPreprocess = imxVideoConvert;
54 else if (!nvidiaVideoConvert.isNull())
55 gstPreprocess = nvidiaVideoConvert;
58 sinkBin.add(gstQueue, gstPreprocess);
59 gstQueue.link(gstPreprocess);
60 sinkBin.addGhostPad(gstQueue,
"sink");
80 gstPipeline = pipeline;
106void QGstreamerVideoSink::createQtSink()
111void QGstreamerVideoSink::updateSinkElement()
118 if (newSink == gstVideoSink)
123 if (!gstVideoSink.
isNull()) {
125 sinkBin.
remove(gstVideoSink);
128 gstVideoSink = newSink;
129 sinkBin.
add(gstVideoSink);
130 if (!gstPreprocess.
link(gstVideoSink))
131 qCDebug(qLcMediaVideoSink) <<
"couldn't link preprocess and sink";
132 gstVideoSink.
setState(GST_STATE_PAUSED);
135 gstPipeline.
dumpGraph(
"updateVideoSink");
138void QGstreamerVideoSink::unrefGstContexts()
140 if (m_gstGlDisplayContext)
141 gst_context_unref(m_gstGlDisplayContext);
142 m_gstGlDisplayContext =
nullptr;
143 if (m_gstGlLocalContext)
144 gst_context_unref(m_gstGlLocalContext);
145 m_gstGlLocalContext =
nullptr;
146 m_eglDisplay =
nullptr;
147 m_eglImageTargetTexture2D =
nullptr;
150void QGstreamerVideoSink::updateGstContexts()
154#if QT_CONFIG(gstreamer_gl)
159 auto glContext = nativeHandles->context;
167 GstGLDisplay *gstGlDisplay =
nullptr;
168 const char *contextName =
"eglcontext";
169 GstGLPlatform glPlatform = GST_GL_PLATFORM_EGL;
172#if GST_GL_HAVE_PLATFORM_EGL
173 gstGlDisplay = (GstGLDisplay *)gst_gl_display_egl_new_with_egl_display(m_eglDisplay);
174 m_eglImageTargetTexture2D = eglGetProcAddress(
"glEGLImageTargetTexture2DOES");
180#if GST_GL_HAVE_WINDOW_X11 && __has_include("X11/Xlib-xcb.h")
182 contextName =
"glxcontext";
183 glPlatform = GST_GL_PLATFORM_GLX;
185 gstGlDisplay = (GstGLDisplay *)gst_gl_display_x11_new_with_display((
Display *)
display);
188#if GST_GL_HAVE_WINDOW_WAYLAND && __has_include("wayland-client.h")
191 gstGlDisplay = (GstGLDisplay *)gst_gl_display_wayland_new_with_display((
struct wl_display *)
display);
198 qWarning() <<
"Could not create GstGLDisplay";
204 qWarning() <<
"Could not find resource for" << contextName;
207 GstGLContext *appContext = gst_gl_context_new_wrapped(gstGlDisplay, (guintptr)nativeContext, glPlatform, glApi);
209 qWarning() <<
"Could not create wrappped context for platform:" << glPlatform;
211 GstGLContext *displayContext =
nullptr;
212 GError *
error =
nullptr;
213 gst_gl_display_create_context(gstGlDisplay, appContext, &displayContext, &
error);
215 qWarning() <<
"Could not create display context:" <<
error->message;
216 g_clear_error(&
error);
220 gst_object_unref(appContext);
222 m_gstGlDisplayContext = gst_context_new(GST_GL_DISPLAY_CONTEXT_TYPE,
false);
223 gst_context_set_gl_display(m_gstGlDisplayContext, gstGlDisplay);
224 gst_object_unref(gstGlDisplay);
226 m_gstGlLocalContext = gst_context_new(
"gst.gl.local_context",
false);
227 GstStructure *structure = gst_context_writable_structure(m_gstGlLocalContext);
228 gst_structure_set(structure,
"context", GST_TYPE_GL_CONTEXT, displayContext,
nullptr);
229 gst_object_unref(displayContext);
231 if (!gstPipeline.
isNull())
232 gst_element_set_context(gstPipeline.
element(), m_gstGlLocalContext);
238#include "moc_qgstreamervideosink_p.cpp"
void remove(const QGstElement &element)
void add(const QGstElement &element)
GstStateChangeReturn setState(GstState state)
GstElement * element() const
bool setStateSync(GstState state)
bool link(const QGstElement &next)
bool inStoppedState() const
void dumpGraph(const char *fileName)
static QGstSubtitleSink * createSink(QGstreamerVideoSink *sink)
static QGstVideoRendererSink * createSink(QGstreamerVideoSink *surface)
bool inStoppedState() const
void setPipeline(QGstPipeline pipeline)
void setRhi(QRhi *rhi) override
static QPlatformNativeInterface * platformNativeInterface()
QString platformName
The name of the underlying platform plugin.
static OpenGLModuleType openGLModuleType()
Returns the underlying OpenGL implementation type.
\variable QRhiGles2InitParams::format
Implementation backend() const
const QRhiNativeHandles * nativeHandles()
\macro QT_RESTRICTED_CAST_FROM_ASCII
The QVideoSink class represents a generic sink for video data.
struct wl_display * display
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
QLatin1StringView QLatin1String
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent