Subplugin register/unregister refactored.
authorMyungJoo Ham <myungjoo.ham@samsung.com>
Wed, 30 Jan 2019 07:27:44 +0000 (16:27 +0900)
committerwooksong <wook16.song@samsung.com>
Sun, 10 Feb 2019 06:07:12 +0000 (15:07 +0900)
A plugin, "filter" and "decoder" no more have their own
internal data structure to store subplugins.

Both filter and decoder subplugins now use APIs of
nnstreamer_subplugin via
nnstreamer_plugin_api.h (filters)
tensordec.h (decoder)

Decoders are to be refactored further to use
nnstreamer_plugin_api.h after moving decoder subplugins
to ext/

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
12 files changed:
ext/nnstreamer/tensor_filter/tensor_filter_tensorflow.c
ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.c
gst/nnstreamer/nnstreamer_plugin_api.h
gst/nnstreamer/nnstreamer_subplugin.c
gst/nnstreamer/nnstreamer_subplugin.h
gst/nnstreamer/tensor_decoder/meson.build
gst/nnstreamer/tensor_decoder/tensordec-plugins.c [deleted file]
gst/nnstreamer/tensor_decoder/tensordec.c
gst/nnstreamer/tensor_decoder/tensordec.h
gst/nnstreamer/tensor_filter/tensor_filter.c
gst/nnstreamer/tensor_filter/tensor_filter.h
gst/nnstreamer/tensor_typedef.h

index 640f124..aa7ad85 100644 (file)
@@ -26,7 +26,7 @@
  *
  */
 
-#include <tensor_typedef.h>
+#include <nnstreamer_plugin_api.h>
 #include "tensor_filter_tensorflow_core.h"
 #include <glib.h>
 #include <string.h>
index 88cceba..5644668 100644 (file)
@@ -26,7 +26,7 @@
  *
  */
 
-#include <tensor_typedef.h>
+#include <nnstreamer_plugin_api.h>
 #include "tensor_filter_tensorflow_lite_core.h"
 #include <glib.h>
 #include <string.h>
index fbca080..25f254e 100644 (file)
@@ -194,5 +194,20 @@ extern size_t get_tensor_element_count (const tensor_dim dim);
  */
 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__ */
index a3e1abe..9476b41 100644 (file)
@@ -41,62 +41,6 @@ static GHashTable *subplugins[NNS_SUBPLUGIN_END] = { 0 };
 
 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)
@@ -132,24 +76,25 @@ get_subplugin (subpluginType type, const char *name)
     /* 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");
@@ -188,6 +133,8 @@ get_subplugin (subpluginType type, const char *name)
     g_assert ((data = g_hash_table_lookup (table, name)) != NULL);
     data->handle = handle;
   }
+
+registered:
   G_UNLOCK (splock);
   return data->data;
 
index e82825f..26e0377 100644 (file)
@@ -87,10 +87,4 @@ register_subplugin (subpluginType type, const char *name, const void *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__ */
index 04a751a..ac1120d 100644 (file)
@@ -1,6 +1,5 @@
 tensor_decoder_sources = [
   'tensordec.c',
-  'tensordec-plugins.c',
   'tensordec-directvideo.c',
   'tensordec-imagelabel.c',
   'tensordec-boundingbox.c'
diff --git a/gst/nnstreamer/tensor_decoder/tensordec-plugins.c b/gst/nnstreamer/tensor_decoder/tensordec-plugins.c
deleted file mode 100644 (file)
index f299ca6..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * 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);
-}
index 36c3b9b..fe6e85d 100644 (file)
@@ -154,6 +154,40 @@ static gboolean gst_tensordec_transform_size (GstBaseTransform * trans,
     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
index ddd874a..f7fdf8b 100644 (file)
@@ -32,6 +32,7 @@
 #include <gst/gst.h>
 #include <gst/base/gstbasetransform.h>
 #include <tensor_common.h>
+#include <nnstreamer_subplugin.h>
 
 G_BEGIN_DECLS
 #define GST_TYPE_TENSORDEC \
@@ -156,10 +157,16 @@ struct _TensorDecDef
       /**< 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__ */
index ddb9d4a..c063725 100644 (file)
 
 #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);
 }
 
 /**
@@ -170,29 +126,9 @@ tensor_filter_probe (GstTensorFilterFramework * 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);
 }
 
 /**
@@ -203,23 +139,6 @@ tensor_filter_exit (const gchar * 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);
 }
 
index 7519a42..0c99374 100644 (file)
@@ -34,6 +34,7 @@
 #include <gst/gstinfo.h>
 #include <gst/base/gstbasetransform.h>
 #include <tensor_common.h>
+#include <nnstreamer_subplugin.h>
 
 G_BEGIN_DECLS
 
index 8a6b791..762a039 100644 (file)
@@ -310,8 +310,4 @@ typedef struct _GstTensorFilterFramework
        */
 } 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__*/