[Common] common functions to prepare multi-tensors
authorJaeyun <jy1210.jung@samsung.com>
Wed, 12 Sep 2018 06:40:35 +0000 (15:40 +0900)
committerMyungJoo Ham <myungjoo.ham@gmail.com>
Thu, 13 Sep 2018 04:33:28 +0000 (13:33 +0900)
prepare multi-tensors (other/tensors)

1. add new structure and functions for tensor info
2. remove dependency of media info
3. remove the rank of tensor dimension

Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
common/tensor_common.c
gst/tensor_aggregator/tensor_aggregator.c
gst/tensor_converter/tensor_converter.c
gst/tensor_decoder/tensordec.c
gst/tensor_filter/tensor_filter.c
gst/tensor_split/gsttensorsplit.c
include/tensor_common.h
include/tensor_typedef.h
tests/common/unittest_common.cpp
tests/nnstreamer_sink/unittest_sink.cpp

index 7ea837f..79623eb 100644 (file)
@@ -87,249 +87,140 @@ gst_tensor_media_type_from_caps (const GstCaps * caps)
 }
 
 /**
- * @brief Initialize the video info structure
- * @param v_info video info structure to be initialized
+ * @brief Initialize the tensor info structure
+ * @param info tensor info structure to be initialized
  */
 void
-gst_tensor_video_info_init (GstTensorVideoInfo * v_info)
+gst_tensor_info_init (GstTensorInfo * info)
 {
-  g_return_if_fail (v_info != NULL);
+  guint i;
 
-  /**
-   * Refer: https://gstreamer.freedesktop.org/documentation/design/mediatype-video-raw.html
-   */
-  v_info->format = GST_VIDEO_FORMAT_UNKNOWN;
-  v_info->w = 0;
-  v_info->h = 0;
-  v_info->fn = -1;
-  v_info->fd = -1;
-  v_info->frames = 0;
-}
+  g_return_if_fail (info != NULL);
 
-/**
- * @brief Initialize the audio info structure
- * @param a_info audio info structure to be initialized
- */
-void
-gst_tensor_audio_info_init (GstTensorAudioInfo * a_info)
-{
-  g_return_if_fail (a_info != NULL);
-
-  /**
-   * Refer: https://gstreamer.freedesktop.org/documentation/design/mediatype-audio-raw.html
-   */
-  a_info->format = GST_AUDIO_FORMAT_UNKNOWN;
-  a_info->ch = 0;
-  a_info->rate = 0;
-  a_info->frames = 0;
-}
+  info->type = _NNS_END;
 
-/**
- * @brief Initialize the text info structure
- * @param t_info text info structure to be initialized
- */
-void
-gst_tensor_text_info_init (GstTensorTextInfo * t_info)
-{
-  g_return_if_fail (t_info != NULL);
-
-  /**
-   * Refer: https://gstreamer.freedesktop.org/documentation/design/mediatype-text-raw.html
-   */
-  t_info->format = 0;
-  t_info->size = 0;
-  t_info->frames = 0;
+  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
+    info->dimension[i] = 0;
+  }
 }
 
 /**
- * @brief Set video info to configure tensor
- * @param v_info video info structure to be filled
- * @param structure caps structure
- * @note Fill frames in GstTensorVideoInfo after calling this function.
+ * @brief Check the tensor info is valid
+ * @param info tensor info structure
+ * @return TRUE if info is valid
  */
-void
-gst_tensor_video_info_from_structure (GstTensorVideoInfo * v_info,
-    const GstStructure * structure)
+gboolean
+gst_tensor_info_validate (const GstTensorInfo * info)
 {
-  const gchar *format;
+  guint i;
 
-  g_return_if_fail (v_info != NULL);
-  g_return_if_fail (structure != NULL);
+  g_return_val_if_fail (info != NULL, FALSE);
 
-  gst_tensor_video_info_init (v_info);
+  if (info->type == _NNS_END) {
+    return FALSE;
+  }
 
-  format = gst_structure_get_string (structure, "format");
-  if (format) {
-    v_info->format = gst_video_format_from_string (format);
+  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
+    if (info->dimension[i] == 0) {
+      return FALSE;
+    }
   }
 
-  gst_structure_get_int (structure, "width", &v_info->w);
-  gst_structure_get_int (structure, "height", &v_info->h);
-  gst_structure_get_fraction (structure, "framerate", &v_info->fn, &v_info->fd);
+  return TRUE;
 }
 
 /**
- * @brief Set audio info to configure tensor
- * @param a_info audio info structure to be filled
- * @param structure caps structure
- * @note Fill frames in GstTensorAudioInfo after calling this function.
+ * @brief Compare tensor info
+ * @param TRUE if equal
  */
-void
-gst_tensor_audio_info_from_structure (GstTensorAudioInfo * a_info,
-    const GstStructure * structure)
+gboolean
+gst_tensor_info_is_equal (const GstTensorInfo * i1, const GstTensorInfo * i2)
 {
-  const gchar *format;
+  guint i;
 
-  g_return_if_fail (a_info != NULL);
-  g_return_if_fail (structure != NULL);
+  g_return_val_if_fail (i1 != NULL, FALSE);
+  g_return_val_if_fail (i2 != NULL, FALSE);
 
-  gst_tensor_audio_info_init (a_info);
+  if (i1->type != i2->type) {
+    return FALSE;
+  }
 
-  format = gst_structure_get_string (structure, "format");
-  if (format) {
-    a_info->format = gst_audio_format_from_string (format);
+  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
+    if (i1->dimension[i] != i2->dimension[i]) {
+      return FALSE;
+    }
   }
 
-  gst_structure_get_int (structure, "channels", &a_info->ch);
-  gst_structure_get_int (structure, "rate", &a_info->rate);
+  /** matched all */
+  return TRUE;
 }
 
 /**
- * @brief Set text info to configure tensor
- * @param t_info text info structure to be filled
- * @param structure caps structure
- * @note Fill size and frames in GstTensorTextInfo after calling this function.
+ * @brief Initialize the tensors info structure
+ * @param info tensors info structure to be initialized
  */
 void
-gst_tensor_text_info_from_structure (GstTensorTextInfo * t_info,
-    const GstStructure * structure)
+gst_tensors_info_init (GstTensorsInfo * info)
 {
-  const gchar *format;
+  guint i;
 
-  g_return_if_fail (t_info != NULL);
-  g_return_if_fail (structure != NULL);
+  g_return_if_fail (info != NULL);
 
-  gst_tensor_text_info_init (t_info);
+  info->num_tensors = 0;
 
-  format = gst_structure_get_string (structure, "format");
-  if (format) {
-    if (g_str_equal (format, "utf8")) {
-      t_info->format = 1;
-    }
+  for (i = 0; i < NNS_TENSOR_SIZE_LIMIT; i++) {
+    gst_tensor_info_init (&info->info[i]);
   }
 }
 
 /**
- * @brief Set the video info structure from tensor config
- * @param v_info video info structure to be filled
- * @param config tensor config structure to be interpreted
- * @note We cannot get the exact media info from tensor config, you have to check media info after calling this function.
- * @return TRUE if no error
+ * @brief Check the tensors info is valid
+ * @param info tensors info structure
+ * @return TRUE if info is valid
  */
 gboolean
-gst_tensor_video_info_from_config (GstTensorVideoInfo * v_info,
-    const GstTensorConfig * config)
+gst_tensors_info_validate (const GstTensorsInfo * info)
 {
-  g_return_val_if_fail (config != NULL, FALSE);
-  g_return_val_if_fail (v_info != NULL, FALSE);
+  guint i;
 
-  gst_tensor_video_info_init (v_info);
+  g_return_val_if_fail (info != NULL, FALSE);
 
-  /**
-   * Set video format with the dimension (color-space).
-   */
-  switch (config->dimension[0]) {
-    case 1:
-      v_info->format = GST_VIDEO_FORMAT_GRAY8;
-      break;
-    case 3:
-      v_info->format = GST_VIDEO_FORMAT_RGB;
-      break;
-    case 4:
-      v_info->format = GST_VIDEO_FORMAT_BGRx;
-      break;
-    default:
-      v_info->format = GST_VIDEO_FORMAT_UNKNOWN;
-      break;
+  if (info->num_tensors < 1) {
+    return FALSE;
   }
 
-  v_info->w = config->dimension[1];
-  v_info->h = config->dimension[2];
-  v_info->frames = config->dimension[3];
-  v_info->fn = config->rate_n;
-  v_info->fd = config->rate_d;
-  return TRUE;
-}
-
-/**
- * @brief Set the audio info structure from tensor config
- * @param a_info audio info structure to be filled
- * @param config tensor config structure to be interpreted
- * @note We cannot get the exact media info from tensor config, you have to check media info after calling this function.
- * @return TRUE if no error
- */
-gboolean
-gst_tensor_audio_info_from_config (GstTensorAudioInfo * a_info,
-    const GstTensorConfig * config)
-{
-  g_return_val_if_fail (config != NULL, FALSE);
-  g_return_val_if_fail (a_info != NULL, FALSE);
-
-  gst_tensor_audio_info_init (a_info);
-
-  /**
-   * Set audio format with the type.
-   */
-  switch (config->type) {
-    case _NNS_INT8:
-      a_info->format = GST_AUDIO_FORMAT_S8;
-      break;
-    case _NNS_UINT8:
-      a_info->format = GST_AUDIO_FORMAT_U8;
-      break;
-    case _NNS_INT16:
-      a_info->format = GST_AUDIO_FORMAT_S16;
-      break;
-    case _NNS_UINT16:
-      a_info->format = GST_AUDIO_FORMAT_U16;
-      break;
-    default:
-      a_info->format = GST_AUDIO_FORMAT_UNKNOWN;
-      break;
+  for (i = 0; i < info->num_tensors; i++) {
+    if (!gst_tensor_info_validate (&info->info[i])) {
+      return FALSE;
+    }
   }
 
-  a_info->ch = config->dimension[0];
-  a_info->frames = config->dimension[1];
-  a_info->rate = config->rate_n;
   return TRUE;
 }
 
 /**
- * @brief Set the text info structure from tensor config
- * @param t_info text info structure to be filled
- * @param config tensor config structure to be interpreted
- * @note We cannot get the exact media info from tensor config, you have to check media info after calling this function.
- * @return TRUE if no error
+ * @brief Compare tensors info
+ * @param TRUE if equal
  */
 gboolean
-gst_tensor_text_info_from_config (GstTensorTextInfo * t_info,
-    const GstTensorConfig * config)
+gst_tensors_info_is_equal (const GstTensorsInfo * i1, const GstTensorsInfo * i2)
 {
-  g_return_val_if_fail (config != NULL, FALSE);
-  g_return_val_if_fail (t_info != NULL, FALSE);
+  guint i;
 
-  gst_tensor_text_info_init (t_info);
+  g_return_val_if_fail (i1 != NULL, FALSE);
+  g_return_val_if_fail (i2 != NULL, FALSE);
 
-  /**
-   * Set text format. Supposed utf8 if type is int8.
-   */
-  if (config->type == _NNS_INT8) {
-    /** Supposed utf8 */
-    t_info->format = 1;
+  if (i1->num_tensors != i2->num_tensors) {
+    return FALSE;
+  }
+
+  for (i = 0; i < i1->num_tensors; i++) {
+    if (!gst_tensor_info_is_equal (&i1->info[i], &i2->info[i])) {
+      return FALSE;
+    }
   }
 
-  t_info->size = config->dimension[0];
-  t_info->frames = config->dimension[1];
+  /** matched all */
   return TRUE;
 }
 
@@ -340,15 +231,9 @@ gst_tensor_text_info_from_config (GstTensorTextInfo * t_info,
 void
 gst_tensor_config_init (GstTensorConfig * config)
 {
-  guint i;
-
   g_return_if_fail (config != NULL);
 
-  config->type = _NNS_END;
-
-  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
-    config->dimension[i] = 0;
-  }
+  gst_tensor_info_init (&config->info);
 
   config->rate_n = -1;
   config->rate_d = -1;
@@ -362,60 +247,35 @@ gst_tensor_config_init (GstTensorConfig * config)
 gboolean
 gst_tensor_config_validate (const GstTensorConfig * config)
 {
-  guint i;
-
   g_return_val_if_fail (config != NULL, FALSE);
 
-  if (config->type == _NNS_END) {
-    return FALSE;
-  }
-
-  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
-    if (config->dimension[i] == 0) {
-      return FALSE;
-    }
-  }
-
   if (config->rate_n < 0 || config->rate_d < 0) {
     return FALSE;
   }
 
-  return TRUE;
+  return gst_tensor_info_validate (&config->info);
 }
 
 /**
  * @brief Compare tensor config info
- * @param TRUE if same
+ * @param TRUE if equal
  */
 gboolean
-gst_tensor_config_is_same (const GstTensorConfig * c1,
+gst_tensor_config_is_equal (const GstTensorConfig * c1,
     const GstTensorConfig * c2)
 {
-  guint i;
-
   g_return_val_if_fail (c1 != NULL, FALSE);
   g_return_val_if_fail (c2 != NULL, FALSE);
 
-  if (c1->type != c2->type) {
-    return FALSE;
-  }
-
   if (c1->rate_n != c2->rate_n || c1->rate_d != c2->rate_d) {
     return FALSE;
   }
 
-  for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++) {
-    if (c1->dimension[i] != c2->dimension[i]) {
-      return FALSE;
-    }
-  }
-
-  /** matched all */
-  return TRUE;
+  return gst_tensor_info_is_equal (&c1->info, &c2->info);
 }
 
 /**
- * @brief Parse structure and set tensor config info
+ * @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
@@ -424,25 +284,27 @@ static gboolean
 gst_tensor_config_from_tensor_structure (GstTensorConfig * config,
     const GstStructure * structure)
 {
+  GstTensorInfo *info;
   const gchar *type_string;
 
   g_return_val_if_fail (config != NULL, FALSE);
-  g_return_val_if_fail (structure != 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")) {
     err_print ("caps is not tensor %s\n", gst_structure_get_name (structure));
     return FALSE;
   }
 
-  gst_structure_get_int (structure, "dim1", (gint *) (&config->dimension[0]));
-  gst_structure_get_int (structure, "dim2", (gint *) (&config->dimension[1]));
-  gst_structure_get_int (structure, "dim3", (gint *) (&config->dimension[2]));
-  gst_structure_get_int (structure, "dim4", (gint *) (&config->dimension[3]));
+  gst_structure_get_int (structure, "dim1", (gint *) (&info->dimension[0]));
+  gst_structure_get_int (structure, "dim2", (gint *) (&info->dimension[1]));
+  gst_structure_get_int (structure, "dim3", (gint *) (&info->dimension[2]));
+  gst_structure_get_int (structure, "dim4", (gint *) (&info->dimension[3]));
 
   type_string = gst_structure_get_string (structure, "type");
-  config->type = get_tensor_type (type_string);
+  info->type = get_tensor_type (type_string);
 
   gst_structure_get_fraction (structure, "framerate", &config->rate_n,
       &config->rate_d);
@@ -451,239 +313,241 @@ gst_tensor_config_from_tensor_structure (GstTensorConfig * config,
 }
 
 /**
- * @brief Parse caps and set tensor config info
- * @param config tensor config structure to be filled
- * @param structure structure to be interpreted
- * @return TRUE if ok
- */
-static gboolean
-gst_tensor_config_from_media_structure (GstTensorConfig * config,
-    const GstStructure * structure)
-{
-  media_type m_type;
-
-  g_return_val_if_fail (config != NULL, FALSE);
-  g_return_val_if_fail (structure != NULL, FALSE);
-
-  gst_tensor_config_init (config);
-
-  m_type = gst_tensor_media_type_from_structure (structure);
-
-  switch (m_type) {
-    case _NNS_VIDEO:
-    {
-      GstTensorVideoInfo v_info;
-
-      gst_tensor_video_info_from_structure (&v_info, structure);
-
-      /** supposed 1 frame in tensor */
-      v_info.frames = 1;
-
-      gst_tensor_config_from_video_info (config, &v_info);
-      break;
-    }
-    case _NNS_AUDIO:
-    {
-      GstTensorAudioInfo a_info;
-
-      gst_tensor_audio_info_from_structure (&a_info, structure);
-
-      /** supposed 1 frame in tensor */
-      a_info.frames = 1;
-
-      gst_tensor_config_from_audio_info (config, &a_info);
-      break;
-    }
-    case _NNS_STRING:
-    {
-      GstTensorTextInfo t_info;
-
-      gst_tensor_text_info_from_structure (&t_info, structure);
-
-      /** fixed size of string */
-      t_info.size = GST_TENSOR_STRING_SIZE;
-      /** supposed 1 frame in tensor */
-      t_info.frames = 1;
-
-      gst_tensor_config_from_text_info (config, &t_info);
-      break;
-    }
-    default:
-      err_print ("Unsupported type %d\n", m_type);
-      return FALSE;
-  }
-
-  return TRUE;
-}
-
-/**
- * @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)
-{
-  g_return_val_if_fail (config != NULL, FALSE);
-  g_return_val_if_fail (structure != NULL, FALSE);
-
-  if (gst_structure_has_name (structure, "other/tensor")) {
-    return gst_tensor_config_from_tensor_structure (config, structure);
-  } else {
-    return gst_tensor_config_from_media_structure (config, structure);
-  }
-}
-
-/**
- * @brief Set the tensor config structure from video info
+ * @brief Set the tensor config structure from video info (internal static function)
  * @param config tensor config structure to be filled
- * @param v_info video info structure to be interpreted
+ * @param structure caps structure
  * @note Change dimention if tensor contains N frames.
  * @return TRUE if supported type
  */
-gboolean
+static gboolean
 gst_tensor_config_from_video_info (GstTensorConfig * config,
-    const GstTensorVideoInfo * v_info)
+    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.
    */
-  g_return_val_if_fail (config != NULL, FALSE);
-  g_return_val_if_fail (v_info != NULL, FALSE);
+  const gchar *format_string;
+  GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
+  gint width = 0;
+  gint height = 0;
+  gint fn = -1; /** numerator */
+  gint fd = -1; /** denominator */
 
+  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", &fn, &fd);
+
   /** [color-space][width][height][frames] */
-  switch (v_info->format) {
+  switch (format) {
     case GST_VIDEO_FORMAT_GRAY8:
-      config->type = _NNS_UINT8;
-      config->dimension[0] = 1;
+      config->info.type = _NNS_UINT8;
+      config->info.dimension[0] = 1;
       break;
     case GST_VIDEO_FORMAT_RGB:
-      config->type = _NNS_UINT8;
-      config->dimension[0] = 3;
+      config->info.type = _NNS_UINT8;
+      config->info.dimension[0] = 3;
       break;
     case GST_VIDEO_FORMAT_BGRx:
-      config->type = _NNS_UINT8;
-      config->dimension[0] = 4;
+      config->info.type = _NNS_UINT8;
+      config->info.dimension[0] = 4;
       break;
     default:
       /** unsupported format */
-      err_print ("Unsupported format = %d\n", v_info->format);
+      err_print ("Unsupported format = %d\n", format);
       break;
   }
 
-  config->dimension[1] = v_info->w;
-  config->dimension[2] = v_info->h;
-  config->dimension[3] = v_info->frames; /** change this if tensor contains N frames */
+  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. */
 
-  config->rate_n = v_info->fn;
-  config->rate_d = v_info->fd;
+  config->rate_n = fn;
+  config->rate_d = fd;
 
-  return (config->type != _NNS_END);
+  return (config->info.type != _NNS_END);
 }
 
 /**
- * @brief Set the tensor config structure from audio info
+ * @brief Set the tensor config structure from audio info (internal static function)
  * @param config tensor config structure to be filled
- * @param a_info audio info structure to be interpreted
+ * @param structure caps structure
  * @note Change dimention if tensor contains N frames.
  * @return TRUE if supported type
  */
-gboolean
+static gboolean
 gst_tensor_config_from_audio_info (GstTensorConfig * config,
-    const GstTensorAudioInfo * a_info)
+    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].
    */
-  g_return_val_if_fail (config != NULL, FALSE);
-  g_return_val_if_fail (a_info != NULL, FALSE);
+  const gchar *format_string;
+  GstAudioFormat format = GST_AUDIO_FORMAT_UNKNOWN;
+  gint channels = 0;
+  gint rate = 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_audio_format_from_string (format_string);
+  }
+
+  gst_structure_get_int (structure, "channels", &channels);
+  gst_structure_get_int (structure, "rate", &rate);
+
   /** [channels][frames] */
-  switch (a_info->format) {
+  switch (format) {
     case GST_AUDIO_FORMAT_S8:
-      config->type = _NNS_INT8;
+      config->info.type = _NNS_INT8;
       break;
     case GST_AUDIO_FORMAT_U8:
-      config->type = _NNS_UINT8;
+      config->info.type = _NNS_UINT8;
       break;
     case GST_AUDIO_FORMAT_S16:
-      config->type = _NNS_INT16;
+      config->info.type = _NNS_INT16;
       break;
     case GST_AUDIO_FORMAT_U16:
-      config->type = _NNS_UINT16;
+      config->info.type = _NNS_UINT16;
       break;
     default:
       /** unsupported format */
-      err_print ("Unsupported format = %d\n", a_info->format);
+      err_print ("Unsupported format = %d\n", format);
       break;
   }
 
-  config->dimension[0] = a_info->ch;
-  config->dimension[1] = a_info->frames; /** change this if tensor contains N frames */
-  config->dimension[2] = 1;
-  config->dimension[3] = 1;
+  config->info.dimension[0] = channels;
+  config->info.dimension[1] = 1; /** Supposed 1 frame in tensor, change this if tensor contains N frames */
+  config->info.dimension[2] = 1;
+  config->info.dimension[3] = 1;
 
-  if (a_info->rate > 0) {
-    config->rate_n = a_info->rate;
+  if (rate > 0) {
+    config->rate_n = rate;
     config->rate_d = 1;
   }
 
-  return (config->type != _NNS_END);
+  return (config->info.type != _NNS_END);
 }
 
 /**
- * @brief Set the tensor config structure from text info
+ * @brief Set the tensor config structure from text info (internal static function)
  * @param config tensor config structure to be filled
- * @param t_info text info structure to be interpreted
+ * @param structure caps structure
  * @note Change dimention if tensor contains N frames.
  * @return TRUE if supported type
  */
-gboolean
+static gboolean
 gst_tensor_config_from_text_info (GstTensorConfig * config,
-    const GstTensorTextInfo * t_info)
+    const GstStructure * structure)
 {
   /**
    * Refer: https://www.tensorflow.org/api_docs/python/tf/summary/text
    * A string-type Tensor
    */
-  g_return_val_if_fail (config != NULL, FALSE);
-  g_return_val_if_fail (t_info != NULL, FALSE);
+  const gchar *format_string;
 
+  g_return_val_if_fail (config != NULL, FALSE);
   gst_tensor_config_init (config);
 
-  /** [size][frames] */
-  switch (t_info->format) {
-    case 1:
-      /** utf8 */
-      config->type = _NNS_INT8;
-      break;
-    default:
+  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_INT8;
+    } else {
       /** unsupported format */
-      err_print ("Unsupported format = %d\n", t_info->format);
-      break;
+      err_print ("Unsupported format\n");
+    }
   }
 
-  config->dimension[0] = t_info->size;
-  config->dimension[1] = t_info->frames; /** change this if tensor contains N frames */
-  config->dimension[2] = 1;
-  config->dimension[3] = 1;
+  /** [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 */
+  config->info.dimension[2] = 1;
+  config->info.dimension[3] = 1;
 
   /** cannot get the framerate for text type */
   config->rate_n = 0;
   config->rate_d = 1;
 
-  return (config->type != _NNS_END);
+  return (config->info.type != _NNS_END);
+}
+
+/**
+ * @brief Parse caps and set tensor config info
+ * @param config tensor config structure to be filled
+ * @param structure structure to be interpreted
+ * @return TRUE if ok
+ */
+static gboolean
+gst_tensor_config_from_media_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);
+
+  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;
+    default:
+      err_print ("Unsupported type %d\n", m_type);
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+ * @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)
+{
+  g_return_val_if_fail (config != NULL, FALSE);
+  g_return_val_if_fail (structure != NULL, FALSE);
+
+  if (gst_structure_has_name (structure, "other/tensor")) {
+    return gst_tensor_config_from_tensor_structure (config, structure);
+  } else {
+    /** tensor config from media stream */
+    return gst_tensor_config_from_media_structure (config, structure);
+  }
 }
 
 /**
@@ -700,25 +564,238 @@ gst_tensor_caps_from_config (const GstTensorConfig * config)
 
   caps = gst_caps_from_string (GST_TENSOR_CAP_DEFAULT);
 
-  if (config->dimension[0] > 0) {
-    gst_caps_set_simple (caps, "dim1", G_TYPE_INT, config->dimension[0], NULL);
+  if (config->info.dimension[0] > 0) {
+    gst_caps_set_simple (caps, "dim1", G_TYPE_INT, config->info.dimension[0],
+        NULL);
   }
 
-  if (config->dimension[1] > 0) {
-    gst_caps_set_simple (caps, "dim2", G_TYPE_INT, config->dimension[1], NULL);
+  if (config->info.dimension[1] > 0) {
+    gst_caps_set_simple (caps, "dim2", G_TYPE_INT, config->info.dimension[1],
+        NULL);
   }
 
-  if (config->dimension[2] > 0) {
-    gst_caps_set_simple (caps, "dim3", G_TYPE_INT, config->dimension[2], NULL);
+  if (config->info.dimension[2] > 0) {
+    gst_caps_set_simple (caps, "dim3", G_TYPE_INT, config->info.dimension[2],
+        NULL);
   }
 
-  if (config->dimension[3] > 0) {
-    gst_caps_set_simple (caps, "dim4", G_TYPE_INT, config->dimension[3], NULL);
+  if (config->info.dimension[3] > 0) {
+    gst_caps_set_simple (caps, "dim4", G_TYPE_INT, config->info.dimension[3],
+        NULL);
   }
 
-  if (config->type != _NNS_END) {
+  if (config->info.type != _NNS_END) {
     gst_caps_set_simple (caps, "type", G_TYPE_STRING,
-        tensor_element_typename[config->type], NULL);
+        tensor_element_typename[config->info.type], NULL);
+  }
+
+  if (config->rate_n >= 0 && config->rate_d > 0) {
+    gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION,
+        config->rate_n, config->rate_d, NULL);
+  }
+
+  return gst_caps_simplify (caps);
+}
+
+/**
+ * @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);
+
+  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
+ */
+gboolean
+gst_tensors_config_is_equal (const GstTensorsConfig * c1,
+    const GstTensorsConfig * c2)
+{
+  g_return_val_if_fail (c1 != NULL, FALSE);
+  g_return_val_if_fail (c2 != NULL, FALSE);
+
+  if (c1->rate_n != c2->rate_n || c1->rate_d != c2->rate_d) {
+    return FALSE;
+  }
+
+  return gst_tensors_info_is_equal (&c1->info, &c2->info);
+}
+
+/**
+ * @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;
+  guint i, j;
+
+  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")) {
+    const gchar *dims_string;
+    const gchar *types_string;
+
+    gst_structure_get_uint (structure, "num_tensors",
+        &config->info.num_tensors);
+    gst_structure_get_fraction (structure, "framerate", &config->rate_n,
+        &config->rate_d);
+
+    /* parse dimensions */
+    dims_string = gst_structure_get_string (structure, "dimensions");
+    if (dims_string) {
+      gchar **str_dim, **str_dims;
+      gint num_dim, num_dims;
+      guint64 val;
+
+      str_dims = g_strsplit (dims_string, ",", -1);
+      num_dims = g_strv_length (str_dims);
+
+      if (config->info.num_tensors != num_dims) {
+        err_print ("Invalid param, dimensions (%d) tensors (%d)\n",
+            num_dims, config->info.num_tensors);
+      }
+
+      for (i = 0; i < num_dims; i++) {
+        str_dim = g_strsplit (str_dims[i], ":", NNS_TENSOR_RANK_LIMIT);
+        num_dim = g_strv_length (str_dim);
+
+        for (j = 0; j < num_dim; j++) {
+          val = g_ascii_strtoull (str_dim[j], NULL, 10);
+          config->info.info[i].dimension[j] = (uint32_t) val;
+        }
+
+        for (; j < NNS_TENSOR_RANK_LIMIT; j++) {
+          config->info.info[i].dimension[j] = 1;
+        }
+
+        g_strfreev (str_dim);
+      }
+
+      g_strfreev (str_dims);
+    }
+
+    /** parse types */
+    types_string = gst_structure_get_string (structure, "types");
+    if (types_string) {
+      gchar **str_types;
+      gint num_types;
+
+      str_types = g_strsplit (dims_string, ",", -1);
+      num_types = g_strv_length (str_types);
+
+      if (config->info.num_tensors != num_types) {
+        err_print ("Invalid param, types (%d) tensors (%d)\n",
+            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 {
+    err_print ("Unsupported type = %s\n", name);
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+ * @brief Get caps from tensors config (for other/tensors)
+ * @param config tensors config info
+ * @return caps for given config
+ */
+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);
+
+    /** dimensions and types */
+    for (i = 0; i < config->info.num_tensors; i++) {
+      /**
+       * @note supposed dimension with rank 4 (NNS_TENSOR_RANK_LIMIT)
+       */
+      gchar *dim_string = g_strdup_printf ("%d:%d:%d:%d",
+          config->info.info[i].dimension[0], config->info.info[i].dimension[1],
+          config->info.info[i].dimension[2], config->info.info[i].dimension[3]);
+
+      dimensions = g_string_append (dimensions, dim_string);
+      types =
+          g_string_append (types,
+          tensor_element_typename[config->info.info[i].type]);
+
+      if (i < config->info.num_tensors - 1) {
+        dimensions = g_string_append (dimensions, ",");
+        types = g_string_append (types, ",");
+      }
+
+      g_free (dim_string);
+    }
+
+    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);
+
+    g_string_free (dimensions, TRUE);
+    g_string_free (types, TRUE);
   }
 
   if (config->rate_n >= 0 && config->rate_d > 0) {
@@ -841,8 +918,7 @@ find_key_strv (const gchar ** strv, const gchar * key)
  */
 int
 get_tensor_dimension (const gchar * param,
-    uint32_t dim[NNS_TENSOR_SIZE_LIMIT][NNS_TENSOR_RANK_LIMIT],
-    int rank[NNS_TENSOR_SIZE_LIMIT])
+    uint32_t dim[NNS_TENSOR_SIZE_LIMIT][NNS_TENSOR_RANK_LIMIT])
 {
   int i, j = 0;
   guint64 val;
@@ -859,7 +935,6 @@ get_tensor_dimension (const gchar * param,
         break;
       val = g_ascii_strtoull (strv[j], NULL, 10);
       dim[i][j] = val;
-      rank[i] = j + 1;
     }
     for (; j < NNS_TENSOR_RANK_LIMIT; j++)
       dim[i][j] = 1;
@@ -947,7 +1022,6 @@ get_tensors_from_structure (const GstStructure * str,
     GstTensor_TensorsMeta * meta, int *framerate_num, int *framerate_denom)
 {
   int num = 0;
-  int rank[NNS_TENSOR_SIZE_LIMIT];
   const gchar *strval;
   gint fn = 0, fd = 0;
   gchar **strv;
@@ -974,7 +1048,7 @@ get_tensors_from_structure (const GstStructure * str,
 
   strval = gst_structure_get_string (str, "dimensions");
 
-  counter = get_tensor_dimension (strval, meta->dims, rank);
+  counter = get_tensor_dimension (strval, meta->dims);
 
   if (counter != num) {
     err_print
index 606fb70..d2b2e12 100644 (file)
@@ -661,7 +661,7 @@ gst_tensor_aggregator_parse_caps (GstTensorAggregator * self,
 
   /** update dimension in output tensor */
   if (self->frames_dim >= 0) {
-    config.dimension[self->frames_dim] = self->frames_out;
+    config.info.dimension[self->frames_dim] = self->frames_out;
   }
 
   self->out_config = config;
index da3c564..62eb2de 100644 (file)
@@ -53,7 +53,7 @@
  * <refsect2>
  * <title>Example launch line</title>
  * |[
- * gst-launch-1.0 videotestsrc ! video/x-raw,format=RGB,width=640,height=480 ! tensor_convert ! tensor_sink
+ * gst-launch-1.0 videotestsrc ! video/x-raw,format=RGB,width=640,height=480 ! tensor_converter ! tensor_sink
  * ]|
  * </refsect2>
  */
@@ -472,8 +472,8 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
   switch (self->in_media_type) {
     case _NNS_VIDEO:
       frame_size =
-          config->dimension[0] * config->dimension[1] * config->dimension[2] *
-          tensor_element_size[config->type];
+          config->info.dimension[0] * config->info.dimension[1] *
+          config->info.dimension[2] * tensor_element_size[config->info.type];
       frames_in = 1; /** supposed 1 frame in buffer */
 
       if (self->remove_padding) {
@@ -495,7 +495,7 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
         /**
          * Refer: https://gstreamer.freedesktop.org/documentation/design/mediatype-video-raw.html
          */
-        size = offset = config->dimension[0] * config->dimension[1];
+        size = offset = config->info.dimension[0] * config->info.dimension[1];
 
         g_assert (offset % 4);
         if (offset % 4) {
@@ -505,7 +505,7 @@ gst_tensor_converter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
         for (d0 = 0; d0 < frames_in; d0++) {
           /** Supposed to be 0 only, 1 frame in buffer. */
           g_assert (d0 == 0);
-          for (d1 = 0; d1 < config->dimension[2]; d1++) { /** Height */
+          for (d1 = 0; d1 < config->info.dimension[2]; d1++) { /** Height */
             memcpy (destptr + dest_idx, srcptr + src_idx, size);
             dest_idx += size;
             src_idx += offset;
@@ -747,7 +747,7 @@ gst_tensor_converter_parse_caps (GstTensorConverter * self,
   }
 
   /** set the number of frames in dimension */
-  config.dimension[frames_dim] = self->frames_per_tensor;
+  config.info.dimension[frames_dim] = self->frames_per_tensor;
 
   self->in_media_type = in_type;
   self->tensor_configured = TRUE;
index 03fe64c..e5ae4d1 100644 (file)
@@ -182,31 +182,49 @@ static GstCaps *
 gst_tensordec_video_caps_from_config (GstTensorDec * self,
     const GstTensorConfig * config)
 {
-  GstTensorVideoInfo v_info;
+  GstVideoFormat format;
+  gint width, height, fn, fd;
   GstCaps *caps;
 
   g_return_val_if_fail (config != NULL, NULL);
 
   caps = gst_caps_from_string (GST_TENSOR_VIDEO_CAPS_STR);
 
-  gst_tensor_video_info_from_config (&v_info, config);
+  switch (config->info.dimension[0]) {
+    case 1:
+      format = GST_VIDEO_FORMAT_GRAY8;
+      break;
+    case 3:
+      format = GST_VIDEO_FORMAT_RGB;
+      break;
+    case 4:
+      format = GST_VIDEO_FORMAT_BGRx;
+      break;
+    default:
+      format = GST_VIDEO_FORMAT_UNKNOWN;
+      break;
+  }
+
+  width = config->info.dimension[1];
+  height = config->info.dimension[2];
+  fn = config->rate_n;
+  fd = config->rate_d;
 
-  if (v_info.format != GST_VIDEO_FORMAT_UNKNOWN) {
-    const gchar *format_string = gst_video_format_to_string (v_info.format);
+  if (format != GST_VIDEO_FORMAT_UNKNOWN) {
+    const gchar *format_string = gst_video_format_to_string (format);
     gst_caps_set_simple (caps, "format", G_TYPE_STRING, format_string, NULL);
   }
 
-  if (v_info.w > 0) {
-    gst_caps_set_simple (caps, "width", G_TYPE_INT, v_info.w, NULL);
+  if (width > 0) {
+    gst_caps_set_simple (caps, "width", G_TYPE_INT, width, NULL);
   }
 
-  if (v_info.h > 0) {
-    gst_caps_set_simple (caps, "height", G_TYPE_INT, v_info.h, NULL);
+  if (height > 0) {
+    gst_caps_set_simple (caps, "height", G_TYPE_INT, height, NULL);
   }
 
-  if (v_info.fn > 0 && v_info.fd > 0) {
-    gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION,
-        v_info.fn, v_info.fd, NULL);
+  if (fn > 0 && fd > 0) {
+    gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, fn, fd, NULL);
   }
 
   return gst_caps_simplify (caps);
@@ -222,26 +240,46 @@ static GstCaps *
 gst_tensordec_audio_caps_from_config (GstTensorDec * self,
     const GstTensorConfig * config)
 {
-  GstTensorAudioInfo a_info;
+  GstAudioFormat format;
+  gint ch, rate;
   GstCaps *caps;
 
   g_return_val_if_fail (config != NULL, NULL);
 
   caps = gst_caps_from_string (GST_TENSOR_AUDIO_CAPS_STR);
 
-  gst_tensor_audio_info_from_config (&a_info, config);
+  switch (config->info.type) {
+    case _NNS_INT8:
+      format = GST_AUDIO_FORMAT_S8;
+      break;
+    case _NNS_UINT8:
+      format = GST_AUDIO_FORMAT_U8;
+      break;
+    case _NNS_INT16:
+      format = GST_AUDIO_FORMAT_S16;
+      break;
+    case _NNS_UINT16:
+      format = GST_AUDIO_FORMAT_U16;
+      break;
+    default:
+      format = GST_AUDIO_FORMAT_UNKNOWN;
+      break;
+  }
+
+  ch = config->info.dimension[0];
+  rate = config->rate_n;
 
-  if (a_info.format != GST_AUDIO_FORMAT_UNKNOWN) {
-    const gchar *format_string = gst_audio_format_to_string (a_info.format);
+  if (format != GST_AUDIO_FORMAT_UNKNOWN) {
+    const gchar *format_string = gst_audio_format_to_string (format);
     gst_caps_set_simple (caps, "format", G_TYPE_STRING, format_string, NULL);
   }
 
-  if (a_info.ch > 0) {
-    gst_caps_set_simple (caps, "channels", G_TYPE_INT, a_info.ch, NULL);
+  if (ch > 0) {
+    gst_caps_set_simple (caps, "channels", G_TYPE_INT, ch, NULL);
   }
 
-  if (a_info.rate > 0) {
-    gst_caps_set_simple (caps, "rate", G_TYPE_INT, a_info.rate, NULL);
+  if (rate > 0) {
+    gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate, NULL);
   }
 
   return gst_caps_simplify (caps);
@@ -257,14 +295,12 @@ static GstCaps *
 gst_tensordec_text_caps_from_config (GstTensorDec * self,
     const GstTensorConfig * config)
 {
-  GstTensorTextInfo t_info;
-
   g_return_val_if_fail (config != NULL, NULL);
 
-  gst_tensor_text_info_from_config (&t_info, config);
-
-  /** utf8 */
-  g_return_val_if_fail (t_info.format != 1, NULL);
+  /**
+   * Set text format. Supposed utf8 if type is int8.
+   */
+  g_return_val_if_fail (config->info.type == _NNS_INT8, NULL);
 
   return gst_caps_from_string (GST_TENSOR_TEXT_CAPS_STR);
 }
@@ -337,7 +373,7 @@ gst_tensordec_check_consistency (GstTensorDec * self, GstTensorConfig * config)
   g_return_val_if_fail (config != NULL, FALSE);
 
   if (self->configured) {
-    return gst_tensor_config_is_same (&self->tensor_config, config);
+    return gst_tensor_config_is_equal (&self->tensor_config, config);
   }
 
   /** not configured yet */
@@ -497,12 +533,27 @@ gst_tensordec_configure (GstTensorDec * self, const GstCaps * caps)
   switch (self->output_type) {
     case OUTPUT_VIDEO:
     {
-      GstTensorVideoInfo v_info;
+      GstVideoFormat format;
+      gint width;
+
+      switch (config.info.dimension[0]) {
+        case 1:
+          format = GST_VIDEO_FORMAT_GRAY8;
+          break;
+        case 3:
+          format = GST_VIDEO_FORMAT_RGB;
+          break;
+        case 4:
+          format = GST_VIDEO_FORMAT_BGRx;
+          break;
+        default:
+          format = GST_VIDEO_FORMAT_UNKNOWN;
+          break;
+      }
+      width = config.info.dimension[1];
 
-      if (gst_tensor_video_info_from_config (&v_info, &config)) {
-        if (gst_tensor_video_stride_padding_per_row (v_info.format, v_info.w)) {
-          self->add_padding = TRUE;
-        }
+      if (gst_tensor_video_stride_padding_per_row (format, width)) {
+        self->add_padding = TRUE;
       }
 
       break;
@@ -546,12 +597,12 @@ gst_tensordec_copy_buffer (GstTensorDec * self,
   g_assert (self->add_padding);
   g_assert (self->output_type == OUTPUT_VIDEO);
 
-  size = offset = config->dimension[0] * config->dimension[1];
+  size = offset = config->info.dimension[0] * config->info.dimension[1];
 
   if (offset % 4)
     offset += 4 - (offset % 4);
 
-  size_out = offset * config->dimension[2] * config->dimension[3];
+  size_out = offset * config->info.dimension[2] * config->info.dimension[3];
 
   if (gst_buffer_get_size (outbuf) < size_out) {
     gst_buffer_set_size (outbuf, size_out);
@@ -563,9 +614,9 @@ gst_tensordec_copy_buffer (GstTensorDec * self,
   inptr = inInfo.data;
   outptr = outInfo.data;
 
-  for (d0 = 0; d0 < config->dimension[3]; d0++) {
+  for (d0 = 0; d0 < config->info.dimension[3]; d0++) {
     g_assert (d0 == 0);
-    for (row = 0; row < config->dimension[2]; row++) {
+    for (row = 0; row < config->info.dimension[2]; row++) {
       memcpy (outptr + dest_idx, inptr + src_idx, size);
       dest_idx += offset;
       src_idx += size;
@@ -827,12 +878,12 @@ gst_tensordec_transform_size (GstBaseTransform * trans,
     /** flag add_padding only for video */
     g_assert (self->output_type == OUTPUT_VIDEO);
 
-    offset = config->dimension[0] * config->dimension[1];
+    offset = config->info.dimension[0] * config->info.dimension[1];
 
     if (offset % 4)
       offset += 4 - (offset % 4);
 
-    *othersize = offset * config->dimension[2] * config->dimension[3];
+    *othersize = offset * config->info.dimension[2] * config->info.dimension[3];
   } else {
     *othersize = size;
   }
index 68b19bb..3ca1df5 100644 (file)
@@ -531,10 +531,8 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id,
         int i;
         prop->inputMeta.num_tensors =
             get_tensor_dimension (g_value_get_string (value),
-            prop->inputMeta.dims, prop->inputMeta.ranks);
+            prop->inputMeta.dims);
         for (i = 0; i < prop->inputMeta.num_tensors; i++) {
-          g_assert (prop->inputMeta.ranks[i] > 0
-              && prop->inputMeta.ranks[i] <= NNS_TENSOR_RANK_LIMIT);
           silent_debug ("Input Prop: %d:%d:%d:%d Rank %d\n",
               prop->inputMeta.dims[i][0], prop->inputMeta.dims[i][1],
               prop->inputMeta.dims[i][2], prop->inputMeta.dims[i][3],
@@ -550,10 +548,8 @@ gst_tensor_filter_set_property (GObject * object, guint prop_id,
         int i;
         prop->outputMeta.num_tensors =
             get_tensor_dimension (g_value_get_string (value),
-            prop->outputMeta.dims, prop->outputMeta.ranks);
+            prop->outputMeta.dims);
         for (i = 0; i < prop->outputMeta.num_tensors; i++) {
-          g_assert (prop->outputMeta.ranks[i] > 0
-              && prop->outputMeta.ranks[i] <= NNS_TENSOR_RANK_LIMIT);
           silent_debug ("Output Prop: %d:%d:%d:%d Rank %d\n",
               prop->outputMeta.dims[i][0], prop->outputMeta.dims[i][1],
               prop->outputMeta.dims[i][2], prop->outputMeta.dims[i][3],
index 028e36e..472fe09 100644 (file)
@@ -316,7 +316,7 @@ gst_get_tensor_pad (GstTensorSplit * tensor_split, GstBuffer * inbuf,
   dim =
       g_array_index (tensor_split->tensorseg, tensor_dim *,
       tensor_split->num_srcpads);
-  type = tensor_split->sink_tensor_conf.type;
+  type = tensor_split->sink_tensor_conf.info.type;
 
   tensor_split->num_srcpads++;
 
@@ -434,7 +434,7 @@ gst_get_splited_tensor (GstTensorSplit * split, GstBuffer * buffer, gint nth)
   dim = g_array_index (split->tensorseg, tensor_dim *, nth);
   for (i = 0; i < NNS_TENSOR_RANK_LIMIT; i++)
     temp *= (*dim)[i];
-  size += temp * tensor_element_size[split->sink_tensor_conf.type];
+  size += temp * tensor_element_size[split->sink_tensor_conf.info.type];
   mem = gst_allocator_alloc (NULL, size, NULL);
   gst_memory_map (mem, &dest_info, GST_MAP_WRITE);
   gst_buffer_map (buffer, &src_info, GST_MAP_READ);
index 5744db8..156e99e 100644 (file)
@@ -98,8 +98,7 @@ G_BEGIN_DECLS
     "num_tensors = " GST_TENSOR_NUM_TENSORS_RANGE ", "\
     "framerate = " GST_TENSOR_RATE_RANGE
     /**
-     * type should be one of
-     * { float32, float64, int32, uint32, int16, uint16, int8, uint8 }
+     * 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
@@ -122,49 +121,24 @@ typedef enum _nns_media_type
 } media_type;
 
 /**
- * @brief Internal data structure for video info to configure tensor.
+ * @brief Internal data structure for configured tensor info (for other/tensor).
  */
 typedef struct
 {
-  GstVideoFormat format; /**< video format */
-  gint w; /**< width */
-  gint h; /**< height */
-  gint fn; /**< framerate numerator */
-  gint fd; /**< framerate denominator */
-  gint frames; /**< number of frames per tensor */
-} GstTensorVideoInfo;
-
-/**
- * @brief Internal data structure for audio info to configure tensor.
- */
-typedef struct
-{
-  GstAudioFormat format; /**< audio format */
-  gint ch; /**< channels */
-  gint rate; /**< rate */
-  gint frames; /**< samples per tensor */
-} GstTensorAudioInfo;
-
-/**
- * @brief Internal data structure for text info to configure tensor.
- */
-typedef struct
-{
-  gint format; /**< text format (0:unknown, 1:utf8) */
-  gint size; /**< string length (now it is fixed size GST_TENSOR_STRING_SIZE) */
-  gint frames; /**< number of frames per tensor */
-} GstTensorTextInfo;
+  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 tensor info.
+ * @brief Internal data structure for configured tensors info (for other/tensors).
  */
 typedef struct
 {
-  tensor_type type; /**< Type of each element in the tensor. User must designate this. Otherwise, this is UINT8 for video/x-raw byte stream */
-  tensor_dim dimension; /**< Dimensions. We support up to 4th ranks.  */
+  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 */
-} GstTensorConfig;
+} GstTensorsConfig;
 
 /**
  * @brief String representations for each tensor element type.
@@ -188,88 +162,48 @@ extern media_type
 gst_tensor_media_type_from_structure (const GstStructure * structure);
 
 /**
- * @brief Initialize the video info structure
- * @param v_info video info structure to be initialized
- */
-extern void
-gst_tensor_video_info_init (GstTensorVideoInfo * v_info);
-
-/**
- * @brief Initialize the audio info structure
- * @param a_info audio info structure to be initialized
- */
-extern void
-gst_tensor_audio_info_init (GstTensorAudioInfo * a_info);
-
-/**
- * @brief Initialize the text info structure
- * @param t_info text info structure to be initialized
+ * @brief Initialize the tensor info structure
+ * @param info tensor info structure to be initialized
  */
 extern void
-gst_tensor_text_info_init (GstTensorTextInfo * t_info);
+gst_tensor_info_init (GstTensorInfo * info);
 
 /**
- * @brief Set video info to configure tensor
- * @param v_info video info structure to be filled
- * @param structure caps structure
- * @note Fill frames in GstTensorVideoInfo after calling this function.
+ * @brief Check the tensor info is valid
+ * @param info tensor info structure
+ * @return TRUE if info is valid
  */
-extern void
-gst_tensor_video_info_from_structure (GstTensorVideoInfo * v_info,
-    const GstStructure * structure);
+extern gboolean
+gst_tensor_info_validate (const GstTensorInfo * info);
 
 /**
- * @brief Set audio info to configure tensor
- * @param a_info audio info structure to be filled
- * @param structure caps structure
- * @note Fill frames in GstTensorAudioInfo after calling this function.
+ * @brief Compare tensor info
+ * @param TRUE if equal
  */
-extern void
-gst_tensor_audio_info_from_structure (GstTensorAudioInfo * a_info,
-    const GstStructure * structure);
+extern gboolean
+gst_tensor_info_is_equal (const GstTensorInfo * i1, const GstTensorInfo * i2);
 
 /**
- * @brief Set text info to configure tensor
- * @param t_info text info structure to be filled
- * @param structure caps structure
- * @note Fill size and frames in GstTensorTextInfo after calling this function.
+ * @brief Initialize the tensors info structure
+ * @param info tensors info structure to be initialized
  */
 extern void
-gst_tensor_text_info_from_structure (GstTensorTextInfo * t_info,
-    const GstStructure * structure);
-
-/**
- * @brief Set the video info structure from tensor config
- * @param v_info video info structure to be filled
- * @param config tensor config structure to be interpreted
- * @note We cannot get the exact media info from tensor config, you have to check media info after calling this function.
- * @return TRUE if no error
- */
-extern gboolean
-gst_tensor_video_info_from_config (GstTensorVideoInfo * v_info,
-    const GstTensorConfig * config);
+gst_tensors_info_init (GstTensorsInfo * info);
 
 /**
- * @brief Set the audio info structure from tensor config
- * @param a_info audio info structure to be filled
- * @param config tensor config structure to be interpreted
- * @note We cannot get the exact media info from tensor config, you have to check media info after calling this function.
- * @return TRUE if no error
+ * @brief Check the tensors info is valid
+ * @param info tensors info structure
+ * @return TRUE if info is valid
  */
 extern gboolean
-gst_tensor_audio_info_from_config (GstTensorAudioInfo * a_info,
-    const GstTensorConfig * config);
+gst_tensors_info_validate (const GstTensorsInfo * info);
 
 /**
- * @brief Set the text info structure from tensor config
- * @param t_info text info structure to be filled
- * @param config tensor config structure to be interpreted
- * @note We cannot get the exact media info from tensor config, you have to check media info after calling this function.
- * @return TRUE if no error
+ * @brief Compare tensors info
+ * @param TRUE if equal
  */
 extern gboolean
-gst_tensor_text_info_from_config (GstTensorTextInfo * t_info,
-    const GstTensorConfig * config);
+gst_tensors_info_is_equal (const GstTensorsInfo * i1, const GstTensorsInfo * i2);
 
 /**
  * @brief Initialize the tensor config info structure
@@ -288,14 +222,14 @@ gst_tensor_config_validate (const GstTensorConfig * config);
 
 /**
  * @brief Compare tensor config info
- * @param TRUE if same
+ * @param TRUE if equal
  */
 extern gboolean
-gst_tensor_config_is_same (const GstTensorConfig * c1,
+gst_tensor_config_is_equal (const GstTensorConfig * c1,
     const GstTensorConfig * c2);
 
 /**
- * @brief Parse structure and set tensor config info
+ * @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.
@@ -306,45 +240,53 @@ gst_tensor_config_from_structure (GstTensorConfig * config,
     const GstStructure * structure);
 
 /**
- * @brief Set the tensor config structure from video info
- * @param config tensor config structure to be filled
- * @param v_info video info structure to be interpreted
- * @note Change dimention if tensor contains N frames.
- * @return TRUE if supported type
+ * @brief Get tensor caps from tensor config (for other/tensor)
+ * @param config tensor config info
+ * @return caps for given config
+ */
+extern GstCaps *
+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_tensor_config_from_video_info (GstTensorConfig * config,
-    const GstTensorVideoInfo * v_info);
+gst_tensors_config_validate (const GstTensorsConfig * config);
 
 /**
- * @brief Set the tensor config structure from audio info
- * @param config tensor config structure to be filled
- * @param a_info audio info structure to be interpreted
- * @note Change dimention if tensor contains N frames.
- * @return TRUE if supported type
+ * @brief Compare tensor config info (for other/tensors)
+ * @param TRUE if equal
  */
 extern gboolean
-gst_tensor_config_from_audio_info (GstTensorConfig * config,
-    const GstTensorAudioInfo * a_info);
+gst_tensors_config_is_equal (const GstTensorsConfig * c1,
+    const GstTensorsConfig * c2);
 
 /**
- * @brief Set the tensor config structure from text info
- * @param config tensor config structure to be filled
- * @param t_info text info structure to be interpreted
- * @note Change dimention if tensor contains N frames.
- * @return TRUE if supported type
+ * @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_tensor_config_from_text_info (GstTensorConfig * config,
-    const GstTensorTextInfo * t_info);
+gst_tensors_config_from_structure (GstTensorsConfig * config,
+    const GstStructure * structure);
 
 /**
- * @brief Get tensor caps from tensor config
- * @param config tensor config info
+ * @brief Get caps from tensors config (for other/tensors)
+ * @param config tensors config info
  * @return caps for given config
  */
 extern GstCaps *
-gst_tensor_caps_from_config (const GstTensorConfig * config);
+gst_tensors_caps_from_config (const GstTensorsConfig * config);
 
 /**
  * @brief Determine if we need zero-padding
@@ -374,8 +316,7 @@ extern int find_key_strv (const gchar ** strv, const gchar * key);
  * @param param The parameter 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];
  */
 extern int get_tensor_dimension (const gchar * param,
-    uint32_t dim[NNS_TENSOR_SIZE_LIMIT][NNS_TENSOR_RANK_LIMIT],
-    int rank[NNS_TENSOR_SIZE_LIMIT]);
+    uint32_t dim[NNS_TENSOR_SIZE_LIMIT][NNS_TENSOR_RANK_LIMIT]);
 
 /**
  * @brief Count the number of elemnts of a tensor
index 25b71fc..a6b0964 100644 (file)
@@ -103,6 +103,7 @@ typedef uint8_t *tensors[NNS_TENSOR_SIZE_LIMIT];     /**< Array of tensors */
 
 /**
  * @brief Internal meta data exchange format for a other/tensors instance
+ * @todo replace this to GstTensorsInfo
  */
 typedef struct
 {
@@ -113,6 +114,24 @@ typedef struct
 } GstTensor_TensorsMeta;
 
 /**
+ * @brief Internal data structure for tensor info.
+ */
+typedef struct
+{
+  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;
+
+/**
+ * @brief Internal meta data exchange format for a other/tensors instance
+ */
+typedef struct
+{
+  unsigned int num_tensors; /**< The number of tensors */
+  GstTensorInfo info[NNS_TENSOR_SIZE_LIMIT]; /**< The list of tensor info */
+} GstTensorsInfo;
+
+/**
  * @brief Tensor_Filter's properties (internal data structure)
  *
  * Because custom filters of tensor_filter may need to access internal data
index e430141..77deeb2 100644 (file)
@@ -175,10 +175,8 @@ TEST (common_find_key_strv, key_index)
 TEST (common_get_tensor_dimension, case1)
 {
   uint32_t dim[NNS_TENSOR_SIZE_LIMIT][NNS_TENSOR_RANK_LIMIT];
-  int rank[NNS_TENSOR_RANK_LIMIT];
-  int num_tensors = get_tensor_dimension ("345:123:433:177", dim, rank);
+  int num_tensors = get_tensor_dimension ("345:123:433:177", dim);
   EXPECT_EQ (num_tensors, 1);
-  EXPECT_EQ (rank[0], 4);
   EXPECT_EQ (dim[0][0], 345);
   EXPECT_EQ (dim[0][1], 123);
   EXPECT_EQ (dim[0][2], 433);
@@ -191,10 +189,8 @@ TEST (common_get_tensor_dimension, case1)
 TEST (common_get_tensor_dimension, case2)
 {
   uint32_t dim[NNS_TENSOR_SIZE_LIMIT][NNS_TENSOR_RANK_LIMIT];
-  int rank[NNS_TENSOR_RANK_LIMIT];
-  int num_tensors = get_tensor_dimension ("345:123:433", dim, rank);
+  int num_tensors = get_tensor_dimension ("345:123:433", dim);
   EXPECT_EQ (num_tensors, 1);
-  EXPECT_EQ (rank[0], 3);
   EXPECT_EQ (dim[0][0], 345);
   EXPECT_EQ (dim[0][1], 123);
   EXPECT_EQ (dim[0][2], 433);
@@ -207,10 +203,8 @@ TEST (common_get_tensor_dimension, case2)
 TEST (common_get_tensor_dimension, case3)
 {
   uint32_t dim[NNS_TENSOR_SIZE_LIMIT][NNS_TENSOR_RANK_LIMIT];
-  int rank[NNS_TENSOR_RANK_LIMIT];
-  int num_tensors = get_tensor_dimension ("345:123", dim, rank);
+  int num_tensors = get_tensor_dimension ("345:123", dim);
   EXPECT_EQ (num_tensors, 1);
-  EXPECT_EQ (rank[0], 2);
   EXPECT_EQ (dim[0][0], 345);
   EXPECT_EQ (dim[0][1], 123);
   EXPECT_EQ (dim[0][2], 1);
@@ -223,10 +217,8 @@ TEST (common_get_tensor_dimension, case3)
 TEST (common_get_tensor_dimension, case4)
 {
   uint32_t dim[NNS_TENSOR_SIZE_LIMIT][NNS_TENSOR_RANK_LIMIT];
-  int rank[NNS_TENSOR_RANK_LIMIT];
-  int num_tensors = get_tensor_dimension ("345", dim, rank);
+  int num_tensors = get_tensor_dimension ("345", dim);
   EXPECT_EQ (num_tensors, 1);
-  EXPECT_EQ (rank[0], 1);
   EXPECT_EQ (dim[0][0], 345);
   EXPECT_EQ (dim[0][1], 1);
   EXPECT_EQ (dim[0][2], 1);
index 082709a..e74d7d6 100644 (file)
@@ -704,11 +704,11 @@ TEST (tensor_stream_test, video_rgb)
 
   /** check tensor config for video */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 3);
-  EXPECT_EQ (g_test_data.config.dimension[1], 160);
-  EXPECT_EQ (g_test_data.config.dimension[2], 120);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 3);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 160);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 30);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -741,11 +741,11 @@ TEST (tensor_stream_test, video_rgb_padding)
 
   /** check tensor config for video */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 3);
-  EXPECT_EQ (g_test_data.config.dimension[1], 162);
-  EXPECT_EQ (g_test_data.config.dimension[2], 120);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 3);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 162);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 30);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -778,11 +778,11 @@ TEST (tensor_stream_test, video_rgb_3f)
 
   /** check tensor config for video */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 3);
-  EXPECT_EQ (g_test_data.config.dimension[1], 160);
-  EXPECT_EQ (g_test_data.config.dimension[2], 120);
-  EXPECT_EQ (g_test_data.config.dimension[3], 3);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 3);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 160);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 3);
   EXPECT_EQ (g_test_data.config.rate_n, 30);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -815,11 +815,11 @@ TEST (tensor_stream_test, video_bgrx)
 
   /** check tensor config for video */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 4);
-  EXPECT_EQ (g_test_data.config.dimension[1], 160);
-  EXPECT_EQ (g_test_data.config.dimension[2], 120);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 4);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 160);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 30);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -852,11 +852,11 @@ TEST (tensor_stream_test, video_bgrx_2f)
 
   /** check tensor config for video */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 4);
-  EXPECT_EQ (g_test_data.config.dimension[1], 160);
-  EXPECT_EQ (g_test_data.config.dimension[2], 120);
-  EXPECT_EQ (g_test_data.config.dimension[3], 2);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 4);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 160);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 2);
   EXPECT_EQ (g_test_data.config.rate_n, 30);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -889,11 +889,11 @@ TEST (tensor_stream_test, video_gray8)
 
   /** check tensor config for video */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 1);
-  EXPECT_EQ (g_test_data.config.dimension[1], 160);
-  EXPECT_EQ (g_test_data.config.dimension[2], 120);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 160);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 30);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -926,11 +926,11 @@ TEST (tensor_stream_test, video_gray8_padding)
 
   /** check tensor config for video */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 1);
-  EXPECT_EQ (g_test_data.config.dimension[1], 162);
-  EXPECT_EQ (g_test_data.config.dimension[2], 120);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 162);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 30);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -963,11 +963,11 @@ TEST (tensor_stream_test, video_gray8_3f_padding)
 
   /** check tensor config for video */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 1);
-  EXPECT_EQ (g_test_data.config.dimension[1], 162);
-  EXPECT_EQ (g_test_data.config.dimension[2], 120);
-  EXPECT_EQ (g_test_data.config.dimension[3], 3);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 162);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 3);
   EXPECT_EQ (g_test_data.config.rate_n, 30);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1000,11 +1000,11 @@ TEST (tensor_stream_test, audio_s8)
 
   /** check tensor config for audio */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_INT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 1);
-  EXPECT_EQ (g_test_data.config.dimension[1], 500);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_INT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 500);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 16000);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1037,11 +1037,11 @@ TEST (tensor_stream_test, audio_u8_100F)
 
   /** check tensor config for audio */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 1);
-  EXPECT_EQ (g_test_data.config.dimension[1], 100);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 100);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 16000);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1074,11 +1074,11 @@ TEST (tensor_stream_test, audio_s16)
 
   /** check tensor config for audio */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_INT16);
-  EXPECT_EQ (g_test_data.config.dimension[0], 1);
-  EXPECT_EQ (g_test_data.config.dimension[1], 500);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_INT16);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 500);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 16000);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1111,11 +1111,11 @@ TEST (tensor_stream_test, audio_u16_1000f)
 
   /** check tensor config for audio */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT16);
-  EXPECT_EQ (g_test_data.config.dimension[0], 1);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1000);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT16);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1000);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 16000);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1151,11 +1151,11 @@ TEST (tensor_stream_test, text_utf8)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_INT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_INT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1191,11 +1191,11 @@ TEST (tensor_stream_test, text_utf8_3f)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_INT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 3);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_INT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 3);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1233,11 +1233,11 @@ TEST (tensor_stream_test, typecast_int32)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, t_type);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, t_type);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1275,11 +1275,11 @@ TEST (tensor_stream_test, typecast_uint32)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, t_type);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, t_type);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1317,11 +1317,11 @@ TEST (tensor_stream_test, typecast_int16)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, t_type);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, t_type);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1359,11 +1359,11 @@ TEST (tensor_stream_test, typecast_uint16)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, t_type);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, t_type);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1401,11 +1401,11 @@ TEST (tensor_stream_test, typecast_float64)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, t_type);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, t_type);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1443,11 +1443,11 @@ TEST (tensor_stream_test, typecast_float32)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, t_type);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, t_type);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1485,11 +1485,11 @@ TEST (tensor_stream_test, typecast_int64)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, t_type);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, t_type);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1527,11 +1527,11 @@ TEST (tensor_stream_test, typecast_uint64)
 
   /** check tensor config for text */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, t_type);
-  EXPECT_EQ (g_test_data.config.dimension[0], GST_TENSOR_STRING_SIZE);
-  EXPECT_EQ (g_test_data.config.dimension[1], 1);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, t_type);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], GST_TENSOR_STRING_SIZE);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 0);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1564,11 +1564,11 @@ TEST (tensor_stream_test, video_aggregate)
 
   /** check tensor config for video */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT8);
-  EXPECT_EQ (g_test_data.config.dimension[0], 3);
-  EXPECT_EQ (g_test_data.config.dimension[1], 160);
-  EXPECT_EQ (g_test_data.config.dimension[2], 120);
-  EXPECT_EQ (g_test_data.config.dimension[3], 10);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT8);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 3);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 160);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 120);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 10);
   EXPECT_EQ (g_test_data.config.rate_n, 30);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1601,11 +1601,11 @@ TEST (tensor_stream_test, audio_aggregate_s16)
 
   /** check tensor config for audio */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_INT16);
-  EXPECT_EQ (g_test_data.config.dimension[0], 1);
-  EXPECT_EQ (g_test_data.config.dimension[1], 2000);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_INT16);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 2000);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 16000);
   EXPECT_EQ (g_test_data.config.rate_d, 1);
 
@@ -1638,11 +1638,11 @@ TEST (tensor_stream_test, audio_aggregate_u16)
 
   /** check tensor config for audio */
   EXPECT_TRUE (gst_tensor_config_validate (&g_test_data.config));
-  EXPECT_EQ (g_test_data.config.type, _NNS_UINT16);
-  EXPECT_EQ (g_test_data.config.dimension[0], 1);
-  EXPECT_EQ (g_test_data.config.dimension[1], 100);
-  EXPECT_EQ (g_test_data.config.dimension[2], 1);
-  EXPECT_EQ (g_test_data.config.dimension[3], 1);
+  EXPECT_EQ (g_test_data.config.info.type, _NNS_UINT16);
+  EXPECT_EQ (g_test_data.config.info.dimension[0], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[1], 100);
+  EXPECT_EQ (g_test_data.config.info.dimension[2], 1);
+  EXPECT_EQ (g_test_data.config.info.dimension[3], 1);
   EXPECT_EQ (g_test_data.config.rate_n, 16000);
   EXPECT_EQ (g_test_data.config.rate_d, 1);