*
*/
-#include <tensor_typedef.h>
+#include <nnstreamer_plugin_api.h>
#include "tensor_filter_tensorflow_core.h"
#include <glib.h>
#include <string.h>
*
*/
-#include <tensor_typedef.h>
+#include <nnstreamer_plugin_api.h>
#include "tensor_filter_tensorflow_lite_core.h"
#include <glib.h>
#include <string.h>
*/
extern tensor_type get_tensor_type (const gchar * typestr);
+
+
+/* extern functions for subplugin management, exist in tensor_filter.c */
+/**
+ * @brief Filter subplugin should call this to register itself
+ * @param[in] tfsp Tensor-Filter Sub-Plugin to be registered
+ * @return TRUE if registered. FALSE is failed or duplicated.
+ */
+extern int tensor_filter_probe (GstTensorFilterFramework *tfsp);
+/**
+ * @brief filter sub-plugin may call this to unregister itself
+ * @param[in] name the name of filter sub-plugin
+ */
+extern void tensor_filter_exit (const char *name);
+
G_END_DECLS
#endif /* __NNS_PLUGIN_API_H__ */
G_LOCK_DEFINE_STATIC (splock);
-
-typedef struct
-{
- char *name;
- const void *data;
-} holdplugins;
-static GHashTable *held_subplugins[NNS_SUBPLUGIN_END] = { 0 };
-
-/**
- * @brief Private function for g_hash_table data destructor, GDestroyNotify
- */
-static void
-_heldsp_destroy (gpointer _data)
-{
- holdplugins *data = _data;
- g_free (data->name);
- /* do not free data here */
- g_free (data);
-}
-
-/**
- * @brief API to notify subplugin-manager that this subplugin is handled already.
- */
-void
-hold_register_subplugin (subpluginType type, const char *name, const void *data)
-{
- holdplugins *ptr;
-
- if (held_subplugins[type] == NULL)
- held_subplugins[type] =
- g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
- _heldsp_destroy);
-
- ptr = g_new (holdplugins, 1);
- ptr->name = g_strdup (name);
- ptr->data = data;
- g_hash_table_insert (held_subplugins[type], g_strdup (name), ptr);
-}
-
-/**
- * @brief Check if this subplugin is held by hold_register_subplugin()
- */
-static const void *
-check_held_subplugin (subpluginType type, const char *name)
-{
- holdplugins *ptr;
-
- if (held_subplugins[type] == NULL)
- return NULL;
- ptr = g_hash_table_lookup (held_subplugins[type], name);
-
- if (ptr)
- return ptr->data;
- return NULL;
-}
-
/** @brief Private function for g_hash_table data destructor, GDestroyNotify */
static void
_spdata_destroy (gpointer _data)
/* Search and register if found with the conf */
const gchar *fullpath = nnsconf_get_fullpath (name, type);
char *dlsym_error;
- const void *held;
nnstreamer_subplugin_data *nsdata;
if (fullpath == NULL)
goto error; /* No Such Thing !!! */
+ G_UNLOCK (splock);
+
handle = dlopen (fullpath, RTLD_NOW);
if (NULL == handle) {
GST_ERROR ("Cannot dlopen %s (%s).", name, fullpath);
- goto error;
+ return NULL;
}
- /* If a plugin calls "probe()" at this step, stop here and return "OK" */
- held = check_held_subplugin (type, name);
- if (held) {
- G_UNLOCK (splock);
- return held;
- }
+ G_LOCK (splock);
+
+ /* If a subplugin's constructor has called register_subplugin, skip the rest */
+ data = g_hash_table_lookup (table, name);
+ if (data != NULL)
+ goto registered;
nsdata = (nnstreamer_subplugin_data *)
dlsym (handle, "nnstreamer_subplugin");
g_assert ((data = g_hash_table_lookup (table, name)) != NULL);
data->handle = handle;
}
+
+registered:
G_UNLOCK (splock);
return data->data;
extern gboolean
unregister_subplugin (subpluginType type, const char *name);
-/**
- * @brief Call this at subplugin probe to avoid duplicated registration
- */
-extern void
-hold_register_subplugin (subpluginType type, const char *name, const void *data);
-
#endif /* __GST_NNSTREAMER_SUBPLUGIN_H__ */
tensor_decoder_sources = [
'tensordec.c',
- 'tensordec-plugins.c',
'tensordec-directvideo.c',
'tensordec-imagelabel.c',
'tensordec-boundingbox.c'
+++ /dev/null
-/**
- * GStreamer / NNStreamer tensor_decoder plugin support
- * Copyright (C) 2018 MyungJoo Ham <myungjoo.ham@samsung.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.
- *
- */
-/**
- * @file tensordec-plugins.c
- * @date 05 Nov 2018
- * @brief Tensor-decoder plugin support logic
- * @see https://github.com/nnsuite/nnstreamer
- * @author MyungJoo Ham <myungjoo.ham@samsung.com>
- * @bug No known bugs except for NYI items
- *
- */
-
-#include "tensordec.h"
-#include <nnstreamer_subplugin.h>
-#include <gst/gstinfo.h>
-
-typedef struct _TensorDecDefList TensorDecDefList;
-
-/**
- * @brief Linked list having all registered decoder subplugins
- */
-struct _TensorDecDefList
-{
- TensorDecDefList *next; /**< "Next" in the list */
- TensorDecDef *body; /**< "Data" in this list element */
-};
-static TensorDecDef unknown = {
- .modename = "unknown",
- .type = OUTPUT_UNKNOWN,
-};
-static TensorDecDefList listhead = {.next = NULL,.body = &unknown };
-
-/**
- * @brief decoder's subplugins should call this function to register
- * @param[in] decoder The decoder subplugin instance
- */
-gboolean
-tensordec_probe (TensorDecDef * decoder)
-{
- TensorDecDefList *list;
-
- if (!decoder || !decoder->modename || !decoder->modename[0]) {
- GST_ERROR ("Cannot register invalid decoder.\n");
- return FALSE;
- }
-
- /**
- * Check if there is no duplicated entry (modename).
- * This is Linked List Traversal.
- * If we hit the "tail", add decoder
- */
- list = &listhead;
- do {
- if (0 == g_strcmp0 (list->body->modename, decoder->modename)) {
- /* Duplicated! */
- GST_ERROR ("Duplicated decoder name found: %s\n", decoder->modename);
- return FALSE;
- }
- if (list->next == NULL) {
- TensorDecDefList *next = g_malloc (sizeof (TensorDecDefList));
- next->next = NULL;
- next->body = decoder;
- list->next = next;
- break;
- }
- list = list->next;
- } while (list != NULL);
-
- GST_INFO ("A new subplugin, \"%s\" is registered for tensor_decoder.\n",
- decoder->modename);
-
- /** @todo @buf unregister at exit */
- hold_register_subplugin (NNS_SUBPLUGIN_DECODER, decoder->modename, decoder);
- return TRUE;
-}
-
-/**
- * @brief decoder's subplugin may call this to unregister
- * @param[in] name the name of decoder (modename)
- */
-void
-tensordec_exit (const gchar * name)
-{
- TensorDecDefList *list = &listhead;
-
- if (!name || !name[0]) {
- GST_ERROR ("Cannot unregister without proper name.\n");
- return;
- }
-
- /**
- * Check if there is no duplicated entry (modename).
- * This is Linked List Traversal.
- * If we hit the "tail", add decoder
- */
- list = &listhead;
- do {
- if (list->next != NULL && 0 == g_strcmp0 (list->next->body->modename, name)) {
- TensorDecDefList *found = list->next;
- list->next = found->next;
- g_free (found);
- GST_INFO ("A subplugin, \"%s\" is removed from tensor_decoder.\n", name);
- return;
- }
- list = list->next;
- } while (list != NULL);
-
- GST_ERROR ("A subplugin, \"%s\" was not found.\n", name);
- return;
-}
-
-/**
- * @brief Find decoders subplugin with the name
- * @param[in] name the name of decoder (modename)
- */
-const TensorDecDef *
-tensordec_find (const gchar * name)
-{
- TensorDecDefList *list = &listhead;
-
- if (!name || !name[0]) {
- GST_ERROR ("Cannot find without proper name.\n");
- return NULL;
- }
-
- do {
- g_assert (list->body);
-
- if (0 == g_strcmp0 (list->body->modename, name)) {
- return list->body;
- }
- list = list->next;
- } while (list != NULL);
-
- /* If not found, try to search with nnstreamer_subplugin APIs */
- return get_subplugin (NNS_SUBPLUGIN_DECODER, name);
-}
GstPadDirection direction, GstCaps * caps, gsize size,
GstCaps * othercaps, gsize * othersize);
+
+/**
+ * @brief decoder's subplugins should call this function to register
+ * @param[in] decoder The decoder subplugin instance
+ */
+gboolean
+tensordec_probe (TensorDecDef * decoder)
+{
+ register_subplugin (NNS_SUBPLUGIN_DECODER, decoder->modename, decoder);
+ return TRUE;
+}
+
+/**
+ * @brief decoder's subplugin may call this to unregister
+ * @param[in] name the name of decoder (modename)
+ */
+void
+tensordec_exit (const gchar * name)
+{
+ unregister_subplugin (NNS_SUBPLUGIN_DECODER, name);
+}
+
+/**
+ * @brief Find decoders subplugin with the name
+ * @param[in] name the name of decoder (modename)
+ */
+static const TensorDecDef *
+tensordec_find (const gchar * name)
+{
+ return get_subplugin (NNS_SUBPLUGIN_DECODER, name);
+}
+
+
+
/**
* @brief Get media caps from tensor config
* @param self "this" pointer
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <tensor_common.h>
+#include <nnstreamer_subplugin.h>
G_BEGIN_DECLS
#define GST_TYPE_TENSORDEC \
/**< EXPERIMENTAL! @todo We are not ready to use this. This should be NULL or return 0 */
};
-extern gboolean tensordec_probe (TensorDecDef *decoder);
-extern void tensordec_exit (const gchar *name);
-extern const TensorDecDef *tensordec_find (const gchar *name);
-
-
+/* extern functions for subplugin management, exist in tensor_decoder.c */
+/**
+ * @brief decoder's subplugins should call this function to register
+ * @param[in] decoder The decoder subplugin instance
+ */
+extern gboolean tensordec_probe (TensorDecDef * decoder);
+/**
+ * @brief decoder's subplugin may call this to unregister
+ * @param[in] name the name of decoder (modename)
+ */
+extern void tensordec_exit (const gchar * name);
G_END_DECLS
#endif /* __GST_TENSORDEC_H__ */
#define g_free_const(x) g_free((void*)(long)(x))
-typedef struct _TensorFilterSPList TensorFilterSPList;
-/**
- * @brief Linked list having all registered filter subplugins
- */
-struct _TensorFilterSPList
-{
- TensorFilterSPList *next; /**< "Next" in the list */
- GstTensorFilterFramework *body; /**< "Data" in the list element */
-};
-static GstTensorFilterFramework unknown = {
- .name = "unknown",
-};
-static TensorFilterSPList listhead = {.next = NULL,.body = &unknown };
-
/**
* @brief Filter subplugin should call this to register itself
* @param[in] tfsp Tensor-Filter Sub-Plugin to be registered
* @return TRUE if registered. FALSE is failed or duplicated.
*/
-gboolean
+int
tensor_filter_probe (GstTensorFilterFramework * tfsp)
{
- TensorFilterSPList *list;
-
- if (!tfsp || !tfsp->name || !tfsp->name[0]) {
- GST_ERROR ("Cannot register invalid filter subplugin.\n");
- return FALSE;
- }
-
- list = &listhead;
- do {
- if (0 == g_strcmp0 (list->body->name, tfsp->name)) {
- /* Duplicated! */
- GST_ERROR ("DUplicated filter sub-plugin name found: %s\n", tfsp->name);
- return FALSE;
- }
- if (list->next == NULL) {
- TensorFilterSPList *next = g_malloc (sizeof (TensorFilterSPList));
- next->next = NULL;
- next->body = tfsp;
- list->next = next;
- break;
- }
- list = list->next;
- } while (list != NULL);
-
- GST_INFO ("A new sub-plugin, \"%s\" is registered for tensor_filter.\n",
- tfsp->name);
-
- /** @todo @bug unregister at exit */
- hold_register_subplugin (NNS_SUBPLUGIN_FILTER, tfsp->name, tfsp);
-
- return TRUE;
+ return register_subplugin (NNS_SUBPLUGIN_FILTER, tfsp->name, tfsp);
}
/**
* @param[in] name the name of filter sub-plugin
*/
void
-tensor_filter_exit (const gchar * name)
+tensor_filter_exit (const char *name)
{
- TensorFilterSPList *list = &listhead;
-
- if (!name || !name[0]) {
- GST_ERROR ("Cannot unregister without a proper name.");
- return;
- }
-
- list = &listhead;
- do {
- if (list->next != NULL && 0 == g_strcmp0 (list->next->body->name, name)) {
- TensorFilterSPList *found = list->next;
- list->next = found->next;
- g_free (found);
- GST_INFO ("A tensor_filter sub-plugin \"%s\" is removed.", name);
- return;
- }
- list = list->next;
- } while (list != NULL);
-
- GST_ERROR ("Cannot find a tensor_filter sub-plugin \"%s\".", name);
- return;
+ unregister_subplugin (NNS_SUBPLUGIN_FILTER, name);
}
/**
static const GstTensorFilterFramework *
tensor_filter_find (const gchar * name)
{
- TensorFilterSPList *list = &listhead;
-
- if (!name || !name[0]) {
- GST_ERROR ("The name of tensor_filter sub-plugin is not given.");
- return NULL;
- }
-
- do {
- g_assert (list->body);
-
- if (0 == g_strcmp0 (list->body->name, name)) {
- return list->body;
- }
- list = list->next;
- } while (list != NULL);
-
- /* If not found, try to search with nnstremer_subplugin APIs */
return get_subplugin (NNS_SUBPLUGIN_FILTER, name);
}
#include <gst/gstinfo.h>
#include <gst/base/gstbasetransform.h>
#include <tensor_common.h>
+#include <nnstreamer_subplugin.h>
G_BEGIN_DECLS
*/
} GstTensorFilterFramework;
-/* extern functions for subplugin management, exist in tensor_filter.c */
-extern int tensor_filter_probe (GstTensorFilterFramework *tfsp);
-extern void tensor_filter_exit (const char *name);
-
#endif /*__GST_TENSOR_TYPEDEF_H__*/