[TensorRepo/Sink] TensorRepo_Sink Draft
authorjijoong.moon <jijoong.moon@samsung.com>
Mon, 19 Nov 2018 11:15:08 +0000 (20:15 +0900)
committerMyungJoo Ham <myungjoo.ham@gmail.com>
Fri, 23 Nov 2018 18:34:27 +0000 (18:34 +0000)
In order to enable the recursion, we may need this tensor
repository. In order to feed or get the tensor(s) to/from tensor
repository, we need tensor_reposink and tensor_reposrc element.

This PR includes initial draft for tensor_repo data structure and
tensor_reposink.

**Self evaluation:**
1. Build test:  [X]Passed [ ]Failed [ ]Skipped
2. Run test:  [ ]Passed [ ]Failed [X]Skipped

Signed-off-by: jijoong.moon <jijoong.moon@samsung.com>
CMakeLists.txt
gst/nnstreamer/nnstreamer.c
gst/nnstreamer/tensor_repo.h [new file with mode: 0644]
gst/tensor_reposink/CMakeLists.txt [new file with mode: 0644]
gst/tensor_reposink/tensor_reposink.c [new file with mode: 0644]
gst/tensor_reposink/tensor_reposink.h [new file with mode: 0644]

index 9b2bc68..12a57ef 100644 (file)
@@ -66,6 +66,7 @@ SET(PROJECTS
        tensor_split
        tensor_transform
        tensor_filter
+       tensor_reposink
 )
 
 ADD_SUBDIRECTORY(nnstreamer_example)
index 383feda..0cedfd3 100644 (file)
@@ -40,6 +40,7 @@ NNSTREAMER_PLUGIN (tensor_sink);
 NNSTREAMER_PLUGIN (tensor_split);
 NNSTREAMER_PLUGIN (tensor_transform);
 NNSTREAMER_PLUGIN (tensor_filter);
+NNSTREAMER_PLUGIN (tensor_reposink);
 
 #define NNSTREAMER_INIT(name, plugin) \
   do { \
@@ -65,6 +66,7 @@ gst_nnstreamer_init (GstPlugin * plugin)
   NNSTREAMER_INIT (tensor_split, plugin);
   NNSTREAMER_INIT (tensor_transform, plugin);
   NNSTREAMER_INIT (tensor_filter, plugin);
+  NNSTREAMER_INIT (tensor_reposink, plugin);
 
   return TRUE;
 }
diff --git a/gst/nnstreamer/tensor_repo.h b/gst/nnstreamer/tensor_repo.h
new file mode 100644 (file)
index 0000000..325f5ea
--- /dev/null
@@ -0,0 +1,112 @@
+/**
+ * NNStreamer Common Header
+ * Copyright (C) 2018 Jijoong Moon <jijoong.moon@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       tensor_repo.h
+ * @date       17 Nov 2018
+ * @brief      tensor repo header 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
+ *
+ */
+#ifndef __GST_TENSOR_REPO_H__
+#define __GST_TENSOR_REPO_H__
+
+#include <glib.h>
+#include <stdint.h>
+#include <tensor_common.h>
+#include "tensor_typedef.h"
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+/**
+ * @brief GstTensorRepo internal data structure.
+ *
+ * GstTensorRepo has GSlist of GstTensorData.
+ *
+ */
+typedef struct
+{
+  GstTensorConfig *config;
+  GstBuffer *buffer;
+  GCond cond;
+  GMutex lock;
+} GstTensorData;
+
+/**
+ * @brief GstTensorRepo data structure.
+ */
+struct GstTensorRepo_s
+{
+  gint num_buffer;
+  GMutex repo_lock;
+  GSList *tensorsdata;
+  gboolean initialized;
+} GstTensorRepo_default={.num_buffer=0, .tensorsdata=NULL, .initialized=FALSE};
+
+typedef struct GstTensorRepo_s GstTensorRepo;
+
+/**
+ * @brief extern variable for GstTensorRepo
+ */
+extern GstTensorRepo _repo;
+
+/**
+ * @brief getter to get nth GstTensorData
+ */
+GstTensorData *
+gst_tensor_repo_get_tensor (guint nth)
+{
+  return g_slist_nth_data (_repo.tensorsdata, nth);
+}
+
+/**
+ * @brief Macro for Lock & Cond
+ */
+#define GST_TENSOR_REPO_GET_LOCK(id) (&((GstTensorData*)(gst_tensor_repo_get_tensor(id)))->lock)
+#define GST_TENSOR_REPO_GET_COND(id) (&((GstTensorData*)(gst_tensor_repo_get_tensor(id)))->cond)
+#define GST_TENSOR_REPO_LOCK(id) (g_mutex_lock(GST_TENSOR_REPO_GET_LOCK(id)))
+#define GST_TENSOR_REPO_UNLOCK(id) (g_mutex_unlock(GST_TENSOR_REPO_GET_LOCK(id)))
+#define GST_TENSOR_REPO_WAIT(id) (g_cond_wait(GST_TENSOR_REPO_GET_COND(id), GET_TENSOR_REPO_GET_LOCK(id)))
+#define GST_TENSOR_REPO_BROADCAST(id) (g_cond_broadcast (GST_TENSOR_REPO_GET_COND(id)))
+
+/**
+ * @brief remove nth GstTensorData from GstTensorRepo
+ */
+void
+gst_tensor_repo_remove_data (guint nth)
+{
+  g_mutex_lock (&_repo.repo_lock);
+  GSList *data = g_slist_nth (_repo.tensorsdata, nth);
+  _repo.tensorsdata = g_slist_delete_link (_repo.tensorsdata, data);
+  g_mutex_unlock (&_repo.repo_lock);
+}
+
+/**
+ * @brief GstTensorRepo initialization
+ */
+void
+gst_tensor_repo_init()
+{
+  _repo.num_buffer=0;
+  g_mutex_init (&_repo.repo_lock);
+  _repo.tensorsdata=NULL;
+  _repo.initialized=TRUE;
+}
+
+G_END_DECLS
+#endif /* __GST_TENSOR_REPO_H__ */
diff --git a/gst/tensor_reposink/CMakeLists.txt b/gst/tensor_reposink/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5296e7d
--- /dev/null
@@ -0,0 +1 @@
+ADD_LIBRARY(tensor_reposinkOBJ OBJECT tensor_reposink.c )
diff --git a/gst/tensor_reposink/tensor_reposink.c b/gst/tensor_reposink/tensor_reposink.c
new file mode 100644 (file)
index 0000000..ede3416
--- /dev/null
@@ -0,0 +1,461 @@
+/**
+ * GStreamer
+ * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
+ * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+/**
+ * SECTION: element-tensor_reposink
+ *
+ * Sink elemnt to handle tensor repo
+ *
+ * @file       tensor_reposink.c
+ * @date       19 Nov 2018
+ * @brief      GStreamer plugin to handle tensor repository
+ * @see                https://github.com/nnsuite/nnstreamer
+ * @author     Jijoong Moon <jijoong.moon@samsung.com>
+ * @bug                No known bugs except for NYI items
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "tensor_reposink.h"
+
+/**
+ * @brief Macro for debug mode.
+ */
+#ifndef DBG
+#define DBG (!self->silent)
+#endif
+
+/**
+ * @brief Macro for debug message.
+ */
+#define silent_debug(...) \
+    debug_print (DBG, __VA_ARGS__)
+
+GST_DEBUG_CATEGORY_STATIC (gst_tensor_reposink_debug);
+#define GST_CAT_DEFAULT gst_tensor_reposink_debug
+
+/**
+ * @brief tensor repository
+ */
+GstTensorRepo _repo;
+
+/**
+ * @brief tensor_reposink signals
+ */
+enum
+{
+  SIGNAL_NEW_DATA,
+  SIGNAL_STREAM_START,
+  SIGNAL_EOS,
+  LAST_SIGNAL
+};
+
+/**
+ * @brief tensor_reposink properties
+ */
+enum
+{
+  PROP_SIGNAL_RATE,
+  PROP_EMIT_SIGNAL,
+  PROP_SILENT
+};
+
+#define DEFAULT_EMIT_SIGNAL TRUE
+#define DEFAULT_SIGNAL_RATE 0
+#define DEFAULT_SILENT TRUE
+#define DEFAULT_QOS TRUE
+
+/**
+ * @brief tensor_reposink sink template
+ */
+static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS (GST_TENSOR_CAP_DEFAULT "; " GST_TENSORS_CAP_DEFAULT));
+
+static guint _tensor_reposink_signals[LAST_SIGNAL] = { 0 };
+
+static void gst_tensor_reposink_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_tensor_reposink_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+static void gst_tensor_reposink_dispose (GObject * object);
+static void gst_tensor_reposink_finalize (GObject * object);
+
+/** GstBaseSink method implementation */
+static gboolean gst_tensor_reposink_start (GstBaseSink * sink);
+static gboolean gst_tensor_reposink_stop (GstBaseSink * sink);
+static gboolean gst_tensor_reposink_event (GstBaseSink * sink,
+    GstEvent * event);
+static gboolean gst_tensor_reposink_query (GstBaseSink * sink,
+    GstQuery * query);
+static GstFlowReturn gst_tensor_reposink_render (GstBaseSink * sink,
+    GstBuffer * buffer);
+static GstFlowReturn gst_tensor_reposink_render_list (GstBaseSink * sink,
+    GstBufferList * buffer_list);
+static gboolean gst_tensor_reposink_set_caps (GstBaseSink * sink,
+    GstCaps * caps);
+static GstCaps *gst_tensor_reposink_get_caps (GstBaseSink * sink,
+    GstCaps * filter);
+
+
+#define gst_tensor_reposink_parent_class parent_class
+G_DEFINE_TYPE (GstTensorRepoSink, gst_tensor_reposink, GST_TYPE_BASE_SINK);
+
+/**
+ * @brief class initialization of tensor_reposink
+ */
+static void
+gst_tensor_reposink_class_init (GstTensorRepoSinkClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *element_class;
+  GstBaseSinkClass *basesink_class;
+  gobject_class = G_OBJECT_CLASS (klass);
+  element_class = GST_ELEMENT_CLASS (klass);
+  basesink_class = GST_BASE_SINK_CLASS (klass);
+
+  gobject_class->set_property = gst_tensor_reposink_set_property;
+  gobject_class->get_property = gst_tensor_reposink_get_property;
+  gobject_class->dispose = gst_tensor_reposink_dispose;
+  gobject_class->finalize = gst_tensor_reposink_finalize;
+
+  g_object_class_install_property (gobject_class, PROP_SIGNAL_RATE,
+      g_param_spec_uint ("signal-rate", "Signal rate",
+          "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_EMIT_SIGNAL,
+      g_param_spec_boolean ("emit-signal", "Emit signal",
+          "Emit signal for new data, stream start, eos", DEFAULT_EMIT_SIGNAL,
+          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));
+
+  _tensor_reposink_signals[SIGNAL_STREAM_START] =
+      g_signal_new ("stream-start", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTensorRepoSinkClass, stream_start),
+      NULL, NULL, NULL, G_TYPE_NONE, 0, G_TYPE_NONE);
+
+  _tensor_reposink_signals[SIGNAL_EOS] =
+      g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
+      G_STRUCT_OFFSET (GstTensorRepoSinkClass, eos), NULL, NULL, NULL,
+      G_TYPE_NONE, 0, G_TYPE_NONE);
+
+  gst_element_class_set_static_metadata (element_class,
+      "TensorRepoSink",
+      "Sink/TensorRepo",
+      "Sink element to handle tensor repository",
+      "Samsung Electronics Co., Ltd.");
+
+  gst_element_class_add_static_pad_template (element_class, &sink_template);
+
+  basesink_class->start = GST_DEBUG_FUNCPTR (gst_tensor_reposink_start);
+  basesink_class->stop = GST_DEBUG_FUNCPTR (gst_tensor_reposink_stop);
+  basesink_class->event = GST_DEBUG_FUNCPTR (gst_tensor_reposink_event);
+  basesink_class->query = GST_DEBUG_FUNCPTR (gst_tensor_reposink_query);
+  basesink_class->render = GST_DEBUG_FUNCPTR (gst_tensor_reposink_render);
+  basesink_class->render_list =
+      GST_DEBUG_FUNCPTR (gst_tensor_reposink_render_list);
+  basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_tensor_reposink_set_caps);
+  basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_tensor_reposink_get_caps);
+}
+
+/**
+ * @brief initialization of tensor_reposink
+ */
+static void
+gst_tensor_reposink_init (GstTensorRepoSink * self)
+{
+  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);
+
+  g_mutex_lock (&_repo.repo_lock);
+  _repo.tensorsdata = g_slist_append (_repo.tensorsdata, &self->data);
+
+  self->myid = _repo.num_buffer;
+  _repo.num_buffer++;
+  g_mutex_unlock (&_repo.repo_lock);
+
+  self->silent = DEFAULT_SILENT;
+  self->emit_signal = DEFAULT_EMIT_SIGNAL;
+  self->signal_rate = DEFAULT_SIGNAL_RATE;
+  self->last_render_time = GST_CLOCK_TIME_NONE;
+  self->in_caps = NULL;
+
+  gst_base_sink_set_qos_enabled (basesink, DEFAULT_QOS);
+}
+
+/**
+ * @brief set property vmethod
+ */
+static void
+gst_tensor_reposink_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  /* NYI */
+}
+
+/**
+ * @brief get property vmethod
+ */
+static void
+gst_tensor_reposink_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  /* NYI */
+}
+
+/**
+ * @brief dispose vmethod implementation
+ */
+static void
+gst_tensor_reposink_dispose (GObject * object)
+{
+  GstTensorRepoSink *self;
+  GstTensorData *data;
+  self = GST_TENSOR_REPOSINK (object);
+
+  GST_TENSOR_REPO_LOCK (self->myid);
+  data = gst_tensor_repo_get_tensor (self->myid);
+  gst_object_unref (data->config);
+  gst_object_unref (data->buffer);
+  GST_TENSOR_REPO_UNLOCK (self->myid);
+
+  g_mutex_clear (GST_TENSOR_REPO_GET_LOCK (self->myid));
+  g_cond_clear (GST_TENSOR_REPO_GET_COND (self->myid));
+
+  gst_tensor_repo_remove_data (self->myid);
+}
+
+/**
+ * @brief finalize vmethod implementation
+ */
+static void
+gst_tensor_reposink_finalize (GObject * object)
+{
+  GstTensorRepoSink *self;
+
+  self = GST_TENSOR_REPOSINK (object);
+  g_mutex_clear (GST_TENSOR_REPO_GET_LOCK (self->myid));
+  g_cond_clear (GST_TENSOR_REPO_GET_COND (self->myid));
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+/**
+ * @brief start vmethod implementation
+ */
+static gboolean
+gst_tensor_reposink_start (GstBaseSink * sink)
+{
+  return TRUE;
+}
+
+/**
+ * @brief stop vmethod implementation
+ */
+static gboolean
+gst_tensor_reposink_stop (GstBaseSink * sink)
+{
+  return TRUE;
+}
+
+/**
+ * @brief event vmethod implementation
+ */
+static gboolean
+gst_tensor_reposink_event (GstBaseSink * sink, GstEvent * event)
+{
+  GstTensorRepoSink *self;
+  GstEventType type;
+
+  self = GST_TENSOR_REPOSINK (sink);
+  type = GST_EVENT_TYPE (event);
+
+  switch (type) {
+    case GST_EVENT_STREAM_START:
+      break;
+
+    case GST_EVENT_EOS:
+      break;
+
+    default:
+      break;
+  }
+
+  silent_debug ("received event %s", GST_EVENT_TYPE_NAME (event));
+
+  return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
+}
+
+/**
+ * @brief query vmethod implementation
+ */
+static gboolean
+gst_tensor_reposink_query (GstBaseSink * sink, GstQuery * query)
+{
+  GstTensorRepoSink *self;
+  GstQueryType type;
+  GstFormat format;
+
+  self = GST_TENSOR_REPOSINK (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 */
+      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
+      gst_query_set_seeking (query, format, FALSE, 0, -1);
+      return TRUE;
+
+    default:
+      break;
+  }
+
+  return GST_BASE_SINK_CLASS (parent_class)->query (sink, query);
+}
+
+/**
+ * @brief render vmethod implementation
+ */
+static GstFlowReturn
+gst_tensor_reposink_render (GstBaseSink * sink, GstBuffer * buffer)
+{
+  return GST_FLOW_OK;
+}
+
+/**
+ * @brief render list vmethod implementation
+ */
+static GstFlowReturn
+gst_tensor_reposink_render_list (GstBaseSink * sink,
+    GstBufferList * buffer_list)
+{
+  return GST_FLOW_OK;
+}
+
+/**
+ * @brief set_caps vmethod implementation
+ */
+static gboolean
+gst_tensor_reposink_set_caps (GstBaseSink * sink, GstCaps * caps)
+{
+  GstTensorRepoSink *self;
+
+  self = GST_TENSOR_REPOSINK (sink);
+
+  GST_TENSOR_REPO_LOCK (self->myid);
+  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;
+}
+
+/**
+ * @brief get_caps vmethod implementation
+ */
+static GstCaps *
+gst_tensor_reposink_get_caps (GstBaseSink * sink, GstCaps * filter)
+{
+  GstTensorRepoSink *self;
+  GstCaps *caps;
+
+  self = GST_TENSOR_REPOSINK (sink);
+
+  GST_TENSOR_REPO_LOCK (self->myid);
+  caps = self->in_caps;
+
+  if (caps) {
+    if (filter) {
+      caps = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    } else {
+      gst_caps_ref (caps);
+    }
+  }
+  GST_TENSOR_REPO_UNLOCK (self->myid);
+
+  return caps;
+}
+
+
+/**
+ * @brief Function to initialize the plugin.
+ *
+ * See GstPluginInitFunc() for more details.
+ */
+NNSTREAMER_PLUGIN_INIT (tensor_reposink)
+{
+  GST_DEBUG_CATEGORY_INIT (gst_tensor_reposink_debug, "tensor_reposink",
+      0, "tensor_reposink element");
+
+  return gst_element_register (plugin, "tensor_reposink",
+      GST_RANK_NONE, GST_TYPE_TENSOR_REPOSINK);
+}
+
+#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_reposink,
+    "Sink element to handle tensor repository",
+    gst_tensor_reposink_plugin_init, VERSION, "LGPL", "nnstreamer",
+    "https://github.com/nnsuite/nnstreamer");
+#endif
diff --git a/gst/tensor_reposink/tensor_reposink.h b/gst/tensor_reposink/tensor_reposink.h
new file mode 100644 (file)
index 0000000..8a20f71
--- /dev/null
@@ -0,0 +1,88 @@
+/**
+ * GStreamer
+ * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
+ * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ *
+ * 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       tensor_reposink.h
+ * @date       19 Nov 2018
+ * @brief      GStreamer plugin to handle tensor repository
+ * @see                https://github.com/nnsuite/nnstreamer
+ * @author     Jijoong Moon <jijoong.moon@samsung.com>
+ * @bug                No known bugs except for NYI items
+ */
+
+#ifndef __GST_TENSOR_REPOSINK_H_
+#define __GST_TENSOR_REPOSINK_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstbasesink.h>
+#include <tensor_repo.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_TENSOR_REPOSINK \
+  (gst_tensor_reposink_get_type())
+#define GST_TENSOR_REPOSINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TENSOR_REPOSINK,GstTensorRepoSink))
+#define GST_TENSOR_REPOSINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TENSOR_REPOSINK,GstTensorRepoSinkClass))
+#define GST_IS_TENSOR_REPOSINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TENSOR_REPOSINK))
+#define GST_IS_TENSOR_REPOSINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TENSOR_REPOSINK))
+typedef struct _GstTensorRepoSink GstTensorRepoSink;
+typedef struct _GstTensorRepoSinkClass GstTensorRepoSinkClass;
+
+/**
+ * @brief GstTensorRepoSink data structure.
+ *
+ * GstTensorRepoSink inherits GstBaseSink.
+ */
+struct _GstTensorRepoSink
+{
+  GstBaseSink element;
+
+  gboolean silent;
+  gboolean emit_signal;
+  guint signal_rate;
+  GstClockTime last_render_time;
+  GstCaps *in_caps;
+  GstTensorData data;
+  guint myid;
+
+};
+
+/**
+ * @brief GstTensorRepoSinkClass data structure.
+ *
+ * GstTensorRepoSink inherits GstBaseSink.
+ */
+struct _GstTensorRepoSinkClass
+{
+  GstBaseSinkClass parent_class;
+
+  void (*new_data) (GstElement * element, GstBuffer * buffer);
+  void (*stream_start) (GstElement * element);
+  void (*eos) (GstElement * element);
+};
+
+/**
+ * @brief Function to get type of tensor_reposink.
+ */
+GType gst_tensor_reposink_get_type (void);
+
+G_END_DECLS
+#endif /** __GST_TENSOR_REPOSINK_H__ */