Doxygen Book
gsttensor_aggregator.c
Go to the documentation of this file.
1 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 #include <string.h>
34 #include "gsttensor_aggregator.h"
35 #include "tensor_meta.h"
36 #include <nnstreamer_util.h>
37 
41 #ifndef DBG
42 #define DBG (!self->silent)
43 #endif
44 
45 #define silent_debug_config(self,c,msg) do { \
46  if (DBG) { \
47  if (c) { \
48  gchar *dim_str; \
49  dim_str = gst_tensor_get_dimension_string ((c)->info.info[0].dimension); \
50  GST_DEBUG_OBJECT (self, msg " type=%d dim=%s rate=%d/%d", (c)->info.info[0].type, dim_str, (c)->rate_n, (c)->rate_d); \
51  g_free (dim_str); \
52  } \
53  } \
54 } while (0)
55 
56 GST_DEBUG_CATEGORY_STATIC (gst_tensor_aggregator_debug);
57 #define GST_CAT_DEFAULT gst_tensor_aggregator_debug
58 
62 enum
63 {
71 };
72 
76 #define DEFAULT_SILENT TRUE
77 
81 #define DEFAULT_FRAMES_IN 1
82 
86 #define DEFAULT_FRAMES_OUT 1
87 
91 #define DEFAULT_FRAMES_FLUSH 0
92 
96 #define DEFAULT_FRAMES_DIMENSION (NNS_TENSOR_RANK_LIMIT - 1)
97 
101 #define DEFAULT_CONCAT TRUE
102 
106 #define CAPS_STRING GST_TENSOR_CAP_DEFAULT ";" GST_TENSORS_CAP_WITH_NUM ("1")
107 
111 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
112  GST_PAD_SINK,
113  GST_PAD_ALWAYS,
114  GST_STATIC_CAPS (CAPS_STRING));
115 
119 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
120  GST_PAD_SRC,
121  GST_PAD_ALWAYS,
122  GST_STATIC_CAPS (CAPS_STRING));
123 
124 #define gst_tensor_aggregator_parent_class parent_class
125 G_DEFINE_TYPE (GstTensorAggregator, gst_tensor_aggregator, GST_TYPE_ELEMENT);
126 
127 static void gst_tensor_aggregator_finalize (GObject * object);
128 static void gst_tensor_aggregator_set_property (GObject * object,
129  guint prop_id, const GValue * value, GParamSpec * pspec);
130 static void gst_tensor_aggregator_get_property (GObject * object,
131  guint prop_id, GValue * value, GParamSpec * pspec);
132 
133 static gboolean gst_tensor_aggregator_sink_event (GstPad * pad,
134  GstObject * parent, GstEvent * event);
135 static gboolean gst_tensor_aggregator_sink_query (GstPad * pad,
136  GstObject * parent, GstQuery * query);
137 static gboolean gst_tensor_aggregator_src_query (GstPad * pad,
138  GstObject * parent, GstQuery * query);
139 static GstFlowReturn gst_tensor_aggregator_chain (GstPad * pad,
140  GstObject * parent, GstBuffer * buf);
141 static GstStateChangeReturn
142 gst_tensor_aggregator_change_state (GstElement * element,
143  GstStateChange transition);
144 
147  GstPad * pad, GstCaps * filter);
149  const GstCaps * caps);
150 
154 static void
156 {
157  GObjectClass *object_class;
158  GstElementClass *element_class;
159 
160  GST_DEBUG_CATEGORY_INIT (gst_tensor_aggregator_debug, "tensor_aggregator", 0,
161  "Element to aggregate tensor stream");
162 
163  object_class = (GObjectClass *) klass;
164  element_class = (GstElementClass *) klass;
165 
166  object_class->set_property = gst_tensor_aggregator_set_property;
167  object_class->get_property = gst_tensor_aggregator_get_property;
168  object_class->finalize = gst_tensor_aggregator_finalize;
169 
177  g_object_class_install_property (object_class, PROP_FRAMES_IN,
178  g_param_spec_uint ("frames-in", "Frames in input",
179  "The number of frames in incoming buffer", 1, G_MAXUINT,
180  DEFAULT_FRAMES_IN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
181 
188  g_object_class_install_property (object_class, PROP_FRAMES_OUT,
189  g_param_spec_uint ("frames-out", "Frames in output",
190  "The number of frames in outgoing buffer", 1, G_MAXUINT,
191  DEFAULT_FRAMES_OUT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
192 
200  g_object_class_install_property (object_class, PROP_FRAMES_FLUSH,
201  g_param_spec_uint ("frames-flush", "Frames to flush",
202  "The number of frames to flush (0 to flush all output)", 0, G_MAXUINT,
203  DEFAULT_FRAMES_FLUSH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
204 
212  g_object_class_install_property (object_class, PROP_FRAMES_DIMENSION,
213  g_param_spec_uint ("frames-dim", "Dimension index of frames",
214  "The dimension index of frames in tensor",
216  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
217 
224  g_object_class_install_property (object_class, PROP_CONCAT,
225  g_param_spec_boolean ("concat", "Concat", "Concatenate output buffer",
226  DEFAULT_CONCAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
227 
233  g_object_class_install_property (object_class, PROP_SILENT,
234  g_param_spec_boolean ("silent", "Silent", "Produce verbose output",
235  DEFAULT_SILENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
236 
237  gst_element_class_set_static_metadata (element_class,
238  "TensorAggregator",
239  "Filter/Tensor",
240  "Element to aggregate tensor stream", "Samsung Electronics Co., Ltd.");
241 
242  gst_element_class_add_pad_template (element_class,
243  gst_static_pad_template_get (&src_template));
244  gst_element_class_add_pad_template (element_class,
245  gst_static_pad_template_get (&sink_template));
246 
247  element_class->change_state = gst_tensor_aggregator_change_state;
248 }
249 
253 static void
255 {
257  self->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
258  gst_pad_set_event_function (self->sinkpad,
259  GST_DEBUG_FUNCPTR (gst_tensor_aggregator_sink_event));
260  gst_pad_set_query_function (self->sinkpad,
261  GST_DEBUG_FUNCPTR (gst_tensor_aggregator_sink_query));
262  gst_pad_set_chain_function (self->sinkpad,
263  GST_DEBUG_FUNCPTR (gst_tensor_aggregator_chain));
264  GST_PAD_SET_PROXY_CAPS (self->sinkpad);
265  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
266 
268  self->srcpad = gst_pad_new_from_static_template (&src_template, "src");
269  gst_pad_set_query_function (self->srcpad,
270  GST_DEBUG_FUNCPTR (gst_tensor_aggregator_src_query));
271  GST_PAD_SET_PROXY_CAPS (self->srcpad);
272  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
273 
275  self->silent = DEFAULT_SILENT;
276  self->frames_in = DEFAULT_FRAMES_IN;
277  self->frames_out = DEFAULT_FRAMES_OUT;
278  self->frames_flush = DEFAULT_FRAMES_FLUSH;
279  self->frames_dim = DEFAULT_FRAMES_DIMENSION;
280  self->concat = DEFAULT_CONCAT;
281 
282  self->tensor_configured = FALSE;
283  gst_tensors_config_init (&self->in_config);
284  gst_tensors_config_init (&self->out_config);
285 
286  self->adapter_table = gst_tensor_aggregation_init ();
288 }
289 
293 static void
295 {
296  GstTensorAggregator *self;
297 
298  self = GST_TENSOR_AGGREGATOR (object);
299 
301 
302  gst_tensors_config_free (&self->in_config);
303  gst_tensors_config_free (&self->out_config);
304  g_hash_table_destroy (self->adapter_table);
305 
306  G_OBJECT_CLASS (parent_class)->finalize (object);
307 }
308 
312 static void
313 gst_tensor_aggregator_set_property (GObject * object, guint prop_id,
314  const GValue * value, GParamSpec * pspec)
315 {
316  GstTensorAggregator *self;
317 
318  self = GST_TENSOR_AGGREGATOR (object);
319 
320  switch (prop_id) {
321  case PROP_FRAMES_IN:
322  self->frames_in = g_value_get_uint (value);
323  break;
324  case PROP_FRAMES_OUT:
325  self->frames_out = g_value_get_uint (value);
326  break;
327  case PROP_FRAMES_FLUSH:
328  self->frames_flush = g_value_get_uint (value);
329  break;
331  self->frames_dim = g_value_get_uint (value);
332  break;
333  case PROP_CONCAT:
334  self->concat = g_value_get_boolean (value);
335  break;
336  case PROP_SILENT:
337  self->silent = g_value_get_boolean (value);
338  break;
339  default:
340  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
341  break;
342  }
343 }
344 
348 static void
349 gst_tensor_aggregator_get_property (GObject * object, guint prop_id,
350  GValue * value, GParamSpec * pspec)
351 {
352  GstTensorAggregator *self;
353 
354  self = GST_TENSOR_AGGREGATOR (object);
355 
356  switch (prop_id) {
357  case PROP_FRAMES_IN:
358  g_value_set_uint (value, self->frames_in);
359  break;
360  case PROP_FRAMES_OUT:
361  g_value_set_uint (value, self->frames_out);
362  break;
363  case PROP_FRAMES_FLUSH:
364  g_value_set_uint (value, self->frames_flush);
365  break;
367  g_value_set_uint (value, self->frames_dim);
368  break;
369  case PROP_CONCAT:
370  g_value_set_boolean (value, self->concat);
371  break;
372  case PROP_SILENT:
373  g_value_set_boolean (value, self->silent);
374  break;
375  default:
376  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
377  break;
378  }
379 }
380 
384 static gboolean
385 gst_tensor_aggregator_sink_event (GstPad * pad, GstObject * parent,
386  GstEvent * event)
387 {
388  GstTensorAggregator *self;
389 
390  self = GST_TENSOR_AGGREGATOR (parent);
391 
392  GST_DEBUG_OBJECT (self, "Received %s event: %" GST_PTR_FORMAT,
393  GST_EVENT_TYPE_NAME (event), event);
394 
395  switch (GST_EVENT_TYPE (event)) {
396  case GST_EVENT_CAPS:
397  {
398  GstCaps *in_caps;
399  GstCaps *out_caps;
400 
401  gst_event_parse_caps (event, &in_caps);
402  silent_debug_caps (self, in_caps, "in-caps");
403 
404  if (gst_tensor_aggregator_parse_caps (self, in_caps)) {
405  gboolean ret = FALSE;
406 
407  out_caps =
408  gst_tensor_pad_caps_from_config (self->srcpad, &self->out_config);
409  silent_debug_caps (self, out_caps, "out-caps");
410 
411  ret = gst_pad_set_caps (self->srcpad, out_caps);
412 
413  gst_event_unref (event);
414  gst_caps_unref (out_caps);
415 
416  return ret;
417  }
418  break;
419  }
420  case GST_EVENT_FLUSH_STOP:
422  break;
423  default:
424  break;
425  }
426 
427  return gst_pad_event_default (pad, parent, event);
428 }
429 
433 static gboolean
434 gst_tensor_aggregator_sink_query (GstPad * pad, GstObject * parent,
435  GstQuery * query)
436 {
437  GstTensorAggregator *self;
438 
439  self = GST_TENSOR_AGGREGATOR (parent);
440 
441  GST_DEBUG_OBJECT (self, "Received %s query: %" GST_PTR_FORMAT,
442  GST_QUERY_TYPE_NAME (query), query);
443 
444  switch (GST_QUERY_TYPE (query)) {
445  case GST_QUERY_CAPS:
446  {
447  GstCaps *caps;
448  GstCaps *filter;
449 
450  gst_query_parse_caps (query, &filter);
451  caps = gst_tensor_aggregator_query_caps (self, pad, filter);
452 
453  gst_query_set_caps_result (query, caps);
454  gst_caps_unref (caps);
455  return TRUE;
456  }
457  case GST_QUERY_ACCEPT_CAPS:
458  {
459  GstCaps *caps;
460  GstCaps *template_caps;
461  gboolean res = FALSE;
462 
463  gst_query_parse_accept_caps (query, &caps);
464  silent_debug_caps (self, caps, "accept-caps");
465 
466  if (gst_caps_is_fixed (caps)) {
467  template_caps = gst_pad_get_pad_template_caps (pad);
468 
469  res = gst_caps_can_intersect (template_caps, caps);
470  gst_caps_unref (template_caps);
471  }
472 
473  gst_query_set_accept_caps_result (query, res);
474  return TRUE;
475  }
476  default:
477  break;
478  }
479 
480  return gst_pad_query_default (pad, parent, query);
481 }
482 
486 static gboolean
487 gst_tensor_aggregator_src_query (GstPad * pad, GstObject * parent,
488  GstQuery * query)
489 {
490  GstTensorAggregator *self;
491 
492  self = GST_TENSOR_AGGREGATOR (parent);
493 
494  GST_DEBUG_OBJECT (self, "Received %s query: %" GST_PTR_FORMAT,
495  GST_QUERY_TYPE_NAME (query), query);
496 
497  switch (GST_QUERY_TYPE (query)) {
498  case GST_QUERY_CAPS:
499  {
500  GstCaps *caps;
501  GstCaps *filter;
502 
503  gst_query_parse_caps (query, &filter);
504  caps = gst_tensor_aggregator_query_caps (self, pad, filter);
505 
506  gst_query_set_caps_result (query, caps);
507  gst_caps_unref (caps);
508  return TRUE;
509  }
510  default:
511  break;
512  }
513 
514  return gst_pad_query_default (pad, parent, query);
515 }
516 
520 static GstAdapter *
522 {
523  GstMetaQuery *meta;
524  guint32 key = 0;
525 
526  meta = gst_buffer_get_meta_query (buf);
527  if (meta)
528  key = meta->client_id;
529 
530  return gst_tensor_aggregation_get_adapter (self->adapter_table, key);
531 }
532 
539 static gboolean
541  const GstTensorInfo * info)
542 {
543  guint i;
544 
545  g_assert (info != NULL);
550  if (self->concat && self->frames_out > 1) {
551  for (i = self->frames_dim + 1; i < NNS_TENSOR_RANK_LIMIT; i++) {
552  if (info->dimension[i] > 1) {
554  return TRUE;
555  }
556  }
557  }
558 
559  return FALSE;
560 }
561 
568 static gboolean
570  const GstTensorInfo * info)
571 {
572  GstBuffer *srcbuf;
573  GstMapInfo src_info, dest_info;
574  guint f;
575  gsize block_size;
576  gsize src_idx, dest_idx;
577  gsize frame_size;
578 
579  frame_size = gst_tensor_info_get_size (info);
580  g_assert (frame_size > 0);
582  srcbuf = gst_buffer_copy (outbuf);
583  outbuf = gst_buffer_make_writable (outbuf);
584 
585  if (!gst_buffer_map (srcbuf, &src_info, GST_MAP_READ)) {
586  ml_logf ("Failed to map source buffer with tensor_aggregator.\n");
587  gst_buffer_unref (srcbuf);
588  return FALSE;
589  }
590  if (!gst_buffer_map (outbuf, &dest_info, GST_MAP_WRITE)) {
591  ml_logf ("Failed to map destination buffer with tensor_aggregator.\n");
592  gst_buffer_unmap (srcbuf, &src_info);
593  gst_buffer_unref (srcbuf);
594  return FALSE;
595  }
596 
773  block_size = gst_tensor_get_element_size (info->type);
774  for (f = 0; f <= self->frames_dim; f++) {
775  block_size *= info->dimension[f];
776  }
777 
778  src_idx = dest_idx = 0;
779 
780  do {
781  for (f = 0; f < self->frames_out; f++) {
782  nns_memcpy (dest_info.data + dest_idx,
783  src_info.data + src_idx + (frame_size * f), block_size);
784  dest_idx += block_size;
785  }
786 
787  src_idx += block_size;
788 
789  g_assert (src_idx <= frame_size);
790  g_assert (dest_idx <= dest_info.size);
791  } while (src_idx < frame_size);
792 
793  gst_buffer_unmap (srcbuf, &src_info);
794  gst_buffer_unmap (outbuf, &dest_info);
795 
796  gst_buffer_unref (srcbuf);
797 
798  return TRUE;
799 }
800 
804 static GstFlowReturn
806  gsize frame_size)
807 {
808  GstTensorInfo info;
809 
811  info = self->out_config.info.info[0];
812  g_assert (self->frames_dim < NNS_TENSOR_RANK_LIMIT);
813  info.dimension[self->frames_dim] /= self->frames_out;
814 
815  if (frame_size != gst_tensor_info_get_size (&info) || frame_size == 0U) {
816  ml_logf
817  ("Invalid output capability of tensor_aggregator. Frame size = %"
818  G_GSIZE_FORMAT "\n", frame_size);
819  return GST_FLOW_ERROR;
820  }
821 
822  if (gst_tensor_aggregator_check_concat_axis (self, &info)) {
824  if (!gst_tensor_aggregator_concat (self, outbuf, &info))
825  return GST_FLOW_ERROR;
826  }
827 
828  return gst_pad_push (self->srcpad, outbuf);
829 }
830 
834 static GstFlowReturn
835 gst_tensor_aggregator_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
836 {
837  GstTensorAggregator *self;
838  GstFlowReturn ret = GST_FLOW_OK;
839  GstAdapter *adapter;
840  gsize avail, buf_size, frame_size, out_size;
841  guint frames_in, frames_out, frames_flush;
842  GstClockTime duration;
843  UNUSED (pad);
844 
845  self = GST_TENSOR_AGGREGATOR (parent);
846  g_assert (self->tensor_configured);
847 
848  buf_size = gst_buffer_get_size (buf);
849  g_return_val_if_fail (buf_size > 0, GST_FLOW_ERROR);
850 
851  frames_in = self->frames_in;
852  frames_out = self->frames_out;
853  frames_flush = self->frames_flush;
854  frame_size = buf_size / frames_in;
855 
856  if (frames_in == frames_out) {
858  return gst_tensor_aggregator_push (self, buf, frame_size);
859  }
860 
861  adapter = gst_tensor_aggregator_get_adapter (self, buf);
862  g_assert (adapter != NULL);
863 
864  duration = GST_BUFFER_DURATION (buf);
865  if (GST_CLOCK_TIME_IS_VALID (duration)) {
867  duration = gst_util_uint64_scale_int (duration, frames_out, frames_in);
868  }
869 
870  gst_adapter_push (adapter, buf);
871 
872  out_size = frame_size * frames_out;
873  g_assert (out_size > 0);
874 
875  while ((avail = gst_adapter_available (adapter)) >= out_size &&
876  ret == GST_FLOW_OK) {
877  GstBuffer *outbuf;
878  GstClockTime pts, dts;
879  guint64 pts_dist, dts_dist;
880  gsize flush;
881 
882  pts = gst_adapter_prev_pts (adapter, &pts_dist);
883  dts = gst_adapter_prev_dts (adapter, &dts_dist);
884 
889  if (frames_in > 1) {
890  gint fn, fd;
891 
892  fn = self->in_config.rate_n;
893  fd = self->in_config.rate_d;
894 
895  if (fn > 0 && fd > 0) {
896  if (GST_CLOCK_TIME_IS_VALID (pts)) {
897  pts +=
898  gst_util_uint64_scale_int (pts_dist * fd, GST_SECOND,
899  fn * frame_size);
900  }
901 
902  if (GST_CLOCK_TIME_IS_VALID (dts)) {
903  dts +=
904  gst_util_uint64_scale_int (dts_dist * fd, GST_SECOND,
905  fn * frame_size);
906  }
907  }
908  }
909 
910  outbuf = gst_adapter_get_buffer (adapter, out_size);
911  outbuf = gst_buffer_make_writable (outbuf);
912 
914  GST_BUFFER_PTS (outbuf) = pts;
915  GST_BUFFER_DTS (outbuf) = dts;
916  GST_BUFFER_DURATION (outbuf) = duration;
917 
918  ret = gst_tensor_aggregator_push (self, outbuf, frame_size);
919 
921  if (frames_flush > 0) {
922  flush = frame_size * frames_flush;
923 
924  if (flush > avail) {
931  flush = avail;
932  }
933  } else {
934  flush = out_size;
935  }
936 
937  gst_adapter_flush (adapter, flush);
938  }
939 
940  return ret;
941 }
942 
946 static GstStateChangeReturn
948  GstStateChange transition)
949 {
950  GstTensorAggregator *self;
951  GstStateChangeReturn ret;
952 
953  self = GST_TENSOR_AGGREGATOR (element);
954 
955  switch (transition) {
956  case GST_STATE_CHANGE_READY_TO_PAUSED:
958  break;
959  default:
960  break;
961  }
962 
963  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
964 
965  switch (transition) {
966  case GST_STATE_CHANGE_PAUSED_TO_READY:
968  break;
969  default:
970  break;
971  }
972 
973  return ret;
974 }
975 
979 static void
981 {
982  /* remove all buffers from adapter */
983  gst_tensor_aggregation_clear_all (self->adapter_table);
984 }
985 
989 static GstCaps *
991  GstCaps * filter)
992 {
993  GstCaps *caps;
994  GstTensorsConfig *config;
995 
996  /* tensor config info for given pad */
997  if (pad == self->sinkpad) {
998  config = &self->in_config;
999  } else {
1000  config = &self->out_config;
1001  }
1002 
1003  /* caps from tensor config info */
1004  caps = gst_tensor_pad_possible_caps_from_config (pad, config);
1005 
1006  silent_debug_caps (self, caps, "caps");
1007  silent_debug_caps (self, filter, "filter");
1008 
1009  if (caps && filter) {
1010  GstCaps *intersection;
1011 
1012  intersection =
1013  gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
1014 
1015  gst_caps_unref (caps);
1016  caps = intersection;
1017  }
1018 
1019  return caps;
1020 }
1021 
1025 static gboolean
1027  const GstCaps * caps)
1028 {
1029  GstStructure *structure;
1030  GstTensorsConfig config;
1031  GstTensorInfo *_info;
1032  uint32_t per_frame;
1033  guint count;
1034 
1035  g_return_val_if_fail (caps != NULL, FALSE);
1036  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
1037 
1038  structure = gst_caps_get_structure (caps, 0);
1039 
1040  if (!gst_tensors_config_from_structure (&config, structure) ||
1041  !gst_tensors_config_validate (&config)) {
1042  GST_ERROR_OBJECT (self, "Cannot configure tensor info");
1043  return FALSE;
1044  }
1045 
1051  count = (self->frames_out + self->frames_in - 1) / self->frames_in;
1052  if (self->frames_in * count < self->frames_flush) {
1053  GST_ERROR_OBJECT (self, "Cannot flush frames");
1054  return FALSE;
1055  }
1056 
1057  self->in_config = config;
1058  /* tensor-aggregator now handles single tensor. */
1059  _info = &config.info.info[0];
1060 
1067  if (self->frames_dim >= NNS_TENSOR_RANK_LIMIT ||
1068  (_info->dimension[self->frames_dim] % self->frames_in) != 0) {
1069  GST_ERROR_OBJECT (self, "Cannot update dimension in output tensor");
1070  return FALSE;
1071  }
1072  per_frame = _info->dimension[self->frames_dim] / self->frames_in;
1073 
1074  _info->dimension[self->frames_dim] = per_frame * self->frames_out;
1075  self->out_config = config;
1076  self->tensor_configured = TRUE;
1077 
1078  silent_debug_config (self, &self->in_config, "in-tensor");
1079  silent_debug_config (self, &self->out_config, "out-tensor");
1080  return TRUE;
1081 }
gst_tensor_aggregator_parse_caps
static gboolean gst_tensor_aggregator_parse_caps(GstTensorAggregator *self, const GstCaps *caps)
Parse caps and set tensor info.
Definition: gsttensor_aggregator.c:1026
gst_tensor_aggregator_get_property
static void gst_tensor_aggregator_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
Getter for tensor_aggregator properties.
Definition: gsttensor_aggregator.c:349
gsttensor_aggregator.h
GStreamer plugin to aggregate tensor stream.
g_assert
g_assert(sizeof(DTYPE_UNSIGNED)==sizeof(DTYPE_SIGNED))
gst_tensor_aggregation_get_adapter
GstAdapter * gst_tensor_aggregation_get_adapter(GHashTable *table, const guint32 key)
Gets adapter from hash table.
Definition: nnstreamer_plugin_api_impl.c:790
G_DEFINE_TYPE
G_DEFINE_TYPE(GstTensorAggregator, gst_tensor_aggregator, GST_TYPE_ELEMENT)
GstTensorInfo
Internal data structure for tensor info.
Definition: tensor_typedef.h:261
FALSE
return FALSE
Definition: gsttensor_transform.c:590
PROP_FRAMES_IN
@ PROP_FRAMES_IN
Definition: gsttensor_aggregator.c:65
CAPS_STRING
#define CAPS_STRING
Template caps string for pads.
Definition: gsttensor_aggregator.c:106
ml_logf
#define ml_logf
Definition: nnstreamer_log.h:80
DEFAULT_SILENT
#define DEFAULT_SILENT
Flag to print minimized log.
Definition: gsttensor_aggregator.c:76
GST_TENSOR_AGGREGATOR
#define GST_TENSOR_AGGREGATOR(obj)
Definition: gsttensor_aggregator.h:37
GstMetaQuery::client_id
query_client_id_t client_id
Definition: tensor_meta.h:30
PROP_0
@ PROP_0
Definition: gsttensor_aggregator.c:64
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
PROP_CONCAT
@ PROP_CONCAT
Definition: gsttensor_aggregator.c:69
_GstTensorAggregator
GstTensorAggregator data structure.
Definition: gsttensor_aggregator.h:52
GstMetaQuery
GstMetaQuery meta structure.
Definition: tensor_meta.h:26
tensor_meta.h
Internal tensor meta header for nnstreamer.
src_template
static GstStaticPadTemplate src_template
Template for src pad.
Definition: gsttensor_aggregator.c:119
gst_tensor_aggregator_concat
static gboolean gst_tensor_aggregator_concat(GstTensorAggregator *self, GstBuffer *outbuf, const GstTensorInfo *info)
Change the data in buffer with given axis.
Definition: gsttensor_aggregator.c:569
gst_tensor_aggregator_chain
static GstFlowReturn gst_tensor_aggregator_chain(GstPad *pad, GstObject *parent, GstBuffer *buf)
Chain function, this function does the actual processing.
Definition: gsttensor_aggregator.c:835
DEFAULT_FRAMES_IN
#define DEFAULT_FRAMES_IN
The number of frames in input buffer.
Definition: gsttensor_aggregator.c:81
gst_tensor_aggregator_reset
static void gst_tensor_aggregator_reset(GstTensorAggregator *self)
Clear and reset data.
Definition: gsttensor_aggregator.c:980
GstTensorsInfo::info
GstTensorInfo info[NNS_TENSOR_MEMORY_MAX]
Definition: tensor_typedef.h:276
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_aggregator_finalize
static void gst_tensor_aggregator_finalize(GObject *object)
Function to finalize instance.
Definition: gsttensor_aggregator.c:294
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_buffer_get_meta_query
#define gst_buffer_get_meta_query(b)
Definition: tensor_meta.h:44
gst_tensor_aggregator_check_concat_axis
static gboolean gst_tensor_aggregator_check_concat_axis(GstTensorAggregator *self, const GstTensorInfo *info)
Check tensor dimension and axis to concatenate data.
Definition: gsttensor_aggregator.c:540
GstTensorsConfig
Internal data structure for configured tensors info (for other/tensors).
Definition: tensor_typedef.h:284
DEFAULT_CONCAT
#define DEFAULT_CONCAT
Flag to concatenate output buffer.
Definition: gsttensor_aggregator.c:101
DEFAULT_FRAMES_FLUSH
#define DEFAULT_FRAMES_FLUSH
The number of frames to flush.
Definition: gsttensor_aggregator.c:91
silent_debug_caps
#define silent_debug_caps(self, caps, msg)
Macro for capability debug message.
Definition: tensor_common.h:285
TRUE
return TRUE
Definition: gsttensor_if.c:897
UNUSED
#define UNUSED(expr)
Definition: mqttcommon.h:19
gst_tensor_aggregation_init
GHashTable * gst_tensor_aggregation_init(void)
Gets new hash table for tensor aggregation.
Definition: nnstreamer_plugin_api_impl.c:737
nnstreamer_util.h
Optional NNStreamer utility functions for sub-plugin writers and users.
gst_tensor_pad_possible_caps_from_config
GstCaps * gst_tensor_pad_possible_caps_from_config(GstPad *pad, const GstTensorsConfig *config)
Get all possible caps from tensors config. Unlike gst_tensor_pad_caps_from_config(),...
Definition: nnstreamer_plugin_api_impl.c:1286
gst_tensor_info_get_size
gsize gst_tensor_info_get_size(const GstTensorInfo *info)
Get data size of single tensor.
Definition: nnstreamer_plugin_api_util_impl.c:156
gst_tensor_aggregator_push
static GstFlowReturn gst_tensor_aggregator_push(GstTensorAggregator *self, GstBuffer *outbuf, gsize frame_size)
Push the buffer to source pad. (Concatenate the buffer if needed)
Definition: gsttensor_aggregator.c:805
PROP_FRAMES_DIMENSION
@ PROP_FRAMES_DIMENSION
Definition: gsttensor_aggregator.c:68
gst_tensor_aggregator_sink_event
static gboolean gst_tensor_aggregator_sink_event(GstPad *pad, GstObject *parent, GstEvent *event)
This function handles sink events.
Definition: gsttensor_aggregator.c:385
gst_tensor_aggregator_change_state
static GstStateChangeReturn gst_tensor_aggregator_change_state(GstElement *element, GstStateChange transition)
Called to perform state change.
Definition: gsttensor_aggregator.c:947
gst_tensor_aggregator_class_init
static void gst_tensor_aggregator_class_init(GstTensorAggregatorClass *klass)
Initialize the tensor_aggregator's class.
Definition: gsttensor_aggregator.c:155
silent_debug_config
#define silent_debug_config(self, c, msg)
Definition: gsttensor_aggregator.c:45
gst_tensor_aggregator_get_adapter
static GstAdapter * gst_tensor_aggregator_get_adapter(GstTensorAggregator *self, GstBuffer *buf)
Internal function to get adapter.
Definition: gsttensor_aggregator.c:521
gst_tensor_aggregator_src_query
static gboolean gst_tensor_aggregator_src_query(GstPad *pad, GstObject *parent, GstQuery *query)
This function handles src pad query.
Definition: gsttensor_aggregator.c:487
PROP_FRAMES_OUT
@ PROP_FRAMES_OUT
Definition: gsttensor_aggregator.c:66
DEFAULT_FRAMES_OUT
#define DEFAULT_FRAMES_OUT
The number of frames in output buffer.
Definition: gsttensor_aggregator.c:86
GST_DEBUG_CATEGORY_STATIC
GST_DEBUG_CATEGORY_STATIC(gst_tensor_aggregator_debug)
gst_tensor_aggregation_clear_all
void gst_tensor_aggregation_clear_all(GHashTable *table)
Clears buffers from all adapters in hash table.
Definition: nnstreamer_plugin_api_impl.c:778
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
GstTensorInfo::type
tensor_type type
Definition: tensor_typedef.h:266
GstTensorsConfig::info
GstTensorsInfo info
Definition: tensor_typedef.h:286
sink_template
static GstStaticPadTemplate sink_template
Template for sink pad.
Definition: gsttensor_aggregator.c:111
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_aggregator_query_caps
static GstCaps * gst_tensor_aggregator_query_caps(GstTensorAggregator *self, GstPad *pad, GstCaps *filter)
Get pad caps for caps negotiation.
Definition: gsttensor_aggregator.c:990
PROP_FRAMES_FLUSH
@ PROP_FRAMES_FLUSH
Definition: gsttensor_aggregator.c:67
PROP_SILENT
@ PROP_SILENT
Definition: gsttensor_aggregator.c:70
GstTensorInfo::dimension
tensor_dim dimension
Definition: tensor_typedef.h:267
gst_tensor_aggregator_sink_query
static gboolean gst_tensor_aggregator_sink_query(GstPad *pad, GstObject *parent, GstQuery *query)
This function handles sink pad query.
Definition: gsttensor_aggregator.c:434
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
if
if(!gst_tensordec_process_plugin_options(self,(opnum) - 1)) GST_ERROR_OBJECT(self
DEFAULT_FRAMES_DIMENSION
#define DEFAULT_FRAMES_DIMENSION
The dimension index of frames in configured tensor.
Definition: gsttensor_aggregator.c:96
gst_tensor_aggregator_init
static void gst_tensor_aggregator_init(GstTensorAggregator *self)
Initialize tensor_aggregator element.
Definition: gsttensor_aggregator.c:254
_GstTensorAggregatorClass
GstTensorAggregatorClass data structure.
Definition: gsttensor_aggregator.h:76
gst_tensor_aggregator_set_property
static void gst_tensor_aggregator_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
Setter for tensor_aggregator properties.
Definition: gsttensor_aggregator.c:313