[gtk/wip.win32.fixes: 2/3] media-gstreamer: Provide fallback mode for playback




commit bc4e7dda8810424a6928996be31b53dc77fb4009
Author: Chun-wei Fan <fanchunwei src gnome org>
Date:   Mon May 24 16:24:39 2021 +0800

    media-gstreamer: Provide fallback mode for playback
    
    Make the "gl-context" property of the GstGLSink readable as well so that
    we can query whether the GstGLContext sharing really succeeded.  If it
    did, then we proceed to playback our video using the glimagesink as we
    did before.  If it didn't, throw out the GtkGstSink we were creating, and
    re-create the GtkGstSink without the "gl-context" property, meaning that
    we won't be using the glimagesink in this case.

 modules/media/gtkgstpaintable.c | 29 ++++++++++++++++++++++++-----
 modules/media/gtkgstsink.c      | 31 ++++++++++++++++++++-----------
 2 files changed, 44 insertions(+), 16 deletions(-)
---
diff --git a/modules/media/gtkgstpaintable.c b/modules/media/gtkgstpaintable.c
index ba5aefca4b..06abcd7583 100644
--- a/modules/media/gtkgstpaintable.c
+++ b/modules/media/gtkgstpaintable.c
@@ -117,20 +117,39 @@ gtk_gst_paintable_video_renderer_create_video_sink (GstPlayerVideoRenderer *rend
 {
   GtkGstPaintable *self = GTK_GST_PAINTABLE (renderer);
   GstElement *sink, *glsinkbin;
+  GdkGLContext *ctx;
 
   sink = g_object_new (GTK_TYPE_GST_SINK,
                        "paintable", self,
                        "gl-context", self->context,
                        NULL);
 
-  if (self->context == NULL)
-    return sink;
+  if (self->context != NULL)
+    g_object_get (GTK_GST_SINK (sink), "gl-context", &ctx, NULL);
+
+  if (self->context != NULL && ctx != NULL)
+    {
+      glsinkbin = gst_element_factory_make ("glsinkbin", NULL);
+
+      g_object_set (glsinkbin, "sink", sink, NULL);
+      g_object_unref (ctx);
 
-  glsinkbin = gst_element_factory_make ("glsinkbin", NULL);
+      return glsinkbin;
+    }
+  else
+    {
+      if (self->context != NULL)
+        {
+          g_warning ("GstGL context creation failed, falling back to non-GL playback");
 
-  g_object_set (glsinkbin, "sink", sink, NULL);
+          g_object_unref (sink);
+          sink = g_object_new (GTK_TYPE_GST_SINK,
+                               "paintable", self,
+                               NULL);
+        }
 
-  return glsinkbin;
+      return sink;
+    }
 }
 
 static void
diff --git a/modules/media/gtkgstsink.c b/modules/media/gtkgstsink.c
index 8775ec54f4..72183278ba 100644
--- a/modules/media/gtkgstsink.c
+++ b/modules/media/gtkgstsink.c
@@ -417,7 +417,7 @@ check_win32_gst_gl_api (GdkGLContext  *ctx,
 #define REACTIVATE_WGL_CONTEXT(ctx)
 #endif
 
-static void
+static gboolean
 gtk_gst_sink_initialize_gl (GtkGstSink *self)
 {
   GdkDisplay *display;
@@ -425,6 +425,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
   GstGLPlatform platform = GST_GL_PLATFORM_NONE;
   GstGLAPI gl_api = GST_GL_API_NONE;
   guintptr gl_handle = 0;
+  gboolean succeeded = FALSE;
 
   display = gdk_gl_context_get_display (self->gdk_context);
 
@@ -465,7 +466,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
       else
         {
           GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext");
-          return;
+          return FALSE;
         }
     }
   else
@@ -491,7 +492,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
       else
         {
           GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext, not using Wayland EGL");
-          return;
+          return FALSE;
         }
     }
   else
@@ -522,10 +523,12 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
 #ifdef HAVE_GST_GL_DISPLAY_NEW_WITH_TYPE
               self->gst_display = gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_WIN32);
 #else
+#if GST_GL_HAVE_PLATFORM_EGL
               g_message ("If media fails to play, set the envvar `GST_DEBUG=1`, and if GstGL context 
creation fails");
               g_message ("due to \"Couldn't create GL context: Cannot share context with non-EGL 
context\",");
               g_message ("set in the environment `GST_GL_PLATFORM=wgl` and `GST_GL_WINDOW=win32`,");
               g_message ("and restart the GTK application");
+#endif
 
               self->gst_display = gst_gl_display_new ();
 #endif
@@ -545,14 +548,14 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
       else
         {
           GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext, not using %s", gl_type);
-             return;
+             return FALSE;
         }
     }
   else
 #endif
     {
       GST_INFO_OBJECT (self, "Unsupported GDK display %s for GL", G_OBJECT_TYPE_NAME (display));
-      return;
+      return FALSE;
     }
 
   g_assert (self->gst_app_context != NULL);
@@ -565,8 +568,8 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
       g_clear_error (&error);
       g_clear_object (&self->gst_app_context);
       g_clear_object (&self->gst_display);
-      HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);;
-      return;
+      HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);
+      return FALSE;
     }
   else
     {
@@ -574,7 +577,9 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
       gst_gl_context_activate (self->gst_app_context, FALSE);
     }
 
-  if (!gst_gl_display_create_context (self->gst_display, self->gst_app_context, &self->gst_context, &error))
+  succeeded = gst_gl_display_create_context (self->gst_display, self->gst_app_context, &self->gst_context, 
&error);
+
+  if (!succeeded)
     {
       GST_ERROR_OBJECT (self, "Couldn't create GL context: %s", error->message);
       g_error_free (error);
@@ -584,6 +589,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
 
   HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);
   REACTIVATE_WGL_CONTEXT (self->gdk_context);
+  return succeeded;
 }
 
 static void
@@ -605,8 +611,8 @@ gtk_gst_sink_set_property (GObject      *object,
 
     case PROP_GL_CONTEXT:
       self->gdk_context = g_value_dup_object (value);
-      if (self->gdk_context != NULL)
-        gtk_gst_sink_initialize_gl (self);
+      if (self->gdk_context != NULL && !gtk_gst_sink_initialize_gl (self))
+        g_clear_object (&self->gdk_context);
       break;
 
     default:
@@ -628,6 +634,9 @@ gtk_gst_sink_get_property (GObject    *object,
     case PROP_PAINTABLE:
       g_value_set_object (value, self->paintable);
       break;
+    case PROP_GL_CONTEXT:
+      g_value_set_object (value, self->gdk_context);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -690,7 +699,7 @@ gtk_gst_sink_class_init (GtkGstSinkClass * klass)
                          P_("gl-context"),
                          P_("GL context to use for rendering"),
                          GDK_TYPE_GL_CONTEXT,
-                         G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
 
   g_object_class_install_properties (gobject_class, N_PROPS, properties);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]