gboolean gst_gl_handle_set_context (GstElement * element, GstContext * context, GstGLDisplay ** display) { GstGLDisplay *replacement = NULL; const gchar *context_type; g_return_val_if_fail (display, FALSE); if (!context) return FALSE; context_type = gst_context_get_context_type (context); if (g_strcmp0 (context_type, GST_GL_DISPLAY_CONTEXT_TYPE) == 0) { if (!gst_context_get_gl_display (context, &replacement)) { GST_WARNING_OBJECT (element, "Failed to get display from context"); return FALSE; } } if (replacement) gst_object_replace ((GstObject **) display, (GstObject *) replacement); return TRUE; }
static void gst_gl_display_context_prepare (GstElement * element, GstGLDisplay ** display_ptr) { GstContext *ctxt; GstQuery *query; if (!GST_CAT_CONTEXT) GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"); /* 2a) Query downstream with GST_QUERY_CONTEXT for the context and * check if downstream already has a context of the specific type * 2b) Query upstream as above. */ ctxt = NULL; query = gst_query_new_context (GST_GL_DISPLAY_CONTEXT_TYPE); if (run_context_query (element, query, GST_PAD_SRC)) { GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "found context (%p) in downstream query", ctxt); gst_query_parse_context (query, &ctxt); } else if (run_context_query (element, query, GST_PAD_SINK)) { GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "found context (%p) in upstream query", ctxt); gst_query_parse_context (query, &ctxt); } else { /* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with * the required context type and afterwards check if a * usable context was set now as in 1). The message could * be handled by the parent bins of the element and the * application. */ GstMessage *msg; GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, "posting need context message"); msg = gst_message_new_need_context (GST_OBJECT_CAST (element), GST_GL_DISPLAY_CONTEXT_TYPE); gst_element_post_message (element, msg); } /* * Whomever responds to the need-context message performs a * GstElement::set_context() with the required context in which the element * is required to update the display_ptr or call gst_gl_handle_set_context(). */ if (ctxt) { if (gst_context_has_context_type (ctxt, GST_GL_DISPLAY_CONTEXT_TYPE)) { gst_context_get_gl_display (ctxt, display_ptr); } } gst_query_unref (query); }
static void gst_gl_display_context_query (GstElement * element, GstGLDisplay ** display_ptr) { GstContext *ctxt; GstQuery *query; #ifndef GST_DISABLE_GST_DEBUG if (!GST_CAT_CONTEXT) GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"); #endif query = _gst_context_query (element, display_ptr, GST_GL_DISPLAY_CONTEXT_TYPE); gst_query_parse_context (query, &ctxt); if (ctxt && gst_context_has_context_type (ctxt, GST_GL_DISPLAY_CONTEXT_TYPE)) gst_context_get_gl_display (ctxt, display_ptr); if (*display_ptr) goto out; #if GST_GL_HAVE_WINDOW_X11 gst_query_unref (query); query = _gst_context_query (element, display_ptr, "gst.x11.display.handle"); gst_query_parse_context (query, &ctxt); if (ctxt && gst_context_has_context_type (ctxt, "gst.x11.display.handle")) { const GstStructure *s; Display *display; s = gst_context_get_structure (ctxt); if (gst_structure_get (s, "display", G_TYPE_POINTER, &display, NULL) && display) { *display_ptr = (GstGLDisplay *) gst_gl_display_x11_new_with_display (display); } } if (*display_ptr) goto out; #endif out: gst_query_unref (query); }
/** * gst_gl_handle_set_context: * @element: a #GstElement * @context: a #GstContext * @display: (inout) (transfer full): location of a #GstGLDisplay * @other_context: (inout) (transfer full): location of a #GstGLContext * * Helper function for implementing GstElement::set_context() in OpenGL capable * elements. * * Retrieve's the #GstGLDisplay or #GstGLContext in @context and places the * result in @display or @other_context respectively. * * Returns: whether the @display or @other_context could be set successfully */ gboolean gst_gl_handle_set_context (GstElement * element, GstContext * context, GstGLDisplay ** display, GstGLContext ** other_context) { GstGLDisplay *display_replacement = NULL; GstGLContext *context_replacement = NULL; const gchar *context_type; g_return_val_if_fail (display != NULL, FALSE); g_return_val_if_fail (other_context != NULL, FALSE); if (!context) return FALSE; context_type = gst_context_get_context_type (context); if (g_strcmp0 (context_type, GST_GL_DISPLAY_CONTEXT_TYPE) == 0) { if (!gst_context_get_gl_display (context, &display_replacement)) { GST_WARNING_OBJECT (element, "Failed to get display from context"); return FALSE; } } #if GST_GL_HAVE_WINDOW_X11 else if (g_strcmp0 (context_type, "gst.x11.display.handle") == 0) { const GstStructure *s; Display *display; s = gst_context_get_structure (context); if (gst_structure_get (s, "display", G_TYPE_POINTER, &display, NULL)) display_replacement = (GstGLDisplay *) gst_gl_display_x11_new_with_display (display); } #endif #if GST_GL_HAVE_WINDOW_WAYLAND else if (g_strcmp0 (context_type, "GstWaylandDisplayHandleContextType") == 0) { const GstStructure *s; struct wl_display *display; s = gst_context_get_structure (context); if (gst_structure_get (s, "display", G_TYPE_POINTER, &display, NULL)) display_replacement = (GstGLDisplay *) gst_gl_display_wayland_new_with_display (display); } #endif else if (g_strcmp0 (context_type, "gst.gl.app_context") == 0) { const GstStructure *s = gst_context_get_structure (context); GstGLDisplay *context_display; GstGLDisplay *element_display; if (gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &context_replacement, NULL)) { context_display = gst_gl_context_get_display (context_replacement); element_display = display_replacement ? display_replacement : *display; if (element_display && (gst_gl_display_get_handle_type (element_display) & gst_gl_display_get_handle_type (context_display)) == 0) { GST_ELEMENT_WARNING (element, LIBRARY, SETTINGS, ("%s", "Cannot set a GL context with a different display type"), ("%s", "Cannot set a GL context with a different display type")); gst_object_unref (context_replacement); context_replacement = NULL; } gst_object_unref (context_display); } } if (display_replacement) { GstGLDisplay *old = *display; *display = display_replacement; if (old) gst_object_unref (old); } if (context_replacement) { GstGLContext *old = *other_context; *other_context = context_replacement; if (old) gst_object_unref (old); } return TRUE; }