From 5b8987903107db305e2fe47a602ed9ee0e93fc52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Wed, 25 May 2022 15:46:04 +0200 Subject: [PATCH 1/4] plugin: gluploader: Remove DMABuf caps features on GLX GLX cannot do DMABufs. Do not advertise its support in caps, so upstream elements will never try using this kind of memory on GLX. --- .../plugin/importers/gstclappergluploader.c | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/lib/gst/plugin/importers/gstclappergluploader.c b/lib/gst/plugin/importers/gstclappergluploader.c index 454cc510..e4f9d45f 100644 --- a/lib/gst/plugin/importers/gstclappergluploader.c +++ b/lib/gst/plugin/importers/gstclappergluploader.c @@ -22,6 +22,11 @@ #endif #include "gstclappergluploader.h" +#include "gst/plugin/gstgtkutils.h" + +#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11 +#include +#endif #define GST_CAT_DEFAULT gst_clapper_gl_uploader_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); @@ -222,11 +227,59 @@ make_importer (void) return g_object_new (GST_TYPE_CLAPPER_GL_UPLOADER, NULL); } +#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX +static gboolean +_filter_glx_caps_cb (GstCapsFeatures *features, + GstStructure *structure, gpointer user_data) +{ + return !gst_caps_features_contains (features, "memory:DMABuf"); +} + +static gboolean +_update_glx_caps_on_main (GstCaps *caps) +{ + GdkDisplay *gdk_display; + + if (!gtk_init_check ()) + return FALSE; + + gdk_display = gdk_display_get_default (); + if (G_UNLIKELY (!gdk_display)) + return FALSE; + + if (GDK_IS_X11_DISPLAY (gdk_display)) { + gboolean using_glx = TRUE; + +#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL + using_glx = (gdk_x11_display_get_egl_display (gdk_display) == NULL); +#endif + + if (using_glx) { + gst_caps_filter_and_map_in_place (caps, + (GstCapsFilterMapFunc) _filter_glx_caps_cb, NULL); + } + } + + return TRUE; +} +#endif + GstCaps * make_caps (GstRank *rank, GStrv *context_types) { + GstCaps *caps = gst_gl_upload_get_input_template_caps (); + +#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX + if (!(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback) + _update_glx_caps_on_main, caps))) + gst_clear_caps (&caps); +#endif + + if (G_UNLIKELY (!caps)) + return NULL; + *rank = GST_RANK_MARGINAL + 1; *context_types = gst_clapper_gl_base_importer_make_gl_context_types (); - return gst_gl_upload_get_input_template_caps (); + return caps; } From 3f7ba0674fb71d49158d1a99142d99775c107f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Wed, 25 May 2022 20:30:56 +0200 Subject: [PATCH 2/4] plugin: importers: Support different template and actual caps Make a template caps during class_init. It will be used for e.g. gst-inspect-1.0, while do and use an actual caps that current HW can handle. --- lib/gst/plugin/gstclapperimporter.h | 3 +- lib/gst/plugin/gstclapperimporterloader.c | 61 +++++++++++-------- lib/gst/plugin/gstclapperimporterloader.h | 2 + lib/gst/plugin/gstclappersink.c | 3 +- .../plugin/importers/gstclapperglimporter.c | 2 +- .../plugin/importers/gstclappergluploader.c | 4 +- .../plugin/importers/gstclapperrawimporter.c | 2 +- 7 files changed, 47 insertions(+), 30 deletions(-) diff --git a/lib/gst/plugin/gstclapperimporter.h b/lib/gst/plugin/gstclapperimporter.h index 1f797de7..be462de8 100644 --- a/lib/gst/plugin/gstclapperimporter.h +++ b/lib/gst/plugin/gstclapperimporter.h @@ -36,7 +36,8 @@ G_BEGIN_DECLS #define GST_CLAPPER_IMPORTER_DEFINE(camel,lower,type) \ G_DEFINE_TYPE (camel, lower, type) \ G_MODULE_EXPORT GstClapperImporter *make_importer (void); \ -G_MODULE_EXPORT GstCaps *make_caps (GstRank *rank, GStrv *context_types); +G_MODULE_EXPORT GstCaps *make_caps (gboolean is_template, \ + GstRank *rank, GStrv *context_types); typedef struct _GstClapperImporter GstClapperImporter; typedef struct _GstClapperImporterClass GstClapperImporterClass; diff --git a/lib/gst/plugin/gstclapperimporterloader.c b/lib/gst/plugin/gstclapperimporterloader.c index f45625f1..91bd4845 100644 --- a/lib/gst/plugin/gstclapperimporterloader.c +++ b/lib/gst/plugin/gstclapperimporterloader.c @@ -33,7 +33,7 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); G_DEFINE_TYPE (GstClapperImporterLoader, gst_clapper_importer_loader, GST_TYPE_OBJECT); typedef GstClapperImporter* (* MakeImporter) (void); -typedef GstCaps* (* MakeCaps) (GstRank *rank, GStrv *context_types); +typedef GstCaps* (* MakeCaps) (gboolean is_template, GstRank *rank, GStrv *context_types); typedef struct { @@ -54,7 +54,7 @@ gst_clapper_importer_data_free (GstClapperImporterData *data) } static GstClapperImporterData * -_obtain_importer_data (GModule *module) +_obtain_importer_data (GModule *module, gboolean is_template) { MakeCaps make_caps; GstClapperImporterData *data; @@ -67,7 +67,7 @@ _obtain_importer_data (GModule *module) data = g_new0 (GstClapperImporterData, 1); data->module = module; - data->caps = make_caps (&data->rank, &data->context_types); + data->caps = make_caps (is_template, &data->rank, &data->context_types); GST_TRACE ("Created importer data: %" GST_PTR_FORMAT, data); @@ -183,7 +183,7 @@ _sort_importers_cb (gconstpointer a, gconstpointer b) } static GPtrArray * -gst_clapper_importer_loader_obtain_available_importers (void) +_obtain_available_importers (gboolean is_template) { const GPtrArray *modules; GPtrArray *importers; @@ -199,7 +199,7 @@ gst_clapper_importer_loader_obtain_available_importers (void) GModule *module = g_ptr_array_index (modules, i); GstClapperImporterData *data; - if ((data = _obtain_importer_data (module))) + if ((data = _obtain_importer_data (module, is_template))) g_ptr_array_add (importers, data); } @@ -210,13 +210,33 @@ gst_clapper_importer_loader_obtain_available_importers (void) return importers; } +GstClapperImporterLoader * +gst_clapper_importer_loader_new (void) +{ + return g_object_new (GST_TYPE_CLAPPER_IMPORTER_LOADER, NULL); +} + +static GstCaps * +_make_caps_for_importers (const GPtrArray *importers) +{ + GstCaps *caps = gst_caps_new_empty (); + guint i; + + for (i = 0; i < importers->len; i++) { + GstClapperImporterData *data = g_ptr_array_index (importers, i); + + gst_caps_append (caps, gst_caps_ref (data->caps)); + } + + return caps; +} + GstPadTemplate * gst_clapper_importer_loader_make_sink_pad_template (void) { GPtrArray *importers; - GstCaps *sink_caps; + GstCaps *caps; GstPadTemplate *templ; - guint i; /* This is only called once from sink class init function */ GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperimporterloader", 0, @@ -224,32 +244,25 @@ gst_clapper_importer_loader_make_sink_pad_template (void) GST_DEBUG ("Making sink pad template"); - importers = gst_clapper_importer_loader_obtain_available_importers (); - sink_caps = gst_caps_new_empty (); - - for (i = 0; i < importers->len; i++) { - GstClapperImporterData *data = g_ptr_array_index (importers, i); - - gst_caps_append (sink_caps, gst_caps_ref (data->caps)); - } - + importers = _obtain_available_importers (TRUE); + caps = _make_caps_for_importers (importers); g_ptr_array_unref (importers); - if (G_UNLIKELY (gst_caps_is_empty (sink_caps))) - gst_caps_append (sink_caps, gst_caps_new_any ()); + if (G_UNLIKELY (gst_caps_is_empty (caps))) + gst_caps_append (caps, gst_caps_new_any ()); - templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps); - gst_caps_unref (sink_caps); + templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps); + gst_caps_unref (caps); GST_TRACE ("Created sink pad template"); return templ; } -GstClapperImporterLoader * -gst_clapper_importer_loader_new (void) +GstCaps * +gst_clapper_importer_loader_make_actual_caps (GstClapperImporterLoader *self) { - return g_object_new (GST_TYPE_CLAPPER_IMPORTER_LOADER, NULL); + return _make_caps_for_importers (self->importers); } static const GstClapperImporterData * @@ -389,7 +402,7 @@ gst_clapper_importer_loader_constructed (GObject *object) { GstClapperImporterLoader *self = GST_CLAPPER_IMPORTER_LOADER_CAST (object); - self->importers = gst_clapper_importer_loader_obtain_available_importers (); + self->importers = _obtain_available_importers (FALSE); GST_CALL_PARENT (G_OBJECT_CLASS, constructed, (object)); } diff --git a/lib/gst/plugin/gstclapperimporterloader.h b/lib/gst/plugin/gstclapperimporterloader.h index f008535a..fd91fb81 100644 --- a/lib/gst/plugin/gstclapperimporterloader.h +++ b/lib/gst/plugin/gstclapperimporterloader.h @@ -42,6 +42,8 @@ GstClapperImporterLoader * gst_clapper_importer_loader_new GstPadTemplate * gst_clapper_importer_loader_make_sink_pad_template (void); +GstCaps * gst_clapper_importer_loader_make_actual_caps (GstClapperImporterLoader *loader); + gboolean gst_clapper_importer_loader_find_importer_for_caps (GstClapperImporterLoader *loader, GstCaps *caps, GstClapperImporter **importer); gboolean gst_clapper_importer_loader_find_importer_for_context_query (GstClapperImporterLoader *loader, GstQuery *query, GstClapperImporter **importer); diff --git a/lib/gst/plugin/gstclappersink.c b/lib/gst/plugin/gstclappersink.c index 788a2f84..43667804 100644 --- a/lib/gst/plugin/gstclappersink.c +++ b/lib/gst/plugin/gstclappersink.c @@ -695,9 +695,10 @@ gst_clapper_sink_get_times (GstBaseSink *bsink, GstBuffer *buffer, static GstCaps * gst_clapper_sink_get_caps (GstBaseSink *bsink, GstCaps *filter) { + GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink); GstCaps *result, *tmp; - tmp = gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (bsink)); + tmp = gst_clapper_importer_loader_make_actual_caps (self->loader); if (filter) { GST_DEBUG ("Intersecting with filter caps: %" GST_PTR_FORMAT, filter); diff --git a/lib/gst/plugin/importers/gstclapperglimporter.c b/lib/gst/plugin/importers/gstclapperglimporter.c index 9cdfcbee..f919a734 100644 --- a/lib/gst/plugin/importers/gstclapperglimporter.c +++ b/lib/gst/plugin/importers/gstclapperglimporter.c @@ -61,7 +61,7 @@ make_importer (void) } GstCaps * -make_caps (GstRank *rank, GStrv *context_types) +make_caps (gboolean is_template, GstRank *rank, GStrv *context_types) { *rank = GST_RANK_SECONDARY; *context_types = gst_clapper_gl_base_importer_make_gl_context_types (); diff --git a/lib/gst/plugin/importers/gstclappergluploader.c b/lib/gst/plugin/importers/gstclappergluploader.c index e4f9d45f..349d9409 100644 --- a/lib/gst/plugin/importers/gstclappergluploader.c +++ b/lib/gst/plugin/importers/gstclappergluploader.c @@ -265,12 +265,12 @@ _update_glx_caps_on_main (GstCaps *caps) #endif GstCaps * -make_caps (GstRank *rank, GStrv *context_types) +make_caps (gboolean is_template, GstRank *rank, GStrv *context_types) { GstCaps *caps = gst_gl_upload_get_input_template_caps (); #if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX - if (!(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback) + if (!is_template && !(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback) _update_glx_caps_on_main, caps))) gst_clear_caps (&caps); #endif diff --git a/lib/gst/plugin/importers/gstclapperrawimporter.c b/lib/gst/plugin/importers/gstclapperrawimporter.c index 67de1f58..00cd9b71 100644 --- a/lib/gst/plugin/importers/gstclapperrawimporter.c +++ b/lib/gst/plugin/importers/gstclapperrawimporter.c @@ -97,7 +97,7 @@ make_importer (void) } GstCaps * -make_caps (GstRank *rank, GStrv *context_types) +make_caps (gboolean is_template, GstRank *rank, GStrv *context_types) { *rank = GST_RANK_MARGINAL; From 713449b4abc0c2af1de3bba8603389707767b4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Thu, 26 May 2022 10:17:36 +0200 Subject: [PATCH 3/4] plugin: sink: Only add pool to query if there is one --- lib/gst/plugin/gstclappersink.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/gst/plugin/gstclappersink.c b/lib/gst/plugin/gstclappersink.c index 43667804..22e6bd76 100644 --- a/lib/gst/plugin/gstclappersink.c +++ b/lib/gst/plugin/gstclappersink.c @@ -412,7 +412,6 @@ static gboolean gst_clapper_sink_propose_allocation (GstBaseSink *bsink, GstQuery *query) { GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink); - GstBufferPool *pool = NULL; GstCaps *caps; GstVideoInfo info; guint size, min_buffers; @@ -437,6 +436,7 @@ gst_clapper_sink_propose_allocation (GstBaseSink *bsink, GstQuery *query) min_buffers = 3; if (need_pool) { + GstBufferPool *pool; GstStructure *config = NULL; GST_DEBUG_OBJECT (self, "Need to create buffer pool"); @@ -458,16 +458,15 @@ gst_clapper_sink_propose_allocation (GstBaseSink *bsink, GstQuery *query) GST_ERROR_OBJECT (self, "Failed to set config"); return FALSE; } + + gst_query_add_allocation_pool (query, pool, size, min_buffers, 0); + gst_object_unref (pool); } else if (config) { GST_WARNING_OBJECT (self, "Got config without a pool to apply it"); gst_structure_free (config); } } - gst_query_add_allocation_pool (query, pool, size, min_buffers, 0); - if (pool) - gst_object_unref (pool); - GST_CLAPPER_SINK_LOCK (self); gst_clapper_importer_add_allocation_metas (self->importer, query); GST_CLAPPER_SINK_UNLOCK (self); From 91efc4ecdbc1d4ee35271ae5a65234a4c006c239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Dzi=C4=99giel?= Date: Thu, 26 May 2022 10:21:06 +0200 Subject: [PATCH 4/4] plugin: gluploader: Use GLUpload provided propose_allocation method Instead figuring out what kind of pool we should make just use the upstream provided functionality that comes as part of GLUpload API. Fixes uploads with GstVideoGLTextureUploadMeta, which legacy VAAPI plugin uses on GLX. --- .../plugin/importers/gstclappergluploader.c | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/gst/plugin/importers/gstclappergluploader.c b/lib/gst/plugin/importers/gstclappergluploader.c index 349d9409..3f779349 100644 --- a/lib/gst/plugin/importers/gstclappergluploader.c +++ b/lib/gst/plugin/importers/gstclappergluploader.c @@ -137,6 +137,31 @@ _upload_perform_locked (GstClapperGLUploader *self, GstBuffer *buffer) return upload_buf; } +static GstBufferPool * +gst_clapper_gl_uploader_create_pool (GstClapperImporter *importer, GstStructure **config) +{ + /* Since GLUpload API provides a ready to use propose_allocation method, + * we will use it with our query in add_allocation_metas instead of + * making pool here ourselves */ + return NULL; +} + +static void +gst_clapper_gl_uploader_add_allocation_metas (GstClapperImporter *importer, GstQuery *query) +{ + GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer); + GstGLUpload *upload; + + GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self); + upload = gst_object_ref (self->upload); + GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self); + + gst_gl_upload_propose_allocation (upload, NULL, query); + gst_object_unref (upload); + + GST_CLAPPER_IMPORTER_CLASS (parent_class)->add_allocation_metas (importer, query); +} + static GdkTexture * gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer, GstBuffer *buffer, GstVideoInfo *v_info) @@ -218,6 +243,8 @@ gst_clapper_gl_uploader_class_init (GstClapperGLUploaderClass *klass) importer_class->prepare = gst_clapper_gl_uploader_prepare; importer_class->set_caps = gst_clapper_gl_uploader_set_caps; + importer_class->create_pool = gst_clapper_gl_uploader_create_pool; + importer_class->add_allocation_metas = gst_clapper_gl_uploader_add_allocation_metas; importer_class->generate_texture = gst_clapper_gl_uploader_generate_texture; }