[852/906] use GstContext for GstGLDisplay propogation

implements the hooks required in GstElement::set_context and the context query
This commit is contained in:
Matthew Waters 2013-11-13 10:43:16 +11:00
parent f230ec14ba
commit 79260ff8f9
8 changed files with 390 additions and 49 deletions

View file

@ -28,11 +28,13 @@
#include "gl.h"
#include "gstgldisplay.h"
GST_DEBUG_CATEGORY_STATIC (gst_context);
GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
#define GST_CAT_DEFAULT gst_gl_display_debug
#define DEBUG_INIT \
GST_DEBUG_CATEGORY_INIT (gst_gl_display_debug, "gldisplay", 0, "opengl display");
GST_DEBUG_CATEGORY_INIT (gst_gl_display_debug, "gldisplay", 0, "opengl display"); \
GST_DEBUG_CATEGORY_GET (gst_context, "GST_CONTEXT");
G_DEFINE_TYPE_WITH_CODE (GstGLDisplay, gst_gl_display, G_TYPE_OBJECT,
DEBUG_INIT);
@ -66,6 +68,8 @@ gst_gl_display_init (GstGLDisplay * display)
display->gl_api = GST_GL_API_NONE;
GST_TRACE ("init %p", display);
gst_gl_memory_init ();
}
@ -79,6 +83,8 @@ gst_gl_display_finalize (GObject * object)
display->context = NULL;
}
GST_TRACE ("finalize %p", object);
G_OBJECT_CLASS (gst_gl_display_parent_class)->finalize (object);
}
@ -142,6 +148,11 @@ gst_context_set_gl_display (GstContext * context, GstGLDisplay * display)
{
GstStructure *s;
g_return_if_fail (context != NULL);
GST_CAT_LOG (gst_context, "setting GstGLDisplay(%p) on context(%p)", display,
context);
s = gst_context_writable_structure (context);
gst_structure_set (s, GST_GL_DISPLAY_CONTEXT_TYPE, GST_TYPE_GL_DISPLAY,
display, NULL);
@ -151,8 +162,17 @@ gboolean
gst_context_get_gl_display (GstContext * context, GstGLDisplay ** display)
{
const GstStructure *s;
gboolean ret;
g_return_val_if_fail (display != NULL, FALSE);
g_return_val_if_fail (context != NULL, FALSE);
s = gst_context_get_structure (context);
return gst_structure_get (s, GST_GL_DISPLAY_CONTEXT_TYPE,
ret = gst_structure_get (s, GST_GL_DISPLAY_CONTEXT_TYPE,
GST_TYPE_GL_DISPLAY, display, NULL);
GST_CAT_LOG (gst_context, "got GstGLDisplay(%p) from context(%p)", *display,
context);
return ret;
}

View file

@ -62,6 +62,8 @@ static void gst_gl_filter_set_property (GObject * object, guint prop_id,
static void gst_gl_filter_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_gl_filter_set_context (GstElement * element,
GstContext * context);
static gboolean gst_gl_filter_query (GstBaseTransform * trans,
GstPadDirection direction, GstQuery * query);
static GstCaps *gst_gl_filter_transform_caps (GstBaseTransform * bt,
@ -112,6 +114,8 @@ gst_gl_filter_class_init (GstGLFilterClass * klass)
gst_gl_filter_decide_allocation;
GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size = gst_gl_filter_get_unit_size;
element_class->set_context = gst_gl_filter_set_context;
g_object_class_install_property (gobject_class, PROP_OTHER_CONTEXT,
g_param_spec_object ("other-context",
"External OpenGL context",
@ -176,6 +180,14 @@ gst_gl_filter_get_property (GObject * object, guint prop_id,
}
}
static void
gst_gl_filter_set_context (GstElement * element, GstContext * context)
{
GstGLFilter *filter = GST_GL_FILTER (element);
gst_gl_handle_set_context (element, context, &filter->display);
}
static gboolean
gst_gl_filter_query (GstBaseTransform * trans, GstPadDirection direction,
GstQuery * query)
@ -186,13 +198,19 @@ gst_gl_filter_query (GstBaseTransform * trans, GstPadDirection direction,
filter = GST_GL_FILTER (trans);
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONTEXT:
{
res = gst_gl_handle_context_query ((GstElement *) filter, query,
&filter->display);
break;
}
case GST_QUERY_CUSTOM:
{
GstStructure *structure = gst_query_writable_structure (query);
if (direction == GST_PAD_SINK &&
gst_structure_has_name (structure, "gstgldisplay")) {
gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER,
filter->display, NULL);
gst_structure_has_name (structure, "gstglcontext")) {
gst_structure_set (structure, "gstglcontext", G_TYPE_POINTER,
filter->context, NULL);
res = TRUE;
} else
res =
@ -243,6 +261,10 @@ gst_gl_filter_reset (GstGLFilter * filter)
if (filter->other_context)
gst_object_unref (filter->other_context);
filter->other_context = NULL;
if (filter->context)
gst_object_unref (filter->context);
filter->context = NULL;
}
static gboolean
@ -251,28 +273,29 @@ gst_gl_filter_start (GstBaseTransform * bt)
GstGLFilter *filter = GST_GL_FILTER (bt);
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
GstStructure *structure;
GstQuery *display_query;
GstQuery *context_query;
const GValue *id_value;
structure = gst_structure_new_empty ("gstgldisplay");
display_query = gst_query_new_custom (GST_QUERY_CUSTOM, structure);
if (!gst_gl_ensure_display (filter, &filter->display))
return FALSE;
if (!gst_pad_peer_query (bt->srcpad, display_query)) {
structure = gst_structure_new_empty ("gstglcontext");
context_query = gst_query_new_custom (GST_QUERY_CUSTOM, structure);
if (!gst_pad_peer_query (bt->srcpad, context_query)) {
GST_WARNING
("Could not query GstGLDisplay from downstream (peer query failed)");
("Could not query GstGLContext from downstream (peer query failed)");
}
id_value = gst_structure_get_value (structure, "gstgldisplay");
id_value = gst_structure_get_value (structure, "gstglcontext");
if (G_VALUE_HOLDS_POINTER (id_value)) {
/* at least one gl element is after in our gl chain */
filter->display =
gst_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
filter->context = gst_gl_display_get_context (filter->display);
filter->context =
gst_object_ref (GST_GL_CONTEXT (g_value_get_pointer (id_value)));
} else {
GError *error = NULL;
GST_INFO ("Creating GstGLDisplay");
filter->display = gst_gl_display_new ();
GST_INFO ("Creating GstGLContext");
filter->context = gst_gl_context_new (filter->display);
if (!gst_gl_context_create (filter->context, filter->other_context, &error)) {
@ -282,6 +305,8 @@ gst_gl_filter_start (GstBaseTransform * bt)
}
}
gst_query_unref (context_query);
if (filter_class->onStart)
filter_class->onStart (filter);
@ -1067,6 +1092,9 @@ gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
filter = GST_GL_FILTER (bt);
filter_class = GST_GL_FILTER_GET_CLASS (bt);
if (!gst_gl_ensure_display (filter, &filter->display))
return GST_FLOW_NOT_NEGOTIATED;
g_assert (filter_class->filter || filter_class->filter_texture);
if (filter_class->filter)

View file

@ -65,7 +65,6 @@ struct _GstGLFilter
GstBufferPool *pool;
GstGLDisplay *display;
GstGLContext *context;
GstVideoInfo in_info;
GstVideoInfo out_info;
@ -81,6 +80,7 @@ struct _GstGLFilter
GstGLShader *default_shader;
GstGLContext *context;
GstGLContext *other_context;
};

View file

@ -60,6 +60,8 @@ static gboolean gst_gl_mixer_sink_event (GstCollectPads * pads,
GstCollectData * cdata, GstEvent * event, GstGLMixer * mix);
static gboolean gst_gl_mixer_src_setcaps (GstPad * pad, GstGLMixer * mix,
GstCaps * caps);
static void gst_gl_mixer_set_context (GstElement * element,
GstContext * context);
enum
{
@ -346,15 +348,21 @@ gst_gl_mixer_sink_query (GstCollectPads * pads, GstCollectData * data,
ret = TRUE;
break;
}
case GST_QUERY_CONTEXT:
{
ret = gst_gl_handle_context_query ((GstElement *) mix, query,
&mix->display);
break;
}
case GST_QUERY_CUSTOM:
{
/* mix is a sink in terms of gl chain, so we are sharing the gldisplay that
* comes from src pad with every display of the sink pads */
GstStructure *structure = gst_query_writable_structure (query);
if (gst_structure_has_name (structure, "gstgldisplay")) {
gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER,
mix->display, NULL);
if (gst_structure_has_name (structure, "gstglcontext")) {
gst_structure_set (structure, "gstglcontext", G_TYPE_POINTER,
mix->context, NULL);
} else {
ret = gst_collect_pads_query_default (pads, data, query, FALSE);
}
@ -513,6 +521,7 @@ gst_gl_mixer_class_init (GstGLMixerClass * klass)
GST_DEBUG_FUNCPTR (gst_gl_mixer_request_new_pad);
element_class->release_pad = GST_DEBUG_FUNCPTR (gst_gl_mixer_release_pad);
element_class->change_state = GST_DEBUG_FUNCPTR (gst_gl_mixer_change_state);
element_class->set_context = GST_DEBUG_FUNCPTR (gst_gl_mixer_set_context);
/* Register the pad class */
g_type_class_ref (GST_TYPE_GL_MIXER_PAD);
@ -845,6 +854,14 @@ gst_gl_mixer_read_qos (GstGLMixer * mix, gdouble * proportion,
GST_OBJECT_UNLOCK (mix);
}
static void
gst_gl_mixer_set_context (GstElement * element, GstContext * context)
{
GstGLMixer *mix = GST_GL_MIXER (element);
gst_gl_handle_set_context (element, context, &mix->display);
}
static gboolean
gst_gl_mixer_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
@ -852,6 +869,12 @@ gst_gl_mixer_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
gboolean res = FALSE;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONTEXT:
{
res = gst_gl_handle_context_query ((GstElement *) mix, query,
&mix->display);
break;
}
case GST_QUERY_POSITION:
{
GstFormat format;
@ -918,27 +941,29 @@ gst_gl_mixer_activate (GstGLMixer * mix, gboolean activate)
{
if (activate) {
GstStructure *structure;
GstQuery *display_query;
GstQuery *context_query;
const GValue *id_value;
structure = gst_structure_new_empty ("gstgldisplay");
display_query = gst_query_new_custom (GST_QUERY_CUSTOM, structure);
if (!gst_pad_peer_query (mix->srcpad, display_query)) {
GST_WARNING
("Could not query GstGLDisplay from downstream (peer query failed)");
if (!gst_gl_ensure_display (mix, &mix->display)) {
return FALSE;
}
id_value = gst_structure_get_value (structure, "gstgldisplay");
structure = gst_structure_new_empty ("gstglcontext");
context_query = gst_query_new_custom (GST_QUERY_CUSTOM, structure);
if (!gst_pad_peer_query (mix->srcpad, context_query)) {
GST_WARNING
("Could not query GstGLContext from downstream (peer query failed)");
}
id_value = gst_structure_get_value (structure, "gstglcontext");
if (G_VALUE_HOLDS_POINTER (id_value)) {
mix->display =
gst_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
mix->context = gst_gl_display_get_context (mix->display);
mix->context =
gst_object_ref (GST_GL_CONTEXT (g_value_get_pointer (id_value)));
} else {
GError *error = NULL;
GST_INFO ("Creating GstGLDisplay");
mix->display = gst_gl_display_new ();
mix->context = gst_gl_context_new (mix->display);
gst_gl_display_set_context (mix->display, mix->context);

View file

@ -365,3 +365,227 @@ gst_gl_context_del_shader (GstGLContext * context, GstGLShader * shader)
{
gst_object_unref (shader);
}
static gboolean
gst_gl_display_found (GstElement * element, GstGLDisplay * display)
{
if (display) {
GST_INFO_OBJECT (element, "already have a display (%p)", display);
return TRUE;
}
return FALSE;
}
GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT);
static gboolean
context_pad_query (const GValue * item, GValue * value, gpointer user_data)
{
GstPad *pad = g_value_get_object (item);
GstQuery *query = user_data;
gboolean res;
res = gst_pad_peer_query (pad, query);
if (res) {
g_value_set_boolean (value, TRUE);
return FALSE;
}
GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, pad, "context pad peer query failed");
return TRUE;
}
static gboolean
run_context_query (GstElement * element, GstQuery * query,
GstPadDirection direction)
{
GstIterator *it;
GstIteratorFoldFunction func = context_pad_query;
GValue res = { 0 };
g_value_init (&res, G_TYPE_BOOLEAN);
g_value_set_boolean (&res, FALSE);
/* Ask neighbor */
if (direction == GST_PAD_SRC)
it = gst_element_iterate_src_pads (element);
else
it = gst_element_iterate_sink_pads (element);
while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC)
gst_iterator_resync (it);
gst_iterator_free (it);
return g_value_get_boolean (&res);
}
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);
}
/* 4) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT
* message.
*/
static void
gst_gl_display_context_propagate (GstElement * element, GstGLDisplay * display)
{
GstContext *context;
GstMessage *msg;
if (!display) {
GST_ERROR_OBJECT (element, "Could not get GL display connection");
return;
}
context = gst_context_new (GST_GL_DISPLAY_CONTEXT_TYPE, TRUE);
gst_context_set_gl_display (context, display);
GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
"posting have context (%p) message with display (%p)", context, display);
msg = gst_message_new_have_context (GST_OBJECT_CAST (element), context);
gst_element_post_message (GST_ELEMENT_CAST (element), msg);
}
gboolean
gst_gl_ensure_display (gpointer element, GstGLDisplay ** display_ptr)
{
GstGLDisplay *display;
g_return_val_if_fail (element != NULL, FALSE);
g_return_val_if_fail (display_ptr != NULL, FALSE);
/* 1) Check if the element already has a context of the specific
* type.
*/
display = *display_ptr;
if (gst_gl_display_found (element, display))
return TRUE;
gst_gl_display_context_prepare (element, display_ptr);
/* Neighbour found and it updated the display */
if (gst_gl_display_found (element, *display_ptr))
return TRUE;
/* If no neighboor, or application not interested, use system default */
display = gst_gl_display_new ();
*display_ptr = display;
gst_gl_display_context_propagate (element, display);
return display != NULL;
}
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;
}
gboolean
gst_gl_handle_context_query (GstElement * element, GstQuery * query,
GstGLDisplay ** display)
{
gboolean res = FALSE;
const gchar *context_type;
GstContext *context, *old_context;
g_return_val_if_fail (element != NULL, FALSE);
g_return_val_if_fail (query != NULL, FALSE);
g_return_val_if_fail (display != NULL, FALSE);
gst_query_parse_context_type (query, &context_type);
if (g_strcmp0 (context_type, GST_GL_DISPLAY_CONTEXT_TYPE) == 0) {
gst_query_parse_context (query, &old_context);
if (old_context)
context = gst_context_copy (old_context);
else
context = gst_context_new (GST_GL_DISPLAY_CONTEXT_TYPE, TRUE);
gst_context_set_gl_display (context, *display);
gst_query_set_context (query, context);
gst_context_unref (context);
res = *display != NULL;
}
return res;
}

View file

@ -102,4 +102,10 @@ gboolean gst_gl_context_check_framebuffer_status (GstGLContext * context);
void gst_gl_context_set_error (GstGLContext * context, const char * format, ...);
gchar *gst_gl_context_get_error (void);
gboolean gst_gl_ensure_display (gpointer element, GstGLDisplay **display_ptr);
gboolean gst_gl_handle_set_context (GstElement * element, GstContext * context,
GstGLDisplay ** display);
gboolean gst_gl_handle_context_query (GstElement * element, GstQuery * query,
GstGLDisplay ** display);
#endif /* __GST_GL_UTILS_H__ */

View file

@ -121,6 +121,8 @@ static void gst_glimage_sink_get_property (GObject * object, guint prop_id,
static gboolean gst_glimage_sink_stop (GstBaseSink * bsink);
static gboolean gst_glimage_sink_query (GstBaseSink * bsink, GstQuery * query);
static void gst_glimage_sink_set_context (GstElement * element,
GstContext * context);
static GstStateChangeReturn
gst_glimage_sink_change_state (GstElement * element, GstStateChange transition);
@ -245,7 +247,7 @@ gst_glimage_sink_class_init (GstGLImageSinkClass * klass)
gobject_class->finalize = gst_glimage_sink_finalize;
gstelement_class->change_state = gst_glimage_sink_change_state;
gstelement_class->set_context = gst_glimage_sink_set_context;
gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_glimage_sink_query);
gstbasesink_class->set_caps = gst_glimage_sink_set_caps;
gstbasesink_class->get_times = gst_glimage_sink_get_times;
@ -373,12 +375,18 @@ gst_glimage_sink_query (GstBaseSink * bsink, GstQuery * query)
gboolean res = FALSE;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONTEXT:
{
return gst_gl_handle_context_query ((GstElement *) glimage_sink, query,
&glimage_sink->display);
break;
}
case GST_QUERY_CUSTOM:
{
GstStructure *structure = gst_query_writable_structure (query);
if (gst_structure_has_name (structure, "gstgldisplay")) {
gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER,
glimage_sink->display, NULL);
if (gst_structure_has_name (structure, "gstglcontext")) {
gst_structure_set (structure, "gstglcontext", G_TYPE_POINTER,
glimage_sink->context, NULL);
res = TRUE;
} else
res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
@ -420,6 +428,14 @@ gst_glimage_sink_stop (GstBaseSink * bsink)
return TRUE;
}
static void
gst_glimage_sink_set_context (GstElement * element, GstContext * context)
{
GstGLImageSink *gl_sink = GST_GLIMAGE_SINK (element);
gst_gl_handle_set_context (element, context, &gl_sink->display);
}
static GstStateChangeReturn
gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
{
@ -439,8 +455,9 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
GstGLWindow *window;
GError *error = NULL;
GST_INFO ("Creating GstGLDisplay");
glimage_sink->display = gst_gl_display_new ();
if (!gst_gl_ensure_display (glimage_sink, &glimage_sink->display))
return GST_STATE_CHANGE_FAILURE;
glimage_sink->context = gst_gl_context_new (glimage_sink->display);
gst_gl_display_set_context (glimage_sink->display,
glimage_sink->context);
@ -691,6 +708,9 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
return GST_FLOW_NOT_NEGOTIATED;
}
if (!gst_gl_ensure_display (bsink, &glimage_sink->display))
return GST_FLOW_NOT_NEGOTIATED;
if (!gst_video_frame_map (&frame, &glimage_sink->info, buf,
GST_MAP_READ | GST_MAP_GL)) {
GST_WARNING ("Failed to map memory");

View file

@ -78,6 +78,8 @@ static gboolean gst_gl_test_src_is_seekable (GstBaseSrc * psrc);
static gboolean gst_gl_test_src_do_seek (GstBaseSrc * bsrc,
GstSegment * segment);
static gboolean gst_gl_test_src_query (GstBaseSrc * bsrc, GstQuery * query);
static void gst_gl_test_src_set_context (GstElement * element,
GstContext * context);
static void gst_gl_test_src_get_times (GstBaseSrc * basesrc,
GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
@ -160,6 +162,8 @@ gst_gl_test_src_class_init (GstGLTestSrcClass * klass)
gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
gst_caps_from_string (GST_GL_DOWNLOAD_VIDEO_CAPS)));
element_class->set_context = gst_gl_test_src_set_context;
gstbasesrc_class->set_caps = gst_gl_test_src_setcaps;
gstbasesrc_class->is_seekable = gst_gl_test_src_is_seekable;
gstbasesrc_class->do_seek = gst_gl_test_src_do_seek;
@ -336,16 +340,29 @@ context_error:
}
}
static void
gst_gl_test_src_set_context (GstElement * element, GstContext * context)
{
GstGLTestSrc *src = GST_GL_TEST_SRC (element);
gst_gl_handle_set_context (element, context, &src->display);
}
static gboolean
gst_gl_test_src_query (GstBaseSrc * bsrc, GstQuery * query)
{
gboolean res;
gboolean res = FALSE;
GstGLTestSrc *src;
src = GST_GL_TEST_SRC (bsrc);
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONTEXT:
{
res = gst_gl_handle_context_query ((GstElement *) src, query,
&src->display);
break;
}
case GST_QUERY_CONVERT:
{
GstFormat src_fmt, dest_fmt;
@ -544,28 +561,29 @@ gst_gl_test_src_start (GstBaseSrc * basesrc)
{
GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc);
GstStructure *structure;
GstQuery *display_query;
GstQuery *context_query;
const GValue *id_value;
structure = gst_structure_new_empty ("gstgldisplay");
display_query = gst_query_new_custom (GST_QUERY_CUSTOM, structure);
if (!gst_gl_ensure_display (src, &src->display))
return FALSE;
if (!gst_pad_peer_query (basesrc->srcpad, display_query)) {
structure = gst_structure_new_empty ("gstglcontext");
context_query = gst_query_new_custom (GST_QUERY_CUSTOM, structure);
if (!gst_pad_peer_query (basesrc->srcpad, context_query)) {
GST_WARNING
("Could not query GstGLDisplay from downstream (peer query failed)");
("Could not query GstGLContext from downstream (peer query failed)");
}
id_value = gst_structure_get_value (structure, "gstgldisplay");
id_value = gst_structure_get_value (structure, "gstglcontext");
if (G_VALUE_HOLDS_POINTER (id_value)) {
/* at least one gl element is after in our gl chain */
src->display =
gst_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
src->context = gst_gl_display_get_context (src->display);
src->context =
gst_object_ref (GST_GL_CONTEXT (g_value_get_pointer (id_value)));
} else {
GError *error = NULL;
GST_INFO ("Creating GstGLDisplay");
src->display = gst_gl_display_new ();
src->context = gst_gl_context_new (src->display);
gst_gl_display_set_context (src->display, src->context);