plugin: Rework code to use new GL context handler

Create a GL context handler subclass of recently added context handler base class and
rework code to use it. This simplifies a lot of things, like: switching of importers
at runtime, handling context queries, sharing data between importers, etc.
This commit is contained in:
Rafał Dzięgiel
2022-06-12 14:03:36 +02:00
parent 0920914b89
commit 04a028d689
17 changed files with 713 additions and 847 deletions

View File

@@ -89,6 +89,14 @@ _default_create_pool (GstClapperImporter *self, GstStructure **config)
return NULL; return NULL;
} }
static void
_default_add_allocation_metas (GstClapperImporter *importer, GstQuery *query)
{
/* Importer base class handles GstVideoOverlayCompositionMeta */
gst_query_add_allocation_meta (query, GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
}
static GdkTexture * static GdkTexture *
_default_generate_texture (GstClapperImporter *self, _default_generate_texture (GstClapperImporter *self,
GstBuffer *buffer, GstVideoInfo *v_info) GstBuffer *buffer, GstVideoInfo *v_info)
@@ -144,6 +152,7 @@ gst_clapper_importer_class_init (GstClapperImporterClass *klass)
gobject_class->finalize = gst_clapper_importer_finalize; gobject_class->finalize = gst_clapper_importer_finalize;
importer_class->create_pool = _default_create_pool; importer_class->create_pool = _default_create_pool;
importer_class->add_allocation_metas = _default_add_allocation_metas;
importer_class->generate_texture = _default_generate_texture; importer_class->generate_texture = _default_generate_texture;
} }
@@ -295,30 +304,6 @@ gst_clapper_importer_prepare_overlays_locked (GstClapperImporter *self)
GST_LOG_OBJECT (self, "Prepared overlays: %u", self->pending_overlays->len); GST_LOG_OBJECT (self, "Prepared overlays: %u", self->pending_overlays->len);
} }
gboolean
gst_clapper_importer_prepare (GstClapperImporter *self)
{
GstClapperImporterClass *importer_class = GST_CLAPPER_IMPORTER_GET_CLASS (self);
if (importer_class->prepare) {
if (!importer_class->prepare (self))
return FALSE;
}
GST_DEBUG_OBJECT (self, "Importer prepared");
return TRUE;
}
void
gst_clapper_importer_share_data (GstClapperImporter *self, GstClapperImporter *dest)
{
GstClapperImporterClass *importer_class = GST_CLAPPER_IMPORTER_GET_CLASS (self);
if (importer_class->share_data)
importer_class->share_data (self, dest);
}
void void
gst_clapper_importer_set_caps (GstClapperImporter *self, GstCaps *caps) gst_clapper_importer_set_caps (GstClapperImporter *self, GstCaps *caps)
{ {
@@ -362,22 +347,9 @@ gst_clapper_importer_add_allocation_metas (GstClapperImporter *self, GstQuery *q
{ {
GstClapperImporterClass *importer_class = GST_CLAPPER_IMPORTER_GET_CLASS (self); GstClapperImporterClass *importer_class = GST_CLAPPER_IMPORTER_GET_CLASS (self);
if (importer_class->add_allocation_metas)
importer_class->add_allocation_metas (self, query); importer_class->add_allocation_metas (self, query);
} }
gboolean
gst_clapper_importer_handle_context_query (GstClapperImporter *self,
GstBaseSink *bsink, GstQuery *query)
{
GstClapperImporterClass *importer_class = GST_CLAPPER_IMPORTER_GET_CLASS (self);
if (!importer_class->handle_context_query)
return FALSE;
return importer_class->handle_context_query (self, bsink, query);
}
void void
gst_clapper_importer_snapshot (GstClapperImporter *self, GdkSnapshot *snapshot, gst_clapper_importer_snapshot (GstClapperImporter *self, GdkSnapshot *snapshot,
gdouble width, gdouble height) gdouble width, gdouble height)

View File

@@ -35,9 +35,9 @@ G_BEGIN_DECLS
#define GST_CLAPPER_IMPORTER_DEFINE(camel,lower,type) \ #define GST_CLAPPER_IMPORTER_DEFINE(camel,lower,type) \
G_DEFINE_TYPE (camel, lower, type) \ G_DEFINE_TYPE (camel, lower, type) \
G_MODULE_EXPORT GstClapperImporter *make_importer (void); \ G_MODULE_EXPORT GstClapperImporter *make_importer (GPtrArray *context_handlers); \
G_MODULE_EXPORT GstCaps *make_caps (gboolean is_template, \ G_MODULE_EXPORT GstCaps *make_caps (gboolean is_template, \
GstRank *rank, GStrv *context_types); GstRank *rank, GPtrArray *context_handlers);
typedef struct _GstClapperImporter GstClapperImporter; typedef struct _GstClapperImporter GstClapperImporter;
typedef struct _GstClapperImporterClass GstClapperImporterClass; typedef struct _GstClapperImporterClass GstClapperImporterClass;
@@ -65,18 +65,9 @@ struct _GstClapperImporterClass
{ {
GstObjectClass parent_class; GstObjectClass parent_class;
gboolean (* prepare) (GstClapperImporter *importer);
void (* share_data) (GstClapperImporter *src,
GstClapperImporter *dest);
void (* set_caps) (GstClapperImporter *importer, void (* set_caps) (GstClapperImporter *importer,
GstCaps *caps); GstCaps *caps);
gboolean (* handle_context_query) (GstClapperImporter *importer,
GstBaseSink *bsink,
GstQuery *query);
GstBufferPool * (* create_pool) (GstClapperImporter *importer, GstBufferPool * (* create_pool) (GstClapperImporter *importer,
GstStructure **config); GstStructure **config);
@@ -90,9 +81,6 @@ struct _GstClapperImporterClass
GType gst_clapper_importer_get_type (void); GType gst_clapper_importer_get_type (void);
gboolean gst_clapper_importer_prepare (GstClapperImporter *importer);
void gst_clapper_importer_share_data (GstClapperImporter *importer, GstClapperImporter *dest);
gboolean gst_clapper_importer_handle_context_query (GstClapperImporter *importer, GstBaseSink *bsink, GstQuery *query);
GstBufferPool * gst_clapper_importer_create_pool (GstClapperImporter *importer, GstStructure **config); GstBufferPool * gst_clapper_importer_create_pool (GstClapperImporter *importer, GstStructure **config);
void gst_clapper_importer_add_allocation_metas (GstClapperImporter *importer, GstQuery *query); void gst_clapper_importer_add_allocation_metas (GstClapperImporter *importer, GstQuery *query);

View File

@@ -25,6 +25,7 @@
#include "gstclapperimporterloader.h" #include "gstclapperimporterloader.h"
#include "gstclapperimporter.h" #include "gstclapperimporter.h"
#include "gstclappercontexthandler.h"
#define GST_CAT_DEFAULT gst_clapper_importer_loader_debug #define GST_CAT_DEFAULT gst_clapper_importer_loader_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
@@ -32,15 +33,14 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define parent_class gst_clapper_importer_loader_parent_class #define parent_class gst_clapper_importer_loader_parent_class
G_DEFINE_TYPE (GstClapperImporterLoader, gst_clapper_importer_loader, GST_TYPE_OBJECT); G_DEFINE_TYPE (GstClapperImporterLoader, gst_clapper_importer_loader, GST_TYPE_OBJECT);
typedef GstClapperImporter* (* MakeImporter) (void); typedef GstClapperImporter* (* MakeImporter) (GPtrArray *context_handlers);
typedef GstCaps* (* MakeCaps) (gboolean is_template, GstRank *rank, GStrv *context_types); typedef GstCaps* (* MakeCaps) (gboolean is_template, GstRank *rank, GPtrArray *context_handlers);
typedef struct typedef struct
{ {
GModule *module; GModule *module;
GstCaps *caps; GstCaps *caps;
GstRank rank; GstRank rank;
GStrv context_types;
} GstClapperImporterData; } GstClapperImporterData;
static void static void
@@ -49,16 +49,17 @@ gst_clapper_importer_data_free (GstClapperImporterData *data)
GST_TRACE ("Freeing importer data: %" GST_PTR_FORMAT, data); GST_TRACE ("Freeing importer data: %" GST_PTR_FORMAT, data);
gst_clear_caps (&data->caps); gst_clear_caps (&data->caps);
g_strfreev (data->context_types);
g_free (data); g_free (data);
} }
static GstClapperImporterData * static GstClapperImporterData *
_obtain_importer_data (GModule *module, gboolean is_template) _obtain_importer_data (GModule *module, gboolean is_template, GPtrArray *context_handlers)
{ {
MakeCaps make_caps; MakeCaps make_caps;
GstClapperImporterData *data; GstClapperImporterData *data;
GST_DEBUG ("Found importer: %s", g_module_name (module));
if (!g_module_symbol (module, "make_caps", (gpointer *) &make_caps) if (!g_module_symbol (module, "make_caps", (gpointer *) &make_caps)
|| make_caps == NULL) { || make_caps == NULL) {
GST_WARNING ("Make caps function missing in importer"); GST_WARNING ("Make caps function missing in importer");
@@ -67,26 +68,30 @@ _obtain_importer_data (GModule *module, gboolean is_template)
data = g_new0 (GstClapperImporterData, 1); data = g_new0 (GstClapperImporterData, 1);
data->module = module; data->module = module;
data->caps = make_caps (is_template, &data->rank, &data->context_types); data->caps = make_caps (is_template, &data->rank, context_handlers);
GST_TRACE ("Created importer data: %" GST_PTR_FORMAT, data); GST_TRACE ("Created importer data: %" GST_PTR_FORMAT, data);
if (G_UNLIKELY (!data->caps)) { if (G_UNLIKELY (!data->caps)) {
if (!is_template) {
GST_ERROR ("Invalid importer without caps: %s", GST_ERROR ("Invalid importer without caps: %s",
g_module_name (data->module)); g_module_name (data->module));
} else {
/* When importer cannot be actually used, due to e.g. unsupported HW */
GST_DEBUG ("No actual caps returned from importer");
}
gst_clapper_importer_data_free (data); gst_clapper_importer_data_free (data);
return NULL; return NULL;
} }
GST_DEBUG ("Found importer: %s, caps: %" GST_PTR_FORMAT, GST_DEBUG ("Importer caps: %" GST_PTR_FORMAT, data->caps);
g_module_name (data->module), data->caps);
return data; return data;
} }
static GstClapperImporter * static GstClapperImporter *
_obtain_importer_internal (GModule *module) _obtain_importer_internal (GModule *module, GPtrArray *context_handlers)
{ {
MakeImporter make_importer; MakeImporter make_importer;
GstClapperImporter *importer; GstClapperImporter *importer;
@@ -97,7 +102,7 @@ _obtain_importer_internal (GModule *module)
return NULL; return NULL;
} }
importer = make_importer (); importer = make_importer (context_handlers);
GST_TRACE ("Created importer: %" GST_PTR_FORMAT, importer); GST_TRACE ("Created importer: %" GST_PTR_FORMAT, importer);
return importer; return importer;
@@ -183,13 +188,14 @@ _sort_importers_cb (gconstpointer a, gconstpointer b)
} }
static GPtrArray * static GPtrArray *
_obtain_available_importers (gboolean is_template) _obtain_importers (gboolean is_template, GPtrArray *context_handlers)
{ {
const GPtrArray *modules; const GPtrArray *modules;
GPtrArray *importers; GPtrArray *importers;
guint i; guint i;
GST_DEBUG ("Checking available importers"); GST_DEBUG ("Checking %s importers",
(is_template) ? "available" : "usable");
modules = gst_clapper_importer_loader_get_available_modules (); modules = gst_clapper_importer_loader_get_available_modules ();
importers = g_ptr_array_new_with_free_func ( importers = g_ptr_array_new_with_free_func (
@@ -199,13 +205,14 @@ _obtain_available_importers (gboolean is_template)
GModule *module = g_ptr_array_index (modules, i); GModule *module = g_ptr_array_index (modules, i);
GstClapperImporterData *data; GstClapperImporterData *data;
if ((data = _obtain_importer_data (module, is_template))) if ((data = _obtain_importer_data (module, is_template, context_handlers)))
g_ptr_array_add (importers, data); g_ptr_array_add (importers, data);
} }
g_ptr_array_sort (importers, (GCompareFunc) _sort_importers_cb); g_ptr_array_sort (importers, (GCompareFunc) _sort_importers_cb);
GST_DEBUG ("Found %i available importers", importers->len); GST_DEBUG ("Found %i %s importers", importers->len,
(is_template) ? "available" : "usable");
return importers; return importers;
} }
@@ -244,7 +251,7 @@ gst_clapper_importer_loader_make_sink_pad_template (void)
GST_DEBUG ("Making sink pad template"); GST_DEBUG ("Making sink pad template");
importers = _obtain_available_importers (TRUE); importers = _obtain_importers (TRUE, NULL);
caps = _make_caps_for_importers (importers); caps = _make_caps_for_importers (importers);
g_ptr_array_unref (importers); g_ptr_array_unref (importers);
@@ -265,6 +272,22 @@ gst_clapper_importer_loader_make_actual_caps (GstClapperImporterLoader *self)
return _make_caps_for_importers (self->importers); return _make_caps_for_importers (self->importers);
} }
gboolean
gst_clapper_importer_loader_handle_context_query (GstClapperImporterLoader *self,
GstBaseSink *bsink, GstQuery *query)
{
guint i;
for (i = 0; i < self->context_handlers->len; i++) {
GstClapperContextHandler *handler = g_ptr_array_index (self->context_handlers, i);
if (gst_clapper_context_handler_handle_context_query (handler, bsink, query))
return TRUE;
}
return FALSE;
}
static const GstClapperImporterData * static const GstClapperImporterData *
_get_importer_data_for_caps (const GPtrArray *importers, const GstCaps *caps) _get_importer_data_for_caps (const GPtrArray *importers, const GstCaps *caps)
{ {
@@ -282,88 +305,40 @@ _get_importer_data_for_caps (const GPtrArray *importers, const GstCaps *caps)
return NULL; return NULL;
} }
static const GstClapperImporterData * gboolean
_get_importer_data_for_context_type (const GPtrArray *importers, const gchar *context_type) gst_clapper_importer_loader_find_importer_for_caps (GstClapperImporterLoader *self,
{ GstCaps *caps, GstClapperImporter **importer)
guint i;
for (i = 0; i < importers->len; i++) {
GstClapperImporterData *data = g_ptr_array_index (importers, i);
guint j;
if (!data->context_types)
continue;
for (j = 0; data->context_types[j]; j++) {
if (strcmp (context_type, data->context_types[j]))
continue;
return data;
}
}
return NULL;
}
static gboolean
_find_importer_internal (GstClapperImporterLoader *self,
GstCaps *caps, GstQuery *query, GstClapperImporter **importer)
{ {
const GstClapperImporterData *data = NULL; const GstClapperImporterData *data = NULL;
GstClapperImporter *found_importer = NULL; GstClapperImporter *found_importer = NULL;
GST_OBJECT_LOCK (self); GST_OBJECT_LOCK (self);
if (caps) {
GST_DEBUG_OBJECT (self, "Requested importer for caps: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Requested importer for caps: %" GST_PTR_FORMAT, caps);
data = _get_importer_data_for_caps (self->importers, caps); data = _get_importer_data_for_caps (self->importers, caps);
} else if (query) {
const gchar *context_type;
gst_query_parse_context_type (query, &context_type);
GST_DEBUG_OBJECT (self, "Requested importer for context: %s", context_type);
data = _get_importer_data_for_context_type (self->importers, context_type);
}
GST_LOG_OBJECT (self, "Old importer path: %s, new path: %s", GST_LOG_OBJECT (self, "Old importer path: %s, new path: %s",
(self->last_module) ? g_module_name (self->last_module) : NULL, (self->last_module) ? g_module_name (self->last_module) : NULL,
(data) ? g_module_name (data->module) : NULL); (data) ? g_module_name (data->module) : NULL);
if (!data) { if (G_UNLIKELY (!data)) {
/* In case of missing importer for context query, leave the old one.
* We should allow some queries to go through unresponded */
if (query)
GST_DEBUG_OBJECT (self, "No importer for query, leaving old one");
else
gst_clear_object (importer); gst_clear_object (importer);
goto finish; goto finish;
} }
if (*importer && (self->last_module == data->module)) { if (*importer && (self->last_module == data->module)) {
GST_DEBUG_OBJECT (self, "No importer change"); GST_DEBUG_OBJECT (self, "No importer change");
if (caps)
gst_clapper_importer_set_caps (*importer, caps); gst_clapper_importer_set_caps (*importer, caps);
goto finish; goto finish;
} }
found_importer = _obtain_importer_internal (data->module); found_importer = _obtain_importer_internal (data->module, self->context_handlers);
if (*importer && found_importer)
gst_clapper_importer_share_data (*importer, found_importer);
gst_clear_object (importer); gst_clear_object (importer);
if (!found_importer || !gst_clapper_importer_prepare (found_importer)) { if (!found_importer)
gst_clear_object (&found_importer);
goto finish; goto finish;
}
if (caps)
gst_clapper_importer_set_caps (found_importer, caps); gst_clapper_importer_set_caps (found_importer, caps);
*importer = found_importer; *importer = found_importer;
@@ -378,33 +353,12 @@ finish:
return (*importer != NULL); return (*importer != NULL);
} }
gboolean
gst_clapper_importer_loader_find_importer_for_caps (GstClapperImporterLoader *self,
GstCaps *caps, GstClapperImporter **importer)
{
return _find_importer_internal (self, caps, NULL, importer);
}
gboolean
gst_clapper_importer_loader_find_importer_for_context_query (GstClapperImporterLoader *self,
GstQuery *query, GstClapperImporter **importer)
{
return _find_importer_internal (self, NULL, query, importer);
}
static void static void
gst_clapper_importer_loader_init (GstClapperImporterLoader *self) gst_clapper_importer_loader_init (GstClapperImporterLoader *self)
{ {
} self->context_handlers = g_ptr_array_new_with_free_func (
(GDestroyNotify) gst_object_unref);
static void self->importers = _obtain_importers (FALSE, self->context_handlers);
gst_clapper_importer_loader_constructed (GObject *object)
{
GstClapperImporterLoader *self = GST_CLAPPER_IMPORTER_LOADER_CAST (object);
self->importers = _obtain_available_importers (FALSE);
GST_CALL_PARENT (G_OBJECT_CLASS, constructed, (object));
} }
static void static void
@@ -414,8 +368,11 @@ gst_clapper_importer_loader_finalize (GObject *object)
GST_TRACE ("Finalize"); GST_TRACE ("Finalize");
if (self->importers)
g_ptr_array_unref (self->importers); g_ptr_array_unref (self->importers);
g_ptr_array_unref (self->context_handlers);
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
} }
@@ -424,6 +381,5 @@ gst_clapper_importer_loader_class_init (GstClapperImporterLoaderClass *klass)
{ {
GObjectClass *gobject_class = (GObjectClass *) klass; GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->constructed = gst_clapper_importer_loader_constructed;
gobject_class->finalize = gst_clapper_importer_loader_finalize; gobject_class->finalize = gst_clapper_importer_loader_finalize;
} }

View File

@@ -20,6 +20,7 @@
#pragma once #pragma once
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/base/gstbasesink.h>
#include "gstclapperimporter.h" #include "gstclapperimporter.h"
@@ -35,7 +36,9 @@ struct _GstClapperImporterLoader
GstObject parent; GstObject parent;
GModule *last_module; GModule *last_module;
GPtrArray *importers; GPtrArray *importers;
GPtrArray *context_handlers;
}; };
GstClapperImporterLoader * gst_clapper_importer_loader_new (void); GstClapperImporterLoader * gst_clapper_importer_loader_new (void);
@@ -44,8 +47,8 @@ GstPadTemplate * gst_clapper_importer_loader_make_sink_pad_template
GstCaps * gst_clapper_importer_loader_make_actual_caps (GstClapperImporterLoader *loader); GstCaps * gst_clapper_importer_loader_make_actual_caps (GstClapperImporterLoader *loader);
gboolean gst_clapper_importer_loader_handle_context_query (GstClapperImporterLoader *loader, GstBaseSink *bsink, GstQuery *query);
gboolean gst_clapper_importer_loader_find_importer_for_caps (GstClapperImporterLoader *loader, GstCaps *caps, GstClapperImporter **importer); 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);
G_END_DECLS G_END_DECLS

View File

@@ -480,24 +480,11 @@ gst_clapper_sink_query (GstBaseSink *bsink, GstQuery *query)
GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink); GstClapperSink *self = GST_CLAPPER_SINK_CAST (bsink);
gboolean res = FALSE; gboolean res = FALSE;
GST_CLAPPER_SINK_LOCK (self);
if (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT) { if (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT) {
gboolean is_inactive; GST_CLAPPER_SINK_LOCK (self);
res = gst_clapper_importer_loader_handle_context_query (self->loader, bsink, query);
GST_OBJECT_LOCK (self);
is_inactive = (GST_STATE (self) < GST_STATE_PAUSED);
GST_OBJECT_UNLOCK (self);
/* Some random context query in the middle of playback
* should not trigger importer replacement */
if (is_inactive)
gst_clapper_importer_loader_find_importer_for_context_query (self->loader, query, &self->importer);
if (self->importer)
res = gst_clapper_importer_handle_context_query (self->importer, bsink, query);
}
GST_CLAPPER_SINK_UNLOCK (self); GST_CLAPPER_SINK_UNLOCK (self);
}
if (res) if (res)
return TRUE; return TRUE;

View File

@@ -21,43 +21,41 @@
#include "config.h" #include "config.h"
#endif #endif
#include "gstclapperglbaseimporter.h" #include "gstclapperglcontexthandler.h"
#include "gst/plugin/gstgdkformats.h" #include "gst/plugin/gstgdkformats.h"
#include "gst/plugin/gstgtkutils.h" #include "gst/plugin/gstgtkutils.h"
#include <gst/gl/gstglfuncs.h> #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND
#include <gdk/wayland/gdkwayland.h> #include <gdk/wayland/gdkwayland.h>
#include <gst/gl/wayland/gstgldisplay_wayland.h> #include <gst/gl/wayland/gstgldisplay_wayland.h>
#endif #endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11 #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11
#include <gdk/x11/gdkx.h> #include <gdk/x11/gdkx.h>
#endif #endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_GLX
#include <gst/gl/x11/gstgldisplay_x11.h> #include <gst/gl/x11/gstgldisplay_x11.h>
#endif #endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL || GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL || GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL
#include <gst/gl/egl/gstgldisplay_egl.h> #include <gst/gl/egl/gstgldisplay_egl.h>
#endif #endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32 #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32
#include <gdk/win32/gdkwin32.h> #include <gdk/win32/gdkwin32.h>
#endif #endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_MACOS #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_MACOS
#include <gdk/macos/gdkmacos.h> #include <gdk/macos/gdkmacos.h>
#endif #endif
#define GST_CAT_DEFAULT gst_clapper_gl_base_importer_debug #define GST_CAT_DEFAULT gst_clapper_gl_context_handler_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define parent_class gst_clapper_gl_base_importer_parent_class #define parent_class gst_clapper_gl_context_handler_parent_class
G_DEFINE_TYPE (GstClapperGLBaseImporter, gst_clapper_gl_base_importer, GST_TYPE_CLAPPER_IMPORTER); G_DEFINE_TYPE (GstClapperGLContextHandler, gst_clapper_gl_context_handler, GST_TYPE_OBJECT);
static GstGLContext * static GstGLContext *
wrap_current_gl (GstGLDisplay *display, GdkGLAPI gdk_gl_api, GstGLPlatform platform) _wrap_current_gl (GstGLDisplay *display, GdkGLAPI gdk_gl_api, GstGLPlatform platform)
{ {
GstGLAPI gst_gl_api = GST_GL_API_NONE; GstGLAPI gst_gl_api = GST_GL_API_NONE;
@@ -85,372 +83,6 @@ wrap_current_gl (GstGLDisplay *display, GdkGLAPI gdk_gl_api, GstGLPlatform platf
return NULL; return NULL;
} }
static gboolean
retrieve_gl_context_on_main (GstClapperGLBaseImporter *self)
{
GstClapperGLBaseImporterClass *gl_bi_class = GST_CLAPPER_GL_BASE_IMPORTER_GET_CLASS (self);
GdkDisplay *gdk_display;
GdkGLContext *gdk_context;
GError *error = NULL;
GdkGLAPI gdk_gl_api;
GstGLPlatform platform = GST_GL_PLATFORM_NONE;
gint gl_major = 0, gl_minor = 0;
if (!gtk_init_check ()) {
GST_ERROR_OBJECT (self, "Could not ensure GTK initialization");
return FALSE;
}
/* Make sure we are clean here, otherwise data sharing
* between GL-based importers may lead to leaks */
gst_clear_object (&self->wrapped_context);
g_clear_object (&self->gdk_context);
gst_clear_object (&self->gst_display);
gdk_display = gdk_display_get_default ();
if (G_UNLIKELY (!gdk_display)) {
GST_ERROR_OBJECT (self, "Could not retrieve Gdk display");
return FALSE;
}
if (!(gdk_context = gdk_display_create_gl_context (gdk_display, &error))) {
GST_ERROR_OBJECT (self, "Error creating Gdk GL context: %s",
error ? error->message : "No error set by Gdk");
g_clear_error (&error);
return FALSE;
}
if (!gl_bi_class->gdk_context_realize (self, gdk_context)) {
GST_ERROR_OBJECT (self, "Could not realize Gdk context: %" GST_PTR_FORMAT,
gdk_context);
g_object_unref (gdk_context);
return FALSE;
}
gdk_gl_api = gdk_gl_context_get_api (gdk_context);
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
self->gdk_context = gdk_context;
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND
if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) {
struct wl_display *wayland_display =
gdk_wayland_display_get_wl_display (gdk_display);
self->gst_display = (GstGLDisplay *)
gst_gl_display_wayland_new_with_display (wayland_display);
}
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11
if (GDK_IS_X11_DISPLAY (gdk_display)) {
gpointer display_ptr;
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL
display_ptr = gdk_x11_display_get_egl_display (gdk_display);
if (display_ptr) {
self->gst_display = (GstGLDisplay *)
gst_gl_display_egl_new_with_egl_display (display_ptr);
}
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX
if (!self->gst_display) {
display_ptr = gdk_x11_display_get_xdisplay (gdk_display);
self->gst_display = (GstGLDisplay *)
gst_gl_display_x11_new_with_display (display_ptr);
}
}
#endif
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32
if (GDK_IS_WIN32_DISPLAY (gdk_display)) {
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL
gpointer display_ptr = gdk_win32_display_get_egl_display (gdk_display);
if (display_ptr) {
self->gst_display = (GstGLDisplay *)
gst_gl_display_egl_new_with_egl_display (display_ptr);
}
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_WGL
if (!self->gst_display) {
self->gst_display =
gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_WIN32);
}
}
#endif
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_MACOS
if (GDK_IS_MACOS_DISPLAY (gdk_display)) {
self->gst_display =
gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_COCOA);
}
#endif
/* Fallback to generic display */
if (G_UNLIKELY (!self->gst_display)) {
GST_WARNING_OBJECT (self, "Unknown Gdk display!");
self->gst_display = gst_gl_display_new ();
}
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND
if (GST_IS_GL_DISPLAY_WAYLAND (self->gst_display)) {
platform = GST_GL_PLATFORM_EGL;
GST_INFO_OBJECT (self, "Using EGL on Wayland");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL
if (GST_IS_GL_DISPLAY_EGL (self->gst_display)
&& GDK_IS_X11_DISPLAY (gdk_display)) {
platform = GST_GL_PLATFORM_EGL;
GST_INFO_OBJECT (self, "Using EGL on x11");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX
if (GST_IS_GL_DISPLAY_X11 (self->gst_display)) {
platform = GST_GL_PLATFORM_GLX;
GST_INFO_OBJECT (self, "Using GLX on x11");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL
if (GST_IS_GL_DISPLAY_EGL (self->gst_display)
&& GDK_IS_WIN32_DISPLAY (gdk_display)) {
platform = GST_GL_PLATFORM_EGL;
GST_INFO_OBJECT (self, "Using EGL on Win32");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_WGL
if (gst_gl_display_get_handle_type (self->gst_display) == GST_GL_DISPLAY_TYPE_WIN32) {
platform = GST_GL_PLATFORM_WGL;
GST_INFO_OBJECT (self, "Using WGL on Win32");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_MACOS
if (gst_gl_display_get_handle_type (self->gst_display) == GST_GL_DISPLAY_TYPE_COCOA) {
platform = GST_GL_PLATFORM_CGL;
GST_INFO_OBJECT (self, "Using CGL on macOS");
goto have_display;
}
#endif
g_clear_object (&self->gdk_context);
gst_clear_object (&self->gst_display);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
GST_ERROR_OBJECT (self, "Unsupported GL platform");
return FALSE;
have_display:
gdk_gl_context_make_current (self->gdk_context);
self->wrapped_context = wrap_current_gl (self->gst_display, gdk_gl_api, platform);
if (!self->wrapped_context) {
GST_ERROR ("Could not retrieve Gdk OpenGL context");
gdk_gl_context_clear_current ();
g_clear_object (&self->gdk_context);
gst_clear_object (&self->gst_display);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
return FALSE;
}
GST_INFO ("Retrieved Gdk OpenGL context %" GST_PTR_FORMAT, self->wrapped_context);
gst_gl_context_activate (self->wrapped_context, TRUE);
if (!gst_gl_context_fill_info (self->wrapped_context, &error)) {
GST_ERROR ("Failed to fill Gdk context info: %s", error->message);
g_clear_error (&error);
gst_gl_context_activate (self->wrapped_context, FALSE);
gst_clear_object (&self->wrapped_context);
g_clear_object (&self->gdk_context);
gst_clear_object (&self->gst_display);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
return FALSE;
}
gst_gl_context_get_gl_version (self->wrapped_context, &gl_major, &gl_minor);
GST_INFO ("Using OpenGL%s %i.%i", (gdk_gl_api == GDK_GL_API_GLES) ? " ES" : "",
gl_major, gl_minor);
/* Deactivate in both places */
gst_gl_context_activate (self->wrapped_context, FALSE);
gdk_gl_context_clear_current ();
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
return TRUE;
}
static gboolean
retrieve_gst_context (GstClapperGLBaseImporter *self)
{
GstGLDisplay *gst_display = NULL;
GstGLContext *gst_context = NULL;
GError *error = NULL;
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
gst_display = gst_object_ref (self->gst_display);
/* GstGLDisplay operations require display object lock to be held */
GST_OBJECT_LOCK (gst_display);
if (!self->gst_context) {
GST_TRACE_OBJECT (self, "Creating new GstGLContext");
if (!gst_gl_display_create_context (gst_display, self->wrapped_context,
&self->gst_context, &error)) {
GST_WARNING ("Could not create OpenGL context: %s",
error ? error->message : "Unknown");
g_clear_error (&error);
GST_OBJECT_UNLOCK (gst_display);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
return FALSE;
}
}
gst_context = gst_object_ref (self->gst_context);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
gst_gl_display_add_context (gst_display, gst_context);
GST_OBJECT_UNLOCK (gst_display);
gst_object_unref (gst_display);
gst_object_unref (gst_context);
return TRUE;
}
static gboolean
gst_clapper_gl_base_importer_prepare (GstClapperImporter *importer)
{
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
gboolean need_invoke;
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
need_invoke = (!self->gdk_context || !self->gst_display || !self->wrapped_context);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
if (need_invoke) {
if (!(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
retrieve_gl_context_on_main, self)))
return FALSE;
}
if (!retrieve_gst_context (self))
return FALSE;
if (!GST_CLAPPER_IMPORTER_CLASS (parent_class)->prepare)
return TRUE;
return GST_CLAPPER_IMPORTER_CLASS (parent_class)->prepare (importer);
}
static void
gst_clapper_gl_base_importer_share_data (GstClapperImporter *importer, GstClapperImporter *dest_importer)
{
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER (importer);
if (GST_IS_CLAPPER_GL_BASE_IMPORTER (dest_importer)) {
GstClapperGLBaseImporter *dest = GST_CLAPPER_GL_BASE_IMPORTER (dest_importer);
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (dest);
/* Successfully prepared GL importer should have all three */
if (self->gdk_context && self->gst_display && self->wrapped_context) {
g_clear_object (&dest->gdk_context);
dest->gdk_context = g_object_ref (self->gdk_context);
gst_clear_object (&dest->gst_display);
dest->gst_display = gst_object_ref (self->gst_display);
gst_clear_object (&dest->wrapped_context);
dest->wrapped_context = gst_object_ref (self->wrapped_context);
}
/* This context is not required, we can create it ourselves
* using gst_display and wrapped_context */
if (self->gst_context) {
gst_clear_object (&dest->gst_context);
dest->gst_context = gst_object_ref (self->gst_context);
}
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (dest);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
}
if (GST_CLAPPER_IMPORTER_CLASS (parent_class)->share_data)
GST_CLAPPER_IMPORTER_CLASS (parent_class)->share_data (importer, dest_importer);
}
static gboolean
gst_clapper_gl_base_importer_handle_context_query (GstClapperImporter *importer,
GstBaseSink *bsink, GstQuery *query)
{
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
gboolean res;
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
res = gst_gl_handle_context_query (GST_ELEMENT_CAST (bsink), query,
self->gst_display, self->gst_context, self->wrapped_context);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
return res;
}
static GstBufferPool *
gst_clapper_gl_base_importer_create_pool (GstClapperImporter *importer, GstStructure **config)
{
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
GstBufferPool *pool;
GST_DEBUG_OBJECT (self, "Creating new GL buffer pool");
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
pool = gst_gl_buffer_pool_new (self->gst_context);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
*config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_add_option (*config, GST_BUFFER_POOL_OPTION_VIDEO_META);
gst_buffer_pool_config_add_option (*config, GST_BUFFER_POOL_OPTION_GL_SYNC_META);
return pool;
}
static void
gst_clapper_gl_base_importer_add_allocation_metas (GstClapperImporter *importer, GstQuery *query)
{
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
gst_query_add_allocation_meta (query, GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
if (self->gst_context->gl_vtable->FenceSync)
gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, NULL);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
}
static gboolean static gboolean
_realize_gdk_context_with_api (GdkGLContext *gdk_context, GdkGLAPI api, gint maj, gint min) _realize_gdk_context_with_api (GdkGLContext *gdk_context, GdkGLAPI api, gint maj, gint min)
{ {
@@ -473,7 +105,7 @@ _realize_gdk_context_with_api (GdkGLContext *gdk_context, GdkGLAPI api, gint maj
} }
static gboolean static gboolean
gst_clapper_gl_base_importer_gdk_context_realize (GstClapperGLBaseImporter *self, GdkGLContext *gdk_context) _gl_context_handler_context_realize (GstClapperGLContextHandler *self, GdkGLContext *gdk_context)
{ {
GdkGLAPI preferred_api = GDK_GL_API_GL; GdkGLAPI preferred_api = GDK_GL_API_GL;
GdkDisplay *gdk_display; GdkDisplay *gdk_display;
@@ -501,15 +133,15 @@ gst_clapper_gl_base_importer_gdk_context_realize (GstClapperGLBaseImporter *self
/* Apple decoder uses rectangle texture-target, which GLES does not support. /* Apple decoder uses rectangle texture-target, which GLES does not support.
* For Linux we prefer EGL + GLES in order to get direct HW colorspace conversion. * For Linux we prefer EGL + GLES in order to get direct HW colorspace conversion.
* Windows will try EGL + GLES setup first and auto fallback to WGL. */ * Windows will try EGL + GLES setup first and auto fallback to WGL. */
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND
if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) if (GDK_IS_WAYLAND_DISPLAY (gdk_display))
preferred_api = GDK_GL_API_GLES; preferred_api = GDK_GL_API_GLES;
#endif #endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL
if (GDK_IS_X11_DISPLAY (gdk_display) && gdk_x11_display_get_egl_display (gdk_display)) if (GDK_IS_X11_DISPLAY (gdk_display) && gdk_x11_display_get_egl_display (gdk_display))
preferred_api = GDK_GL_API_GLES; preferred_api = GDK_GL_API_GLES;
#endif #endif
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL
if (GDK_IS_WIN32_DISPLAY (gdk_display) && gdk_win32_display_get_egl_display (gdk_display)) if (GDK_IS_WIN32_DISPLAY (gdk_display) && gdk_win32_display_get_egl_display (gdk_display))
preferred_api = GDK_GL_API_GLES; preferred_api = GDK_GL_API_GLES;
#endif #endif
@@ -518,7 +150,7 @@ gst_clapper_gl_base_importer_gdk_context_realize (GstClapperGLBaseImporter *self
* "scrambled" image on Linux with Intel GPUs that are mostly used together with * "scrambled" image on Linux with Intel GPUs that are mostly used together with
* x86 CPUs at the expense of using slightly slower non-direct DMABuf import. * x86 CPUs at the expense of using slightly slower non-direct DMABuf import.
* See: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1236 */ * See: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1236 */
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND || GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND || GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL
#if !defined(HAVE_GST_PATCHES) && (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)) #if !defined(HAVE_GST_PATCHES) && (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64))
preferred_api = GDK_GL_API_GL; preferred_api = GDK_GL_API_GL;
#endif #endif
@@ -547,16 +179,289 @@ gst_clapper_gl_base_importer_gdk_context_realize (GstClapperGLBaseImporter *self
return success; return success;
} }
static void static gboolean
gst_clapper_gl_base_importer_init (GstClapperGLBaseImporter *self) _retrieve_gl_context_on_main (GstClapperGLContextHandler *self)
{ {
g_mutex_init (&self->lock); GdkDisplay *gdk_display;
GdkGLContext *gdk_context;
GError *error = NULL;
GdkGLAPI gdk_gl_api;
GstGLPlatform platform = GST_GL_PLATFORM_NONE;
gint gl_major = 0, gl_minor = 0;
if (!gtk_init_check ()) {
GST_ERROR_OBJECT (self, "Could not ensure GTK initialization");
return FALSE;
}
gdk_display = gdk_display_get_default ();
if (G_UNLIKELY (!gdk_display)) {
GST_ERROR_OBJECT (self, "Could not retrieve Gdk display");
return FALSE;
}
if (!(gdk_context = gdk_display_create_gl_context (gdk_display, &error))) {
GST_ERROR_OBJECT (self, "Error creating Gdk GL context: %s",
error ? error->message : "No error set by Gdk");
g_clear_error (&error);
return FALSE;
}
if (!_gl_context_handler_context_realize (self, gdk_context)) {
GST_ERROR_OBJECT (self, "Could not realize Gdk context: %" GST_PTR_FORMAT,
gdk_context);
g_object_unref (gdk_context);
return FALSE;
}
gdk_gl_api = gdk_gl_context_get_api (gdk_context);
GST_OBJECT_LOCK (self);
self->gdk_context = gdk_context;
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND
if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) {
struct wl_display *wayland_display =
gdk_wayland_display_get_wl_display (gdk_display);
self->gst_display = (GstGLDisplay *)
gst_gl_display_wayland_new_with_display (wayland_display);
}
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11
if (GDK_IS_X11_DISPLAY (gdk_display)) {
gpointer display_ptr;
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL
display_ptr = gdk_x11_display_get_egl_display (gdk_display);
if (display_ptr) {
self->gst_display = (GstGLDisplay *)
gst_gl_display_egl_new_with_egl_display (display_ptr);
}
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_GLX
if (!self->gst_display) {
display_ptr = gdk_x11_display_get_xdisplay (gdk_display);
self->gst_display = (GstGLDisplay *)
gst_gl_display_x11_new_with_display (display_ptr);
}
}
#endif
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32
if (GDK_IS_WIN32_DISPLAY (gdk_display)) {
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL
gpointer display_ptr = gdk_win32_display_get_egl_display (gdk_display);
if (display_ptr) {
self->gst_display = (GstGLDisplay *)
gst_gl_display_egl_new_with_egl_display (display_ptr);
}
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_WGL
if (!self->gst_display) {
self->gst_display =
gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_WIN32);
}
}
#endif
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_MACOS
if (GDK_IS_MACOS_DISPLAY (gdk_display)) {
self->gst_display =
gst_gl_display_new_with_type (GST_GL_DISPLAY_TYPE_COCOA);
}
#endif
/* Fallback to generic display */
if (G_UNLIKELY (!self->gst_display)) {
GST_WARNING_OBJECT (self, "Unknown Gdk display!");
self->gst_display = gst_gl_display_new ();
}
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND
if (GST_IS_GL_DISPLAY_WAYLAND (self->gst_display)) {
platform = GST_GL_PLATFORM_EGL;
GST_INFO_OBJECT (self, "Using EGL on Wayland");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL
if (GST_IS_GL_DISPLAY_EGL (self->gst_display)
&& GDK_IS_X11_DISPLAY (gdk_display)) {
platform = GST_GL_PLATFORM_EGL;
GST_INFO_OBJECT (self, "Using EGL on x11");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_GLX
if (GST_IS_GL_DISPLAY_X11 (self->gst_display)) {
platform = GST_GL_PLATFORM_GLX;
GST_INFO_OBJECT (self, "Using GLX on x11");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL
if (GST_IS_GL_DISPLAY_EGL (self->gst_display)
&& GDK_IS_WIN32_DISPLAY (gdk_display)) {
platform = GST_GL_PLATFORM_EGL;
GST_INFO_OBJECT (self, "Using EGL on Win32");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_WGL
if (gst_gl_display_get_handle_type (self->gst_display) == GST_GL_DISPLAY_TYPE_WIN32) {
platform = GST_GL_PLATFORM_WGL;
GST_INFO_OBJECT (self, "Using WGL on Win32");
goto have_display;
}
#endif
#if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_MACOS
if (gst_gl_display_get_handle_type (self->gst_display) == GST_GL_DISPLAY_TYPE_COCOA) {
platform = GST_GL_PLATFORM_CGL;
GST_INFO_OBJECT (self, "Using CGL on macOS");
goto have_display;
}
#endif
g_clear_object (&self->gdk_context);
gst_clear_object (&self->gst_display);
GST_OBJECT_UNLOCK (self);
GST_ERROR_OBJECT (self, "Unsupported GL platform");
return FALSE;
have_display:
gdk_gl_context_make_current (self->gdk_context);
self->wrapped_context = _wrap_current_gl (self->gst_display, gdk_gl_api, platform);
if (!self->wrapped_context) {
GST_ERROR ("Could not retrieve Gdk OpenGL context");
gdk_gl_context_clear_current ();
g_clear_object (&self->gdk_context);
gst_clear_object (&self->gst_display);
GST_OBJECT_UNLOCK (self);
return FALSE;
}
GST_INFO ("Retrieved Gdk OpenGL context %" GST_PTR_FORMAT, self->wrapped_context);
gst_gl_context_activate (self->wrapped_context, TRUE);
if (!gst_gl_context_fill_info (self->wrapped_context, &error)) {
GST_ERROR ("Failed to fill Gdk context info: %s", error->message);
g_clear_error (&error);
gst_gl_context_activate (self->wrapped_context, FALSE);
gst_clear_object (&self->wrapped_context);
g_clear_object (&self->gdk_context);
gst_clear_object (&self->gst_display);
GST_OBJECT_UNLOCK (self);
return FALSE;
}
gst_gl_context_get_gl_version (self->wrapped_context, &gl_major, &gl_minor);
GST_INFO ("Using OpenGL%s %i.%i", (gdk_gl_api == GDK_GL_API_GLES) ? " ES" : "",
gl_major, gl_minor);
/* Deactivate in both places */
gst_gl_context_activate (self->wrapped_context, FALSE);
gdk_gl_context_clear_current ();
GST_OBJECT_UNLOCK (self);
return TRUE;
}
static gboolean
_retrieve_gst_context (GstClapperGLContextHandler *self)
{
GstGLDisplay *gst_display = NULL;
GstGLContext *gst_context = NULL;
GError *error = NULL;
GST_OBJECT_LOCK (self);
gst_display = gst_object_ref (self->gst_display);
GST_TRACE_OBJECT (self, "Creating new GstGLContext");
/* GstGLDisplay operations require display object lock to be held */
GST_OBJECT_LOCK (gst_display);
if (!gst_gl_display_create_context (gst_display, self->wrapped_context,
&self->gst_context, &error)) {
GST_WARNING ("Could not create OpenGL context: %s",
error ? error->message : "Unknown");
g_clear_error (&error);
GST_OBJECT_UNLOCK (gst_display);
GST_OBJECT_UNLOCK (self);
return FALSE;
}
gst_context = gst_object_ref (self->gst_context);
GST_OBJECT_UNLOCK (self);
gst_gl_display_add_context (gst_display, gst_context);
GST_OBJECT_UNLOCK (gst_display);
gst_object_unref (gst_display);
gst_object_unref (gst_context);
return TRUE;
}
static gboolean
gst_clapper_gl_context_handler_handle_context_query (GstClapperContextHandler *handler,
GstBaseSink *bsink, GstQuery *query)
{
GstClapperGLContextHandler *self = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (handler);
gboolean res;
GST_OBJECT_LOCK (self);
res = gst_gl_handle_context_query (GST_ELEMENT_CAST (bsink), query,
self->gst_display, self->gst_context, self->wrapped_context);
GST_OBJECT_UNLOCK (self);
return res;
} }
static void static void
gst_clapper_gl_base_importer_finalize (GObject *object) gst_clapper_gl_context_handler_init (GstClapperGLContextHandler *self)
{ {
GstClapperGLBaseImporter *self = GST_CLAPPER_GL_BASE_IMPORTER_CAST (object); }
static void
gst_clapper_gl_context_handler_constructed (GObject *object)
{
GstClapperGLContextHandler *self = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (object);
if (! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
_retrieve_gl_context_on_main, self)) {
_retrieve_gst_context (self);
}
GST_CALL_PARENT (G_OBJECT_CLASS, constructed, (object));
}
static void
gst_clapper_gl_context_handler_finalize (GObject *object)
{
GstClapperGLContextHandler *self = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (object);
GST_TRACE ("Finalize");
g_clear_object (&self->gdk_context); g_clear_object (&self->gdk_context);
@@ -564,70 +469,74 @@ gst_clapper_gl_base_importer_finalize (GObject *object)
gst_clear_object (&self->wrapped_context); gst_clear_object (&self->wrapped_context);
gst_clear_object (&self->gst_context); gst_clear_object (&self->gst_context);
g_mutex_clear (&self->lock);
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
} }
static void static void
gst_clapper_gl_base_importer_class_init (GstClapperGLBaseImporterClass *klass) gst_clapper_gl_context_handler_class_init (GstClapperGLContextHandlerClass *klass)
{ {
GObjectClass *gobject_class = (GObjectClass *) klass; GObjectClass *gobject_class = (GObjectClass *) klass;
GstClapperImporterClass *importer_class = (GstClapperImporterClass *) klass; GstClapperContextHandlerClass *handler_class = (GstClapperContextHandlerClass *) klass;
GstClapperGLBaseImporterClass *gl_bi_class = (GstClapperGLBaseImporterClass *) klass;
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperglbaseimporter", 0, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperglcontexthandler", 0,
"Clapper GL Base Importer"); "Clapper GL Context Handler");
gobject_class->finalize = gst_clapper_gl_base_importer_finalize; gobject_class->constructed = gst_clapper_gl_context_handler_constructed;
gobject_class->finalize = gst_clapper_gl_context_handler_finalize;
importer_class->prepare = gst_clapper_gl_base_importer_prepare; handler_class->handle_context_query = gst_clapper_gl_context_handler_handle_context_query;
importer_class->share_data = gst_clapper_gl_base_importer_share_data; }
importer_class->handle_context_query = gst_clapper_gl_base_importer_handle_context_query;
importer_class->create_pool = gst_clapper_gl_base_importer_create_pool;
importer_class->add_allocation_metas = gst_clapper_gl_base_importer_add_allocation_metas;
gl_bi_class->gdk_context_realize = gst_clapper_gl_base_importer_gdk_context_realize; void
gst_clapper_gl_context_handler_add_handler (GPtrArray *context_handlers)
{
guint i;
gboolean found = FALSE;
for (i = 0; i < context_handlers->len; i++) {
GstClapperContextHandler *handler = g_ptr_array_index (context_handlers, i);
if ((found = GST_IS_CLAPPER_GL_CONTEXT_HANDLER (handler)))
break;
}
if (!found) {
GstClapperGLContextHandler *handler = g_object_new (
GST_TYPE_CLAPPER_GL_CONTEXT_HANDLER, NULL);
g_ptr_array_add (context_handlers, handler);
GST_DEBUG ("Added GL context handler to handlers array");
}
} }
GstCaps * GstCaps *
gst_clapper_gl_base_importer_make_supported_gdk_gl_caps (void) gst_clapper_gl_context_handler_make_gdk_gl_caps (const gchar *features, gboolean only_2d)
{ {
GstCaps *caps, *tmp; GstCaps *caps, *tmp;
tmp = gst_caps_from_string ( if (only_2d) {
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, tmp = gst_caps_from_string (GST_VIDEO_CAPS_MAKE (
"{ " GST_GDK_GL_TEXTURE_FORMATS " }") ", " "{ " GST_GDK_GL_TEXTURE_FORMATS " }") ", "
"texture-target = (string) { " GST_GL_TEXTURE_TARGET_2D_STR " }"); "texture-target = (string) { " GST_GL_TEXTURE_TARGET_2D_STR " }");
} else {
tmp = gst_caps_from_string (GST_VIDEO_CAPS_MAKE (
"{ " GST_GDK_GL_TEXTURE_FORMATS " }"));
}
caps = gst_caps_copy (tmp); caps = gst_caps_copy (tmp);
gst_caps_set_features_simple (tmp, gst_caps_features_new (
features, NULL));
gst_caps_set_features_simple (caps, gst_caps_features_new ( gst_caps_set_features_simple (caps, gst_caps_features_new (
GST_CAPS_FEATURE_MEMORY_GL_MEMORY, features, GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL));
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL));
gst_caps_append (caps, tmp); gst_caps_append (caps, tmp);
return caps; return caps;
} }
GStrv
gst_clapper_gl_base_importer_make_gl_context_types (void)
{
GStrv context_types;
GStrvBuilder *builder = g_strv_builder_new ();
g_strv_builder_add (builder, GST_GL_DISPLAY_CONTEXT_TYPE);
g_strv_builder_add (builder, "gst.gl.app_context");
g_strv_builder_add (builder, "gst.gl.local_context");
context_types = g_strv_builder_end (builder);
g_strv_builder_unref (builder);
return context_types;
}
GdkTexture * GdkTexture *
gst_clapper_gl_base_importer_make_gl_texture (GstClapperGLBaseImporter *self, gst_clapper_gl_context_handler_make_gl_texture (GstClapperGLContextHandler *self,
GstBuffer *buffer, GstVideoInfo *v_info) GstBuffer *buffer, GstVideoInfo *v_info)
{ {
GdkTexture *texture; GdkTexture *texture;
@@ -639,7 +548,7 @@ gst_clapper_gl_base_importer_make_gl_texture (GstClapperGLBaseImporter *self,
return NULL; return NULL;
} }
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self); GST_OBJECT_LOCK (self);
/* Must have context active here for both sync meta /* Must have context active here for both sync meta
* and Gdk texture format auto-detection to work */ * and Gdk texture format auto-detection to work */
@@ -666,7 +575,7 @@ gst_clapper_gl_base_importer_make_gl_texture (GstClapperGLBaseImporter *self,
gst_gl_context_activate (self->wrapped_context, FALSE); gst_gl_context_activate (self->wrapped_context, FALSE);
gdk_gl_context_clear_current (); gdk_gl_context_clear_current ();
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self); GST_OBJECT_UNLOCK (self);
gst_video_frame_unmap (&frame); gst_video_frame_unmap (&frame);

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#pragma once
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/gl/gl.h>
#include <gst/gl/gstglfuncs.h>
#include <gtk/gtk.h>
#include "gst/plugin/gstclappercontexthandler.h"
G_BEGIN_DECLS
#define GST_TYPE_CLAPPER_GL_CONTEXT_HANDLER (gst_clapper_gl_context_handler_get_type())
G_DECLARE_FINAL_TYPE (GstClapperGLContextHandler, gst_clapper_gl_context_handler, GST, CLAPPER_GL_CONTEXT_HANDLER, GstClapperContextHandler)
#define GST_CLAPPER_GL_CONTEXT_HANDLER_CAST(obj) ((GstClapperGLContextHandler *)(obj))
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WAYLAND (GST_GL_HAVE_WINDOW_WAYLAND && defined (GDK_WINDOWING_WAYLAND))
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11 (GST_GL_HAVE_WINDOW_X11 && defined (GDK_WINDOWING_X11))
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_GLX (GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11 && GST_GL_HAVE_PLATFORM_GLX)
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL (GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11 && GST_GL_HAVE_PLATFORM_EGL)
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32 (GST_GL_HAVE_WINDOW_WIN32 && defined (GDK_WINDOWING_WIN32))
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_WGL (GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32 && GST_GL_HAVE_PLATFORM_WGL)
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32_EGL (GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_WIN32 && GST_GL_HAVE_PLATFORM_EGL)
#define GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_MACOS (GST_GL_HAVE_WINDOW_COCOA && defined (GDK_WINDOWING_MACOS) && GST_GL_HAVE_PLATFORM_CGL)
struct _GstClapperGLContextHandler
{
GstClapperContextHandler parent;
GdkGLContext *gdk_context;
GstGLDisplay *gst_display;
GstGLContext *wrapped_context;
GstGLContext *gst_context;
};
void gst_clapper_gl_context_handler_add_handler (GPtrArray *context_handlers);
GstCaps * gst_clapper_gl_context_handler_make_gdk_gl_caps (const gchar *features, gboolean only_2d);
GdkTexture * gst_clapper_gl_context_handler_make_gl_texture (GstClapperGLContextHandler *handler, GstBuffer *buffer, GstVideoInfo *v_info);
G_END_DECLS

83
lib/gst/plugin/handlers/gl/meson.build vendored Normal file
View File

@@ -0,0 +1,83 @@
gst_clapper_gl_ch_dep = dependency('', required: false)
build_gl_ch = (
not get_option('glimporter').disabled()
or not get_option('gluploader').disabled()
)
gl_support_required = (
get_option('glimporter').enabled()
or get_option('gluploader').enabled()
)
gst_plugin_gl_ch_deps = [gst_clapper_sink_dep, gstgl_dep, gstglproto_dep]
have_gtk_gl_windowing = false
if gst_gl_have_window_x11 and (gst_gl_have_platform_egl or gst_gl_have_platform_glx)
gtk_x11_dep = dependency('gtk4-x11', required: false)
if gtk_x11_dep.found()
gst_plugin_gl_ch_deps += gtk_x11_dep
if gst_gl_have_platform_glx
gst_plugin_gl_ch_deps += gstglx11_dep
endif
have_gtk_gl_windowing = true
endif
endif
if gst_gl_have_window_wayland and gst_gl_have_platform_egl
gtk_wayland_dep = dependency('gtk4-wayland', required: false)
if gtk_wayland_dep.found()
gst_plugin_gl_ch_deps += [gtk_wayland_dep, gstglwayland_dep]
have_gtk_gl_windowing = true
endif
endif
if gst_gl_have_window_win32 and (gst_gl_have_platform_egl or gst_gl_have_platform_wgl)
gtk_win32_dep = dependency('gtk4-win32', required: false)
if gtk_win32_dep.found()
gst_plugin_gl_ch_deps += gtk_win32_dep
have_gtk_gl_windowing = true
endif
endif
if gst_gl_have_window_cocoa and gst_gl_have_platform_cgl
gtk_macos_dep = dependency('gtk4-macos', required: false)
if gtk_macos_dep.found()
gst_plugin_gl_ch_deps += gtk_macos_dep
have_gtk_gl_windowing = true
endif
endif
if not have_gtk_gl_windowing
if gl_support_required
error('GL-based importer was enabled, but support for current GL windowing is missing')
endif
build_gl_ch = false
endif
if gst_gl_have_platform_egl
gst_plugin_gl_ch_deps += gstglegl_dep
endif
foreach dep : gst_plugin_gl_ch_deps
if not dep.found()
if gl_support_required
error('GL-based importer was enabled, but required dependencies were not found')
endif
build_gl_ch = false
endif
endforeach
if build_gl_ch
gst_clapper_gl_ch_dep = declare_dependency(
link_with: library('gstclapperglcontexthandler',
'gstclapperglcontexthandler.c',
c_args: gst_clapper_plugin_args,
include_directories: configinc,
dependencies: gst_plugin_gl_ch_deps,
version: libversion,
install: true,
),
include_directories: configinc,
dependencies: gst_plugin_gl_ch_deps,
)
endif

1
lib/gst/plugin/handlers/meson.build vendored Normal file
View File

@@ -0,0 +1 @@
subdir('gl')

View File

@@ -1,85 +0,0 @@
/*
* Copyright (C) 2022 Rafał Dzięgiel <rafostar.github@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#pragma once
#include <gst/gl/gl.h>
#include "gst/plugin/gstclapperimporter.h"
G_BEGIN_DECLS
#define GST_TYPE_CLAPPER_GL_BASE_IMPORTER (gst_clapper_gl_base_importer_get_type())
#define GST_IS_CLAPPER_GL_BASE_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_CLAPPER_GL_BASE_IMPORTER))
#define GST_IS_CLAPPER_GL_BASE_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_CLAPPER_GL_BASE_IMPORTER))
#define GST_CLAPPER_GL_BASE_IMPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CLAPPER_GL_BASE_IMPORTER, GstClapperGLBaseImporterClass))
#define GST_CLAPPER_GL_BASE_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_CLAPPER_GL_BASE_IMPORTER, GstClapperGLBaseImporter))
#define GST_CLAPPER_GL_BASE_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_CLAPPER_GL_BASE_IMPORTER, GstClapperGLBaseImporterClass))
#define GST_CLAPPER_GL_BASE_IMPORTER_CAST(obj) ((GstClapperGLBaseImporter *)(obj))
#define GST_CLAPPER_GL_BASE_IMPORTER_GET_LOCK(obj) (&GST_CLAPPER_GL_BASE_IMPORTER_CAST(obj)->lock)
#define GST_CLAPPER_GL_BASE_IMPORTER_LOCK(obj) g_mutex_lock (GST_CLAPPER_GL_BASE_IMPORTER_GET_LOCK(obj))
#define GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK(obj) g_mutex_unlock (GST_CLAPPER_GL_BASE_IMPORTER_GET_LOCK(obj))
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WAYLAND (GST_GL_HAVE_WINDOW_WAYLAND && defined (GDK_WINDOWING_WAYLAND))
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11 (GST_GL_HAVE_WINDOW_X11 && defined (GDK_WINDOWING_X11))
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX (GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11 && GST_GL_HAVE_PLATFORM_GLX)
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL (GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11 && GST_GL_HAVE_PLATFORM_EGL)
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32 (GST_GL_HAVE_WINDOW_WIN32 && defined (GDK_WINDOWING_WIN32))
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_WGL (GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32 && GST_GL_HAVE_PLATFORM_WGL)
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32_EGL (GST_CLAPPER_GL_BASE_IMPORTER_HAVE_WIN32 && GST_GL_HAVE_PLATFORM_EGL)
#define GST_CLAPPER_GL_BASE_IMPORTER_HAVE_MACOS (GST_GL_HAVE_WINDOW_COCOA && defined (GDK_WINDOWING_MACOS) && GST_GL_HAVE_PLATFORM_CGL)
typedef struct _GstClapperGLBaseImporter GstClapperGLBaseImporter;
typedef struct _GstClapperGLBaseImporterClass GstClapperGLBaseImporterClass;
#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GstClapperGLBaseImporter, gst_object_unref)
#endif
struct _GstClapperGLBaseImporter
{
GstClapperImporter parent;
GMutex lock;
GdkGLContext *gdk_context;
GstGLDisplay *gst_display;
GstGLContext *wrapped_context;
GstGLContext *gst_context;
};
struct _GstClapperGLBaseImporterClass
{
GstClapperImporterClass parent_class;
gboolean (* gdk_context_realize) (GstClapperGLBaseImporter *gl_bi,
GdkGLContext *gdk_context);
};
GType gst_clapper_gl_base_importer_get_type (void);
GstCaps * gst_clapper_gl_base_importer_make_supported_gdk_gl_caps (void);
GStrv gst_clapper_gl_base_importer_make_gl_context_types (void);
GdkTexture * gst_clapper_gl_base_importer_make_gl_texture (GstClapperGLBaseImporter *self, GstBuffer *buffer, GstVideoInfo *v_info);
G_END_DECLS

View File

@@ -27,15 +27,45 @@
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define parent_class gst_clapper_gl_importer_parent_class #define parent_class gst_clapper_gl_importer_parent_class
GST_CLAPPER_IMPORTER_DEFINE (GstClapperGLImporter, gst_clapper_gl_importer, GST_TYPE_CLAPPER_GL_BASE_IMPORTER); GST_CLAPPER_IMPORTER_DEFINE (GstClapperGLImporter, gst_clapper_gl_importer, GST_TYPE_CLAPPER_IMPORTER);
static GstBufferPool *
gst_clapper_gl_importer_create_pool (GstClapperImporter *importer, GstStructure **config)
{
GstClapperGLImporter *self = GST_CLAPPER_GL_IMPORTER_CAST (importer);
GstBufferPool *pool;
GST_DEBUG_OBJECT (self, "Creating new GL buffer pool");
pool = gst_gl_buffer_pool_new (self->gl_handler->gst_context);
*config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_add_option (*config, GST_BUFFER_POOL_OPTION_VIDEO_META);
gst_buffer_pool_config_add_option (*config, GST_BUFFER_POOL_OPTION_GL_SYNC_META);
return pool;
}
static void
gst_clapper_gl_importer_add_allocation_metas (GstClapperImporter *importer, GstQuery *query)
{
GstClapperGLImporter *self = GST_CLAPPER_GL_IMPORTER_CAST (importer);
/* We can support GL sync meta */
if (self->gl_handler->gst_context->gl_vtable->FenceSync)
gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, NULL);
/* Also add base importer class supported meta */
GST_CLAPPER_IMPORTER_CLASS (parent_class)->add_allocation_metas (importer, query);
}
static GdkTexture * static GdkTexture *
gst_clapper_gl_importer_generate_texture (GstClapperImporter *importer, gst_clapper_gl_importer_generate_texture (GstClapperImporter *importer,
GstBuffer *buffer, GstVideoInfo *v_info) GstBuffer *buffer, GstVideoInfo *v_info)
{ {
GstClapperGLBaseImporter *gl_bi = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer); GstClapperGLImporter *self = GST_CLAPPER_GL_IMPORTER_CAST (importer);
return gst_clapper_gl_base_importer_make_gl_texture (gl_bi, buffer, v_info); return gst_clapper_gl_context_handler_make_gl_texture (self->gl_handler, buffer, v_info);
} }
static void static void
@@ -43,28 +73,58 @@ gst_clapper_gl_importer_init (GstClapperGLImporter *self)
{ {
} }
static void
gst_clapper_gl_importer_finalize (GObject *object)
{
GstClapperGLImporter *self = GST_CLAPPER_GL_IMPORTER_CAST (object);
gst_clear_object (&self->gl_handler);
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
}
static void static void
gst_clapper_gl_importer_class_init (GstClapperGLImporterClass *klass) gst_clapper_gl_importer_class_init (GstClapperGLImporterClass *klass)
{ {
GObjectClass *gobject_class = (GObjectClass *) klass;
GstClapperImporterClass *importer_class = (GstClapperImporterClass *) klass; GstClapperImporterClass *importer_class = (GstClapperImporterClass *) klass;
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperglimporter", 0, GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperglimporter", 0,
"Clapper GL Importer"); "Clapper GL Importer");
gobject_class->finalize = gst_clapper_gl_importer_finalize;
importer_class->create_pool = gst_clapper_gl_importer_create_pool;
importer_class->add_allocation_metas = gst_clapper_gl_importer_add_allocation_metas;
importer_class->generate_texture = gst_clapper_gl_importer_generate_texture; importer_class->generate_texture = gst_clapper_gl_importer_generate_texture;
} }
GstClapperImporter * GstClapperImporter *
make_importer (void) make_importer (GPtrArray *context_handlers)
{ {
return g_object_new (GST_TYPE_CLAPPER_GL_IMPORTER, NULL); GstClapperGLImporter *self;
GstClapperContextHandler *handler;
handler = gst_clapper_context_handler_obtain_with_type (context_handlers,
GST_TYPE_CLAPPER_GL_CONTEXT_HANDLER);
if (G_UNLIKELY (!handler))
return NULL;
self = g_object_new (GST_TYPE_CLAPPER_GL_IMPORTER, NULL);
self->gl_handler = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (handler);
return GST_CLAPPER_IMPORTER_CAST (self);
} }
GstCaps * GstCaps *
make_caps (gboolean is_template, GstRank *rank, GStrv *context_types) make_caps (gboolean is_template, GstRank *rank, GPtrArray *context_handlers)
{ {
*rank = GST_RANK_SECONDARY; *rank = GST_RANK_SECONDARY;
*context_types = gst_clapper_gl_base_importer_make_gl_context_types ();
return gst_clapper_gl_base_importer_make_supported_gdk_gl_caps (); if (!is_template && context_handlers)
gst_clapper_gl_context_handler_add_handler (context_handlers);
return gst_clapper_gl_context_handler_make_gdk_gl_caps (
GST_CAPS_FEATURE_MEMORY_GL_MEMORY, TRUE);
} }

View File

@@ -19,18 +19,21 @@
#pragma once #pragma once
#include "gstclapperglbaseimporter.h" #include "gst/plugin/gstclapperimporter.h"
#include "gst/plugin/handlers/gl/gstclapperglcontexthandler.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_CLAPPER_GL_IMPORTER (gst_clapper_gl_importer_get_type()) #define GST_TYPE_CLAPPER_GL_IMPORTER (gst_clapper_gl_importer_get_type())
G_DECLARE_FINAL_TYPE (GstClapperGLImporter, gst_clapper_gl_importer, GST, CLAPPER_GL_IMPORTER, GstClapperGLBaseImporter) G_DECLARE_FINAL_TYPE (GstClapperGLImporter, gst_clapper_gl_importer, GST, CLAPPER_GL_IMPORTER, GstClapperImporter)
#define GST_CLAPPER_GL_IMPORTER_CAST(obj) ((GstClapperGLImporter *)(obj)) #define GST_CLAPPER_GL_IMPORTER_CAST(obj) ((GstClapperGLImporter *)(obj))
struct _GstClapperGLImporter struct _GstClapperGLImporter
{ {
GstClapperGLBaseImporter parent; GstClapperImporter parent;
GstClapperGLContextHandler *gl_handler;
}; };
G_END_DECLS G_END_DECLS

View File

@@ -24,7 +24,7 @@
#include "gstclappergluploader.h" #include "gstclappergluploader.h"
#include "gst/plugin/gstgtkutils.h" #include "gst/plugin/gstgtkutils.h"
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11 #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11
#include <gdk/x11/gdkx.h> #include <gdk/x11/gdkx.h>
#endif #endif
@@ -32,30 +32,33 @@
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define parent_class gst_clapper_gl_uploader_parent_class #define parent_class gst_clapper_gl_uploader_parent_class
GST_CLAPPER_IMPORTER_DEFINE (GstClapperGLUploader, gst_clapper_gl_uploader, GST_TYPE_CLAPPER_GL_BASE_IMPORTER); GST_CLAPPER_IMPORTER_DEFINE (GstClapperGLUploader, gst_clapper_gl_uploader, GST_TYPE_CLAPPER_IMPORTER);
static void static void
_update_elements_caps_locked (GstClapperGLUploader *self, GstCaps *upload_sink_caps) _update_elements_caps_locked (GstClapperGLUploader *self, GstCaps *upload_sink_caps)
{ {
GstClapperGLBaseImporter *gl_bi = GST_CLAPPER_GL_BASE_IMPORTER_CAST (self); GstGLContext *gst_context;
GstCaps *upload_src_caps, *color_sink_caps, *color_src_caps, *gdk_sink_caps; GstCaps *upload_src_caps, *color_sink_caps, *color_src_caps, *gdk_sink_caps;
gst_context = self->gl_handler->gst_context;
GST_INFO_OBJECT (self, "Input caps: %" GST_PTR_FORMAT, upload_sink_caps); GST_INFO_OBJECT (self, "Input caps: %" GST_PTR_FORMAT, upload_sink_caps);
upload_src_caps = gst_gl_upload_transform_caps (self->upload, gl_bi->gst_context, upload_src_caps = gst_gl_upload_transform_caps (self->upload, gst_context,
GST_PAD_SINK, upload_sink_caps, NULL); GST_PAD_SINK, upload_sink_caps, NULL);
upload_src_caps = gst_caps_fixate (upload_src_caps); upload_src_caps = gst_caps_fixate (upload_src_caps);
GST_INFO_OBJECT (self, "GLUpload caps: %" GST_PTR_FORMAT, upload_src_caps); GST_INFO_OBJECT (self, "GLUpload caps: %" GST_PTR_FORMAT, upload_src_caps);
gst_gl_upload_set_caps (self->upload, upload_sink_caps, upload_src_caps); gst_gl_upload_set_caps (self->upload, upload_sink_caps, upload_src_caps);
gdk_sink_caps = gst_clapper_gl_base_importer_make_supported_gdk_gl_caps (); gdk_sink_caps = gst_clapper_gl_context_handler_make_gdk_gl_caps (
color_sink_caps = gst_gl_color_convert_transform_caps (gl_bi->gst_context, GST_CAPS_FEATURE_MEMORY_GL_MEMORY, TRUE);
color_sink_caps = gst_gl_color_convert_transform_caps (gst_context,
GST_PAD_SRC, upload_src_caps, gdk_sink_caps); GST_PAD_SRC, upload_src_caps, gdk_sink_caps);
gst_caps_unref (gdk_sink_caps); gst_caps_unref (gdk_sink_caps);
/* Second caps arg is transfer-full */ /* Second caps arg is transfer-full */
color_src_caps = gst_gl_color_convert_fixate_caps (gl_bi->gst_context, color_src_caps = gst_gl_color_convert_fixate_caps (gst_context,
GST_PAD_SINK, upload_src_caps, color_sink_caps); GST_PAD_SINK, upload_src_caps, color_sink_caps);
GST_INFO_OBJECT (self, "GLColorConvert caps: %" GST_PTR_FORMAT, color_src_caps); GST_INFO_OBJECT (self, "GLColorConvert caps: %" GST_PTR_FORMAT, color_src_caps);
@@ -72,9 +75,9 @@ gst_clapper_gl_uploader_set_caps (GstClapperImporter *importer, GstCaps *caps)
{ {
GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer); GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer);
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self); GST_CLAPPER_GL_UPLOADER_LOCK (self);
_update_elements_caps_locked (self, caps); _update_elements_caps_locked (self, caps);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self); GST_CLAPPER_GL_UPLOADER_UNLOCK (self);
} }
static void static void
@@ -92,28 +95,6 @@ _uploader_reconfigure_locked (GstClapperGLUploader *self)
} }
} }
static gboolean
gst_clapper_gl_uploader_prepare (GstClapperImporter *importer)
{
gboolean res = GST_CLAPPER_IMPORTER_CLASS (parent_class)->prepare (importer);
if (res) {
GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer);
GstClapperGLBaseImporter *gl_bi = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self);
if (!self->upload)
self->upload = gst_gl_upload_new (gl_bi->gst_context);
if (!self->color_convert)
self->color_convert = gst_gl_color_convert_new (gl_bi->gst_context);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self);
}
return res;
}
static GstBuffer * static GstBuffer *
_upload_perform_locked (GstClapperGLUploader *self, GstBuffer *buffer) _upload_perform_locked (GstClapperGLUploader *self, GstBuffer *buffer)
{ {
@@ -152,13 +133,19 @@ gst_clapper_gl_uploader_add_allocation_metas (GstClapperImporter *importer, GstQ
GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer); GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer);
GstGLUpload *upload; GstGLUpload *upload;
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self); GST_CLAPPER_GL_UPLOADER_LOCK (self);
upload = gst_object_ref (self->upload); upload = gst_object_ref (self->upload);
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self); GST_CLAPPER_GL_UPLOADER_UNLOCK (self);
/* Add glupload supported meta */
gst_gl_upload_propose_allocation (upload, NULL, query); gst_gl_upload_propose_allocation (upload, NULL, query);
gst_object_unref (upload); gst_object_unref (upload);
/* We can support GL sync meta */
if (self->gl_handler->gst_context->gl_vtable->FenceSync)
gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, NULL);
/* Also add base importer class supported meta */
GST_CLAPPER_IMPORTER_CLASS (parent_class)->add_allocation_metas (importer, query); GST_CLAPPER_IMPORTER_CLASS (parent_class)->add_allocation_metas (importer, query);
} }
@@ -167,7 +154,6 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
GstBuffer *buffer, GstVideoInfo *v_info) GstBuffer *buffer, GstVideoInfo *v_info)
{ {
GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer); GstClapperGLUploader *self = GST_CLAPPER_GL_UPLOADER_CAST (importer);
GstClapperGLBaseImporter *gl_bi = GST_CLAPPER_GL_BASE_IMPORTER_CAST (importer);
GstBuffer *upload_buf, *color_buf; GstBuffer *upload_buf, *color_buf;
GdkTexture *texture; GdkTexture *texture;
@@ -177,13 +163,13 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
GST_LOG_OBJECT (self, "Uploading %" GST_PTR_FORMAT, buffer); GST_LOG_OBJECT (self, "Uploading %" GST_PTR_FORMAT, buffer);
GST_CLAPPER_GL_BASE_IMPORTER_LOCK (self); GST_CLAPPER_GL_UPLOADER_LOCK (self);
upload_buf = _upload_perform_locked (self, buffer); upload_buf = _upload_perform_locked (self, buffer);
if (G_UNLIKELY (!upload_buf)) { if (G_UNLIKELY (!upload_buf)) {
GST_ERROR_OBJECT (self, "Could not perform upload on input buffer"); GST_ERROR_OBJECT (self, "Could not perform upload on input buffer");
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self); GST_CLAPPER_GL_UPLOADER_UNLOCK (self);
return NULL; return NULL;
} }
@@ -198,7 +184,7 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
self->has_pending_v_info = FALSE; self->has_pending_v_info = FALSE;
} }
GST_CLAPPER_GL_BASE_IMPORTER_UNLOCK (self); GST_CLAPPER_GL_UPLOADER_UNLOCK (self);
if (G_UNLIKELY (!color_buf)) { if (G_UNLIKELY (!color_buf)) {
GST_ERROR_OBJECT (self, "Could not perform color conversion on input buffer"); GST_ERROR_OBJECT (self, "Could not perform color conversion on input buffer");
@@ -206,7 +192,7 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
} }
GST_LOG_OBJECT (self, "Color converted into %" GST_PTR_FORMAT, color_buf); GST_LOG_OBJECT (self, "Color converted into %" GST_PTR_FORMAT, color_buf);
texture = gst_clapper_gl_base_importer_make_gl_texture (gl_bi, color_buf, &self->v_info); texture = gst_clapper_gl_context_handler_make_gl_texture (self->gl_handler, color_buf, &self->v_info);
gst_buffer_unref (color_buf); gst_buffer_unref (color_buf);
return texture; return texture;
@@ -215,6 +201,8 @@ gst_clapper_gl_uploader_generate_texture (GstClapperImporter *importer,
static void static void
gst_clapper_gl_uploader_init (GstClapperGLUploader *self) gst_clapper_gl_uploader_init (GstClapperGLUploader *self)
{ {
g_mutex_init (&self->lock);
gst_video_info_init (&self->pending_v_info); gst_video_info_init (&self->pending_v_info);
gst_video_info_init (&self->v_info); gst_video_info_init (&self->v_info);
} }
@@ -227,6 +215,10 @@ gst_clapper_gl_uploader_finalize (GObject *object)
gst_clear_object (&self->upload); gst_clear_object (&self->upload);
gst_clear_object (&self->color_convert); gst_clear_object (&self->color_convert);
gst_clear_object (&self->gl_handler);
g_mutex_clear (&self->lock);
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
} }
@@ -241,7 +233,6 @@ gst_clapper_gl_uploader_class_init (GstClapperGLUploaderClass *klass)
gobject_class->finalize = gst_clapper_gl_uploader_finalize; gobject_class->finalize = gst_clapper_gl_uploader_finalize;
importer_class->prepare = gst_clapper_gl_uploader_prepare;
importer_class->set_caps = gst_clapper_gl_uploader_set_caps; importer_class->set_caps = gst_clapper_gl_uploader_set_caps;
importer_class->create_pool = gst_clapper_gl_uploader_create_pool; importer_class->create_pool = gst_clapper_gl_uploader_create_pool;
importer_class->add_allocation_metas = gst_clapper_gl_uploader_add_allocation_metas; importer_class->add_allocation_metas = gst_clapper_gl_uploader_add_allocation_metas;
@@ -249,12 +240,26 @@ gst_clapper_gl_uploader_class_init (GstClapperGLUploaderClass *klass)
} }
GstClapperImporter * GstClapperImporter *
make_importer (void) make_importer (GPtrArray *context_handlers)
{ {
return g_object_new (GST_TYPE_CLAPPER_GL_UPLOADER, NULL); GstClapperGLUploader *self;
GstClapperContextHandler *handler;
handler = gst_clapper_context_handler_obtain_with_type (context_handlers,
GST_TYPE_CLAPPER_GL_CONTEXT_HANDLER);
if (G_UNLIKELY (!handler))
return NULL;
self = g_object_new (GST_TYPE_CLAPPER_GL_UPLOADER, NULL);
self->gl_handler = GST_CLAPPER_GL_CONTEXT_HANDLER_CAST (handler);
self->upload = gst_gl_upload_new (self->gl_handler->gst_context);
self->color_convert = gst_gl_color_convert_new (self->gl_handler->gst_context);
return GST_CLAPPER_IMPORTER_CAST (self);
} }
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11
static gboolean static gboolean
_filter_glx_caps_cb (GstCapsFeatures *features, _filter_glx_caps_cb (GstCapsFeatures *features,
GstStructure *structure, gpointer user_data) GstStructure *structure, gpointer user_data)
@@ -277,7 +282,7 @@ _update_glx_caps_on_main (GstCaps *caps)
if (GDK_IS_X11_DISPLAY (gdk_display)) { if (GDK_IS_X11_DISPLAY (gdk_display)) {
gboolean using_glx = TRUE; gboolean using_glx = TRUE;
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_EGL #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_EGL
using_glx = (gdk_x11_display_get_egl_display (gdk_display) == NULL); using_glx = (gdk_x11_display_get_egl_display (gdk_display) == NULL);
#endif #endif
@@ -292,11 +297,11 @@ _update_glx_caps_on_main (GstCaps *caps)
#endif #endif
GstCaps * GstCaps *
make_caps (gboolean is_template, GstRank *rank, GStrv *context_types) make_caps (gboolean is_template, GstRank *rank, GPtrArray *context_handlers)
{ {
GstCaps *caps = gst_gl_upload_get_input_template_caps (); GstCaps *caps = gst_gl_upload_get_input_template_caps ();
#if GST_CLAPPER_GL_BASE_IMPORTER_HAVE_X11_GLX #if GST_CLAPPER_GL_CONTEXT_HANDLER_HAVE_X11_GLX
if (!is_template && !(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback) if (!is_template && !(! !gst_gtk_invoke_on_main ((GThreadFunc) (GCallback)
_update_glx_caps_on_main, caps))) _update_glx_caps_on_main, caps)))
gst_clear_caps (&caps); gst_clear_caps (&caps);
@@ -306,7 +311,9 @@ make_caps (gboolean is_template, GstRank *rank, GStrv *context_types)
return NULL; return NULL;
*rank = GST_RANK_MARGINAL + 1; *rank = GST_RANK_MARGINAL + 1;
*context_types = gst_clapper_gl_base_importer_make_gl_context_types ();
if (!is_template && context_handlers)
gst_clapper_gl_context_handler_add_handler (context_handlers);
return caps; return caps;
} }

View File

@@ -19,18 +19,27 @@
#pragma once #pragma once
#include "gstclapperglbaseimporter.h" #include "gst/plugin/gstclapperimporter.h"
#include "gst/plugin/handlers/gl/gstclapperglcontexthandler.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#define GST_TYPE_CLAPPER_GL_UPLOADER (gst_clapper_gl_uploader_get_type()) #define GST_TYPE_CLAPPER_GL_UPLOADER (gst_clapper_gl_uploader_get_type())
G_DECLARE_FINAL_TYPE (GstClapperGLUploader, gst_clapper_gl_uploader, GST, CLAPPER_GL_UPLOADER, GstClapperGLBaseImporter) G_DECLARE_FINAL_TYPE (GstClapperGLUploader, gst_clapper_gl_uploader, GST, CLAPPER_GL_UPLOADER, GstClapperImporter)
#define GST_CLAPPER_GL_UPLOADER_CAST(obj) ((GstClapperGLUploader *)(obj)) #define GST_CLAPPER_GL_UPLOADER_CAST(obj) ((GstClapperGLUploader *)(obj))
#define GST_CLAPPER_GL_UPLOADER_GET_LOCK(obj) (&GST_CLAPPER_GL_UPLOADER_CAST(obj)->lock)
#define GST_CLAPPER_GL_UPLOADER_LOCK(obj) g_mutex_lock (GST_CLAPPER_GL_UPLOADER_GET_LOCK(obj))
#define GST_CLAPPER_GL_UPLOADER_UNLOCK(obj) g_mutex_unlock (GST_CLAPPER_GL_UPLOADER_GET_LOCK(obj))
struct _GstClapperGLUploader struct _GstClapperGLUploader
{ {
GstClapperGLBaseImporter parent; GstClapperImporter parent;
GMutex lock;
GstClapperGLContextHandler *gl_handler;
GstGLUpload *upload; GstGLUpload *upload;
GstGLColorConvert *color_convert; GstGLColorConvert *color_convert;

View File

@@ -47,13 +47,6 @@ gst_clapper_raw_importer_create_pool (GstClapperImporter *importer, GstStructure
return pool; return pool;
} }
static void
gst_clapper_raw_importer_add_allocation_metas (GstClapperImporter *importer, GstQuery *query)
{
gst_query_add_allocation_meta (query, GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
}
static GdkTexture * static GdkTexture *
gst_clapper_raw_importer_generate_texture (GstClapperImporter *importer, gst_clapper_raw_importer_generate_texture (GstClapperImporter *importer,
GstBuffer *buffer, GstVideoInfo *v_info) GstBuffer *buffer, GstVideoInfo *v_info)
@@ -86,18 +79,17 @@ gst_clapper_raw_importer_class_init (GstClapperRawImporterClass *klass)
"Clapper RAW Importer"); "Clapper RAW Importer");
importer_class->create_pool = gst_clapper_raw_importer_create_pool; importer_class->create_pool = gst_clapper_raw_importer_create_pool;
importer_class->add_allocation_metas = gst_clapper_raw_importer_add_allocation_metas;
importer_class->generate_texture = gst_clapper_raw_importer_generate_texture; importer_class->generate_texture = gst_clapper_raw_importer_generate_texture;
} }
GstClapperImporter * GstClapperImporter *
make_importer (void) make_importer (GPtrArray *context_handlers)
{ {
return g_object_new (GST_TYPE_CLAPPER_RAW_IMPORTER, NULL); return g_object_new (GST_TYPE_CLAPPER_RAW_IMPORTER, NULL);
} }
GstCaps * GstCaps *
make_caps (gboolean is_template, GstRank *rank, GStrv *context_types) make_caps (gboolean is_template, GstRank *rank, GPtrArray *context_handlers)
{ {
*rank = GST_RANK_MARGINAL; *rank = GST_RANK_MARGINAL;

View File

@@ -1,20 +1,9 @@
gst_clapper_gl_base_importer_dep = dependency('', required: false)
all_importers = [ all_importers = [
'glimporter', 'glimporter',
'gluploader', 'gluploader',
'rawimporter', 'rawimporter',
] ]
build_glbase = (
not get_option('glimporter').disabled()
or not get_option('gluploader').disabled()
)
gl_support_required = (
get_option('glimporter').enabled()
or get_option('gluploader').enabled()
)
# We cannot build any importers without sink that they depend on # We cannot build any importers without sink that they depend on
if not gst_clapper_sink_dep.found() if not gst_clapper_sink_dep.found()
foreach imp : all_importers foreach imp : all_importers
@@ -24,89 +13,16 @@ if not gst_clapper_sink_dep.found()
endforeach endforeach
endif endif
gst_plugin_gl_base_deps = [gst_clapper_sink_dep, gstgl_dep, gstglproto_dep]
have_gtk_gl_windowing = false
if gst_gl_have_window_x11 and (gst_gl_have_platform_egl or gst_gl_have_platform_glx)
gtk_x11_dep = dependency('gtk4-x11', required: false)
if gtk_x11_dep.found()
gst_plugin_gl_base_deps += gtk_x11_dep
if gst_gl_have_platform_glx
gst_plugin_gl_base_deps += gstglx11_dep
endif
have_gtk_gl_windowing = true
endif
endif
if gst_gl_have_window_wayland and gst_gl_have_platform_egl
gtk_wayland_dep = dependency('gtk4-wayland', required: false)
if gtk_wayland_dep.found()
gst_plugin_gl_base_deps += [gtk_wayland_dep, gstglwayland_dep]
have_gtk_gl_windowing = true
endif
endif
if gst_gl_have_window_win32 and (gst_gl_have_platform_egl or gst_gl_have_platform_wgl)
gtk_win32_dep = dependency('gtk4-win32', required: false)
if gtk_win32_dep.found()
gst_plugin_gl_base_deps += gtk_win32_dep
have_gtk_gl_windowing = true
endif
endif
if gst_gl_have_window_cocoa and gst_gl_have_platform_cgl
gtk_macos_dep = dependency('gtk4-macos', required: false)
if gtk_macos_dep.found()
gst_plugin_gl_base_deps += gtk_macos_dep
have_gtk_gl_windowing = true
endif
endif
if not have_gtk_gl_windowing
if gl_support_required
error('GL-based importer was enabled, but support for current GL windowing is missing')
endif
build_glbase = false
endif
if gst_gl_have_platform_egl
gst_plugin_gl_base_deps += gstglegl_dep
endif
foreach dep : gst_plugin_gl_base_deps
if not dep.found()
if gl_support_required
error('GL-based importer was enabled, but required dependencies were not found')
endif
build_glbase = false
endif
endforeach
if build_glbase
gst_clapper_gl_base_importer_dep = declare_dependency(
link_with: library('gstclapperglbaseimporter',
'gstclapperglbaseimporter.c',
c_args: gst_clapper_plugin_args,
include_directories: configinc,
dependencies: gst_plugin_gl_base_deps,
version: libversion,
install: true,
),
include_directories: configinc,
dependencies: gst_plugin_gl_base_deps,
)
endif
build_glimporter = ( build_glimporter = (
not get_option('glimporter').disabled() not get_option('glimporter').disabled()
and gst_clapper_gl_base_importer_dep.found() and gst_clapper_gl_ch_dep.found()
) )
if build_glimporter if build_glimporter
library( library(
'gstclapperglimporter', 'gstclapperglimporter',
'gstclapperglimporter.c', 'gstclapperglimporter.c',
dependencies: gst_clapper_gl_base_importer_dep, dependencies: gst_clapper_gl_ch_dep,
include_directories: configinc, include_directories: configinc,
c_args: gst_clapper_plugin_args, c_args: gst_clapper_plugin_args,
install: true, install: true,
@@ -116,14 +32,14 @@ endif
build_gluploader = ( build_gluploader = (
not get_option('gluploader').disabled() not get_option('gluploader').disabled()
and gst_clapper_gl_base_importer_dep.found() and gst_clapper_gl_ch_dep.found()
) )
if build_gluploader if build_gluploader
library( library(
'gstclappergluploader', 'gstclappergluploader',
'gstclappergluploader.c', 'gstclappergluploader.c',
dependencies: gst_clapper_gl_base_importer_dep, dependencies: gst_clapper_gl_ch_dep,
include_directories: configinc, include_directories: configinc,
c_args: gst_clapper_plugin_args, c_args: gst_clapper_plugin_args,
install: true, install: true,

View File

@@ -61,4 +61,5 @@ if build_gst_plugin
) )
endif endif
subdir('handlers')
subdir('importers') subdir('importers')