diff options
author | Matthew Waters <matthew@centricular.com> | 2015-04-30 11:15:40 +1000 |
---|---|---|
committer | Matthew Waters <matthew@centricular.com> | 2015-04-30 11:26:33 +1000 |
commit | 87d8270f302b03f63ce04f986d824892a2c131fd (patch) | |
tree | 38b814dca0d624fb976a83e6e03fbd1d3cb2f509 /gst-libs | |
parent | b4bd11f2f3a60224d188b27ab55b278077cb1217 (diff) | |
download | gstreamer-plugins-bad-87d8270f302b03f63ce04f986d824892a2c131fd.tar.gz |
gl: readd glupload/download onto element pads
Allows insertion of gl elements into non-gl pipelines without converter
(upload/download) elements.
https://bugzilla.gnome.org/show_bug.cgi?id=743974
Diffstat (limited to 'gst-libs')
-rw-r--r-- | gst-libs/gst/gl/gstglcolorconvert.c | 12 | ||||
-rw-r--r-- | gst-libs/gst/gl/gstglfilter.c | 107 | ||||
-rw-r--r-- | gst-libs/gst/gl/gstglfilter.h | 2 | ||||
-rw-r--r-- | gst-libs/gst/gl/gstglutils.c | 18 | ||||
-rw-r--r-- | gst-libs/gst/gl/gstglutils.h | 2 |
5 files changed, 91 insertions, 50 deletions
diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c index 243fc7189..4ff7c1889 100644 --- a/gst-libs/gst/gl/gstglcolorconvert.c +++ b/gst-libs/gst/gl/gstglcolorconvert.c @@ -676,23 +676,21 @@ gst_gl_color_convert_caps_remove_format_info (GstCaps * caps) } GstCaps * -gst_gl_color_convert_transform_caps (GstGLContext * convert, +gst_gl_color_convert_transform_caps (GstGLContext * context, GstPadDirection direction, GstCaps * caps, GstCaps * filter) { - GstCaps *templ, *result; + GstCaps *templ, *tmp, *result; templ = gst_caps_from_string (GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, GST_GL_COLOR_CONVERT_FORMATS)); - caps = gst_gl_color_convert_caps_remove_format_info (caps); - result = gst_caps_intersect (caps, templ); - gst_caps_unref (caps); + tmp = gst_gl_color_convert_caps_remove_format_info (caps); + result = gst_caps_intersect (tmp, templ); + gst_caps_unref (tmp); gst_caps_unref (templ); if (filter) { - GstCaps *tmp; - tmp = gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (result); result = tmp; diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c index 169ded9f9..f06fb5dc4 100644 --- a/gst-libs/gst/gl/gstglfilter.c +++ b/gst-libs/gst/gl/gstglfilter.c @@ -37,21 +37,12 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); static GstStaticPadTemplate gst_gl_filter_src_pad_template = -GST_STATIC_PAD_TEMPLATE ("src", + GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, - "RGBA")) - ); - -static GstStaticPadTemplate gst_gl_filter_sink_pad_template = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, - "RGBA")) + "RGBA") ";" GST_VIDEO_CAPS_MAKE ("RGBA")) ); /* Properties */ @@ -63,7 +54,8 @@ enum #define gst_gl_filter_parent_class parent_class G_DEFINE_TYPE_WITH_CODE (GstGLFilter, gst_gl_filter, GST_TYPE_GL_BASE_FILTER, GST_DEBUG_CATEGORY_INIT (gst_gl_filter_debug, "glfilter", 0, - "glfilter element");); + "glfilter element"); + ); static void gst_gl_filter_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); @@ -94,6 +86,7 @@ gst_gl_filter_class_init (GstGLFilterClass * klass) { GObjectClass *gobject_class; GstElementClass *element_class; + GstCaps *upload_caps, *elem_caps, *templ; gobject_class = (GObjectClass *) klass; element_class = GST_ELEMENT_CLASS (klass); @@ -118,8 +111,15 @@ gst_gl_filter_class_init (GstGLFilterClass * klass) gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_gl_filter_src_pad_template)); + + elem_caps = gst_caps_from_string ("video/x-raw(ANY),format=RGBA"); + upload_caps = gst_gl_upload_get_input_template_caps (); + templ = gst_caps_intersect (elem_caps, upload_caps); gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_gl_filter_sink_pad_template)); + gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, templ)); + gst_caps_unref (upload_caps); + gst_caps_unref (elem_caps); + gst_caps_unref (templ); } static void @@ -156,6 +156,11 @@ gst_gl_filter_reset (GstGLFilter * filter) { gst_caps_replace (&filter->out_caps, NULL); + if (filter->upload) { + gst_object_unref (filter->upload); + filter->upload = NULL; + } + if (filter->pool) { gst_object_unref (filter->pool); filter->pool = NULL; @@ -605,8 +610,7 @@ gst_gl_filter_caps_remove_size (GstCaps * caps) } static GstCaps * -gst_gl_filter_set_caps_features (const GstCaps * caps, - const gchar * feature_name) +gst_gl_filter_set_caps_features (GstCaps * caps, const gchar * feature_name) { GstCaps *ret = gst_gl_caps_replace_all_caps_features (caps, feature_name); gst_caps_set_simple (ret, "format", G_TYPE_STRING, "RGBA", NULL); @@ -617,23 +621,48 @@ static GstCaps * gst_gl_filter_transform_caps (GstBaseTransform * bt, GstPadDirection direction, GstCaps * caps, GstCaps * filter_caps) { + GstGLContext *context = GST_GL_BASE_FILTER (bt)->context; GstCaps *tmp = NULL; GstCaps *result = NULL; - result = gst_gl_filter_caps_remove_size (caps); - tmp = result; - GST_DEBUG_OBJECT (bt, "size removal returned caps %" GST_PTR_FORMAT, tmp); + if (direction == GST_PAD_SINK) { + result = gst_gl_upload_transform_caps (context, direction, caps, NULL); + } else { + tmp = + gst_gl_caps_replace_all_caps_features (caps, + GST_CAPS_FEATURE_MEMORY_GL_MEMORY); + result = gst_caps_merge (gst_caps_ref (caps), tmp); + } - result = - gst_gl_filter_set_caps_features (tmp, GST_CAPS_FEATURE_MEMORY_GL_MEMORY); - gst_caps_unref (tmp); - tmp = result; + GST_DEBUG_OBJECT (bt, "transfer returned %" GST_PTR_FORMAT, result); - if (filter_caps) { - result = - gst_caps_intersect_full (filter_caps, tmp, GST_CAPS_INTERSECT_FIRST); - gst_caps_unref (tmp); + tmp = gst_gl_filter_caps_remove_size (result); + gst_caps_unref (result); + result = tmp; + GST_DEBUG_OBJECT (bt, "size removal returned caps %" GST_PTR_FORMAT, result); + + tmp = + gst_gl_filter_set_caps_features (result, + GST_CAPS_FEATURE_MEMORY_GL_MEMORY); + gst_caps_unref (result); + result = tmp; + + if (direction == GST_PAD_SRC) { + tmp = gst_gl_upload_transform_caps (context, direction, result, NULL); + gst_caps_unref (result); + result = tmp; } else { + tmp = + gst_gl_caps_replace_all_caps_features (result, + GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY); + result = gst_caps_merge (result, tmp); + } + GST_DEBUG_OBJECT (bt, "transfer returned %" GST_PTR_FORMAT, result); + + if (filter_caps) { + tmp = + gst_caps_intersect_full (filter_caps, result, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (result); result = tmp; } @@ -777,10 +806,11 @@ config_failed: static gboolean gst_gl_filter_decide_allocation (GstBaseTransform * trans, GstQuery * query) { + GstGLFilter *filter = GST_GL_FILTER (trans); GstGLContext *context; GstBufferPool *pool = NULL; GstStructure *config; - GstCaps *caps; + GstCaps *caps, *upload_caps; guint min, max, size; gboolean update_pool; @@ -832,6 +862,18 @@ gst_gl_filter_decide_allocation (GstBaseTransform * trans, GstQuery * query) gst_object_unref (pool); + if (!filter->upload) + filter->upload = gst_gl_upload_new (context); + + upload_caps = gst_caps_copy (caps); + gst_caps_set_features (upload_caps, 0, + gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY)); + if (!gst_gl_upload_set_caps (filter->upload, caps, upload_caps)) { + gst_caps_unref (upload_caps); + return FALSE; + } + gst_caps_unref (upload_caps); + return TRUE; } @@ -853,11 +895,18 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf, GstGLFilterClass *filter_class; guint in_tex, out_tex; GstVideoFrame gl_frame, out_frame; + GstBuffer *gl_buffer; gboolean ret; filter_class = GST_GL_FILTER_GET_CLASS (filter); - if (!gst_video_frame_map (&gl_frame, &filter->in_info, inbuf, + if (GST_GL_UPLOAD_DONE != gst_gl_upload_perform_with_buffer (filter->upload, + inbuf, &gl_buffer) || !gl_buffer) { + ret = FALSE; + goto gl_buf_error; + } + + if (!gst_video_frame_map (&gl_frame, &filter->in_info, gl_buffer, GST_MAP_READ | GST_MAP_GL)) { ret = FALSE; goto inbuf_error; @@ -883,6 +932,8 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf, unmap_out_error: gst_video_frame_unmap (&gl_frame); inbuf_error: + gst_buffer_unref (gl_buffer); +gl_buf_error: return ret; } diff --git a/gst-libs/gst/gl/gstglfilter.h b/gst-libs/gst/gl/gstglfilter.h index a5caf3211..2a69f26c5 100644 --- a/gst-libs/gst/gl/gstglfilter.h +++ b/gst-libs/gst/gl/gstglfilter.h @@ -66,6 +66,8 @@ struct _GstGLFilter GstCaps *out_caps; /* <private> */ + GstGLUpload *upload; + GLuint fbo; GLuint depthbuffer; diff --git a/gst-libs/gst/gl/gstglutils.c b/gst-libs/gst/gl/gstglutils.c index e4d9cad67..48e1653fe 100644 --- a/gst-libs/gst/gl/gstglutils.c +++ b/gst-libs/gst/gl/gstglutils.c @@ -881,26 +881,16 @@ gst_gl_get_plane_data_size (GstVideoInfo * info, GstVideoAlignment * align, } GstCaps * -gst_gl_caps_replace_all_caps_features (const GstCaps * caps, +gst_gl_caps_replace_all_caps_features (GstCaps * caps, const gchar * feature_name) { GstCaps *tmp = gst_caps_copy (caps); guint n = gst_caps_get_size (tmp); guint i = 0; - for (i = 0; i < n; i++) { - GstCapsFeatures *features = gst_caps_get_features (tmp, i); - if (features) { - guint n_f = gst_caps_features_get_size (features); - guint j = 0; - for (j = 0; j < n_f; j++) { - gst_caps_features_remove_id (features, - gst_caps_features_get_nth_id (features, j)); - } - } - - gst_caps_features_add (features, feature_name); - } + for (i = 0; i < n; i++) + gst_caps_set_features (tmp, i, + gst_caps_features_from_string (feature_name)); return tmp; } diff --git a/gst-libs/gst/gl/gstglutils.h b/gst-libs/gst/gl/gstglutils.h index c915bfb6f..5b1933d06 100644 --- a/gst-libs/gst/gl/gstglutils.h +++ b/gst-libs/gst/gl/gstglutils.h @@ -103,7 +103,7 @@ gboolean gst_gl_run_query (GstElement * element, GstQuery * query, GstPadDirection direction); gsize gst_gl_get_plane_data_size (GstVideoInfo * info, GstVideoAlignment * align, guint plane); -GstCaps * gst_gl_caps_replace_all_caps_features (const GstCaps * caps, +GstCaps * gst_gl_caps_replace_all_caps_features (GstCaps * caps, const gchar * feature_name); G_END_DECLS |