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 
219 static gboolean
221 {
222  GstStructure *st;
223 
224  st = gst_caps_get_structure (caps, 0);
225 
227 }
228 
232 static gboolean
233 gst_tensor_split_event (GstPad * pad, GstObject * parent, GstEvent * event)
234 {
235  GstTensorSplit *split;
236 
237  split = GST_TENSOR_SPLIT (parent);
238 
239  switch (GST_EVENT_TYPE (event)) {
240  case GST_EVENT_CAPS:
241  {
242  GstCaps *caps;
243  gst_event_parse_caps (event, &caps);
244  if (!gst_tensor_split_get_capsparam (split, caps)) {
245  GST_ELEMENT_ERROR (split, STREAM, WRONG_TYPE,
246  ("This stream contains no valid type."), NULL);
247  }
248  break;
249  }
250  case GST_EVENT_EOS:
251  if (!split->srcpads) {
252  GST_ELEMENT_ERROR (split, STREAM, WRONG_TYPE,
253  ("This stream contains no valid stremas."),
254  ("Got EOS before adding any pads"));
255  gst_event_unref (event);
256  return FALSE;
257  }
258  break;
259  default:
260  break;
261  }
262 
263  return gst_pad_event_default (pad, parent, event);
264 }
265 
275 static GstTensorPad *
277  gboolean * created, guint nth)
278 {
279  GstElement *element = GST_ELEMENT_CAST (split);
280  g_autofree gchar *element_name = gst_element_get_name (element);
281  GSList *walk;
282  GstPad *pad;
283  GstTensorPad *tensorpad;
284  gchar *name;
285  GstEvent *event;
286  gchar *stream_id;
287  GstCaps *caps;
288  GstTensorsConfig pad_config;
289  tensor_dim *dim;
290  guint i;
291  UNUSED (inbuf);
292 
293  walk = split->srcpads;
294  while (walk) {
295  GstTensorPad *pad = (GstTensorPad *) walk->data;
296  if (nth == pad->nth) {
297  if (created) {
298  *created = FALSE;
299  }
300  return pad;
301  }
302  walk = g_slist_next (walk);
303  }
304 
305  tensorpad = g_new0 (GstTensorPad, 1);
306  g_assert (tensorpad != NULL);
307  GST_DEBUG_OBJECT (split, "creating pad: %d(%dth)", split->num_srcpads, nth);
308 
309  name = g_strdup_printf ("src_%u", split->num_srcpads);
310  pad = gst_pad_new_from_static_template (&src_templ, name);
311  stream_id = gst_pad_create_stream_id_printf (pad, element,
312  "%s-nnssplit-%s-%08x", element_name, name, g_random_int ());
313  g_free (name);
314 
315  tensorpad->pad = pad;
316  tensorpad->nth = nth;
317  tensorpad->last_ret = GST_FLOW_OK;
318  tensorpad->last_ts = GST_CLOCK_TIME_NONE;
319 
320  split->srcpads = g_slist_append (split->srcpads, tensorpad);
321  dim = g_array_index (split->tensorseg, tensor_dim *, split->num_srcpads);
322 
323  split->num_srcpads++;
324 
325  gst_pad_use_fixed_caps (pad);
326  gst_pad_set_active (pad, TRUE);
327 
328  if (!split->have_group_id) {
329  event =
330  gst_pad_get_sticky_event (split->sinkpad, GST_EVENT_STREAM_START, 0);
331  if (event) {
332  split->have_group_id = gst_event_parse_group_id (event, &split->group_id);
333  gst_event_unref (event);
334  } else if (!split->have_group_id) {
335  split->have_group_id = TRUE;
336  split->group_id = gst_util_group_id_next ();
337  }
338  }
339 
340  event = gst_event_new_stream_start (stream_id);
341  if (split->have_group_id)
342  gst_event_set_group_id (event, split->group_id);
343 
344  gst_pad_store_sticky_event (pad, event);
345  g_free (stream_id);
346  gst_event_unref (event);
347 
348  /* tensor config to set caps */
349  gst_tensors_config_init (&pad_config);
350  pad_config.info.num_tensors = 1;
351  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
352  pad_config.info.info[0].dimension[i] = (*dim)[i];
353  }
354  pad_config.info.info[0].type = split->sink_tensor_conf.info.info[0].type;
355  pad_config.rate_n = split->sink_tensor_conf.rate_n;
356  pad_config.rate_d = split->sink_tensor_conf.rate_d;
357 
358  caps = gst_tensor_pad_caps_from_config (pad, &pad_config);
359 
360  gst_pad_set_caps (pad, caps);
361  gst_element_add_pad (GST_ELEMENT_CAST (split), pad);
362 
363  gst_caps_unref (caps);
364 
365  if (created) {
366  *created = TRUE;
367  }
368 
369  if (split->tensorpick != NULL) {
370  GST_DEBUG_OBJECT (split, "TensorPick is set! : %dth tensor\n", nth);
371  if (g_list_length (split->tensorpick) == split->num_srcpads) {
372  gst_element_no_more_pads (GST_ELEMENT_CAST (split));
373  }
374  }
375 
376  return tensorpad;
377 }
378 
386 static GstFlowReturn
388  GstTensorPad * pad, GstFlowReturn ret)
389 {
390  GSList *walk;
391  GstTensorPad *opad;
392 
393  pad->last_ret = ret;
394  if (ret != GST_FLOW_NOT_LINKED)
395  goto done;
396 
397  for (walk = split->srcpads; walk; walk = g_slist_next (walk)) {
398  opad = (GstTensorPad *) walk->data;
399  ret = opad->last_ret;
400  if (ret != GST_FLOW_NOT_LINKED)
401  goto done;
402  }
403 done:
404  return ret;
405 }
406 
414 static GstMemory *
415 gst_tensor_split_get_splitted (GstTensorSplit * split, GstBuffer * buffer,
416  gint nth)
417 {
418  GstMemory *mem;
419  tensor_dim *dim;
420  int i;
421  gsize size, offset;
422  GstMapInfo src_info, dest_info;
423 
424  dim = g_array_index (split->tensorseg, tensor_dim *, nth);
425  size = gst_tensor_get_element_count (*dim) *
427 
428  mem = gst_allocator_alloc (NULL, size, NULL);
429  if (!gst_memory_map (mem, &dest_info, GST_MAP_WRITE)) {
430  ml_logf ("Cannot map memory for destination buffer.\n");
431  gst_memory_unref (mem);
432  return NULL;
433  }
434  if (!gst_buffer_map (buffer, &src_info, GST_MAP_READ)) {
435  ml_logf ("Cannot map src-memory to gst buffer at tensor-split.\n");
436  gst_memory_unmap (mem, &dest_info);
437  gst_memory_unref (mem);
438  return NULL;
439  }
440 
441  offset = 0;
442  for (i = 0; i < nth; i++) {
443  dim = g_array_index (split->tensorseg, tensor_dim *, i);
444  offset += gst_tensor_get_element_count (*dim) *
446  }
447 
448  nns_memcpy (dest_info.data, src_info.data + offset, size);
449  gst_buffer_unmap (buffer, &src_info);
450  gst_memory_unmap (mem, &dest_info);
451 
452  return mem;
453 }
454 
458 static GstFlowReturn
459 gst_tensor_split_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
460 {
461  GstTensorSplit *split;
462  guint num_tensors, i;
463  GstFlowReturn res = GST_FLOW_OK;
464  UNUSED (pad);
465 
466  split = GST_TENSOR_SPLIT (parent);
467 
468  num_tensors = split->num_tensors;
469  GST_DEBUG_OBJECT (split, " Number of Tensors: %d", num_tensors);
470 
471  if (split->tensorseg == NULL) {
472  GST_ERROR_OBJECT (split, "No rule to split incoming buffers.");
473  return GST_FLOW_ERROR;
474  }
475 
476  for (i = 0; i < num_tensors; i++) {
477  GstTensorPad *srcpad;
478  GstBuffer *outbuf;
479  GstMemory *mem;
480  gboolean created;
481  GstClockTime ts;
482 
483  if (split->tensorpick != NULL) {
484  gboolean found = FALSE;
485  GList *list;
486  for (list = split->tensorpick; list != NULL; list = list->next) {
487  if (i == GPOINTER_TO_UINT (list->data)) {
488  found = TRUE;
489  break;
490  }
491  }
492  if (!found)
493  continue;
494  }
495 
496  srcpad = gst_tensor_split_get_tensor_pad (split, buf, &created, i);
497 
498  outbuf = gst_buffer_new ();
499  mem = gst_tensor_split_get_splitted (split, buf, i);
500  gst_buffer_append_memory (outbuf, mem);
501  ts = GST_BUFFER_TIMESTAMP (buf);
502 
503  if (created) {
504  GstSegment segment;
505  gst_segment_init (&segment, GST_FORMAT_TIME);
506  gst_pad_push_event (srcpad->pad, gst_event_new_segment (&segment));
507  }
508 
509  outbuf = gst_buffer_make_writable (outbuf);
510 
511  /* metadata from incoming buffer */
512  gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1);
513 
514  if (srcpad->last_ts == GST_CLOCK_TIME_NONE || srcpad->last_ts != ts) {
515  srcpad->last_ts = ts;
516  } else {
517  GST_DEBUG_OBJECT (split, "invalid timestamp %" GST_TIME_FORMAT,
518  GST_TIME_ARGS (ts));
519  }
520 
521  GST_DEBUG_OBJECT (split, "pushing buffer with timestamp %" GST_TIME_FORMAT,
522  GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
523  res = gst_pad_push (srcpad->pad, outbuf);
524  res = gst_tensor_split_combine_flows (split, srcpad, res);
525  if (res != GST_FLOW_OK)
526  break;
527  }
528 
529  gst_buffer_unref (buf);
530  return res;
531 }
532 
536 static GstStateChangeReturn
537 gst_tensor_split_change_state (GstElement * element, GstStateChange transition)
538 {
539  GstTensorSplit *split;
540  GstStateChangeReturn ret;
541 
542  split = GST_TENSOR_SPLIT (element);
543 
544  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
545  if (ret == GST_STATE_CHANGE_FAILURE)
546  return ret;
547 
548  switch (transition) {
549  case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
550  break;
551  case GST_STATE_CHANGE_PAUSED_TO_READY:
552  split->group_id = G_MAXUINT;
553  split->have_group_id = FALSE;
555  break;
556  case GST_STATE_CHANGE_READY_TO_NULL:
557  break;
558  default:
559  break;
560  }
561 
562  return ret;
563 }
564 
568 static void
570 {
571  g_free (*element);
572 }
573 
577 static void
578 gst_tensor_split_set_property (GObject * object, guint prop_id,
579  const GValue * value, GParamSpec * pspec)
580 {
581  GstTensorSplit *split;
582 
583  split = GST_TENSOR_SPLIT (object);
584 
585  switch (prop_id) {
586  case PROP_SILENT:
587  split->silent = g_value_get_boolean (value);
588  break;
589  case PROP_TENSORPICK:
590  {
591  gint i;
592  gint64 val;
593  const gchar *param = g_value_get_string (value);
594  gchar **strv = g_strsplit_set (param, ",.;/", -1);
595  gint num = g_strv_length (strv);
596  for (i = 0; i < num; i++) {
597  val = g_ascii_strtoll (strv[i], NULL, 10);
598  split->tensorpick =
599  g_list_append (split->tensorpick, GINT_TO_POINTER (val));
600  }
601  g_strfreev (strv);
602  break;
603  }
604  case PROP_TENSORSEG:
605  {
606  guint i;
607  const gchar *param = g_value_get_string (value);
608  gchar **strv = g_strsplit_set (param, ",.;/", -1);
609  GArray *tensorseg = split->tensorseg;
610 
611  split->num_tensors = g_strv_length (strv);
612  if (NULL == tensorseg) {
613  split->tensorseg =
614  g_array_sized_new (FALSE, FALSE, sizeof (tensor_dim *),
615  split->num_tensors);
616  g_array_set_clear_func (split->tensorseg,
617  (GDestroyNotify) _clear_tensorseg);
618 
619  for (i = 0; i < split->num_tensors; i++) {
620  tensor_dim *d = g_new0 (tensor_dim, 1);
621  g_array_append_val (split->tensorseg, d);
622  }
623  tensorseg = split->tensorseg;
624  }
625  for (i = 0; i < split->num_tensors; i++) {
626  gchar **p;
627  gint num, k;
628  tensor_dim *d;
629  p = g_strsplit_set (strv[i], ":", -1);
630  num = g_strv_length (p);
631 
632  d = g_array_index (tensorseg, tensor_dim *, i);
633 
634  for (k = 0; k < num; k++) {
635  (*d)[k] = g_ascii_strtod (p[k], NULL);
636  }
637 
638  g_strfreev (p);
639  }
640  g_strfreev (strv);
641  break;
642  }
643  default:
644  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
645  break;
646  }
647 }
648 
652 static void
653 gst_tensor_split_get_property (GObject * object, guint prop_id,
654  GValue * value, GParamSpec * pspec)
655 {
656  GstTensorSplit *split;
657 
658  split = GST_TENSOR_SPLIT (object);
659 
660  switch (prop_id) {
661  case PROP_SILENT:
662  g_value_set_boolean (value, split->silent);
663  break;
664  case PROP_TENSORPICK:
665  {
666  GList *list;
667  char *p;
668  GPtrArray *arr = g_ptr_array_new ();
669  gchar **strings;
670 
671  for (list = split->tensorpick; list != NULL; list = list->next) {
672  g_ptr_array_add (arr, g_strdup_printf ("%i",
673  GPOINTER_TO_INT (list->data)));
674  }
675  g_ptr_array_add (arr, NULL);
676  strings = (gchar **) g_ptr_array_free (arr, FALSE);
677  p = g_strjoinv (",", strings);
678  g_strfreev (strings);
679  g_value_take_string (value, p);
680  break;
681  }
682  case PROP_TENSORSEG:
683  {
684  if ((split->tensorseg) && (split->tensorseg->len > 0)) {
685  tensor_dim *dim = NULL;
686  gchar *strv = NULL;
687  guint i, j;
688 
689 
690  for (i = 0; i < split->tensorseg->len; i++) {
691  GPtrArray *arr = g_ptr_array_new ();
692  gchar *p = NULL;
693  gchar **strings;
694 
695  dim = g_array_index (split->tensorseg, tensor_dim *, i);
696  for (j = 0; j < NNS_TENSOR_RANK_LIMIT; j++) {
697  g_ptr_array_add (arr, g_strdup_printf ("%i", (*dim)[j]));
698  }
699  g_ptr_array_add (arr, NULL);
700  strings = (gchar **) g_ptr_array_free (arr, FALSE);
701  p = g_strjoinv (":", strings);
702  g_strfreev (strings);
703  if (i > 0) {
708  gchar *oldstrv = strv;
709 
710  strv = g_strjoin (",", strv, p, NULL);
711  g_free (oldstrv);
712  g_free (p);
713  } else {
714  strv = p;
715  }
716  }
717  /* the second parameter, strv (i.e., gchar *v_string), is nullable */
718  g_value_take_string (value, strv ? strv : g_strdup (""));
719  } else {
720  g_value_set_string (value, "");
721  }
722  break;
723  }
724  default:
725  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
726  break;
727  }
728 }
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:459
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:590
_GstTensorSplit::num_srcpads
guint32 num_srcpads
Definition: gsttensor_split.h:58
ml_logf
#define ml_logf
Definition: nnstreamer_log.h:80
gst_tensor_split_get_capsparam
static gboolean gst_tensor_split_get_capsparam(GstTensorSplit *split, GstCaps *caps)
Set Caps in pad.
Definition: gsttensor_split.c:220
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:578
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:387
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:653
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:897
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:233
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
_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:537
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:569
GstTensorInfo::dimension
tensor_dim dimension
Definition: tensor_typedef.h:267
gst_tensors_config_from_structure
gboolean gst_tensors_config_from_structure(GstTensorsConfig *config, const GstStructure *structure)
Parse structure and set tensors config (for other/tensors)
Definition: nnstreamer_plugin_api_impl.c:1413
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:276
_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:415
PROP_0
@ PROP_0
Definition: gsttensor_split.c:64