Doxygen Book
gsttensor_split.c
Go to the documentation of this file.
1 
47 #ifdef HAVE_CONFIG_H
48 #include <config.h>
49 #endif
50 
51 #include <string.h>
52 #include <gst/gst.h>
53 #include <glib.h>
54 
55 #include "gsttensor_split.h"
56 #include <tensor_common.h>
57 #include <nnstreamer_util.h>
58 
59 GST_DEBUG_CATEGORY_STATIC (gst_tensor_split_debug);
60 #define GST_CAT_DEFAULT gst_tensor_split_debug
61 
62 enum
63 {
68 };
69 
73 #define CAPS_STRING GST_TENSOR_CAP_DEFAULT ";" GST_TENSORS_CAP_WITH_NUM ("1")
74 
79 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src_%u",
80  GST_PAD_SRC,
81  GST_PAD_SOMETIMES,
82  GST_STATIC_CAPS (CAPS_STRING));
83 
84 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
85  GST_PAD_SINK,
86  GST_PAD_ALWAYS,
87  GST_STATIC_CAPS (CAPS_STRING));
88 
89 static GstFlowReturn gst_tensor_split_chain (GstPad * pad, GstObject * parent,
90  GstBuffer * buf);
91 static gboolean gst_tensor_split_event (GstPad * pad, GstObject * parent,
92  GstEvent * event);
93 static GstStateChangeReturn gst_tensor_split_change_state (GstElement * element,
94  GstStateChange transition);
95 static void gst_tensor_split_set_property (GObject * object, guint prop_id,
96  const GValue * value, GParamSpec * pspec);
97 static void gst_tensor_split_get_property (GObject * object, guint prop_id,
98  GValue * value, GParamSpec * pspec);
99 static void gst_tensor_split_finalize (GObject * object);
100 
101 #define gst_tensor_split_parent_class parent_class
102 G_DEFINE_TYPE (GstTensorSplit, gst_tensor_split, GST_TYPE_ELEMENT);
103 
104 
108 static void
110 {
111  GObjectClass *gobject_class;
112  GstElementClass *gstelement_class;
113 
114  GST_DEBUG_CATEGORY_INIT (gst_tensor_split_debug, "tensor_split", 0,
115  "Element to split tensors stream to tensor stream");
116 
117  gobject_class = (GObjectClass *) klass;
118  gstelement_class = (GstElementClass *) klass;
119 
120  parent_class = g_type_class_peek_parent (klass);
121 
122  gobject_class->finalize = gst_tensor_split_finalize;
123  gobject_class->get_property = gst_tensor_split_get_property;
124  gobject_class->set_property = gst_tensor_split_set_property;
125 
126  g_object_class_install_property (gobject_class, PROP_SILENT,
127  g_param_spec_boolean ("silent", "Silent",
128  "Do not produce verbose output ?", TRUE, G_PARAM_READWRITE));
129 
130  g_object_class_install_property (gobject_class, PROP_TENSORPICK,
131  g_param_spec_string ("tensorpick", "TensorPick",
132  "Choose nth tensor among tensors ?", "", G_PARAM_READWRITE));
133 
134  g_object_class_install_property (gobject_class, PROP_TENSORSEG,
135  g_param_spec_string ("tensorseg", "TensorSeg",
136  "How to split tensor ?", "", G_PARAM_READWRITE));
137 
138  gstelement_class->change_state =
139  GST_DEBUG_FUNCPTR (gst_tensor_split_change_state);
140 
141  gst_element_class_add_pad_template (gstelement_class,
142  gst_static_pad_template_get (&sink_templ));
143  gst_element_class_add_pad_template (gstelement_class,
144  gst_static_pad_template_get (&src_templ));
145 
146  gst_element_class_set_details_simple (gstelement_class,
147  "TensorSplit",
148  "Demuxer/Tensor",
149  "Split tensor stream to other/tensor stream",
150  "Jijoong Moon <jijoong.moon@samsung.com>");
151 }
152 
159 static void
161 {
162  split->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
163  gst_element_add_pad (GST_ELEMENT_CAST (split), split->sinkpad);
164  gst_pad_set_chain_function (split->sinkpad,
165  GST_DEBUG_FUNCPTR (gst_tensor_split_chain));
166  gst_pad_set_event_function (split->sinkpad,
167  GST_DEBUG_FUNCPTR (gst_tensor_split_event));
168 
169  split->num_tensors = 0;
170  split->num_srcpads = 0;
171  split->silent = TRUE;
172  split->tensorpick = NULL;
173  split->tensorseg = NULL;
174  split->have_group_id = FALSE;
175  split->group_id = G_MAXUINT;
176  split->srcpads = NULL;
178 }
179 
183 static void
185 {
186  while (split->srcpads != NULL) {
187  GstTensorPad *tensor_pad = split->srcpads->data;
188  gst_element_remove_pad (GST_ELEMENT (split), tensor_pad->pad);
189  g_free (tensor_pad);
190  split->srcpads = g_slist_delete_link (split->srcpads, split->srcpads);
191  }
192  split->srcpads = NULL;
193  split->num_tensors = 0;
194  split->num_srcpads = 0;
196 }
197 
201 static void
202 gst_tensor_split_finalize (GObject * object)
203 {
204  GstTensorSplit *split;
205 
206  split = GST_TENSOR_SPLIT (object);
208  g_list_free (split->tensorpick);
209  g_array_free (split->tensorseg, TRUE);
210  G_OBJECT_CLASS (parent_class)->finalize (object);
211 }
212 
216 static gboolean
217 gst_tensor_split_event (GstPad * pad, GstObject * parent, GstEvent * event)
218 {
219  GstTensorSplit *split;
220 
221  split = GST_TENSOR_SPLIT (parent);
222 
223  switch (GST_EVENT_TYPE (event)) {
224  case GST_EVENT_CAPS:
225  {
226  GstCaps *caps;
227  gst_event_parse_caps (event, &caps);
228  if (!gst_tensors_config_from_cap (&split->sink_tensor_conf, caps)) {
229  GST_ELEMENT_ERROR (split, STREAM, WRONG_TYPE,
230  ("This stream contains no valid type."), NULL);
231  }
232  break;
233  }
234  case GST_EVENT_EOS:
235  if (!split->srcpads) {
236  GST_ELEMENT_ERROR (split, STREAM, WRONG_TYPE,
237  ("This stream contains no valid stremas."),
238  ("Got EOS before adding any pads"));
239  gst_event_unref (event);
240  return FALSE;
241  }
242  break;
243  default:
244  break;
245  }
246 
247  return gst_pad_event_default (pad, parent, event);
248 }
249 
259 static GstTensorPad *
261  gboolean * created, guint nth)
262 {
263  GstElement *element = GST_ELEMENT_CAST (split);
264  g_autofree gchar *element_name = gst_element_get_name (element);
265  GSList *walk;
266  GstPad *pad;
267  GstTensorPad *tensorpad;
268  gchar *name;
269  GstEvent *event;
270  gchar *stream_id;
271  GstCaps *caps;
272  GstTensorsConfig pad_config;
273  tensor_dim *dim;
274  guint i;
275  UNUSED (inbuf);
276 
277  walk = split->srcpads;
278  while (walk) {
279  GstTensorPad *pad = (GstTensorPad *) walk->data;
280  if (nth == pad->nth) {
281  if (created) {
282  *created = FALSE;
283  }
284  return pad;
285  }
286  walk = g_slist_next (walk);
287  }
288 
289  tensorpad = g_new0 (GstTensorPad, 1);
290  g_assert (tensorpad != NULL);
291  GST_DEBUG_OBJECT (split, "creating pad: %d(%dth)", split->num_srcpads, nth);
292 
293  name = g_strdup_printf ("src_%u", split->num_srcpads);
294  pad = gst_pad_new_from_static_template (&src_templ, name);
295  stream_id = gst_pad_create_stream_id_printf (pad, element,
296  "%s-nnssplit-%s-%08x", element_name, name, g_random_int ());
297  g_free (name);
298 
299  tensorpad->pad = pad;
300  tensorpad->nth = nth;
301  tensorpad->last_ret = GST_FLOW_OK;
302  tensorpad->last_ts = GST_CLOCK_TIME_NONE;
303 
304  split->srcpads = g_slist_append (split->srcpads, tensorpad);
305  dim = g_array_index (split->tensorseg, tensor_dim *, split->num_srcpads);
306 
307  split->num_srcpads++;
308 
309  gst_pad_use_fixed_caps (pad);
310  gst_pad_set_active (pad, TRUE);
311 
312  if (!split->have_group_id) {
313  event =
314  gst_pad_get_sticky_event (split->sinkpad, GST_EVENT_STREAM_START, 0);
315  if (event) {
316  split->have_group_id = gst_event_parse_group_id (event, &split->group_id);
317  gst_event_unref (event);
318  } else if (!split->have_group_id) {
319  split->have_group_id = TRUE;
320  split->group_id = gst_util_group_id_next ();
321  }
322  }
323 
324  event = gst_event_new_stream_start (stream_id);
325  if (split->have_group_id)
326  gst_event_set_group_id (event, split->group_id);
327 
328  gst_pad_store_sticky_event (pad, event);
329  g_free (stream_id);
330  gst_event_unref (event);
331 
332  /* tensor config to set caps */
333  gst_tensors_config_init (&pad_config);
334  pad_config.info.num_tensors = 1;
335  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
336  pad_config.info.info[0].dimension[i] = (*dim)[i];
337  }
338  pad_config.info.info[0].type = split->sink_tensor_conf.info.info[0].type;
339  pad_config.rate_n = split->sink_tensor_conf.rate_n;
340  pad_config.rate_d = split->sink_tensor_conf.rate_d;
341 
342  caps = gst_tensor_pad_caps_from_config (pad, &pad_config);
343 
344  gst_pad_set_caps (pad, caps);
345  gst_element_add_pad (GST_ELEMENT_CAST (split), pad);
346 
347  gst_caps_unref (caps);
348 
349  if (created) {
350  *created = TRUE;
351  }
352 
353  if (split->tensorpick != NULL) {
354  GST_DEBUG_OBJECT (split, "TensorPick is set! : %dth tensor\n", nth);
355  if (g_list_length (split->tensorpick) == split->num_srcpads) {
356  gst_element_no_more_pads (GST_ELEMENT_CAST (split));
357  }
358  }
359 
360  return tensorpad;
361 }
362 
370 static GstFlowReturn
372  GstTensorPad * pad, GstFlowReturn ret)
373 {
374  GSList *walk;
375  GstTensorPad *opad;
376 
377  pad->last_ret = ret;
378  if (ret != GST_FLOW_NOT_LINKED)
379  goto done;
380 
381  for (walk = split->srcpads; walk; walk = g_slist_next (walk)) {
382  opad = (GstTensorPad *) walk->data;
383  ret = opad->last_ret;
384  if (ret != GST_FLOW_NOT_LINKED)
385  goto done;
386  }
387 done:
388  return ret;
389 }
390 
398 static GstMemory *
399 gst_tensor_split_get_splitted (GstTensorSplit * split, GstBuffer * buffer,
400  gint nth)
401 {
402  GstMemory *mem;
403  tensor_dim *dim;
404  int i;
405  gsize size, offset;
406  GstMapInfo src_info, dest_info;
407 
408  dim = g_array_index (split->tensorseg, tensor_dim *, nth);
409  size = gst_tensor_get_element_count (*dim) *
411 
412  mem = gst_allocator_alloc (NULL, size, NULL);
413  if (!gst_memory_map (mem, &dest_info, GST_MAP_WRITE)) {
414  ml_logf ("Cannot map memory for destination buffer.\n");
415  gst_memory_unref (mem);
416  return NULL;
417  }
418  if (!gst_buffer_map (buffer, &src_info, GST_MAP_READ)) {
419  ml_logf ("Cannot map src-memory to gst buffer at tensor-split.\n");
420  gst_memory_unmap (mem, &dest_info);
421  gst_memory_unref (mem);
422  return NULL;
423  }
424 
425  offset = 0;
426  for (i = 0; i < nth; i++) {
427  dim = g_array_index (split->tensorseg, tensor_dim *, i);
428  offset += gst_tensor_get_element_count (*dim) *
430  }
431 
432  nns_memcpy (dest_info.data, src_info.data + offset, size);
433  gst_buffer_unmap (buffer, &src_info);
434  gst_memory_unmap (mem, &dest_info);
435 
436  return mem;
437 }
438 
442 static GstFlowReturn
443 gst_tensor_split_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
444 {
445  GstTensorSplit *split;
446  guint num_tensors, i;
447  GstFlowReturn res = GST_FLOW_OK;
448  UNUSED (pad);
449 
450  split = GST_TENSOR_SPLIT (parent);
451 
452  num_tensors = split->num_tensors;
453  GST_DEBUG_OBJECT (split, " Number of Tensors: %d", num_tensors);
454 
455  if (split->tensorseg == NULL) {
456  GST_ERROR_OBJECT (split, "No rule to split incoming buffers.");
457  return GST_FLOW_ERROR;
458  }
459 
460  for (i = 0; i < num_tensors; i++) {
461  GstTensorPad *srcpad;
462  GstBuffer *outbuf;
463  GstMemory *mem;
464  gboolean created;
465  GstClockTime ts;
466 
467  if (split->tensorpick != NULL) {
468  gboolean found = FALSE;
469  GList *list;
470  for (list = split->tensorpick; list != NULL; list = list->next) {
471  if (i == GPOINTER_TO_UINT (list->data)) {
472  found = TRUE;
473  break;
474  }
475  }
476  if (!found)
477  continue;
478  }
479 
480  srcpad = gst_tensor_split_get_tensor_pad (split, buf, &created, i);
481 
482  outbuf = gst_buffer_new ();
483  mem = gst_tensor_split_get_splitted (split, buf, i);
484  gst_buffer_append_memory (outbuf, mem);
485  ts = GST_BUFFER_TIMESTAMP (buf);
486 
487  if (created) {
488  GstSegment segment;
489  gst_segment_init (&segment, GST_FORMAT_TIME);
490  gst_pad_push_event (srcpad->pad, gst_event_new_segment (&segment));
491  }
492 
493  outbuf = gst_buffer_make_writable (outbuf);
494 
495  /* metadata from incoming buffer */
496  gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1);
497 
498  if (srcpad->last_ts == GST_CLOCK_TIME_NONE || srcpad->last_ts != ts) {
499  srcpad->last_ts = ts;
500  } else {
501  GST_DEBUG_OBJECT (split, "invalid timestamp %" GST_TIME_FORMAT,
502  GST_TIME_ARGS (ts));
503  }
504 
505  GST_DEBUG_OBJECT (split, "pushing buffer with timestamp %" GST_TIME_FORMAT,
506  GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
507  res = gst_pad_push (srcpad->pad, outbuf);
508  res = gst_tensor_split_combine_flows (split, srcpad, res);
509  if (res != GST_FLOW_OK)
510  break;
511  }
512 
513  gst_buffer_unref (buf);
514  return res;
515 }
516 
520 static GstStateChangeReturn
521 gst_tensor_split_change_state (GstElement * element, GstStateChange transition)
522 {
523  GstTensorSplit *split;
524  GstStateChangeReturn ret;
525 
526  split = GST_TENSOR_SPLIT (element);
527 
528  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
529  if (ret == GST_STATE_CHANGE_FAILURE)
530  return ret;
531 
532  switch (transition) {
533  case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
534  break;
535  case GST_STATE_CHANGE_PAUSED_TO_READY:
536  split->group_id = G_MAXUINT;
537  split->have_group_id = FALSE;
539  break;
540  case GST_STATE_CHANGE_READY_TO_NULL:
541  break;
542  default:
543  break;
544  }
545 
546  return ret;
547 }
548 
552 static void
554 {
555  g_free (*element);
556 }
557 
561 static void
562 gst_tensor_split_set_property (GObject * object, guint prop_id,
563  const GValue * value, GParamSpec * pspec)
564 {
565  GstTensorSplit *split;
566 
567  split = GST_TENSOR_SPLIT (object);
568 
569  switch (prop_id) {
570  case PROP_SILENT:
571  split->silent = g_value_get_boolean (value);
572  break;
573  case PROP_TENSORPICK:
574  {
575  gint i;
576  gint64 val;
577  const gchar *param = g_value_get_string (value);
578  gchar **strv = g_strsplit_set (param, ",.;/", -1);
579  gint num = g_strv_length (strv);
580  for (i = 0; i < num; i++) {
581  val = g_ascii_strtoll (strv[i], NULL, 10);
582  split->tensorpick =
583  g_list_append (split->tensorpick, GINT_TO_POINTER (val));
584  }
585  g_strfreev (strv);
586  break;
587  }
588  case PROP_TENSORSEG:
589  {
590  guint i;
591  const gchar *param = g_value_get_string (value);
592  gchar **strv = g_strsplit_set (param, ",.;/", -1);
593  GArray *tensorseg = split->tensorseg;
594 
595  split->num_tensors = g_strv_length (strv);
596  if (NULL == tensorseg) {
597  split->tensorseg =
598  g_array_sized_new (FALSE, FALSE, sizeof (tensor_dim *),
599  split->num_tensors);
600  g_array_set_clear_func (split->tensorseg,
601  (GDestroyNotify) _clear_tensorseg);
602 
603  for (i = 0; i < split->num_tensors; i++) {
604  tensor_dim *d = g_new0 (tensor_dim, 1);
605  g_array_append_val (split->tensorseg, d);
606  }
607  tensorseg = split->tensorseg;
608  }
609  for (i = 0; i < split->num_tensors; i++) {
610  gchar **p;
611  gint num, k;
612  tensor_dim *d;
613  p = g_strsplit_set (strv[i], ":", -1);
614  num = g_strv_length (p);
615 
616  d = g_array_index (tensorseg, tensor_dim *, i);
617 
618  for (k = 0; k < num; k++) {
619  (*d)[k] = g_ascii_strtod (p[k], NULL);
620  }
621 
622  g_strfreev (p);
623  }
624  g_strfreev (strv);
625  break;
626  }
627  default:
628  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
629  break;
630  }
631 }
632 
636 static void
637 gst_tensor_split_get_property (GObject * object, guint prop_id,
638  GValue * value, GParamSpec * pspec)
639 {
640  GstTensorSplit *split;
641 
642  split = GST_TENSOR_SPLIT (object);
643 
644  switch (prop_id) {
645  case PROP_SILENT:
646  g_value_set_boolean (value, split->silent);
647  break;
648  case PROP_TENSORPICK:
649  {
650  GList *list;
651  char *p;
652  GPtrArray *arr = g_ptr_array_new ();
653  gchar **strings;
654 
655  for (list = split->tensorpick; list != NULL; list = list->next) {
656  g_ptr_array_add (arr, g_strdup_printf ("%i",
657  GPOINTER_TO_INT (list->data)));
658  }
659  g_ptr_array_add (arr, NULL);
660  strings = (gchar **) g_ptr_array_free (arr, FALSE);
661  p = g_strjoinv (",", strings);
662  g_strfreev (strings);
663  g_value_take_string (value, p);
664  break;
665  }
666  case PROP_TENSORSEG:
667  {
668  if ((split->tensorseg) && (split->tensorseg->len > 0)) {
669  tensor_dim *dim = NULL;
670  gchar *strv = NULL;
671  guint i, j;
672 
673 
674  for (i = 0; i < split->tensorseg->len; i++) {
675  GPtrArray *arr = g_ptr_array_new ();
676  gchar *p = NULL;
677  gchar **strings;
678 
679  dim = g_array_index (split->tensorseg, tensor_dim *, i);
680  for (j = 0; j < NNS_TENSOR_RANK_LIMIT; j++) {
681  g_ptr_array_add (arr, g_strdup_printf ("%i", (*dim)[j]));
682  }
683  g_ptr_array_add (arr, NULL);
684  strings = (gchar **) g_ptr_array_free (arr, FALSE);
685  p = g_strjoinv (":", strings);
686  g_strfreev (strings);
687  if (i > 0) {
692  gchar *oldstrv = strv;
693 
694  strv = g_strjoin (",", strv, p, NULL);
695  g_free (oldstrv);
696  g_free (p);
697  } else {
698  strv = p;
699  }
700  }
701  /* the second parameter, strv (i.e., gchar *v_string), is nullable */
702  g_value_take_string (value, strv ? strv : g_strdup (""));
703  } else {
704  g_value_set_string (value, "");
705  }
706  break;
707  }
708  default:
709  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
710  break;
711  }
712 }
gst_tensor_split_chain
static GstFlowReturn gst_tensor_split_chain(GstPad *pad, GstObject *parent, GstBuffer *buf)
chain function for sink (gst element vmethod)
Definition: gsttensor_split.c:443
g_assert
g_assert(sizeof(DTYPE_UNSIGNED)==sizeof(DTYPE_SIGNED))
tensor_dim
uint32_t tensor_dim[NNS_TENSOR_RANK_LIMIT]
Definition: tensor_typedef.h:247
GstTensorPad
Internal data structure for pad in demux / split.
Definition: tensor_common.h:102
FALSE
return FALSE
Definition: gsttensor_transform.c:596
_GstTensorSplit::num_srcpads
guint32 num_srcpads
Definition: gsttensor_split.h:58
ml_logf
#define ml_logf
Definition: nnstreamer_log.h:80
gst_tensor_split_set_property
static void gst_tensor_split_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
Get property (gst element vmethod)
Definition: gsttensor_split.c:562
PROP_SILENT
@ PROP_SILENT
Definition: gsttensor_split.c:65
PROP_TENSORSEG
@ PROP_TENSORSEG
Definition: gsttensor_split.c:67
gst_tensor_pad_caps_from_config
GstCaps * gst_tensor_pad_caps_from_config(GstPad *pad, const GstTensorsConfig *config)
Get pad caps from tensors config and caps of the peer connected to the pad.
Definition: nnstreamer_plugin_api_impl.c:1209
nns_memcpy
#define nns_memcpy
Definition: tensor_common.h:52
_GstTensorSplit::sinkpad
GstPad * sinkpad
Definition: gsttensor_split.h:55
PROP_TENSORPICK
@ PROP_TENSORPICK
Definition: gsttensor_split.c:66
gst_tensor_split_combine_flows
static GstFlowReturn gst_tensor_split_combine_flows(GstTensorSplit *split, GstTensorPad *pad, GstFlowReturn ret)
Check the status among sources in split.
Definition: gsttensor_split.c:371
GstTensorsConfig::rate_d
int rate_d
Definition: tensor_typedef.h:288
src_templ
static GstStaticPadTemplate src_templ
the capabilities of the inputs and outputs. describe the real formats here.
Definition: gsttensor_split.c:79
GstTensorPad::last_ts
GstClockTime last_ts
Definition: tensor_common.h:105
_GstTensorSplit::tensorseg
GArray * tensorseg
Definition: gsttensor_split.h:60
gst_tensor_split_finalize
static void gst_tensor_split_finalize(GObject *object)
finalize function for tensor split (gst element vmethod)
Definition: gsttensor_split.c:202
gsttensor_split.h
GStreamer plugin to split tensor (as a filter for other general neural network filters)
GST_TENSOR_SPLIT
#define GST_TENSOR_SPLIT(obj)
Definition: gsttensor_split.h:37
g_free
g_free(self->option[(opnum) - 1])
opnum: \
g_value_set_string
g_value_set_string(value, self->option[opnum - 1])
opnum: \
GstTensorsConfig::rate_n
int rate_n
Definition: tensor_typedef.h:287
_GstTensorSplit::have_group_id
gboolean have_group_id
Definition: gsttensor_split.h:61
sink_templ
static GstStaticPadTemplate sink_templ
Definition: gsttensor_split.c:84
GstTensorsInfo::info
GstTensorInfo info[NNS_TENSOR_MEMORY_MAX]
Definition: tensor_typedef.h:276
gst_tensor_get_element_count
gulong gst_tensor_get_element_count(const tensor_dim dim)
Count the number of elements of a tensor.
Definition: nnstreamer_plugin_api_util_impl.c:1186
gst_tensor_get_element_size
gsize gst_tensor_get_element_size(tensor_type type)
Get element size of tensor type (byte per element)
Definition: nnstreamer_plugin_api_util_impl.c:1205
gst_tensor_split_get_property
static void gst_tensor_split_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
Get property (gst element vmethod)
Definition: gsttensor_split.c:637
gst_tensors_config_free
void gst_tensors_config_free(GstTensorsConfig *config)
Free allocated data in tensors config structure.
Definition: nnstreamer_plugin_api_util_impl.c:845
GstTensorsConfig
Internal data structure for configured tensors info (for other/tensors).
Definition: tensor_typedef.h:284
gst_tensor_split_init
static void gst_tensor_split_init(GstTensorSplit *split)
initialize the new element instantiate pads and add them to element set pad callback functions initia...
Definition: gsttensor_split.c:160
_GstTensorSplit::silent
gboolean silent
Definition: gsttensor_split.h:54
_GstTensorSplit
Tensor Split data structure.
Definition: gsttensor_split.h:50
_GstTensorSplit::group_id
guint group_id
Definition: gsttensor_split.h:62
TRUE
return TRUE
Definition: gsttensor_if.c:879
UNUSED
#define UNUSED(expr)
Definition: mqttcommon.h:19
_GstTensorSplit::sink_tensor_conf
GstTensorsConfig sink_tensor_conf
Definition: gsttensor_split.h:63
nnstreamer_util.h
Optional NNStreamer utility functions for sub-plugin writers and users.
CAPS_STRING
#define CAPS_STRING
Template caps string.
Definition: gsttensor_split.c:73
gst_tensor_split_remove_src_pads
static void gst_tensor_split_remove_src_pads(GstTensorSplit *split)
function to remove srcpad list
Definition: gsttensor_split.c:184
gst_tensor_split_event
static gboolean gst_tensor_split_event(GstPad *pad, GstObject *parent, GstEvent *event)
event function for sink (gst element vmethod)
Definition: gsttensor_split.c:217
GstTensorPad::pad
GstPad * pad
Definition: tensor_common.h:104
GST_DEBUG_CATEGORY_STATIC
GST_DEBUG_CATEGORY_STATIC(gst_tensor_split_debug)
G_DEFINE_TYPE
G_DEFINE_TYPE(GstTensorSplit, gst_tensor_split, GST_TYPE_ELEMENT)
tensor_common.h
Common header file for NNStreamer, the GStreamer plugin for neural networks.
GstTensorPad::nth
guint nth
Definition: tensor_common.h:107
gst_tensors_config_from_cap
gboolean gst_tensors_config_from_cap(GstTensorsConfig *config, const GstCaps *caps)
Parse caps and set tensors config (for other/tensors)
Definition: nnstreamer_plugin_api_impl.c:1509
_GstTensorSplitClass
GstTensorSplitClass inherits GstElementClass.
Definition: gsttensor_split.h:69
GstTensorsInfo::num_tensors
unsigned int num_tensors
Definition: tensor_typedef.h:275
_GstTensorSplit::srcpads
GSList * srcpads
Definition: gsttensor_split.h:56
_GstTensorSplit::num_tensors
guint32 num_tensors
Definition: gsttensor_split.h:57
gst_tensors_config_init
void gst_tensors_config_init(GstTensorsConfig *config)
Initialize the tensors config info structure (for other/tensors)
Definition: nnstreamer_plugin_api_util_impl.c:830
gst_tensor_split_change_state
static GstStateChangeReturn gst_tensor_split_change_state(GstElement *element, GstStateChange transition)
change state (gst element vmethod)
Definition: gsttensor_split.c:521
GstTensorInfo::type
tensor_type type
Definition: tensor_typedef.h:266
GstTensorsConfig::info
GstTensorsInfo info
Definition: tensor_typedef.h:286
_clear_tensorseg
static void _clear_tensorseg(tensor_dim **element)
Glib Array Clear Function.
Definition: gsttensor_split.c:553
GstTensorInfo::dimension
tensor_dim dimension
Definition: tensor_typedef.h:267
NNS_TENSOR_RANK_LIMIT
#define NNS_TENSOR_RANK_LIMIT
Definition: tensor_typedef.h:34
gst_tensor_split_class_init
static void gst_tensor_split_class_init(GstTensorSplitClass *klass)
initialize the tensor_split's class
Definition: gsttensor_split.c:109
GstTensorPad::last_ret
GstFlowReturn last_ret
Definition: tensor_common.h:106
if
if(!gst_tensordec_process_plugin_options(self,(opnum) - 1)) GST_ERROR_OBJECT(self
gst_tensor_split_get_tensor_pad
static GstTensorPad * gst_tensor_split_get_tensor_pad(GstTensorSplit *split, GstBuffer *inbuf, gboolean *created, guint nth)
Checking if the source pad is created and if not, create TensorPad.
Definition: gsttensor_split.c:260
_GstTensorSplit::tensorpick
GList * tensorpick
Definition: gsttensor_split.h:59
gst_tensor_split_get_splitted
static GstMemory * gst_tensor_split_get_splitted(GstTensorSplit *split, GstBuffer *buffer, gint nth)
Make splitted tensor.
Definition: gsttensor_split.c:399
PROP_0
@ PROP_0
Definition: gsttensor_split.c:64