/**
- * NNStreamer Common Header
+ * NNStreamer Tensor Repo Header's Contents
* Copyright (C) 2018 Jijoong Moon <jijoong.moon@samsung.com>
*
* This library is free software; you can redistribute it and/or
/**
* @file tensor_repo.c
* @date 17 Nov 2018
- * @brief tensor repo header file for NNStreamer, the GStreamer plugin for neural networks
+ * @brief tensor repo file for NNStreamer, the GStreamer plugin for neural networks
* @see https://github.com/nnsuite/nnstreamer
* @author Jijoong Moon <jijoong.moon@samsung.com>
* @bug No known bugs except for NYI items
*/
#include<tensor_repo.h>
+#include <stdio.h>
+
+#ifndef DBG
+#define DBG TRUE
+#endif
+
+#define _print_log(...) if (DBG) g_message(__VA_ARGS__)
/**
* @brief tensor repo global variable with init.
*/
-GstTensorRepo _repo = {.num_data = 0,.tensorsdata = NULL,.initialized = FALSE };
+GstTensorRepo _repo = {.num_data = 0,.initialized = FALSE };
/**
* @brief getter to get nth GstTensorData
GstTensorData *
gst_tensor_repo_get_tensor (guint nth)
{
- return g_slist_nth_data (_repo.tensorsdata, nth);
+ GstTensorData *data;
+ gpointer *p = g_hash_table_lookup (_repo.hash, GINT_TO_POINTER (nth));
+ data = (GstTensorData *) p;
+ g_return_val_if_fail (data != NULL, NULL);
+ return data;
}
/**
* @brief add GstTensorData into repo
*/
-guint
-gst_tensor_repo_add_data (GstTensorData * data)
+gboolean
+gst_tensor_repo_add_data (GstTensorData * data, guint myid)
{
- guint id = _repo.num_data;
+ gboolean ret = FALSE;
+
+ if (!_repo.initialized)
+ gst_tensor_repo_init ();
+
GST_REPO_LOCK ();
- _repo.tensorsdata = g_slist_append (_repo.tensorsdata, data);
+ ret = g_hash_table_insert (_repo.hash, GINT_TO_POINTER (myid), data);
+ g_assert (ret);
+
+ _print_log ("Successfully added in hash table with key[%d]", myid);
+
_repo.num_data++;
GST_REPO_UNLOCK ();
- return id;
+ return ret;
}
/**
* @brief push GstBuffer into repo
*/
-void
+gboolean
gst_tensor_repo_push_buffer (guint nth, GstBuffer * buffer)
{
GST_TENSOR_REPO_LOCK (nth);
GstTensorData *data = gst_tensor_repo_get_tensor (nth);
+ g_return_val_if_fail (data != NULL, FALSE);
+
data->buffer = buffer;
GST_TENSOR_REPO_BROADCAST (nth);
GST_TENSOR_REPO_UNLOCK (nth);
+ return TRUE;
}
/**
GST_TENSOR_REPO_LOCK (nth);
GstTensorData *current_data, *data;
- current_data = g_slist_nth_data (_repo.tensorsdata, nth);
+ current_data = gst_tensor_repo_get_tensor (nth);
while (!current_data)
GST_TENSOR_REPO_WAIT (nth);
/**
* @brief remove nth GstTensorData from GstTensorRepo
*/
-void
+gboolean
gst_tensor_repo_remove_data (guint nth)
{
+ gboolean ret;
GST_REPO_LOCK ();
- GSList *data = g_slist_nth (_repo.tensorsdata, nth);
g_mutex_clear (GST_TENSOR_REPO_GET_LOCK (nth));
g_cond_clear (GST_TENSOR_REPO_GET_COND (nth));
- _repo.tensorsdata = g_slist_delete_link (_repo.tensorsdata, data);
- _repo.num_data--;
+
+ ret = g_hash_table_remove (_repo.hash, GINT_TO_POINTER (nth));
+
+ if (ret) {
+ _repo.num_data--;
+ _print_log ("key[%d] is removed\n", nth);
+ }
+
GST_REPO_UNLOCK ();
+ return ret;
}
/**
{
_repo.num_data = 0;
g_mutex_init (&_repo.repo_lock);
- _repo.tensorsdata = NULL;
+ _repo.hash = g_hash_table_new (g_direct_hash, g_direct_equal);
_repo.initialized = TRUE;
}
/**
- * NNStreamer Common Header
+ * NNStreamer Tensor Repo Header
* Copyright (C) 2018 Jijoong Moon <jijoong.moon@samsung.com>
*
* This library is free software; you can redistribute it and/or
* GstTensorRepo has GSlist of GstTensorData.
*
*/
+
typedef struct
{
GstTensorConfig *config;
/**
* @brief GstTensorRepo data structure.
*/
-struct GstTensorRepo_s
+typedef struct
{
gint num_data;
GMutex repo_lock;
- GSList *tensorsdata;
+ GHashTable* hash;
gboolean initialized;
-};
-
-typedef struct GstTensorRepo_s GstTensorRepo;
+} GstTensorRepo;
/**
* @brief getter to get nth GstTensorData
GstTensorData *
gst_tensor_repo_get_tensor (guint nth);
-guint
-gst_tensor_repo_add_data(GstTensorData *data);
+/**
+ * @brief add GstTensorData into repo
+ */
+/* guint */
+gboolean
+gst_tensor_repo_add_data (GstTensorData * data, guint myid);
-void
-gst_tensor_repo_push_buffer(guint nth, GstBuffer *buffer);
+/**
+ * @brief push GstBuffer into repo
+ */
+gboolean
+gst_tensor_repo_push_buffer (guint nth, GstBuffer * buffer);
+/**
+ * @brief pop GstTensorData from repo
+ */
GstTensorData *
-gst_tensor_repopop_buffer(guint nth);
+gst_tensor_repopop_buffer (guint nth);
/**
* @brief remove nth GstTensorData from GstTensorRepo
*/
-void
+gboolean
gst_tensor_repo_remove_data (guint nth);
/**
* @brief GstTensorRepo initialization
*/
void
-gst_tensor_repo_init();
+gst_tensor_repo_init ();
/**
#include "tensor_repopush.h"
/**
- * @brief Macro for debug mode.
- */
-#ifndef DBG
-#define DBG (!self->silent)
-#endif
-
-/**
* @brief tensor repository
*/
extern GstTensorRepo _repo;
-/**
- * @brief Macro for debug message.
- */
-#define silent_debug(...) \
- debug_print (DBG, __VA_ARGS__)
GST_DEBUG_CATEGORY_STATIC (gst_tensor_repopush_debug);
#define GST_CAT_DEFAULT gst_tensor_repopush_debug
{
PROP_0,
PROP_SIGNAL_RATE,
+ PROP_SLOT,
PROP_SILENT
};
#define DEFAULT_SIGNAL_RATE 0
#define DEFAULT_SILENT TRUE
#define DEFAULT_QOS TRUE
+#define DEFAULT_INDEX 0
/**
* @brief tensor_repopush sink template
"New data signals per second (0 for unlimited, max 500)", 0, 500,
DEFAULT_SIGNAL_RATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_SLOT,
+ g_param_spec_uint ("slot-index", "Slot Index", "repository slot index",
+ 0, UINT_MAX, DEFAULT_INDEX,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_property (gobject_class, PROP_SILENT,
g_param_spec_boolean ("silent", "Silent", "Produce verbose output",
DEFAULT_SILENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
static void
gst_tensor_repopush_init (GstTensorRepoPush * self)
{
+ gboolean ret = FALSE;
GstBaseSink *basesink;
basesink = GST_BASE_SINK (self);
- if (!_repo.initialized)
- gst_tensor_repo_init ();
-
self->data.config = NULL;
self->data.buffer = NULL;
g_mutex_init (&self->data.lock);
g_cond_init (&self->data.cond);
- self->myid = gst_tensor_repo_add_data (&self->data);
+ ret = gst_tensor_repo_add_data (&self->data, self->myid);
+ g_assert (ret);
+
self->silent = DEFAULT_SILENT;
self->signal_rate = DEFAULT_SIGNAL_RATE;
case PROP_SILENT:
self->silent = g_value_get_boolean (value);
break;
+ case PROP_SLOT:
+ self->myid = g_value_get_uint (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_SILENT:
g_value_set_boolean (value, self->silent);
break;
+ case PROP_SLOT:
+ g_value_set_uint (value, self->myid);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
static void
gst_tensor_repopush_dispose (GObject * object)
{
+ gboolean ret;
GstTensorRepoPush *self;
self = GST_TENSOR_REPOPUSH (object);
- gst_tensor_repo_remove_data (self->myid);
+ ret = gst_tensor_repo_remove_data (self->myid);
+ if (!ret)
+ GST_ELEMENT_ERROR (self, RESOURCE, WRITE,
+ ("Cannot remove [key: %d] in repo", self->myid), NULL);
}
/**
static gboolean
gst_tensor_repopush_query (GstBaseSink * sink, GstQuery * query)
{
- GstTensorRepoPush *self;
GstQueryType type;
GstFormat format;
- self = GST_TENSOR_REPOPUSH (sink);
type = GST_QUERY_TYPE (query);
- silent_debug ("received query %s", GST_QUERY_TYPE_NAME (query));
switch (type) {
case GST_QUERY_SEEKING:
/** tensor sink does not support seeking */
}
if (notify) {
+ gboolean ret = FALSE;
self->last_render_time = now;
- gst_tensor_repo_push_buffer (self->myid, buffer);
+ ret = gst_tensor_repo_push_buffer (self->myid, buffer);
+ if (!ret)
+ GST_ELEMENT_ERROR (self, RESOURCE, WRITE,
+ ("Cannot push buffer into repo [key: %d]", self->myid), NULL);
}
}
gst_caps_replace (&self->in_caps, caps);
GST_TENSOR_REPO_UNLOCK (self->myid);
- if (DBG) {
- guint caps_size, i;
-
- caps_size = gst_caps_get_size (caps);
- silent_debug ("set caps, size is %d", caps_size);
-
- for (i = 0; i < caps_size; i++) {
- GstStructure *structure = gst_caps_get_structure (caps, i);
- gchar *str = gst_structure_to_string (structure);
-
- silent_debug ("[%d] %s", i, str);
- g_free (str);
- }
- }
-
return TRUE;
}
return gst_element_register (plugin, "tensor_repopush",
GST_RANK_NONE, GST_TYPE_TENSOR_REPOPUSH);
}
-
-#ifndef SINGLE_BINARY
-/**
- * @brief Definition for identifying tensor_sink plugin.
- *
- * PACKAGE: this is usually set by autotools depending on some _INIT macro
- * in configure.ac and then written into and defined in config.h, but we can
- * just set it ourselves here in case someone doesn't use autotools to
- * compile this code. GST_PLUGIN_DEFINE needs PACKAGE to be defined.
- */
-#ifndef PACKAGE
-#define PACKAGE "nnstreamer"
-#endif
-
-/**
- * @brief Macro to define the entry point of the plugin.
- */
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
- GST_VERSION_MINOR,
- tensor_repopush,
- "Push element to handle tensor repository",
- gst_tensor_repopush_plugin_init, VERSION, "LGPL", "nnstreamer",
- "https://github.com/nnsuite/nnstreamer");
-#endif