Doxygen Book
gsttensor_mux.c
Go to the documentation of this file.
1 
57 #ifdef HAVE_CONFIG_H
58 #include <config.h>
59 #endif
60 
61 #include <string.h>
62 #include <gst/gst.h>
63 #include <glib.h>
64 #include <nnstreamer_util.h>
65 
66 #include "gsttensor_mux.h"
67 
68 GST_DEBUG_CATEGORY_STATIC (gst_tensor_mux_debug);
69 #define GST_CAT_DEFAULT gst_tensor_mux_debug
70 
74 #ifndef DBG
75 #define DBG (!tensor_mux->silent)
76 #endif
77 
78 enum
79 {
84 };
85 
89 #define CAPS_STRING_SINK GST_TENSOR_CAP_DEFAULT ";" GST_TENSORS_CAP_MAKE ("{ static, flexible }")
90 
94 #define CAPS_STRING_SRC GST_TENSORS_CAP_MAKE ("{ static, flexible }")
95 
100 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
101  GST_PAD_SRC,
102  GST_PAD_ALWAYS,
103  GST_STATIC_CAPS (CAPS_STRING_SRC)
104  );
105 
106 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink_%u",
107  GST_PAD_SINK,
108  GST_PAD_REQUEST,
109  GST_STATIC_CAPS (CAPS_STRING_SINK)
110  );
111 
112 static gboolean gst_tensor_mux_src_event (GstPad * pad, GstObject * parent,
113  GstEvent * event);
114 static GstPad *gst_tensor_mux_request_new_pad (GstElement * element,
115  GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
116 static GstStateChangeReturn gst_tensor_mux_change_state (GstElement * element,
117  GstStateChange transition);
118 static gboolean gst_tensor_mux_sink_event (GstCollectPads * pads,
119  GstCollectData * data, GstEvent * event, GstTensorMux * tensor_mux);
120 static GstFlowReturn gst_tensor_mux_collected (GstCollectPads * pads,
121  GstTensorMux * tensor_mux);
122 static GstFlowReturn gst_tensor_mux_do_clip (GstCollectPads * pads,
123  GstCollectData * data, GstBuffer * buffer, GstBuffer ** out,
124  GstTensorMux * tensor_mux);
125 
126 static void gst_tensor_mux_set_property (GObject * object, guint prop_id,
127  const GValue * value, GParamSpec * pspec);
128 static void gst_tensor_mux_get_property (GObject * object, guint prop_id,
129  GValue * value, GParamSpec * pspec);
130 static void gst_tensor_mux_finalize (GObject * object);
131 
132 #define gst_tensor_mux_parent_class parent_class
133 G_DEFINE_TYPE (GstTensorMux, gst_tensor_mux, GST_TYPE_ELEMENT);
134 
138 static void
140 {
141  GObjectClass *gobject_class;
142  GstElementClass *gstelement_class;
143 
144  GST_DEBUG_CATEGORY_INIT (gst_tensor_mux_debug, "tensor_mux", 0,
145  "Element to merge tensor stream to tensors stream");
146 
147  gobject_class = (GObjectClass *) klass;
148  gstelement_class = (GstElementClass *) klass;
149 
150  parent_class = g_type_class_peek_parent (klass);
151 
152  gobject_class->finalize = gst_tensor_mux_finalize;
153  gobject_class->get_property = gst_tensor_mux_get_property;
154  gobject_class->set_property = gst_tensor_mux_set_property;
155 
156  g_object_class_install_property (gobject_class, PROP_SILENT,
157  g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
158  TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
159 
160  g_object_class_install_property (gobject_class, PROP_SYNC_MODE,
161  g_param_spec_string ("sync-mode", "Sync Mode",
162  "Time synchronization mode?", "", G_PARAM_READWRITE));
163 
164  g_object_class_install_property (gobject_class, PROP_SYNC_OPTION,
165  g_param_spec_string ("sync-option", "Sync Option",
166  "Option for the time synchronization mode ?", "", G_PARAM_READWRITE));
167 
168  gstelement_class->request_new_pad =
169  GST_DEBUG_FUNCPTR (gst_tensor_mux_request_new_pad);
170  gstelement_class->change_state =
171  GST_DEBUG_FUNCPTR (gst_tensor_mux_change_state);
172 
173  gst_element_class_add_pad_template (gstelement_class,
174  gst_static_pad_template_get (&sink_templ));
175  gst_element_class_add_pad_template (gstelement_class,
176  gst_static_pad_template_get (&src_templ));
177 
178  gst_element_class_set_details_simple (gstelement_class,
179  "TensorMux",
180  "Muxer/Tensor",
181  "Merge multiple tensor stream to tensors stream",
182  "Jijoong Moon <jijoong.moon@samsung.com>");
183 
184 }
185 
192 static void
194 {
195  GstElementClass *klass = GST_ELEMENT_GET_CLASS (tensor_mux);
196 
197  tensor_mux->srcpad =
198  gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
199  "src"), "src");
200  gst_pad_set_event_function (tensor_mux->srcpad, gst_tensor_mux_src_event);
201 
202  gst_element_add_pad (GST_ELEMENT (tensor_mux), tensor_mux->srcpad);
203 
204  tensor_mux->collect = gst_collect_pads_new ();
205  gst_collect_pads_set_event_function (tensor_mux->collect,
206  (GstCollectPadsEventFunction)
207  GST_DEBUG_FUNCPTR (gst_tensor_mux_sink_event), tensor_mux);
208  gst_collect_pads_set_function (tensor_mux->collect,
209  (GstCollectPadsFunction) GST_DEBUG_FUNCPTR (gst_tensor_mux_collected),
210  tensor_mux);
211  gst_collect_pads_set_clip_function (tensor_mux->collect,
212  (GstCollectPadsClipFunction) GST_DEBUG_FUNCPTR (gst_tensor_mux_do_clip),
213  tensor_mux);
214 
215  tensor_mux->silent = TRUE;
216  tensor_mux->sync.mode = SYNC_SLOWEST;
217  tensor_mux->sync.option = NULL;
218  tensor_mux->current_time = 0;
219  tensor_mux->need_set_time = TRUE;
221 }
222 
226 static void
227 gst_tensor_mux_finalize (GObject * object)
228 {
229  GstTensorMux *tensor_mux;
230 
231  tensor_mux = GST_TENSOR_MUX (object);
232 
233  if (tensor_mux->collect) {
234  gst_tensor_time_sync_flush (tensor_mux->collect);
235  gst_object_unref (tensor_mux->collect);
236  tensor_mux->collect = NULL;
237  }
238 
239  if (tensor_mux->sync.option) {
240  g_free (tensor_mux->sync.option);
241  tensor_mux->sync.option = NULL;
242  }
243 
245 
246  G_OBJECT_CLASS (parent_class)->finalize (object);
247 }
248 
252 static GstPad *
253 gst_tensor_mux_request_new_pad (GstElement * element, GstPadTemplate * templ,
254  const gchar * req_name, const GstCaps * caps)
255 {
256  GstPad *newpad;
257  GSList *walk = NULL;
258  GstTensorMux *tensor_mux;
259  gchar *name;
260  UNUSED (req_name);
261  UNUSED (caps);
262 
263  g_return_val_if_fail (templ != NULL, NULL);
264  g_return_val_if_fail (GST_IS_TENSOR_MUX (element), NULL);
265 
266  tensor_mux = GST_TENSOR_MUX (element);
267  walk = tensor_mux->collect->data;
268 
269  name = g_strdup_printf ("sink_%u", g_slist_length (walk));
270  newpad = gst_pad_new_from_template (templ, name);
271  g_free (name);
272 
273  if (newpad) {
274  GstTensorCollectPadData *tensormuxpad;
275  gboolean locked, waiting;
276 
277  locked = waiting = TRUE;
278 
279  if (tensor_mux->sync.mode == SYNC_REFRESH) {
280  locked = waiting = FALSE;
281  }
282 
283  tensormuxpad = (GstTensorCollectPadData *)
284  gst_collect_pads_add_pad (tensor_mux->collect, newpad,
285  sizeof (GstTensorCollectPadData), NULL, locked);
286 
287  /* NOTE: if locked is TRUE, waiting flag is not effective */
288  gst_collect_pads_set_waiting (tensor_mux->collect,
289  (GstCollectData *) tensormuxpad, waiting);
290 
291  gst_pad_set_element_private (newpad, tensormuxpad);
292  gst_element_add_pad (element, newpad);
293  } else {
294  GST_WARNING_OBJECT (tensor_mux, "failed to create request pad");
295  }
296  return newpad;
297 }
298 
302 static gboolean
303 gst_tensor_mux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
304 {
305  g_return_val_if_fail (event != NULL, FALSE);
306 
307  switch (GST_EVENT_TYPE (event)) {
308  case GST_EVENT_SEEK:
309  gst_event_unref (event);
310  return FALSE;
311  default:
312  break;
313  }
314 
315  return gst_pad_event_default (pad, parent, event);
316 }
317 
321 static void
322 gst_tensor_mux_set_waiting (GstTensorMux * tensor_mux, gboolean waiting)
323 {
324  if (tensor_mux->sync.mode == SYNC_REFRESH) {
325  GstCollectPads *pads = tensor_mux->collect;
326  GSList *walk = pads->data;
327 
328  while (walk) {
329  gst_collect_pads_set_waiting (pads, walk->data, waiting);
330  walk = g_slist_next (walk);
331  }
332  }
333 }
334 
338 static gboolean
339 gst_tensor_mux_sink_event (GstCollectPads * pads, GstCollectData * data,
340  GstEvent * event, GstTensorMux * tensor_mux)
341 {
342  g_return_val_if_fail (event != NULL, FALSE);
343 
344  switch (GST_EVENT_TYPE (event)) {
345  case GST_EVENT_FLUSH_STOP:
346  tensor_mux->need_segment = TRUE;
347  tensor_mux->need_set_time = TRUE;
348  gst_tensor_time_sync_flush (tensor_mux->collect);
349  break;
350  case GST_EVENT_EOS:
351  gst_tensor_mux_set_waiting (tensor_mux, FALSE);
352  break;
353  default:
354  break;
355  }
356 
357  return gst_collect_pads_event_default (pads, data, event, FALSE);
358 }
359 
367 static gboolean
369  GstBuffer * tensors_buf, gboolean * is_eos)
370 {
371  if (tensor_mux->need_set_time) {
373  &tensor_mux->sync, &tensor_mux->current_time, tensors_buf)) {
374  /* end-of-stream */
375  *is_eos = TRUE;
376  return FALSE;
377  }
378 
379  tensor_mux->need_set_time = FALSE;
380  silent_debug (tensor_mux, "Current Time : %" GST_TIME_FORMAT,
381  GST_TIME_ARGS (tensor_mux->current_time));
382  }
383 
385  &tensor_mux->sync, tensor_mux->current_time, tensors_buf,
386  &tensor_mux->tensors_config, is_eos);
387 }
388 
392 static gboolean
394 {
395  if (!tensor_mux->negotiated) {
396  GstCaps *caps;
397 
398  if (gst_tensors_config_validate (&tensor_mux->tensors_config)) {
399  caps = gst_tensor_pad_caps_from_config (tensor_mux->srcpad,
400  &tensor_mux->tensors_config);
401 
402  if (gst_pad_set_caps (tensor_mux->srcpad, caps)) {
403  tensor_mux->negotiated = TRUE;
404  }
405 
406  gst_caps_unref (caps);
407  }
408  }
409 
410  if (!tensor_mux->negotiated) {
411  GST_WARNING_OBJECT (tensor_mux, "failed to set caps");
412  GST_ELEMENT_ERROR (tensor_mux, CORE, NEGOTIATION, (NULL), (NULL));
413  }
414 
415  return tensor_mux->negotiated;
416 }
417 
421 static void
423  GstClockTime pts, GstClockTime dts)
424 {
425  if (tensor_mux->need_segment) {
426  GstSegment segment;
427  GstClockTime time = 0;
428 
429  if (GST_CLOCK_TIME_IS_VALID (dts)) {
430  time = dts;
431  } else if (GST_CLOCK_TIME_IS_VALID (pts)) {
432  time = pts;
433  }
434 
435  gst_segment_init (&segment, GST_FORMAT_TIME);
436  segment.start = time;
437  gst_pad_push_event (tensor_mux->srcpad, gst_event_new_segment (&segment));
438  tensor_mux->need_segment = FALSE;
439  }
440 }
441 
445 static GstBuffer *
446 gst_tensor_mux_chain_flex_tensor (GstTensorMux * tensor_mux, GstBuffer * buf)
447 {
448  GstBuffer *buffer;
449  GstMemory *mem, *new_mem;
450  GstTensorsInfo *info;
451  GstTensorInfo *_info;
452  GstTensorMetaInfo meta;
453  guint i;
454 
455  /* If input is flexible, do nothing. It is already flexible tensor. */
457  return buf;
458 
459  info = &tensor_mux->tensors_config.info;
460  buffer = gst_buffer_new ();
461 
462  for (i = 0; i < info->num_tensors; i++) {
463  mem = gst_tensor_buffer_get_nth_memory (buf, i);
464 
465  /* append header */
466  _info = gst_tensors_info_get_nth_info (info, i);
467  gst_tensor_info_convert_to_meta (_info, &meta);
468  new_mem = gst_tensor_meta_info_append_header (&meta, mem);
469  gst_memory_unref (mem);
470 
471  gst_tensor_buffer_append_memory (buffer, new_mem, _info);
472  }
473 
474  gst_buffer_copy_into (buffer, buf, GST_BUFFER_COPY_METADATA, 0, -1);
475  gst_buffer_unref (buf);
476  return buffer;
477 }
478 
485 static GstFlowReturn
486 gst_tensor_mux_collected (GstCollectPads * pads, GstTensorMux * tensor_mux)
487 {
488  GstFlowReturn ret = GST_FLOW_OK;
489  GstBuffer *tensors_buf;
490  gboolean isEOS = FALSE;
491  gboolean buf_collected = FALSE;
492 
493  GST_DEBUG_OBJECT (tensor_mux, " all pads are collected ");
494 
495  if (tensor_mux->need_stream_start) {
500  GstCollectData *data = (GstCollectData *) pads->data->data;
501  g_autofree gchar *sink_stream_id = gst_pad_get_stream_id (data->pad);
502  g_autofree gchar *element_name = gst_element_get_name (tensor_mux);
503  g_autofree gchar *pad_name = gst_pad_get_name (tensor_mux->srcpad);
504  g_autofree gchar *stream_id = g_strdup_printf ("%s-%s-nnsmux-%s-%08x",
505  GST_STR_NULL (sink_stream_id), element_name, pad_name, g_random_int ());
506 
507  gst_pad_push_event (tensor_mux->srcpad, gst_event_new_stream_start (stream_id));
508  tensor_mux->need_stream_start = FALSE;
509  }
510 
511  if ((tensors_buf = gst_buffer_new ()) == NULL) {
512  ml_logf ("gst_buffer_new() returns NULL. Out of memory?\n");
513  return GST_FLOW_ERROR;
514  }
515 
516  buf_collected =
517  gst_tensor_mux_collect_buffer (tensor_mux, tensors_buf, &isEOS);
518 
519  gst_tensor_mux_set_waiting (tensor_mux, TRUE);
520 
521  if (!buf_collected) {
522  if (isEOS) {
523  gst_pad_push_event (tensor_mux->srcpad, gst_event_new_eos ());
524  ret = GST_FLOW_EOS;
525  }
526 
527  gst_buffer_unref (tensors_buf);
528  return ret;
529  }
530 
531  if (!gst_tensor_mux_set_src_caps (tensor_mux)) {
532  gst_buffer_unref (tensors_buf);
533  return GST_FLOW_NOT_NEGOTIATED;
534  }
535 
536  gst_tensor_mux_send_segment_event (tensor_mux, GST_BUFFER_PTS (tensors_buf),
537  GST_BUFFER_DTS (tensors_buf));
538 
539  /* add header if output is flexible */
540  if (gst_tensor_pad_caps_is_flexible (tensor_mux->srcpad))
541  tensors_buf = gst_tensor_mux_chain_flex_tensor (tensor_mux, tensors_buf);
542 
543  ret = gst_pad_push (tensor_mux->srcpad, tensors_buf);
544  tensor_mux->need_set_time = TRUE;
545 
546  if (ret != GST_FLOW_OK) {
547  GST_WARNING_OBJECT (tensor_mux, "pushed outbuf, result = %s",
548  gst_flow_get_name (ret));
549  }
550 
551  return ret;
552 }
553 
557 static GstFlowReturn
558 gst_tensor_mux_do_clip (GstCollectPads * pads, GstCollectData * data,
559  GstBuffer * buffer, GstBuffer ** out, GstTensorMux * tensor_mux)
560 {
561  UNUSED (pads);
562  UNUSED (data);
563  gst_tensor_mux_set_waiting (tensor_mux, FALSE);
564  *out = buffer;
565  return GST_FLOW_OK;
566 }
567 
571 static void
573 {
574  tensor_mux->need_stream_start = TRUE;
575  tensor_mux->need_segment = TRUE;
576  tensor_mux->negotiated = FALSE;
577  gst_collect_pads_start (tensor_mux->collect);
578 }
579 
583 static GstStateChangeReturn
584 gst_tensor_mux_change_state (GstElement * element, GstStateChange transition)
585 {
586  GstTensorMux *tensor_mux;
587  GstStateChangeReturn ret;
588  tensor_mux = GST_TENSOR_MUX (element);
589  switch (transition) {
590  case GST_STATE_CHANGE_READY_TO_PAUSED:
591  gst_tensor_mux_ready_to_paused (tensor_mux);
592  break;
593  case GST_STATE_CHANGE_PAUSED_TO_READY:
594  gst_collect_pads_stop (tensor_mux->collect);
595  break;
596  default:
597  break;
598  }
599 
600  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
601  if (ret == GST_STATE_CHANGE_FAILURE)
602  return ret;
603  switch (transition) {
604  case GST_STATE_CHANGE_PAUSED_TO_READY:
605  break;
606  default:
607  break;
608  }
609 
610  return ret;
611 }
612 
616 static void
617 gst_tensor_mux_set_property (GObject * object, guint prop_id,
618  const GValue * value, GParamSpec * pspec)
619 {
620  GstTensorMux *tensor_mux = GST_TENSOR_MUX (object);
621  switch (prop_id) {
622  case PROP_SILENT:
623  tensor_mux->silent = g_value_get_boolean (value);
624  break;
625  case PROP_SYNC_MODE:
626  tensor_mux->sync.mode =
627  gst_tensor_time_sync_get_mode (g_value_get_string (value));
628  if (tensor_mux->sync.mode == SYNC_END) {
629  tensor_mux->sync.mode = SYNC_SLOWEST;
630  }
631  silent_debug (tensor_mux, "Mode = %d(%s)\n", tensor_mux->sync.mode,
634  break;
635  case PROP_SYNC_OPTION:
636  tensor_mux->sync.option = g_value_dup_string (value);
637  silent_debug (tensor_mux, "Option = %s\n", tensor_mux->sync.option);
639  break;
640  default:
641  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
642  break;
643  }
644 }
645 
649 static void
650 gst_tensor_mux_get_property (GObject * object, guint prop_id,
651  GValue * value, GParamSpec * pspec)
652 {
653  GstTensorMux *tensor_mux = GST_TENSOR_MUX (object);
654  switch (prop_id) {
655  case PROP_SILENT:
656  g_value_set_boolean (value, tensor_mux->silent);
657  break;
658  case PROP_SYNC_MODE:
659  g_value_set_string (value,
661  break;
662  case PROP_SYNC_OPTION:
663  g_value_set_string (value, tensor_mux->sync.option);
664  break;
665  default:
666  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
667  break;
668  }
669 }
PROP_SILENT
@ PROP_SILENT
Definition: gsttensor_mux.c:81
gst_tensors_config_is_flexible
#define gst_tensors_config_is_flexible(c)
Macro to check stream format (flexible tensors for caps negotiation)
Definition: nnstreamer_plugin_api_util.h:279
PROP_SYNC_MODE
@ PROP_SYNC_MODE
Definition: gsttensor_mux.c:82
gst_tensor_mux_send_segment_event
static void gst_tensor_mux_send_segment_event(GstTensorMux *tensor_mux, GstClockTime pts, GstClockTime dts)
Create a new segment event if necessary.
Definition: gsttensor_mux.c:422
data
svtc_1 data
Definition: gsttensor_if.c:844
GstTensorInfo
Internal data structure for tensor info.
Definition: tensor_typedef.h:261
GST_TENSOR_MUX
#define GST_TENSOR_MUX(obj)
Definition: gsttensor_mux.h:36
gst_tensor_mux_get_property
static void gst_tensor_mux_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
Get property (gst element vmethod)
Definition: gsttensor_mux.c:650
gst_tensor_mux_init
static void gst_tensor_mux_init(GstTensorMux *tensor_mux)
initialize the new element instantiate pads and add them to element set pad callback functions initia...
Definition: gsttensor_mux.c:193
gst_tensor_time_sync_set_option_data
gboolean gst_tensor_time_sync_set_option_data(tensor_time_sync_data *sync)
Setup time sync option.
Definition: nnstreamer_plugin_api_impl.c:126
FALSE
return FALSE
Definition: gsttensor_transform.c:590
_GstTensorMux::srcpad
GstPad * srcpad
Definition: gsttensor_mux.h:54
ml_logf
#define ml_logf
Definition: nnstreamer_log.h:80
GST_IS_TENSOR_MUX
#define GST_IS_TENSOR_MUX(obj)
Definition: gsttensor_mux.h:39
GstTensorsInfo
Internal meta data exchange format for a other/tensors instance.
Definition: tensor_typedef.h:273
gst_tensor_time_sync_buffer_from_collectpad
gboolean gst_tensor_time_sync_buffer_from_collectpad(GstCollectPads *collect, tensor_time_sync_data *sync, GstClockTime current_time, GstBuffer *tensors_buf, GstTensorsConfig *configs, gboolean *is_eos)
A function call to make tensors from collected pads. It decide which buffer is going to be used accor...
Definition: nnstreamer_plugin_api_impl.c:332
gst_tensor_mux_sink_event
static gboolean gst_tensor_mux_sink_event(GstCollectPads *pads, GstCollectData *data, GstEvent *event, GstTensorMux *tensor_mux)
sink event vmethod
Definition: gsttensor_mux.c:339
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
gst_tensor_time_sync_get_mode_string
const gchar * gst_tensor_time_sync_get_mode_string(tensor_time_sync_mode mode)
Get the time-sync mode string.
Definition: nnstreamer_plugin_api_impl.c:115
GstTensorMetaInfo
Data structure to describe a tensor data. This represents the basic information of a memory block for...
Definition: tensor_typedef.h:310
SYNC_END
@ SYNC_END
Definition: tensor_common.h:68
gst_tensor_mux_set_waiting
static void gst_tensor_mux_set_waiting(GstTensorMux *tensor_mux, gboolean waiting)
set pads waiting property
Definition: gsttensor_mux.c:322
gst_tensor_mux_do_clip
static GstFlowReturn gst_tensor_mux_do_clip(GstCollectPads *pads, GstCollectData *data, GstBuffer *buffer, GstBuffer **out, GstTensorMux *tensor_mux)
Gst Clip Pads Function which is called right after a buffer is received for each pad.
Definition: gsttensor_mux.c:558
SYNC_SLOWEST
@ SYNC_SLOWEST
Definition: tensor_common.h:65
gst_tensor_mux_change_state
static GstStateChangeReturn gst_tensor_mux_change_state(GstElement *element, GstStateChange transition)
change state (gst element vmethod)
Definition: gsttensor_mux.c:584
gst_tensor_mux_ready_to_paused
static void gst_tensor_mux_ready_to_paused(GstTensorMux *tensor_mux)
Ready --> Pasuse State Change.
Definition: gsttensor_mux.c:572
gst_tensor_mux_src_event
static gboolean gst_tensor_mux_src_event(GstPad *pad, GstObject *parent, GstEvent *event)
src event vmethod
Definition: gsttensor_mux.c:303
silent_debug
#define silent_debug(self,...)
Macro for debug message.
Definition: tensor_common.h:276
gst_tensor_pad_caps_is_flexible
#define gst_tensor_pad_caps_is_flexible(p)
Macro to check current pad caps is flexible tensor.
Definition: tensor_common.h:231
gst_tensor_meta_info_append_header
GstMemory * gst_tensor_meta_info_append_header(GstTensorMetaInfo *meta, GstMemory *mem)
Append header to memory.
Definition: nnstreamer_plugin_api_impl.c:1544
gst_tensor_mux_set_src_caps
static gboolean gst_tensor_mux_set_src_caps(GstTensorMux *tensor_mux)
Set src pad caps if src pad is not negotiated.
Definition: gsttensor_mux.c:393
g_free
g_free(self->option[(opnum) - 1])
opnum: \
_GstTensorMux::need_stream_start
gboolean need_stream_start
Definition: gsttensor_mux.h:59
_GstTensorMux::negotiated
gboolean negotiated
Definition: gsttensor_mux.h:57
g_value_set_string
g_value_set_string(value, self->option[opnum - 1])
opnum: \
_GstTensorMux::tensors_config
GstTensorsConfig tensors_config
Definition: gsttensor_mux.h:64
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
gst_tensor_mux_request_new_pad
static GstPad * gst_tensor_mux_request_new_pad(GstElement *element, GstPadTemplate *templ, const gchar *name, const GstCaps *caps)
making new request pad (gst element vmethod)
Definition: gsttensor_mux.c:253
gst_tensor_info_convert_to_meta
gboolean gst_tensor_info_convert_to_meta(GstTensorInfo *info, GstTensorMetaInfo *meta)
Convert GstTensorInfo structure to GstTensorMetaInfo.
Definition: nnstreamer_plugin_api_util_impl.c:260
gst_tensor_mux_collected
static GstFlowReturn gst_tensor_mux_collected(GstCollectPads *pads, GstTensorMux *tensor_mux)
Gst Collect Pads Function which is called once collect pads done.
Definition: gsttensor_mux.c:486
_GstTensorMux::need_segment
gboolean need_segment
Definition: gsttensor_mux.h:58
gsttensor_mux.h
GStreamer plugin to mux tensors (as a filter for other general neural network filters)
_GstTensorMux::collect
GstCollectPads * collect
Definition: gsttensor_mux.h:56
src_templ
static GstStaticPadTemplate src_templ
the capabilities of the inputs and outputs. describe the real formats here.
Definition: gsttensor_mux.c:100
TRUE
return TRUE
Definition: gsttensor_if.c:897
UNUSED
#define UNUSED(expr)
Definition: mqttcommon.h:19
GstTensorCollectPadData
Internal data structure for Collect Pad in mux / merge.
Definition: tensor_common.h:93
nnstreamer_util.h
Optional NNStreamer utility functions for sub-plugin writers and users.
gst_tensor_mux_set_property
static void gst_tensor_mux_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
Get property (gst element vmethod)
Definition: gsttensor_mux.c:617
_tensor_time_sync_data::mode
tensor_time_sync_mode mode
Definition: tensor_common.h:83
sink_templ
static GstStaticPadTemplate sink_templ
Definition: gsttensor_mux.c:106
_GstTensorMux::sync
tensor_time_sync_data sync
Definition: gsttensor_mux.h:53
GST_DEBUG_CATEGORY_STATIC
GST_DEBUG_CATEGORY_STATIC(gst_tensor_mux_debug)
_GstTensorMux::silent
gboolean silent
Definition: gsttensor_mux.h:52
CAPS_STRING_SRC
#define CAPS_STRING_SRC
Default caps string for src pad.
Definition: gsttensor_mux.c:94
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
_tensor_time_sync_data::option
gchar * option
Definition: tensor_common.h:84
gst_tensor_mux_class_init
static void gst_tensor_mux_class_init(GstTensorMuxClass *klass)
initialize the tensor_mux's class
Definition: gsttensor_mux.c:139
PROP_0
@ PROP_0
Definition: gsttensor_mux.c:80
gst_tensor_mux_chain_flex_tensor
static GstBuffer * gst_tensor_mux_chain_flex_tensor(GstTensorMux *tensor_mux, GstBuffer *buf)
Process flex tensor.
Definition: gsttensor_mux.c:446
_GstTensorMuxClass
GstTensroMuxClass inherits GstElementClass.
Definition: gsttensor_mux.h:70
G_DEFINE_TYPE
G_DEFINE_TYPE(GstTensorMux, gst_tensor_mux, GST_TYPE_ELEMENT)
_GstTensorMux::current_time
GstClockTime current_time
Definition: gsttensor_mux.h:62
gst_tensor_mux_collect_buffer
static gboolean gst_tensor_mux_collect_buffer(GstTensorMux *tensor_mux, GstBuffer *tensors_buf, gboolean *is_eos)
Looping to generete output buffer for srcpad.
Definition: gsttensor_mux.c:368
GstTensorsInfo::num_tensors
unsigned int num_tensors
Definition: tensor_typedef.h:275
gst_tensor_mux_finalize
static void gst_tensor_mux_finalize(GObject *object)
finalize vmethod
Definition: gsttensor_mux.c:227
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_SYNC_OPTION
@ PROP_SYNC_OPTION
Definition: gsttensor_mux.c:83
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
_GstTensorMux::need_set_time
gboolean need_set_time
Definition: gsttensor_mux.h:61
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
gst_tensor_time_sync_get_current_time
gboolean gst_tensor_time_sync_get_current_time(GstCollectPads *collect, tensor_time_sync_data *sync, GstClockTime *current_time, GstBuffer *tensors_buf)
A function call to decide current timestamp among collected pads based on PTS. It will decide current...
Definition: nnstreamer_plugin_api_impl.c:203
_GstTensorMux
Tensor Muxer data structure.
Definition: gsttensor_mux.h:48
CAPS_STRING_SINK
#define CAPS_STRING_SINK
Default caps string for sink pad.
Definition: gsttensor_mux.c:89
gst_tensor_time_sync_get_mode
tensor_time_sync_mode gst_tensor_time_sync_get_mode(const gchar *str)
Get the corresponding mode from the string value.
Definition: nnstreamer_plugin_api_impl.c:101
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
SYNC_REFRESH
@ SYNC_REFRESH
Definition: tensor_common.h:67
gst_tensor_time_sync_flush
void gst_tensor_time_sync_flush(GstCollectPads *collect)
A function to be called while processing a flushing event. It should clear old buffer and reset pad d...
Definition: nnstreamer_plugin_api_impl.c:263