[Filter/Common] common functions for tensor info
authorJaeyun <jy1210.jung@samsung.com>
Mon, 14 Jan 2019 07:58:43 +0000 (16:58 +0900)
committerjaeyun-jung <39614140+jaeyun-jung@users.noreply.github.com>
Tue, 15 Jan 2019 10:52:14 +0000 (19:52 +0900)
Add common functions to handle the fomatted string of dimension, type, and name in tensors info.

Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
gst/nnstreamer/tensor_common.c
gst/nnstreamer/tensor_common.h
gst/nnstreamer/tensor_filter/tensor_filter.c
tests/common/unittest_common.cpp

index 37199e0..801221e 100644 (file)
@@ -251,6 +251,222 @@ gst_tensors_info_is_equal (const GstTensorsInfo * i1, const GstTensorsInfo * i2)
 }
 
 /**
+ * @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
+ * @return number of parsed names
+ */
+guint
+gst_tensors_info_parse_names_string (GstTensorsInfo * info,
+    const gchar * name_string)
+{
+  gint num_names = 0;
+
+  g_return_val_if_fail (info != NULL, 0);
+
+  if (name_string) {
+    guint i;
+    gchar *str_name;
+    gchar **str_names;
+
+    str_names = g_strsplit (name_string, ",", -1);
+    num_names = g_strv_length (str_names);
+
+    if (num_names > NNS_TENSOR_SIZE_LIMIT) {
+      GST_WARNING ("Invalid param, names (%d) max (%d)\n",
+          num_names, NNS_TENSOR_SIZE_LIMIT);
+
+      num_names = NNS_TENSOR_SIZE_LIMIT;
+    }
+
+    for (i = 0; i < num_names; i++) {
+      str_name = g_strdup (str_names[i]);
+      g_strstrip (str_name);
+
+      g_free (info->info[i].name);
+      info->info[i].name = str_name;
+    }
+
+    g_strfreev (str_names);
+  }
+
+  return num_names;
+}
+
+/**
+ * @brief Get the string of dimensions in tensors info
+ * @param info tensors info structure
+ * @return string of dimensions in tensors info (NULL if the number of tensors is 0)
+ * @note The returned value should be freed with g_free()
+ */
+gchar *
+gst_tensors_info_get_dimensions_string (const GstTensorsInfo * info)
+{
+  gchar *dim_str = NULL;
+
+  g_return_val_if_fail (info != NULL, NULL);
+
+  if (info->num_tensors > 0) {
+    guint i;
+    GString *dimensions = g_string_new (NULL);
+
+    for (i = 0; i < info->num_tensors; i++) {
+      dim_str = get_tensor_dimension_string (info->info[i].dimension);
+
+      g_string_append (dimensions, dim_str);
+
+      if (i < info->num_tensors - 1) {
+        g_string_append (dimensions, ",");
+      }
+
+      g_free (dim_str);
+    }
+
+    dim_str = g_string_free (dimensions, FALSE);
+  }
+
+  return dim_str;
+}
+
+/**
+ * @brief Get the string of types in tensors info
+ * @param info tensors info structure
+ * @return string of types in tensors info (NULL if the number of tensors is 0)
+ * @note The returned value should be freed with g_free()
+ */
+gchar *
+gst_tensors_info_get_types_string (const GstTensorsInfo * info)
+{
+  gchar *type_str = NULL;
+
+  g_return_val_if_fail (info != NULL, NULL);
+
+  if (info->num_tensors > 0) {
+    guint i;
+    GString *types = g_string_new (NULL);
+
+    for (i = 0; i < info->num_tensors; i++) {
+      g_string_append (types, tensor_element_typename[info->info[i].type]);
+
+      if (i < info->num_tensors - 1) {
+        g_string_append (types, ",");
+      }
+    }
+
+    type_str = g_string_free (types, FALSE);
+  }
+
+  return type_str;
+}
+
+/**
+ * @brief Get the string of tensor names in tensors info
+ * @param info tensors info structure
+ * @return string of names in tensors info (NULL if the number of tensors is 0)
+ * @note The returned value should be freed with g_free()
+ */
+gchar *
+gst_tensors_info_get_names_string (const GstTensorsInfo * info)
+{
+  gchar *name_str = NULL;
+
+  g_return_val_if_fail (info != NULL, NULL);
+
+  if (info->num_tensors > 0) {
+    guint i;
+    GString *names = g_string_new (NULL);
+
+    for (i = 0; i < info->num_tensors; i++) {
+      g_string_append (names, info->info[i].name);
+
+      if (i < info->num_tensors - 1) {
+        g_string_append (names, ",");
+      }
+    }
+
+    name_str = g_string_free (names, FALSE);
+  }
+
+  return name_str;
+}
+
+/**
  * @brief Initialize the tensor config info structure
  * @param config tensor config structure to be initialized
  */
@@ -752,7 +968,6 @@ gst_tensors_config_from_structure (GstTensorsConfig * config,
     const GstStructure * structure)
 {
   const gchar *name;
-  guint i;
 
   g_return_val_if_fail (config != NULL, FALSE);
   gst_tensors_config_init (config);
@@ -787,51 +1002,29 @@ gst_tensors_config_from_structure (GstTensorsConfig * config,
     /* parse dimensions */
     dims_string = gst_structure_get_string (structure, "dimensions");
     if (dims_string) {
-      gchar **str_dims;
-      gint num_dims;
+      guint num_dims;
 
-      str_dims = g_strsplit (dims_string, ",", -1);
-      num_dims = g_strv_length (str_dims);
+      num_dims =
+          gst_tensors_info_parse_dimensions_string (&config->info, dims_string);
 
       if (config->info.num_tensors != num_dims) {
         GST_WARNING ("Invalid param, dimensions (%d) tensors (%d)\n",
             num_dims, config->info.num_tensors);
-
-        if (num_dims > config->info.num_tensors) {
-          num_dims = config->info.num_tensors;
-        }
       }
-
-      for (i = 0; i < num_dims; i++) {
-        get_tensor_dimension (str_dims[i], config->info.info[i].dimension);
-      }
-
-      g_strfreev (str_dims);
     }
 
-    /** parse types */
+    /* parse types */
     types_string = gst_structure_get_string (structure, "types");
     if (types_string) {
-      gchar **str_types;
-      gint num_types;
+      guint num_types;
 
-      str_types = g_strsplit (types_string, ",", -1);
-      num_types = g_strv_length (str_types);
+      num_types =
+          gst_tensors_info_parse_types_string (&config->info, types_string);
 
       if (config->info.num_tensors != num_types) {
         GST_WARNING ("Invalid param, types (%d) tensors (%d)\n",
             num_types, config->info.num_tensors);
-
-        if (num_types > config->info.num_tensors) {
-          num_types = config->info.num_tensors;
-        }
-      }
-
-      for (i = 0; i < num_types; i++) {
-        config->info.info[i].type = get_tensor_type (str_types[i]);
       }
-
-      g_strfreev (str_types);
     }
   } else {
     GST_WARNING ("Unsupported type = %s\n", name ? name : "Unknown");
@@ -850,41 +1043,24 @@ GstCaps *
 gst_tensors_caps_from_config (const GstTensorsConfig * config)
 {
   GstCaps *caps;
-  guint i;
 
   g_return_val_if_fail (config != NULL, NULL);
 
   caps = gst_caps_from_string (GST_TENSORS_CAP_DEFAULT);
 
   if (config->info.num_tensors > 0) {
-    GString *dimensions = g_string_new (NULL);
-    GString *types = g_string_new (NULL);
-    gchar *dim_str;
+    gchar *dim_str, *type_str;
 
-    /** dimensions and types */
-    for (i = 0; i < config->info.num_tensors; i++) {
-      dim_str = get_tensor_dimension_string (config->info.info[i].dimension);
-
-      g_string_append (dimensions, dim_str);
-      g_string_append (types,
-          tensor_element_typename[config->info.info[i].type]);
-
-      if (i < config->info.num_tensors - 1) {
-        g_string_append (dimensions, ",");
-        g_string_append (types, ",");
-      }
-
-      g_free (dim_str);
-    }
+    dim_str = gst_tensors_info_get_dimensions_string (&config->info);
+    type_str = gst_tensors_info_get_types_string (&config->info);
 
     gst_caps_set_simple (caps, "num_tensors", G_TYPE_INT,
         config->info.num_tensors, NULL);
-    gst_caps_set_simple (caps, "dimensions", G_TYPE_STRING, dimensions->str,
-        NULL);
-    gst_caps_set_simple (caps, "types", G_TYPE_STRING, types->str, NULL);
+    gst_caps_set_simple (caps, "dimensions", G_TYPE_STRING, dim_str, NULL);
+    gst_caps_set_simple (caps, "types", G_TYPE_STRING, type_str, NULL);
 
-    g_string_free (dimensions, TRUE);
-    g_string_free (types, TRUE);
+    g_free (dim_str);
+    g_free (type_str);
   }
 
   if (config->rate_n >= 0 && config->rate_d > 0) {
index 9ab6e44..9bc7be1 100644 (file)
@@ -281,6 +281,60 @@ extern gboolean
 gst_tensors_info_is_equal (const GstTensorsInfo * i1, const GstTensorsInfo * i2);
 
 /**
+ * @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
+ * @return number of parsed names
+ */
+extern guint
+gst_tensors_info_parse_names_string (GstTensorsInfo * info, const gchar * name_string);
+
+/**
+ * @brief Get the string of dimensions in tensors info
+ * @param info tensors info structure
+ * @return string of dimensions in tensors info (NULL if the number of tensors is 0)
+ * @note The returned value should be freed with g_free()
+ */
+extern gchar *
+gst_tensors_info_get_dimensions_string (const GstTensorsInfo * info);
+
+/**
+ * @brief Get the string of types in tensors info
+ * @param info tensors info structure
+ * @return string of types in tensors info (NULL if the number of tensors is 0)
+ * @note The returned value should be freed with g_free()
+ */
+extern gchar *
+gst_tensors_info_get_types_string (const GstTensorsInfo * info);
+
+/**
+ * @brief Get the string of tensor names in tensors info
+ * @param info tensors info structure
+ * @return string of names in tensors info (NULL if the number of tensors is 0)
+ * @note The returned value should be freed with g_free()
+ */
+extern gchar *
+gst_tensors_info_get_names_string (const GstTensorsInfo * info);
+
+/**
  * @brief Initialize the tensor config info structure
  * @param config tensor config structure to be initialized
  */
index e3bc53a..2e5941d 100644 (file)
@@ -552,6 +552,7 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id,
       if (prop->model_file) {
         gst_tensor_filter_close_fw (self);
         g_free ((char *) prop->model_file);     /* g_free cannot handle const * */
+        prop->model_file = NULL;
       }
 
       /* Once configures, it cannot be changed in runtime */
@@ -571,80 +572,72 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id,
       g_assert (!prop->input_configured && value);
       /* Once configures, it cannot be changed in runtime */
       {
-        int i, rank;
-        gchar **str_dims;
+        guint num_dims;
 
-        str_dims = g_strsplit (g_value_get_string (value), ",", -1);
-        prop->input_meta.num_tensors = g_strv_length (str_dims);
+        num_dims = gst_tensors_info_parse_dimensions_string (&prop->input_meta,
+            g_value_get_string (value));
 
-        for (i = 0; i < prop->input_meta.num_tensors; i++) {
-          rank =
-              get_tensor_dimension (str_dims[i],
-              prop->input_meta.info[i].dimension);
-          g_assert (rank > 0);
-
-          silent_debug_info (&prop->input_meta, "input prop");
+        if (prop->input_meta.num_tensors > 0 &&
+            prop->input_meta.num_tensors != num_dims) {
+          GST_WARNING_OBJECT (self,
+              "Invalid input-dim, given param does not match with old value.");
         }
 
-        g_strfreev (str_dims);
+        prop->input_meta.num_tensors = num_dims;
       }
       break;
     case PROP_OUTPUT:
       g_assert (!prop->output_configured && value);
       /* Once configures, it cannot be changed in runtime */
       {
-        int i, rank;
-        gchar **str_dims;
-
-        str_dims = g_strsplit (g_value_get_string (value), ",", -1);
-        prop->output_meta.num_tensors = g_strv_length (str_dims);
+        guint num_dims;
 
-        for (i = 0; i < prop->output_meta.num_tensors; i++) {
-          rank =
-              get_tensor_dimension (str_dims[i],
-              prop->output_meta.info[i].dimension);
-          g_assert (rank > 0);
+        num_dims = gst_tensors_info_parse_dimensions_string (&prop->output_meta,
+            g_value_get_string (value));
 
-          silent_debug_info (&prop->output_meta, "output prop");
+        if (prop->output_meta.num_tensors > 0 &&
+            prop->output_meta.num_tensors != num_dims) {
+          GST_WARNING_OBJECT (self,
+              "Invalid output-dim, given param does not match with old value.");
         }
 
-        g_strfreev (str_dims);
+        prop->output_meta.num_tensors = num_dims;
       }
       break;
     case PROP_INPUTTYPE:
       g_assert (!prop->input_configured && value);
       /* Once configures, it cannot be changed in runtime */
       {
-        int i;
-        gchar **str_types;
+        guint num_types;
 
-        str_types = g_strsplit (g_value_get_string (value), ",", -1);
-        prop->input_meta.num_tensors = g_strv_length (str_types);
+        num_types = gst_tensors_info_parse_types_string (&prop->input_meta,
+            g_value_get_string (value));
 
-        for (i = 0; i < prop->input_meta.num_tensors; i++) {
-          prop->input_meta.info[i].type = get_tensor_type (str_types[i]);
-          g_assert (prop->input_meta.info[i].type != _NNS_END);
+        if (prop->input_meta.num_tensors > 0 &&
+            prop->input_meta.num_tensors != num_types) {
+          GST_WARNING_OBJECT (self,
+              "Invalid input-type, given param does not match with old value.");
         }
 
-        g_strfreev (str_types);
+        prop->input_meta.num_tensors = num_types;
       }
       break;
     case PROP_OUTPUTTYPE:
       g_assert (!prop->output_configured && value);
       /* Once configures, it cannot be changed in runtime */
       {
-        int i;
-        gchar **str_types;
+        guint num_types;
 
-        str_types = g_strsplit (g_value_get_string (value), ",", -1);
-        prop->output_meta.num_tensors = g_strv_length (str_types);
+        num_types = gst_tensors_info_parse_types_string (&prop->output_meta,
+            g_value_get_string (value));
 
-        for (i = 0; i < prop->output_meta.num_tensors; i++) {
-          prop->output_meta.info[i].type = get_tensor_type (str_types[i]);
-          g_assert (prop->output_meta.info[i].type != _NNS_END);
+        if (prop->output_meta.num_tensors > 0 &&
+            prop->output_meta.num_tensors != num_types) {
+          GST_WARNING_OBJECT (self,
+              "Invalid output-type, given param does not match with old value.");
         }
 
-        g_strfreev (str_types);
+        prop->output_meta.num_tensors = num_types;
       }
       break;
     case PROP_INPUTNAME:
@@ -652,20 +645,18 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id,
       g_assert (!prop->input_configured && value);
       /* Once configures, it cannot be changed in runtime */
       {
-        int i;
-        gchar **str_names;
+        guint num_names;
 
-        str_names = g_strsplit (g_value_get_string (value), ",", -1);
-        prop->input_meta.num_tensors = g_strv_length (str_names);
+        num_names = gst_tensors_info_parse_names_string (&prop->input_meta,
+            g_value_get_string (value));
 
-        for (i = 0; i < prop->input_meta.num_tensors; i++) {
-          g_free ((char *) prop->input_meta.info[i].name);
-          prop->input_meta.info[i].name = g_strdup (str_names[i]);
-          g_assert (prop->input_meta.info[i].name &&
-              prop->input_meta.info[i].name[0] != '\0');
+        if (prop->input_meta.num_tensors > 0 &&
+            prop->input_meta.num_tensors != num_names) {
+          GST_WARNING_OBJECT (self,
+              "Invalid input-name, given param does not match with old value.");
         }
 
-        g_strfreev (str_names);
+        prop->input_meta.num_tensors = num_names;
       }
       break;
     case PROP_OUTPUTNAME:
@@ -673,20 +664,18 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id,
       g_assert (!prop->output_configured && value);
       /* Once configures, it cannot be changed in runtime */
       {
-        int i;
-        gchar **str_names;
+        guint num_names;
 
-        str_names = g_strsplit (g_value_get_string (value), ",", -1);
-        prop->output_meta.num_tensors = g_strv_length (str_names);
+        num_names = gst_tensors_info_parse_names_string (&prop->output_meta,
+            g_value_get_string (value));
 
-        for (i = 0; i < prop->output_meta.num_tensors; i++) {
-          g_free ((char *) prop->output_meta.info[i].name);
-          prop->output_meta.info[i].name = g_strdup (str_names[i]);
-          g_assert (prop->output_meta.info[i].name &&
-              prop->output_meta.info[i].name[0] != '\0');
+        if (prop->output_meta.num_tensors > 0 &&
+            prop->output_meta.num_tensors != num_names) {
+          GST_WARNING_OBJECT (self,
+              "Invalid input-name, given param does not match with old value.");
         }
 
-        g_strfreev (str_names);
+        prop->output_meta.num_tensors = num_names;
       }
       break;
     case PROP_CUSTOM:
@@ -728,126 +717,72 @@ gst_tensor_filter_get_property (GObject * object, guint prop_id,
       break;
     case PROP_INPUT:
       if (prop->input_meta.num_tensors > 0) {
-        GString *dimensions = g_string_new (NULL);
         gchar *dim_str;
-        int i;
-
-        for (i = 0; i < prop->input_meta.num_tensors; i++) {
-          dim_str =
-              get_tensor_dimension_string (prop->input_meta.info[i].dimension);
-          g_string_append (dimensions, dim_str);
 
-          if (i < prop->input_meta.num_tensors - 1) {
-            g_string_append (dimensions, ",");
-          }
-
-          g_free (dim_str);
-        }
+        dim_str = gst_tensors_info_get_dimensions_string (&prop->input_meta);
 
-        g_value_set_string (value, dimensions->str);
-        g_string_free (dimensions, TRUE);
+        g_value_set_string (value, dim_str);
+        g_free (dim_str);
       } else {
         g_value_set_string (value, "");
       }
       break;
     case PROP_OUTPUT:
       if (prop->output_meta.num_tensors > 0) {
-        GString *dimensions = g_string_new (NULL);
         gchar *dim_str;
-        int i;
 
-        for (i = 0; i < prop->output_meta.num_tensors; i++) {
-          dim_str =
-              get_tensor_dimension_string (prop->output_meta.info[i].dimension);
-          g_string_append (dimensions, dim_str);
+        dim_str = gst_tensors_info_get_dimensions_string (&prop->output_meta);
 
-          if (i < prop->output_meta.num_tensors - 1) {
-            g_string_append (dimensions, ",");
-          }
-
-          g_free (dim_str);
-        }
-
-        g_value_set_string (value, dimensions->str);
-        g_string_free (dimensions, TRUE);
+        g_value_set_string (value, dim_str);
+        g_free (dim_str);
       } else {
         g_value_set_string (value, "");
       }
       break;
     case PROP_INPUTTYPE:
       if (prop->input_meta.num_tensors > 0) {
-        GString *types = g_string_new (NULL);
-        int i;
-
-        for (i = 0; i < prop->input_meta.num_tensors; i++) {
-          g_string_append (types,
-              tensor_element_typename[prop->input_meta.info[i].type]);
+        gchar *type_str;
 
-          if (i < prop->input_meta.num_tensors - 1) {
-            g_string_append (types, ",");
-          }
-        }
+        type_str = gst_tensors_info_get_types_string (&prop->input_meta);
 
-        g_value_set_string (value, types->str);
-        g_string_free (types, TRUE);
+        g_value_set_string (value, type_str);
+        g_free (type_str);
       } else {
         g_value_set_string (value, "");
       }
       break;
     case PROP_OUTPUTTYPE:
       if (prop->output_meta.num_tensors > 0) {
-        GString *types = g_string_new (NULL);
-        int i;
-
-        for (i = 0; i < prop->output_meta.num_tensors; i++) {
-          g_string_append (types,
-              tensor_element_typename[prop->output_meta.info[i].type]);
+        gchar *type_str;
 
-          if (i < prop->output_meta.num_tensors - 1) {
-            g_string_append (types, ",");
-          }
-        }
+        type_str = gst_tensors_info_get_types_string (&prop->output_meta);
 
-        g_value_set_string (value, types->str);
-        g_string_free (types, TRUE);
+        g_value_set_string (value, type_str);
+        g_free (type_str);
       } else {
         g_value_set_string (value, "");
       }
       break;
     case PROP_INPUTNAME:
       if (prop->input_meta.num_tensors > 0) {
-        GString *names = g_string_new (NULL);
-        int i;
+        gchar *name_str;
 
-        for (i = 0; i < prop->input_meta.num_tensors; i++) {
-          g_string_append (names, prop->input_meta.info[i].name);
+        name_str = gst_tensors_info_get_names_string (&prop->input_meta);
 
-          if (i < prop->input_meta.num_tensors - 1) {
-            g_string_append (names, ",");
-          }
-        }
-
-        g_value_set_string (value, names->str);
-        g_string_free (names, TRUE);
+        g_value_set_string (value, name_str);
+        g_free (name_str);
       } else {
         g_value_set_string (value, "");
       }
       break;
     case PROP_OUTPUTNAME:
       if (prop->output_meta.num_tensors > 0) {
-        GString *names = g_string_new (NULL);
-        int i;
-
-        for (i = 0; i < prop->output_meta.num_tensors; i++) {
-          g_string_append (names, prop->output_meta.info[i].name);
+        gchar *name_str;
 
-          if (i < prop->output_meta.num_tensors - 1) {
-            g_string_append (names, ",");
-          }
-        }
+        name_str = gst_tensors_info_get_names_string (&prop->output_meta);
 
-        g_value_set_string (value, names->str);
-        g_string_free (names, TRUE);
+        g_value_set_string (value, name_str);
+        g_free (name_str);
       } else {
         g_value_set_string (value, "");
       }
index f644155..27d91a9 100644 (file)
@@ -253,6 +253,121 @@ TEST (common_get_tensor_dimension, case4)
 }
 
 /**
+ * @brief Test for dimensions string in tensors info.
+ */
+TEST (common_tensors_info_string, dimensions)
+{
+  GstTensorsInfo info;
+  guint num_dims;
+  gchar *str_dims;
+
+  gst_tensors_info_init (&info);
+
+  /* 1 tensor info */
+  num_dims = gst_tensors_info_parse_dimensions_string (&info, "1:2:3:4");
+  EXPECT_EQ (num_dims, 1);
+
+  info.num_tensors = num_dims;
+
+  str_dims = gst_tensors_info_get_dimensions_string (&info);
+  EXPECT_TRUE (g_str_equal (str_dims, "1:2:3:4"));
+  g_free (str_dims);
+
+  /* 4 tensors info */
+  num_dims = gst_tensors_info_parse_dimensions_string (&info, "1, 2, 3, 4");
+  EXPECT_EQ (num_dims, 4);
+
+  info.num_tensors = num_dims;
+
+  str_dims = gst_tensors_info_get_dimensions_string (&info);
+  EXPECT_TRUE (g_str_equal (str_dims, "1:1:1:1,2:1:1:1,3:1:1:1,4:1:1:1"));
+  g_free (str_dims);
+
+  /* max */
+  num_dims = gst_tensors_info_parse_dimensions_string (&info,
+      "1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20");
+  EXPECT_EQ (num_dims, NNS_TENSOR_SIZE_LIMIT);
+}
+
+/**
+ * @brief Test for types string in tensors info.
+ */
+TEST (common_tensors_info_string, types)
+{
+  GstTensorsInfo info;
+  guint num_types;
+  gchar *str_types;
+
+  gst_tensors_info_init (&info);
+
+  /* 1 tensor info */
+  num_types = gst_tensors_info_parse_types_string (&info, "uint16");
+  EXPECT_EQ (num_types, 1);
+
+  info.num_tensors = num_types;
+
+  str_types = gst_tensors_info_get_types_string (&info);
+  EXPECT_TRUE (g_str_equal (str_types, "uint16"));
+  g_free (str_types);
+
+  /* 4 tensors info */
+  num_types = gst_tensors_info_parse_types_string (&info,
+      "int8, int16, int32, int64");
+  EXPECT_EQ (num_types, 4);
+
+  info.num_tensors = num_types;
+
+  str_types = gst_tensors_info_get_types_string (&info);
+  EXPECT_TRUE (g_str_equal (str_types, "int8,int16,int32,int64"));
+  g_free (str_types);
+
+  /* max */
+  num_types = gst_tensors_info_parse_types_string (&info,
+      "int8, int8, int8, int8, int8, int8, int8, int8, int8, int8, int8, "
+      "int8, int8, int8, int8, int8, int8, int8, int8, int8, int8, int8");
+  EXPECT_EQ (num_types, NNS_TENSOR_SIZE_LIMIT);
+}
+
+/**
+ * @brief Test for names string in tensors info.
+ */
+TEST (common_tensors_info_string, names)
+{
+  GstTensorsInfo info;
+  guint num_names;
+  gchar *str_names;
+
+  gst_tensors_info_init (&info);
+
+  /* 1 tensor info */
+  num_names = gst_tensors_info_parse_names_string (&info, "t1");
+  EXPECT_EQ (num_names, 1);
+
+  info.num_tensors = num_names;
+
+  str_names = gst_tensors_info_get_names_string (&info);
+  EXPECT_TRUE (g_str_equal (str_names, "t1"));
+  g_free (str_names);
+
+  /* 4 tensors info */
+  num_names = gst_tensors_info_parse_names_string (&info,
+      "tensor1, tensor2, tensor3, tensor4");
+  EXPECT_EQ (num_names, 4);
+
+  info.num_tensors = num_names;
+
+  str_names = gst_tensors_info_get_names_string (&info);
+  EXPECT_TRUE (g_str_equal (str_names, "tensor1,tensor2,tensor3,tensor4"));
+  g_free (str_names);
+
+  /* max */
+  num_names = gst_tensors_info_parse_names_string (&info,
+      "t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, "
+      "t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28");
+  EXPECT_EQ (num_names, NNS_TENSOR_SIZE_LIMIT);
+}
+
+/**
  * @brief Main function for unit test.
  */
 int