From 83c34503af44a50d506d0b8eff1f2fcf46838664 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Fri, 31 Oct 2014 12:52:07 +1100 Subject: [PATCH] glmixer: advertise support for changing input caps mid-stream https://bugzilla.gnome.org/show_bug.cgi?id=739334 --- ext/gl/gstglmixer.c | 189 ++++++++++++++++++++++++++-------------------------- 1 file changed, 96 insertions(+), 93 deletions(-) diff --git a/ext/gl/gstglmixer.c b/ext/gl/gstglmixer.c index f95a955..9b1dcb5 100644 --- a/ext/gl/gstglmixer.c +++ b/ext/gl/gstglmixer.c @@ -288,6 +288,98 @@ gst_gl_mixer_pad_sink_acceptcaps (GstPad * pad, GstGLMixer * mix, } static GstCaps * +gst_gl_mixer_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; +} + +/* copies the given caps */ +static GstCaps * +gst_gl_mixer_caps_remove_format_info (GstCaps * caps) +{ + GstStructure *st; + GstCapsFeatures *f; + gint i, n; + GstCaps *res; + + res = gst_caps_new_empty (); + + n = gst_caps_get_size (caps); + for (i = 0; i < n; i++) { + st = gst_caps_get_structure (caps, i); + f = gst_caps_get_features (caps, i); + + /* If this is already expressed by the existing caps + * skip this structure */ + if (i > 0 && gst_caps_is_subset_structure_full (res, st, f)) + continue; + + st = gst_structure_copy (st); + /* Only remove format info for the cases when we can actually convert */ + if (!gst_caps_features_is_any (f) + && gst_caps_features_is_equal (f, + GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) + gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site", + "width", "height", NULL); + + gst_caps_append_structure_full (res, st, gst_caps_features_copy (f)); + } + + return res; +} + +GstCaps * +gst_gl_mixer_update_caps (GstGLMixer * mix, GstCaps * caps) +{ + GstCaps *result = NULL; + GstCaps *glcaps = gst_gl_mixer_set_caps_features (caps, + GST_CAPS_FEATURE_MEMORY_GL_MEMORY); +#if GST_GL_HAVE_PLATFORM_EGL + GstCaps *eglcaps = gst_gl_mixer_set_caps_features (caps, + GST_CAPS_FEATURE_MEMORY_EGL_IMAGE); +#endif + GstCaps *uploadcaps = gst_gl_mixer_set_caps_features (caps, + GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META); + GstCaps *raw_caps = + gst_caps_from_string (GST_VIDEO_CAPS_MAKE (GST_GL_COLOR_CONVERT_FORMATS)); + + result = gst_caps_new_empty (); + + result = gst_caps_merge (result, glcaps); +#if GST_GL_HAVE_PLATFORM_EGL + result = gst_caps_merge (result, eglcaps); +#endif + result = gst_caps_merge (result, uploadcaps); + result = gst_caps_merge (result, raw_caps); + + result = gst_caps_merge (result, gst_gl_mixer_caps_remove_format_info (caps)); + + GST_DEBUG_OBJECT (mix, "returning %" GST_PTR_FORMAT, result); + + return result; +} + +static GstCaps * gst_gl_mixer_pad_sink_getcaps (GstPad * pad, GstGLMixer * mix, GstCaps * filter) { GstCaps *srccaps; @@ -302,6 +394,8 @@ gst_gl_mixer_pad_sink_getcaps (GstPad * pad, GstGLMixer * mix, GstCaps * filter) if (srccaps == NULL) { had_current_caps = FALSE; srccaps = template_caps; + } else { + srccaps = gst_caps_merge (srccaps, gst_gl_mixer_update_caps (mix, srccaps)); } filtered_caps = srccaps; @@ -309,12 +403,13 @@ gst_gl_mixer_pad_sink_getcaps (GstPad * pad, GstGLMixer * mix, GstCaps * filter) filtered_caps = gst_caps_intersect (srccaps, filter); returned_caps = gst_caps_intersect (filtered_caps, template_caps); - gst_caps_unref (srccaps); if (filter) gst_caps_unref (filtered_caps); if (had_current_caps) gst_caps_unref (template_caps); + GST_DEBUG_OBJECT (pad, "returning %" GST_PTR_FORMAT, returned_caps); + return returned_caps; } @@ -590,98 +685,6 @@ gst_gl_mixer_src_activate_mode (GstAggregator * aggregator, GstPadMode mode, return result; } -static GstCaps * -gst_gl_mixer_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; -} - -/* copies the given caps */ -static GstCaps * -gst_gl_mixer_caps_remove_format_info (GstCaps * caps) -{ - GstStructure *st; - GstCapsFeatures *f; - gint i, n; - GstCaps *res; - - res = gst_caps_new_empty (); - - n = gst_caps_get_size (caps); - for (i = 0; i < n; i++) { - st = gst_caps_get_structure (caps, i); - f = gst_caps_get_features (caps, i); - - /* If this is already expressed by the existing caps - * skip this structure */ - if (i > 0 && gst_caps_is_subset_structure_full (res, st, f)) - continue; - - st = gst_structure_copy (st); - /* Only remove format info for the cases when we can actually convert */ - if (!gst_caps_features_is_any (f) - && gst_caps_features_is_equal (f, - GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) - gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site", - "width", "height", NULL); - - gst_caps_append_structure_full (res, st, gst_caps_features_copy (f)); - } - - return res; -} - -GstCaps * -gst_gl_mixer_update_caps (GstGLMixer * mix, GstCaps * caps) -{ - GstCaps *result = NULL; - GstCaps *glcaps = gst_gl_mixer_set_caps_features (caps, - GST_CAPS_FEATURE_MEMORY_GL_MEMORY); -#if GST_GL_HAVE_PLATFORM_EGL - GstCaps *eglcaps = gst_gl_mixer_set_caps_features (caps, - GST_CAPS_FEATURE_MEMORY_EGL_IMAGE); -#endif - GstCaps *uploadcaps = gst_gl_mixer_set_caps_features (caps, - GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META); - GstCaps *raw_caps = - gst_caps_from_string (GST_VIDEO_CAPS_MAKE (GST_GL_COLOR_CONVERT_FORMATS)); - - result = gst_caps_new_empty (); - - result = gst_caps_merge (result, glcaps); -#if GST_GL_HAVE_PLATFORM_EGL - result = gst_caps_merge (result, eglcaps); -#endif - result = gst_caps_merge (result, uploadcaps); - result = gst_caps_merge (result, raw_caps); - - result = gst_caps_merge (result, gst_gl_mixer_caps_remove_format_info (caps)); - - GST_DEBUG_OBJECT (mix, "returning %" GST_PTR_FORMAT, result); - - return result; -} - static gboolean gst_gl_mixer_query_caps (GstPad * pad, GstAggregator * agg, GstQuery * query) { -- 2.7.4