aboutsummaryrefslogtreecommitdiff
path: root/gst-libs/gst/gl/gstglfilter.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst-libs/gst/gl/gstglfilter.c')
-rw-r--r--gst-libs/gst/gl/gstglfilter.c141
1 files changed, 89 insertions, 52 deletions
diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c
index 48748515..4007ac21 100644
--- a/gst-libs/gst/gl/gstglfilter.c
+++ b/gst-libs/gst/gl/gstglfilter.c
@@ -38,7 +38,9 @@ static GstStaticPadTemplate gst_gl_filter_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
+ (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
+ "RGBA") "; "
#if GST_GL_HAVE_PLATFORM_EGL
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_EGL_IMAGE,
"RGBA") "; "
@@ -52,7 +54,9 @@ static GstStaticPadTemplate gst_gl_filter_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
+ (GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
+ "RGBA") "; "
#if GST_GL_HAVE_PLATFORM_EGL
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_EGL_IMAGE,
"RGBA") "; "
@@ -656,31 +660,72 @@ done:
return othercaps;
}
+
+static GstCaps *
+gst_gl_filter_set_caps_features (const 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);
+ gst_caps_set_simple (tmp, "format", G_TYPE_STRING, "RGBA", NULL);
+ }
+
+ return tmp;
+}
+
static GstCaps *
gst_gl_filter_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
- GstCaps *newcaps, *result;
-
- if (direction == GST_PAD_SINK)
- newcaps =
- gst_static_pad_template_get_caps (&gst_gl_filter_src_pad_template);
- else if (direction == GST_PAD_SRC)
- newcaps =
- gst_static_pad_template_get_caps (&gst_gl_filter_sink_pad_template);
- else
- newcaps = gst_caps_new_any ();
+ GstCaps *tmp = NULL;
+ GstCaps *result = NULL;
+
+ if (direction == GST_PAD_SINK) {
+ GstCaps *glcaps = gst_gl_filter_set_caps_features (caps,
+ GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
+#if GST_GL_HAVE_PLATFORM_EGL
+ GstCaps *eglcaps = gst_gl_filter_set_caps_features (caps,
+ GST_CAPS_FEATURE_MEMORY_EGL_IMAGE);
+#endif
+ GstCaps *uploadcaps = gst_gl_filter_set_caps_features (caps,
+ GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META);
+
+ tmp = gst_caps_new_empty ();
+
+ tmp = gst_caps_merge (tmp, glcaps);
+#if GST_GL_HAVE_PLATFORM_EGL
+ tmp = gst_caps_merge (tmp, eglcaps);
+#endif
+ tmp = gst_caps_merge (tmp, uploadcaps);
+ tmp = gst_caps_merge (tmp, gst_caps_copy (caps));
+ } else {
+ tmp = gst_caps_copy (caps);
+ }
if (filter) {
- result =
- gst_caps_intersect_full (filter, newcaps, GST_CAPS_INTERSECT_FIRST);
- gst_caps_unref (newcaps);
- newcaps = result;
+ result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
+ gst_caps_unref (tmp);
+ } else {
+ result = tmp;
}
- GST_DEBUG_OBJECT (bt, "returning caps: %" GST_PTR_FORMAT, newcaps);
+ GST_DEBUG_OBJECT (bt, "returning caps: %" GST_PTR_FORMAT, result);
- return newcaps;
+ return result;
}
@@ -742,7 +787,7 @@ gst_gl_filter_propose_allocation (GstBaseTransform * trans,
GstGLFilter *filter = GST_GL_FILTER (trans);
GstBufferPool *pool;
GstStructure *config;
- GstCaps *caps;
+ GstCaps *caps, *decide_caps;
guint size;
gboolean need_pool;
GError *error = NULL;
@@ -788,20 +833,29 @@ gst_gl_filter_propose_allocation (GstBaseTransform * trans,
if (pool == NULL && need_pool) {
GstVideoInfo info;
+ GstBufferPool *decide_pool;
if (!gst_video_info_from_caps (&info, caps))
goto invalid_caps;
- GST_DEBUG_OBJECT (filter, "create new pool");
- pool = gst_gl_buffer_pool_new (filter->context);
+ gst_query_parse_allocation (decide_query, &decide_caps, NULL);
+ decide_pool = gst_base_transform_get_buffer_pool (trans);
+ if (GST_IS_GL_BUFFER_POOL (decide_pool)
+ && gst_caps_is_equal_fixed (decide_caps, caps)) {
+ pool = decide_pool;
+ } else {
+ GST_DEBUG_OBJECT (filter, "create new pool");
+ gst_object_unref (decide_pool);
+ pool = gst_gl_buffer_pool_new (filter->context);
- /* the normal size of a frame */
- size = info.size;
+ /* the normal size of a frame */
+ size = info.size;
- config = gst_buffer_pool_get_config (pool);
- gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
- if (!gst_buffer_pool_set_config (pool, config))
- goto config_failed;
+ config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
+ if (!gst_buffer_pool_set_config (pool, config))
+ goto config_failed;
+ }
}
/* we need at least 2 buffer because we hold on to the last one */
if (pool) {
@@ -837,9 +891,11 @@ gst_gl_filter_propose_allocation (GstBaseTransform * trans,
gst_object_unref (allocator);
#if GST_GL_HAVE_PLATFORM_EGL
- allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
- gst_query_add_allocation_param (query, allocator, &params);
- gst_object_unref (allocator);
+ if (gst_gl_context_check_feature (filter->context, "EGL_KHR_image_base")) {
+ allocator = gst_allocator_find (GST_EGL_IMAGE_MEMORY_TYPE);
+ gst_query_add_allocation_param (query, allocator, &params);
+ gst_object_unref (allocator);
+ }
#endif
return TRUE;
@@ -1058,19 +1114,10 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf,
GST_LOG ("Output Buffer does not contain correct memory, "
"attempting to wrap for download");
- if (!filter->download) {
+ if (!filter->download)
filter->download = gst_gl_download_new (filter->context);
- if (!gst_gl_download_init_format (filter->download,
- GST_VIDEO_FRAME_FORMAT (&out_frame),
- GST_VIDEO_FRAME_WIDTH (&out_frame),
- GST_VIDEO_FRAME_HEIGHT (&out_frame))) {
- GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND,
- ("%s", "Failed to init download format"), (NULL));
- ret = FALSE;
- goto error;
- }
- }
+ gst_gl_download_set_format (filter->download, &out_frame.info);
out_tex = filter->out_tex_id;
}
@@ -1123,9 +1170,8 @@ gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
filter->upload = gst_object_ref (GST_GL_BUFFER_POOL (pool)->upload);
} else {
filter->upload = gst_gl_upload_new (filter->context);
- if (!gst_gl_upload_init_format (filter->upload, &filter->in_info))
- goto upload_error;
}
+ gst_gl_upload_set_format (filter->upload, &filter->in_info);
gst_caps_unref (in_caps);
gst_caps_unref (out_caps);
@@ -1140,15 +1186,6 @@ gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
gst_gl_filter_filter_texture (filter, inbuf, outbuf);
return GST_FLOW_OK;
-
-upload_error:
- {
- GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, ("Failed to init upload"),
- (NULL));
- gst_object_unref (filter->upload);
- filter->upload = NULL;
- return GST_FLOW_ERROR;
- }
}
/* convenience functions to simplify filter development */