forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
ccdec5da77
commit
16f307b305
@ -117,20 +117,39 @@ gtk_gst_paintable_video_renderer_create_video_sink (GstPlayerVideoRenderer *rend
|
|||||||
{
|
{
|
||||||
GtkGstPaintable *self = GTK_GST_PAINTABLE (renderer);
|
GtkGstPaintable *self = GTK_GST_PAINTABLE (renderer);
|
||||||
GstElement *sink, *glsinkbin;
|
GstElement *sink, *glsinkbin;
|
||||||
|
GdkGLContext *ctx;
|
||||||
|
|
||||||
sink = g_object_new (GTK_TYPE_GST_SINK,
|
sink = g_object_new (GTK_TYPE_GST_SINK,
|
||||||
"paintable", self,
|
"paintable", self,
|
||||||
"gl-context", self->context,
|
"gl-context", self->context,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (self->context == NULL)
|
if (self->context != NULL)
|
||||||
return sink;
|
g_object_get (GTK_GST_SINK (sink), "gl-context", &ctx, NULL);
|
||||||
|
|
||||||
glsinkbin = gst_element_factory_make ("glsinkbin", NULL);
|
if (self->context != NULL && ctx != NULL)
|
||||||
|
{
|
||||||
|
glsinkbin = gst_element_factory_make ("glsinkbin", NULL);
|
||||||
|
|
||||||
g_object_set (glsinkbin, "sink", sink, NULL);
|
g_object_set (glsinkbin, "sink", sink, NULL);
|
||||||
|
g_object_unref (ctx);
|
||||||
|
|
||||||
return glsinkbin;
|
return glsinkbin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (self->context != NULL)
|
||||||
|
{
|
||||||
|
g_warning ("GstGL context creation failed, falling back to non-GL playback");
|
||||||
|
|
||||||
|
g_object_unref (sink);
|
||||||
|
sink = g_object_new (GTK_TYPE_GST_SINK,
|
||||||
|
"paintable", self,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sink;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -417,7 +417,7 @@ check_win32_gst_gl_api (GdkGLContext *ctx,
|
|||||||
#define REACTIVATE_WGL_CONTEXT(ctx)
|
#define REACTIVATE_WGL_CONTEXT(ctx)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static gboolean
|
||||||
gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
||||||
{
|
{
|
||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
@ -425,6 +425,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
|||||||
GstGLPlatform platform = GST_GL_PLATFORM_NONE;
|
GstGLPlatform platform = GST_GL_PLATFORM_NONE;
|
||||||
GstGLAPI gl_api = GST_GL_API_NONE;
|
GstGLAPI gl_api = GST_GL_API_NONE;
|
||||||
guintptr gl_handle = 0;
|
guintptr gl_handle = 0;
|
||||||
|
gboolean succeeded = FALSE;
|
||||||
|
|
||||||
display = gdk_gl_context_get_display (self->gdk_context);
|
display = gdk_gl_context_get_display (self->gdk_context);
|
||||||
|
|
||||||
@ -465,7 +466,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext");
|
GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext");
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -491,7 +492,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext, not using Wayland EGL");
|
GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext, not using Wayland EGL");
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -522,10 +523,12 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
|||||||
#ifdef HAVE_GST_GL_DISPLAY_NEW_WITH_TYPE
|
#ifdef HAVE_GST_GL_DISPLAY_NEW_WITH_TYPE
|
||||||
self->gst_display = gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_WIN32);
|
self->gst_display = gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_WIN32);
|
||||||
#else
|
#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 ("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 ("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 ("set in the environment `GST_GL_PLATFORM=wgl` and `GST_GL_WINDOW=win32`,");
|
||||||
g_message ("and restart the GTK application");
|
g_message ("and restart the GTK application");
|
||||||
|
#endif
|
||||||
|
|
||||||
self->gst_display = gst_gl_display_new ();
|
self->gst_display = gst_gl_display_new ();
|
||||||
#endif
|
#endif
|
||||||
@ -545,14 +548,14 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext, not using %s", gl_type);
|
GST_ERROR_OBJECT (self, "Failed to get handle from GdkGLContext, not using %s", gl_type);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
GST_INFO_OBJECT (self, "Unsupported GDK display %s for GL", G_OBJECT_TYPE_NAME (display));
|
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);
|
g_assert (self->gst_app_context != NULL);
|
||||||
@ -565,8 +568,8 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
|||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
g_clear_object (&self->gst_app_context);
|
g_clear_object (&self->gst_app_context);
|
||||||
g_clear_object (&self->gst_display);
|
g_clear_object (&self->gst_display);
|
||||||
HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);;
|
HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -574,7 +577,9 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
|||||||
gst_gl_context_activate (self->gst_app_context, FALSE);
|
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);
|
GST_ERROR_OBJECT (self, "Couldn't create GL context: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
@ -584,6 +589,7 @@ gtk_gst_sink_initialize_gl (GtkGstSink *self)
|
|||||||
|
|
||||||
HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);
|
HANDLE_EXTERNAL_WGL_MAKE_CURRENT (self->gdk_context);
|
||||||
REACTIVATE_WGL_CONTEXT (self->gdk_context);
|
REACTIVATE_WGL_CONTEXT (self->gdk_context);
|
||||||
|
return succeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -605,8 +611,8 @@ gtk_gst_sink_set_property (GObject *object,
|
|||||||
|
|
||||||
case PROP_GL_CONTEXT:
|
case PROP_GL_CONTEXT:
|
||||||
self->gdk_context = g_value_dup_object (value);
|
self->gdk_context = g_value_dup_object (value);
|
||||||
if (self->gdk_context != NULL)
|
if (self->gdk_context != NULL && !gtk_gst_sink_initialize_gl (self))
|
||||||
gtk_gst_sink_initialize_gl (self);
|
g_clear_object (&self->gdk_context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -628,6 +634,9 @@ gtk_gst_sink_get_property (GObject *object,
|
|||||||
case PROP_PAINTABLE:
|
case PROP_PAINTABLE:
|
||||||
g_value_set_object (value, self->paintable);
|
g_value_set_object (value, self->paintable);
|
||||||
break;
|
break;
|
||||||
|
case PROP_GL_CONTEXT:
|
||||||
|
g_value_set_object (value, self->gdk_context);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
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"),
|
||||||
P_("GL context to use for rendering"),
|
P_("GL context to use for rendering"),
|
||||||
GDK_TYPE_GL_CONTEXT,
|
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);
|
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user