From eb81d0d5d82754c9d776650321ae3e9d94b517ad Mon Sep 17 00:00:00 2001 From: Jaeyun Date: Thu, 6 Feb 2020 13:57:58 +0900 Subject: [PATCH] [Api/Single] add new function about property 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 --- api/capi/include/nnstreamer-single.h | 27 +++++ api/capi/src/nnstreamer-capi-single.c | 122 +++++++++++++++++++++ .../tensor_filter/tensor_filter_common.c | 11 +- 3 files changed, 154 insertions(+), 6 deletions(-) diff --git a/api/capi/include/nnstreamer-single.h b/api/capi/include/nnstreamer-single.h index 4fbb7e5..7b56cc1 100644 --- a/api/capi/include/nnstreamer-single.h +++ b/api/capi/include/nnstreamer-single.h @@ -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 diff --git a/api/capi/src/nnstreamer-capi-single.c b/api/capi/src/nnstreamer-capi-single.c index f436865..1d9fbe9 100644 --- a/api/capi/src/nnstreamer-capi-single.c +++ b/api/capi/src/nnstreamer-capi-single.c @@ -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; +} diff --git a/gst/nnstreamer/tensor_filter/tensor_filter_common.c b/gst/nnstreamer/tensor_filter/tensor_filter_common.c index e0a4abc..f521215 100644 --- a/gst/nnstreamer/tensor_filter/tensor_filter_common.c +++ b/gst/nnstreamer/tensor_filter/tensor_filter_common.c @@ -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; -- 2.7.4