Doxygen Book
tensor_filter_custom.c
Go to the documentation of this file.
1 
29 #include <errno.h>
30 #include <glib.h>
31 #include <gmodule.h>
32 
33 #include "tensor_filter_custom.h"
35 #include "nnstreamer_conf.h"
36 #include <nnstreamer_log.h>
37 
38 void init_filter_custom (void) __attribute__((constructor));
39 void fini_filter_custom (void) __attribute__((destructor));
40 
41 static const gchar *custom_accl_support[] = {
44  NULL
45 };
46 
51 {
52  GModule *module;
54 
56 };
58 
63 static int
64 custom_loadlib (const GstTensorFilterProperties * prop, void **private_data)
65 {
66  internal_data *ptr;
67  gpointer custom_cls;
68 
69  if (*private_data != NULL) {
71  ml_loge ("Init is called but it is already initialized.\n");
72  return -EINVAL;
73  }
74 
75  if (!prop->model_files || prop->num_models != 1 ||
76  !prop->model_files[0] || prop->model_files[0][0] == '\0') {
77  /* The .so file path is not given */
78  ml_logw ("Custom filter file is not given.\n");
79  return -EINVAL;
80  }
81 
83  prop->model_files[0])) {
84  /* Cannot load the library */
85  ml_logw ("Custom filter file %s is invalid.\n", prop->model_files[0]);
86  return -EINVAL;
87  }
88 
89  ptr = *private_data = g_new0 (internal_data, 1);
90  if (ptr == NULL) {
91  ml_loge ("Failed to allocate memory for custom filter.\n");
92  return -ENOMEM;
93  }
94 
95  /* Load .so if this is the first time for this instance. */
96  ptr->module = g_module_open (prop->model_files[0], 0);
97  if (!ptr->module) {
98  g_free (ptr);
99  *private_data = NULL;
100  ml_logw ("Cannot load custom filter file %s.\n", prop->model_files[0]);
101  return -EINVAL;
102  }
103 
104  if (!g_module_symbol (ptr->module, "NNStreamer_custom", &custom_cls)) {
105  ml_loge ("tensor_filter_custom:loadlib error: %s\n", g_module_error ());
106  g_module_close (ptr->module);
107  g_free (ptr);
108  *private_data = NULL;
109  return -EINVAL;
110  }
111 
112  ptr->methods = *(NNStreamer_custom_class **) custom_cls;
113 
114  if (NULL == ptr->methods->initfunc) {
115  ml_loge ("tensor_filter_custom (%s) requires a valid 'initfunc'.",
116  prop->model_files[0]);
117  return -EINVAL;
118  }
119 
121 
122  /* After init func, (getInput XOR setInput) && (getOutput XOR setInput) must hold! */
124  if (!ptr->methods->getInputDim != !ptr->methods->setInputDim &&
125  !ptr->methods->getOutputDim != !ptr->methods->setInputDim)
126  return 0; /* it holds! */
127 
128  ml_loge
129  ("tensor_filter_custom (%s) requires input/output dimension callbacks.",
130  prop->model_files[0]);
131  return -EINVAL;
132 }
133 
137 static int
138 custom_open (const GstTensorFilterProperties * prop, void **private_data)
139 {
140  int retval = custom_loadlib (prop, private_data);
141  internal_data *ptr;
142 
143  /* This must be called only once */
144  if (retval != 0)
145  return retval;
146 
147  ptr = *private_data;
148 
149  /* One of the two is defined. (but not both) */
150  if (!ptr->methods->invoke != !ptr->methods->allocate_invoke)
151  return 0;
152 
153  ml_loge
154  ("An invoke callback is not given or both invoke functions are given. Cannot load %s.\n",
155  prop->model_files[0]);
156  return -EINVAL;
157 }
158 
166 static int
167 custom_invoke (const GstTensorFilterProperties * prop, void **private_data,
168  const GstTensorMemory * input, GstTensorMemory * output)
169 {
170  internal_data *ptr;
171 
172  /* Actually, tensor_filter must have called getInput/OutputDim first. */
173  g_return_val_if_fail (*private_data != NULL, -EINVAL);
174  g_return_val_if_fail (input != NULL, -EINVAL);
175  g_return_val_if_fail (output != NULL, -EINVAL);
176 
177  ptr = *private_data;
178  if (ptr->methods->invoke) {
179  return ptr->methods->invoke (ptr->customFW_private_data, prop,
180  input, output);
181  } else if (ptr->methods->allocate_invoke) {
182  return ptr->methods->allocate_invoke (ptr->customFW_private_data,
183  prop, input, output);
184  } else {
185  return -1;
186  }
187 }
188 
192 static int
193 custom_getInputDim (const GstTensorFilterProperties * prop, void **private_data,
194  GstTensorsInfo * info)
195 {
196  internal_data *ptr;
197 
198  ptr = *private_data;
199  g_return_val_if_fail (ptr != NULL, -EINVAL);
200  g_return_val_if_fail (info != NULL, -EINVAL);
201 
202  if (ptr->methods->getInputDim == NULL)
203  return -ENOENT;
204 
205  return ptr->methods->getInputDim (ptr->customFW_private_data, prop, info);
206 }
207 
211 static int
213  void **private_data, GstTensorsInfo * info)
214 {
215  internal_data *ptr;
216 
217  ptr = *private_data;
218  g_return_val_if_fail (ptr != NULL, -EINVAL);
219  g_return_val_if_fail (info != NULL, -EINVAL);
220 
221  if (ptr->methods->getOutputDim == NULL)
222  return -ENOENT;
223 
224  return ptr->methods->getOutputDim (ptr->customFW_private_data, prop, info);
225 }
226 
230 static int
231 custom_setInputDim (const GstTensorFilterProperties * prop, void **private_data,
232  const GstTensorsInfo * in_info, GstTensorsInfo * out_info)
233 {
234  internal_data *ptr;
235 
236  ptr = *private_data;
237  g_return_val_if_fail (ptr != NULL, -EINVAL);
238  g_return_val_if_fail (in_info != NULL, -EINVAL);
239  g_return_val_if_fail (out_info != NULL, -EINVAL);
240 
241  if (ptr->methods->setInputDim == NULL)
242  return -ENOENT;
243 
244  return ptr->methods->setInputDim (ptr->customFW_private_data,
245  prop, in_info, out_info);
246 }
247 
251 static void
252 custom_close (const GstTensorFilterProperties * prop, void **private_data)
253 {
254  internal_data *ptr = *private_data;
255 
256  g_return_if_fail (ptr != NULL);
257 
259  g_free (ptr);
260  *private_data = NULL;
261 }
262 
266 static void
267 custom_destroyNotify (void **private_data, void *data)
268 {
269  internal_data *ptr = *private_data;
270 
271  if (ptr && ptr->methods->allocate_invoke && ptr->methods->destroy_notify &&
272  data) {
273  ptr->methods->destroy_notify (data);
274  } else {
275  g_free (data);
276  }
277 }
278 
282 static int
283 custom_allocateInInvoke (void **private_data)
284 {
285  internal_data *ptr = *private_data;
286 
287  if (ptr && ptr->methods->allocate_invoke) {
288  return 0;
289  }
290 
291  return -EINVAL;
292 }
293 
297 static int
299 {
300  if (g_strv_contains (custom_accl_support, get_accl_hw_str (hw)))
301  return 0;
302 
303  return -ENOENT;
304 }
305 
306 static gchar filter_subplugin_custom[] = "custom";
307 
310  .name = filter_subplugin_custom,
311  .allow_in_place = FALSE, /* custom cannot support in-place (output == input). */
312  .allocate_in_invoke = TRUE, /* GstTensorFilter allocates output buffers */
313  .run_without_model = FALSE, /* custom needs a so file */
314  .invoke_NN = custom_invoke,
315  .handleEvent = NULL, /* do not set event function for custom filter */
316  .getInputDimension = custom_getInputDim,
317  .getOutputDimension = custom_getOutputDim,
318  .setInputDimension = custom_setInputDim,
319  .open = custom_open,
320  .close = custom_close,
321  .destroyNotify = custom_destroyNotify, /* if custom filter model supports allocate_in_invoke, this will be set from custom filter. */
322  .allocateInInvoke = custom_allocateInInvoke,
323  .checkAvailability = custom_checkAvailability,
324 };
325 
327 void
328 init_filter_custom (void)
329 {
331 }
332 
334 void
336 {
338 }
accl_hw
accl_hw
acceleration hw properties.
Definition: nnstreamer_plugin_api_filter.h:80
custom_loadlib
static int custom_loadlib(const GstTensorFilterProperties *prop, void **private_data)
Load the custom library. Will skip loading if it's already loaded.
Definition: tensor_filter_custom.c:64
custom_destroyNotify
static void custom_destroyNotify(void **private_data, void *data)
The optional callback for GstTensorFilterFramework.
Definition: tensor_filter_custom.c:267
ACCL_AUTO_STR
#define ACCL_AUTO_STR
Definition: nnstreamer_plugin_api_filter.h:22
_NNStreamer_custom_class::exitfunc
NNS_custom_exit_func exitfunc
Definition: tensor_filter_custom.h:128
_internal_data
internal_data
Definition: tensor_filter_custom.c:50
data
svtc_1 data
Definition: gsttensor_if.c:844
ml_logw
#define ml_logw
Definition: nnstreamer_log.h:77
nnstreamer_filter_exit
void nnstreamer_filter_exit(const char *name)
Filter's sub-plugin may call this to unregister itself.
Definition: tensor_filter_common.c:638
FALSE
return FALSE
Definition: gsttensor_transform.c:590
custom_open
static int custom_open(const GstTensorFilterProperties *prop, void **private_data)
The open callback for GstTensorFilterFramework. Called before anything else.
Definition: tensor_filter_custom.c:138
nnstreamer_conf.h
Internal header for conf/env-var management.
GstTensorsInfo
Internal meta data exchange format for a other/tensors instance.
Definition: tensor_typedef.h:273
_NNStreamer_custom_class::getInputDim
NNS_custom_get_input_dimension getInputDim
Definition: tensor_filter_custom.h:129
prop
GstTensorSrcIIOChannelProperties * prop
DTYPE_UNSIGNED ( .
Definition: gsttensor_srciio.c:110
ACCL_DEFAULT_STR
#define ACCL_DEFAULT_STR
Definition: nnstreamer_plugin_api_filter.h:21
nnstreamer_log.h
Internal log util for NNStreamer plugins and native APIs.
GstTensorMemory
The unit of each data tensors. It will be used as an input/output tensor of other/tensors.
Definition: tensor_typedef.h:252
_GstTensorFilterFramework
Tensor_Filter Subplugin definition.
Definition: nnstreamer_plugin_api_filter.h:249
_GstTensorFilterFramework::version
uint64_t version
Definition: nnstreamer_plugin_api_filter.h:251
NNS_support_custom
static GstTensorFilterFramework NNS_support_custom
Definition: tensor_filter_custom.c:308
_NNStreamer_custom_class
Custom Filter Class.
Definition: tensor_filter_custom.h:125
_internal_data::customFW_private_data
void * customFW_private_data
Definition: tensor_filter_custom.c:55
g_free
g_free(self->option[(opnum) - 1])
opnum: \
custom_getInputDim
static int custom_getInputDim(const GstTensorFilterProperties *prop, void **private_data, GstTensorsInfo *info)
The optional callback for GstTensorFilterFramework.
Definition: tensor_filter_custom.c:193
_NNStreamer_custom_class::initfunc
NNS_custom_init_func initfunc
Definition: tensor_filter_custom.h:127
_internal_data::module
GModule * module
Definition: tensor_filter_custom.c:52
__attribute__
__attribute__((__format__(__printf__, 1, 2)))
overwrites the error message buffer with the new message.
Definition: nnstreamer_log.c:97
nnsconf_validate_file
gboolean nnsconf_validate_file(nnsconf_type_path type, const gchar *fullpath)
Public function to validate sub-plugin library is available.
Definition: nnstreamer_conf.c:503
NNSCONF_PATH_CUSTOM_FILTERS
@ NNSCONF_PATH_CUSTOM_FILTERS
Definition: nnstreamer_conf.h:66
GST_TENSOR_FILTER_FRAMEWORK_V0
#define GST_TENSOR_FILTER_FRAMEWORK_V0
Definition: nnstreamer_plugin_api_filter.h:37
get_accl_hw_str
const char * get_accl_hw_str(const accl_hw key)
return string based on accl_hw type
Definition: tensor_filter_common.c:2598
tensor_filter_custom.h
Custom tensor post-processing interface for NNStreamer suite for post-processing code developers.
init_filter_custom
void init_filter_custom(void)
Initialize this object for tensor_filter subplugin runtime register.
Definition: tensor_filter_custom.c:38
_GstTensorFilterFramework::name
char * name
Definition: nnstreamer_plugin_api_filter.h:284
filter_subplugin_custom
static gchar filter_subplugin_custom[]
Definition: tensor_filter_custom.c:306
custom_getOutputDim
static int custom_getOutputDim(const GstTensorFilterProperties *prop, void **private_data, GstTensorsInfo *info)
The optional callback for GstTensorFilterFramework.
Definition: tensor_filter_custom.c:212
ml_loge
#define ml_loge
Definition: nnstreamer_log.h:78
nnstreamer_plugin_api_filter.h
Mandatory APIs for NNStreamer Filter sub-plugins (No External Dependencies)
TRUE
return TRUE
Definition: gsttensor_if.c:897
nnstreamer_filter_probe
int nnstreamer_filter_probe(GstTensorFilterFramework *tfsp)
Filter's sub-plugin should call this function to register itself.
Definition: tensor_filter_common.c:611
_GstTensorFilterProperties
GstTensorFilter's properties for NN framework (internal data structure)
Definition: nnstreamer_plugin_api_filter.h:112
custom_setInputDim
static int custom_setInputDim(const GstTensorFilterProperties *prop, void **private_data, const GstTensorsInfo *in_info, GstTensorsInfo *out_info)
The set-input-dim callback for GstTensorFilterFramework.
Definition: tensor_filter_custom.c:231
custom_checkAvailability
static int custom_checkAvailability(accl_hw hw)
Check support of the backend.
Definition: tensor_filter_custom.c:298
_NNStreamer_custom_class::getOutputDim
NNS_custom_get_output_dimension getOutputDim
Definition: tensor_filter_custom.h:130
_NNStreamer_custom_class::allocate_invoke
NNS_custom_allocate_invoke allocate_invoke
Definition: tensor_filter_custom.h:133
_NNStreamer_custom_class::destroy_notify
NNS_custom_destroy_notify destroy_notify
Definition: tensor_filter_custom.h:134
_internal_data::methods
NNStreamer_custom_class * methods
Definition: tensor_filter_custom.c:53
custom_invoke
static int custom_invoke(const GstTensorFilterProperties *prop, void **private_data, const GstTensorMemory *input, GstTensorMemory *output)
The mandatory callback for GstTensorFilterFramework.
Definition: tensor_filter_custom.c:167
custom_close
static void custom_close(const GstTensorFilterProperties *prop, void **private_data)
Free privateData and move on.
Definition: tensor_filter_custom.c:252
fini_filter_custom
void fini_filter_custom(void)
Destruct the subplugin.
Definition: tensor_filter_custom.c:335
custom_allocateInInvoke
static int custom_allocateInInvoke(void **private_data)
The optional callback for GstTensorFilterFramework.
Definition: tensor_filter_custom.c:283
_NNStreamer_custom_class::invoke
NNS_custom_invoke invoke
Definition: tensor_filter_custom.h:132
_NNStreamer_custom_class::setInputDim
NNS_custom_set_input_dimension setInputDim
Definition: tensor_filter_custom.h:131