Doxygen Book
gsttensor_sparseenc.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: LGPL-2.1-only */
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35 
36 #include <string.h>
37 #include <nnstreamer_util.h>
38 #include "gsttensor_sparseenc.h"
39 
43 #ifndef DBG
44 #define DBG (!self->silent)
45 #endif
46 
47 GST_DEBUG_CATEGORY_STATIC (gst_tensor_sparse_enc_debug);
48 #define GST_CAT_DEFAULT gst_tensor_sparse_enc_debug
49 
53 enum
54 {
57 };
58 
62 #define DEFAULT_SILENT TRUE
63 
67 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
68  GST_PAD_SINK,
69  GST_PAD_ALWAYS,
70  GST_STATIC_CAPS (GST_TENSORS_CAP_DEFAULT));
71 
75 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
76  GST_PAD_SRC,
77  GST_PAD_ALWAYS,
78  GST_STATIC_CAPS (GST_TENSORS_SPARSE_CAP_DEFAULT));
79 
80 #define gst_tensor_sparse_enc_parent_class parent_class
81 G_DEFINE_TYPE (GstTensorSparseEnc, gst_tensor_sparse_enc, GST_TYPE_ELEMENT);
82 
83 static void gst_tensor_sparse_enc_finalize (GObject * object);
84 static void gst_tensor_sparse_enc_set_property (GObject * object, guint prop_id,
85  const GValue * value, GParamSpec * pspec);
86 static void gst_tensor_sparse_enc_get_property (GObject * object, guint prop_id,
87  GValue * value, GParamSpec * pspec);
88 static GstFlowReturn
89 gst_tensor_sparse_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf);
91  GstPad * pad, GstCaps * filter);
92 static gboolean gst_tensor_sparse_enc_sink_event (GstPad * pad,
93  GstObject * parent, GstEvent * event);
94 static gboolean gst_tensor_sparse_enc_sink_query (GstPad * pad,
95  GstObject * parent, GstQuery * query);
96 
100 static void
102 {
103  GObjectClass *object_class;
104  GstElementClass *element_class;
105 
106  GST_DEBUG_CATEGORY_INIT (gst_tensor_sparse_enc_debug, "tensor_sparse_enc", 0,
107  "Element to encode sparse tensors");
108 
109  object_class = (GObjectClass *) klass;
110  element_class = (GstElementClass *) klass;
111 
112  object_class->set_property = gst_tensor_sparse_enc_set_property;
113  object_class->get_property = gst_tensor_sparse_enc_get_property;
114  object_class->finalize = gst_tensor_sparse_enc_finalize;
115 
121  g_object_class_install_property (object_class, PROP_SILENT,
122  g_param_spec_boolean ("silent", "Silent", "Produce verbose output",
123  DEFAULT_SILENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
124 
125  gst_element_class_add_pad_template (element_class,
126  gst_static_pad_template_get (&src_template));
127 
128  gst_element_class_add_pad_template (element_class,
129  gst_static_pad_template_get (&sink_template));
130 
131  gst_element_class_set_static_metadata (element_class,
132  "TensorSparseEnc",
133  "Filter/Tensor",
134  "Element to encode dense tensors into sparse tensors",
135  "Samsung Electronics Co., Ltd.");
136 }
137 
141 static void
143 {
144  /* setup sink pad */
145  self->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
146  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
147 
148  /* setup src pad */
149  self->srcpad = gst_pad_new_from_static_template (&src_template, "src");
150  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
151 
152  /* setup chain function */
153  gst_pad_set_chain_function (self->sinkpad,
154  GST_DEBUG_FUNCPTR (gst_tensor_sparse_enc_chain));
155 
156  /* setup event function */
157  gst_pad_set_event_function (self->sinkpad,
158  GST_DEBUG_FUNCPTR (gst_tensor_sparse_enc_sink_event));
159 
160  gst_pad_set_query_function (self->sinkpad,
161  GST_DEBUG_FUNCPTR (gst_tensor_sparse_enc_sink_query));
162 
163  /* init properties */
164  self->silent = DEFAULT_SILENT;
165  gst_tensors_config_init (&self->in_config);
166 }
167 
171 static void
173 {
174  GstTensorSparseEnc *self;
175  self = GST_TENSOR_SPARSE_ENC (object);
176 
177  gst_tensors_config_free (&self->in_config);
178 
179  G_OBJECT_CLASS (parent_class)->finalize (object);
180 }
181 
185 static void
186 gst_tensor_sparse_enc_set_property (GObject * object, guint prop_id,
187  const GValue * value, GParamSpec * pspec)
188 {
189  GstTensorSparseEnc *self;
190 
191  self = GST_TENSOR_SPARSE_ENC (object);
192 
193  switch (prop_id) {
194  case PROP_SILENT:
195  self->silent = g_value_get_boolean (value);
196  break;
197  default:
198  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
199  break;
200  }
201 }
202 
206 static void
207 gst_tensor_sparse_enc_get_property (GObject * object, guint prop_id,
208  GValue * value, GParamSpec * pspec)
209 {
210  GstTensorSparseEnc *self;
211 
212  self = GST_TENSOR_SPARSE_ENC (object);
213 
214  switch (prop_id) {
215  case PROP_SILENT:
216  g_value_set_boolean (value, self->silent);
217  break;
218  default:
219  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
220  break;
221  }
222 }
223 
227 static gboolean
228 gst_tensor_sparse_enc_sink_event (GstPad * pad, GstObject * parent,
229  GstEvent * event)
230 {
231  GstTensorSparseEnc *self;
232  self = GST_TENSOR_SPARSE_ENC (parent);
233 
234  g_return_val_if_fail (event != NULL, FALSE);
235 
236  switch (GST_EVENT_TYPE (event)) {
237  case GST_EVENT_CAPS:
238  {
239  GstCaps *caps;
240  gboolean ret;
241 
242  gst_event_parse_caps (event, &caps);
243  silent_debug_caps (self, caps, "caps");
244 
245  ret = gst_tensors_config_from_cap (&self->in_config, caps);
246  gst_event_unref (event);
247  return ret;
248  }
249  default:
250  break;
251  }
252 
253  return gst_pad_event_default (pad, parent, event);
254 }
255 
259 static GstCaps *
261  GstCaps * filter)
262 {
263  GstCaps *caps;
264 
265  caps = gst_pad_get_current_caps (pad);
266  if (!caps) {
268  caps = gst_pad_get_pad_template_caps (pad);
269  }
270 
271  silent_debug_caps (self, caps, "caps");
272  silent_debug_caps (self, filter, "filter");
273 
274  if (filter) {
275  GstCaps *intersection;
276  intersection =
277  gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
278 
279  gst_caps_unref (caps);
280  caps = intersection;
281  }
282 
283  silent_debug_caps (self, caps, "result");
284  return caps;
285 }
286 
290 static gboolean
291 gst_tensor_sparse_enc_sink_query (GstPad * pad, GstObject * parent,
292  GstQuery * query)
293 {
294  GstTensorSparseEnc *self;
295 
296  self = GST_TENSOR_SPARSE_ENC (parent);
297 
298  GST_DEBUG_OBJECT (self, "Received %s query: %" GST_PTR_FORMAT,
299  GST_QUERY_TYPE_NAME (query), query);
300 
301  switch (GST_QUERY_TYPE (query)) {
302  case GST_QUERY_CAPS:
303  {
304  GstCaps *caps;
305  GstCaps *filter;
306 
307  gst_query_parse_caps (query, &filter);
308  caps = gst_tensor_sparse_enc_query_caps (self, pad, filter);
309  silent_debug_caps (self, filter, "filter");
310  silent_debug_caps (self, caps, "caps");
311  gst_query_set_caps_result (query, caps);
312  gst_caps_unref (caps);
313  return TRUE;
314  }
315  case GST_QUERY_ACCEPT_CAPS:
316  {
317  GstCaps *caps;
318  GstCaps *template_caps;
319  gboolean res = FALSE;
320 
321  gst_query_parse_accept_caps (query, &caps);
322  silent_debug_caps (self, caps, "caps");
323 
324  if (gst_caps_is_fixed (caps)) {
325  template_caps = gst_pad_get_pad_template_caps (pad);
326 
327  res = gst_caps_can_intersect (template_caps, caps);
328  gst_caps_unref (template_caps);
329  }
330 
331  gst_query_set_accept_caps_result (query, res);
332  return TRUE;
333  }
334  default:
335  break;
336  }
337 
338  return gst_pad_query_default (pad, parent, query);
339 }
340 
341 
345 static GstFlowReturn
346 gst_tensor_sparse_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
347 {
348  GstFlowReturn ret = GST_FLOW_OK;
349  GstTensorSparseEnc *self = GST_TENSOR_SPARSE_ENC (parent);
350  GstMemory *in_mem, *out_mem;
351  GstBuffer *outbuf;
352  GstTensorsInfo *info;
353  GstTensorInfo *_info;
354  guint i;
355 
356  UNUSED (pad);
357 
358  info = &self->in_config.info;
359  buf = gst_tensor_buffer_from_config (buf, &self->in_config);
360  outbuf = gst_buffer_new ();
361 
362  for (i = 0; i < info->num_tensors; ++i) {
363  GstTensorMetaInfo meta;
364 
365  _info = gst_tensors_info_get_nth_info (info, i);
366  gst_tensor_info_convert_to_meta (_info, &meta);
367 
369  meta.media_type = _NNS_TENSOR;
370 
371  /* do real encoding here */
372  in_mem = gst_tensor_buffer_get_nth_memory (buf, i);
373  out_mem = gst_tensor_sparse_from_dense (&meta, in_mem);
374  gst_memory_unref (in_mem);
375 
376  if (!out_mem) {
377  nns_loge ("failed to convert to sparse tensor");
378  ret = GST_FLOW_ERROR;
379  goto done;
380  }
381 
382  gst_tensor_buffer_append_memory (outbuf, out_mem, _info);
383  }
384 
385  ret = gst_pad_push (self->srcpad, outbuf);
386 
387 done:
388  gst_buffer_unref (buf);
389  if (ret != GST_FLOW_OK)
390  gst_buffer_unref (outbuf);
391 
392  return ret;
393 }
GST_DEBUG_CATEGORY_STATIC
GST_DEBUG_CATEGORY_STATIC(gst_tensor_sparse_enc_debug)
DEFAULT_SILENT
#define DEFAULT_SILENT
Flag to print minimized log.
Definition: gsttensor_sparseenc.c:62
gst_tensor_sparse_from_dense
GstMemory * gst_tensor_sparse_from_dense(GstTensorMetaInfo *meta, GstMemory *mem)
Make sparse tensor with input dense tensor.
Definition: gsttensor_sparseutil.c:116
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
gst_tensor_sparse_enc_query_caps
static GstCaps * gst_tensor_sparse_enc_query_caps(GstTensorSparseEnc *self, GstPad *pad, GstCaps *filter)
Get pad caps for caps negotiation.
Definition: gsttensor_sparseenc.c:260
gst_tensor_sparse_enc_sink_query
static gboolean gst_tensor_sparse_enc_sink_query(GstPad *pad, GstObject *parent, GstQuery *query)
This function handles sink pad query.
Definition: gsttensor_sparseenc.c:291
GstTensorInfo
Internal data structure for tensor info.
Definition: tensor_typedef.h:261
FALSE
return FALSE
Definition: gsttensor_transform.c:596
GstTensorsInfo
Internal meta data exchange format for a other/tensors instance.
Definition: tensor_typedef.h:273
sink_template
static GstStaticPadTemplate sink_template
Template for sink pad.
Definition: gsttensor_sparseenc.c:67
_GstTensorSparseEncClass
GstTensorSparseClass data structure.
Definition: gsttensor_sparseenc.h:53
GST_TENSOR_SPARSE_ENC
#define GST_TENSOR_SPARSE_ENC(obj)
Definition: gsttensor_sparseenc.h:24
gst_tensor_sparse_enc_class_init
static void gst_tensor_sparse_enc_class_init(GstTensorSparseEncClass *klass)
Initialize the tensor_sparse's class.
Definition: gsttensor_sparseenc.c:101
GstTensorMetaInfo
Data structure to describe a tensor data. This represents the basic information of a memory block for...
Definition: tensor_typedef.h:310
_NNS_TENSOR
@ _NNS_TENSOR
Definition: tensor_typedef.h:186
GstTensorMetaInfo::media_type
uint32_t media_type
Definition: tensor_typedef.h:317
gst_tensor_sparse_enc_finalize
static void gst_tensor_sparse_enc_finalize(GObject *object)
Function to finalize instance.
Definition: gsttensor_sparseenc.c:172
gst_tensor_sparse_enc_init
static void gst_tensor_sparse_enc_init(GstTensorSparseEnc *self)
Initialize tensor_sparse_enc element.
Definition: gsttensor_sparseenc.c:142
gst_tensor_sparse_enc_chain
static GstFlowReturn gst_tensor_sparse_enc_chain(GstPad *pad, GstObject *parent, GstBuffer *buf)
Internal function to transform the input buffer.
Definition: gsttensor_sparseenc.c:346
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
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
_NNS_TENSOR_FORMAT_SPARSE
@ _NNS_TENSOR_FORMAT_SPARSE
Definition: tensor_typedef.h:197
silent_debug_caps
#define silent_debug_caps(self, caps, msg)
Macro for capability debug message.
Definition: tensor_common.h:285
PROP_SILENT
@ PROP_SILENT
Definition: gsttensor_sparseenc.c:56
TRUE
return TRUE
Definition: gsttensor_if.c:879
UNUSED
#define UNUSED(expr)
Definition: mqttcommon.h:19
nns_loge
#define nns_loge
Definition: nnstreamer_log.h:142
src_template
static GstStaticPadTemplate src_template
Template for src pad.
Definition: gsttensor_sparseenc.c:75
nnstreamer_util.h
Optional NNStreamer utility functions for sub-plugin writers and users.
GST_TENSORS_SPARSE_CAP_DEFAULT
#define GST_TENSORS_SPARSE_CAP_DEFAULT
Caps string for the caps template of sparse tensors. This mimetype handles non-static,...
Definition: tensor_typedef.h:131
G_DEFINE_TYPE
G_DEFINE_TYPE(GstTensorSparseEnc, gst_tensor_sparse_enc, GST_TYPE_ELEMENT)
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
GST_TENSORS_CAP_DEFAULT
#define GST_TENSORS_CAP_DEFAULT
Caps string for the caps template of static tensor stream.
Definition: tensor_typedef.h:115
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
GstTensorMetaInfo::format
uint32_t format
Definition: tensor_typedef.h:316
GstTensorsInfo::num_tensors
unsigned int num_tensors
Definition: tensor_typedef.h:275
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
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_sparse_enc_set_property
static void gst_tensor_sparse_enc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
Setter for tensor_sparse_enc properties.
Definition: gsttensor_sparseenc.c:186
gst_tensor_sparse_enc_get_property
static void gst_tensor_sparse_enc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
Getter for tensor_sparse_enc properties.
Definition: gsttensor_sparseenc.c:207
PROP_0
@ PROP_0
Definition: gsttensor_sparseenc.c:55
_GstTensorSparseEnc
GstTensorSparseEnc data structure.
Definition: gsttensor_sparseenc.h:39
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
gst_tensor_sparse_enc_sink_event
static gboolean gst_tensor_sparse_enc_sink_event(GstPad *pad, GstObject *parent, GstEvent *event)
This function handles sink pad event.
Definition: gsttensor_sparseenc.c:228
gsttensor_sparseenc.h
GStreamer element to encode sparse tensors into dense tensors.