Doxygen Book
gsttensor_reposrc.c
Go to the documentation of this file.
1 
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 
35 #include <string.h>
36 #include "gsttensor_repo.h"
37 #include "gsttensor_reposrc.h"
38 
39 GST_DEBUG_CATEGORY_STATIC (gst_tensor_reposrc_debug);
40 #define GST_CAT_DEFAULT gst_tensor_reposrc_debug
41 #define CAPS_STRING GST_TENSOR_CAP_DEFAULT "; " GST_TENSORS_CAP_DEFAULT
42 
46 enum
47 {
52 };
53 
54 #define DEFAULT_SILENT TRUE
55 #define DEFAULT_INDEX 0
56 #define INVALID_INDEX G_MAXUINT
57 
58 static void gst_tensor_reposrc_set_property (GObject * object, guint prop_id,
59  const GValue * value, GParamSpec * pspec);
60 static void gst_tensor_reposrc_get_property (GObject * object, guint prop_id,
61  GValue * value, GParamSpec * pspec);
62 static void gst_tensor_reposrc_dispose (GObject * object);
63 static GstCaps *gst_tensor_reposrc_getcaps (GstBaseSrc * src, GstCaps * filter);
64 static GstFlowReturn gst_tensor_reposrc_create (GstPushSrc * src,
65  GstBuffer ** buffer);
66 
67 #define gst_tensor_reposrc_parent_class parent_class
68 G_DEFINE_TYPE (GstTensorRepoSrc, gst_tensor_reposrc, GST_TYPE_PUSH_SRC);
69 
73 static void
75 {
76  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
77  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
78  GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
79  GstBaseSrcClass *basesrc_class = GST_BASE_SRC_CLASS (klass);
80  GstPadTemplate *pad_template;
81  GstCaps *pad_caps;
82 
83  GST_DEBUG_CATEGORY_INIT (gst_tensor_reposrc_debug, "tensor_reposrc", 0,
84  "Source element to handle tensor repository");
85 
86  gobject_class->set_property = gst_tensor_reposrc_set_property;
87  gobject_class->get_property = gst_tensor_reposrc_get_property;
88  gobject_class->dispose = gst_tensor_reposrc_dispose;
89 
90  g_object_class_install_property (gobject_class, PROP_CAPS,
91  g_param_spec_boxed ("caps", "Caps",
92  "Caps describing the format of the data.",
93  GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
94 
95  g_object_class_install_property (gobject_class, PROP_SILENT,
96  g_param_spec_boolean ("silent", "Silent", "Produce verbose output",
97  DEFAULT_SILENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
98 
99  g_object_class_install_property (gobject_class, PROP_SLOT_ID,
100  g_param_spec_uint ("slot-index", "Slot Index", "repository slot index",
102  G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
103 
104  basesrc_class->get_caps = gst_tensor_reposrc_getcaps;
105  pushsrc_class->create = gst_tensor_reposrc_create;
106 
107  gst_element_class_set_static_metadata (element_class,
108  "TensorRepoSrc",
109  "Source/Tensor/Repository",
110  "Pop element to handle tensor repository",
111  "Samsung Electronics Co., Ltd.");
112 
113  /* pad template */
114  pad_caps = gst_caps_from_string (GST_TENSOR_CAP_DEFAULT "; "
116  pad_template = gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
117  pad_caps);
118  gst_element_class_add_pad_template (element_class, pad_template);
119  gst_caps_unref (pad_caps);
120 }
121 
125 static void
127 {
128  self->silent = TRUE;
129  self->ini = FALSE;
130  self->negotiation = FALSE;
131  gst_tensors_config_init (&self->config);
132  self->caps = NULL;
133  self->set_startid = FALSE;
134  self->myid = INVALID_INDEX;
135 }
136 
140 static void
141 gst_tensor_reposrc_dispose (GObject * object)
142 {
143  GstTensorRepoSrc *self = GST_TENSOR_REPOSRC (object);
144 
145  if (self->myid != INVALID_INDEX
146  && !gst_tensor_repo_remove_repodata (self->myid))
147  GST_ELEMENT_ERROR (self, RESOURCE, WRITE,
148  ("Cannot remove [key: %d] in repo", self->myid), NULL);
149 
150  if (self->caps)
151  gst_caps_unref (self->caps);
152 
153  G_OBJECT_CLASS (parent_class)->dispose (object);
154 }
155 
159 static GstCaps *
160 gst_tensor_reposrc_getcaps (GstBaseSrc * src, GstCaps * filter)
161 {
162  GstTensorRepoSrc *self = GST_TENSOR_REPOSRC (src);
163  GstCaps *cap, *check, *result;
164  GstStructure *st = NULL;
165 
166  GST_DEBUG_OBJECT (self, "returning %" GST_PTR_FORMAT, self->caps);
167 
168  if (self->caps) {
169  if (filter) {
170  cap = gst_caps_intersect_full (filter, self->caps,
171  GST_CAPS_INTERSECT_FIRST);
172  } else
173  cap = gst_caps_ref (self->caps);
174  } else {
175  if (filter) {
176  cap = gst_caps_ref (filter);
177  } else
178  cap = gst_caps_new_any ();
179  }
180 
181  check = gst_caps_from_string (CAPS_STRING);
182  result = gst_caps_intersect_full (cap, check, GST_CAPS_INTERSECT_FIRST);
183 
184  if (!result) {
185  GST_ELEMENT_ERROR (GST_ELEMENT (self), STREAM, WRONG_TYPE,
186  ("Only Tensor/Tensors MIME are supported for now"), (NULL));
187  }
188  gst_caps_unref (check);
189  gst_caps_unref (cap);
190 
191  st = gst_caps_get_structure (result, 0);
192  gst_tensors_config_from_structure (&self->config, st);
193 
194  return result;
195 }
196 
200 static void
201 gst_tensor_reposrc_set_property (GObject * object, guint prop_id,
202  const GValue * value, GParamSpec * pspec)
203 {
204  GstTensorRepoSrc *self = GST_TENSOR_REPOSRC (object);
205 
206  switch (prop_id) {
207  case PROP_SILENT:
208  self->silent = g_value_get_boolean (value);
209  break;
210  case PROP_SLOT_ID:
211  self->o_myid = self->myid;
212  self->myid = g_value_get_uint (value);
213  self->negotiation = FALSE;
214 
215  gst_tensor_repo_add_repodata (self->myid, FALSE);
216 
217  if (!self->set_startid) {
218  self->o_myid = self->myid;
219  self->set_startid = TRUE;
220  }
221 
222  if (self->o_myid != self->myid)
223  gst_tensor_repo_set_changed (self->o_myid, self->myid, FALSE);
224  break;
225  case PROP_CAPS:
226  {
227  GstStructure *st = NULL;
228  const GstCaps *caps = gst_value_get_caps (value);
229  GstCaps *new_caps;
230 
231  if (caps == NULL) {
232  new_caps = gst_caps_new_any ();
233  } else {
234  new_caps = gst_caps_copy (caps);
235  }
236  gst_caps_replace (&self->caps, new_caps);
237  gst_pad_set_caps (GST_BASE_SRC_PAD (self), new_caps);
238  st = gst_caps_get_structure (new_caps, 0);
239 
240  if (new_caps && gst_caps_get_size (new_caps) == 1 && st
241  && gst_structure_get_fraction (st, "framerate", &self->fps_n,
242  &self->fps_d)) {
243  GST_INFO_OBJECT (self, "Setting framerate to %d/%d", self->fps_n,
244  self->fps_d);
245  } else {
246  self->fps_n = -1;
247  self->fps_d = -1;
248  }
249 
250  if (new_caps)
251  gst_caps_unref (new_caps);
252  self->negotiation = FALSE;
253  break;
254  }
255  default:
256  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
257  break;
258  }
259 }
260 
264 static void
265 gst_tensor_reposrc_get_property (GObject * object, guint prop_id,
266  GValue * value, GParamSpec * pspec)
267 {
268  GstTensorRepoSrc *self = GST_TENSOR_REPOSRC (object);
269 
270  switch (prop_id) {
271  case PROP_SILENT:
272  g_value_set_boolean (value, self->silent);
273  break;
274  case PROP_SLOT_ID:
275  g_value_set_uint (value, self->myid);
276  break;
277  case PROP_CAPS:
278  gst_value_set_caps (value, self->caps);
279  break;
280  default:
281  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
282  break;
283  }
284 }
285 
289 static GstBuffer *
291 {
292  GstBuffer *buf = NULL;
293  GstTensorInfo *_info;
294  GstMemory *mem;
295  GstMapInfo map;
296  guint i, num_tensors;
297  gsize size = 0;
298 
299  buf = gst_buffer_new ();
300  num_tensors = self->config.info.num_tensors;
301 
302  for (i = 0; i < num_tensors; i++) {
303  _info = gst_tensors_info_get_nth_info (&self->config.info, i);
304  size = gst_tensor_info_get_size (_info);
305  mem = gst_allocator_alloc (NULL, size, NULL);
306  gst_tensor_buffer_append_memory (buf, mem, _info);
307 
308  if (!gst_memory_map (mem, &map, GST_MAP_WRITE)) {
309  gst_buffer_unref (buf);
310  ml_logf ("Cannot map gst memory (tensor-repo-src).");
311  return NULL;
312  }
313 
314  memset (map.data, 0, map.size);
315  gst_memory_unmap (mem, &map);
316  }
317 
318  return buf;
319 }
320 
324 static GstFlowReturn
325 gst_tensor_reposrc_create (GstPushSrc * src, GstBuffer ** buffer)
326 {
327  GstTensorRepoSrc *self;
328  GstBuffer *buf = NULL;
329  GstCaps *caps = NULL;
330  gboolean eos = FALSE;
331  guint newid;
332 
333  self = GST_TENSOR_REPOSRC (src);
335 
336  if (!self->ini) {
338  self->ini = TRUE;
339  } else {
340  while (!buf && !eos) {
341  buf = gst_tensor_repo_get_buffer (self->myid, &eos, &newid, &caps);
342  }
343 
344  if (eos)
345  goto handle_eos;
346 
347  if (!self->negotiation && buf != NULL) {
348  if (!gst_tensor_caps_can_intersect (self->caps, caps)) {
349  GST_ELEMENT_ERROR (GST_ELEMENT (self), CORE, NEGOTIATION,
350  ("Negotiation Failed! : repo_sink & repos_src"), (NULL));
351 
352  gst_tensor_repo_set_eos (self->myid);
353  goto handle_eos;
354  }
355 
356  self->negotiation = TRUE;
357  }
358 
359  if (caps)
360  gst_caps_unref (caps);
361  }
362 
363  *buffer = buf;
364  return GST_FLOW_OK;
365 
366 handle_eos:
367  if (buf)
368  gst_buffer_unref (buf);
369  if (caps)
370  gst_caps_unref (caps);
371  return GST_FLOW_EOS;
372 }
GST_TENSOR_CAP_DEFAULT
#define GST_TENSOR_CAP_DEFAULT
Default static capability for other/tensor.
Definition: tensor_typedef.h:78
GstTensorInfo
Internal data structure for tensor info.
Definition: tensor_typedef.h:261
FALSE
return FALSE
Definition: gsttensor_transform.c:590
result
case tensor_data_s gboolean * result
Definition: gsttensor_if.c:839
ml_logf
#define ml_logf
Definition: nnstreamer_log.h:80
gst_tensor_repo_set_changed
gboolean gst_tensor_repo_set_changed(guint o_nth, guint nth, gboolean is_sink)
Set the changing status of repo.
Definition: gsttensor_repo.c:91
_GstTensorRepoSrcClass
GstTensorRepoSrcClass data structure.
Definition: gsttensor_reposrc.h:74
gst_tensor_reposrc_create
static GstFlowReturn gst_tensor_reposrc_create(GstPushSrc *src, GstBuffer **buffer)
create func of tensor_reposrc
Definition: gsttensor_reposrc.c:325
gst_tensor_reposrc_init
static void gst_tensor_reposrc_init(GstTensorRepoSrc *self)
object initialization of tensor_reposrc
Definition: gsttensor_reposrc.c:126
gst_tensor_reposrc_get_property
static void gst_tensor_reposrc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
get property of tensor_reposrc
Definition: gsttensor_reposrc.c:265
PROP_SILENT
@ PROP_SILENT
Definition: gsttensor_reposrc.c:51
gst_tensor_repo_remove_repodata
gboolean gst_tensor_repo_remove_repodata(guint nth)
Remove nth GstTensorRepoData from GstTensorRepo.
Definition: gsttensor_repo.c:357
PROP_0
@ PROP_0
Definition: gsttensor_reposrc.c:48
gst_tensor_repo_wait
gboolean gst_tensor_repo_wait(void)
Wait for finish of initialization.
Definition: gsttensor_repo.c:406
PROP_CAPS
@ PROP_CAPS
Definition: gsttensor_reposrc.c:49
_GstTensorRepoSrc
GstTensorRepoSrc data structure.
Definition: gsttensor_reposrc.h:54
gst_tensor_reposrc_class_init
static void gst_tensor_reposrc_class_init(GstTensorRepoSrcClass *klass)
class initialization of tensor_reposrc
Definition: gsttensor_reposrc.c:74
gst_tensor_repo_set_eos
gboolean gst_tensor_repo_set_eos(guint nth)
Set EOS (End-of-Stream) of slot.
Definition: gsttensor_repo.c:287
GST_DEBUG_CATEGORY_STATIC
GST_DEBUG_CATEGORY_STATIC(gst_tensor_reposrc_debug)
gst_tensor_reposrc_getcaps
static GstCaps * gst_tensor_reposrc_getcaps(GstBaseSrc *src, GstCaps *filter)
get cap of tensor_reposrc
Definition: gsttensor_reposrc.c:160
gst_tensor_reposrc_gen_dummy_buffer
static GstBuffer * gst_tensor_reposrc_gen_dummy_buffer(GstTensorRepoSrc *self)
create dummy buffer for initialization
Definition: gsttensor_reposrc.c:290
TRUE
return TRUE
Definition: gsttensor_if.c:897
PROP_SLOT_ID
@ PROP_SLOT_ID
Definition: gsttensor_reposrc.c:50
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
G_DEFINE_TYPE
G_DEFINE_TYPE(GstTensorRepoSrc, gst_tensor_reposrc, GST_TYPE_PUSH_SRC)
CAPS_STRING
#define CAPS_STRING
Definition: gsttensor_reposrc.c:41
gsttensor_reposrc.h
GStreamer plugin to handle tensor repository.
gst_tensor_caps_can_intersect
gboolean gst_tensor_caps_can_intersect(GstCaps *caps1, GstCaps *caps2)
Try intersecting @caps1 and @caps2 for tensor stream.
Definition: nnstreamer_plugin_api_impl.c:1142
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
DEFAULT_SILENT
#define DEFAULT_SILENT
Definition: gsttensor_reposrc.c:54
GST_TENSORS_CAP_DEFAULT
#define GST_TENSORS_CAP_DEFAULT
Caps string for the caps template of static tensor stream.
Definition: tensor_typedef.h:115
gsttensor_repo.h
tensor repo header file for NNStreamer, the GStreamer plugin for neural networks
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
INVALID_INDEX
#define INVALID_INDEX
Definition: gsttensor_reposrc.c:56
DEFAULT_INDEX
#define DEFAULT_INDEX
Definition: gsttensor_reposrc.c:55
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_reposrc_set_property
static void gst_tensor_reposrc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
set property of tensor_reposrc
Definition: gsttensor_reposrc.c:201
gst_tensor_reposrc_dispose
static void gst_tensor_reposrc_dispose(GObject *object)
object dispose of tensor_reposrc
Definition: gsttensor_reposrc.c:141
GST_TENSOR_REPOSRC
#define GST_TENSOR_REPOSRC(obj)
Definition: gsttensor_reposrc.h:37
gst_tensor_repo_add_repodata
gboolean gst_tensor_repo_add_repodata(guint nth, gboolean is_sink)
Add GstTensorRepoData into repo.
Definition: gsttensor_repo.c:129
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
gst_tensor_repo_get_buffer
GstBuffer * gst_tensor_repo_get_buffer(guint nth, gboolean *eos, guint *newid, GstCaps **caps)
Get GstTensorRepoData from repo.
Definition: gsttensor_repo.c:309