[Api/Single] add new function about property
authorJaeyun <jy1210.jung@samsung.com>
Thu, 6 Feb 2020 04:57:58 +0000 (13:57 +0900)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Tue, 11 Feb 2020 05:58:32 +0000 (21:58 -0800)
ACR required.
Add new function to set/get the property of tensor-filter in single-shot.

With this function, we can support the tensor layout in single-shot instance.

Signed-off-by: Jaeyun <jy1210.jung@samsung.com>
api/capi/include/nnstreamer-single.h
api/capi/src/nnstreamer-capi-single.c
gst/nnstreamer/tensor_filter/tensor_filter_common.c

index 4fbb7e5..7b56cc1 100644 (file)
@@ -186,6 +186,33 @@ int ml_single_set_input_info (ml_single_h single, const ml_tensors_info_h info);
 int ml_single_set_timeout (ml_single_h single, unsigned int timeout);
 
 /**
+ * @brief Sets the property value for the given model.
+ * @details Note that a model/framework may not support to change the property after opening the model.
+ * @since_tizen 6.0
+ * @param[in] single The model handle.
+ * @param[in] name The property name.
+ * @param[in] value The property value.
+ * @return @c 0 on success. Otherwise a negative error value.
+ * @retval #ML_ERROR_NONE Successful
+ * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
+ * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
+ */
+int ml_single_set_property (ml_single_h single, const char *name, const char *value);
+
+/**
+ * @brief Gets the property value for the given model.
+ * @since_tizen 6.0
+ * @param[in] single The model handle.
+ * @param[in] name The property name.
+ * @param[out] value The property value. The caller is responsible for freeing the value using g_free().
+ * @return @c 0 on success. Otherwise a negative error value.
+ * @retval #ML_ERROR_NONE Successful
+ * @retval #ML_ERROR_NOT_SUPPORTED Not supported.
+ * @retval #ML_ERROR_INVALID_PARAMETER Fail. The parameter is invalid.
+ */
+int ml_single_get_property (ml_single_h single, const char *name, char **value);
+
+/**
  * @}
  */
 #ifdef __cplusplus
index f436865..1d9fbe9 100644 (file)
@@ -956,3 +956,125 @@ exit:
 
   return status;
 }
+
+/**
+ * @brief Sets the property value for the given model.
+ */
+int
+ml_single_set_property (ml_single_h single, const char *name, const char *value)
+{
+  ml_single *single_h;
+  int status = ML_ERROR_NONE;
+  char *old_value = NULL;
+
+  check_feature_state ();
+
+  if (!single || !name || !value)
+    return ML_ERROR_INVALID_PARAMETER;
+
+  /* get old value, also check the property is updatable. */
+  status = ml_single_get_property (single, name, &old_value);
+  if (status != ML_ERROR_NONE)
+    return status;
+
+  /* if sets same value, do not change. */
+  if (g_ascii_strcasecmp (old_value, value) == 0) {
+    g_free (old_value);
+    return ML_ERROR_NONE;
+  }
+
+  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 0);
+
+  /* update property */
+  if (g_str_equal (name, "is-updatable")) {
+    /* boolean */
+    if (g_ascii_strcasecmp (value, "true") == 0) {
+      if (g_ascii_strcasecmp (old_value, "true") != 0)
+        g_object_set (G_OBJECT (single_h->filter), name, (gboolean) TRUE, NULL);
+    } else if (g_ascii_strcasecmp (value, "false") == 0) {
+      if (g_ascii_strcasecmp (old_value, "false") != 0)
+        g_object_set (G_OBJECT (single_h->filter), name, (gboolean) FALSE, NULL);
+    } else {
+      ml_loge ("The property value (%s) is not available.", value);
+      status = ML_ERROR_INVALID_PARAMETER;
+    }
+  } else if (g_str_equal (name, "input") || g_str_equal (name, "inputtype") || g_str_equal (name, "inputname") ||
+      g_str_equal (name, "output") || g_str_equal (name, "outputtype") || g_str_equal (name, "outputname")) {
+    GstTensorsInfo gst_info;
+    gboolean is_input = g_str_has_prefix (name, "input");
+    guint num;
+
+    ml_single_get_gst_info (single_h, is_input, &gst_info);
+
+    if (g_str_has_suffix (name, "type"))
+      num = gst_tensors_info_parse_types_string (&gst_info, value);
+    else if (g_str_has_suffix (name, "name"))
+      num = gst_tensors_info_parse_names_string (&gst_info, value);
+    else
+      num = gst_tensors_info_parse_dimensions_string (&gst_info, value);
+
+    if (num == gst_info.num_tensors) {
+      ml_tensors_info_h ml_info;
+
+      ml_tensors_info_create_from_gst (&ml_info, &gst_info);
+
+      /* change configuration */
+      status = ml_single_set_gst_info (single_h, ml_info);
+
+      ml_tensors_info_destroy (ml_info);
+    } else {
+      ml_loge ("The property value (%s) is not available.", value);
+      status = ML_ERROR_INVALID_PARAMETER;
+    }
+
+    gst_tensors_info_free (&gst_info);
+  } else {
+    g_object_set (G_OBJECT (single_h->filter), name, value, NULL);
+  }
+
+  ML_SINGLE_HANDLE_UNLOCK (single_h);
+
+  g_free (old_value);
+  return status;
+}
+
+/**
+ * @brief Gets the property value for the given model.
+ */
+int
+ml_single_get_property (ml_single_h single, const char *name, char **value)
+{
+  ml_single *single_h;
+  int status = ML_ERROR_NONE;
+
+  check_feature_state ();
+
+  if (!single || !name || !value)
+    return ML_ERROR_INVALID_PARAMETER;
+
+  /* init null */
+  *value = NULL;
+
+  ML_SINGLE_GET_VALID_HANDLE_LOCKED (single_h, single, 0);
+
+  if (g_str_equal (name, "input") || g_str_equal (name, "inputtype") ||
+      g_str_equal (name, "inputname") || g_str_equal (name, "inputlayout") ||
+      g_str_equal (name, "output") || g_str_equal (name, "outputtype") ||
+      g_str_equal (name, "outputname") || g_str_equal (name, "outputlayout") ||
+      g_str_equal (name, "accelerator")) {
+    /* string */
+    g_object_get (G_OBJECT (single_h->filter), name, value, NULL);
+  } else if (g_str_equal (name, "is-updatable")) {
+    gboolean bool_value = FALSE;
+
+    /* boolean */
+    g_object_get (G_OBJECT (single_h->filter), name, &bool_value, NULL);
+    *value = (bool_value) ? g_strdup ("true") : g_strdup ("false");
+  } else {
+    ml_loge ("The property %s is not available.", name);
+    status = ML_ERROR_INVALID_PARAMETER;
+  }
+
+  ML_SINGLE_HANDLE_UNLOCK (single_h);
+  return status;
+}
index e0a4abc..f521215 100644 (file)
@@ -811,15 +811,14 @@ gst_tensor_filter_common_set_property (GstTensorFilterPrivate * priv,
     }
     case PROP_INPUTLAYOUT:
     {
-      /** TODO: allow updating the data layout after fw has been opened */
       guint num_layouts;
-
+#if 0 /** @todo allow updating the data layout after fw has been opened */
       if (priv->prop.fw_opened == TRUE) {
         g_warning
             ("Updating data layout is not supported after opened framework.");
         break;
       }
-
+#endif
       num_layouts = gst_tensors_parse_layouts_string (prop->input_layout,
           g_value_get_string (value));
 
@@ -833,15 +832,14 @@ gst_tensor_filter_common_set_property (GstTensorFilterPrivate * priv,
     }
     case PROP_OUTPUTLAYOUT:
     {
-      /** TODO: allow updating the data layout after fw has been opened */
       guint num_layouts;
-
+#if 0 /** @todo allow updating the data layout after fw has been opened */
       if (priv->prop.fw_opened == TRUE) {
         g_warning
             ("Updating data layout is not supported after opened framework.");
         break;
       }
-
+#endif
       num_layouts = gst_tensors_parse_layouts_string (prop->output_layout,
           g_value_get_string (value));
 
@@ -1090,6 +1088,7 @@ gst_tensor_filter_common_close_fw (GstTensorFilterPrivate * priv)
     if (priv->fw && priv->fw->close) {
       priv->fw->close (&priv->prop, &priv->privateData);
     }
+    priv->prop.input_configured = priv->prop.output_configured = FALSE;
     priv->prop.fw_opened = FALSE;
     g_free_const (priv->prop.fwname);
     priv->prop.fwname = NULL;