[ml-service] Add service APIs using pipelind d-bus interface
authorYongjoo Ahn <yongjoo1.ahn@samsung.com>
Fri, 8 Jul 2022 06:01:22 +0000 (15:01 +0900)
committerjaeyun-jung <39614140+jaeyun-jung@users.noreply.github.com>
Fri, 19 Aug 2022 06:32:22 +0000 (15:32 +0900)
- Implement some service APIs using pipeline d-bus interface

Signed-off-by: Yongjoo Ahn <yongjoo1.ahn@samsung.com>
c/meson.build
c/src/ml-api-service-agent-client.c [new file with mode: 0644]
meson.build

index 23adfbd..38991cd 100644 (file)
@@ -17,6 +17,10 @@ nns_capi_common_srcs += join_paths(meson.current_source_dir(), 'src', 'ml-api-in
 nns_capi_single_srcs += join_paths(meson.current_source_dir(), 'src', 'ml-api-inference-single.c')
 nns_capi_pipeline_srcs += join_paths(meson.current_source_dir(), 'src', 'ml-api-inference-pipeline.c')
 
+if get_option('enable-machine-learning-agent')
+  nns_capi_service_srcs += join_paths(meson.current_source_dir(), 'src', 'ml-api-service-agent-client.c')
+endif
+
 if get_option('enable-tizen')
   if get_option('enable-tizen-feature-check')
     nns_capi_common_srcs += join_paths(meson.current_source_dir(), 'src', 'ml-api-common-tizen-feature-check.c')
@@ -43,7 +47,7 @@ endif
 
 # Dependencies
 nns_capi_common_deps = [glib_dep, gmodule_dep, nnstreamer_single_dep]
-nns_capi_deps = [nnstreamer_dep, glib_dep, gmodule_dep, gst_dep, gst_app_dep, leveldb_dep]
+nns_capi_deps = [nnstreamer_dep, glib_dep, gmodule_dep, gio_dep, gst_dep, gst_app_dep, leveldb_dep]
 
 if (get_option('enable-tizen'))
   message('C-API is in Tizen mode')
@@ -97,6 +101,9 @@ if (get_option('enable-tizen'))
   nns_capi_deps += [dependency('dlog')]
 endif
 
+if (get_option('enable-machine-learning-agent'))
+  nns_capi_deps += [gio_unix_dep, gdbus_gen_header_dep]
+endif
 
 # Single-shot API.
 nns_capi_single_shared_lib = shared_library ('capi-ml-inference-single',
diff --git a/c/src/ml-api-service-agent-client.c b/c/src/ml-api-service-agent-client.c
new file mode 100644 (file)
index 0000000..bb5cc4c
--- /dev/null
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
+ *
+ * @file ml-api-service-agent-client.c
+ * @date 20 Jul 2022
+ * @brief agent (dbus) implementation of NNStreamer/Service C-API
+ * @see https://github.com/nnstreamer/nnstreamer
+ * @author Yongjoo Ahn <yongjoo1.ahn@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <gio/gio.h>
+
+#include "ml-api-internal.h"
+#include "ml-api-service.h"
+#include "pipeline-dbus.h"
+
+/**
+ * @brief Structure for ml_service_h
+ */
+typedef struct
+{
+  gint64 id;
+  gchar *service_name;
+} ml_service_s;
+
+/**
+ * @brief Internal function to get proxy of the pipeline d-bus interface
+ */
+static MachinelearningServicePipeline *
+_get_proxy_new_for_bus_sync (void)
+{
+  /** @todo deal with GError */
+  return
+      machinelearning_service_pipeline_proxy_new_for_bus_sync
+      (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE,
+      "org.tizen.machinelearning.service",
+      "/Org/Tizen/MachineLearning/Service/Pipeline", NULL, NULL);
+}
+
+int
+ml_service_launch_pipeline (const char *name, ml_service_h * h)
+{
+  ml_service_s *server;
+  gint out_return_code;
+  gint64 out_id;
+  MachinelearningServicePipeline *mlsp;
+
+  check_feature_state (ML_FEATURE_SERVICE);
+
+  if (!h)
+    _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+        "The parameter, 'h' is NULL. It should be a valid ml_service_h");
+
+  server = g_new0 (ml_service_s, 1);
+
+  if (server == NULL)
+    _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY,
+        "Failed to allocate memory for the service_server. Out of memory?");
+
+
+  mlsp = _get_proxy_new_for_bus_sync ();
+  machinelearning_service_pipeline_call_launch_pipeline_sync (mlsp, name,
+      &out_return_code, &out_id, NULL, NULL);
+
+  if (out_return_code != 0) {
+    g_free (server);
+    g_object_unref (mlsp);
+    _ml_error_report_return (out_return_code,
+        "Failed to launch pipeline, please check its integrity.");
+  }
+
+  server->id = out_id;
+  server->service_name = g_strdup (name);
+  *h = (ml_service_h *) server;
+
+  g_object_unref (mlsp);
+
+  return ML_ERROR_NONE;
+}
+
+/**
+ * @brief Start the pipeline of given ml_service_h
+ */
+int
+ml_service_start_pipeline (ml_service_h h)
+{
+  gint out_result;
+  ml_service_s *server = (ml_service_s *) h;
+  MachinelearningServicePipeline *mlsp;
+
+  check_feature_state (ML_FEATURE_SERVICE);
+
+  if (!h)
+    _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+        "The parameter, 'h' is NULL. It should be a valid ml_service_h");
+
+  mlsp = _get_proxy_new_for_bus_sync ();
+  machinelearning_service_pipeline_call_start_pipeline_sync (mlsp, server->id,
+      &out_result, NULL, NULL);
+
+  g_object_unref (mlsp);
+
+  return ML_ERROR_NONE;
+}
+
+/**
+ * @brief Stop the pipeline of given ml_service_h
+ */
+int
+ml_service_stop_pipeline (ml_service_h h)
+{
+  gint out_result;
+  ml_service_s *server = (ml_service_s *) h;
+  MachinelearningServicePipeline *mlsp;
+
+  check_feature_state (ML_FEATURE_SERVICE);
+
+  if (!h)
+    _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+        "The parameter, 'h' is NULL. It should be a valid ml_service_h");
+
+  mlsp = _get_proxy_new_for_bus_sync ();
+  machinelearning_service_pipeline_call_stop_pipeline_sync (mlsp, server->id,
+      &out_result, NULL, NULL);
+
+  g_object_unref (mlsp);
+
+  return ML_ERROR_NONE;
+}
+
+/**
+ * @brief Destroy the pipeline of given ml_service_h
+ */
+int
+ml_service_destroy_pipeline (ml_service_h h)
+{
+  gint out_result;
+  ml_service_s *server = (ml_service_s *) h;
+  MachinelearningServicePipeline *mlsp;
+
+  check_feature_state (ML_FEATURE_SERVICE);
+
+  if (!h)
+    _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+        "The parameter, 'h' is NULL. It should be a valid ml_service_h");
+
+  mlsp = _get_proxy_new_for_bus_sync ();
+  machinelearning_service_pipeline_call_destroy_pipeline_sync (mlsp, server->id,
+      &out_result, NULL, NULL);
+
+  g_object_unref (mlsp);
+
+  g_free (server->service_name);
+  g_free (server);
+  return ML_ERROR_NONE;
+}
+
+/**
+ * @brief Return state of given ml_service_h
+ */
+int
+ml_service_getstate_pipeline (ml_service_h h, ml_pipeline_state_e * state)
+{
+  gint out_result;
+  gint _state;
+  ml_service_s *server = (ml_service_s *) h;
+  MachinelearningServicePipeline *mlsp;
+
+  check_feature_state (ML_FEATURE_SERVICE);
+
+  if (!h)
+    _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+        "The parameter, 'h' is NULL. It should be a valid ml_service_h");
+
+  mlsp = _get_proxy_new_for_bus_sync ();
+  machinelearning_service_pipeline_call_get_state_sync (mlsp, server->id,
+      &out_result, &_state, NULL, NULL);
+
+  *state = (ml_pipeline_state_e) _state;
+
+  g_object_unref (mlsp);
+
+  return ML_ERROR_NONE;
+}
+
+/**
+ * @brief Return the pipeline description of given ml_service_h
+ */
+int
+ml_service_getdesc_pipeline (ml_service_h h, char **desc)
+{
+  gint out_result;
+  ml_service_s *server = (ml_service_s *) h;
+  MachinelearningServicePipeline *mlsp;
+
+  check_feature_state (ML_FEATURE_SERVICE);
+
+  if (!h)
+    _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
+        "The parameter, 'h' is NULL. It should be a valid ml_service_h");
+
+  mlsp = _get_proxy_new_for_bus_sync ();
+  machinelearning_service_pipeline_call_get_description_sync (mlsp, server->id,
+      &out_result, desc, NULL, NULL);
+
+  g_object_unref (mlsp);
+
+  return ML_ERROR_NONE;
+}
index b9dadc3..458bf09 100644 (file)
@@ -155,13 +155,13 @@ api_conf.set('EXEC_PREFIX', api_install_bindir)
 api_conf.set('LIB_INSTALL_DIR', api_install_libdir)
 api_conf.set('INCLUDE_INSTALL_DIR', api_install_includedir)
 
-# Build C-API
-subdir('c')
-
 if get_option('enable-machine-learning-agent')
   subdir('daemon')
 endif
 
+# Build C-API
+subdir('c')
+
 # Build JNI wrapper when developer sets java-home
 # (e.g., -Djava-home=$JAVA_HOME from environment variables)
 java_home = get_option('java-home').strip()