From 2938ce4a2f0020fc5179d88e360cc870f4c5bbb3 Mon Sep 17 00:00:00 2001 From: "jijoong.moon" Date: Mon, 19 Nov 2018 20:15:08 +0900 Subject: [PATCH] [TensorRepo/Sink] TensorRepo_Sink Draft 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 --- CMakeLists.txt | 1 + gst/nnstreamer/nnstreamer.c | 2 + gst/nnstreamer/tensor_repo.h | 112 +++++++++ gst/tensor_reposink/CMakeLists.txt | 1 + gst/tensor_reposink/tensor_reposink.c | 461 ++++++++++++++++++++++++++++++++++ gst/tensor_reposink/tensor_reposink.h | 88 +++++++ 6 files changed, 665 insertions(+) create mode 100644 gst/nnstreamer/tensor_repo.h create mode 100644 gst/tensor_reposink/CMakeLists.txt create mode 100644 gst/tensor_reposink/tensor_reposink.c create mode 100644 gst/tensor_reposink/tensor_reposink.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b2bc68..12a57ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,7 @@ SET(PROJECTS tensor_split tensor_transform tensor_filter + tensor_reposink ) ADD_SUBDIRECTORY(nnstreamer_example) diff --git a/gst/nnstreamer/nnstreamer.c b/gst/nnstreamer/nnstreamer.c index 383feda..0cedfd3 100644 --- a/gst/nnstreamer/nnstreamer.c +++ b/gst/nnstreamer/nnstreamer.c @@ -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 index 0000000..325f5ea --- /dev/null +++ b/gst/nnstreamer/tensor_repo.h @@ -0,0 +1,112 @@ +/** + * NNStreamer Common Header + * Copyright (C) 2018 Jijoong Moon + * + * 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 + * @bug No known bugs except for NYI items + * + */ +#ifndef __GST_TENSOR_REPO_H__ +#define __GST_TENSOR_REPO_H__ + +#include +#include +#include +#include "tensor_typedef.h" +#include + +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 index 0000000..5296e7d --- /dev/null +++ b/gst/tensor_reposink/CMakeLists.txt @@ -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 index 0000000..ede3416 --- /dev/null +++ b/gst/tensor_reposink/tensor_reposink.c @@ -0,0 +1,461 @@ +/** + * GStreamer + * Copyright (C) 2005 Thomas Vander Stichele + * Copyright (C) 2005 Ronald S. Bultje + * 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 + * @bug No known bugs except for NYI items + */ + +#ifdef HAVE_CONFIG_H +#include +#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 index 0000000..8a20f71 --- /dev/null +++ b/gst/tensor_reposink/tensor_reposink.h @@ -0,0 +1,88 @@ +/** + * GStreamer + * Copyright (C) 2005 Thomas Vander Stichele + * Copyright (C) 2005 Ronald S. Bultje + * 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 + * @bug No known bugs except for NYI items + */ + +#ifndef __GST_TENSOR_REPOSINK_H_ +#define __GST_TENSOR_REPOSINK_H__ + +#include +#include +#include + +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__ */ -- 2.7.4