summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2015-04-30 11:15:40 +1000
committerMatthew Waters <matthew@centricular.com>2015-04-30 11:26:33 +1000
commit87d8270f302b03f63ce04f986d824892a2c131fd (patch)
tree38b814dca0d624fb976a83e6e03fbd1d3cb2f509 /gst-libs
parentb4bd11f2f3a60224d188b27ab55b278077cb1217 (diff)
downloadgstreamer-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.c12
-rw-r--r--gst-libs/gst/gl/gstglfilter.c107
-rw-r--r--gst-libs/gst/gl/gstglfilter.h2
-rw-r--r--gst-libs/gst/gl/gstglutils.c18
-rw-r--r--gst-libs/gst/gl/gstglutils.h2
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