-/*
+/**
* Gstreamer Tensor Meta
* Copyright (C) 2018 Jijoong Moon <jijoong.moon@samsung.com>
*
#include <glib.h>
#include <dlfcn.h>
+/**
+ * @brief return meta type (GstMetaTensor)
+ * @return GType GstMetaTensor
+ */
GType
gst_meta_tensor_api_get_type (void)
{
static gboolean
gst_meta_tensor_init (GstMeta * meta, gpointer params, GstBuffer * buffer)
{
- /* @TODO To be filled */
-
GstMetaTensor *emeta = (GstMetaTensor *) meta;
emeta->num_tensors = 0;
emeta->dimensions = NULL;
-
+ emeta->types = NULL;
return TRUE;
}
gst_meta_tensor_transform (GstBuffer * transbuf, GstMeta * meta,
GstBuffer * buffer, GQuark type, gpointer data)
{
- /* @TODO To be filled */
GstMetaTensor *dest_meta = GST_META_TENSOR_ADD (transbuf);
GstMetaTensor *src_meta = (GstMetaTensor *) meta;
static void
gst_meta_tensor_free (GstMeta * meta, GstBuffer * buffer)
{
+ gboolean haslock = FALSE;
+ if (!GST_OBJECT_GET_LOCK (buffer)) {
+ GST_OBJECT_LOCK (buffer);
+ haslock = TRUE;
+ }
+
GstMetaTensor *emeta = (GstMetaTensor *) meta;
- /* If there is buffer free in here */
+
+ GList *l = emeta->dimensions;
+ while (l != NULL) {
+ GList *next = l->next;
+ g_free (next->data);
+ }
+ g_list_free (emeta->dimensions);
+
+ l = emeta->types;
+ while (l != NULL) {
+ GList *next = l->next;
+ g_free (next->data);
+ }
+ g_list_free (emeta->types);
+
+ if (haslock)
+ GST_OBJECT_UNLOCK (buffer);
+
emeta->num_tensors = 0;
}
}
/**
- * @brief @todo fill this in
+ * @brief Add Meta into buffer
*/
GstMetaTensor *
gst_buffer_add_meta_tensor (GstBuffer * buffer)
}
/**
- * @brief @todo fill this in
+ * @brief fill this in
*/
GstMetaTensor *
gst_make_tensors (GstBuffer * buffer)
}
/**
- * @brief @todo fill this in
+ * @brief append tensor into buffer
*/
GstMetaTensor *
-gst_append_tensor (GstBuffer * buffer, GstMemory * mem, tensor_dim * dim)
+gst_append_tensor (GstBuffer * buffer, GstMemory * mem, tensor_dim dim,
+ tensor_type type)
{
tensor_dim *d;
+ tensor_type *t;
+ gboolean haslock = FALSE;
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
+ if (!GST_OBJECT_GET_LOCK (buffer)) {
+ GST_OBJECT_LOCK (buffer);
+ haslock = TRUE;
+ }
gst_buffer_append_memory (buffer, mem);
memcpy (d, dim, sizeof (tensor_dim));
meta->dimensions = g_list_append (meta->dimensions, d);
+ t = g_slice_new (tensor_type);
+ *t = type;
+ meta->types = g_list_append (meta->types, t);
+
+ if (haslock)
+ GST_OBJECT_UNLOCK (buffer);
+
return meta;
}
/**
- * @brief @todo fill this in
+ * @brief Get tensor GstMemory
*/
GstMemory *
gst_get_tensor (GstBuffer * buffer, gint nth)
}
/**
- * @brief @todo fill this in
+ * @brief Get tensor dimension
*/
tensor_dim *
gst_get_tensordim (GstBuffer * buffer, gint nth)
{
GstMetaTensor *meta;
- tensor_dim *dim;
+ tensor_dim *dim = NULL;
meta = (GstMetaTensor *) gst_buffer_get_meta_tensor (buffer);
if (meta) {
- dim = (tensor_dim *) g_list_nth_data (meta->dimensions, nth);
- return dim;
+ dim = g_list_nth_data (meta->dimensions, nth);
+ }
+ return dim;
+}
+
+/**
+ * @brief Get tensor type
+ */
+tensor_type
+gst_get_tensortype (GstBuffer * buffer, gint nth)
+{
+ GstMetaTensor *meta;
+ tensor_type *t;
+ tensor_type type;
+ meta = (GstMetaTensor *) gst_buffer_get_meta_tensor (buffer);
+ if (meta) {
+ t = g_list_nth_data (meta->types, nth);
+ type = *t;
+ return type;
} else {
- return NULL;
+ return _NNS_END;
}
}
/**
- * @brief @todo fill this in
+ * @brief Remove tensor in tensors
*/
GstFlowReturn
gst_remove_tensor (GstBuffer * buffer, gint nth)
{
+ gboolean haslock = FALSE;
+ if (!GST_OBJECT_GET_LOCK (buffer)) {
+ GST_OBJECT_LOCK (buffer);
+ haslock = TRUE;
+ }
GstMetaTensor *meta = (GstMetaTensor *) gst_buffer_get_meta_tensor (buffer);
if (meta) {
- if (meta->num_tensors == 0)
+ if (meta->num_tensors == 0) {
+ if (haslock)
+ GST_OBJECT_UNLOCK (buffer);
return GST_FLOW_ERROR;
+ }
meta->num_tensors = meta->num_tensors - 1;
GList *list = meta->dimensions;
gint th = 0;
th++;
list = next;
}
+
+ list = meta->types;
+ th = 0;
+ while (list != NULL) {
+ GList *next = list->next;
+ if (th == nth) {
+ meta->types = g_list_delete_link (meta->types, list);
+ }
+ th++;
+ list = next;
+ }
gst_buffer_remove_memory (buffer, nth);
}
+ if (haslock)
+ GST_OBJECT_UNLOCK (buffer);
+
return GST_FLOW_OK;
}
}
/**
+ * @brief push tensor in tensors
+ * @param pad Sink pad
+ * @param tensor_mux Tensor Mux
+ * @param buffer input buffer
+ */
+static gboolean
+gst_push_tensor (GstPad * pad, GstTensorMux * tensor_mux, GstBuffer * buffer)
+{
+ tensor_dim dim;
+ GstMemory *mem;
+ gboolean ret = FALSE;
+ tensor_type tensor_type;
+ GstTensor_Filter_CheckStatus status;
+
+ GstCaps *caps = gst_pad_get_current_caps (pad);
+
+ status = get_tensor_from_padcap (caps, dim, &tensor_type);
+ g_assert ((status & _TFC_ALL) == _TFC_ALL);
+
+ mem = gst_buffer_get_memory (buffer, 0);
+ gst_memory_ref (mem);
+ if (gst_append_tensor (tensor_mux->outbuffer, mem, dim, tensor_type))
+ ret = TRUE;
+
+ return ret;
+}
+
+/**
* @brief chain function (gst element vmethod)
*/
static GstFlowReturn
changed = TRUE;
g_clear_object (&tensor_mux->last_pad);
tensor_mux->last_pad = g_object_ref (pad);
- GstCaps *tcap = gst_pad_get_current_caps (pad);
- GstStructure *s = gst_caps_get_structure (tcap, 0);
- tensor_dim dim;
- gst_structure_get_int (s, "dim1", (int *) &dim[0]);
- gst_structure_get_int (s, "dim2", (int *) &dim[1]);
- gst_structure_get_int (s, "dim3", (int *) &dim[2]);
- gst_structure_get_int (s, "dim4", (int *) &dim[3]);
-
- GstMemory *mem = gst_buffer_get_memory (buffer, 0);
- gst_memory_ref (mem);
- gst_append_tensor (tensor_mux->outbuffer, mem, &dim);
+
+ if (!gst_push_tensor (pad, tensor_mux, buffer))
+ GST_ERROR_OBJECT (tensor_mux, "Cannot append GstMemory\n");
g_mutex_lock (&buf_mutex);
buf_count++;
-/*
+/**
* GStreamer Tensor Meta
* Copyright (C) 2018 Jijoong Moon <jijoong.moon@samsung.com>
*
GstMeta meta;
gint num_tensors;
GList *dimensions;
+ GList *types;
};
/**
* @param dim tensor_dim for tensor
* @return GstMetaTensor
*/
-GstMetaTensor * gst_append_tensor (GstBuffer *buffer, GstMemory *mem, tensor_dim *dim);
+GstMetaTensor * gst_append_tensor (GstBuffer *buffer, GstMemory *mem, tensor_dim dim, tensor_type type);
/**
* @brief Utility function to get tensor from tensors.
* @param nth order of tensor
* @return tensor_dim Tensor dimension
*/
+
tensor_dim * gst_get_tensordim (GstBuffer *buffer, gint nth);
/**
+ * @brief Utility function to get nth tensor type
+ * @param buffer Target GstBuffer Object
+ * @param nth order of tensor
+ * @return tensor_type Tensor type
+ */
+tensor_type gst_get_tensortype (GstBuffer *buffer, gint nth);
+
+/**
* @brief Utility function to remove nth tensor from tensors
* @param buffer Target GstBuffer Object
* @param nth order of tensor
G_END_DECLS
-#endif /* __GST_TENSOR_META_H__ */
+#endif /** __GST_TENSOR_META_H__ */
-/*
+/**
* GStreamer
* Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
* Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* @brief test element to check tensors
* @see http://github.com/TO-BE-DETERMINED-SOON
* @see https://github.sec.samsung.net/STAR/nnstreamer
+ * @bug no known bugs
* @author Jijoong Moon <jijoong.moon@samsung.com>
*
*/
GST_DEBUG_CATEGORY_STATIC (gst_tensorscheck_debug);
#define GST_CAT_DEFAULT gst_tensorscheck_debug
-/* Filter signals and args */
+/** Filter signals and args */
enum
{
- /* FILL ME */
+ /** FILL ME */
LAST_SIGNAL
};
PROP_SILENT
};
-/* the capabilities of the inputs and outputs.
+/** the capabilities of the inputs and outputs.
*
* describe the real formats here.
*/
static GstFlowReturn gst_tensorscheck_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf);
-/* GObject vmethod implementations */
+/** GObject vmethod implementations */
-/* initialize the tensorscheck's class */
+/**
+ * @brief initialize the tensorscheck's class
+ */
static void
gst_tensorscheck_class_init (GsttensorscheckClass * klass)
{
gst_static_pad_template_get (&sink_factory));
}
-/* initialize the new element
+/**
+ * @brief initialize the new element
* instantiate pads and add them to element
* set pad calback functions
* initialize instance structure
filter->silent = FALSE;
}
+/**
+ * @brief set property vmthod
+ */
static void
gst_tensorscheck_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
}
}
+/**
+ * @brief get property vmthod
+ */
static void
gst_tensorscheck_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
}
-/* entry point to initialize the plug-in
+/**
+ * @brief entry point to initialize the plug-in
* initialize the plug-in itself
* register the element factories and other features
*/
static gboolean
tensorscheck_init (GstPlugin * tensorscheck)
{
- /* debug category for fltering log messages
+ /** debug category for fltering log messages
*
* exchange the string 'Template tensorscheck' with your description
*/
GST_TYPE_TENSORSCHECK);
}
-/* PACKAGE: this is usually set by autotools depending on some _INIT macro
+/** 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.
#define PACKAGE "tensorscheck"
#endif
-/* gstreamer looks for this structure to register tensorschecks
+/** gstreamer looks for this structure to register tensorschecks
*
* exchange the string 'Template tensorscheck' with your tensorscheck description
*/
"Template tensorscheck",
tensorscheck_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
-/*
+/**
* @brief Set Caps in pad.
* @param filter Gsttensorscheck instance
* @param caps incomming capablity
return ret;
}
-/*
+/**
* @brief make GstBuffer for output tensor.
* @param filter Gsttensorscheck
* @param inbuf incomming GstBuffer. (tensors)
unsigned int d0, d1, d2, i;
gboolean ret;
- /* Mapping input buffer (tensors) into src_info */
+ /** Mapping input buffer (tensors) into src_info */
gst_buffer_map (inbuf, &src_info, GST_MAP_READ);
- /* Making output GstBuffer */
+ /** Making output GstBuffer */
outbuf = gst_buffer_new ();
- /* Making output buffer (one big buffer for check tensors) */
+ /** Making output buffer (one big buffer for check tensors) */
buffer_mem = gst_allocator_alloc (NULL,
- /* filter->dimension[0] * filter->dimension[1] * filter->dimension[2] * */
- /* filter->dimension[3], NULL); */
+ /** filter->dimension[0] * filter->dimension[1] * filter->dimension[2] * */
+ /** filter->dimension[3], NULL); */
3 * 640 * 480 * 1, NULL);
gst_buffer_append_memory (outbuf, buffer_mem);
gst_buffer_map (outbuf, &dest_info, GST_MAP_WRITE);
- /* Get number of tensors */
+ /** Get number of tensors */
num_tensors = gst_get_num_tensors (inbuf);
debug_print (!filter->silent, "Number of Tensors : %d\n", num_tensors);
for (i = 0; i < num_tensors; i++) {
return outbuf;
}
-/* GstElement vmethod implementations */
+/** GstElement vmethod implementations */
-/* this function handles sink events */
+/**
+ * @brief this function handles sink events
+ */
static gboolean
gst_tensorscheck_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
return ret;
}
-/* chain function
+/**
+ * @brief chain function
* this function does the actual processing
*/
static GstFlowReturn
-/*
+/**
* GStreamer
* Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
* Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* @brief Element to test tensors (witch generates tensors)
* @see http://github.com/TO-BE-DETERMINED-SOON
* @see https://github.sec.samsung.net/STAR/nnstreamer
+ * @bug no known bugs
* @author Jijoong Moon <jijoong.moon@samsung.com>
*
*/
GST_DEBUG_CATEGORY_STATIC (gst_testtensors_debug);
#define GST_CAT_DEFAULT gst_testtensors_debug
-/* Filter signals and args */
+/** Filter signals and args */
enum
{
- /* FILL ME */
+ /** FILL ME */
LAST_SIGNAL
};
PROP_SILENT
};
-/* the capabilities of the inputs and outputs.
+/** the capabilities of the inputs and outputs.
*
* describe the real formats here.
*/
static GstFlowReturn gst_testtensors_chain (GstPad * pad, GstObject * parent,
GstBuffer * buf);
-/* GObject vmethod implementations */
+/** GObject vmethod implementations */
-/* initialize the testtensors's class */
+/**
+ * @brief initialize the testtensors's class
+ */
static void
gst_testtensors_class_init (GsttesttensorsClass * klass)
{
gst_static_pad_template_get (&sink_factory));
}
-/* initialize the new element
+/**
+ * @brief initialize the new element
* instantiate pads and add them to element
* set pad calback functions
* initialize instance structure
filter->silent = FALSE;
}
+/**
+ * @brief Set property vmethod
+ */
static void
gst_testtensors_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
}
}
+/**
+ * @brief Get property vmethod
+ */
static void
gst_testtensors_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
}
}
-/* entry point to initialize the plug-in
+/**
+ * @brief entry point to initialize the plug-in
* initialize the plug-in itself
* register the element factories and other features
*/
static gboolean
testtensors_init (GstPlugin * testtensors)
{
- /* debug category for fltering log messages
+ /** debug category for fltering log messages
*
* exchange the string 'Template testtensors' with your description
*/
GST_TYPE_TESTTENSORS);
}
-/* PACKAGE: this is usually set by autotools depending on some _INIT macro
+/** 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.
#define PACKAGE "testtensors"
#endif
-/* gstreamer looks for this structure to register testtensorss
+/** gstreamer looks for this structure to register testtensorss
*
* exchange the string 'Template testtensors' with your testtensors description
*/
"Template testtensors",
testtensors_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")
-/*
+/**
* @brief Set Caps in pad.
* @param filter Gsttesttensors instance
* @param caps incomming capablity
return ret;
}
-/*
+/**
* @brief make GstBuffer for output tensor.
* @param filter Gsttesttensors
* @param inbuf incomming GstBuffer. (x-raw)
dim[3] = 1;
gst_memory_unmap (mem, &info);
- gst_append_tensor (outbuf, mem, &dim);
+ gst_append_tensor (outbuf, mem, dim, filter->type);
}
gst_buffer_unmap (inbuf, &src_info);
return outbuf;
}
-/* GstElement vmethod implementations */
+/** GstElement vmethod implementations */
-/* this function handles sink events */
+/**
+ * @brief this function handles sink events
+ */
static gboolean
gst_testtensors_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
return ret;
}
-/* chain function
+/**
+ * @brief chain function
* this function does the actual processing
*/
static GstFlowReturn
filter = GST_TESTTENSORS (parent);
- /* just push out the incoming buffer without touching it */
+ /** just push out the incoming buffer without touching it */
if (filter->passthrough)
return gst_pad_push (filter->srcpad, buf);
gst_buffer_unref (buf);
- /* In order to keep the data in outbuffer, we have to increase buffer ref count */
+ /** In order to keep the data in outbuffer, we have to increase buffer ref count */
gst_buffer_ref (out);
return gst_pad_push (filter->srcpad, out);