mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-29 20:35:40 +00:00
[385/906] rewrite the way a gstgldisplay is transmited to the gl elements
Before, a gstgldisplay was instancied by the gl src in terms of gl chain. And then the next element got it through the first gstglbuffer. Now, this is done though queries. All glelements get their ref on a gstgldisplay in READY state. This rewrite is mainly a first step to be able to share OpenGL context hold by the gstgldisplay using more complex glelements. For example, with a glvideomixer. The associated gstgldisplay of each gl chain of the sink pads will share their OpenGL context.
This commit is contained in:
parent
3b0a88850d
commit
65f4d40e6d
8 changed files with 275 additions and 118 deletions
|
@ -55,6 +55,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 gboolean gst_gl_filter_src_query (GstPad *pad, GstQuery * query);
|
||||
|
||||
static GstCaps *gst_gl_filter_transform_caps (GstBaseTransform * bt,
|
||||
GstPadDirection direction, GstCaps * caps);
|
||||
static void gst_gl_filter_reset (GstGLFilter * filter);
|
||||
|
@ -118,10 +120,10 @@ gst_gl_filter_class_init (GstGLFilterClass * klass)
|
|||
static void
|
||||
gst_gl_filter_init (GstGLFilter * filter, GstGLFilterClass * klass)
|
||||
{
|
||||
//gst_element_create_all_pads (GST_ELEMENT (filter));
|
||||
|
||||
filter->sinkpad = gst_element_get_static_pad (GST_ELEMENT (filter), "sink");
|
||||
filter->srcpad = gst_element_get_static_pad (GST_ELEMENT (filter), "src");
|
||||
GstBaseTransform *base_trans = GST_BASE_TRANSFORM (filter);
|
||||
|
||||
gst_pad_set_query_function (base_trans->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_gl_filter_src_query));
|
||||
|
||||
gst_gl_filter_reset (filter);
|
||||
}
|
||||
|
@ -152,6 +154,36 @@ gst_gl_filter_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_filter_src_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
GstElement *parent = GST_ELEMENT (gst_pad_get_parent (pad));
|
||||
GstGLFilter *filter = GST_GL_FILTER (parent);
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CUSTOM:
|
||||
{
|
||||
GstStructure *structure = gst_query_get_structure (query);
|
||||
if (filter->display) {
|
||||
/* this gl filter is a sink in terms of the gl chain */
|
||||
gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER, filter->display, NULL);
|
||||
} else {
|
||||
/* at least one gl element is before in our gl chain */
|
||||
res = g_strcmp0 (gst_element_get_name (parent), gst_structure_get_name (structure)) == 0;
|
||||
}
|
||||
if (!res)
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_filter_reset (GstGLFilter * filter)
|
||||
{
|
||||
|
@ -181,6 +213,27 @@ gst_gl_filter_start (GstBaseTransform * bt)
|
|||
{
|
||||
GstGLFilter *filter = GST_GL_FILTER (bt);
|
||||
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
||||
GstElement *parent = GST_ELEMENT (gst_element_get_parent (filter));
|
||||
GstStructure *structure = gst_structure_new (gst_element_get_name (filter), NULL);
|
||||
GstQuery *query = gst_query_new_application (GST_QUERY_CUSTOM, structure);
|
||||
|
||||
gboolean isPerformed = gst_element_query (parent, query);
|
||||
|
||||
if (isPerformed) {
|
||||
const GValue *id_value = gst_structure_get_value (structure, "gstgldisplay");
|
||||
if (G_VALUE_HOLDS_POINTER (id_value))
|
||||
/* at least one gl element is before in our gl chain */
|
||||
filter->display = g_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
||||
else
|
||||
/* this gl filter is a sink in terms of the gl chain */
|
||||
filter->display = gst_gl_display_new ();
|
||||
}
|
||||
|
||||
gst_query_unref (query);
|
||||
gst_object_unref (GST_OBJECT (parent));
|
||||
|
||||
if (!isPerformed)
|
||||
return FALSE;
|
||||
|
||||
if (filter_class->onStart)
|
||||
filter_class->onStart (filter);
|
||||
|
@ -275,24 +328,6 @@ gst_gl_filter_prepare_output_buffer (GstBaseTransform * trans,
|
|||
|
||||
filter = GST_GL_FILTER (trans);
|
||||
|
||||
if (filter->display == NULL) {
|
||||
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
||||
|
||||
filter->display = g_object_ref (gl_inbuf->display);
|
||||
|
||||
//blocking call, generate a FBO
|
||||
gst_gl_display_gen_fbo (filter->display, filter->width, filter->height,
|
||||
&filter->fbo, &filter->depthbuffer);
|
||||
|
||||
if (filter_class->display_init_cb != NULL) {
|
||||
gst_gl_display_thread_add (filter->display, gst_gl_filter_start_gl,
|
||||
filter);
|
||||
}
|
||||
|
||||
if (filter_class->onInitFBO)
|
||||
filter_class->onInitFBO (filter);
|
||||
}
|
||||
|
||||
gl_outbuf = gst_gl_buffer_new (filter->display,
|
||||
filter->width, filter->height);
|
||||
|
||||
|
@ -313,8 +348,23 @@ gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
|
|||
gboolean ret = FALSE;
|
||||
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
||||
|
||||
if (!filter->display)
|
||||
return FALSE;
|
||||
|
||||
ret = gst_gl_buffer_parse_caps (outcaps, &filter->width, &filter->height);
|
||||
|
||||
//blocking call, generate a FBO
|
||||
gst_gl_display_gen_fbo (filter->display, filter->width, filter->height,
|
||||
&filter->fbo, &filter->depthbuffer);
|
||||
|
||||
if (filter_class->display_init_cb != NULL) {
|
||||
gst_gl_display_thread_add (filter->display, gst_gl_filter_start_gl,
|
||||
filter);
|
||||
}
|
||||
|
||||
if (filter_class->onInitFBO)
|
||||
filter_class->onInitFBO (filter);
|
||||
|
||||
if (filter_class->set_caps)
|
||||
filter_class->set_caps (filter, incaps, outcaps);
|
||||
|
||||
|
|
|
@ -57,9 +57,6 @@ struct _GstGLFilter
|
|||
{
|
||||
GstBaseTransform base_transform;
|
||||
|
||||
GstPad *srcpad;
|
||||
GstPad *sinkpad;
|
||||
|
||||
GstGLDisplay *display;
|
||||
|
||||
gint width;
|
||||
|
|
|
@ -168,6 +168,7 @@ gst_gl_bumper_init_resources (GstGLFilter * filter)
|
|||
guint y = 0;
|
||||
guchar *raw_data = NULL;
|
||||
guchar **rows = NULL;
|
||||
png_byte magic[8];
|
||||
|
||||
if (!filter->display)
|
||||
return;
|
||||
|
@ -177,6 +178,16 @@ gst_gl_bumper_init_resources (GstGLFilter * filter)
|
|||
if ((fp = fopen (bumper->location, "rb")) == NULL)
|
||||
LOAD_ERROR ("file not found");
|
||||
|
||||
/* Read magic number */
|
||||
fread (magic, 1, sizeof (magic), fp);
|
||||
|
||||
/* Check for valid magic number */
|
||||
if (!png_check_sig (magic, sizeof (magic)))
|
||||
{
|
||||
fclose (fp);
|
||||
LOAD_ERROR ("not a valid PNG image");
|
||||
}
|
||||
|
||||
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
|
||||
if (png_ptr == NULL) {
|
||||
|
|
|
@ -135,6 +135,8 @@ static void gst_gl_download_set_property (GObject * object, guint prop_id,
|
|||
static void gst_gl_download_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_gl_download_src_query (GstPad *pad, GstQuery * query);
|
||||
|
||||
static void gst_gl_download_reset (GstGLDownload * download);
|
||||
static gboolean gst_gl_download_set_caps (GstBaseTransform * bt,
|
||||
GstCaps * incaps, GstCaps * outcaps);
|
||||
|
@ -185,6 +187,11 @@ gst_gl_download_class_init (GstGLDownloadClass * klass)
|
|||
static void
|
||||
gst_gl_download_init (GstGLDownload * download, GstGLDownloadClass * klass)
|
||||
{
|
||||
GstBaseTransform *base_trans = GST_BASE_TRANSFORM (download);
|
||||
|
||||
gst_pad_set_query_function (base_trans->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_gl_download_src_query));
|
||||
|
||||
gst_gl_download_reset (download);
|
||||
}
|
||||
|
||||
|
@ -216,6 +223,27 @@ gst_gl_download_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_download_src_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
GstGLDownload *download = GST_GL_DOWNLOAD (gst_pad_get_parent (pad));
|
||||
gboolean res = FALSE;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CUSTOM:
|
||||
{
|
||||
GstStructure *structure = gst_query_get_structure (query);
|
||||
gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER, download->display, NULL);
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_download_reset (GstGLDownload * download)
|
||||
|
@ -230,7 +258,9 @@ gst_gl_download_reset (GstGLDownload * download)
|
|||
static gboolean
|
||||
gst_gl_download_start (GstBaseTransform * bt)
|
||||
{
|
||||
//GstGLDownload* download = GST_GL_DOWNLOAD (bt);
|
||||
GstGLDownload* download = GST_GL_DOWNLOAD (bt);
|
||||
|
||||
download->display = gst_gl_display_new ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -319,6 +349,15 @@ gst_gl_download_set_caps (GstBaseTransform * bt, GstCaps * incaps,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!download->display) {
|
||||
GST_ERROR ("display is null");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//blocking call, init color space conversion if needed
|
||||
gst_gl_display_init_download (download->display, download->video_format,
|
||||
download->width, download->height);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -353,15 +392,6 @@ gst_gl_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
|||
GstGLDownload *download = GST_GL_DOWNLOAD (trans);
|
||||
GstGLBuffer *gl_inbuf = GST_GL_BUFFER (inbuf);
|
||||
|
||||
if (download->display == NULL) {
|
||||
download->display = g_object_ref (gl_inbuf->display);
|
||||
|
||||
//blocking call, init color space conversion if needed
|
||||
gst_gl_display_init_download (download->display, download->video_format,
|
||||
download->width, download->height);
|
||||
} else
|
||||
g_assert (download->display == gl_inbuf->display);
|
||||
|
||||
GST_DEBUG ("making video %p size %d",
|
||||
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf));
|
||||
|
||||
|
|
|
@ -98,6 +98,8 @@ static void gst_glimage_sink_set_property (GObject * object, guint prop_id,
|
|||
static void gst_glimage_sink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * param_spec);
|
||||
|
||||
static gboolean gst_glimage_sink_query (GstElement * element, GstQuery * query);
|
||||
|
||||
static GstStateChangeReturn
|
||||
gst_glimage_sink_change_state (GstElement * element, GstStateChange transition);
|
||||
|
||||
|
@ -106,8 +108,6 @@ static void gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
|||
static gboolean gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
|
||||
static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink,
|
||||
GstBuffer * buf);
|
||||
static gboolean gst_glimage_sink_start (GstBaseSink * bsink);
|
||||
static gboolean gst_glimage_sink_stop (GstBaseSink * bsink);
|
||||
|
||||
static void gst_glimage_sink_xoverlay_init (GstXOverlayClass * iface);
|
||||
static void gst_glimage_sink_set_xwindow_id (GstXOverlay * overlay,
|
||||
|
@ -235,13 +235,12 @@ 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->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;
|
||||
gstbasesink_class->preroll = gst_glimage_sink_render;
|
||||
gstbasesink_class->render = gst_glimage_sink_render;
|
||||
gstbasesink_class->start = gst_glimage_sink_start;
|
||||
gstbasesink_class->stop = gst_glimage_sink_stop;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -336,6 +335,29 @@ gst_glimage_sink_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_glimage_sink_query (GstElement * element, GstQuery * query)
|
||||
{
|
||||
GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (element);
|
||||
gboolean res = FALSE;
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CUSTOM:
|
||||
{
|
||||
GstStructure *structure = gst_query_get_structure (query);
|
||||
gst_structure_set (structure, "gstgldisplay", G_TYPE_POINTER, glimage_sink->display, NULL);
|
||||
res = GST_ELEMENT_CLASS (parent_class)->query (element, query);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = GST_ELEMENT_CLASS (parent_class)->query (element, query);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GstElement methods
|
||||
*/
|
||||
|
@ -354,6 +376,8 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
if (!glimage_sink->display)
|
||||
glimage_sink->display = gst_gl_display_new ();
|
||||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||
break;
|
||||
|
@ -369,11 +393,24 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||
gst_glimage_sink_stop (GST_BASE_SINK (glimage_sink));
|
||||
{
|
||||
if (glimage_sink->stored_buffer) {
|
||||
gst_buffer_unref (GST_BUFFER_CAST (glimage_sink->stored_buffer));
|
||||
glimage_sink->stored_buffer = NULL;
|
||||
}
|
||||
if (glimage_sink->display) {
|
||||
g_object_unref (glimage_sink->display);
|
||||
glimage_sink->display = NULL;
|
||||
}
|
||||
|
||||
glimage_sink->window_id = 0;
|
||||
//but do not reset glimage_sink->new_window_id
|
||||
|
||||
glimage_sink->fps_n = 0;
|
||||
glimage_sink->fps_d = 1;
|
||||
GST_VIDEO_SINK_WIDTH (glimage_sink) = 0;
|
||||
GST_VIDEO_SINK_HEIGHT (glimage_sink) = 0;
|
||||
}
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
break;
|
||||
|
@ -384,44 +421,6 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* GstBaseSink methods
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
gst_glimage_sink_start (GstBaseSink * bsink)
|
||||
{
|
||||
//GstGLImageSink* glimage_sink = GST_GLIMAGE_SINK (bsink);
|
||||
|
||||
GST_DEBUG ("start");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_glimage_sink_stop (GstBaseSink * bsink)
|
||||
{
|
||||
GstGLImageSink *glimage_sink;
|
||||
|
||||
GST_DEBUG ("stop");
|
||||
|
||||
glimage_sink = GST_GLIMAGE_SINK (bsink);
|
||||
|
||||
if (glimage_sink->stored_buffer) {
|
||||
gst_buffer_unref (GST_BUFFER_CAST (glimage_sink->stored_buffer));
|
||||
glimage_sink->stored_buffer = NULL;
|
||||
}
|
||||
if (glimage_sink->display) {
|
||||
g_object_unref (glimage_sink->display);
|
||||
glimage_sink->display = NULL;
|
||||
}
|
||||
|
||||
glimage_sink->window_id = 0;
|
||||
//but do not reset glimage_sink->new_window_id
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
||||
GstClockTime * start, GstClockTime * end)
|
||||
|
@ -470,7 +469,22 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
} else {
|
||||
is_gl = FALSE;
|
||||
ok = gst_video_format_parse_caps (caps, &format, &width, &height);
|
||||
|
||||
/* init opengl context */
|
||||
gst_gl_display_create_context (glimage_sink->display,
|
||||
width, height, 0);
|
||||
|
||||
/* init colorspace conversion if needed */
|
||||
gst_gl_display_init_upload (glimage_sink->display, format,
|
||||
width, height, width, height);
|
||||
}
|
||||
|
||||
gst_gl_display_set_client_reshape_callback (glimage_sink->display,
|
||||
glimage_sink->clientReshapeCallback);
|
||||
|
||||
gst_gl_display_set_client_draw_callback (glimage_sink->display,
|
||||
glimage_sink->clientDrawCallback);
|
||||
|
||||
ok &= gst_video_parse_caps_framerate (caps, &fps_n, &fps_d);
|
||||
ok &= gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d);
|
||||
|
||||
|
@ -480,7 +494,6 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
GST_VIDEO_SINK_WIDTH (glimage_sink) = width;
|
||||
GST_VIDEO_SINK_HEIGHT (glimage_sink) = height;
|
||||
glimage_sink->is_gl = is_gl;
|
||||
glimage_sink->format = format;
|
||||
glimage_sink->width = width;
|
||||
glimage_sink->height = height;
|
||||
glimage_sink->fps_n = fps_n;
|
||||
|
@ -508,40 +521,9 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
|||
if (glimage_sink->is_gl) {
|
||||
//increment gl buffer ref before storage
|
||||
gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf));
|
||||
|
||||
//if glimagesink has not the display yet
|
||||
if (glimage_sink->display == NULL) {
|
||||
glimage_sink->display = g_object_ref (gl_buffer->display);
|
||||
|
||||
gst_gl_display_set_client_reshape_callback (glimage_sink->display,
|
||||
glimage_sink->clientReshapeCallback);
|
||||
|
||||
gst_gl_display_set_client_draw_callback (glimage_sink->display,
|
||||
glimage_sink->clientDrawCallback);
|
||||
}
|
||||
}
|
||||
//is not gl
|
||||
else {
|
||||
//if glimagesink has not the display yet
|
||||
if (glimage_sink->display == NULL) {
|
||||
//create a display
|
||||
glimage_sink->display = gst_gl_display_new ();
|
||||
|
||||
//init opengl context
|
||||
gst_gl_display_create_context (glimage_sink->display,
|
||||
glimage_sink->width, glimage_sink->height, 0);
|
||||
|
||||
//init colorspace conversion if needed
|
||||
gst_gl_display_init_upload (glimage_sink->display, glimage_sink->format,
|
||||
glimage_sink->width, glimage_sink->height,
|
||||
glimage_sink->width, glimage_sink->height);
|
||||
|
||||
gst_gl_display_set_client_reshape_callback (glimage_sink->display,
|
||||
glimage_sink->clientReshapeCallback);
|
||||
|
||||
gst_gl_display_set_client_draw_callback (glimage_sink->display,
|
||||
glimage_sink->clientDrawCallback);
|
||||
}
|
||||
//blocking call
|
||||
gl_buffer = gst_gl_buffer_new (glimage_sink->display,
|
||||
glimage_sink->width, glimage_sink->height);
|
||||
|
|
|
@ -57,7 +57,6 @@ struct _GstGLImageSink
|
|||
|
||||
//caps
|
||||
GstCaps *caps;
|
||||
GstVideoFormat format;
|
||||
gint width;
|
||||
gint height;
|
||||
gboolean is_gl;
|
||||
|
|
|
@ -76,6 +76,8 @@ static void gst_gl_test_src_set_property (GObject * object, guint prop_id,
|
|||
static void gst_gl_test_src_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_gl_test_src_src_query (GstPad * pad, GstQuery * query);
|
||||
|
||||
static gboolean gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps);
|
||||
static void gst_gl_test_src_src_fixate (GstPad * pad, GstCaps * caps);
|
||||
|
||||
|
@ -190,6 +192,9 @@ gst_gl_test_src_init (GstGLTestSrc * src, GstGLTestSrcClass * g_class)
|
|||
/* we operate in time */
|
||||
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
|
||||
gst_base_src_set_live (GST_BASE_SRC (src), FALSE);
|
||||
|
||||
gst_pad_set_query_function (pad,
|
||||
GST_DEBUG_FUNCPTR (gst_gl_test_src_src_query));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -301,6 +306,27 @@ gst_gl_test_src_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_test_src_src_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
GstElement *parent = GST_ELEMENT (gst_pad_get_parent (pad));
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CUSTOM:
|
||||
{
|
||||
GstStructure *structure = gst_query_get_structure (query);
|
||||
res = g_strcmp0 (gst_element_get_name (parent), gst_structure_get_name (structure)) == 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_test_src_parse_caps (const GstCaps * caps,
|
||||
gint * width, gint * height, gint * rate_numerator, gint * rate_denominator)
|
||||
|
@ -361,8 +387,6 @@ gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
|
|||
gltestsrc->width, gltestsrc->height,
|
||||
gltestsrc->rate_numerator, gltestsrc->rate_denominator);
|
||||
|
||||
gltestsrc->display = gst_gl_display_new ();
|
||||
|
||||
gst_gl_display_create_context (gltestsrc->display,
|
||||
gltestsrc->width, gltestsrc->height, 0);
|
||||
|
||||
|
@ -596,12 +620,30 @@ static gboolean
|
|||
gst_gl_test_src_start (GstBaseSrc * basesrc)
|
||||
{
|
||||
GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc);
|
||||
GstElement *parent = GST_ELEMENT (gst_element_get_parent (src));
|
||||
GstStructure *structure = gst_structure_new (gst_element_get_name (src), NULL);
|
||||
GstQuery *query = gst_query_new_application (GST_QUERY_CUSTOM, structure);
|
||||
|
||||
gboolean isPerformed = gst_element_query (parent, query);
|
||||
|
||||
if (isPerformed) {
|
||||
const GValue *id_value = gst_structure_get_value (structure, "gstgldisplay");
|
||||
if (G_VALUE_HOLDS_POINTER (id_value))
|
||||
/* at least one gl element is before in our gl chain */
|
||||
src->display = g_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
||||
else
|
||||
/* this gl filter is a sink in terms of the gl chain */
|
||||
src->display = gst_gl_display_new ();
|
||||
}
|
||||
|
||||
gst_query_unref (query);
|
||||
gst_object_unref (GST_OBJECT (parent));
|
||||
|
||||
src->running_time = 0;
|
||||
src->n_frames = 0;
|
||||
src->negotiated = FALSE;
|
||||
|
||||
return TRUE;
|
||||
return isPerformed;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -136,6 +136,8 @@ static void gst_gl_upload_set_property (GObject * object, guint prop_id,
|
|||
static void gst_gl_upload_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_gl_upload_src_query (GstPad *pad, GstQuery * query);
|
||||
|
||||
static void gst_gl_upload_reset (GstGLUpload * upload);
|
||||
static gboolean gst_gl_upload_set_caps (GstBaseTransform * bt,
|
||||
GstCaps * incaps, GstCaps * outcaps);
|
||||
|
@ -196,6 +198,11 @@ gst_gl_upload_class_init (GstGLUploadClass * klass)
|
|||
static void
|
||||
gst_gl_upload_init (GstGLUpload * upload, GstGLUploadClass * klass)
|
||||
{
|
||||
GstBaseTransform *base_trans = GST_BASE_TRANSFORM (upload);
|
||||
|
||||
gst_pad_set_query_function (base_trans->srcpad,
|
||||
GST_DEBUG_FUNCPTR (gst_gl_upload_src_query));
|
||||
|
||||
gst_gl_upload_reset (upload);
|
||||
}
|
||||
|
||||
|
@ -230,6 +237,29 @@ gst_gl_upload_get_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_gl_upload_src_query (GstPad * pad, GstQuery * query)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
GstElement *parent = GST_ELEMENT (gst_pad_get_parent (pad));
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_CUSTOM:
|
||||
{
|
||||
GstStructure *structure = gst_query_get_structure (query);
|
||||
res = g_strcmp0 (gst_element_get_name (parent), gst_structure_get_name (structure)) == 0;
|
||||
if (!res)
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = gst_pad_query_default (pad, query);
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_gl_upload_reset (GstGLUpload * upload)
|
||||
{
|
||||
|
@ -243,9 +273,27 @@ gst_gl_upload_reset (GstGLUpload * upload)
|
|||
static gboolean
|
||||
gst_gl_upload_start (GstBaseTransform * bt)
|
||||
{
|
||||
//GstGLUpload* upload = GST_GL_UPLOAD (bt);
|
||||
GstGLUpload* upload = GST_GL_UPLOAD (bt);
|
||||
GstElement *parent = GST_ELEMENT (gst_element_get_parent (upload));
|
||||
GstStructure *structure = gst_structure_new (gst_element_get_name (upload), NULL);
|
||||
GstQuery *query = gst_query_new_application (GST_QUERY_CUSTOM, structure);
|
||||
|
||||
return TRUE;
|
||||
gboolean isPerformed = gst_element_query (parent, query);
|
||||
|
||||
if (isPerformed) {
|
||||
const GValue *id_value = gst_structure_get_value (structure, "gstgldisplay");
|
||||
if (G_VALUE_HOLDS_POINTER (id_value))
|
||||
/* at least one gl element is before in our gl chain */
|
||||
upload->display = g_object_ref (GST_GL_DISPLAY (g_value_get_pointer (id_value)));
|
||||
else
|
||||
/* this gl filter is a sink in terms of the gl chain */
|
||||
upload->display = gst_gl_display_new ();
|
||||
}
|
||||
|
||||
gst_query_unref (query);
|
||||
gst_object_unref (GST_OBJECT (parent));
|
||||
|
||||
return isPerformed;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -444,8 +492,6 @@ gst_gl_upload_set_caps (GstBaseTransform * bt, GstCaps * incaps,
|
|||
GST_DEBUG ("caps connot be parsed");
|
||||
return FALSE;
|
||||
}
|
||||
//we have video and gl size, we can now init OpenGL stuffs
|
||||
upload->display = gst_gl_display_new ();
|
||||
|
||||
//init unvisible opengl context
|
||||
gst_gl_display_create_context (upload->display,
|
||||
|
|
Loading…
Reference in a new issue