예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
/**
 * 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;
}