From: Lukasz Bardeli Date: Tue, 12 Jan 2021 09:24:45 +0000 (+0100) Subject: [ML][Pipeline] Implement getNodeInfo X-Git-Tag: submit/tizen/20210128.113801~23 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=29885d6544861f5067fcfc31f08d1123822249f7;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [ML][Pipeline] Implement getNodeInfo ACR: TWDAPI-274 [Verification] Code compiles without error. Tested in chrome console var pipeline = tizen.ml.pipeline.createPipeline("videotestsrc ! video/x-raw,format=RGB,width=640,height=480 ! videorate max-rate=1 ! tensor_converter ! tensor_mux ! tensor_demux name=demux ! tensor_sink") var nodeinfo = pipeline.getNodeInfo("demux") Change-Id: I503f0a2a52b151ac676a64e2ad888f45abc51170 Signed-off-by: Lukasz Bardeli --- diff --git a/src/ml/js/ml_pipeline.js b/src/ml/js/ml_pipeline.js index 17dba5ef..df2913af 100755 --- a/src/ml/js/ml_pipeline.js +++ b/src/ml/js/ml_pipeline.js @@ -114,7 +114,11 @@ var Pipeline = function(id) { //Pipeline::state end //Pipeline::start() begin -var ValidPipelineStartStopExceptions = ['NotFoundError', 'NotSupportedError', 'AbortError']; +var ValidPipelineStartStopExceptions = [ + 'NotFoundError', + 'NotSupportedError', + 'AbortError' +]; Pipeline.prototype.start = function() { var nativeArgs = { id: this._id @@ -163,7 +167,44 @@ Pipeline.prototype.dispose = function() { //Pipeline::dispose() end //Pipeline::getNodeInfo() begin +var NodeInfo = function(name, pipeline_id) { + Object.defineProperties(this, { + name: { enumerable: true, writable: false, value: name }, + _pipeline_id: { value: pipeline_id } + }); +}; + +var ValidPipelineGetNodeInfoExceptions = [ + 'InvalidValuesError', + 'NotFoundError', + 'NotSupportedError', + 'AbortError' +]; + +Pipeline.prototype.getNodeInfo = function() { + var args = validator_.validateArgs(arguments, [ + { + name: 'name', + type: validator_.Types.STRING + } + ]); + + var nativeArgs = { + id: this._id, + name: args.name + }; + + var result = native_.callSync('MLPipelineGetNodeInfo', nativeArgs); + if (native_.isFailure(result)) { + throw native_.getErrorObjectAndValidate( + result, + ValidPipelineGetNodeInfoExceptions, + AbortError + ); + } + return new NodeInfo(args.name, this._id); +}; //Pipeline::getNodeInfo() end //Pipeline::getSource() begin diff --git a/src/ml/ml.gyp b/src/ml/ml.gyp index 65a987d2..c0ab8262 100644 --- a/src/ml/ml.gyp +++ b/src/ml/ml.gyp @@ -19,6 +19,8 @@ 'ml_pipeline.h', 'ml_pipeline_manager.cc', 'ml_pipeline_manager.h', + 'ml_pipeline_nodeinfo.cc', + 'ml_pipeline_nodeinfo.h', 'ml_utils.cc', 'ml_utils.h', ], diff --git a/src/ml/ml_instance.cc b/src/ml/ml_instance.cc index 3a0cd4d4..7a69c2b6 100644 --- a/src/ml/ml_instance.cc +++ b/src/ml/ml_instance.cc @@ -44,6 +44,7 @@ MlInstance::MlInstance() : pipeline_manager_{this} { REGISTER_METHOD(MLPipelineDispose); REGISTER_METHOD(MLPipelineStart); REGISTER_METHOD(MLPipelineStop); + REGISTER_METHOD(MLPipelineGetNodeInfo); // Pipeline API end #undef REGISTER_METHOD @@ -66,6 +67,7 @@ MlInstance::~MlInstance() { namespace { const std::string kId = "id"; +const std::string kName = "name"; const std::string kDefinition = "definition"; const std::string kPipelineStateChangeListenerName = "listenerName"; @@ -205,7 +207,33 @@ void MlInstance::MLPipelineDispose(const picojson::value& args, picojson::object // Pipeline::dispose() end // Pipeline::getNodeInfo() begin +void MlInstance::MLPipelineGetNodeInfo(const picojson::value& args, picojson::object& out) { + ScopeLogger("args: %s", args.serialize().c_str()); + + if (!args.get(kId).is()) { + LoggerD("id is not a number"); + ReportError(PlatformResult{ErrorCode::ABORT_ERR, "Invalid pipeline"}, &out); + return; + } + + if (!args.get(kName).is()) { + LoggerD("name is not a string"); + ReportError(PlatformResult{ErrorCode::ABORT_ERR, "Invalid name"}, &out); + return; + } + auto name = args.get(kName).get(); + auto id = static_cast(args.get(kId).get()); + + PlatformResult result = pipeline_manager_.GetNodeInfo(id, name); + + if (!result) { + LogAndReportError(result, &out); + return; + } + + ReportSuccess(out); +} // Pipeline::getNodeInfo() end // Pipeline::getSource() begin diff --git a/src/ml/ml_instance.h b/src/ml/ml_instance.h index df6e214c..9b1f430c 100644 --- a/src/ml/ml_instance.h +++ b/src/ml/ml_instance.h @@ -64,7 +64,7 @@ class MlInstance : public common::ParsedInstance { // Pipeline::dispose() end // Pipeline::getNodeInfo() begin - + void MLPipelineGetNodeInfo(const picojson::value& args, picojson::object& out); // Pipeline::getNodeInfo() end // Pipeline::getSource() begin diff --git a/src/ml/ml_pipeline.cc b/src/ml/ml_pipeline.cc index 10930cf2..c843df35 100644 --- a/src/ml/ml_pipeline.cc +++ b/src/ml/ml_pipeline.cc @@ -191,6 +191,8 @@ PlatformResult Pipeline::Dispose() { * If they're released after pipeline_, the app may crash. */ + node_info_.clear(); + auto ret = ml_pipeline_destroy(pipeline_); if (ML_ERROR_NONE != ret) { LoggerE("ml_pipeline_destroy() failed: [%d] (%s)", ret, get_error_message(ret)); @@ -205,7 +207,26 @@ PlatformResult Pipeline::Dispose() { // Pipeline::dispose() end // Pipeline::getNodeInfo() begin +PlatformResult Pipeline::GetNodeInfo(std::string& name) { + ScopeLogger("id_: [%d], name: [%s]", id_, name.c_str()); + + auto nodeinfo_it = node_info_.find(name); + if (node_info_.end() != nodeinfo_it) { + LoggerD("NodeInfo [%s] found", name.c_str()); + return PlatformResult{}; + } + std::unique_ptr node_info_ptr; + auto ret = NodeInfo::CreateNodeInfo(pipeline_, name, &node_info_ptr); + + if (!ret) { + return ret; + } + + node_info_.insert({name, std::move(node_info_ptr)}); + + return PlatformResult{}; +} // Pipeline::getNodeInfo() end // Pipeline::getSource() begin diff --git a/src/ml/ml_pipeline.h b/src/ml/ml_pipeline.h index 42287f8b..80c859ba 100644 --- a/src/ml/ml_pipeline.h +++ b/src/ml/ml_pipeline.h @@ -25,8 +25,10 @@ #include "common/extension.h" #include "common/picojson.h" #include "common/platform_result.h" +#include "ml_pipeline_nodeinfo.h" using common::PlatformResult; +using extension::ml::pipeline::NodeInfo; namespace extension { namespace ml { @@ -68,7 +70,7 @@ class Pipeline { // Pipeline::dispose() end // Pipeline::getNodeInfo() begin - + PlatformResult GetNodeInfo(std::string& name); // Pipeline::getNodeInfo() end // Pipeline::getSource() begin @@ -135,6 +137,8 @@ class Pipeline { const std::string state_change_listener_name_; common::Instance* instance_ptr_; + std::map> node_info_; + static void PipelineStateChangeListener(ml_pipeline_state_e state, void* user_data); }; diff --git a/src/ml/ml_pipeline_manager.cc b/src/ml/ml_pipeline_manager.cc index 3d578618..cadb4d4f 100644 --- a/src/ml/ml_pipeline_manager.cc +++ b/src/ml/ml_pipeline_manager.cc @@ -128,7 +128,18 @@ PlatformResult PipelineManager::DisposePipeline(int id) { // Pipeline::dispose() end // Pipeline::getNodeInfo() begin +PlatformResult PipelineManager::GetNodeInfo(int id, std::string& name) { + ScopeLogger("id: [%d], name [%s]", id, name.c_str()); + auto pipeline_it = pipelines_.find(id); + if (pipelines_.end() == pipeline_it) { + LoggerD("Pipeline not found: [%d]", id); + return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"}; + } + + auto ret = pipeline_it->second->GetNodeInfo(name); + return ret; +} // Pipeline::getNodeInfo() end // Pipeline::getSource() begin diff --git a/src/ml/ml_pipeline_manager.h b/src/ml/ml_pipeline_manager.h index 300aa311..63ee5aa7 100644 --- a/src/ml/ml_pipeline_manager.h +++ b/src/ml/ml_pipeline_manager.h @@ -60,7 +60,7 @@ class PipelineManager { // Pipeline::dispose() end // Pipeline::getNodeInfo() begin - + PlatformResult GetNodeInfo(int id, std::string& name); // Pipeline::getNodeInfo() end // Pipeline::getSource() begin diff --git a/src/ml/ml_pipeline_nodeinfo.cc b/src/ml/ml_pipeline_nodeinfo.cc new file mode 100644 index 00000000..c1e7a34c --- /dev/null +++ b/src/ml/ml_pipeline_nodeinfo.cc @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020 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 + +#include "common/logger.h" +#include "ml_pipeline_nodeinfo.h" +#include "ml_utils.h" + +using common::PlatformResult; +using common::ErrorCode; + +namespace extension { +namespace ml { +namespace pipeline { + +PlatformResult NodeInfo::CreateNodeInfo(ml_pipeline_h pipeline, const std::string& name, + std::unique_ptr* out) { + std::unique_ptr nodeinfo_ptr{new (std::nothrow) NodeInfo{name}}; + if (!nodeinfo_ptr) { + return LogAndCreateResult(ErrorCode::ABORT_ERR, "An unknown occurred.", + ("Could not allocate memory for NodeInfo")); + } + auto ret = ml_pipeline_element_get_handle(pipeline, name.c_str(), &nodeinfo_ptr->node_info_); + if (ML_ERROR_NONE != ret) { + LoggerE("ml_pipeline_element_get_handle() failed: [%d] (%s)", ret, get_error_message(ret)); + return util::ToPlatformResult(ret, "Could not get NodeInfo"); + } + + *out = std::move(nodeinfo_ptr); + return PlatformResult{}; +} + +NodeInfo::NodeInfo(const std::string& name) : name_{name} { + ScopeLogger("name: [%s], ", name.c_str()); +} + +NodeInfo::~NodeInfo() { + ScopeLogger("name: [%s], handle: [%p]", name_.c_str(), node_info_); + + auto ret = ml_pipeline_element_release_handle(node_info_); + if (ML_ERROR_NONE != ret) { + LoggerE("ml_pipeline_element_release_handle() failed: [%d] (%s)", ret, get_error_message(ret)); + } else { + LoggerD("ml_pipeline_element_release_handle() succeeded"); + } +} + +} // namespace pipeline +} // namespace ml +} // namespace extension \ No newline at end of file diff --git a/src/ml/ml_pipeline_nodeinfo.h b/src/ml/ml_pipeline_nodeinfo.h new file mode 100644 index 00000000..4140025e --- /dev/null +++ b/src/ml/ml_pipeline_nodeinfo.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 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_NODEINFO_H_ +#define ML_ML_PIPELINE_NODEINFO_H_ + +#include +#include + +#include + +#include "common/platform_result.h" + +using common::PlatformResult; + +namespace extension { +namespace ml { +namespace pipeline { + +class NodeInfo { + public: + NodeInfo() = delete; + NodeInfo(const NodeInfo&) = delete; + NodeInfo& operator=(const NodeInfo&) = delete; + static PlatformResult CreateNodeInfo(ml_pipeline_h pipeline, const std::string& name, + std::unique_ptr* out); + + ~NodeInfo(); + + private: + NodeInfo(const std::string& name); + const std::string name_; + ml_pipeline_element_h node_info_; +}; + +} // namespace pipeline +} // namespace ml +} // namespace extension + +#endif // ML_ML_PIPELINE_NODEINFO_H_ \ No newline at end of file