From 7a70cc2b3a67d553459fb184ec75a22ab22af882 Mon Sep 17 00:00:00 2001 From: "jijoong.moon" Date: Tue, 20 Nov 2018 18:39:44 +0900 Subject: [PATCH] [Repo/Push] Rename Repo_sink to repopush and implement NYI **Changes proposed in this PR:** - Rename tensor_reposink to tensor_repopush. It seems more reseanable. - Split tensor_repo.h and tensor_repo.c for the repo utility function and place them in gst/nnstreamer. - Implement render fucntion to push GstBuffer into repo. **Self evaluation:** 1. Build test: [X]Passed [ ]Failed [ ]Skipped 2. Run test: [X]Passed [ ]Failed [ ]Skipped Signed-off-by: jijoong.moon --- CMakeLists.txt | 6 +- gst/nnstreamer/nnstreamer.c | 4 +- gst/nnstreamer/tensor_repo.c | 115 ++++++++ gst/nnstreamer/tensor_repo.h | 60 ++-- gst/tensor_repopush/CMakeLists.txt | 1 + .../tensor_repopush.c} | 320 ++++++++++----------- .../tensor_repopush.h} | 53 ++-- gst/tensor_reposink/CMakeLists.txt | 1 - 8 files changed, 323 insertions(+), 237 deletions(-) create mode 100644 gst/nnstreamer/tensor_repo.c create mode 100644 gst/tensor_repopush/CMakeLists.txt rename gst/{tensor_reposink/tensor_reposink.c => tensor_repopush/tensor_repopush.c} (52%) rename gst/{tensor_reposink/tensor_reposink.h => tensor_repopush/tensor_repopush.h} (50%) delete mode 100644 gst/tensor_reposink/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 12a57ef..434e4ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,7 @@ SET(PROJECTS tensor_split tensor_transform tensor_filter - tensor_reposink + tensor_repopush ) ADD_SUBDIRECTORY(nnstreamer_example) @@ -94,12 +94,12 @@ IF(ENABLE_TENSORFLOW) ENDIF(ENABLE_TENSORFLOW) LIST(LENGTH FILTER_DEP FILTER_DEP_LEN) -ADD_LIBRARY(nnstreamerStatic STATIC gst/nnstreamer/nnstreamer.c gst/nnstreamer/tensor_common.c ${OBJECTS}) +ADD_LIBRARY(nnstreamerStatic STATIC gst/nnstreamer/nnstreamer.c gst/nnstreamer/tensor_common.c gst/nnstreamer/tensor_repo.c ${OBJECTS}) SET_TARGET_PROPERTIES(nnstreamerStatic PROPERTIES OUTPUT_NAME nnstreamer) TARGET_INCLUDE_DIRECTORIES(nnstreamerStatic PUBLIC ${pkgs_INCLUDE_DIRS}) TARGET_COMPILE_OPTIONS(nnstreamerStatic PUBLIC ${pkgs_CFLAGS_OTHER}) -ADD_LIBRARY(nnstreamer SHARED gst/nnstreamer/nnstreamer.c gst/nnstreamer/tensor_common.c ${OBJECTS}) +ADD_LIBRARY(nnstreamer SHARED gst/nnstreamer/nnstreamer.c gst/nnstreamer/tensor_common.c gst/nnstreamer/tensor_repo.c ${OBJECTS}) TARGET_INCLUDE_DIRECTORIES(nnstreamer PUBLIC ${pkgs_INCLUDE_DIRS}) TARGET_COMPILE_OPTIONS(nnstreamer PUBLIC ${pkgs_CFLAGS_OTHER}) TARGET_LINK_LIBRARIES(nnstreamer ${pkgs_LIBRARIES} ${FILTER_LIB}) diff --git a/gst/nnstreamer/nnstreamer.c b/gst/nnstreamer/nnstreamer.c index 0cedfd3..0ce12f9 100644 --- a/gst/nnstreamer/nnstreamer.c +++ b/gst/nnstreamer/nnstreamer.c @@ -40,7 +40,7 @@ NNSTREAMER_PLUGIN (tensor_sink); NNSTREAMER_PLUGIN (tensor_split); NNSTREAMER_PLUGIN (tensor_transform); NNSTREAMER_PLUGIN (tensor_filter); -NNSTREAMER_PLUGIN (tensor_reposink); +NNSTREAMER_PLUGIN (tensor_repopush); #define NNSTREAMER_INIT(name, plugin) \ do { \ @@ -66,7 +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); + NNSTREAMER_INIT (tensor_repopush, plugin); return TRUE; } diff --git a/gst/nnstreamer/tensor_repo.c b/gst/nnstreamer/tensor_repo.c new file mode 100644 index 0000000..6e44032 --- /dev/null +++ b/gst/nnstreamer/tensor_repo.c @@ -0,0 +1,115 @@ +/** + * 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.c + * @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 + * + */ + +#include + +/** + * @brief tensor repo global variable with init. + */ +GstTensorRepo _repo = {.num_data = 0,.tensorsdata = NULL,.initialized = FALSE }; + +/** + * @brief getter to get nth GstTensorData + */ +GstTensorData * +gst_tensor_repo_get_tensor (guint nth) +{ + return g_slist_nth_data (_repo.tensorsdata, nth); +} + +/** + * @brief add GstTensorData into repo + */ +guint +gst_tensor_repo_add_data (GstTensorData * data) +{ + guint id = _repo.num_data; + GST_REPO_LOCK (); + _repo.tensorsdata = g_slist_append (_repo.tensorsdata, data); + _repo.num_data++; + GST_REPO_UNLOCK (); + return id; +} + +/** + * @brief push GstBuffer into repo + */ +void +gst_tensor_repo_push_buffer (guint nth, GstBuffer * buffer) +{ + GST_TENSOR_REPO_LOCK (nth); + + GstTensorData *data = gst_tensor_repo_get_tensor (nth); + data->buffer = buffer; + GST_TENSOR_REPO_BROADCAST (nth); + GST_TENSOR_REPO_UNLOCK (nth); +} + +/** + * @brief pop GstTensorData from repo + */ +GstTensorData * +gst_tensor_repopop_buffer (guint nth) +{ + GST_TENSOR_REPO_LOCK (nth); + GstTensorData *current_data, *data; + + current_data = g_slist_nth_data (_repo.tensorsdata, nth); + + while (!current_data) + GST_TENSOR_REPO_WAIT (nth); + data = current_data; + current_data = NULL; + GST_TENSOR_REPO_UNLOCK (nth); + + return data; +} + +/** + * @brief remove nth GstTensorData from GstTensorRepo + */ +void +gst_tensor_repo_remove_data (guint nth) +{ + 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--; + GST_REPO_UNLOCK (); +} + +/** + * @brief GstTensorRepo initialization + */ +void +gst_tensor_repo_init () +{ + _repo.num_data = 0; + g_mutex_init (&_repo.repo_lock); + _repo.tensorsdata = NULL; + _repo.initialized = TRUE; +} diff --git a/gst/nnstreamer/tensor_repo.h b/gst/nnstreamer/tensor_repo.h index 325f5ea..1474965 100644 --- a/gst/nnstreamer/tensor_repo.h +++ b/gst/nnstreamer/tensor_repo.h @@ -52,61 +52,53 @@ typedef struct */ struct GstTensorRepo_s { - gint num_buffer; + gint num_data; 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); -} +gst_tensor_repo_get_tensor (guint 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))) +guint +gst_tensor_repo_add_data(GstTensorData *data); + +void +gst_tensor_repo_push_buffer(guint nth, GstBuffer *buffer); + +GstTensorData * +gst_tensor_repopop_buffer(guint nth); /** * @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); -} +gst_tensor_repo_remove_data (guint nth); /** * @brief GstTensorRepo initialization */ void -gst_tensor_repo_init() -{ - _repo.num_buffer=0; - g_mutex_init (&_repo.repo_lock); - _repo.tensorsdata=NULL; - _repo.initialized=TRUE; -} +gst_tensor_repo_init(); + + +/** + * @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), GST_TENSOR_REPO_GET_LOCK(id))) +#define GST_TENSOR_REPO_BROADCAST(id) (g_cond_broadcast (GST_TENSOR_REPO_GET_COND(id))) +#define GST_REPO_LOCK()(g_mutex_lock(&_repo.repo_lock)) +#define GST_REPO_UNLOCK()(g_mutex_unlock(&_repo.repo_lock)) G_END_DECLS #endif /* __GST_TENSOR_REPO_H__ */ diff --git a/gst/tensor_repopush/CMakeLists.txt b/gst/tensor_repopush/CMakeLists.txt new file mode 100644 index 0000000..b687b6d --- /dev/null +++ b/gst/tensor_repopush/CMakeLists.txt @@ -0,0 +1 @@ +ADD_LIBRARY(tensor_repopushOBJ OBJECT tensor_repopush.c) diff --git a/gst/tensor_reposink/tensor_reposink.c b/gst/tensor_repopush/tensor_repopush.c similarity index 52% rename from gst/tensor_reposink/tensor_reposink.c rename to gst/tensor_repopush/tensor_repopush.c index ede3416..6dd34dc 100644 --- a/gst/tensor_reposink/tensor_reposink.c +++ b/gst/tensor_repopush/tensor_repopush.c @@ -16,11 +16,11 @@ */ /** - * SECTION: element-tensor_reposink + * SECTION: element-tensor_repopush * - * Sink elemnt to handle tensor repo + * Push elemnt to handle tensor repo * - * @file tensor_reposink.c + * @file tensor_repopush.c * @date 19 Nov 2018 * @brief GStreamer plugin to handle tensor repository * @see https://github.com/nnsuite/nnstreamer @@ -32,7 +32,7 @@ #include #endif -#include "tensor_reposink.h" +#include "tensor_repopush.h" /** * @brief Macro for debug mode. @@ -42,87 +42,69 @@ #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; +extern GstTensorRepo _repo; /** - * @brief tensor_reposink signals + * @brief Macro for debug message. */ -enum -{ - SIGNAL_NEW_DATA, - SIGNAL_STREAM_START, - SIGNAL_EOS, - LAST_SIGNAL -}; +#define silent_debug(...) \ + debug_print (DBG, __VA_ARGS__) + +GST_DEBUG_CATEGORY_STATIC (gst_tensor_repopush_debug); +#define GST_CAT_DEFAULT gst_tensor_repopush_debug /** - * @brief tensor_reposink properties + * @brief tensor_repopush properties */ enum { + PROP_0, 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 + * @brief tensor_repopush 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, +static void gst_tensor_repopush_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_tensor_reposink_get_property (GObject * object, guint prop_id, +static void gst_tensor_repopush_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, +static void gst_tensor_repopush_dispose (GObject * object); + +static gboolean gst_tensor_repopush_start (GstBaseSink * sink); +static gboolean gst_tensor_repopush_stop (GstBaseSink * sink); +static gboolean gst_tensor_repopush_query (GstBaseSink * sink, GstQuery * query); -static GstFlowReturn gst_tensor_reposink_render (GstBaseSink * sink, +static GstFlowReturn gst_tensor_repopush_render (GstBaseSink * sink, GstBuffer * buffer); -static GstFlowReturn gst_tensor_reposink_render_list (GstBaseSink * sink, +static GstFlowReturn gst_tensor_repopush_render_list (GstBaseSink * sink, GstBufferList * buffer_list); -static gboolean gst_tensor_reposink_set_caps (GstBaseSink * sink, +static gboolean gst_tensor_repopush_set_caps (GstBaseSink * sink, GstCaps * caps); -static GstCaps *gst_tensor_reposink_get_caps (GstBaseSink * sink, +static GstCaps *gst_tensor_repopush_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); +#define gst_tensor_repopush_parent_class parent_class +G_DEFINE_TYPE (GstTensorRepoPush, gst_tensor_repopush, GST_TYPE_BASE_SINK); /** - * @brief class initialization of tensor_reposink + * @brief class initialization of tensor_repopush */ static void -gst_tensor_reposink_class_init (GstTensorRepoSinkClass * klass) +gst_tensor_repopush_class_init (GstTensorRepoPushClass * klass) { GObjectClass *gobject_class; GstElementClass *element_class; @@ -131,59 +113,42 @@ gst_tensor_reposink_class_init (GstTensorRepoSinkClass * 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; + gobject_class->set_property = gst_tensor_repopush_set_property; + gobject_class->get_property = gst_tensor_repopush_get_property; + gobject_class->dispose = gst_tensor_repopush_dispose; 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", + "TensorRepoPush", + "Push/TensorRepo", + "Push 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->start = GST_DEBUG_FUNCPTR (gst_tensor_repopush_start); + basesink_class->stop = GST_DEBUG_FUNCPTR (gst_tensor_repopush_stop); + basesink_class->query = GST_DEBUG_FUNCPTR (gst_tensor_repopush_query); + basesink_class->render = GST_DEBUG_FUNCPTR (gst_tensor_repopush_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); + GST_DEBUG_FUNCPTR (gst_tensor_repopush_render_list); + basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_tensor_repopush_set_caps); + basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_tensor_repopush_get_caps); } /** - * @brief initialization of tensor_reposink + * @brief initialization of tensor_repopush */ static void -gst_tensor_reposink_init (GstTensorRepoSink * self) +gst_tensor_repopush_init (GstTensorRepoPush * self) { GstBaseSink *basesink; basesink = GST_BASE_SINK (self); @@ -197,15 +162,9 @@ gst_tensor_reposink_init (GstTensorRepoSink * self) 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->myid = gst_tensor_repo_add_data (&self->data); 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; @@ -217,64 +176,63 @@ gst_tensor_reposink_init (GstTensorRepoSink * self) * @brief set property vmethod */ static void -gst_tensor_reposink_set_property (GObject * object, guint prop_id, +gst_tensor_repopush_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { - /* NYI */ + GstTensorRepoPush *self; + self = GST_TENSOR_REPOPUSH (object); + + switch (prop_id) { + case PROP_SIGNAL_RATE: + self->signal_rate = g_value_get_uint (value); + break; + case PROP_SILENT: + self->silent = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } /** * @brief get property vmethod */ static void -gst_tensor_reposink_get_property (GObject * object, guint prop_id, +gst_tensor_repopush_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { - /* NYI */ + GstTensorRepoPush *self; + self = GST_TENSOR_REPOPUSH (object); + switch (prop_id) { + case PROP_SIGNAL_RATE: + g_value_set_uint (value, self->signal_rate); + break; + case PROP_SILENT: + g_value_set_boolean (value, self->silent); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } /** * @brief dispose vmethod implementation */ static void -gst_tensor_reposink_dispose (GObject * object) +gst_tensor_repopush_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)); - + GstTensorRepoPush *self; + self = GST_TENSOR_REPOPUSH (object); 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) +gst_tensor_repopush_start (GstBaseSink * sink) { return TRUE; } @@ -283,50 +241,22 @@ gst_tensor_reposink_start (GstBaseSink * sink) * @brief stop vmethod implementation */ static gboolean -gst_tensor_reposink_stop (GstBaseSink * sink) +gst_tensor_repopush_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) +gst_tensor_repopush_query (GstBaseSink * sink, GstQuery * query) { - GstTensorRepoSink *self; + GstTensorRepoPush *self; GstQueryType type; GstFormat format; - self = GST_TENSOR_REPOSINK (sink); + self = GST_TENSOR_REPOPUSH (sink); type = GST_QUERY_TYPE (query); silent_debug ("received query %s", GST_QUERY_TYPE_NAME (query)); @@ -344,12 +274,53 @@ gst_tensor_reposink_query (GstBaseSink * sink, GstQuery * query) return GST_BASE_SINK_CLASS (parent_class)->query (sink, query); } + +/** + * @brief push GstBuffer + */ +static void +gst_tensor_repopush_render_buffer (GstTensorRepoPush * self, GstBuffer * buffer) +{ + GstClockTime now = GST_CLOCK_TIME_NONE; + guint signal_rate; + gboolean notify = FALSE; + g_return_if_fail (GST_IS_TENSOR_REPOPUSH (self)); + + signal_rate = self->signal_rate; + + if (signal_rate) { + GstClock *clock; + GstClockTime render_time; + clock = gst_element_get_clock (GST_ELEMENT (self)); + + if (clock) { + now = gst_clock_get_time (clock); + render_time = (1000 / signal_rate) * GST_MSECOND + self->last_render_time; + if (!GST_CLOCK_TIME_IS_VALID (self->last_render_time) || + GST_CLOCK_DIFF (now, render_time) <= 0) + notify = TRUE; + gst_object_unref (clock); + } + } else { + notify = TRUE; + } + + if (notify) { + self->last_render_time = now; + gst_tensor_repo_push_buffer (self->myid, buffer); + } +} + /** * @brief render vmethod implementation */ static GstFlowReturn -gst_tensor_reposink_render (GstBaseSink * sink, GstBuffer * buffer) +gst_tensor_repopush_render (GstBaseSink * sink, GstBuffer * buffer) { + GstTensorRepoPush *self; + self = GST_TENSOR_REPOPUSH (sink); + + gst_tensor_repopush_render_buffer (self, buffer); return GST_FLOW_OK; } @@ -357,9 +328,22 @@ gst_tensor_reposink_render (GstBaseSink * sink, GstBuffer * buffer) * @brief render list vmethod implementation */ static GstFlowReturn -gst_tensor_reposink_render_list (GstBaseSink * sink, +gst_tensor_repopush_render_list (GstBaseSink * sink, GstBufferList * buffer_list) { + GstTensorRepoPush *self; + GstBuffer *buffer; + guint i; + guint num_buffers; + + self = GST_TENSOR_REPOPUSH (sink); + num_buffers = gst_buffer_list_length (buffer_list); + + for (i = 0; i < num_buffers; i++) { + buffer = gst_buffer_list_get (buffer_list, i); + gst_tensor_repopush_render_buffer (self, buffer); + } + return GST_FLOW_OK; } @@ -367,11 +351,11 @@ gst_tensor_reposink_render_list (GstBaseSink * sink, * @brief set_caps vmethod implementation */ static gboolean -gst_tensor_reposink_set_caps (GstBaseSink * sink, GstCaps * caps) +gst_tensor_repopush_set_caps (GstBaseSink * sink, GstCaps * caps) { - GstTensorRepoSink *self; + GstTensorRepoPush *self; - self = GST_TENSOR_REPOSINK (sink); + self = GST_TENSOR_REPOPUSH (sink); GST_TENSOR_REPO_LOCK (self->myid); gst_caps_replace (&self->in_caps, caps); @@ -399,12 +383,12 @@ gst_tensor_reposink_set_caps (GstBaseSink * sink, GstCaps * caps) * @brief get_caps vmethod implementation */ static GstCaps * -gst_tensor_reposink_get_caps (GstBaseSink * sink, GstCaps * filter) +gst_tensor_repopush_get_caps (GstBaseSink * sink, GstCaps * filter) { - GstTensorRepoSink *self; + GstTensorRepoPush *self; GstCaps *caps; - self = GST_TENSOR_REPOSINK (sink); + self = GST_TENSOR_REPOPUSH (sink); GST_TENSOR_REPO_LOCK (self->myid); caps = self->in_caps; @@ -427,13 +411,13 @@ gst_tensor_reposink_get_caps (GstBaseSink * sink, GstCaps * filter) * * See GstPluginInitFunc() for more details. */ -NNSTREAMER_PLUGIN_INIT (tensor_reposink) +NNSTREAMER_PLUGIN_INIT (tensor_repopush) { - GST_DEBUG_CATEGORY_INIT (gst_tensor_reposink_debug, "tensor_reposink", - 0, "tensor_reposink element"); + GST_DEBUG_CATEGORY_INIT (gst_tensor_repopush_debug, "tensor_repopush", + 0, "tensor_repopush element"); - return gst_element_register (plugin, "tensor_reposink", - GST_RANK_NONE, GST_TYPE_TENSOR_REPOSINK); + return gst_element_register (plugin, "tensor_repopush", + GST_RANK_NONE, GST_TYPE_TENSOR_REPOPUSH); } #ifndef SINGLE_BINARY @@ -454,8 +438,8 @@ NNSTREAMER_PLUGIN_INIT (tensor_reposink) */ 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", + tensor_repopush, + "Push element to handle tensor repository", + gst_tensor_repopush_plugin_init, VERSION, "LGPL", "nnstreamer", "https://github.com/nnsuite/nnstreamer"); #endif diff --git a/gst/tensor_reposink/tensor_reposink.h b/gst/tensor_repopush/tensor_repopush.h similarity index 50% rename from gst/tensor_reposink/tensor_reposink.h rename to gst/tensor_repopush/tensor_repopush.h index 8a20f71..31840a3 100644 --- a/gst/tensor_reposink/tensor_reposink.h +++ b/gst/tensor_repopush/tensor_repopush.h @@ -16,7 +16,7 @@ */ /** - * @file tensor_reposink.h + * @file tensor_repopush.h * @date 19 Nov 2018 * @brief GStreamer plugin to handle tensor repository * @see https://github.com/nnsuite/nnstreamer @@ -24,8 +24,8 @@ * @bug No known bugs except for NYI items */ -#ifndef __GST_TENSOR_REPOSINK_H_ -#define __GST_TENSOR_REPOSINK_H__ +#ifndef __GST_TENSOR_REPOPUSH_H_ +#define __GST_TENSOR_REPOPUSH_H__ #include #include @@ -33,30 +33,29 @@ 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; +#define GST_TYPE_TENSOR_REPOPUSH \ + (gst_tensor_repopush_get_type()) +#define GST_TENSOR_REPOPUSH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TENSOR_REPOPUSH,GstTensorRepoPush)) +#define GST_TENSOR_REPOPUSH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TENSOR_REPOPUSH,GstTensorRepoPushClass)) +#define GST_IS_TENSOR_REPOPUSH(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TENSOR_REPOPUSH)) +#define GST_IS_TENSOR_REPOPUSH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TENSOR_REPOPUSH)) +typedef struct _GstTensorRepoPush GstTensorRepoPush; +typedef struct _GstTensorRepoPushClass GstTensorRepoPushClass; /** - * @brief GstTensorRepoSink data structure. + * @brief GstTensorRepoPush data structure. * - * GstTensorRepoSink inherits GstBaseSink. + * GstTensorRepoPush inherits GstBaseSink. */ -struct _GstTensorRepoSink +struct _GstTensorRepoPush { GstBaseSink element; gboolean silent; - gboolean emit_signal; guint signal_rate; GstClockTime last_render_time; GstCaps *in_caps; @@ -66,23 +65,19 @@ struct _GstTensorRepoSink }; /** - * @brief GstTensorRepoSinkClass data structure. + * @brief GstTensorRepoPushClass data structure. * - * GstTensorRepoSink inherits GstBaseSink. + * GstTensorRepoPush inherits GstBaseSink. */ -struct _GstTensorRepoSinkClass +struct _GstTensorRepoPushClass { 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. + * @brief Function to get type of tensor_repopush. */ -GType gst_tensor_reposink_get_type (void); +GType gst_tensor_repopush_get_type (void); G_END_DECLS -#endif /** __GST_TENSOR_REPOSINK_H__ */ +#endif /** __GST_TENSOR_REPOPUSH_H__ */ diff --git a/gst/tensor_reposink/CMakeLists.txt b/gst/tensor_reposink/CMakeLists.txt deleted file mode 100644 index 5296e7d..0000000 --- a/gst/tensor_reposink/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -ADD_LIBRARY(tensor_reposinkOBJ OBJECT tensor_reposink.c ) -- 2.7.4