Add new function to set the timeout to wait for the output.
The function try_pull is supported from gst 1.10, check gst version and return error code if is not supported.
Signed-off-by: Jaeyun Jung <jy1210.jung@samsung.com>
* @brief Invokes the model with the given input data.
* @details Even if the model has flexible input data dimensions,
* input data frames of an instance of a model should share the same dimension.
- * Note that this has a timeout of 3 seconds.
+ * Note that this has a default timeout of 3 seconds. If an application wants to change the time to wait for an output, set the timeout using ml_single_set_timeout().
* @since_tizen 5.5
* @param[in] single The model handle to be inferred.
* @param[in] input The input data to be inferred.
int ml_single_get_output_info (ml_single_h single, ml_tensors_info_h *info);
/**
+ * @brief Sets the maximum amount of time to wait for an output, in milliseconds.
+ * @since_tizen 5.5
+ * @param[in] single The model handle.
+ * @param[in] timeout The time to wait for an output.
+ * @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_timeout (ml_single_h single, unsigned int timeout);
+
+/**
* @}
*/
#ifdef __cplusplus
#include "nnstreamer-capi-private.h"
#include "nnstreamer_plugin_api.h"
+#undef ML_SINGLE_SUPPORT_TIMEOUT
+#if (GST_VERSION_MAJOR > 1 || (GST_VERSION_MAJOR == 1 && GST_VERSION_MINOR >= 10))
+#define ML_SINGLE_SUPPORT_TIMEOUT
+#endif
+
+/**
+ * @brief Default time to wait for an output in appsink (3 seconds).
+ */
+#define SINGLE_DEFAULT_TIMEOUT 3000
+
typedef struct
{
ml_pipeline_h pipe;
ml_tensors_info_s in_info;
ml_tensors_info_s out_info;
+
+ guint timeout; /* milliseconds */
} ml_single;
/**
single_h->src = appsrc;
single_h->sink = appsink;
single_h->filter = filter;
+ single_h->timeout = SINGLE_DEFAULT_TIMEOUT;
ml_tensors_info_initialize (&single_h->in_info);
ml_tensors_info_initialize (&single_h->out_info);
}
/* Try to get the result */
-#if (GST_VERSION_MAJOR > 1 || (GST_VERSION_MAJOR == 1 && GST_VERSION_MINOR >= 10))
+#ifdef ML_SINGLE_SUPPORT_TIMEOUT
/* gst_app_sink_try_pull_sample() is available at gstreamer-1.10 */
sample =
- gst_app_sink_try_pull_sample (GST_APP_SINK (single_h->sink), GST_SECOND * 3);
+ gst_app_sink_try_pull_sample (GST_APP_SINK (single_h->sink), GST_MSECOND * single_h->timeout);
#else
sample = gst_app_sink_pull_sample (GST_APP_SINK (single_h->sink));
#endif
gst_tensors_info_free (&gst_info);
return ML_ERROR_NONE;
}
+
+/**
+ * @brief Sets the maximum amount of time to wait for an output, in milliseconds.
+ */
+int
+ml_single_set_timeout (ml_single_h single, unsigned int timeout)
+{
+#ifdef ML_SINGLE_SUPPORT_TIMEOUT
+ ml_single *single_h;
+
+ check_feature_state ();
+
+ if (!single || timeout == 0)
+ return ML_ERROR_INVALID_PARAMETER;
+
+ single_h = (ml_single *) single;
+
+ single_h->timeout = (guint) timeout;
+ return ML_ERROR_NONE;
+#else
+ return ML_ERROR_NOT_SUPPORTED;
+#endif
+}
ml_tensors_info_destroy (in_info);
ml_tensors_info_destroy (out_info);
}
+
+/**
+ * @brief Test NNStreamer single shot (tensorflow-lite)
+ * @detail Testcase with timeout.
+ */
+TEST (nnstreamer_capi_singleshot, invoke_timeout)
+{
+ ml_single_h single;
+ int status;
+
+ const gchar *root_path = g_getenv ("NNSTREAMER_BUILD_ROOT_PATH");
+ gchar *test_model;
+
+ /* supposed to run test in build directory */
+ if (root_path == NULL)
+ root_path = "..";
+
+ test_model = g_build_filename (root_path, "tests", "test_models", "models",
+ "mobilenet_v1_1.0_224_quant.tflite", NULL);
+ ASSERT_TRUE (g_file_test (test_model, G_FILE_TEST_EXISTS));
+
+ status = ml_single_open (&single, test_model, NULL, NULL,
+ ML_NNFW_TYPE_TENSORFLOW_LITE, ML_NNFW_HW_ANY);
+ EXPECT_EQ (status, ML_ERROR_NONE);
+
+ /* set timeout 5 ms */
+ status = ml_single_set_timeout (single, 5);
+ /* test timeout if supported (gstreamer ver >= 1.10) */
+ if (status == ML_ERROR_NONE) {
+ ml_tensors_info_h in_info;
+ ml_tensors_data_h input, output;
+ ml_tensor_dimension in_dim;
+
+ ml_tensors_info_create (&in_info);
+
+ in_dim[0] = 3;
+ in_dim[1] = 224;
+ in_dim[2] = 224;
+ in_dim[3] = 1;
+ ml_tensors_info_set_count (in_info, 1);
+ ml_tensors_info_set_tensor_type (in_info, 0, ML_TENSOR_TYPE_UINT8);
+ ml_tensors_info_set_tensor_dimension (in_info, 0, in_dim);
+
+ input = output = NULL;
+
+ /* generate dummy data */
+ status = ml_tensors_data_create (in_info, &input);
+ EXPECT_EQ (status, ML_ERROR_NONE);
+ EXPECT_TRUE (input != NULL);
+
+ status = ml_single_invoke (single, input, &output);
+ EXPECT_EQ (status, ML_ERROR_TIMED_OUT);
+ EXPECT_TRUE (output == NULL);
+
+ ml_tensors_data_destroy (output);
+ ml_tensors_data_destroy (input);
+ ml_tensors_info_destroy (in_info);
+ }
+
+ status = ml_single_close (single);
+ EXPECT_EQ (status, ML_ERROR_NONE);
+
+ g_free (test_model);
+}
#endif /* ENABLE_TENSORFLOW_LITE */
/**