qmlglsrc: fix operation without any qmlglsink

E.g. a pipeline like qmlglsrc ! gldownload ! ... would currently fail to
run because the OpenGL context are not created in the correct order.

The QtWindow also needs to know the OpenGL context used by downstream
elements in order to set optimize for the correct GstGLSyncMeta for
synchonisation purposes.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/1036>
This commit is contained in:
Matthew Waters 2021-07-21 20:14:46 +10:00 committed by GStreamer Marge Bot
parent 9499976fbb
commit b1fb787859
3 changed files with 49 additions and 3 deletions

View file

@ -290,8 +290,12 @@ gst_qt_src_query (GstBaseSrc * bsrc, GstQuery * query)
return FALSE;
if (!qt_src->display && !qt_src->qt_context) {
qt_src->display = qt_window_get_display (qt_src->window);
qt_src->qt_context = qt_window_get_qt_context (qt_src->window);
if (!qt_src->display)
qt_src->display = qt_window_get_display (qt_src->window);
if (!qt_src->qt_context)
qt_src->qt_context = qt_window_get_qt_context (qt_src->window);
if (!qt_src->context)
qt_src->context = qt_window_get_context (qt_src->window);
}
if (gst_gl_handle_context_query ((GstElement *) qt_src, query,
@ -367,6 +371,9 @@ gst_qt_src_decide_allocation (GstBaseSrc * bsrc, GstQuery * query)
if (!qt_src->context && !_find_local_gl_context (qt_src))
return FALSE;
if (!qt_window_set_context (qt_src->window, qt_src->context))
return FALSE;
if (!pool) {
if (!qt_src->context || !GST_IS_GL_CONTEXT (qt_src->context))
return FALSE;
@ -532,6 +539,7 @@ gst_qt_src_start (GstBaseSrc * basesrc)
qt_src->display = qt_window_get_display (qt_src->window);
qt_src->qt_context = qt_window_get_qt_context (qt_src->window);
qt_src->context = qt_window_get_context (qt_src->window);
if (!qt_src->display || !qt_src->qt_context) {
GST_ERROR_OBJECT (qt_src,

View file

@ -70,6 +70,7 @@ struct _QtGLWindowPrivate
GstGLDisplay *display;
GstGLContext *other_context;
GstGLContext *context;
GLuint fbo;
@ -141,6 +142,8 @@ QtGLWindow::~QtGLWindow()
gst_object_unref(this->priv->other_context);
if (this->priv->display)
gst_object_unref(this->priv->display);
if (this->priv->context)
gst_object_unref(this->priv->context);
g_free (this->priv);
this->priv = NULL;
}
@ -189,6 +192,7 @@ QtGLWindow::afterRendering()
guint width, height;
const GstGLFuncs *gl;
GLuint dst_tex;
GstGLSyncMeta *sync_meta;
g_mutex_lock (&this->priv->lock);
@ -253,6 +257,14 @@ QtGLWindow::afterRendering()
gl->CopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, width, height, 0);
}
if (this->priv->context) {
sync_meta = gst_buffer_get_gl_sync_meta (this->priv->buffer);
if (!sync_meta) {
sync_meta = gst_buffer_add_gl_sync_meta (this->priv->context, this->priv->buffer);
}
gst_gl_sync_meta_set_sync_point (sync_meta, context);
}
GST_DEBUG ("rendering finished");
errors:
@ -293,7 +305,7 @@ QtGLWindow::onSceneGraphInitialized()
this->source->openglContext ());
this->priv->initted = gst_qt_get_gl_wrapcontext (this->priv->display,
&this->priv->other_context, NULL);
&this->priv->other_context, &this->priv->context);
if (this->priv->initted && this->priv->other_context) {
const GstGLFuncs *gl;
@ -361,6 +373,30 @@ qt_window_get_display (QtGLWindow * qt_window)
return (GstGLDisplay *) gst_object_ref (qt_window->priv->display);
}
GstGLContext *
qt_window_get_context (QtGLWindow * qt_window)
{
g_return_val_if_fail (qt_window != NULL, NULL);
if (!qt_window->priv->context)
return NULL;
return (GstGLContext *) gst_object_ref (qt_window->priv->context);
}
gboolean
qt_window_set_context (QtGLWindow * qt_window, GstGLContext * context)
{
g_return_val_if_fail (qt_window != NULL, FALSE);
if (qt_window->priv->context && qt_window->priv->context != context)
return FALSE;
gst_object_replace ((GstObject **) &qt_window->priv->context, (GstObject *) context);
return TRUE;
}
gboolean
qt_window_is_scenegraph_initialized (QtGLWindow * qt_window)
{

View file

@ -62,6 +62,8 @@ extern "C"
gboolean qt_window_set_buffer (QtGLWindow * qt_window, GstBuffer * buffer);
gboolean qt_window_set_caps (QtGLWindow * qt_window, GstCaps * caps);
GstGLContext * qt_window_get_qt_context (QtGLWindow * qt_window);
GstGLContext * qt_window_get_context (QtGLWindow * qt_window);
gboolean qt_window_set_context (QtGLWindow * qt_window, GstGLContext * context);
GstGLDisplay * qt_window_get_display (QtGLWindow * qt_window);
gboolean qt_window_is_scenegraph_initialized (QtGLWindow * qt_window);
void qt_window_use_default_fbo (QtGLWindow * qt_window, gboolean useDefaultFbo);