Ejemplo n.º 1
0
GstQuery *
gst_vulkan_local_context_query (GstElement * element,
    const gchar * context_type, gboolean set_context)
{
  GstQuery *query;
  GstContext *ctxt;

  _init_context_debug ();

  /*  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.
   */
  query = gst_query_new_context (context_type);
  if (gst_vulkan_run_query (element, query, GST_PAD_SRC)) {
    gst_query_parse_context (query, &ctxt);
    GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
        "found context (%p) in downstream query", ctxt);
    if (set_context)
      gst_element_set_context (element, ctxt);
  } else if (gst_vulkan_run_query (element, query, GST_PAD_SINK)) {
    gst_query_parse_context (query, &ctxt);
    GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
        "found context (%p) in upstream query", ctxt);
    if (set_context)
      gst_element_set_context (element, ctxt);
  } else {
    gst_query_unref (query);
    query = NULL;
  }

  return query;
}
Ejemplo n.º 2
0
/**
 * gst_gl_query_local_gl_context:
 * @element: a #GstElement to query from
 * @direction: the #GstPadDirection to query
 * @context_ptr: (inout): location containing the current and/or resulting
 *                      #GstGLContext
 *
 * Performs a GST_QUERY_CONTEXT query of type "gst.gl.local_context" on all
 * #GstPads in @element of @direction for the local OpenGL context used by
 * GStreamer elements.
 *
 * Returns: whether @context_ptr contains a #GstGLContext
 */
gboolean
gst_gl_query_local_gl_context (GstElement * element, GstPadDirection direction,
    GstGLContext ** context_ptr)
{
  GstQuery *query;
  GstContext *context;
  const GstStructure *s;

  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
  g_return_val_if_fail (context_ptr != NULL, FALSE);

  if (*context_ptr)
    return TRUE;

  query = gst_query_new_context ("gst.gl.local_context");
  if (gst_gl_run_query (GST_ELEMENT (element), query, direction)) {
    gst_query_parse_context (query, &context);
    if (context) {
      s = gst_context_get_structure (context);
      gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, context_ptr, NULL);
    }
  }

  gst_query_unref (query);

  return *context_ptr != NULL;
}
Ejemplo n.º 3
0
static gboolean
gst_wayland_sink_find_display (GstWaylandSink * sink)
{
  GstQuery *query;
  GstMessage *msg;
  GstContext *context = NULL;
  GError *error = NULL;
  gboolean ret = TRUE;

  g_mutex_lock (&sink->display_lock);

  if (!sink->display) {
    /* first query upstream for the needed display handle */
    query = gst_query_new_context (GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE);
    if (gst_pad_peer_query (GST_VIDEO_SINK_PAD (sink), query)) {
      gst_query_parse_context (query, &context);
      gst_wayland_sink_set_display_from_context (sink, context);
    }
    gst_query_unref (query);

    if (G_LIKELY (!sink->display)) {
      /* now ask the application to set the display handle */
      msg = gst_message_new_need_context (GST_OBJECT_CAST (sink),
          GST_WAYLAND_DISPLAY_HANDLE_CONTEXT_TYPE);

      g_mutex_unlock (&sink->display_lock);
      gst_element_post_message (GST_ELEMENT_CAST (sink), msg);
      /* at this point we expect gst_wayland_sink_set_context
       * to get called and fill sink->display */
      g_mutex_lock (&sink->display_lock);

      if (!sink->display) {
        /* if the application didn't set a display, let's create it ourselves */
        GST_OBJECT_LOCK (sink);
        sink->display = gst_wl_display_new (sink->display_name, &error);
        GST_OBJECT_UNLOCK (sink);

        if (error) {
          GST_ELEMENT_WARNING (sink, RESOURCE, OPEN_READ_WRITE,
              ("Could not initialise Wayland output"),
              ("Failed to create GstWlDisplay: '%s'", error->message));
          g_error_free (error);
          ret = FALSE;
        } else {
          /* inform the world about the new display */
          context =
              gst_wayland_display_handle_context_new (sink->display->display);
          msg = gst_message_new_have_context (GST_OBJECT_CAST (sink), context);
          gst_element_post_message (GST_ELEMENT_CAST (sink), msg);
        }
      }
    }
  }

  g_mutex_unlock (&sink->display_lock);

  return ret;
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
static void
_gst_context_query (GstElement * element, const gchar * display_type)
{
  GstQuery *query;
  GstContext *ctxt;

  _init_context_debug ();

  /*  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.
   */
  query = gst_query_new_context (display_type);
  if (gst_gl_run_query (element, query, GST_PAD_SRC)) {
    gst_query_parse_context (query, &ctxt);
    GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
        "found context (%p) in downstream query", ctxt);
    gst_element_set_context (element, ctxt);
  } else if (gst_gl_run_query (element, query, GST_PAD_SINK)) {
    gst_query_parse_context (query, &ctxt);
    GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
        "found context (%p) in upstream query", ctxt);
    gst_element_set_context (element, 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),
        display_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().
   */

  gst_query_unref (query);
}
static void
_gst_context_query (GstElement * element, const gchar * context_type)
{
  GstQuery *query;
  GstMessage *msg;

  _init_context_debug ();

  /* 2) Query downstream with GST_QUERY_CONTEXT for the context and
     check if downstream already has a context of the specific
     type */
  /* 3) Query upstream with GST_QUERY_CONTEXT for the context and
     check if upstream already has a context of the specific
     type */
  query = gst_query_new_context (context_type);
  if (_gst_context_get_from_query (element, query, GST_PAD_SRC))
    goto found;
  if (_gst_context_get_from_query (element, query, GST_PAD_SINK))
    goto found;

  /* 4) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with
     the required context types and afterwards check if an
     usable context was set now as in 1). The message could
     be handled by the parent bins of the element and the
     application. */
  GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
      "posting `need-context' message");
  msg = gst_message_new_need_context (GST_OBJECT_CAST (element), 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
   */

found:
  gst_query_unref (query);
}
Ejemplo n.º 7
0
static gboolean
_find_local_gl_context (GstGLStereoSplit * split)
{
  GstQuery *query;
  GstContext *context;
  const GstStructure *s;

  if (split->context)
    return TRUE;

  query = gst_query_new_context ("gst.gl.local_context");
  if (!split->context
      && gst_gl_run_query (GST_ELEMENT (split), query, GST_PAD_SRC)) {
    gst_query_parse_context (query, &context);
    if (context) {
      s = gst_context_get_structure (context);
      gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &split->context,
          NULL);
    }
  }
  if (!split->context
      && gst_gl_run_query (GST_ELEMENT (split), query, GST_PAD_SINK)) {
    gst_query_parse_context (query, &context);
    if (context) {
      s = gst_context_get_structure (context);
      gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &split->context,
          NULL);
    }
  }

  GST_DEBUG_OBJECT (split, "found local context %p", split->context);

  gst_query_unref (query);

  if (split->context)
    return TRUE;

  return FALSE;
}
gboolean
gst_vaapi_find_gl_local_context (GstElement * element,
    GstObject ** gl_context_ptr)
{
#if USE_GST_GL_HELPERS
  GstQuery *query;
  GstContext *context;
  const GstStructure *s;
  GstObject *gl_context;

  g_return_val_if_fail (gl_context_ptr, FALSE);

  gl_context = NULL;
  query = gst_query_new_context ("gst.gl.local_context");
  if (_gst_context_run_query (element, query, GST_PAD_SRC)) {
    gst_query_parse_context (query, &context);
    if (context) {
      s = gst_context_get_structure (context);
      gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL);
    }
  }
  if (!gl_context && _gst_context_run_query (element, query, GST_PAD_SINK)) {
    gst_query_parse_context (query, &context);
    if (context) {
      s = gst_context_get_structure (context);
      gst_structure_get (s, "context", GST_TYPE_GL_CONTEXT, &gl_context, NULL);
    }
  }
  gst_query_unref (query);
  if (gl_context) {
    *gl_context_ptr = gl_context;
    return TRUE;
  }
#endif
  return FALSE;
}
Ejemplo n.º 9
0
static gboolean
gst_vtdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
{
  gboolean ret;
  GstCaps *caps;
  GstCapsFeatures *features;
  GstVtdec *vtdec = GST_VTDEC (decoder);

  ret =
      GST_VIDEO_DECODER_CLASS (gst_vtdec_parent_class)->decide_allocation
      (decoder, query);
  if (!ret)
    goto out;

  gst_query_parse_allocation (query, &caps, NULL);
  if (caps) {
    GstGLContext *gl_context = NULL;
    features = gst_caps_get_features (caps, 0);

    if (gst_caps_features_contains (features,
            GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) {
      GstContext *context = NULL;
      GstQuery *query = gst_query_new_context ("gst.gl.local_context");
      if (gst_pad_peer_query (GST_VIDEO_DECODER_SRC_PAD (decoder), query)) {

        gst_query_parse_context (query, &context);
        if (context) {
          const GstStructure *s = gst_context_get_structure (context);
          gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &gl_context,
              NULL);
        }
      }
      gst_query_unref (query);

      if (context) {
        GstVideoFormat internal_format;
        GstVideoCodecState *output_state =
            gst_video_decoder_get_output_state (decoder);

        GST_INFO_OBJECT (decoder, "pushing textures. GL context %p", context);
        if (vtdec->texture_cache)
          gst_core_video_texture_cache_free (vtdec->texture_cache);

#ifdef HAVE_IOS
        internal_format = GST_VIDEO_FORMAT_NV12;
#else
        internal_format = GST_VIDEO_FORMAT_UYVY;
#endif
        vtdec->texture_cache = gst_core_video_texture_cache_new (gl_context);
        gst_core_video_texture_cache_set_format (vtdec->texture_cache,
            internal_format, output_state->caps);
        gst_video_codec_state_unref (output_state);
        gst_object_unref (gl_context);
      } else {
        GST_WARNING_OBJECT (decoder,
            "got memory:GLMemory caps but not GL context from downstream element");
      }
    }
  }

out:
  return ret;
}