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 
234 static gboolean
235 gst_tensor_demux_parse_caps (GstTensorDemux * tensor_demux, GstCaps * caps)
236 {
237  GstStructure *structure;
238  GstTensorsConfig *config;
239 
240  config = &tensor_demux->tensors_config;
241 
242  structure = gst_caps_get_structure (caps, 0);
243  gst_tensors_config_from_structure (config, structure);
244 
245  return gst_tensors_config_validate (config);
246 }
247 
251 static gboolean
252 gst_tensor_demux_event (GstPad * pad, GstObject * parent, GstEvent * event)
253 {
254  GstTensorDemux *tensor_demux;
255  tensor_demux = GST_TENSOR_DEMUX (parent);
256 
257  switch (GST_EVENT_TYPE (event)) {
258  case GST_EVENT_CAPS:
259  {
260  GstCaps *caps;
261  gst_event_parse_caps (event, &caps);
262  gst_tensor_demux_parse_caps (tensor_demux, caps);
263  break;
264  }
265  case GST_EVENT_EOS:
266  if (!tensor_demux->srcpads) {
267  GST_ELEMENT_ERROR (tensor_demux, STREAM, WRONG_TYPE,
268  ("This stream contains no valid stremas."),
269  ("Got EOS before adding any pads"));
270  gst_event_unref (event);
271  return FALSE;
272  }
273  break;
274  default:
275  break;
276  }
277 
278  return gst_pad_event_default (pad, parent, event);
279 }
280 
289 static gboolean
291  GstTensorsConfig * config, const guint nth, const guint total)
292 {
293  gst_tensors_config_init (config);
294 
295  if (tensor_demux->tensorpick != NULL) {
296  gchar *selected_tensor;
297  gchar **strv;
298  guint i, num, idx;
299 
300  g_assert (g_list_length (tensor_demux->tensorpick) >= nth);
301 
302  selected_tensor = (gchar *) g_list_nth_data (tensor_demux->tensorpick, nth);
303  strv = g_strsplit_set (selected_tensor, ":+", -1);
304  num = g_strv_length (strv);
305 
306  for (i = 0; i < num; i++) {
307  idx = (guint) g_ascii_strtoll (strv[i], NULL, 10);
308 
309  /* Internal error, handle invalid index. */
310  if (idx >= total) {
311  g_strfreev (strv);
312  return FALSE;
313  }
314 
317  idx));
318  }
319 
320  config->info.num_tensors = num;
321  g_strfreev (strv);
322  } else {
323  /* Internal error, handle invalid index. */
324  if (nth >= total)
325  return FALSE;
326 
327  config->info.num_tensors = 1;
328  gst_tensor_info_copy (&config->info.info[0],
330  nth));
331  }
332 
333  config->info.format = tensor_demux->tensors_config.info.format;
334  config->rate_n = tensor_demux->tensors_config.rate_n;
335  config->rate_d = tensor_demux->tensors_config.rate_d;
336  return TRUE;
337 }
338 
348 static GstTensorPad *
350  gboolean * created, const guint nth, const guint total)
351 {
352  GstElement *element = GST_ELEMENT_CAST (tensor_demux);
353  g_autofree gchar *element_name = gst_element_get_name (element);
354  GSList *walk;
355  GstPad *pad;
356  GstTensorPad *tensorpad;
357  gchar *name;
358  GstEvent *event;
359  gchar *stream_id;
360  GstCaps *caps = NULL;
361  GstTensorsConfig config;
362 
363  walk = tensor_demux->srcpads;
364  while (walk) {
365  GstTensorPad *pad = (GstTensorPad *) walk->data;
366  if (nth == pad->nth) {
367  if (created) {
368  *created = FALSE;
369  }
370  return pad;
371  }
372  walk = walk->next;
373  }
374 
375  tensorpad = g_new0 (GstTensorPad, 1);
376  g_assert (tensorpad != NULL);
377  GST_DEBUG_OBJECT (tensor_demux, "creating pad: %d(%dth)",
378  tensor_demux->num_srcpads, nth);
379 
380  name = g_strdup_printf ("src_%u", tensor_demux->num_srcpads);
381  pad = gst_pad_new_from_static_template (&src_templ, name);
382  stream_id = gst_pad_create_stream_id_printf (pad, element,
383  "%s-nnsdemux-%s-%08x", element_name, name, g_random_int ());
384  g_free (name);
385 
386  tensorpad->pad = pad;
387  tensorpad->nth = nth;
388  tensorpad->last_ret = GST_FLOW_OK;
389  tensorpad->last_ts = GST_CLOCK_TIME_NONE;
390 
391  tensor_demux->srcpads = g_slist_append (tensor_demux->srcpads, tensorpad);
392  tensor_demux->num_srcpads++;
393 
394  gst_pad_use_fixed_caps (pad);
395  gst_pad_set_active (pad, TRUE);
396  gst_element_add_pad (GST_ELEMENT_CAST (tensor_demux), pad);
397 
398  if (!tensor_demux->have_group_id) {
399  event =
400  gst_pad_get_sticky_event (tensor_demux->sinkpad, GST_EVENT_STREAM_START,
401  0);
402  if (event) {
403  tensor_demux->have_group_id =
404  gst_event_parse_group_id (event, &tensor_demux->group_id);
405  gst_event_unref (event);
406  } else if (!tensor_demux->have_group_id) {
407  tensor_demux->have_group_id = TRUE;
408  tensor_demux->group_id = gst_util_group_id_next ();
409  }
410  }
411 
412  event = gst_event_new_stream_start (stream_id);
413  if (tensor_demux->have_group_id)
414  gst_event_set_group_id (event, tensor_demux->group_id);
415 
416  gst_pad_store_sticky_event (pad, event);
417  g_free (stream_id);
418  gst_event_unref (event);
419 
420  /* configure nth pad caps */
421  if (gst_tensor_demux_get_tensor_config (tensor_demux, &config, nth, total)) {
422  caps = gst_tensor_pad_caps_from_config (pad, &config);
423 
424  gst_pad_set_caps (pad, caps);
425  gst_caps_unref (caps);
426  } else {
427  GST_WARNING_OBJECT (tensor_demux, "Unable to set pad caps");
428  }
429 
430  if (created) {
431  *created = TRUE;
432  }
433 
434  if (tensor_demux->tensorpick != NULL) {
435  GST_DEBUG_OBJECT (tensor_demux, "TensorPick is set! : %dth tensor\n", nth);
436  if (g_list_length (tensor_demux->tensorpick) == tensor_demux->num_srcpads) {
437  gst_element_no_more_pads (GST_ELEMENT_CAST (tensor_demux));
438  }
439  }
440 
441  gst_tensors_config_free (&config);
442  return tensorpad;
443 }
444 
452 static GstFlowReturn
454  GstTensorPad * pad, GstFlowReturn ret)
455 {
456  GSList *walk;
457  pad->last_ret = ret;
458 
459  if (ret != GST_FLOW_NOT_LINKED)
460  goto done;
461 
462  for (walk = tensor_demux->srcpads; walk; walk = g_slist_next (walk)) {
463  GstTensorPad *opad = (GstTensorPad *) walk->data;
464  ret = opad->last_ret;
465  if (ret != GST_FLOW_NOT_LINKED)
466  goto done;
467  }
468 done:
469  return ret;
470 }
471 
475 static GstFlowReturn
476 gst_tensor_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
477 {
478  guint num_tensors, num_srcs, i, idx;
479  GstFlowReturn res = GST_FLOW_OK;
480  GstTensorDemux *tensor_demux;
481  GList *list = NULL;
482  GstTensorInfo *_info;
483 
484  UNUSED (pad);
485  tensor_demux = GST_TENSOR_DEMUX (parent);
486 
487  buf = gst_tensor_buffer_from_config (buf, &tensor_demux->tensors_config);
488 
494  num_tensors = gst_tensor_buffer_get_count (buf);
495  if (gst_tensors_config_is_static (&tensor_demux->tensors_config))
496  g_assert (tensor_demux->tensors_config.info.num_tensors == num_tensors);
497 
498  GST_DEBUG_OBJECT (tensor_demux, " Number of Tensors: %d", num_tensors);
499 
500  num_srcs = num_tensors;
501  if (tensor_demux->tensorpick != NULL) {
502  num_srcs = g_list_length (tensor_demux->tensorpick);
503  list = tensor_demux->tensorpick;
504  }
505 
506  for (i = 0; i < num_srcs; i++) {
507  GstTensorPad *srcpad;
508  GstBuffer *outbuf;
509  GstMemory *mem;
510  gboolean created;
511  GstClockTime ts;
512 
513  srcpad = gst_tensor_demux_get_tensor_pad (tensor_demux, &created, i,
514  num_tensors);
515  outbuf = gst_buffer_new ();
516 
517  if (tensor_demux->tensorpick != NULL) {
518  guint num, j;
519  gchar **strv = g_strsplit_set ((gchar *) list->data, ":+", -1);
520 
521  num = g_strv_length (strv);
522  for (j = 0; j < num; j++) {
523  idx = (guint) g_ascii_strtoll (strv[j], NULL, 10);
524  _info =
526  idx);
527  mem = gst_tensor_buffer_get_nth_memory (buf, idx);
528  if (!gst_tensor_buffer_append_memory (outbuf, mem, _info)) {
529  gst_buffer_unref (outbuf);
530  res = GST_FLOW_ERROR;
531  goto error;
532  }
533  }
534  g_strfreev (strv);
535  list = list->next;
536  } else {
537  _info =
539  mem = gst_tensor_buffer_get_nth_memory (buf, i);
540  if (!gst_tensor_buffer_append_memory (outbuf, mem, _info)) {
541  gst_buffer_unref (outbuf);
542  res = GST_FLOW_ERROR;
543  goto error;
544  }
545  }
546 
547  ts = GST_BUFFER_TIMESTAMP (buf);
548 
549  if (created) {
550  GstSegment segment;
551  gst_segment_init (&segment, GST_FORMAT_TIME);
552  gst_pad_push_event (srcpad->pad, gst_event_new_segment (&segment));
553  }
554 
555  outbuf = gst_buffer_make_writable (outbuf);
556 
557  /* metadata from incoming buffer */
558  gst_buffer_copy_into (outbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1);
559 
560  if (srcpad->last_ts == GST_CLOCK_TIME_NONE || srcpad->last_ts != ts) {
561  srcpad->last_ts = ts;
562  } else {
563  GST_DEBUG_OBJECT (tensor_demux, "invalid timestamp %" GST_TIME_FORMAT,
564  GST_TIME_ARGS (ts));
565  }
566 
567  GST_DEBUG_OBJECT (tensor_demux,
568  "pushing buffer with timestamp %" GST_TIME_FORMAT,
569  GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
570  res = gst_pad_push (srcpad->pad, outbuf);
571  res = gst_tensor_demux_combine_flows (tensor_demux, srcpad, res);
572 
573  if (res != GST_FLOW_OK)
574  break;
575  }
576 
577 error:
578  gst_buffer_unref (buf);
579  return res;
580 }
581 
585 static GstStateChangeReturn
586 gst_tensor_demux_change_state (GstElement * element, GstStateChange transition)
587 {
588  GstTensorDemux *tensor_demux;
589  GstStateChangeReturn ret;
590  tensor_demux = GST_TENSOR_DEMUX (element);
591  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
592  if (ret == GST_STATE_CHANGE_FAILURE)
593  return ret;
594  switch (transition) {
595  case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
596  break;
597  case GST_STATE_CHANGE_PAUSED_TO_READY:
598  tensor_demux->group_id = G_MAXUINT;
599  tensor_demux->have_group_id = FALSE;
600  gst_tensor_demux_remove_src_pads (tensor_demux);
601  break;
602  case GST_STATE_CHANGE_READY_TO_NULL:
603  break;
604  default:
605  break;
606  }
607 
608  return ret;
609 }
610 
614 static void
615 gst_tensor_demux_set_property (GObject * object, guint prop_id,
616  const GValue * value, GParamSpec * pspec)
617 {
618  GstTensorDemux *filter = GST_TENSOR_DEMUX (object);
619  switch (prop_id) {
620  case PROP_SILENT:
621  filter->silent = g_value_get_boolean (value);
622  break;
623  case PROP_TENSORPICK:
624  {
625  guint i;
626  const gchar *param = g_value_get_string (value);
627  gchar **strv = g_strsplit_set (param, ",.;/", -1);
628  guint num = g_strv_length (strv);
629 
630  /* Before setting the new Tensor Pick data, the existing one should be removed. */
631  if (filter->tensorpick) {
632  g_list_free_full (filter->tensorpick, g_free);
633  filter->tensorpick = NULL;
634  }
635  for (i = 0; i < num; i++) {
636  gchar *tmp = g_strdup (strv[i]);
637  filter->tensorpick = g_list_append (filter->tensorpick, tmp);
638  }
639  g_strfreev (strv);
640  break;
641  }
642  default:
643  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
644  break;
645  }
646 }
647 
651 static void
652 gst_tensor_demux_get_property (GObject * object, guint prop_id,
653  GValue * value, GParamSpec * pspec)
654 {
655  GstTensorDemux *filter = GST_TENSOR_DEMUX (object);
656  switch (prop_id) {
657  case PROP_SILENT:
658  g_value_set_boolean (value, filter->silent);
659  break;
660  case PROP_TENSORPICK:
661  {
662  GList *list;
663  char *p;
664  GPtrArray *arr = g_ptr_array_new ();
665  gchar **strings;
666 
667  for (list = filter->tensorpick; list != NULL; list = list->next) {
668  g_ptr_array_add (arr, g_strdup_printf ("%s", (gchar *) list->data));
669  }
670  g_ptr_array_add (arr, NULL);
671  strings = (gchar **) g_ptr_array_free (arr, FALSE);
672  p = g_strjoinv (",", strings);
673  g_strfreev (strings);
674  g_value_take_string (value, p);
675  break;
676  }
677  default:
678  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
679  break;
680  }
681 }
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:652
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:349
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:586
_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:590
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:615
_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:252
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:897
UNUSED
#define UNUSED(expr)
Definition: mqttcommon.h:19
gst_tensor_demux_parse_caps
static gboolean gst_tensor_demux_parse_caps(GstTensorDemux *tensor_demux, GstCaps *caps)
Parse caps and configure tensors info.
Definition: gsttensor_demux.c:235
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:476
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:290
_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:453
_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:1586
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:1813
GstTensorsConfig::info
GstTensorsInfo info
Definition: tensor_typedef.h:286
gst_tensors_config_validate
gboolean gst_tensors_config_validate(const GstTensorsConfig *config)
Check the tensors are all configured (for other/tensors)
Definition: nnstreamer_plugin_api_util_impl.c:858
_GstTensorDemux::tensorpick
GList * tensorpick
Definition: gsttensor_demux.h:58
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
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:1666
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