qmlglsrc: fix operation without any qmlglsink
authorMatthew Waters <matthew@centricular.com>
Wed, 21 Jul 2021 10:14:46 +0000 (20:14 +1000)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 28 Jul 2021 02:11:44 +0000 (02:11 +0000)
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>

ext/qt/gstqtsrc.cc
ext/qt/qtwindow.cc
ext/qt/qtwindow.h

index fd7dd56..57fb990 100644 (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,
index aec6ba7..3995966 100644 (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)
 {
index 697f389..a607a31 100644 (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);