diff options
Diffstat (limited to 'gst-libs/gst/gl/gstglfilter.c')
-rw-r--r-- | gst-libs/gst/gl/gstglfilter.c | 141 |
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, ¶ms); - 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, ¶ms); + 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 */ |