/**
* @brief List of bounding-box decoding schemes in string
*/
-static const gchar *bb_modes[] = {
+static const char *bb_modes[] = {
[TFLITE_SSD_BOUNDING_BOX] = "tflite-ssd",
[TF_SSD_BOUNDING_BOX] = "tf-ssd",
NULL,
typedef struct
{
/* From option3, box prior data */
- gchar *box_prior_path; /**< Box Prior file path */
+ char *box_prior_path; /**< Box Prior file path */
gfloat box_priors[BOX_SIZE][TFLITE_SSD_DETECTION_MAX + 1]; /** loaded box prior */
} properties_TFLite_SSD;
};
/* From option2 */
- gchar *label_path; /**< Label file path. */
- gchar **labels; /**< The list of loaded labels. Null if not loaded */
+ char *label_path; /**< Label file path. */
+ char **labels; /**< The list of loaded labels. Null if not loaded */
guint total_labels; /**< The number of loaded labels */
guint max_word_length; /**< The max size of labels */
} bounding_boxes;
/** @brief Initialize bounding_boxes per mode */
-static gboolean
+static int
_init_modes (bounding_boxes * bdata)
{
if (bdata->mode == TFLITE_SSD_BOUNDING_BOX) {
}
/** @brief tensordec-plugin's TensorDecDef callback */
-static gboolean
-bb_init (GstTensorDec * self)
+static int
+bb_init (void **pdata)
{
/** @todo check if we need to ensure plugin_data is not yet allocated */
bounding_boxes *bdata;
int i, j, k;
- self->plugin_data = g_new0 (bounding_boxes, 1);
+ *pdata = g_new0 (bounding_boxes, 1);
- bdata = self->plugin_data;
+ bdata = *pdata;
bdata->mode = BOUNDING_BOX_UNKNOWN;
bdata->width = 0;
bdata->height = 0;
/** @brief tensordec-plugin's TensorDecDef callback */
static void
-bb_exit (GstTensorDec * self)
+bb_exit (void **pdata)
{
- bounding_boxes *bdata = self->plugin_data;
+ bounding_boxes *bdata = *pdata;
if (bdata->labels) {
int i;
g_free (bdata->label_path);
_exit_modes (bdata);
- g_free (self->plugin_data);
- self->plugin_data = NULL;
+ g_free (*pdata);
+ *pdata = NULL;
}
/**
char *line = NULL;
size_t len = 0;
ssize_t read;
- gchar *label;
+ char *label;
GList *labels = NULL, *cursor;
if (line[strlen (line) - 1] == '\n') {
line[strlen (line) - 1] = '\0';
}
- label = g_strdup ((gchar *) line);
+ label = g_strdup ((char *) line);
labels = g_list_append (labels, label);
free (line);
if (strlen (label) > data->max_word_length)
free (line);
}
- /* Flatten labels (GList) into data->labels (array gchar **) */
+ /* Flatten labels (GList) into data->labels (array char **) */
data->total_labels = g_list_length (labels);
- data->labels = g_new (gchar *, data->total_labels);
+ data->labels = g_new (char *, data->total_labels);
i = 0;
cursor = g_list_first (labels);
for (cursor = labels; cursor != NULL; cursor = cursor->next) {
return;
}
-static gboolean _tflite_ssd_loadBoxPrior (bounding_boxes * bdata);
+static int _tflite_ssd_loadBoxPrior (bounding_boxes * bdata);
/** @brief configure per-mode option (option3) */
-static gboolean
-_setOption_mode (bounding_boxes * bdata, const gchar * param)
+static int
+_setOption_mode (bounding_boxes * bdata, const char *param)
{
if (bdata->mode == TFLITE_SSD_BOUNDING_BOX) {
/* Load prior boxes with the path from option3 */
}
/** @brief tensordec-plugin's TensorDecDef callback */
-static gboolean
-bb_setOption (GstTensorDec * self, int opNum, const gchar * param)
+static int
+bb_setOption (void **pdata, int opNum, const char *param)
{
- bounding_boxes *bdata = self->plugin_data;
+ bounding_boxes *bdata = *pdata;
if (opNum == 0) {
/* option1 = Bounding Box Decoding mode */
/**
* @brief check the num_tensors is valid
*/
-static gboolean
+static int
_check_tensors (const GstTensorsConfig * config, const int limit)
{
int i;
/**
* @brief set the max_detection
*/
-static gboolean
+static int
_set_max_detection (bounding_boxes * data, const guint max_detection,
const int limit)
{
* If there are third or more tensors, such tensors will be ignored.
*/
static GstCaps *
-bb_getOutCaps (GstTensorDec * self, const GstTensorsConfig * config)
+bb_getOutCaps (void **pdata, const GstTensorsConfig * config)
{
/** @todo this is compatible with "SSD" only. expand the capability! */
- bounding_boxes *data = self->plugin_data;
+ bounding_boxes *data = *pdata;
GstCaps *caps;
int i;
- gchar *str;
+ char *str;
guint max_detection, max_label;
if (data->mode == TFLITE_SSD_BOUNDING_BOX) {
* @param[in/out] bdata The internal data.
* @return TRUE if loaded and configured. FALSE if failed to do so.
*/
-static gboolean
+static int
_tflite_ssd_loadBoxPrior (bounding_boxes * bdata)
{
FILE *fp;
return FALSE;
}
if (line) {
- gchar **list = g_strsplit_set (line, " \t,", -1);
- gchar *word;
+ char **list = g_strsplit_set (line, " \t,", -1);
+ char *word;
while ((word = list[column]) != NULL) {
column++;
}
/** @brief tensordec-plugin's TensorDecDef callback */
-static gsize
-bb_getTransformSize (GstTensorDec * self, GstCaps * caps,
- gsize size, GstCaps * othercaps, GstPadDirection direction)
+static size_t
+bb_getTransformSize (void **pdata, const GstTensorsConfig * config,
+ GstCaps * caps, size_t size, GstCaps * othercaps, GstPadDirection direction)
{
return 0;
/** @todo Use appropriate values */
/** @brief Represents a detect object */
typedef struct
{
- gboolean valid;
+ int valid;
int class_id;
int x;
int y;
{ \
int d; \
_type * boxinput_ = (_type *) boxinput; \
- gsize boxbpi = config->info.info[0].dimension[0]; \
+ size_t boxbpi = config->info.info[0].dimension[0]; \
_type * detinput_ = (_type *) detinput; \
- gsize detbpi = config->info.info[1].dimension[0]; \
+ size_t detbpi = config->info.info[1].dimension[0]; \
int num = (TFLITE_SSD_DETECTION_MAX > bb->max_detection) ? bb->max_detection : TFLITE_SSD_DETECTION_MAX; \
detectedObject object = { .valid = FALSE, .class_id = 0, .x = 0, .y = 0, .width = 0, .height = 0, .prob = .0 }; \
for (d = 0; d < num; d++) { \
_type * boxes_ = (_type *) boxesinput; \
int num = (int) num_detection_[0]; \
results = g_array_sized_new (FALSE, TRUE, sizeof (detectedObject), num); \
- gsize boxbpi = config->info.info[3].dimension[0]; \
+ size_t boxbpi = config->info.info[3].dimension[0]; \
for (d = 0; d < num; d++) { \
detectedObject object; \
object.valid = TRUE; \
int x1, x2, y1, y2; /* Box positions on the output surface */
int j;
uint32_t *pos1, *pos2;
- const gchar *label;
+ const char *label;
int label_len;
detectedObject *a = &g_array_index (results, detectedObject, i);
/** @brief tensordec-plugin's TensorDecDef callback */
static GstFlowReturn
-bb_decode (GstTensorDec * self, const GstTensorMemory * input,
- GstBuffer * outbuf)
+bb_decode (void **pdata, const GstTensorsConfig * config,
+ const GstTensorMemory * input, GstBuffer * outbuf)
{
- bounding_boxes *bdata = self->plugin_data;
- const gsize size = bdata->width * bdata->height * 4; /* RGBA */
+ bounding_boxes *bdata = *pdata;
+ const size_t size = bdata->width * bdata->height * 4; /* RGBA */
GstMapInfo out_info;
GstMemory *out_mem;
GArray *results = NULL;
- const GstTensorsConfig *config = &self->tensor_config;
const int num_tensors = config->info.num_tensors;
g_assert (outbuf);
#include <tensor_common.h>
/** @brief tensordec-plugin's TensorDecDef callback */
-static gboolean
-dv_init (GstTensorDec * self)
+static int
+dv_init (void **pdata)
{
- self->plugin_data = NULL; /* We have no internal data */
+ *pdata = NULL; /* We have no internal data */
return TRUE;
}
/** @brief tensordec-plugin's TensorDecDef callback */
static void
-dv_exit (GstTensorDec * self)
+dv_exit (void **pdata)
{
/* Nothing to do */
return;
}
/** @brief tensordec-plugin's TensorDecDef callback */
-static gboolean
-dv_setOption (GstTensorDec * self, int opNum, const gchar * param)
+static int
+dv_setOption (void **pdata, int opNum, const char *param)
{
/* We do not accept anything. */
return TRUE;
/** @brief tensordec-plugin's TensorDecDef callback */
static GstCaps *
-dv_getOutCaps (GstTensorDec * self, const GstTensorsConfig * config)
+dv_getOutCaps (void **pdata, const GstTensorsConfig * config)
{
/* Old gst_tensordec_video_caps_from_config () had this */
GstVideoFormat format;
fd = config->rate_d;
if (format != GST_VIDEO_FORMAT_UNKNOWN) {
- const gchar *format_string = gst_video_format_to_string (format);
+ const char *format_string = gst_video_format_to_string (format);
gst_caps_set_simple (caps, "format", G_TYPE_STRING, format_string, NULL);
}
}
/** @brief get video output buffer size */
-static gsize
-_get_video_xraw_bufsize (tensor_dim dim)
+static size_t
+_get_video_xraw_bufsize (const tensor_dim dim)
{
/* dim[0] is bpp and there is zeropadding only when dim[0]%4 > 0 */
return ((dim[0] * dim[1] - 1) / 4 + 1) * 4 * dim[2];
}
/** @brief tensordec-plugin's TensorDecDef callback */
-static gsize
-dv_getTransformSize (GstTensorDec * self, GstCaps * caps,
- gsize size, GstCaps * othercaps, GstPadDirection direction)
+static size_t
+dv_getTransformSize (void **pdata, const GstTensorsConfig * config,
+ GstCaps * caps, size_t size, GstCaps * othercaps, GstPadDirection direction)
{
- GstTensorsConfig *config = &self->tensor_config;
/* Direct video uses the first tensor only even if it's multi-tensor */
- uint32_t *dim = &(config->info.info[0].dimension[0]);
+ const uint32_t *dim = &(config->info.info[0].dimension[0]);
if (direction == GST_PAD_SINK)
return _get_video_xraw_bufsize (dim);
/** @brief tensordec-plugin's TensorDecDef callback */
static GstFlowReturn
-dv_decode (GstTensorDec * self, const GstTensorMemory * input,
- GstBuffer * outbuf)
+dv_decode (void **pdata, const GstTensorsConfig * config,
+ const GstTensorMemory * input, GstBuffer * outbuf)
{
GstMapInfo out_info;
GstMemory *out_mem;
- GstTensorsConfig *config = &self->tensor_config;
/* Direct video uses the first tensor only even if it's multi-tensor */
- uint32_t *dim = &(config->info.info[0].dimension[0]);
+ const uint32_t *dim = &(config->info.info[0].dimension[0]);
size_t size = _get_video_xraw_bufsize (dim);
g_assert (outbuf);
/** @brief Internal data structure for image labeling */
typedef struct
{
- gchar *label_path; /**< Label file path. */
- gchar **labels; /**< The list of loaded labels. Null if not loaded */
+ char *label_path; /**< Label file path. */
+ char **labels; /**< The list of loaded labels. Null if not loaded */
guint total_labels; /**< The number of loaded labels */
guint max_word_length; /**< The max size of labels */
} ImageLabelData;
/** @brief tensordec-plugin's TensorDecDef callback */
-static gboolean
-il_init (GstTensorDec * self)
+static int
+il_init (void **pdata)
{
/** @todo check if we need to ensure plugin_data is not yet allocated */
- self->plugin_data = g_new0 (ImageLabelData, 1);
+ *pdata = g_new0 (ImageLabelData, 1);
return TRUE;
}
/** @brief tensordec-plugin's TensorDecDef callback */
static void
-il_exit (GstTensorDec * self)
+il_exit (void **pdata)
{
- ImageLabelData *data = self->plugin_data;
+ ImageLabelData *data = *pdata;
if (data->labels) {
int i;
for (i = 0; i < data->total_labels; i++)
if (data->label_path)
g_free (data->label_path);
- g_free (self->plugin_data);
- self->plugin_data = NULL;
+ g_free (*pdata);
+ *pdata = NULL;
}
/**
char *line = NULL;
size_t len = 0;
ssize_t read;
- gchar *label;
+ char *label;
GList *labels = NULL, *cursor;
while ((read = getline (&line, &len, fp)) != -1) {
if (line) {
- label = g_strdup ((gchar *) line);
+ label = g_strdup ((char *) line);
labels = g_list_append (labels, label);
free (line);
if (strlen (label) > data->max_word_length)
free (line);
}
- /* Flatten labels (GList) into data->labels (array gchar **) */
+ /* Flatten labels (GList) into data->labels (array char **) */
data->total_labels = g_list_length (labels);
- data->labels = g_new (gchar *, data->total_labels);
+ data->labels = g_new (char *, data->total_labels);
i = 0;
cursor = g_list_first (labels);
for (cursor = labels; cursor != NULL; cursor = cursor->next) {
}
/** @brief tensordec-plugin's TensorDecDef callback */
-static gboolean
-il_setOption (GstTensorDec * self, int opNum, const gchar * param)
+static int
+il_setOption (void **pdata, int opNum, const char *param)
{
- ImageLabelData *data = self->plugin_data;
+ ImageLabelData *data = *pdata;
/* opNum 1 = label file path */
if (opNum == 0) {
/** @brief tensordec-plugin's TensorDecDef callback */
static GstCaps *
-il_getOutCaps (GstTensorDec * self, const GstTensorsConfig * config)
+il_getOutCaps (void **pdata, const GstTensorsConfig * config)
{
const uint32_t *dim;
int i;
}
/** @brief tensordec-plugin's TensorDecDef callback */
-static gsize
-il_getTransformSize (GstTensorDec * self, GstCaps * caps,
- gsize size, GstCaps * othercaps, GstPadDirection direction)
+static size_t
+il_getTransformSize (void **pdata, const GstTensorsConfig * config,
+ GstCaps * caps, size_t size, GstCaps * othercaps, GstPadDirection direction)
{
return 0;
/** @todo Use max_word_length if that's appropriate */
/** @brief tensordec-plugin's TensorDecDef callback */
static GstFlowReturn
-il_decode (GstTensorDec * self, const GstTensorMemory * input,
- GstBuffer * outbuf)
+il_decode (void **pdata, const GstTensorsConfig * config,
+ const GstTensorMemory * input, GstBuffer * outbuf)
{
- ImageLabelData *data = self->plugin_data;
+ ImageLabelData *data = *pdata;
GstMapInfo out_info;
GstMemory *out_mem;
- gsize bpe = tensor_element_size[self->tensor_config.info.info[0].type];
+ size_t bpe = tensor_element_size[config->info.info[0].type];
tensor_element max_val;
guint max_index = 0;
- gsize num_data; /* Size / bpe */
+ size_t num_data; /* Size / bpe */
void *input_data;
- gsize size;
- gchar *str;
+ size_t size;
+ char *str;
g_assert (bpe > 0);
g_assert (outbuf);
input_data = input->data;
- num_data = gst_tensor_info_get_size (&self->tensor_config.info.info[0]) / bpe;
+ num_data = gst_tensor_info_get_size (&config->info.info[0]) / bpe;
- switch (self->tensor_config.info.info[0].type) {
+ switch (config->info.info[0].type) {
search_max_case (int32_t, _NNS_INT32);
search_max_case (uint32_t, _NNS_UINT32);
search_max_case (int16_t, _NNS_INT16);
if (self->mode == DECODE_MODE_PLUGIN) {
g_assert (self->decoder);
- return self->decoder->getOutCaps (self, config);
+ return self->decoder->getOutCaps (&self->plugin_data, config);
}
GST_ERROR_OBJECT (self, "Decoder plugin not yet configured.");
return TRUE; /* This decoder cannot process options */
if (self->option[opnum] == NULL)
return TRUE; /* No option to process */
- return self->decoder->setOption (self, opnum, self->option[opnum]);
+ return self->decoder->setOption (&self->plugin_data, opnum,
+ self->option[opnum]);
}
/**
} else {
/* Changing decoder. Deallocate the previous */
if (self->cleanup_plugin_data) {
- self->cleanup_plugin_data (self);
+ self->cleanup_plugin_data (&self->plugin_data);
} else {
g_free (self->plugin_data);
}
self->decoder = decoder;
}
- g_assert (self->decoder->init (self));
+ g_assert (self->decoder->init (&self->plugin_data));
self->cleanup_plugin_data = self->decoder->exit;
silent_debug ("tensor_decoder plugin mode (%s)\n", temp_string);
temp_string);
if (NULL != self->decoder) {
if (self->cleanup_plugin_data) {
- self->cleanup_plugin_data (self);
+ self->cleanup_plugin_data (&self->plugin_data);
} else {
g_free (self->plugin_data);
}
input[i].type = self->tensor_config.info.info[i].type;
}
- res = self->decoder->decode (self, input, outbuf);
+ res = self->decoder->decode (&self->plugin_data, &self->tensor_config,
+ input, outbuf);
for (i = 0; i < num_tensors; i++)
gst_memory_unmap (in_mem[i], &in_info[i]);
if (self->mode == DECODE_MODE_PLUGIN) {
if (self->decoder->getTransformSize)
- *othersize = self->decoder->getTransformSize (self, caps, size,
- othercaps, direction);
+ *othersize = self->decoder->getTransformSize (&self->plugin_data,
+ &self->tensor_config, caps, size, othercaps, direction);
else
*othersize = 0;
/** For Tensor */
gboolean configured; /**< TRUE if already successfully configured tensor metadata */
void *plugin_data;
- void (*cleanup_plugin_data)(GstTensorDec *self); /**< exit() of subplugin is registered here. If it's null, gfree(plugin_data) is used. */
+ void (*cleanup_plugin_data)(void **pdata); /**< exit() of subplugin is registered here. If it's null, gfree(plugin_data) is used. */
GstTensorsConfig tensor_config; /**< configured tensor info @todo support tensors in the future */
const TensorDecDef *decoder; /**< Plugin object */
};
/**
- * @brief Output type.
+ * @brief Decoder Mode.
*/
typedef enum
{
- OUTPUT_VIDEO,
- OUTPUT_AUDIO,
- OUTPUT_TEXT,
- OUTPUT_UNKNOWN
-} GstDecMediaType;
+ DECODE_MODE_PLUGIN,
+ DECODE_MODE_UNKNOWN
+} GstDecMode;
/**
- * @brief Decoder Mode.
+ * @brief Tensor Decoder Output type.
*/
typedef enum
{
- DECODE_MODE_PLUGIN,
- DECODE_MODE_UNKNOWN
-} GstDecMode;
+ OUTPUT_VIDEO,
+ OUTPUT_AUDIO,
+ OUTPUT_TEXT,
+ OUTPUT_UNKNOWN
+} GstDecMediaType;
/**
* @brief Output type for each mode
*/
struct _TensorDecDef
{
- gchar *modename;
+ char *modename;
/**< Unique decoder name. GST users choose decoders with mode="modename". */
GstDecMediaType type;
/**< Output media type. VIDEO/AUDIO/TEXT are supported */
- gboolean (*init) (GstTensorDec *self);
+ int (*init) (void **private_data);
/**< Object initialization for the decoder */
- void (*exit) (GstTensorDec *self);
+ void (*exit) (void **private_data);
/**< Object destruction for the decoder */
- gboolean (*setOption) (GstTensorDec *self, int opNum, const gchar *param);
+ int (*setOption) (void **private_data, int opNum, const char *param);
/**< Process with the given options. It can be called repeatedly */
- GstCaps *(*getOutCaps) (GstTensorDec *self, const GstTensorsConfig *config);
+ GstCaps *(*getOutCaps) (void **private_data, const GstTensorsConfig *config);
/**< The caller should unref the returned GstCaps
* Current implementation supports single-tensor only.
* @todo WIP: support multi-tensor for input!!!
*/
- GstFlowReturn (*decode) (GstTensorDec *self, const GstTensorMemory *input,
- GstBuffer *outbuf);
+ GstFlowReturn (*decode) (void **private_data, const GstTensorsConfig *config,
+ const GstTensorMemory *input, GstBuffer *outbuf);
/**< outbuf must be allocated but empty (gst_buffer_get_size (outbuf) == 0).
* Note that we support single-tensor (other/tensor) only!
* @todo WIP: support multi-tensor for input!!!
*/
- gsize (*getTransformSize) (GstTensorDec *self, GstCaps *caps, gsize size, GstCaps *othercaps, GstPadDirection direction);
+ size_t (*getTransformSize) (void **private_data, const GstTensorsConfig *config,
+ GstCaps *caps, size_t size, GstCaps *othercaps,
+ GstPadDirection direction);
/**< EXPERIMENTAL! @todo We are not ready to use this. This should be NULL or return 0 */
};