[ML][pipeline] Implement Pipeline::getValve() 02/251902/5
authorPawel Wasowski <p.wasowski2@samsung.com>
Wed, 20 Jan 2021 15:49:03 +0000 (16:49 +0100)
committerPawel Wasowski <p.wasowski2@samsung.com>
Fri, 22 Jan 2021 02:05:47 +0000 (03:05 +0100)
ACR: TWDAPI-274

[Verification] Tested in Chrome DevTools with the below snippets, works
fine.

var pipeline_def = "videotestsrc is-live=true ! videoconvert ! videoscale"
                   + " ! video/x-raw,format=RGBx,width=16,height=16,framerate=10/1"
                   + " ! tensor_converter ! valve name=valve1 ! fakesink";

var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
                                      function(state) {console.log(state);});

pipeline.getValve('valve1')
// alve {name: "valve1", _pipeline_id: 1}

pipeline.getValve('valve_XXX')
// WebAPIException {code: 0, name: "InvalidValuesError", ...

pipeline.getValve()
// WebAPIException {code: 0, name: "InvalidValuesError", ...

Change-Id: Id11414f80c42a9879532dfc1c651f766c4f12834
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
src/ml/js/ml_pipeline.js
src/ml/ml.gyp
src/ml/ml_instance.cc
src/ml/ml_instance.h
src/ml/ml_pipeline.cc
src/ml/ml_pipeline.h
src/ml/ml_pipeline_manager.cc
src/ml/ml_pipeline_manager.h
src/ml/ml_pipeline_valve.cc [new file with mode: 0644]
src/ml/ml_pipeline_valve.h [new file with mode: 0644]

index 6ca93666c882e5a9848fbf6f4832782cbc3c6bc7..ad745f18e0d563d41c536c05a2c3c9e527fa043d 100755 (executable)
@@ -261,7 +261,48 @@ Pipeline.prototype.getSwitch = function() {
 //Pipeline::getSwitch() end
 
 //Pipeline::getValve() begin
+function Valve(name, pipeline_id) {
+    Object.defineProperties(this, {
+        name: {
+            enumerable: true,
+            value: name
+        },
+        _pipeline_id: {
+            value: pipeline_id
+        }
+    });
+}
 
+var ValidPipelineGetValveExceptions = [
+    'InvalidValuesError',
+    'NotFoundError',
+    'NotSupportedError',
+    'AbortError'
+];
+Pipeline.prototype.getValve = function() {
+    var args = validator_.validateArgs(arguments, [
+        {
+            name: 'name',
+            type: validator_.Types.STRING
+        }
+    ]);
+
+    var nativeArgs = {
+        name: args.name,
+        id: this._id
+    };
+
+    var result = native_.callSync('MLPipelineGetValve', nativeArgs);
+    if (native_.isFailure(result)) {
+        throw native_.getErrorObjectAndValidate(
+            result,
+            ValidPipelineGetValveExceptions,
+            AbortError
+        );
+    }
+
+    return new Valve(nativeArgs.name, this._id);
+};
 //Pipeline::getValve() end
 
 //Pipeline::registerSinkCallback() begin
index a8fb82f2dddfe7814d3a015bfc5b546a74728ee4..cc6c5b81cf053c26f2bb32195f760fa5c8e255a1 100644 (file)
@@ -24,7 +24,8 @@
         'ml_pipeline_switch.cc',
         'ml_pipeline_switch.h',
         #TODO pipeline Source
-        #TODO pipeline Valve
+        'ml_pipeline_valve.h',
+        'ml_pipeline_valve.cc',
         'ml_tensors_info_manager.cc',
         'ml_tensors_info_manager.h',
         #TODO single SingleShotManager
index 1c7edcfefad00f40db4779736c953463d7540e3c..01837ef4d8e26633d1b969b4f28f7381ac3ac7e8 100644 (file)
@@ -113,6 +113,7 @@ MlInstance::MlInstance() : pipeline_manager_{this} {
   REGISTER_METHOD(MLPipelineGetSwitch);
   REGISTER_METHOD(MLPipelineSwitchGetPadList);
   REGISTER_METHOD(MLPipelineSwitchSelect);
+  REGISTER_METHOD(MLPipelineGetValve);
 // Pipeline API end
 
 #undef REGISTER_METHOD
@@ -760,7 +761,23 @@ void MlInstance::MLPipelineGetSwitch(const picojson::value& args, picojson::obje
 // Pipeline::getSwitch() end
 
 // Pipeline::getValve() begin
+void MlInstance::MLPipelineGetValve(const picojson::value& args, picojson::object& out) {
+  ScopeLogger("args: %s", args.serialize().c_str());
+
+  CHECK_ARGS(args, kId, double, out);
+  CHECK_ARGS(args, kName, std::string, out);
+
+  auto name = args.get(kName).get<std::string>();
+  auto pipeline_id = args.get(kId).get<double>();
 
+  auto ret = pipeline_manager_.GetValve(name, pipeline_id);
+  if (!ret) {
+    LogAndReportError(ret, &out);
+    return;
+  }
+
+  ReportSuccess(out);
+}
 // Pipeline::getValve() end
 
 // Pipeline::registerSinkCallback() begin
index 31ccde53b6a48a1da5a56683ceb02d53b00a7e85..a79076a59253b48f5d7d7c3fc1de77e45b885b22 100644 (file)
@@ -102,7 +102,7 @@ class MlInstance : public common::ParsedInstance {
   // Pipeline::getSwitch() end
 
   // Pipeline::getValve() begin
-
+  void MLPipelineGetValve(const picojson::value& args, picojson::object& out);
   // Pipeline::getValve() end
 
   // Pipeline::registerSinkCallback() begin
index ded7436876713e5188242af794955bad631dd2c4..11ec31a380f4a70cb41a7174be958f9d93541c70 100644 (file)
@@ -194,6 +194,8 @@ PlatformResult Pipeline::Dispose() {
 
   node_info_.clear();
 
+  valves_.clear();
+
   auto ret = ml_pipeline_destroy(pipeline_);
   if (ML_ERROR_NONE != ret) {
     LoggerE("ml_pipeline_destroy() failed: [%d] (%s)", ret, get_error_message(ret));
@@ -257,7 +259,23 @@ PlatformResult Pipeline::GetSwitch(const std::string& name, std::string* type) {
 // Pipeline::getSwitch() end
 
 // Pipeline::getValve() begin
+PlatformResult Pipeline::GetValve(const std::string& name) {
+  ScopeLogger("id: [%d], name: [%s]", id_, name.c_str());
+
+  auto valve_it = valves_.find(name);
+  if (valves_.end() != valve_it) {
+    LoggerD("Valve [%s] found", name.c_str());
+    return PlatformResult{};
+  }
+  LoggerD("Creating [%s] Valve", name.c_str());
 
+  std::unique_ptr<Valve> valve_ptr;
+  auto ret = Valve::CreateValve(name, pipeline_, &valve_ptr);
+  if (ret) {
+    valves_.insert({name, std::move(valve_ptr)});
+  }
+  return ret;
+}
 // Pipeline::getValve() end
 
 // Pipeline::registerSinkCallback() begin
index fda943a02695f5b2af8fb6575543c65f4e63242c..110cec90231e949f8b98071b5f320f2b7f58f2d8 100644 (file)
@@ -28,6 +28,7 @@
 #include "common/platform_result.h"
 #include "ml_pipeline_nodeinfo.h"
 #include "ml_pipeline_switch.h"
+#include "ml_pipeline_valve.h"
 
 using common::PlatformResult;
 using namespace extension::ml::pipeline;
@@ -83,7 +84,7 @@ class Pipeline {
   // Pipeline::getSwitch() end
 
   // Pipeline::getValve() begin
-
+  PlatformResult GetValve(const std::string& name);
   // Pipeline::getValve() end
 
   // Pipeline::registerSinkCallback() begin
@@ -141,13 +142,14 @@ class Pipeline {
    */
 
   /*
-   * As switch controls the flow of the data in the pipeline
-   * and users could potentially want to access it
-   * often, we use unordered_map instead of a map for quick
+   * As switch/valve control the flow of the data in the pipeline
+   * and users could potentially want to access them
+   * often, we use unordered_maps instead of a maps for quick
    * retrieval.
    */
   std::unordered_map<std::string, std::unique_ptr<Switch>> switches_;
   std::map<std::string, std::unique_ptr<NodeInfo>> node_info_;
+  std::unordered_map<std::string, std::unique_ptr<Valve>> valves_;
 
   static void PipelineStateChangeListener(ml_pipeline_state_e state, void* user_data);
 };
index 3ee54e3a4bc232160807b8d22839da51dbb21a27..a40320054052e8f52be88418d54b02e44d50412f 100644 (file)
@@ -163,7 +163,17 @@ PlatformResult PipelineManager::GetSwitch(const std::string& name, int pipeline_
 // Pipeline::getSwitch() end
 
 // Pipeline::getValve() begin
+PlatformResult PipelineManager::GetValve(const std::string& name, int pipeline_id) {
+  ScopeLogger("name: [%s], pipeline_id: [%d]", name.c_str(), pipeline_id);
+
+  auto pipeline_it = pipelines_.find(pipeline_id);
+  if (pipelines_.end() == pipeline_it) {
+    LoggerD("Pipeline not found: [%d]", pipeline_id);
+    return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"};
+  }
 
+  return pipeline_it->second->GetValve(name);
+}
 // Pipeline::getValve() end
 
 // Pipeline::registerSinkCallback() begin
index 668933a0eb7f52831376540d4fa9d94b019752ce..666887f067fc6541b61dd1e153a3237b5d66d510 100644 (file)
@@ -72,7 +72,7 @@ class PipelineManager {
   // Pipeline::getSwitch() end
 
   // Pipeline::getValve() begin
-
+  PlatformResult GetValve(const std::string& name, int pipeline_id);
   // Pipeline::getValve() end
 
   // Pipeline::registerSinkCallback() begin
diff --git a/src/ml/ml_pipeline_valve.cc b/src/ml/ml_pipeline_valve.cc
new file mode 100644 (file)
index 0000000..cbd6fda
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "ml_pipeline_valve.h"
+#include "ml_utils.h"
+
+using common::PlatformResult;
+using common::ErrorCode;
+
+namespace extension {
+namespace ml {
+namespace pipeline {
+
+PlatformResult Valve::CreateValve(const std::string& name, ml_pipeline_h pipeline,
+                                  std::unique_ptr<Valve>* out) {
+  ScopeLogger("name: [%s], pipeline: [%p]", name.c_str(), pipeline);
+
+  ml_pipeline_valve_h valve_handle = nullptr;
+  auto ret = ml_pipeline_valve_get_handle(pipeline, name.c_str(), &valve_handle);
+  if (ML_ERROR_NONE != ret) {
+    LoggerE("ml_pipeline_valve_get_handle() failed: [%d] (%s)", ret, get_error_message(ret));
+    return util::ToPlatformResult(ret, "Could not get valve");
+  }
+  LoggerD("ml_pipeline_valve_get_handle() succeeded");
+
+  out->reset(new (std::nothrow) Valve{name, valve_handle});
+  if (!out) {
+    ret = ml_pipeline_valve_release_handle(valve_handle);
+    if (ML_ERROR_NONE != ret) {
+      LoggerE("ml_pipeline_valve_release_handle() failed: [%d] (%s)", ret, get_error_message(ret));
+    } else {
+      LoggerD("ml_pipeline_valve_release_handle() succeeded");
+    }
+    return LogAndCreateResult(ErrorCode::ABORT_ERR, "Could not get the valve",
+                              ("Could not allocate memory"));
+  }
+
+  return PlatformResult{};
+}
+
+Valve::Valve(const std::string& name, ml_pipeline_valve_h valve_handle)
+    : name_{name}, valve_{valve_handle} {
+  ScopeLogger("name: [%s], handle: [%p]", name.c_str(), valve_handle);
+}
+
+Valve::~Valve() {
+  ScopeLogger("name: [%s], handle: [%p]", name_.c_str(), valve_);
+
+  auto ret = ml_pipeline_valve_release_handle(valve_);
+  if (ML_ERROR_NONE != ret) {
+    LoggerE("ml_pipeline_valve_release_handle() failed: [%d] (%s)", ret, get_error_message(ret));
+  } else {
+    LoggerD("ml_pipeline_valve_release_handle() succeeded");
+  }
+}
+
+}  // namespace pipeline
+}  // namespace ml
+}  // namespace extension
\ No newline at end of file
diff --git a/src/ml/ml_pipeline_valve.h b/src/ml/ml_pipeline_valve.h
new file mode 100644 (file)
index 0000000..a03e0e7
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef ML_ML_PIPELINE_VALVE_H_
+#define ML_ML_PIPELINE_VALVE_H_
+
+#include <memory>
+#include <string>
+
+#include <nnstreamer/nnstreamer.h>
+
+#include "common/platform_result.h"
+
+using common::PlatformResult;
+
+namespace extension {
+namespace ml {
+namespace pipeline {
+
+class Valve {
+ public:
+  static PlatformResult CreateValve(const std::string& name, ml_pipeline_h pipeline,
+                                    std::unique_ptr<Valve>* out);
+
+  ~Valve();
+
+  Valve(const Valve&) = delete;
+  Valve& operator=(const Valve&) = delete;
+
+ private:
+  Valve(const std::string& name, ml_pipeline_valve_h valve_handle);
+  const std::string name_;
+  const ml_pipeline_valve_h valve_;
+};
+
+}  // namespace pipeline
+}  // namespace ml
+}  // namespace extension
+
+#endif  // ML_ML_PIPELINE_VALVE_H_
\ No newline at end of file