#include <glib.h>
/**
- * @brief String representations for each tensor element type.
- */
-const gchar *tensor_element_typename[] = {
- [_NNS_INT32] = "int32",
- [_NNS_UINT32] = "uint32",
- [_NNS_INT16] = "int16",
- [_NNS_UINT16] = "uint16",
- [_NNS_INT8] = "int8",
- [_NNS_UINT8] = "uint8",
- [_NNS_FLOAT64] = "float64",
- [_NNS_FLOAT32] = "float32",
- [_NNS_INT64] = "int64",
- [_NNS_UINT64] = "uint64",
- [_NNS_END] = NULL,
-};
-
-/**
- * @brief Get media type from structure
- * @param structure structure to be interpreted
- * @return corresponding media type (returns _NNS_MEDIA_END for unsupported type)
- */
-media_type
-gst_tensor_media_type_from_structure (const GstStructure * structure)
-{
- const gchar *name;
-
- name = gst_structure_get_name (structure);
-
- g_return_val_if_fail (name != NULL, _NNS_MEDIA_END);
-
- if (g_str_has_prefix (name, "video/")) {
- return _NNS_VIDEO;
- }
-
- if (g_str_has_prefix (name, "audio/")) {
- return _NNS_AUDIO;
- }
-
- if (g_str_has_prefix (name, "text/")) {
- return _NNS_STRING;
- }
-
- if (g_str_equal (name, "application/octet-stream")) {
- return _NNS_OCTET;
- }
-
- /** unknown, or not-supported type */
- return _NNS_MEDIA_END;
-}
-
-/**
* @brief Get media type from caps
* @param caps caps to be interpreted
* @return corresponding media type (returns _NNS_MEDIA_END for unsupported type)
}
/**
- * @brief Initialize the tensor info structure
- * @param info tensor info structure to be initialized
- */
-void
-gst_tensor_info_init (GstTensorInfo * info)
-{
- guint i;
-
- g_return_if_fail (info != NULL);
-
- info->name = NULL;
- info->type = _NNS_END;
-
- for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
- info->dimension[i] = 0;
- }
-}
-
-/**
- * @brief Check the tensor info is valid
- * @param info tensor info structure
- * @return TRUE if info is valid
- */
-gboolean
-gst_tensor_info_validate (const GstTensorInfo * info)
-{
- g_return_val_if_fail (info != NULL, FALSE);
-
- if (info->type == _NNS_END) {
- return FALSE;
- }
-
- /* validate tensor dimension */
- return gst_tensor_dimension_is_valid (info->dimension);
-}
-
-/**
* @brief Compare tensor info
* @param TRUE if equal
*/
}
/**
- * @brief Get data size of single tensor
- * @param info tensor info structure
- * @return data size
- */
-gsize
-gst_tensor_info_get_size (const GstTensorInfo * info)
-{
- gsize data_size;
-
- g_return_val_if_fail (info != NULL, 0);
-
- data_size = get_tensor_element_count (info->dimension) *
- tensor_element_size[info->type];
-
- return data_size;
-}
-
-/**
- * @brief Initialize the tensors info structure
- * @param info tensors info structure to be initialized
- */
-void
-gst_tensors_info_init (GstTensorsInfo * info)
-{
- guint i;
-
- g_return_if_fail (info != NULL);
-
- info->num_tensors = 0;
-
- for (i = 0; i < NNS_TENSOR_SIZE_LIMIT; i++) {
- gst_tensor_info_init (&info->info[i]);
- }
-}
-
-/**
- * @brief Check the tensors info is valid
- * @param info tensors info structure
- * @return TRUE if info is valid
- */
-gboolean
-gst_tensors_info_validate (const GstTensorsInfo * info)
-{
- guint i;
-
- g_return_val_if_fail (info != NULL, FALSE);
-
- if (info->num_tensors < 1) {
- return FALSE;
- }
-
- for (i = 0; i < info->num_tensors; i++) {
- if (!gst_tensor_info_validate (&info->info[i])) {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-/**
* @brief Compare tensors info
* @param TRUE if equal
*/
}
/**
- * @brief Parse the string of dimensions
- * @param info tensors info structure
- * @param dim_string string of dimensions
- * @return number of parsed dimensions
- */
-guint
-gst_tensors_info_parse_dimensions_string (GstTensorsInfo * info,
- const gchar * dim_string)
-{
- guint num_dims = 0;
-
- g_return_val_if_fail (info != NULL, 0);
-
- if (dim_string) {
- guint i;
- gchar **str_dims;
-
- str_dims = g_strsplit (dim_string, ",", -1);
- num_dims = g_strv_length (str_dims);
-
- if (num_dims > NNS_TENSOR_SIZE_LIMIT) {
- GST_WARNING ("Invalid param, dimensions (%d) max (%d)\n",
- num_dims, NNS_TENSOR_SIZE_LIMIT);
-
- num_dims = NNS_TENSOR_SIZE_LIMIT;
- }
-
- for (i = 0; i < num_dims; i++) {
- get_tensor_dimension (str_dims[i], info->info[i].dimension);
- }
-
- g_strfreev (str_dims);
- }
-
- return num_dims;
-}
-
-/**
- * @brief Parse the string of types
- * @param info tensors info structure
- * @param type_string string of types
- * @return number of parsed types
- */
-guint
-gst_tensors_info_parse_types_string (GstTensorsInfo * info,
- const gchar * type_string)
-{
- gint num_types = 0;
-
- g_return_val_if_fail (info != NULL, 0);
-
- if (type_string) {
- guint i;
- gchar **str_types;
-
- str_types = g_strsplit (type_string, ",", -1);
- num_types = g_strv_length (str_types);
-
- if (num_types > NNS_TENSOR_SIZE_LIMIT) {
- GST_WARNING ("Invalid param, types (%d) max (%d)\n",
- num_types, NNS_TENSOR_SIZE_LIMIT);
-
- num_types = NNS_TENSOR_SIZE_LIMIT;
- }
-
- for (i = 0; i < num_types; i++) {
- info->info[i].type = get_tensor_type (str_types[i]);
- }
-
- g_strfreev (str_types);
- }
-
- return num_types;
-}
-
-/**
* @brief Parse the string of names
* @param info tensors info structure
* @param name_string string of names
}
/**
- * @brief Initialize the tensor config info structure
- * @param config tensor config structure to be initialized
- */
-void
-gst_tensor_config_init (GstTensorConfig * config)
-{
- g_return_if_fail (config != NULL);
-
- gst_tensor_info_init (&config->info);
-
- config->rate_n = -1;
- config->rate_d = -1;
-}
-
-/**
- * @brief Check the tensor is all configured
- * @param config tensor config structure
- * @return TRUE if configured
- */
-gboolean
-gst_tensor_config_validate (const GstTensorConfig * config)
-{
- g_return_val_if_fail (config != NULL, FALSE);
-
- /**
- * check framerate (numerator >= 0 and denominator > 0)
- */
- if (config->rate_n < 0 || config->rate_d <= 0) {
- return FALSE;
- }
-
- return gst_tensor_info_validate (&config->info);
-}
-
-/**
* @brief Compare tensor config info
* @param TRUE if equal
*/
}
/**
- * @brief Parse structure and set tensor config info (internal static function)
- * @param config tensor config structure to be filled
- * @param structure structure to be interpreted
- * @return TRUE if ok
- */
-static gboolean
-gst_tensor_config_from_tensor_structure (GstTensorConfig * config,
- const GstStructure * structure)
-{
- GstTensorInfo *info;
-
- g_return_val_if_fail (config != NULL, FALSE);
- gst_tensor_config_init (config);
- info = &config->info;
-
- g_return_val_if_fail (structure != NULL, FALSE);
-
- if (!gst_structure_has_name (structure, "other/tensor")) {
- GST_WARNING ("caps is not tensor %s\n", gst_structure_get_name (structure));
- return FALSE;
- }
-
- if (gst_structure_has_field (structure, "dimension")) {
- const gchar *dim_str = gst_structure_get_string (structure, "dimension");
- get_tensor_dimension (dim_str, info->dimension);
- }
-
- if (gst_structure_has_field (structure, "type")) {
- const gchar *type_str = gst_structure_get_string (structure, "type");
- info->type = get_tensor_type (type_str);
- }
-
- gst_structure_get_fraction (structure, "framerate", &config->rate_n,
- &config->rate_d);
-
- return TRUE;
-}
-
-/**
- * @brief Set the tensor config structure from video info (internal static function)
- * @param config tensor config structure to be filled
- * @param structure caps structure
- * @note Change dimention if tensor contains N frames.
- * @return TRUE if supported type
- */
-static gboolean
-gst_tensor_config_from_video_info (GstTensorConfig * config,
- const GstStructure * structure)
-{
- /**
- * Refer: https://www.tensorflow.org/api_docs/python/tf/summary/image
- * A 4-D uint8 or float32 Tensor of shape [batch_size, height, width, channels]
- * where channels is 1, 3, or 4.
- */
- const gchar *format_string;
- GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
- gint width = 0;
- gint height = 0;
-
- g_return_val_if_fail (config != NULL, FALSE);
- gst_tensor_config_init (config);
-
- g_return_val_if_fail (structure != NULL, FALSE);
-
- format_string = gst_structure_get_string (structure, "format");
- if (format_string) {
- format = gst_video_format_from_string (format_string);
- }
-
- gst_structure_get_int (structure, "width", &width);
- gst_structure_get_int (structure, "height", &height);
- gst_structure_get_fraction (structure, "framerate", &config->rate_n,
- &config->rate_d);
-
- /** [color-space][width][height][frames] */
- switch (format) {
- case GST_VIDEO_FORMAT_GRAY8:
- config->info.type = _NNS_UINT8;
- config->info.dimension[0] = 1;
- break;
- case GST_VIDEO_FORMAT_RGB:
- case GST_VIDEO_FORMAT_BGR:
- config->info.type = _NNS_UINT8;
- config->info.dimension[0] = 3;
- break;
- case GST_VIDEO_FORMAT_RGBx:
- case GST_VIDEO_FORMAT_BGRx:
- case GST_VIDEO_FORMAT_xRGB:
- case GST_VIDEO_FORMAT_xBGR:
- case GST_VIDEO_FORMAT_RGBA:
- case GST_VIDEO_FORMAT_BGRA:
- case GST_VIDEO_FORMAT_ARGB:
- case GST_VIDEO_FORMAT_ABGR:
- config->info.type = _NNS_UINT8;
- config->info.dimension[0] = 4;
- break;
- default:
- /** unsupported format */
- GST_WARNING ("Unsupported format = %s\n",
- format_string ? format_string : "Unknown");
- break;
- }
-
- config->info.dimension[1] = width;
- config->info.dimension[2] = height;
- config->info.dimension[3] = 1; /** Supposed 1 frame in tensor, change this if tensor contains N frames. */
-#if 0
- /**
- * @todo To fix coverity issue, now block these lines.
- * If NNS_TENSOR_RANK_LIMIT is larger than 4, unblock these to initialize the tensor dimension.
- */
- gint i;
- for (i = 4; i < NNS_TENSOR_RANK_LIMIT; i++) {
- config->info.dimension[i] = 1;
- }
-#endif
- return (config->info.type != _NNS_END);
-}
-
-/**
- * @brief Set the tensor config structure from audio info (internal static function)
- * @param config tensor config structure to be filled
- * @param structure caps structure
- * @note Change dimention if tensor contains N frames.
- * @return TRUE if supported type
- */
-static gboolean
-gst_tensor_config_from_audio_info (GstTensorConfig * config,
- const GstStructure * structure)
-{
- /**
- * Refer: https://www.tensorflow.org/api_docs/python/tf/summary/audio
- * A 3-D float32 Tensor of shape [batch_size, frames, channels]
- * or a 2-D float32 Tensor of shape [batch_size, frames].
- */
- const gchar *format_string;
- GstAudioFormat format = GST_AUDIO_FORMAT_UNKNOWN;
- gint channels = 0;
- gint rate = 0;
- gint i;
-
- g_return_val_if_fail (config != NULL, FALSE);
- gst_tensor_config_init (config);
-
- g_return_val_if_fail (structure != NULL, FALSE);
-
- format_string = gst_structure_get_string (structure, "format");
- if (format_string) {
- format = gst_audio_format_from_string (format_string);
- }
-
- gst_structure_get_int (structure, "channels", &channels);
- gst_structure_get_int (structure, "rate", &rate);
-
- /** [channels][frames] */
- switch (format) {
- case GST_AUDIO_FORMAT_S8:
- config->info.type = _NNS_INT8;
- break;
- case GST_AUDIO_FORMAT_U8:
- config->info.type = _NNS_UINT8;
- break;
- case GST_AUDIO_FORMAT_S16:
- config->info.type = _NNS_INT16;
- break;
- case GST_AUDIO_FORMAT_U16:
- config->info.type = _NNS_UINT16;
- break;
- case GST_AUDIO_FORMAT_S32:
- config->info.type = _NNS_INT32;
- break;
- case GST_AUDIO_FORMAT_U32:
- config->info.type = _NNS_UINT32;
- break;
- case GST_AUDIO_FORMAT_F32:
- config->info.type = _NNS_FLOAT32;
- break;
- case GST_AUDIO_FORMAT_F64:
- config->info.type = _NNS_FLOAT64;
- break;
- default:
- /** unsupported format */
- GST_WARNING ("Unsupported format = %s\n",
- format_string ? format_string : "Unknown");
- break;
- }
-
- config->info.dimension[0] = channels;
- config->info.dimension[1] = 1; /** Supposed 1 frame in tensor, change this if tensor contains N frames */
-
- for (i = 2; i < NNS_TENSOR_RANK_LIMIT; i++) {
- config->info.dimension[i] = 1;
- }
-
- if (rate > 0) {
- config->rate_n = rate;
- config->rate_d = 1;
- }
-
- return (config->info.type != _NNS_END);
-}
-
-/**
- * @brief Set the tensor config structure from text info (internal static function)
- * @param config tensor config structure to be filled
- * @param structure caps structure
- * @note Change dimention if tensor contains N frames.
- * @return TRUE if supported type
- */
-static gboolean
-gst_tensor_config_from_text_info (GstTensorConfig * config,
- const GstStructure * structure)
-{
- /**
- * Refer: https://www.tensorflow.org/api_docs/python/tf/summary/text
- * A string-type Tensor
- */
- const gchar *format_string;
- gint i;
-
- g_return_val_if_fail (config != NULL, FALSE);
- gst_tensor_config_init (config);
-
- g_return_val_if_fail (structure != NULL, FALSE);
-
- format_string = gst_structure_get_string (structure, "format");
- if (format_string) {
- if (g_str_equal (format_string, "utf8")) {
- config->info.type = _NNS_UINT8;
- } else {
- /** unsupported format */
- GST_WARNING ("Unsupported format = %s\n", format_string);
- }
- }
-
- /** [size][frames] */
- config->info.dimension[0] = GST_TENSOR_STRING_SIZE; /** fixed size of string */
- config->info.dimension[1] = 1; /** Supposed 1 frame in tensor, change this if tensor contains N frames */
-
- for (i = 2; i < NNS_TENSOR_RANK_LIMIT; i++) {
- config->info.dimension[i] = 1;
- }
-
- if (gst_structure_has_field (structure, "framerate")) {
- gst_structure_get_fraction (structure, "framerate", &config->rate_n,
- &config->rate_d);
- } else {
- /** cannot get the framerate for text type */
- config->rate_n = 0;
- config->rate_d = 1;
- }
-
- return (config->info.type != _NNS_END);
-}
-
-/**
- * @brief Set the tensor config structure from octet stream (internal static function)
- * @param config tensor config structure to be filled
- * @param structure caps structure
- * @note Change tensor dimention and type.
- * @return TRUE if supported type
- */
-static gboolean
-gst_tensor_config_from_octet_stream_info (GstTensorConfig * config,
- const GstStructure * structure)
-{
- g_return_val_if_fail (config != NULL, FALSE);
- gst_tensor_config_init (config);
-
- g_return_val_if_fail (structure != NULL, FALSE);
-
- /**
- * Raw byte-stream (application/octet-stream)
- * We cannot get the exact tensor info from caps.
- * All tensor info should be updated.
- */
- config->info.type = _NNS_UINT8;
-
- if (gst_structure_has_field (structure, "framerate")) {
- gst_structure_get_fraction (structure, "framerate", &config->rate_n,
- &config->rate_d);
- } else {
- /** cannot get the framerate */
- config->rate_n = 0;
- config->rate_d = 1;
- }
-
- return (config->info.type != _NNS_END);
-}
-
-/**
- * @brief Parse structure and set tensor config info
- * @param config tensor config structure to be filled
- * @param structure structure to be interpreted
- * @note Change dimention if tensor contains N frames.
- * @return TRUE if no error
- */
-gboolean
-gst_tensor_config_from_structure (GstTensorConfig * config,
- const GstStructure * structure)
-{
- media_type m_type;
-
- g_return_val_if_fail (config != NULL, FALSE);
- gst_tensor_config_init (config);
-
- g_return_val_if_fail (structure != NULL, FALSE);
-
- /** update config from tensor stream */
- if (gst_structure_has_name (structure, "other/tensor")) {
- return gst_tensor_config_from_tensor_structure (config, structure);
- }
-
- /** update config from media stream */
- m_type = gst_tensor_media_type_from_structure (structure);
-
- switch (m_type) {
- case _NNS_VIDEO:
- gst_tensor_config_from_video_info (config, structure);
- break;
- case _NNS_AUDIO:
- gst_tensor_config_from_audio_info (config, structure);
- break;
- case _NNS_STRING:
- gst_tensor_config_from_text_info (config, structure);
- break;
- case _NNS_OCTET:
- gst_tensor_config_from_octet_stream_info (config, structure);
- break;
- default:
- GST_WARNING ("Unsupported type %d\n", m_type);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
* @brief Get tensor caps from tensor config
* @param config tensor config info
* @return caps for given config
}
/**
- * @brief Initialize the tensors config info structure (for other/tensors)
- * @param config tensors config structure to be initialized
- */
-void
-gst_tensors_config_init (GstTensorsConfig * config)
-{
- g_return_if_fail (config != NULL);
-
- gst_tensors_info_init (&config->info);
-
- config->rate_n = -1;
- config->rate_d = -1;
-}
-
-/**
- * @brief Check the tensors are all configured
- * @param config tensor config structure
- * @return TRUE if configured
- */
-gboolean
-gst_tensors_config_validate (const GstTensorsConfig * config)
-{
- g_return_val_if_fail (config != NULL, FALSE);
-
- /**
- * check framerate (numerator >= 0 and denominator > 0)
- */
- if (config->rate_n < 0 || config->rate_d <= 0) {
- return FALSE;
- }
-
- return gst_tensors_info_validate (&config->info);
-}
-
-/**
* @brief Compare tensor config info
* @param TRUE if equal
*/
}
/**
- * @brief Parse structure and set tensors config (for other/tensors)
- * @param config tensors config structure to be filled
- * @param structure structure to be interpreted
- * @return TRUE if no error
- */
-gboolean
-gst_tensors_config_from_structure (GstTensorsConfig * config,
- const GstStructure * structure)
-{
- const gchar *name;
-
- g_return_val_if_fail (config != NULL, FALSE);
- gst_tensors_config_init (config);
-
- g_return_val_if_fail (structure != NULL, FALSE);
-
- name = gst_structure_get_name (structure);
-
- if (g_str_equal (name, "other/tensor")) {
- GstTensorConfig c;
-
- gst_tensor_config_from_tensor_structure (&c, structure);
-
- config->info.num_tensors = 1;
- config->info.info[0] = c.info;
- config->rate_d = c.rate_d;
- config->rate_n = c.rate_n;
- } else if (g_str_equal (name, "other/tensors")) {
- gst_structure_get_int (structure, "num_tensors",
- (gint *) (&config->info.num_tensors));
- gst_structure_get_fraction (structure, "framerate", &config->rate_n,
- &config->rate_d);
-
- if (config->info.num_tensors > NNS_TENSOR_SIZE_LIMIT) {
- GST_WARNING ("Invalid param, max size is %d", NNS_TENSOR_SIZE_LIMIT);
- config->info.num_tensors = NNS_TENSOR_SIZE_LIMIT;
- }
-
- /* parse dimensions */
- if (gst_structure_has_field (structure, "dimensions")) {
- const gchar *dims_str;
- guint num_dims;
-
- dims_str = gst_structure_get_string (structure, "dimensions");
- num_dims =
- gst_tensors_info_parse_dimensions_string (&config->info, dims_str);
-
- if (config->info.num_tensors != num_dims) {
- GST_WARNING ("Invalid param, dimensions (%d) tensors (%d)\n",
- num_dims, config->info.num_tensors);
- }
- }
-
- /* parse types */
- if (gst_structure_has_field (structure, "types")) {
- const gchar *types_str;
- guint num_types;
-
- types_str = gst_structure_get_string (structure, "types");
- num_types =
- gst_tensors_info_parse_types_string (&config->info, types_str);
-
- if (config->info.num_tensors != num_types) {
- GST_WARNING ("Invalid param, types (%d) tensors (%d)\n",
- num_types, config->info.num_tensors);
- }
- }
- } else {
- GST_WARNING ("Unsupported type = %s\n", name ? name : "Unknown");
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
* @brief Get caps from tensors config (for other/tensors)
* @param config tensors config info
* @return caps for given config
}
/**
- * @brief Get tensor_type from string tensor_type input
- * @return Corresponding tensor_type. _NNS_END if unrecognized value is there.
- * @param typestr The string type name, supposed to be one of tensor_element_typename[]
- */
-tensor_type
-get_tensor_type (const gchar * typestr)
-{
- int len;
- gchar *type_string;
- tensor_type type = _NNS_END;
-
- if (typestr == NULL)
- return _NNS_END;
-
- /** remove spaces */
- type_string = g_strdup (typestr);
- g_strstrip (type_string);
-
- len = strlen (type_string);
-
- if (type_string[0] == 'u' || type_string[0] == 'U') {
- /**
- * Let's believe the developer and the following three letters are "int"
- * (case insensitive)
- */
- if (len == 6) { /* uint16, uint32 */
- if (type_string[4] == '1' && type_string[5] == '6')
- type = _NNS_UINT16;
- else if (type_string[4] == '3' && type_string[5] == '2')
- type = _NNS_UINT32;
- else if (type_string[4] == '6' && type_string[5] == '4')
- type = _NNS_UINT64;
- } else if (len == 5) { /* uint8 */
- if (type_string[4] == '8')
- type = _NNS_UINT8;
- }
- } else if (type_string[0] == 'i' || type_string[0] == 'I') {
- /**
- * Let's believe the developer and the following two letters are "nt"
- * (case insensitive)
- */
- if (len == 5) { /* int16, int32 */
- if (type_string[3] == '1' && type_string[4] == '6')
- type = _NNS_INT16;
- else if (type_string[3] == '3' && type_string[4] == '2')
- type = _NNS_INT32;
- else if (type_string[3] == '6' && type_string[4] == '4')
- type = _NNS_INT64;
- } else if (len == 4) { /* int8 */
- if (type_string[3] == '8')
- type = _NNS_INT8;
- }
- } else if (type_string[0] == 'f' || type_string[0] == 'F') {
- /* Let's assume that the following 4 letters are "loat" */
- if (len == 7) {
- if (type_string[5] == '6' && type_string[6] == '4')
- type = _NNS_FLOAT64;
- else if (type_string[5] == '3' && type_string[6] == '2')
- type = _NNS_FLOAT32;
- }
- }
-
- g_free (type_string);
- return type;
-}
-
-/**
* @brief Find the index value of the given key string array
* @return Corresponding index. Returns -1 if not found.
* @param strv Null terminated array of gchar *
}
/**
- * @brief Check the tensor dimension is valid
- * @param dim tensor dimension
- * @return TRUE if dimension is valid
- */
-gboolean
-gst_tensor_dimension_is_valid (const tensor_dim dim)
-{
- guint i;
-
- for (i = 0; i < NNS_TENSOR_RANK_LIMIT; ++i) {
- if (dim[i] == 0) {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-/**
- * @brief Parse tensor dimension parameter string
- * @return The Rank. 0 if error.
- * @param dimstr The dimension string in the format of d1:d2:d3:d4, d1:d2:d3, d1:d2, or d1, where dN is a positive integer and d1 is the innermost dimension; i.e., dim[d4][d3][d2][d1];
- * @param dim dimension to be filled.
- */
-int
-get_tensor_dimension (const gchar * dimstr, tensor_dim dim)
-{
- int rank = 0;
- guint64 val;
- gchar **strv;
- gchar *dim_string;
- gint i, num_dims;
-
- if (dimstr == NULL)
- return 0;
-
- /** remove spaces */
- dim_string = g_strdup (dimstr);
- g_strstrip (dim_string);
-
- strv = g_strsplit (dim_string, ":", NNS_TENSOR_RANK_LIMIT);
- num_dims = g_strv_length (strv);
-
- for (i = 0; i < num_dims; i++) {
- g_strstrip (strv[i]);
- if (strv[i] == NULL || strlen (strv[i]) == 0)
- break;
-
- val = g_ascii_strtoull (strv[i], NULL, 10);
- dim[i] = (uint32_t) val;
- rank = i + 1;
- }
-
- for (; i < NNS_TENSOR_RANK_LIMIT; i++)
- dim[i] = 1;
-
- g_strfreev (strv);
- g_free (dim_string);
- return rank;
-}
-
-/**
- * @brief Get dimension string from given tensor dimension.
- * @param dim tensor dimension
- * @return Formatted string of given dimension (d1:d2:d3:d4).
- * @note The returned value should be freed with g_free()
- */
-gchar *
-get_tensor_dimension_string (const tensor_dim dim)
-{
- gint i;
- GString *dim_str;
-
- dim_str = g_string_new (NULL);
-
- for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
- g_string_append_printf (dim_str, "%d", dim[i]);
-
- if (i < NNS_TENSOR_RANK_LIMIT - 1) {
- g_string_append (dim_str, ":");
- }
- }
-
- return g_string_free (dim_str, FALSE);
-}
-
-/**
- * @brief Count the number of elemnts of a tensor
- * @return The number of elements. 0 if error.
- * @param dim The tensor dimension
- */
-size_t
-get_tensor_element_count (const tensor_dim dim)
-{
- size_t count = 1;
- int i;
-
- for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
- count *= dim[i];
- }
-
- return count;
-}
-
-/**
* @brief A callback for typefind, trying to find whether a file is other/tensors or not.
* For the concrete definition of headers, please look at the wiki page of nnstreamer:
* https://github.com/nnsuite/nnstreamer/wiki/Design-External-Save-Format-for-other-tensor-and-other-tensors-Stream-for-TypeFind
#include <gst/base/gstcollectpads.h>
#include <gst/gstplugin.h>
+#include "nnstreamer_plugin_api.h"
+
#ifdef HAVE_ORC
#include <orc/orc.h>
G_BEGIN_DECLS
-/**
- * @brief Fixed size of string type
- */
-#ifndef GST_TENSOR_STRING_SIZE
-#define GST_TENSOR_STRING_SIZE (1024)
-#endif
-
#define GST_TENSOR_VIDEO_CAPS_STR \
GST_VIDEO_CAPS_MAKE ("{ RGB, BGR, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, GRAY8 }") \
", views = (int) 1, interlace-mode = (string) progressive"
GST_TENSOR_TEXT_CAPS_STR "; " \
GST_TENSOR_OCTET_CAPS_STR
-#define GST_TENSOR_RATE_RANGE "(fraction) [ 0, max ]"
#define GST_TENSOR_TYPE_ALL "{ float32, float64, int64, uint64, int32, uint32, int16, uint16, int8, uint8 }"
-#define GST_TENSOR_CAP_DEFAULT \
- "other/tensor, " \
- "framerate = " GST_TENSOR_RATE_RANGE
- /**
- * type should be one of types in GST_TENSOR_TYPE_ALL
- * "type = (string) uint8"
- * dimension shoule be a formatted string with rank NNS_TENSOR_RANK_LIMIT
- * "dimension = (string) dim1:dim2:dim3:dim4"
- */
-
-/**
- * @brief This value, 16, can be checked with gst_buffer_get_max_memory(),
- * which is GST_BUFFER_MEM_MAX in gstreamer/gstbuffer.c.
- * We redefined the value because GST_BUFFER_MEM_MAX is not exported and
- * we need static value. To modify (increase) this value, you need to update
- * gstreamer/gstbuffer.c as well.
- */
-#define GST_TENSOR_NUM_TENSORS_RANGE "(int) [ 1, " NNS_TENSOR_SIZE_LIMIT_STR " ]"
-
-/**
- * @brief Default static capibility for other/tensors
- *
- * This type uses GstMetaTensor to describe tensor. So there is no need to ask information
- * to identify each tensor.
- *
- */
-#define GST_TENSORS_CAP_DEFAULT \
- "other/tensors, " \
- "num_tensors = " GST_TENSOR_NUM_TENSORS_RANGE ", "\
- "framerate = " GST_TENSOR_RATE_RANGE
- /**
- * 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
- * "dimensions = (string) dim1:dim2:dim3:dim4, dim1:dim2:dim3:dim4"
- */
-
-/**
- * @brief Possible input stream types for other/tensor.
- *
- * This is realted with media input stream to other/tensor.
- * There is no restrictions for the outputs.
- */
-typedef enum _nns_media_type
-{
- _NNS_VIDEO = 0, /**< supposedly video/x-raw */
- _NNS_AUDIO, /**< supposedly audio/x-raw */
- _NNS_STRING, /**< supposedly text/x-raw */
- _NNS_OCTET, /**< supposedly application/octet-stream */
-
- _NNS_MEDIA_END, /**< End Marker */
-} media_type;
-
-/**
- * @brief Internal data structure for configured tensor info (for other/tensor).
- */
-typedef struct
-{
- GstTensorInfo info; /**< tensor info*/
- gint rate_n; /**< framerate is in fraction, which is numerator/denominator */
- gint rate_d; /**< framerate is in fraction, which is numerator/denominator */
-} GstTensorConfig;
-
-/**
- * @brief Internal data structure for configured tensors info (for other/tensors).
- */
-typedef struct
-{
- GstTensorsInfo info; /**< tensor info*/
- gint rate_n; /**< framerate is in fraction, which is numerator/denominator */
- gint rate_d; /**< framerate is in fraction, which is numerator/denominator */
-} GstTensorsConfig;
-
/**
* @brief time synchronization options
*/
} GstTensorCollectPadData;
/**
- * @brief String representations for each tensor element type.
- */
-extern const gchar *tensor_element_typename[];
-
-/**
* @brief Get media type from caps
* @param caps caps to be interpreted
* @return corresponding media type (returns _NNS_MEDIA_END for unsupported type)
gst_tensor_media_type_from_caps (const GstCaps * caps);
/**
- * @brief Get media type from structure
- * @param structure structure to be interpreted
- * @return corresponding media type (returns _NNS_MEDIA_END for unsupported type)
- */
-extern media_type
-gst_tensor_media_type_from_structure (const GstStructure * structure);
-
-/**
- * @brief Initialize the tensor info structure
- * @param info tensor info structure to be initialized
- */
-extern void
-gst_tensor_info_init (GstTensorInfo * info);
-
-/**
- * @brief Check the tensor info is valid
- * @param info tensor info structure
- * @return TRUE if info is valid
- */
-extern gboolean
-gst_tensor_info_validate (const GstTensorInfo * info);
-
-/**
* @brief Compare tensor info
* @param TRUE if equal
*/
gst_tensor_info_copy (GstTensorInfo * dest, const GstTensorInfo * src);
/**
- * @brief Get data size of single tensor
- * @param info tensor info structure
- * @return data size
- */
-extern gsize
-gst_tensor_info_get_size (const GstTensorInfo * info);
-
-/**
- * @brief Initialize the tensors info structure
- * @param info tensors info structure to be initialized
- */
-extern void
-gst_tensors_info_init (GstTensorsInfo * info);
-
-/**
- * @brief Check the tensors info is valid
- * @param info tensors info structure
- * @return TRUE if info is valid
- */
-extern gboolean
-gst_tensors_info_validate (const GstTensorsInfo * info);
-
-/**
* @brief Compare tensors info
* @param TRUE if equal
*/
gst_tensors_info_copy (GstTensorsInfo * dest, const GstTensorsInfo * src);
/**
- * @brief Parse the string of dimensions
- * @param info tensors info structure
- * @param dim_string string of dimensions
- * @return number of parsed dimensions
- */
-extern guint
-gst_tensors_info_parse_dimensions_string (GstTensorsInfo * info, const gchar * dim_string);
-
-/**
- * @brief Parse the string of types
- * @param info tensors info structure
- * @param type_string string of types
- * @return number of parsed types
- */
-extern guint
-gst_tensors_info_parse_types_string (GstTensorsInfo * info, const gchar * type_string);
-
-/**
* @brief Parse the string of names
* @param info tensors info structure
* @param name_string string of names
gst_tensors_info_get_names_string (const GstTensorsInfo * info);
/**
- * @brief Initialize the tensor config info structure
- * @param config tensor config structure to be initialized
- */
-extern void
-gst_tensor_config_init (GstTensorConfig * config);
-
-/**
- * @brief Check the tensor is all configured
- * @param config tensor config structure
- * @return TRUE if configured
- */
-extern gboolean
-gst_tensor_config_validate (const GstTensorConfig * config);
-
-/**
* @brief Compare tensor config info
* @param TRUE if equal
*/
const GstTensorConfig * c2);
/**
- * @brief Parse structure and set tensor config info (for other/tensor)
- * @param config tensor config structure to be filled
- * @param structure structure to be interpreted
- * @note Change dimention if tensor contains N frames.
- * @return TRUE if no error
- */
-extern gboolean
-gst_tensor_config_from_structure (GstTensorConfig * config,
- const GstStructure * structure);
-
-/**
* @brief Get tensor caps from tensor config (for other/tensor)
* @param config tensor config info
* @return caps for given config
gst_tensor_caps_from_config (const GstTensorConfig * config);
/**
- * @brief Initialize the tensors config info structure (for other/tensors)
- * @param config tensors config structure to be initialized
- */
-extern void
-gst_tensors_config_init (GstTensorsConfig * config);
-
-/**
- * @brief Check the tensors are all configured (for other/tensors)
- * @param config tensor config structure
- * @return TRUE if configured
- */
-extern gboolean
-gst_tensors_config_validate (const GstTensorsConfig * config);
-
-/**
* @brief Compare tensor config info (for other/tensors)
* @param TRUE if equal
*/
const GstTensorsConfig * c2);
/**
- * @brief Parse structure and set tensors config (for other/tensors)
- * @param config tensors config structure to be filled
- * @param structure structure to be interpreted
- * @return TRUE if no error
- */
-extern gboolean
-gst_tensors_config_from_structure (GstTensorsConfig * config,
- const GstStructure * structure);
-
-/**
* @brief Get caps from tensors config (for other/tensors)
* @param config tensors config info
* @return caps for given config
gst_tensors_caps_from_config (const GstTensorsConfig * config);
/**
- * @brief Get tensor_type from string tensor_type input
- * @return Corresponding tensor_type. _NNS_END if unrecognized value is there.
- * @param typestr The string type name, supposed to be one of tensor_element_typename[]
- */
-extern tensor_type get_tensor_type (const gchar * typestr);
-
-/**
* @brief Find the index value of the given key string array
* @return Corresponding index
* @param strv Null terminated array of gchar *
extern int find_key_strv (const gchar ** strv, const gchar * key);
/**
- * @brief Check the tensor dimension is valid
- * @param dim tensor dimension
- * @return TRUE if dimension is valid
- */
-extern gboolean
-gst_tensor_dimension_is_valid (const tensor_dim dim);
-
-/**
- * @brief Parse tensor dimension parameter string
- * @return The Rank. 0 if error.
- * @param dimstr The dimension string in the format of d1:d2:d3:d4, d1:d2:d3, d1:d2, or d1, where dN is a positive integer and d1 is the innermost dimension; i.e., dim[d4][d3][d2][d1];
- * @param dim dimension to be filled.
- */
-extern int get_tensor_dimension (const gchar * dimstr, tensor_dim dim);
-
-/**
- * @brief Get dimension string from given tensor dimension.
- * @param dim tensor dimension
- * @return Formatted string of given dimension (d1:d2:d3:d4).
- * @note The returned value should be freed with g_free()
- */
-extern gchar *get_tensor_dimension_string (const tensor_dim dim);
-
-/**
- * @brief Count the number of elemnts of a tensor
- * @return The number of elements. 0 if error.
- * @param dim The tensor dimension
- */
-extern size_t get_tensor_element_count (const tensor_dim dim);
-
-/**
* @brief A callback for typefind, trying to find whether a file is other/tensors or not.
* For the concrete definition of headers, please look at the wiki page of nnstreamer:
* https://github.com/nnsuite/nnstreamer/wiki/Design-External-Save-Format-for-other-tensor-and-other-tensors-Stream-for-TypeFind