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..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); @@ -695,9 +694,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 454cc510..3f779349 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); @@ -132,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) @@ -213,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; } @@ -222,11 +254,59 @@ make_importer (void) return g_object_new (GST_TYPE_CLAPPER_GL_UPLOADER, NULL); } -GstCaps * -make_caps (GstRank *rank, GStrv *context_types) +#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 (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 (!is_template && !(! !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; } 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;