Doxygen Book
gsttensor_demux.c
Go to the documentation of this file.
1 
61 #ifdef HAVE_CONFIG_H
62 #include <config.h>
63 #endif
64 
65 #include <string.h>
66 #include <gst/gst.h>
67 #include <glib.h>
68 #include <nnstreamer_util.h>
69 
70 #include "gsttensor_demux.h"
71 
72 GST_DEBUG_CATEGORY_STATIC (gst_tensor_demux_debug);
73 #define GST_CAT_DEFAULT gst_tensor_demux_debug
74 
78 #define CAPS_STRING_SINK GST_TENSORS_CAP_MAKE ("{ static, flexible }")
79 
83 #define CAPS_STRING_SRC GST_TENSOR_CAP_DEFAULT ";" GST_TENSORS_CAP_MAKE ("{ static, flexible }")
84 
85 enum
86 {
90 };
91 
96 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src_%u",
97  GST_PAD_SRC,
98  GST_PAD_SOMETIMES,
99  GST_STATIC_CAPS (CAPS_STRING_SRC)
100  );
101 
102 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
103  GST_PAD_SINK,
104  GST_PAD_ALWAYS,
105  GST_STATIC_CAPS (CAPS_STRING_SINK)
106  );
107 
108 static GstFlowReturn gst_tensor_demux_chain (GstPad * pad, GstObject * parent,
109  GstBuffer * buf);
110 static gboolean gst_tensor_demux_event (GstPad * pad, GstObject * parent,
111  GstEvent * event);
112 static GstStateChangeReturn gst_tensor_demux_change_state (GstElement * element,
113  GstStateChange transition);
114 static void gst_tensor_demux_set_property (GObject * object, guint prop_id,
115  const GValue * value, GParamSpec * pspec);
116 static void gst_tensor_demux_get_property (GObject * object, guint prop_id,
117  GValue * value, GParamSpec * pspec);
118 static void gst_tensor_demux_dispose (GObject * object);
119 #define gst_tensor_demux_parent_class parent_class
120 G_DEFINE_TYPE (GstTensorDemux, gst_tensor_demux, GST_TYPE_ELEMENT);
121 
122 
126 static void
128 {
129  GObjectClass *gobject_class;
130  GstElementClass *gstelement_class;
131 
132  GST_DEBUG_CATEGORY_INIT (gst_tensor_demux_debug, "tensor_demux", 0,
133  "Element to demux tensors to tensor stream");
134 
135  gobject_class = (GObjectClass *) klass;
136  gstelement_class = (GstElementClass *) klass;
137 
138  parent_class = g_type_class_peek_parent (klass);
139 
140  gobject_class->dispose = gst_tensor_demux_dispose;
141  gobject_class->get_property = gst_tensor_demux_get_property;
142  gobject_class->set_property = gst_tensor_demux_set_property;
143 
144  g_object_class_install_property (gobject_class, PROP_SILENT,
145  g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
146  TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
147 
148  g_object_class_install_property (gobject_class, PROP_TENSORPICK,
149  g_param_spec_string ("tensorpick", "TensorPick",
150  "Choose nth tensor among tensors ?", "",
151  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
152 
153  gstelement_class->change_state =
154  GST_DEBUG_FUNCPTR (gst_tensor_demux_change_state);
155 
156  gst_element_class_add_pad_template (gstelement_class,
157  gst_static_pad_template_get (&sink_templ));
158  gst_element_class_add_pad_template (gstelement_class,
159  gst_static_pad_template_get (&src_templ));
160 
161  gst_element_class_set_details_simple (gstelement_class,
162  "TensorDemux",
163  "Demuxer/Tensor",
164  "Demux tensors stream to other/tensor stream",
165  "Jijoong Moon <jijoong.moon@samsung.com>");
166 }
167 
174 static void
176 {
177  tensor_demux->sinkpad =
178  gst_pad_new_from_static_template (&sink_templ, "sink");
179  gst_element_add_pad (GST_ELEMENT_CAST (tensor_demux), tensor_demux->sinkpad);
180  gst_pad_set_chain_function (tensor_demux->sinkpad,
181  GST_DEBUG_FUNCPTR (gst_tensor_demux_chain));
182  gst_pad_set_event_function (tensor_demux->sinkpad,
183  GST_DEBUG_FUNCPTR (gst_tensor_demux_event));
184 
185  tensor_demux->num_srcpads = 0;
186  tensor_demux->silent = TRUE;
187  tensor_demux->tensorpick = NULL;
188  tensor_demux->have_group_id = FALSE;
189  tensor_demux->group_id = G_MAXUINT;
190  tensor_demux->srcpads = NULL;
191 
192  gst_tensors_config_init (&tensor_demux->tensors_config);
193 }
194 
198 static void
200 {
201  while (tensor_demux->srcpads != NULL) {
202  GstTensorPad *tensor_pad = tensor_demux->srcpads->data;
203  gst_element_remove_pad (GST_ELEMENT (tensor_demux), tensor_pad->pad);
204  g_free (tensor_pad);
205  tensor_demux->srcpads =
206  g_slist_delete_link (tensor_demux->srcpads, tensor_demux->srcpads);
207  }
208  tensor_demux->srcpads = NULL;
209  tensor_demux->num_srcpads = 0;
210 
211  gst_tensors_config_free (&tensor_demux->tensors_config);
212  gst_tensors_config_init (&tensor_demux->tensors_config);
213 }
214 
218 static void
219 gst_tensor_demux_dispose (GObject * object)
220 {
221  GstTensorDemux *tensor_demux = GST_TENSOR_DEMUX (object);
222 
223  gst_tensor_demux_remove_src_pads (tensor_demux);
224  g_list_free_full (tensor_demux->tensorpick, g_free);
225  G_OBJECT_CLASS (parent_class)->dispose (object);
226 }
227 
231 static gboolean
232 gst_tensor_demux_event (GstPad * pad, GstObject * parent, GstEvent * event)
233 {
234  GstTensorDemux *tensor_demux;
235  tensor_demux = GST_TENSOR_DEMUX (parent);
236 
237  switch (GST_EVENT_TYPE (event)) {
238  case GST_EVENT_CAPS:
239  {
240  GstCaps *caps;
241  gst_event_parse_caps (event, &caps);
242  gst_tensors_config_from_cap (&tensor_demux->tensors_config, caps);
243  break;
244  }
245  case GST_EVENT_EOS:
246  if (!tensor_demux->srcpads) {
247  GST_ELEMENT_ERROR (tensor_demux, STREAM, WRONG_TYPE,
248  ("This stream contains no valid stremas."),
249  ("Got EOS before adding any pads"));
250  gst_event_unref (event);
251  return FALSE;
252  }
253  break;
254  default:
255  break;
256  }
257 
258  return gst_pad_event_default (pad, parent, event);
259 }
260 
269 static gboolean
271  GstTensorsConfig * config, const guint nth, const guint total)
272 {
273  gst_tensors_config_init (config);
274 
275  if (tensor_demux->tensorpick != NULL) {
276  gchar *selected_tensor;
277  gchar **strv;
278  guint i, num, idx;
279 
280  g_assert (g_list_length (tensor_demux->tensorpick) >= nth);
281 
282  selected_tensor = (gchar *) g_list_nth_data (tensor_demux->tensorpick, nth);
283  strv = g_strsplit_set (selected_tensor, ":+", -1);
284  num = g_strv_length (strv);
285 
286  for (i = 0; i < num; i++) {
287  idx = (guint) g_ascii_strtoll (strv[i], NULL, 10);
288 
289  /* Internal error, handle invalid index. */
290  if (idx >= total) {
291  g_strfreev (strv);
292  return FALSE;
293  }
294 
297  idx));
298  }
299 
300  config->info.num_tensors = num;
301  g_strfreev (strv);
302  } else {
303  /* Internal error, handle invalid index. */
304  if (nth >= total)
305  return FALSE;
306 
307  config->info.num_tensors = 1;
308  gst_tensor_info_copy (&config->info.info[0],
310  nth));
311  }
312 
313  config->info.format = tensor_demux->tensors_config.info.format;
314  config->rate_n = tensor_demux->tensors_config.rate_n;
315  config->rate_d = tensor_demux->tensors_config.rate_d;
316  return TRUE;
317 }
318 
328 static GstTensorPad *
330  gboolean * created, const guint nth, const guint total)
331 {
332  GstElement *element = GST_ELEMENT_CAST (tensor_demux);
333  g_autofree gchar *element_name = gst_element_get_name (element);
334  GSList *walk;
335  GstPad *pad;
336  GstTensorPad *tensorpad;
337  gchar *name;
338  GstEvent *event;
339  gchar *stream_id;
340  GstCaps *caps = NULL;
341  GstTensorsConfig config;
342 
343  walk = tensor_demux->srcpads;
344  while (walk) {
345  GstTensorPad *pad = (GstTensorPad *) walk->data;
346  if (nth == pad->nth) {
347  if (created) {
348  *created = FALSE;
349  }
350  return pad;
351  }
352  walk = walk->next;
353  }
354 
355  tensorpad = g_new0 (GstTensorPad, 1);
356  g_assert (tensorpad != NULL);
357  GST_DEBUG_OBJECT (tensor_demux, "creating pad: %d(%dth)",
358  tensor_demux->num_srcpads, nth);
359 
360  name = g_strdup_printf ("src_%u", tensor_demux->num_srcpads);
361  pad = gst_pad_new_from_static_template (&src_templ, name);
362  stream_id = gst_pad_create_stream_id_printf (pad, element,
363  "%s-nnsdemux-%s-%08x", element_name, name, g_random_int ());
364  g_free (name);
365 
366  tensorpad->pad = pad;
367  tensorpad->nth = nth;
368  tensorpad->last_ret = GST_FLOW_OK;
369  tensorpad->last_ts = GST_CLOCK_TIME_NONE;
370 
371  tensor_demux->srcpads = g_slist_append (tensor_demux->srcpads, tensorpad);
372  tensor_demux->num_srcpads++;
373 
374  gst_pad_use_fixed_caps (pad);
375  gst_pad_set_active (pad, TRUE);
376  gst_element_add_pad (GST_ELEMENT_CAST (tensor_demux), pad);
377 
378  if (!tensor_demux->have_group_id) {
379  event =
380  gst_pad_get_sticky_event (tensor_demux->sinkpad, GST_EVENT_STREAM_START,
381  0);
382  if (event) {
383  tensor_demux->have_group_id =
384  gst_event_parse_group_id (event, &tensor_demux->group_id);
385  gst_event_unref (event);
386  } else if (!tensor_demux->have_group_id) {
387  tensor_demux->have_group_id = TRUE;
388  tensor_demux->group_id = gst_util_group_id_next ();
389  }
390  }
391 
392  event = gst_event_new_stream_start (stream_id);
393  if (tensor_demux->have_group_id)
394  gst_event_set_group_id (event, tensor_demux->group_id);
395 
396  gst_pad_store_sticky_event (pad, event);
397  g_free (stream_id);
398  gst_event_unref (event);
399 
400  /* configure nth pad caps */
401  if (gst_tensor_demux_get_tensor_config (tensor_demux, &config, nth, total)) {
402  caps = gst_tensor_pad_caps_from_config (pad, &config);
403 
404  gst_pad_set_caps (pad, caps);
405  gst_caps_unref (caps);
406  } else {
407  GST_WARNING_OBJECT (tensor_demux, "Unable to set pad caps");
408  }
409 
410  if (created) {
411  *created = TRUE;
412  }
413 
414  if (tensor_demux->tensorpick != NULL) {
415  GST_DEBUG_OBJECT (tensor_demux, "TensorPick is set! : %dth tensor\n", nth);
416  if (g_list_length (tensor_demux->tensorpick) == tensor_demux->num_srcpads) {
417  gst_element_no_more_pads (GST_ELEMENT_CAST (tensor_demux));
418  }
419  }
420 
421  gst_tensors_config_free (&config);
422  return tensorpad;
423 }
424 
432 static GstFlowReturn
434  GstTensorPad * pad, GstFlowReturn ret)
435 {
436  GSList *walk;
437  pad->last_ret = ret;
438 
439  if (ret != GST_FLOW_NOT_LINKED)
440  goto done;
441 
442  for (walk = tensor_demux->srcpads; walk; walk = g_slist_next (walk)) {
443  GstTensorPad *opad = (GstTensorPad *) walk->data;
444  ret = opad->last_ret;
445  if (ret != GST_FLOW_NOT_LINKED)
446  goto done;
447  }
448 done:
449  return ret;
450 }
451 
455 static GstFlowReturn
456 gst_tensor_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
457 {
458  guint num_tensors, num_srcs, i, idx;
459  GstFlowReturn res = GST_FLOW_OK;
460  GstTensorDemux *tensor_demux;
461  GList *list = NULL;
462  GstTensorInfo *_info;
463 
464  UNUSED (pad);
465  tensor_demux = GST_TENSOR_DEMUX (parent);
466 
467  buf = gst_tensor_buffer_from_config (buf, &tensor_demux->tensors_config);
468 
474  num_tensors = gst_tensor_buffer_get_count (buf);
475  if (gst_tensors_config_is_static (&tensor_demux->tensors_config))
476  g_assert (tensor_demux->tensors_config.info.num_tensors == num_tensors);
477 
478  GST_DEBUG_OBJECT (tensor_demux, " Number of Tensors: %d", num_tensors);
479 
480  num_srcs = num_tensors;
481  if (tensor_demux->tensorpick != NULL) {
482  num_srcs = g_list_length (tensor_demux->tensorpick);
483  list = tensor_demux->tensorpick;
484  }
485 
486  for (i = 0; i < num_srcs; i++) {
487  GstTensorPad *srcpad;
488  GstBuffer *outbuf;
489  GstMemory *mem;
490  gboolean created;
491  GstClockTime ts;
492 
493  srcpad = gst_tensor_demux_get_tensor_pad (tensor_demux, &created, i,
494  num_tensors);
495  outbuf = gst_buffer_new ();
496 
497  if (tensor_demux->tensorpick != NULL) {
498  guint num, j;
499  gchar **strv = g_strsplit_set ((gchar *) list->data, ":+", -1);
500 
501  num = g_strv_length (strv);
502  for (j = 0; j < num; j++) {
503  idx = (guint) g_ascii_strtoll (strv[j], NULL, 10);
504  _info =
506  idx);
507  mem = gst_tensor_buffer_get_nth_memory (buf, idx);
508  if (!gst_tensor_buffer_append_memory (outbuf, mem, _info)) {
509  gst_buffer_unref (outbuf);
510  res = GST_FLOW_ERROR;
511  goto error;
512  }
513  }
514  g_strfreev (strv);
515  list = list->next;
516  } else {
517  _info =
519  mem = gst_tensor_buffer_get_nth_memory (buf, i);
520  if (!gst_tensor_buffer_append_memory (outbuf, mem, _info)) {
521  gst_buffer_unref (outbuf);
522  res = GST_FLOW_ERROR;
523  goto error;
524  }
525  }
526 
527  ts = GST_BUFFER_TIMESTAMP (buf);
528 
529  if (created) {
530  GstSegment segment;
531  gst_segment_init (&segment, GST_FORMAT_TIME);
532  gst_pad_push_event (srcpad->pad, gst_event_new_segment (&segment));
533  }
534 
535  outbuf = gst_buffer_make_writable (outbuf);
536 
537  /* metadata from incoming buffer */
538  gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1);
539 
540  if (srcpad->last_ts == GST_CLOCK_TIME_NONE || srcpad->last_ts != ts) {
541  srcpad->last_ts = ts;
542  } else {
543  GST_DEBUG_OBJECT (tensor_demux, "invalid timestamp %" GST_TIME_FORMAT,
544  GST_TIME_ARGS (ts));
545  }
546 
547  GST_DEBUG_OBJECT (tensor_demux,
548  "pushing buffer with timestamp %" GST_TIME_FORMAT,
549  GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
550  res = gst_pad_push (srcpad->pad, outbuf);
551  res = gst_tensor_demux_combine_flows (tensor_demux, srcpad, res);
552 
553  if (res != GST_FLOW_OK)
554  break;
555  }
556 
557 error:
558  gst_buffer_unref (buf);
559  return res;
560 }
561 
565 static GstStateChangeReturn
566 gst_tensor_demux_change_state (GstElement * element, GstStateChange transition)
567 {
568  GstTensorDemux *tensor_demux;
569  GstStateChangeReturn ret;
570  tensor_demux = GST_TENSOR_DEMUX (element);
571  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
572  if (ret == GST_STATE_CHANGE_FAILURE)
573  return ret;
574  switch (transition) {
575  case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
576  break;
577  case GST_STATE_CHANGE_PAUSED_TO_READY:
578  tensor_demux->group_id = G_MAXUINT;
579  tensor_demux->have_group_id = FALSE;
580  gst_tensor_demux_remove_src_pads (tensor_demux);
581  break;
582  case GST_STATE_CHANGE_READY_TO_NULL:
583  break;
584  default:
585  break;
586  }
587 
588  return ret;
589 }
590 
594 static void
595 gst_tensor_demux_set_property (GObject * object, guint prop_id,
596  const GValue * value, GParamSpec * pspec)
597 {
598  GstTensorDemux *filter = GST_TENSOR_DEMUX (object);
599  switch (prop_id) {
600  case PROP_SILENT:
601  filter->silent = g_value_get_boolean (value);
602  break;
603  case PROP_TENSORPICK:
604  {
605  guint i;
606  const gchar *param = g_value_get_string (value);
607  gchar **strv = g_strsplit_set (param, ",.;/", -1);
608  guint num = g_strv_length (strv);
609 
610  /* Before setting the new Tensor Pick data, the existing one should be removed. */
611  if (filter->tensorpick) {
612  g_list_free_full (filter->tensorpick, g_free);
613  filter->tensorpick = NULL;
614  }
615  for (i = 0; i < num; i++) {
616  gchar *tmp = g_strdup (strv[i]);
617  filter->tensorpick = g_list_append (filter->tensorpick, tmp);
618  }
619  g_strfreev (strv);
620  break;
621  }
622  default:
623  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
624  break;
625  }
626 }
627 
631 static void
632 gst_tensor_demux_get_property (GObject * object, guint prop_id,
633  GValue * value, GParamSpec * pspec)
634 {
635  GstTensorDemux *filter = GST_TENSOR_DEMUX (object);
636  switch (prop_id) {
637  case PROP_SILENT:
638  g_value_set_boolean (value, filter->silent);
639  break;
640  case PROP_TENSORPICK:
641  {
642  GList *list;
643  char *p;
644  GPtrArray *arr = g_ptr_array_new ();
645  gchar **strings;
646 
647  for (list = filter->tensorpick; list != NULL; list = list->next) {
648  g_ptr_array_add (arr, g_strdup_printf ("%s", (gchar *) list->data));
649  }
650  g_ptr_array_add (arr, NULL);
651  strings = (gchar **) g_ptr_array_free (arr, FALSE);
652  p = g_strjoinv (",", strings);
653  g_strfreev (strings);
654  g_value_take_string (value, p);
655  break;
656  }
657  default:
658  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
659  break;
660  }
661 }
gst_tensor_demux_get_property
static void gst_tensor_demux_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
Get property (gst element vmethod)
Definition: gsttensor_demux.c:632
gst_tensor_buffer_from_config
GstBuffer * gst_tensor_buffer_from_config(GstBuffer *in, GstTensorsConfig *config)
Configure gst-buffer with tensors information. NNStreamer handles single memory chunk as single tenso...
Definition: nnstreamer_plugin_api_impl.c:535
g_assert
g_assert(sizeof(DTYPE_UNSIGNED)==sizeof(DTYPE_SIGNED))
gst_tensor_demux_get_tensor_pad
static GstTensorPad * gst_tensor_demux_get_tensor_pad(GstTensorDemux *tensor_demux, gboolean *created, const guint nth, const guint total)
Checking if the source pad is created and if not, create TensorPad.
Definition: gsttensor_demux.c:329
gst_tensor_demux_change_state
static GstStateChangeReturn gst_tensor_demux_change_state(GstElement *element, GstStateChange transition)
change state (gst element vmethod)
Definition: gsttensor_demux.c:566
_GstTensorDemux
Tensor Muxer data structure.
Definition: gsttensor_demux.h:50
GstTensorInfo
Internal data structure for tensor info.
Definition: tensor_typedef.h:261
GstTensorPad
Internal data structure for pad in demux / split.
Definition: tensor_common.h:102
FALSE
return FALSE
Definition: gsttensor_transform.c:596
gst_tensor_demux_set_property
static void gst_tensor_demux_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
Get property (gst element vmethod)
Definition: gsttensor_demux.c:595
_GstTensorDemux::num_srcpads
guint32 num_srcpads
Definition: gsttensor_demux.h:57
_GstTensorDemux::sinkpad
GstPad * sinkpad
Definition: gsttensor_demux.h:55
_GstTensorDemux::group_id
guint group_id
Definition: gsttensor_demux.h:60
gst_tensor_info_copy
void gst_tensor_info_copy(GstTensorInfo *dest, const GstTensorInfo *src)
Copy tensor info.
Definition: nnstreamer_plugin_api_util_impl.c:248
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
_GstTensorDemux::tensors_config
GstTensorsConfig tensors_config
Definition: gsttensor_demux.h:62
GstTensorsConfig::rate_d
int rate_d
Definition: tensor_typedef.h:288
gsttensor_demux.h
GStreamer plugin to demux tensors (as a filter for other general neural network filters)
GstTensorPad::last_ts
GstClockTime last_ts
Definition: tensor_common.h:105
g_free
g_free(self->option[(opnum) - 1])
opnum: \
PROP_SILENT
@ PROP_SILENT
Definition: gsttensor_demux.c:88
GstTensorsConfig::rate_n
int rate_n
Definition: tensor_typedef.h:287
CAPS_STRING_SINK
#define CAPS_STRING_SINK
Default caps string for sink pad.
Definition: gsttensor_demux.c:78
gst_tensor_demux_event
static gboolean gst_tensor_demux_event(GstPad *pad, GstObject *parent, GstEvent *event)
event function for sink (gst element vmethod)
Definition: gsttensor_demux.c:232
GstTensorsInfo::info
GstTensorInfo info[NNS_TENSOR_MEMORY_MAX]
Definition: tensor_typedef.h:276
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
CAPS_STRING_SRC
#define CAPS_STRING_SRC
Default caps string for src pad.
Definition: gsttensor_demux.c:83
GstTensorsConfig
Internal data structure for configured tensors info (for other/tensors).
Definition: tensor_typedef.h:284
sink_templ
static GstStaticPadTemplate sink_templ
Definition: gsttensor_demux.c:102
GST_TENSOR_DEMUX
#define GST_TENSOR_DEMUX(obj)
Definition: gsttensor_demux.h:37
TRUE
return TRUE
Definition: gsttensor_if.c:879
UNUSED
#define UNUSED(expr)
Definition: mqttcommon.h:19
src_templ
static GstStaticPadTemplate src_templ
the capabilities of the inputs and outputs. describe the real formats here.
Definition: gsttensor_demux.c:96
nnstreamer_util.h
Optional NNStreamer utility functions for sub-plugin writers and users.
gst_tensor_demux_chain
static GstFlowReturn gst_tensor_demux_chain(GstPad *pad, GstObject *parent, GstBuffer *buf)
chain function for sink (gst element vmethod)
Definition: gsttensor_demux.c:456
gst_tensors_info_get_nth_info
GstTensorInfo * gst_tensors_info_get_nth_info(GstTensorsInfo *info, guint index)
Get the pointer of nth tensor information.
Definition: nnstreamer_plugin_api_util_impl.c:296
_GstTensorDemuxClass
GstTensorDeMuxClass inherits GstElementClass.
Definition: gsttensor_demux.h:68
GstTensorPad::pad
GstPad * pad
Definition: tensor_common.h:104
_GstTensorDemux::have_group_id
gboolean have_group_id
Definition: gsttensor_demux.h:59
GST_DEBUG_CATEGORY_STATIC
GST_DEBUG_CATEGORY_STATIC(gst_tensor_demux_debug)
GstTensorPad::nth
guint nth
Definition: tensor_common.h:107
gst_tensor_demux_get_tensor_config
static gboolean gst_tensor_demux_get_tensor_config(GstTensorDemux *tensor_demux, GstTensorsConfig *config, const guint nth, const guint total)
Get tensor config info from configured tensors.
Definition: gsttensor_demux.c:270
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
_GstTensorDemux::silent
gboolean silent
Definition: gsttensor_demux.h:54
gst_tensor_demux_combine_flows
static GstFlowReturn gst_tensor_demux_combine_flows(GstTensorDemux *tensor_demux, GstTensorPad *pad, GstFlowReturn ret)
Check the status among sources in demux.
Definition: gsttensor_demux.c:433
_GstTensorDemux::srcpads
GSList * srcpads
Definition: gsttensor_demux.h:56
gst_tensor_demux_class_init
static void gst_tensor_demux_class_init(GstTensorDemuxClass *klass)
initialize the tensor_demux's class
Definition: gsttensor_demux.c:127
GstTensorsInfo::num_tensors
unsigned int num_tensors
Definition: tensor_typedef.h:275
PROP_0
@ PROP_0
Definition: gsttensor_demux.c:87
gst_tensor_buffer_get_nth_memory
GstMemory * gst_tensor_buffer_get_nth_memory(GstBuffer *buffer, const guint index)
Get the nth GstMemory from given buffer.
Definition: nnstreamer_plugin_api_impl.c:1608
PROP_TENSORPICK
@ PROP_TENSORPICK
Definition: gsttensor_demux.c:89
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_buffer_get_count
guint gst_tensor_buffer_get_count(GstBuffer *buffer)
Get the number of tensors in the buffer.
Definition: nnstreamer_plugin_api_impl.c:1835
GstTensorsConfig::info
GstTensorsInfo info
Definition: tensor_typedef.h:286
_GstTensorDemux::tensorpick
GList * tensorpick
Definition: gsttensor_demux.h:58
gst_tensor_demux_init
static void gst_tensor_demux_init(GstTensorDemux *tensor_demux)
initialize the new element instantiate pads and add them to element set pad callback functions initia...
Definition: gsttensor_demux.c:175
gst_tensor_demux_dispose
static void gst_tensor_demux_dispose(GObject *object)
dispose function for tensor demux (gst element vmethod)
Definition: gsttensor_demux.c:219
G_DEFINE_TYPE
G_DEFINE_TYPE(GstTensorDemux, gst_tensor_demux, GST_TYPE_ELEMENT)
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_tensors_config_is_static
#define gst_tensors_config_is_static(c)
Macro to check stream format (static tensors for caps negotiation)
Definition: nnstreamer_plugin_api_util.h:274
gst_tensor_buffer_append_memory
gboolean gst_tensor_buffer_append_memory(GstBuffer *buffer, GstMemory *memory, const GstTensorInfo *info)
Append memory to given buffer.
Definition: nnstreamer_plugin_api_impl.c:1688
GstTensorsInfo::format
tensor_format format
Definition: tensor_typedef.h:278
gst_tensor_demux_remove_src_pads
static void gst_tensor_demux_remove_src_pads(GstTensorDemux *tensor_demux)
function to remove srcpad list
Definition: gsttensor_demux.c:199