From 745bb4085de9103f31d75508bbef56b6902d6f15 Mon Sep 17 00:00:00 2001 From: Jaeyun Date: Fri, 26 Apr 2019 14:04:05 +0900 Subject: [PATCH] [Filter/Api] move NNFW struct Mode the struct NNFW definition and properties into filter-api header. Change function name and code clean. TODO : update decoder struct and api also. Signed-off-by: Jaeyun Jung --- .../tensor_filter/tensor_filter_python.c | 15 ++- .../tensor_filter/tensor_filter_tensorflow.c | 10 +- .../tensor_filter/tensor_filter_tensorflow_core.h | 3 +- .../tensor_filter/tensor_filter_tensorflow_lite.c | 8 +- .../tensor_filter_tensorflow_lite_core.h | 3 +- gst/nnstreamer/nnstreamer_plugin_api_filter.h | 119 +++++++++++++++++++- gst/nnstreamer/tensor_filter/tensor_filter.c | 9 +- gst/nnstreamer/tensor_filter/tensor_filter.h | 6 +- .../tensor_filter/tensor_filter_custom.c | 9 +- gst/nnstreamer/tensor_filter_custom.h | 1 + gst/nnstreamer/tensor_typedef.h | 124 +-------------------- 11 files changed, 158 insertions(+), 149 deletions(-) diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_python.c b/ext/nnstreamer/tensor_filter/tensor_filter_python.c index d634190..0128cd1 100644 --- a/ext/nnstreamer/tensor_filter/tensor_filter_python.c +++ b/ext/nnstreamer/tensor_filter/tensor_filter_python.c @@ -29,6 +29,9 @@ #include #include +void init_filter_py (void) __attribute__ ((constructor)); +void fini_filter_py (void) __attribute__ ((destructor)); + /** * @brief internal data of python */ @@ -228,16 +231,16 @@ GstTensorFilterFramework _NNS_support_python = { }; /** @brief Initialize this object for tensor_filter subplugin runtime register */ -__attribute__ ((constructor)) - void init_filter_py (void) +void +init_filter_py (void) { NNS_support_python = &_NNS_support_python; - tensor_filter_probe (NNS_support_python); + nnstreamer_filter_probe (NNS_support_python); } /** @brief Destruct the subplugin */ -__attribute__ ((destructor)) - void fini_filter_py (void) +void +fini_filter_py (void) { - tensor_filter_exit (NNS_support_python->name); + nnstreamer_filter_exit (NNS_support_python->name); } diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow.c b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow.c index 62a4206..2a6d2ed 100644 --- a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow.c +++ b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow.c @@ -26,11 +26,11 @@ * */ -#include -#include "tensor_filter_tensorflow_core.h" #include #include -#include + +#include "nnstreamer_conf.h" +#include "tensor_filter_tensorflow_core.h" void init_filter_tf (void) __attribute__ ((constructor)); void fini_filter_tf (void) __attribute__ ((destructor)); @@ -192,12 +192,12 @@ static GstTensorFilterFramework NNS_support_tensorflow = { void init_filter_tf (void) { - tensor_filter_probe (&NNS_support_tensorflow); + nnstreamer_filter_probe (&NNS_support_tensorflow); } /** @brief Destruct the subplugin */ void fini_filter_tf (void) { - tensor_filter_exit (NNS_support_tensorflow.name); + nnstreamer_filter_exit (NNS_support_tensorflow.name); } diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_core.h b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_core.h index eebc38d..24591e1 100644 --- a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_core.h +++ b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_core.h @@ -26,13 +26,14 @@ #ifndef TENSOR_FILTER_TENSORFLOW_CORE_H #define TENSOR_FILTER_TENSORFLOW_CORE_H -#include #include #include #include #include #include +#include "nnstreamer_plugin_api_filter.h" + #ifdef __cplusplus #include #include diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.c b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.c index fd03205..49d9ae4 100644 --- a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.c +++ b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite.c @@ -26,11 +26,11 @@ * */ -#include -#include "tensor_filter_tensorflow_lite_core.h" #include #include +#include "tensor_filter_tensorflow_lite_core.h" + void init_filter_tflite (void) __attribute__ ((constructor)); void fini_filter_tflite (void) __attribute__ ((destructor)); @@ -178,12 +178,12 @@ static GstTensorFilterFramework NNS_support_tensorflow_lite = { void init_filter_tflite (void) { - tensor_filter_probe (&NNS_support_tensorflow_lite); + nnstreamer_filter_probe (&NNS_support_tensorflow_lite); } /** @brief Destruct the subplugin */ void fini_filter_tflite (void) { - tensor_filter_exit (NNS_support_tensorflow_lite.name); + nnstreamer_filter_exit (NNS_support_tensorflow_lite.name); } diff --git a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite_core.h b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite_core.h index 78cea50..af66825 100644 --- a/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite_core.h +++ b/ext/nnstreamer/tensor_filter/tensor_filter_tensorflow_lite_core.h @@ -23,10 +23,11 @@ #ifndef TENSOR_FILTER_TENSORFLOW_LITE_CORE_H #define TENSOR_FILTER_TENSORFLOW_LITE_CORE_H -#include #include #include +#include "nnstreamer_plugin_api_filter.h" + #ifdef __cplusplus #include diff --git a/gst/nnstreamer/nnstreamer_plugin_api_filter.h b/gst/nnstreamer/nnstreamer_plugin_api_filter.h index b9e48d0..78f4689 100644 --- a/gst/nnstreamer/nnstreamer_plugin_api_filter.h +++ b/gst/nnstreamer/nnstreamer_plugin_api_filter.h @@ -14,7 +14,7 @@ * */ /** - * @file nnstreamer_plugin_api_filters.h + * @file nnstreamer_plugin_api_filter.h * @date 30 Jan 2019 * @brief Mandatory APIs for NNStreamer Filter sub-plugins (No External Dependencies) * @see https://github.com/nnsuite/nnstreamer @@ -26,17 +26,130 @@ #include "tensor_typedef.h" +/** + * @brief GstTensorFilter's properties for NN framework (internal data structure) + * + * Because custom filters of tensor_filter may need to access internal data + * of GstTensorFilter, we define this data structure here. + */ +typedef struct _GstTensorFilterProperties +{ + const char *fwname; /**< The name of NN Framework */ + int fw_opened; /**< TRUE IF open() is called or tried. Use int instead of gboolean because this is refered by custom plugins. */ + const char *model_file; /**< Filepath to the model file (as an argument for NNFW). char instead of gchar for non-glib custom plugins */ + + int input_configured; /**< TRUE if input tensor is configured. Use int instead of gboolean because this is refered by custom plugins. */ + GstTensorsInfo input_meta; /**< configured input tensor info */ + + int output_configured; /**< TRUE if output tensor is configured. Use int instead of gboolean because this is refered by custom plugins. */ + GstTensorsInfo output_meta; /**< configured output tensor info */ + + const char *custom_properties; /**< sub-plugin specific custom property values in string */ +} GstTensorFilterProperties; + +/** + * @brief Tensor_Filter Subplugin definition + * + * Common callback parameters: + * prop Filter properties. Read Only. + * private_data Subplugin's private data. Set this (*private_data = XXX) if you want to change filter->private_data. + */ +typedef struct _GstTensorFilterFramework +{ + char *name; /**< Name of the neural network framework, searchable by FRAMEWORK property */ + int allow_in_place; /**< TRUE(nonzero) if InPlace transfer of input-to-output is allowed. Not supported in main, yet */ + int allocate_in_invoke; /**< TRUE(nonzero) if invoke_NN is going to allocate outputptr by itself and return the address via outputptr. Do not change this value after cap negotiation is complete (or the stream has been started). */ + + int (*invoke_NN) (const GstTensorFilterProperties * prop, void **private_data, + const GstTensorMemory * input, GstTensorMemory * output); + /**< Mandatory callback. Invoke the given network model. + * + * @param[in] prop read-only property values + * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. + * @param[in] input The array of input tensors. Allocated and filled by tensor_filter/main + * @param[out] output The array of output tensors. Allocated by tensor_filter/main and to be filled by invoke_NN. If allocate_in_invoke is TRUE, sub-plugin should allocate the memory block for output tensor. (data in GstTensorMemory) + * @return 0 if OK. non-zero if error. + */ + + int (*getInputDimension) (const GstTensorFilterProperties * prop, + void **private_data, GstTensorsInfo * info); + /**< Optional. Set NULL if not supported. Get dimension of input tensor + * If getInputDimension is NULL, setInputDimension must be defined. + * If getInputDimension is defined, it is recommended to define getOutputDimension + * + * @param[in] prop read-only property values + * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. + * @param[out] info structure of tensor info (return value) + * @return the size of input tensors + */ + + int (*getOutputDimension) (const GstTensorFilterProperties * prop, + void **private_data, GstTensorsInfo * info); + /**< Optional. Set NULL if not supported. Get dimension of output tensor + * If getInputDimension is NULL, setInputDimension must be defined. + * If getInputDimension is defined, it is recommended to define getOutputDimension + * + * @param[in] prop read-only property values + * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. + * @param[out] info structure of tensor info (return value) + * @return the size of output tensors + */ + + int (*setInputDimension) (const GstTensorFilterProperties * prop, + void **private_data, const GstTensorsInfo * in_info, + GstTensorsInfo * out_info); + /**< Optional. Set Null if not supported. Tensor_Filter::main will + * configure input dimension from pad-cap in run-time for the sub-plugin. + * Then, the sub-plugin is required to return corresponding output dimension + * If this is NULL, both getInput/OutputDimension must be non-NULL. + * + * When you use this, do NOT allocate or fix internal data structure based on it + * until invoke is called. Gstreamer may try different dimensions before + * settling down. + * + * @param[in] prop read-only property values + * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. + * @param[in] in_info structure of input tensor info + * @param[out] out_info structure of output tensor info (return value) + * @return 0 if OK. non-zero if error. + */ + + int (*open) (const GstTensorFilterProperties * prop, void **private_data); + /**< Optional. tensor_filter.c will call this before any of other callbacks and will call once before calling close + * + * @param[in] prop read-only property values + * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. Normally, open() allocates memory for private_data. + * @return 0 if ok. < 0 if error. + */ + + void (*close) (const GstTensorFilterProperties * prop, void **private_data); + /**< Optional. tensor_filter.c will not call other callbacks after calling close. Free-ing private_data is this function's responsibility. Set NULL after that. + * + * @param[in] prop read-only property values + * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. Normally, close() frees private_data and set NULL. + */ + + void (*destroyNotify) (void * data); + /**< Optional. tensor_filter.c will call it when 'allocate_in_invoke' flag of the framework is TRUE. Basically, it is called when the data element is destroyed. If it's set as NULL, g_free() will be used as a default. It will be helpful when the data pointer is included as an object of a nnfw. For instance, if the data pointer is removed when the object is gone, it occurs error. In this case, the objects should be maintained for a while first and destroyed when the data pointer is destroyed. Those kinds of logic could be defined at this method. + * + * @param[in] data the data element. + */ +} GstTensorFilterFramework; + /* extern functions for subplugin management, exist in tensor_filter.c */ /** * @brief Filter subplugin should call this to register itself * @param[in] tfsp Tensor-Filter Sub-Plugin to be registered * @return TRUE if registered. FALSE is failed or duplicated. */ -extern int tensor_filter_probe (GstTensorFilterFramework *tfsp); +extern int +nnstreamer_filter_probe (GstTensorFilterFramework * tfsp); + /** * @brief filter sub-plugin may call this to unregister itself * @param[in] name the name of filter sub-plugin */ -extern void tensor_filter_exit (const char *name); +extern void +nnstreamer_filter_exit (const char * name); #endif /* __NNS_PLUGIN_API_FILTER_H__ */ diff --git a/gst/nnstreamer/tensor_filter/tensor_filter.c b/gst/nnstreamer/tensor_filter/tensor_filter.c index 34842d4..1e503ea 100644 --- a/gst/nnstreamer/tensor_filter/tensor_filter.c +++ b/gst/nnstreamer/tensor_filter/tensor_filter.c @@ -60,7 +60,6 @@ #include #include "tensor_filter.h" -#include "nnstreamer_plugin_api_filter.h" /** * @brief Macro for debug mode. @@ -116,7 +115,7 @@ * @return TRUE if registered. FALSE is failed or duplicated. */ int -tensor_filter_probe (GstTensorFilterFramework * tfsp) +nnstreamer_filter_probe (GstTensorFilterFramework * tfsp) { return register_subplugin (NNS_SUBPLUGIN_FILTER, tfsp->name, tfsp); } @@ -126,7 +125,7 @@ tensor_filter_probe (GstTensorFilterFramework * tfsp) * @param[in] name the name of filter sub-plugin */ void -tensor_filter_exit (const char *name) +nnstreamer_filter_exit (const char *name) { unregister_subplugin (NNS_SUBPLUGIN_FILTER, name); } @@ -137,7 +136,7 @@ tensor_filter_exit (const char *name) * @return NULL if not found or the sub-plugin object. */ static const GstTensorFilterFramework * -tensor_filter_find (const gchar * name) +nnstreamer_filter_find (const gchar * name) { return get_subplugin (NNS_SUBPLUGIN_FILTER, name); } @@ -459,7 +458,7 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id, if (self->fw != NULL) { gst_tensor_filter_close_fw (self); } - self->fw = tensor_filter_find (fw_name); + self->fw = nnstreamer_filter_find (fw_name); silent_debug ("Framework = %s\n", fw_name); if (self->fw == NULL) { diff --git a/gst/nnstreamer/tensor_filter/tensor_filter.h b/gst/nnstreamer/tensor_filter/tensor_filter.h index b0b95ac..c2db4cf 100644 --- a/gst/nnstreamer/tensor_filter/tensor_filter.h +++ b/gst/nnstreamer/tensor_filter/tensor_filter.h @@ -33,8 +33,10 @@ #include #include #include -#include -#include + +#include "tensor_common.h" +#include "nnstreamer_subplugin.h" +#include "nnstreamer_plugin_api_filter.h" G_BEGIN_DECLS diff --git a/gst/nnstreamer/tensor_filter/tensor_filter_custom.c b/gst/nnstreamer/tensor_filter/tensor_filter_custom.c index ecdc263..7f94bee 100644 --- a/gst/nnstreamer/tensor_filter/tensor_filter_custom.c +++ b/gst/nnstreamer/tensor_filter/tensor_filter_custom.c @@ -27,11 +27,12 @@ */ #include -#include "tensor_filter_custom.h" -#include #include #include +#include "tensor_filter_custom.h" +#include "nnstreamer_plugin_api_filter.h" + void init_filter_custom (void) __attribute__ ((constructor)); void fini_filter_custom (void) __attribute__ ((destructor)); @@ -253,12 +254,12 @@ static GstTensorFilterFramework NNS_support_custom = { void init_filter_custom (void) { - tensor_filter_probe (&NNS_support_custom); + nnstreamer_filter_probe (&NNS_support_custom); } /** @brief Destruct the subplugin */ void fini_filter_custom (void) { - tensor_filter_exit (NNS_support_custom.name); + nnstreamer_filter_exit (NNS_support_custom.name); } diff --git a/gst/nnstreamer/tensor_filter_custom.h b/gst/nnstreamer/tensor_filter_custom.h index 2f350ac..b79fecd 100644 --- a/gst/nnstreamer/tensor_filter_custom.h +++ b/gst/nnstreamer/tensor_filter_custom.h @@ -36,6 +36,7 @@ #include #include "tensor_typedef.h" +#include "nnstreamer_plugin_api_filter.h" /** * @brief A function that is called before calling other functions. diff --git a/gst/nnstreamer/tensor_typedef.h b/gst/nnstreamer/tensor_typedef.h index 1426aab..5e8a6a1 100644 --- a/gst/nnstreamer/tensor_typedef.h +++ b/gst/nnstreamer/tensor_typedef.h @@ -75,7 +75,7 @@ * type should be one of types in GST_TENSOR_TYPE_ALL * "types = (string) uint8, uint8, uint8" * Dimensions of Tensors for negotiation. It's comment out here, - but when we call gst_structure_get_string, it actually is working well + * but when we call gst_structure_get_string, it actually is working well. * "dimensions = (string) dim1:dim2:dim3:dim4, dim1:dim2:dim3:dim4" */ @@ -165,7 +165,7 @@ typedef struct */ typedef struct { - char * name; /**< Name of each element in the tensor. User must designate this. */ + char *name; /**< Name of each element in the tensor. User must designate this. */ tensor_type type; /**< Type of each element in the tensor. User must designate this. */ tensor_dim dimension; /**< Dimension. We support up to 4th ranks. */ } GstTensorInfo; @@ -185,8 +185,8 @@ typedef struct typedef struct { GstTensorInfo info; /**< tensor info*/ - int32_t rate_n; /**< framerate is in fraction, which is numerator/denominator */ - int32_t rate_d; /**< framerate is in fraction, which is numerator/denominator */ + int rate_n; /**< framerate is in fraction, which is numerator/denominator */ + int rate_d; /**< framerate is in fraction, which is numerator/denominator */ } GstTensorConfig; /** @@ -195,120 +195,8 @@ typedef struct typedef struct { GstTensorsInfo info; /**< tensor info*/ - int32_t rate_n; /**< framerate is in fraction, which is numerator/denominator */ - int32_t rate_d; /**< framerate is in fraction, which is numerator/denominator */ + int rate_n; /**< framerate is in fraction, which is numerator/denominator */ + int rate_d; /**< framerate is in fraction, which is numerator/denominator */ } GstTensorsConfig; - -/** @todo Separate headers per subplugin-category */ -/** - * @brief GstTensorFilter's properties for NN framework (internal data structure) - * - * Because custom filters of tensor_filter may need to access internal data - * of GstTensorFilter, we define this data structure here. - */ -typedef struct _GstTensorFilterProperties -{ - const char *fwname; /**< The name of NN Framework */ - int fw_opened; /**< TRUE IF open() is called or tried. Use int instead of gboolean because this is refered by custom plugins. */ - const char *model_file; /**< Filepath to the model file (as an argument for NNFW). char instead of gchar for non-glib custom plugins */ - - int input_configured; /**< TRUE if input tensor is configured. Use int instead of gboolean because this is refered by custom plugins. */ - GstTensorsInfo input_meta; /**< configured input tensor info */ - - int output_configured; /**< TRUE if output tensor is configured. Use int instead of gboolean because this is refered by custom plugins. */ - GstTensorsInfo output_meta; /**< configured output tensor info */ - - const char *custom_properties; /**< sub-plugin specific custom property values in string */ -} GstTensorFilterProperties; - -/** - * @brief Tensor_Filter Subplugin definition - * - * Common callback parameters: - * prop Filter properties. Read Only. - * private_data Subplugin's private data. Set this (*private_data = XXX) if you want to change filter->private_data. - */ -typedef struct _GstTensorFilterFramework -{ - char *name; /**< Name of the neural network framework, searchable by FRAMEWORK property */ - int allow_in_place; /**< TRUE(nonzero) if InPlace transfer of input-to-output is allowed. Not supported in main, yet */ - int allocate_in_invoke; /**< TRUE(nonzero) if invoke_NN is going to allocate outputptr by itself and return the address via outputptr. Do not change this value after cap negotiation is complete (or the stream has been started). */ - - int (*invoke_NN) (const GstTensorFilterProperties * prop, void **private_data, - const GstTensorMemory * input, GstTensorMemory * output); - /**< Mandatory callback. Invoke the given network model. - * - * @param[in] prop read-only property values - * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. - * @param[in] input The array of input tensors. Allocated and filled by tensor_filter/main - * @param[out] output The array of output tensors. Allocated by tensor_filter/main and to be filled by invoke_NN. If allocate_in_invoke is TRUE, sub-plugin should allocate the memory block for output tensor. (data in GstTensorMemory) - * @return 0 if OK. non-zero if error. - */ - - int (*getInputDimension) (const GstTensorFilterProperties * prop, - void **private_data, GstTensorsInfo * info); - /**< Optional. Set NULL if not supported. Get dimension of input tensor - * If getInputDimension is NULL, setInputDimension must be defined. - * If getInputDimension is defined, it is recommended to define getOutputDimension - * - * @param[in] prop read-only property values - * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. - * @param[out] info structure of tensor info (return value) - * @return the size of input tensors - */ - - int (*getOutputDimension) (const GstTensorFilterProperties * prop, - void **private_data, GstTensorsInfo * info); - /**< Optional. Set NULL if not supported. Get dimension of output tensor - * If getInputDimension is NULL, setInputDimension must be defined. - * If getInputDimension is defined, it is recommended to define getOutputDimension - * - * @param[in] prop read-only property values - * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. - * @param[out] info structure of tensor info (return value) - * @return the size of output tensors - */ - - int (*setInputDimension) (const GstTensorFilterProperties * prop, - void **private_data, const GstTensorsInfo * in_info, - GstTensorsInfo * out_info); - /**< Optional. Set Null if not supported. Tensor_Filter::main will - * configure input dimension from pad-cap in run-time for the sub-plugin. - * Then, the sub-plugin is required to return corresponding output dimension - * If this is NULL, both getInput/OutputDimension must be non-NULL. - * - * When you use this, do NOT allocate or fix internal data structure based on it - * until invoke is called. Gstreamer may try different dimensions before - * settling down. - * - * @param[in] prop read-only property values - * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. - * @param[in] in_info structure of input tensor info - * @param[out] out_info structure of output tensor info (return value) - * @return 0 if OK. non-zero if error. - */ - - int (*open) (const GstTensorFilterProperties * prop, void **private_data); - /**< Optional. tensor_filter.c will call this before any of other callbacks and will call once before calling close - * - * @param[in] prop read-only property values - * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. Normally, open() allocates memory for private_data. - * @return 0 if ok. < 0 if error. - */ - - void (*close) (const GstTensorFilterProperties * prop, void **private_data); - /**< Optional. tensor_filter.c will not call other callbacks after calling close. Free-ing private_data is this function's responsibility. Set NULL after that. - * - * @param[in] prop read-only property values - * @param[in/out] private_data A subplugin may save its internal private data here. The subplugin is responsible for alloc/free of this pointer. Normally, close() frees private_data and set NULL. - */ - - void (*destroyNotify) (void * data); - /**< Optional. tensor_filter.c will call it when 'allocate_in_invoke' flag of the framework is TRUE. Basically, it is called when the data element is destroyed. If it's set as NULL, g_free() will be used as a default. It will be helpful when the data pointer is included as an object of a nnfw. For instance, if the data pointer is removed when the object is gone, it occurs error. In this case, the objects should be maintained for a while first and destroyed when the data pointer is destroyed. Those kinds of logic could be defined at this method. - * - * @param[in] data the data element. - */ -} GstTensorFilterFramework; - #endif /*__GST_TENSOR_TYPEDEF_H__*/ -- 2.7.4