Pawel Wasowski [Fri, 6 Aug 2021 15:00:22 +0000 (17:00 +0200)]
[common] Add the definition of a legacy messaging interface
This recent change that introduced new binary messaging interfaces,
replacing XW_MESSAGING_INTERFACE_1 with XW_MESSAGING_INTERFACE_2.
This chang broken the build of webapi-plugins-teec project, which depends
on the declaration of the legacy interface.
This commit fixes this problem, by adding the legacy interface back
to XW_Extension.h.
[Verification] webapi-plugins builds. webapi-plugins-teec builds,
when webapi-plugins built with this change is installed in GBS root.
Change-Id: Ia057a8e9ea9d51e06616a0ad16dc28b3ea342d8c
[version] 2.85
Change-Id: I2524f9fcf99cf55054f69bf6da38b3404ba2e98e
[ml][single] Implemented communication in ML API
[Verification] Performance increased in Chromium console.
TCT passrate - 100%
Change-Id: I7079ec1a690696dc4acc5d827920603e3a12e9ab
[extension] Binary messanger implementation added
[verification] Code compiles without errors.
Change-Id: If98eaf371ffbb47a2bf39978f9529307a9e9b06f
Pawel Wasowski [Wed, 4 Aug 2021 14:49:28 +0000 (16:49 +0200)]
[ML][Single] Fix invokeAsync
invokeAsync implementation did not should copy the input TensorsData
object, as it was supposed to. This commit adds copying
[Verification] Tested with the snippet below several times - the outputs
of invoke and invokeAsync were always identical:
var tensorsData;
var model;
function errorCallback(error)
{
console.log("Error during invokeAsync: " + error.message);
}
function isSameArray(a, b) {
if(a.length != b.length) {
return false;
}
for(var i=0 ; i<a.length ; i++) {
if(a[i] != b[i]) {
return false;
}
}
return true;
}
function successCallback(tensorsDataOut)
{
var asyncResult = tensorsDataOut.getTensorRawData(0).data;
var syncResultTD = model.invoke(tensorsData);
var syncResult = syncResultTD.getTensorRawData(0).data;
if (isSameArray(syncResult, asyncResult)) {
console.log('Sync and async versions of invoke returned the same output');
} else {
console.error('Outputs of sync and async invoke versions differ!');
}
}
function run_test () {
model = tizen.ml.single.openModel("wgt-package/models/mobilenet_v1_1.0_224_quant.tflite", null, null, "TENSORFLOW_LITE", "ANY");
var tensorsInfo = new tizen.ml.TensorsInfo();
tensorsInfo.addTensorInfo("tensor", "UINT8", [224, 224, 3]);
tensorsData = tensorsInfo.getTensorsData();
var randomData = Array.from({length: 224 * 224 * 3}, () => Math.floor(Math.random() * 255));
var rgb = new Uint8Array(randomData);
tensorsData.setTensorRawData(0, rgb);
model.invokeAsync(tensorsData, successCallback, errorCallback);
};
Change-Id: Iff0d39ca6be9e1c5d2ff3c9f9fc3d061d49377c5
Pawel Wasowski [Thu, 15 Jul 2021 13:03:15 +0000 (15:03 +0200)]
[Alarm] Don't raise an error when an alarm without TYPE is found
tizen.alarm.get() and tizen.alarm.getAll() used to fail when alarms
without "TYPE" property in related app_control existed.
This commit returns such alarms as JS Alarm objects.
[Verification] tct-alarm-tizen-tests (auto): 100 %
I've tested in Chrome DevTools debugger, that when an alarm without
"type" property comes to JS, a valid "Alarm" object is created
(I don't provide any test code snippet, because it required stopping
app in the debugger).
Change-Id: I4b5bcea75509f454bd17b787c080417849720f5a
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[version] 2.84
Change-Id: Iaeb9f2c1ce570ad109ea4a5c34a512b4a328442e
[Filesystem] Change setVirtualPath method to be not enumerable
Feature of setVirtualPath is needed for proper handling virtual paths
in thread service model - related change:
https://review.tizen.org/gerrit/gitweb?p=platform/core/api/webapi-plugins.git;a=commit;h=
4870490975f9cbfa3eb16cc892f3593cb74b6668
[Verification] Code compiles without errors. Code was properly
formatted.
Checked in chrome console - setVirtualPath is not iterable, but still
accessible.
Change-Id: Ia3d2720cd1267d0a4d002538f319cfd993e83d4a
DongHyun Song [Wed, 7 Jul 2021 08:47:14 +0000 (17:47 +0900)]
Support setVirtualPath for thread-model wrt-service
thread-model wrt-service runs all service application on worker
thread as daemon process.
For the virtual path resolving, it cannot get service application's
path. i.e. /home/owner/apps_rw/{service_app_pkgid}/data, becuase
wrt-service is org.tizen.chromium-efl package.
Thus, setting virtual path will be set by wrt-service framework
before each node worker thread started.
- node worker has own V8 context
Change-Id: I8dd5e524584ebe71416c86c1e8648a2c4cfc4b94
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
DongHyun Song [Wed, 7 Jul 2021 08:47:14 +0000 (17:47 +0900)]
Support setVirtualPath for thread-model wrt-service
thread-model wrt-service runs all service application on worker
thread as daemon process.
For the virtual path resolving, it cannot get service application's
path. i.e. /home/owner/apps_rw/{service_app_pkgid}/data, becuase
wrt-service is org.tizen.chromium-efl package.
Thus, setting virtual path will be set by wrt-service framework
before each node worker thread started.
- node worker has own V8 context
Change-Id: I8dd5e524584ebe71416c86c1e8648a2c4cfc4b94
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
[Filesystem] Fixed Blob to Uint8Array conversion
Fix inspired by this answer: https://stackoverflow.com/a/
63920556/
11502478
[Verification] in Chrome console:
// assume having wav file on the device
input = tizen.filesystem.openFile("documents/sample1.wav", "r")
blob = input.readBlob() /// Blob {size: 1073218, type: ""}
output = tizen.filesystem.openFile("documents/sample1_output.wav", "w")
output.writeBlob(blob)
output.close()
output_test = tizen.filesystem.openFile("documents/sample1_output.wav", "r")
blob_test = output_test.readBlob() /// Blob {size: 1073218, type: ""}
console.log("Verification passed: " + (blob.size === blob_test.size))
input.close()
output_test.close()
TCT (filesystem, deprecated) passrate 100%
Change-Id: I5e4beea31d69430e9dbe44a7899cf675e779c7f8
[version] 2.83
Change-Id: Ie9ee7bcf4b480406921ec878717b5592dd0cc9a5
Piotr Kosko [Mon, 28 Jun 2021 05:55:56 +0000 (05:55 +0000)]
Merge "[ML][Single] Added InvokeAsync() implementation" into tizen
Piotr Kosko [Mon, 28 Jun 2021 05:55:48 +0000 (05:55 +0000)]
Merge "[Application] Enable system events listener" into tizen
[ML][Single] Added InvokeAsync() implementation
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-278
[Verification] Code compiles without errors.
TCT passrate of existing APIs didn't change.
Checked in chrome console with below snippets:
// initialize test data
model = tizen.ml.single.openModel("documents/model.tflite");
var tensorsInfo = new tizen.ml.TensorsInfo();
tensorsInfo.addTensorInfo("tensor", "UINT8", [3, 224, 224]);
var tensorsData = tensorsInfo.getTensorsData();
var tensorsInfoInvalid = new tizen.ml.TensorsInfo();
tensorsInfoInvalid.addTensorInfo("tensor", "UINT8", [3, 125, 125]);
var tensorsDataInvalid = tensorsInfoInvalid.getTensorsData();
function errorCallback(error) {
console.log(error);
}
function successCallback(tensorsDataOut) {
console.log("Inference finished successfully");
console.log(tensorsDataOut.getTensorRawData(0));
tensorsDataOut.dispose();
}
// success
// test1
model.invokeAsync(tensorsData, successCallback, errorCallback);
// test2
model.invokeAsync(tensorsData, successCallback);
// errors
// test3
model.invokeAsync(tensorsData); // TypeMismatchError - sync
// test4
model.invokeAsync(null, successCallback); // TypeMismatchError - sync
// test5
model.invokeAsync(tensorsDataInvalid, successCallback, errorCallback); // AbortError - async
// test6
model.setTimeout(1)
model.invokeAsync(tensorsData, successCallback, errorCallback); // TimeoutError - async
// clear tensorsData
tensorsData.dispose();
tensorsInfo.dispose();
// test7 - use of disposed tesnsorsData
model.invokeAsync(tensorsData, successCallback, errorCallback); // AbortError - sync
// clear other data
tensorsDataInvalid.dispose();
tensorsInfoInvalid.dispose();
model.close();
Change-Id: I59900d7bab9a76939e27d68cb2bcd5434f446b3d
[version] 2.82
Change-Id: I851cb3ea68068d0ea2fa38ac5eac19ca0a5904c1
Rafal Walczyna [Mon, 14 Jun 2021 09:17:33 +0000 (11:17 +0200)]
[ML] Add new HWType and NNFWType enums
[XWALK-2312]
[TWDAPI-277]
Tested also with code:
var HWType = ["ANY", "NPU_SLSI"];
var NNFWType = ["ANY", "NNTR_INF", "PYTORCH", "SRNPU", "VD_AIFW"];
HWType.forEach(hw => {
NNFWType.forEach(nnfw => {
console.log(nnfw + ", " + hw + ": " + tizen.ml.checkNNFWAvailability(nnfw, hw))
});
});
[Verification] 100% passrate
Change-Id: I9257240d1596c2b017581997b488a01447385060
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
[version] 2.81
Change-Id: I5225e6004d027167b720b9f1fcd1d213a9840769
[Filesystem] Use non-static worker instead of singleton TaskQueue
In filesystem webapi, TaskQueue is a singleton instance used by
multiple FilesystemInstance. With thread model web service
applications, there might be smack violation because each service
app (thread) try to use same worker.
This commit resolves problem by changing usage of singleton TaskQueue to
a member worker owned by FilesystemInstance.
Commit keeps two separated workers for better operation
performance:
- global_worker queues 'global' operations on fielsystem instance e.g.
opening files, rename, move etc.
- file_worker queues only file operation as reading
Above design prevents to block 'quick' global operations in case of
long-lasting file reading/writing operation in background.
[Verification] Code compiles without errors.
Filesystem TCT passrate 100%.
Change-Id: Idf0bd1915f67b64a65fcc1afc2e17d011bb5b918
Signed-off-by: DongHyun Song <dh81.song@samsung.com>
Signed-off-by: Piotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics <p.kosko@samsung.com>
Rafal Walczyna [Mon, 24 May 2021 13:02:02 +0000 (15:02 +0200)]
[Tools] Force clang-format version to 3.9
Using version newer than 3.9 results in a lot of format changes.
As user may want to use newer clang-format version for different
projects, script has been changed to use clang-format-3.9 executable.
[Verification] No change in C++ formatting
Change-Id: I4f569644549db8104bb39efc6bc1eca23ac6bbd6
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Piotr Kosko [Thu, 20 May 2021 06:18:23 +0000 (06:18 +0000)]
Merge "[Bluetooth] Fix Coverity issue" into tizen
Piotr Kosko [Thu, 20 May 2021 06:17:59 +0000 (06:17 +0000)]
Merge "[nfc] Fixing memory management for messages and records" into tizen
Piotr Kosko [Thu, 20 May 2021 04:28:08 +0000 (04:28 +0000)]
Merge "[ML][common] Fix a Coverity issue" into tizen
Piotr Kosko [Thu, 20 May 2021 04:26:20 +0000 (04:26 +0000)]
Merge "[mediacontroller] Fixing Coverity issues" into tizen
Pawel Wasowski [Wed, 19 May 2021 09:56:25 +0000 (11:56 +0200)]
[Bluetooth] Fix Coverity issue
Coverity issue numbers:
1227417
1227505
1229055
[Verification] Code compiles
Change-Id: Ie05e4184cf200b69615b2e4ba92d3d5cb291d4d0
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[nfc] Fixing memory management for messages and records
Should fix Coverity issues:
* 1227523
* 1227594
* 1228259
* 1228588
* 1229210
* 1229523
* 1229587
[Verification] Code compiles without errors.
Change-Id: I07813a855ce2d335fe783956a7af6f340a314602
[mediacontroller] Fixing Coverity issues
Fixes: 1192721
Change-Id: I1bd564b935d35f0586e174869f7df10cd0cc705b
Pawel Wasowski [Tue, 18 May 2021 14:11:12 +0000 (16:11 +0200)]
[ML][common] Fix a Coverity issue
Coverity issue numver: 1229783
This commit fixes a potential memory leak.
[Verification] The code compiles (it's hard to provoke the code to enter
the problematic branch, so the new code wasn't executed)
Change-Id: Id560ffdffc18ff6bbf2bc987e8e0ad6853b2cdb6
Pawel Wasowski [Mon, 29 Mar 2021 14:24:08 +0000 (16:24 +0200)]
[ML] Remove unneccessary comments and already resolved TODOs
[Verification] Code compiles
Change-Id: I4ccd17dcee4cc1344c739d20492c93f94f08545e
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Pawel Wasowski [Thu, 25 Mar 2021 10:42:12 +0000 (11:42 +0100)]
[ML][Pipeline] Prevent a crash in ~CustomFilter and unregister failures
This commit fixes a crash that used to follow the sequence below:
1. ~CustomFilter() is called, but native
ml_pipeline_custom_easy_filter_unregister()
fails to unregister the filter. CustomFilter is
removed, but a pointer to this object (now defunct)
is still kept in CustomFilter::valid_filters_ container.
2. LockRequestIdToJSResponseMutexIfFilterIsNotWaitingForJSResponses,
that iterates over valid_filters_ accesses the destroyed object
and thus crashes the app.
This commit also changes the order of destruction of Pipeline and
CustomFilter objects managed by Web API. Pipeline objects should
be destroyed first.
[Verification] Tested in Chrome DevTools with the snippets below, works
fine.
inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo("3D", "UINT8", [4, 20, 15, 1]);
outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo("flat", "UINT8", [1200]);
filterCB = function (input, output) {
console.log('hello');
tizen.ml.pipeline.unregisterCustomFilter("flattenFilter");
console.log('bye');
}
retValue = tizen.ml.pipeline.registerCustomFilter("flattenFilter", filterCB,
inputTI, outputTI,
console.warn);
pipelineDefinition = "videotestsrc num-buffers=3 " +
"! video/x-raw,width=20,height=15,format=BGRA " +
"! tensor_converter " +
"! tensor_filter framework=custom-easy model=flattenFilter "
+ "! fakesink";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.start();
// hello
// WebAPIException {name: "AbortError", message:
// "CustomFilter has thrown exception: InvalidStateErr CustomFilter has
// thrown exception: InvalidStateError: The custom filter is processing
// data now. Stop the pipeline to unregister the filter."}
// <no deadlock>
///////////////////////////////////////////////////////////////////////////
inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo("3D", "UINT8", [4, 20, 15, 1]);
outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo("ti1", "UINT8", [1200]);
customFilter = function (input, output) {
try {
inputTI.dispose();
outputTI.dispose();
pipeline.stop();
pipeline.dispose();
} catch (err) {
console.warn(err);
}
}
tizen.ml.pipeline.registerCustomFilter("flattenFilter", customFilter, inputTI, outputTI);
pipelineDefinition = "videotestsrc num-buffers=3 " +
"! video/x-raw,width=20,height=15,format=BGRA " +
"! tensor_converter " +
"! tensor_filter framework=custom-easy model=flattenFilter " +
"! fakesink";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.start();
// WebAPIException {name: "InvalidStateError",
// message: "Pipeline cannot be disposed when at least one custom filter
// is currently processing data.",
// <no deadlock>
///////////////////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
// <CustomFilter and SinkListener callbacks' outputs 3 times>
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario; ignore the data
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return 1; // ignore data
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// Custom filter called
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - CustomFilter returns an error
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return -1;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Invalid CustomFilterOutput.status
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return 123;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// InvalidValuesError,
// message: "CustomFilterOutput.status === 1 is the only legal positive value"
////////////////////////////////////////////////////////////
// Check if {input, output}.dispose() and input.setTensorRawData()
// have any effect
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
// dispose should have no efect
input.dispose();
console.log('input count: ' + input.tensorsInfo.count);
// dispose should have no efect
input.dispose();
console.log('output count: ' + output.tensorsInfo.count);
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
// this call should have no effect
input.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
Change-Id: I4c5b773203239321de5826b5e4908c50cd84b7d6
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Piotr Kosko [Wed, 24 Mar 2021 09:50:41 +0000 (09:50 +0000)]
Merge "[Common][ML] Fixing SVACE issues and code formatting" into tizen
[Archive] Fixed Coverity issue
Issue id: 1218132
[Verification]
Code compiles, TCT passrate 100%.
Coverity showed no issues:
https://analysishub.sec.samsung.net/service/analyses/418348
Change-Id: I5d28891a7b2c3b42237c661474ea88d00e028184
Rafal Walczyna [Tue, 23 Mar 2021 14:32:25 +0000 (15:32 +0100)]
[ML][single] Change InvalidValues to TypeMismatch
In case when no arguments are provided, TypeMismatch should be thrown.
Verification: Tested in google chrome console.
Change-Id: Iab1f606c8a731c096dd93f5e38b0ec4c9b6beb6f
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
[Common][ML] Fixing SVACE issues and code formatting
[SVACE] 1222586, 1222593
[Verification] Code compiles without errors.
Change-Id: Ibf34be9edb25f1b4e61e8480c9b6ad42262d42a4
Piotr Kosko [Fri, 19 Mar 2021 06:03:37 +0000 (06:03 +0000)]
Merge "[ML][single] Fix SingleShot.input attribute change" into tizen
Rafal Walczyna [Thu, 18 Mar 2021 14:08:32 +0000 (15:08 +0100)]
[ML][single] Fix SingleShot.input attribute change
Changing input attribute should enable invoking model with different tensor.
User should not be able to modify or dispose input by direct call.
Change is only possible by replacing whole object.
Code:
var ti1 = new tizen.ml.TensorsInfo()
ti1.addTensorInfo("three", "FLOAT32", [1, 1, 1, 1])
var td1 = ti1.getTensorsData(0);
var ti3 = new tizen.ml.TensorsInfo()
ti3.addTensorInfo("three", "FLOAT32", [3, 1, 1, 1])
var td3 = ti3.getTensorsData(0);
var model = tizen.ml.single.openModel("documents/add.tflite", null, null, "ANY", "ANY", false)
model.invoke(td1)
model.input = ti3
model.invoke(td3)
[Verification] Tested in Google Chrome console
Change-Id: Iac17fd72d7e417d30bad983f6c349bd5e5ef05ed
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Piotr Kosko [Thu, 18 Mar 2021 12:56:33 +0000 (12:56 +0000)]
Merge "[ML][Pipeline] Prevent deadlock in CustomFilter" into tizen
Pawel Wasowski [Mon, 15 Mar 2021 15:52:07 +0000 (16:52 +0100)]
[ML][Pipeline] Prevent deadlock in CustomFilter
ACR: TWDAPI-274
A deadlock could happen in 2 scenarios:
1. An attempt of unregistering a CustomFilter from its callback, (i.e.
calling tizen.ml.pipeline.unregisterCustomFilter('xxx') from xxx's
CustomFilter callback).
2. An attempt of disposing the pipeline using a CustomFilter which is
currently processing data.
This commit fixes the problems.
[Verification] Tested in Chrome DevTools with the snippets below, works
fine.
inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo("3D", "UINT8", [4, 20, 15, 1]);
outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo("flat", "UINT8", [1200]);
filterCB = function (input, output) {
console.log('hello');
tizen.ml.pipeline.unregisterCustomFilter("flattenFilter");
console.log('bye');
}
retValue = tizen.ml.pipeline.registerCustomFilter("flattenFilter", filterCB,
inputTI, outputTI,
console.warn);
pipelineDefinition = "videotestsrc num-buffers=3 " +
"! video/x-raw,width=20,height=15,format=BGRA " +
"! tensor_converter " +
"! tensor_filter framework=custom-easy model=flattenFilter "
+ "! fakesink";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.start();
// hello
// WebAPIException {name: "AbortError", message:
// "CustomFilter has thrown exception: InvalidStateErr CustomFilter has
// thrown exception: InvalidStateError: The custom filter is processing
// data now. Stop the pipeline to unregister the filter."}
// <no deadlock>
///////////////////////////////////////////////////////////////////////////
inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo("3D", "UINT8", [4, 20, 15, 1]);
outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo("ti1", "UINT8", [1200]);
customFilter = function (input, output) {
try {
inputTI.dispose();
outputTI.dispose();
pipeline.stop();
pipeline.dispose();
} catch (err) {
console.warn(err);
}
}
tizen.ml.pipeline.registerCustomFilter("flattenFilter", customFilter, inputTI, outputTI);
pipelineDefinition = "videotestsrc num-buffers=3 " +
"! video/x-raw,width=20,height=15,format=BGRA " +
"! tensor_converter " +
"! tensor_filter framework=custom-easy model=flattenFilter " +
"! fakesink";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.start();
// WebAPIException {name: "InvalidStateError",
// message: "Pipeline cannot be disposed when at least one custom filter
// is currently processing data.",
// <no deadlock>
///////////////////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
// <CustomFilter and SinkListener callbacks' outputs 3 times>
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario; ignore the data
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return 1; // ignore data
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// Custom filter called
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - CustomFilter returns an error
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return -1;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Invalid CustomFilterOutput.status
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return 123;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// InvalidValuesError,
// message: "CustomFilterOutput.status === 1 is the only legal positive value"
////////////////////////////////////////////////////////////
// Check if {input, output}.dispose() and input.setTensorRawData()
// have any effect
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
// dispose should have no efect
input.dispose();
console.log('input count: ' + input.tensorsInfo.count);
// dispose should have no efect
input.dispose();
console.log('output count: ' + output.tensorsInfo.count);
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
// this call should have no effect
input.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
Change-Id: Id6cda7782e3065248b2f2c5f859ca2af07c108a6
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Pawel Wasowski [Wed, 17 Mar 2021 17:26:29 +0000 (18:26 +0100)]
[ML][Pipeline] Remove InvalidValuesError from createPipeline
ACR: TWDAPI-274
This commit removes InvalidValuesError from the list of valid
tizen.ml.pipeline.createPipeline() exceptions, because we cannot
reliably detect, when a pipeline description is invalid.
Instead, AbortError with custom message, suggesting that the
description may be invalid, will be used.
[Verification] Tested in Chrome DevTools with the snippets below, works
fine
// Invalid pipeline definition
var pipeline_def = "invalid";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
// WebAPIException {name: "AbortError", message: "Could not create pipeline:
// invalid pipeline description or an internal error"}
//////////////////////////////////////////////////////////////////////
// Valid pipeline definition
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
// dispose should have no efect
input.dispose();
console.log('input count: ' + input.tensorsInfo.count);
// dispose should have no efect
input.dispose();
console.log('output count: ' + output.tensorsInfo.count);
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
// this call should have no effect
input.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// pipeline starts properly
Change-Id: If8d08160cb98b3acc34812f47b2741c2cce83cd8
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[version] 2.80
Change-Id: I70978ba74a8a100745631723bdccd66239b7224e
Piotr Kosko [Mon, 15 Mar 2021 06:05:05 +0000 (06:05 +0000)]
Merge "[ML][Pipeline] Fix issues reported by TCT team" into tizen
Pawel Wasowski [Fri, 12 Mar 2021 14:32:18 +0000 (15:32 +0100)]
[ML][Pipeline] Fix issues reported by TCT team
Fixed problems:
- Pipeline::{getNodeInfo, getSwitch, getValve}: throw TypeMismatchError
when no argument is passed
- NodeInfo::setProperty: throw TypeMismatchError, instead of AbortError
when value type is other than expected
- Pipeline::unregisterSinkListener: throw InvalidValuesError when sink
has not been registered
[Verification] Code was tested with the snippets below and worked fine
///// checking problems with getNodeInfo, getSwitch, getValve,
///// and unregisterSinkListener
var pipelineDefinition = "videotestsrc name=vsrc is-live=true " +
"! videoconvert " +
"! videoscale name=vscale " +
"! video/x-raw,format=RGBx,width=224,height=224,framerate=60/1 " +
"! tensor_converter " +
"! valve name=valvex " +
"! input-selector name=is01 " +
"! tensor_sink name=sinkx";
var pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
pipeline.getNodeInfo();
// TypeMismatchError
pipeline.getSwitch();
// TypeMismatchError
pipeline.getValve();
// TypeMismatchError
pipeline.unregisterSinkListener('test')
// InvalidValuesError
///// checking problem with setProperty
pipelineDefinition = "videotestsrc name=vsrc is-live=true " +
"! videoconvert " +
"! videoscale name=vscale " +
"! video/x-raw,format=RGBx,width=224,height=224,framerate=60/1 " +
"! tensor_converter " +
"! valve name=valvex " +
"! input-selector name=is01 " +
"! tensor_sink name=sinkx";
pipeline = tizen.ml.pipeline.createPipeline(pipelineDefinition);
nodeInfo = pipeline.getNodeInfo("vsrc");
nodeInfo.setProperty("is-live", "DOUBLE", NaN);
// TypeMismatchError
Change-Id: I25438b037e0a2dd2f91f8d9b398cffcaf457386b
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Rafal Walczyna [Fri, 12 Mar 2021 12:23:06 +0000 (13:23 +0100)]
[ML][Single] Fix issues that came out after TCT tests
- SingleShot.openModel should throw TypeError when no arguments provided
[Verification] Tested in chrome-dev console
Change-Id: I13b7946aa90f86ff4becccb9834b76d4f6bf6d22
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Piotr Kosko [Fri, 12 Mar 2021 10:17:40 +0000 (10:17 +0000)]
Merge "[ML][Pipeline] Invalidate CustomFilter arguments after return" into tizen
Pawel Wasowski [Wed, 10 Mar 2021 12:38:22 +0000 (13:38 +0100)]
[ML][Pipeline] Invalidate CustomFilter arguments after return
ACR: TWDAPI-274
This commit makes input and output of a JS CustomFilter act as if they
were disposed after the callback's return.
[Verification] Change was tested in Chrome DevTools with the snippets
below. It works fine.
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
console.log(input);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// TensorsData {_id: 0, _tensorsInfo: TensorsInfo, _disposable: false}
// PAUSED
pipeline.start()
// CustomFilter is called 3 times
inputFromCustomFilter.getTensorRawData(0)
inputFromCustomFilter.tensorsInfo
outputFromCustomFilter.getTensorRawData(0)
outputFromCustomFilter.tensorsInfo
// The 4 lines above result in the following exception
// WebAPIException {name: "AbortError", message: "TensorsData is disposed"}
// as expected
//////////////////////////////////////////////////////////////////////////
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var inputTD = inputTI.getTensorsData()
inputTD.dispose()
inputTD.tensorsInfo
inputTD.getTensorRawData(0)
// The 2 lines above result in the following exception
// WebAPIException {name: "AbortError", message: "TensorsData is disposed"}
// as expected - the behavior of TensorsData.dispose() did not change
Change-Id: Ib6c6afc4bb09ad2ce04bb85650b79868e9923b7b
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Rafal Walczyna [Fri, 12 Mar 2021 07:55:42 +0000 (08:55 +0100)]
[ML][Common] Fix issues that came out after TCT tests
- tizen.ml.single and tizen.ml.prototype should be not writable
- TensorsInfo.addTensorsInfo should return newly added tensors info id
- ValidateBufferForTensorsData issue
[Verification] Tested in chromium console
Change-Id: I9ba7e074c79ffc7acb4de32a87a42db6c5f22beb
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Piotr Kosko [Fri, 12 Mar 2021 05:32:20 +0000 (05:32 +0000)]
Merge "[ML] Change InvalidValuesError to TypeMismatchError for no args" into tizen
Piotr Kosko [Fri, 12 Mar 2021 05:25:37 +0000 (05:25 +0000)]
Merge "[MediaController] Add guards to map of playlists' handles" into tizen
Rafal Walczyna [Thu, 11 Mar 2021 14:06:57 +0000 (15:06 +0100)]
[ML] Change InvalidValuesError to TypeMismatchError for no args
When function is called without args, converter throws TypeError.
This commit unifies it.
code_format has been also applied.
[Verification] Builts successful, tested in chrome console
Change-Id: I032fd3f78e06b561ae472cdbbafe3bcf4092a6d9
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Tue, 9 Mar 2021 11:00:50 +0000 (12:00 +0100)]
[MediaController] Add guards to map of playlists' handles
Previously only mc_server handle were guarded by mutexes.
Playlist also needs one.
[Verification] Tested on TM1, tct-mediacontroller pass 100% x 10, no issue occurred.
Change-Id: I155cc4f2dd87d4b1237537532105b7c251689279
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Pawel Wasowski [Wed, 10 Mar 2021 10:31:04 +0000 (11:31 +0100)]
[ML][Pipeline][Single] Fix SVACE issues
This commit fixes the following issues reported on
analysishub.sec.samsung.net (WGIDs):
- 457566
- 457567
- 457568
[Verification] Code compiles. SVACE analysis after
applying the patch
(https://analysishub.sec.samsung.net/service/analyses/394936)
found no errors.
CustomFilter tested in Chrome DevTools with the
snippet below works fine
// Valid CustomFilter callback - the happy scenario
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
// <CustomFilter and SinkListener callbacks' outputs 3 times>
Change-Id: Id1d35167532c3aeecbd3c73c3546b80e31e8f76c
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[Application] Enable system events listener
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-276
[Verification] Code compiles without errors.
TCT passrate for application, appcontrol, capablity, deprecated - 100%
Checked some of native events from:
https://docs.tizen.org/application/native/guides/app-management/event/
var app = tizen.application.getCurrentApplication();
watchId =
app.addEventListener({"name": "location_enable_state"}, function(event, data)
{
console.log("Event" + JSON.stringify(event) + " Data: " + JSON.stringify(data));
});
var watchId =
app.addEventListener({"appId": app.appInfo.id, "name": "custom_user_event"}, function(event, data)
{
console.log("Event" + JSON.stringify(event) + " Data: " + JSON.stringify(data));
/* Do something. */
});
after triggering associated event - listener seem to be called properly:
> app.broadcastEvent({'name': 'custom_user_event'}, {'test': 't'})
console-via-logger.js:173 Event{"appId":"Bwk0GVY1f3.BasicUI40","name":"custom_user_event"} Data: {"test":"t"}
> // ebable location on device
console-via-logger.js:173 Event{"name":"LOCATION_ENABLE_STATE"} Data: {"value":"disabled","type":"LOCATION_ENABLE_STATE"}
Change-Id: I73ae5b2b180c441db4f2da2eb84292b04b8e188f
Id: I65c83787c7d366fef918103be882370614034354
Piotr Kosko [Mon, 8 Mar 2021 05:49:45 +0000 (05:49 +0000)]
Merge "[SPEC][UT] Add conditions to unit test build and run" into tizen
Rafal Walczyna [Wed, 3 Mar 2021 10:30:09 +0000 (11:30 +0100)]
[SPEC][UT] Add conditions to unit test build and run
Unit tests can be run inside GBS - by setting flag in spec file.
[Verification] Built successful with unified, profile mobile, profile wearable
both with ut flags on and off.
Change-Id: I2a89562893182cf35cd41f8b396a19c4777fe580
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Thu, 4 Mar 2021 13:37:02 +0000 (14:37 +0100)]
[systeminfo] Fix armv8l and texture_format on RPI
[TSDF-257]
- RPI4 has armv8l architecture, which was not supported by webapi.
- RPI4 does not support any opnegles texture_format
[Verification] TM1 6.5 systeminfo TCT 100% pass. Tested in chrome console on RPI4.
Change-Id: Ic479e2860250ebe15033a2cf8a53f827a2bd4bcd
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
[version] 2.79
Change-Id: I10b8b53727146f2ef80b8e98f1fcb5365ffd3ae8
Piotr Kosko [Wed, 3 Mar 2021 13:12:16 +0000 (13:12 +0000)]
Merge "[ML][Pipeline] Change CustomFilter interface and implementation" into tizen
Piotr Kosko [Wed, 3 Mar 2021 13:11:19 +0000 (13:11 +0000)]
Merge "[ML][Single] Implemented setTimeout and close" into tizen
Piotr Kosko [Tue, 2 Mar 2021 13:38:09 +0000 (13:38 +0000)]
Merge "[GYP] Update build configuration for ML API" into tizen
[ML][Single] Implemented setTimeout and close
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-273
[Verification] Code compiles. Verified in chrome console:
var m = tizen.ml.single.openModel("/opt/usr/home/owner/media/Documents/mobilenet_v1_1.0_224_quant.tflite") // success
// timeout check
// check if invoke works 'normally'
var ti = new tizen.ml.TensorsInfo();
ti.addTensorInfo("tensor", "UINT8", [3, 224, 224])
var td = ti.getTensorsData();
var tdout = m.invoke(td) // success
// check if timeout will change behaviour of invoke, while short timeout is set
m.setTimeout(5) // success
var tdout = m.invoke(td) // TimeoutError
// check empty arguments
m.setTimeout() // InvalidValuesError
// close check
m.close() // success
// Abort error: "SingleShot object was closed and using it is no longer possible."
// for following calls:
m.close()
m.input
m.output
m.invoke()
m.getValue()
m.setValue()
m.setTimeout()
Change-Id: I3ff7b899fc1527f62aea24387cadf4d0f0db3f05
[GYP] Update build configuration for ML API
Change-Id: Icb9f4993e8bbeae6e2c12bfca6689d279823d54e
Pawel Wasowski [Thu, 25 Feb 2021 19:02:20 +0000 (20:02 +0100)]
[ML][Pipeline] Change CustomFilter interface and implementation
ACR: TWDAPI-274
CustomFilter API and implementation are changed to avoid
copying TensorsData.
Change-Id: Id48b774c86b65f5b45f3dd74733c006b6a729b8c
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[Verification] Code tested with the snippets below works fine
// Valid CustomFilter callback - the happy scenario
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
// <CustomFilter and SinkListener callbacks' outputs 3 times>
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario; ignore the data
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return 1; // ignore data
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// Custom filter called
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - CustomFilter returns an error
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input, output) {
console.log("Custom filter called");
return -1;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Invalid CustomFilterOutput.status
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return 123;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// InvalidValuesError,
// message: "CustomFilterOutput.status === 1 is the only legal positive value"
////////////////////////////////////////////////////////////
// Check if {input, output}.dispose() and input.setTensorRawData()
// have any effect
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenAndSet123 = function(input, output) {
console.log("Custom filter called");
// dispose should have no efect
input.dispose();
console.log('input count: ' + input.tensorsInfo.count);
// dispose should have no efect
input.dispose();
console.log('output count: ' + output.tensorsInfo.count);
var rawOutputData = new Uint8Array(1200);
for (var i = 0; i < rawOutputData.length; ++i) {
rawOutputData[i] = 123;
}
output.setTensorRawData(0, rawOutputData);
// this call should have no effect
input.setTensorRawData(0, rawOutputData);
return 0;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenAndSet123, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
Change-Id: Id48b774c86b65f5b45f3dd74733c006b6a729b8c
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Rafal Walczyna [Thu, 25 Feb 2021 12:38:46 +0000 (13:38 +0100)]
[ML][single] SingleShot.invoke implementation added
ACR: TWDAPI-273
Test code:
var ti1 = new tizen.ml.TensorsInfo()
ti1.addTensorInfo("three", "FLOAT32", [1, 1, 1, 1])
var td1 = ti1.getTensorsData(0);
td1.setTensorRawData(0, [1]);
var ti3 = new tizen.ml.TensorsInfo()
ti3.addTensorInfo("three", "FLOAT32", [3, 1, 1, 1])
var td3 = ti3.getTensorsData(0);
td3.setTensorRawData(0, [1, 2, 3]);
var ti5 = new tizen.ml.TensorsInfo()
ti5.addTensorInfo("three", "FLOAT32", [5, 1, 1, 1])
var td5 = ti5.getTensorsData(0);
td5.setTensorRawData(0, [1, 2, 3, 4, 5]);
// using model from nnstreamer API
var m = tizen.ml.single.openModel('documents/add.tflite', null, null, "ANY", "ANY")
m.invoke(td1) // ok
m.invoke(td3) // error
m.invoke(td5) // error
var m_dynamic = tizen.ml.single.openModel('documents/add.tflite', null, null, "ANY", "ANY", true)
m_dynamic.invoke(td1) // ok
m_dynamic.invoke(td3) // ok
m_dynamic.invoke(td5) // ok
[Verification] Built successful. Tested in Chrome Dev console.
Change-Id: I25218c122c57d6cb781181388f94a27ee0605ee8
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Piotr Kosko [Thu, 25 Feb 2021 12:09:10 +0000 (12:09 +0000)]
Merge "[ML][Pipeline] Implement CustomFilter callback" into tizen
Piotr Kosko [Thu, 25 Feb 2021 12:08:46 +0000 (12:08 +0000)]
Merge "[ML][Pipeline] Implement {register, unregister}CustomFilter" into tizen
Pawel Wasowski [Mon, 22 Feb 2021 10:07:11 +0000 (11:07 +0100)]
[ML][Pipeline] Implement CustomFilter callback
ACR: TWDAPI-274
This is the second part of CustomFilter implementation. It adds
transfering the data between JS and C++.
[Verification] Code tested with the snippets below works fine
// Valid CustomFilter callback - the happy scenario
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
var outputTD = outputTI.getTensorsData();
var rawInputData = input.getTensorRawData(0);
for (var i = 0; i < rawInputData.data.size; ++i) {
rawInputData.data[i] = rawInputData.data[i] + 1;
}
outputTD.setTensorRawData(0, rawInputData.data);
return new tizen.ml.CustomFilterOutput(0, outputTD);
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
// <CustomFilter and SinkListener callbacks' outputs 3 times>
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - the happy scenario; ignore the data
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return new tizen.ml.CustomFilterOutput(1, null); // ignore data
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// Custom filter called
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Valid CustomFilter callback - CustomFilter returns an error
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return new tizen.ml.CustomFilterOutput(-1, null);
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// PAUSED
pipeline.start()
// PLAYING
////////////////////////////////////////////////////////////
// Invalid CustomFilter callback output - status == 0, but no
TensorsData
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return new tizen.ml.CustomFilterOutput(0, null);
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// custom filter error:
// {name: "AbortError", message: "CustomFilter has thrown exception:
// {'code':0, 'name':'InvalidValuesError' ..."}
////////////////////////////////////////////////////////////
// Invalid CustomFilter callback output - non-CustomFilterOutput
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return 123;
}
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// custom filter error:
// {name: "TypeMismatchError",
// message: "The value returned from CustomFilter is not a
// CustomFilterOutput object"}
////////////////////////////////////////////////////////////
// CustomFilter callback returns TensorsData with dimensions other
// than specified in tizen.ml.pipeline.registerCustomFilter(...) call
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
var invalidOutputTI = new tizen.ml.TensorsInfo();
invalidOutputTI.addTensorInfo('ti1', 'UINT8', [5, 2]);
var outputTD = invalidOutputTI.getTensorsData();
outputTD.setTensorRawData(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
return new tizen.ml.CustomFilterOutput(0, outputTD);
}
// register - the happy scenario
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// custom filter error: {name: "InvalidValuesError",
// message: "Output's TensorsInfo is not equal to expected"}
pipeline.start()
////////////////////////////////////////////////////////////
// CustomFilter callback returns non-TensorsData as output
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called");
return new tizen.ml.CustomFilterOutput(0, "this should be TensorsData");
}
// register - the happy scenario
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
pipeline.registerSinkListener('mysink', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
// READY
// Custom filter called
// custom filter error:
// {name: "AbortError", message: "CustomFilter has thrown exception: {
..."}
////////////////////////////////////////////////////////////
// Invalid CustomFilterOutput.status
new tizen.ml.CustomFilterOutput(666, null);
// InvalidValuesError,
// message: "CustomFilterOutput.status === 1 is the only legal positive value"
Change-Id: Icf2edee853eb97dde54ecd83f00164b302aa29ca
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Pawel Wasowski [Thu, 18 Feb 2021 10:09:04 +0000 (11:09 +0100)]
[ML][Pipeline] Implement {register, unregister}CustomFilter
ACR: TWDAPI-274
This is the first part of the implementation of nnstreamer's pipeline
CustomFilter Web API. It enables registering and unregistering
CustomFilters, but they don't process the data.
[Verification] Tested with the snippets below, works fine
var inputTI = new tizen.ml.TensorsInfo();
inputTI.addTensorInfo('ti1', 'UINT8', [4, 20, 15, 1]);
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var flattenPlusOne = function(input) {
console.log("Custom filter called with: ");
var outputTD = outputTI.getTensorsData();
var rawInputData = input.getTensorRawData(0);
for (var i = 0; i < rawInputData.data.size; ++i) {
rawInputData.data[i] = rawInputData.data[i] + 1;
}
outputTD.setTensorRawData(0, rawInputData.data);
return new tizen.ml.CustomFilterOutput(0, outputTD);
}
// register - the happy scenario
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
var pipeline_def = "videotestsrc num-buffers=3 "
+ "! video/x-raw,width=20,height=15,format=BGRA "
+ "! tensor_converter "
+ "! tensor_filter framework=custom-easy model=testfilter2 "
+ "! appsink name=mysink";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
state => {console.log(state);})
// READY
pipeline.start()
// unregister - the happy scenario
tizen.ml.pipeline.unregisterCustomFilter('testfilter2')
// overwrite a previously registered filter - that's ok
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
tizen.ml.pipeline.registerCustomFilter('testfilter2', flattenPlusOne, inputTI,
outputTI, function errorCallback(error) {
console.warn('custom filter error:') ; console.warn(error);
});
// unregister nonexistent filter
tizen.ml.pipeline.unregisterCustomFilter('nonexistentfilter')
// InvalidValuesError: ""nonexistentfilter" CustomFilter not found"
Change-Id: Ib01490e669376149eae654937131116f5ec1a4df
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Youngsoo Choi [Mon, 22 Feb 2021 23:42:09 +0000 (15:42 -0800)]
Check thread smack label for thread-based app model
Legacy web service app had been launched on a process but
new web service app is launched on a thread to save memory usage.
With the thread-based app model, the thread smack label needs to be checked
from the path |/proc/<tid>/attr/current|.
Also, checking thread smack label is compatible with process-based app model
because main thread utilizes same path of |/proc/<pid>/attr/current| as well.
Change-Id: Ib02237c926a2deedcd91451a36dd2a3d832cfb04
Signed-off-by: Youngsoo Choi <kenshin.choi@samsung.com>
Piotr Kosko [Mon, 22 Feb 2021 14:53:57 +0000 (14:53 +0000)]
Merge "[Mediakey] Conditional support for module" into tizen
[Mediakey] Conditional support for module
Tested in chrome and with TCT (capability & mediakey).
With feature disabled:
TCT:
capability 100% pass
mediakey - not exectued
Chrome:
> tizen.mediakey === undefined
true
With feature enabled:
TCT:
capability 100% pass
mediakey 100% pass
Chrome:
> tizen.mediakey === undefined
false
> tizen.mediakey
MediaKeyManager {}
Change-Id: I1b6a4654c0aabcb2e21defd0d05936d65115263f
Piotr Kosko [Mon, 22 Feb 2021 12:23:48 +0000 (12:23 +0000)]
Merge "[ML][Common] Minor fixes" into tizen
[ML] Fixed SVACE issue - not initialized size_in_bytes
[SVACE] Issue 456940
Change-Id: Icc31326b1768939ed82dbd5efde76c156c5f9be9
Pawel Wasowski [Fri, 19 Feb 2021 01:29:00 +0000 (02:29 +0100)]
[ML][Common] Minor fixes
ACR: TWDAPI-273/TWDAPI-274
This commit adds 2 missing logs and replaces one variable name with a
proper one.
[Verification] Tested with below snippets, works as expected
// This snippets triggers the added log:
var pipeline_def = "videotestsrc num-buffers=3 ! videoconvert"
+ " ! tensor_converter ! tensor_sink name=sinkx";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
function(state) {console.log(state);});
// READY
// PAUSED
pipeline.registerSinkListener('sinkx', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
pipeline.start()
// registered SinkListener is called 3 times
///////////////////////////////////////////////////////////
// This snippet no longer triggers the changed log:
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var outputTD = outputTI.getTensorsData();
outputTD.dispose()
///////////////////////////////////////////////////////////
// This snippet triggers the exception which message is now correct:
var outputTI = new tizen.ml.TensorsInfo();
outputTI.addTensorInfo('ti1', 'UINT8', [1200]);
var outputTD = outputTI.getTensorsData();
outputTD.setTensorRawData(0, 'invalid data');
Change-Id: Iec192971882b094cc93679f2104499568dc43777
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Piotr Kosko [Thu, 18 Feb 2021 05:19:04 +0000 (05:19 +0000)]
Merge "[ML-API] Use capi-ml-inference package instead of capi-nnstreamer" into tizen
[ML] Added SingleShot openModelAsync() implementation
[ACR] https://code.sec.samsung.net/jira/browse/TWDAPI-273
[Verification] Code compiles without errors.
Checked in chrome console with few calls:
// Success calls:
tizen.ml.single.openModelAsync("documents/mobilenet_v1_1.0_224_quant.tflite", (s) => console.log(s))
tizen.ml.single.openModelAsync("documents/mobilenet_v1_1.0_224_quant.tflite", (s) => console.log(s), null, null, null, "TENSORFLOW_LITE")
tizen.ml.single.openModelAsync("documents/mobilenet_v1_1.0_224_quant.tflite", (s) => console.log(s), null, null, null, "TENSORFLOW_LITE", "ANY", true)
// Fails for invalid or not-existing file:
tizen.ml.single.openModelAsync("documents/fail.tflite", (s) => console.log(s), (e) => console.log(e)) // Abort Error
tizen.ml.single.openModelAsync("documents/notexisting", (s) => console.log(s), (e) => console.log(e)) // NotFound
tizen.ml.single.openModelAsync("notexisting", (s) => console.log(s), (e) => console.log(e)) // NotFound
// ASYNC version verification //
// without storage privilege
tizen.ml.single.openModelAsync("notexistingfile", (s) => console.log(s), (e) => console.log("Async: " + JSON.stringify(e))) // async NotFoundError
tizen.ml.single.openModelAsync("/dddd/notexistingfile", (s) => console.log(s), (e) => console.log("Async: " + JSON.stringify(e))) // async NotFoundError
tizen.ml.single.openModelAsync("documents/notexistingfile", (s) => console.log(s), (e) => console.log("Async: " + JSON.stringify(e))) // throws SecurityError
tizen.ml.single.openModelAsync("documents/mobilenet_v1_1.0_224_quant.tflite", (s) => console.log(s), (e) => console.log("Async: " + JSON.stringify(e))) // throws SecurityError
// with storage privilege
tizen.ml.single.openModelAsync("notexistingfile", (s) => console.log(s), (e) => console.log("Async: " + JSON.stringify(e))) // async NotFoundError
tizen.ml.single.openModelAsync("/dddd/notexistingfile", (s) => console.log(s), (e) => console.log("Async: " + JSON.stringify(e))) // async NotFoundError
tizen.ml.single.openModelAsync("documents/notexistingfile", (s) => console.log(s), (e) => console.log("Async: " + JSON.stringify(e))) // async NotFoundError
tizen.ml.single.openModelAsync("documents/mobilenet_v1_1.0_224_quant.tflite", (s) => console.log(s), (e) => console.log("Async: " + JSON.stringify(e))) // success
// SYNC version verification //
// without storage privilege
tizen.ml.single.openModel("notexistingfile") // throws NotFoundError
tizen.ml.single.openModel("/dddd/notexistingfile") // throws NotFoundError
tizen.ml.single.openModel("documents/notexistingfile") // throws SecurityError
tizen.ml.single.openModel("documents/mobilenet_v1_1.0_224_quant.tflite") // throws SecurityError
// with storage privilege
tizen.ml.single.openModel("notexistingfile") // throws NotFoundError
tizen.ml.single.openModel("/dddd/notexistingfile") // throws NotFoundError
tizen.ml.single.openModel("documents/notexistingfile") // throws NotFoundError
tizen.ml.single.openModel("documents/mobilenet_v1_1.0_224_quant.tflite") // success
Change-Id: I93e009efec4e1bcbe6d6c3b381b34cada910d8aa
Piotr Kosko [Wed, 17 Feb 2021 05:50:52 +0000 (05:50 +0000)]
Merge "[ML][single] SingleShot.setValue and SingleShot.getValue" into tizen
Sangjung Woo [Wed, 17 Feb 2021 04:43:31 +0000 (13:43 +0900)]
[ML-API] Use capi-ml-inference package instead of capi-nnstreamer
The name of capi-nnstreamer and its pc file is changed to
capi-ml-inference. To build without any errors, this patch updates its
related information.
Change-Id: I037cc1151461fbaacfd87fcf2175e32b65dd337e
Signed-off-by: Sangjung Woo <sangjung.woo@samsung.com>
Rafal Walczyna [Mon, 15 Feb 2021 14:02:14 +0000 (15:02 +0100)]
[ML][single] SingleShot.setValue and SingleShot.getValue
ACR: TWDAPI-273
Test code:
var m = tizen.ml.single.openModel('documents/mobilenet_v1_1.0_224_quant.tflite')
var arr = ["input", "inputtype", "inputlayout", "output", "outputtype", "outputlayout",
"accelerator", "is-updatable", "inputname", "outputname", "custom" ]
arr.forEach((v) => {
try {
console.log(v, ':', m.getValue(v));
} catch (error) {
console.log(v, ':', error.message)
}
});
m.setValue("input", "3:244:244:4");
console.log("input: " + m.getValue("input"))
m.setValue("is-updatable", "true");
console.log("is-updatable: " + m.getValue("is-updatable"))
[Verification] Built successful. Tested in Chrome Dev console.
Change-Id: Id911ed1717fb7b96c7ac75350ea27c78786cc5d9
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Pawel Wasowski [Tue, 2 Feb 2021 09:58:52 +0000 (10:58 +0100)]
[ML][common] Add synchronization of access to tensor info/data maps
ACR: TWDAPI-273/TWDAPI-274
Pipeline's SinkCallbacks and CustomFilters may be called from threads
other than the main thread. As they access members of
Tensors{Data, Info}Managers, the access to these members should be
synchronized to prevent 2 threads from modifying the same data
concurrently.
[Verification] Tested with code snippets used from other commits
implementing Tensors{Data, Info} or Pipeline - the snippets still work.
The snippets used for tests were found in commit messages of these changes:
https://review.tizen.org/gerrit/c/platform/core/api/webapi-plugins/+/251435
https://review.tizen.org/gerrit/c/platform/core/api/webapi-plugins/+/251699
https://review.tizen.org/gerrit/c/platform/core/api/webapi-plugins/+/251524
https://review.tizen.org/gerrit/c/platform/core/api/webapi-plugins/+/252001
https://review.tizen.org/gerrit/c/platform/core/api/webapi-plugins/+/252002
https://review.tizen.org/gerrit/c/platform/core/api/webapi-plugins/+/252289
https://review.tizen.org/gerrit/c/platform/core/api/webapi-plugins/+/252290
https://review.tizen.org/gerrit/c/platform/core/api/webapi-plugins/+/252482
Change-Id: I32f5df4ba92e86034c78d751e901c77a9d60ca4e
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Pawel Wasowski [Mon, 1 Feb 2021 14:01:13 +0000 (15:01 +0100)]
[ML][pipeline] Implement Pipeline::{register,unregister}SinkListener
ACR: TWDAPI-274
[Verification] Tested in Chrome DevTools with the snippets below. Works
fine
var pipeline_def = "videotestsrc num-buffers=3 ! videoconvert"
+ " ! tensor_converter ! tensor_sink name=sinkx";
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def,
function(state) {console.log(state);});
// READY
// PAUSED
pipeline.registerSinkListener('sinkx', function(sinkName, data) {
console.log('SinkListener for "' + sinkName + '" sink called');
console.log(data);
})
pipeline.start()
// registered SinkListener is called 3 times
Change-Id: I8790327d070e54d27fd9cc028882773487a48d7a
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Piotr Kosko [Fri, 12 Feb 2021 07:19:38 +0000 (07:19 +0000)]
Merge "[ML][Common] Add unit tests to TensorsData::GetTensorRawData" into tizen
Piotr Kosko [Fri, 12 Feb 2021 07:19:33 +0000 (07:19 +0000)]
Merge "[ML][Common] Add TensorsData.getTensorRawData location/size support" into tizen
Piotr Kosko [Fri, 12 Feb 2021 07:19:29 +0000 (07:19 +0000)]
Merge "[ML][Common] Add unit tests to TensorsData::SetTensorRawData" into tizen
Piotr Kosko [Fri, 12 Feb 2021 07:19:23 +0000 (07:19 +0000)]
Merge "[ML][Common] Add TensorsData.setTensorRawData location/size support" into tizen
Rafal Walczyna [Wed, 3 Feb 2021 14:48:06 +0000 (15:48 +0100)]
[ML][Common] Add unit tests to TensorsData::GetTensorRawData
[==========] 17 tests from 2 test suites ran. (120 ms total)
[ PASSED ] 17 tests.
[Verification] Built successful. Tested on TM1
Change-Id: Ia73add4cab4500de078ce45933ca68f952975e4e
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Mon, 1 Feb 2021 14:55:36 +0000 (15:55 +0100)]
[ML][Common] Add TensorsData.getTensorRawData location/size support
ACR: TWDAPI-273
Test code:
var ti = new tizen.ml.TensorsInfo();
ti.addTensorInfo("tensor", "INT16", [3, 3])
var td = ti.getTensorsData();
td.setTensorRawData(0, [1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 0], [3, 3])
var data = td.getTensorRawData(0, [1, 1], [])
console.log(data)
console.log(data.data)
// Int16Array(4) [5, 6, 8, 9]
// 5, 6
// 8, 9
data = td.getTensorRawData(0, [0, 0], [3, 1])
console.log(data)
console.log(data.data)
// Int16Array(3) [1, 2, 3]
// 1, 2, 3
data = td.getTensorRawData(0, [2, 0], [1, 2])
console.log(data)
console.log(data.data)
// Int16Array(2) [3, 6]
// 3
// 6
data = td.getTensorRawData(0, [], [1, 1])
console.log(data)
console.log(data.data)
// Int16Array(1) [1]
data = td.getTensorRawData(0, [0, 1], [-1,1])
console.log(data)
console.log(data.data)
// Int16Array(1) [3] (4, 5, 6)
[Verification] Built successful. Tested in Chrome Dev console.
Change-Id: Ife781390e8806309bc72963f43a5d001bcd2f5c2
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Pawel Wasowski [Wed, 10 Feb 2021 09:20:12 +0000 (10:20 +0100)]
[ML] Fix issues found by SVACE
This commit fixes the following SVACE problems (WGIDs) in ML:
456856, 456857, 456858
[Verification] Code compiles. The changed code was tested with the
snippets below
// Source
var pipeline_input = tizen.ml.pipeline.createPipeline("appsrc name=srcx ! "
+ "other/tensor,dimension=(string)1:1:1:1,type=(string)int8,"
+"framerate=(fraction)0/1 ! tensor_sink name=sinkx")
var source_input = pipeline_input.getSource("srcx")
// Valve
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);});
// READY
// PAUSED
var v = pipeline.getValve('valve1')
// Valve {name: "valve1", _pipeline_id: 1}
// Switch
var pipeline_def = "videotestsrc is-live=true"
+ " ! videoconvert"
+ " ! tensor_converter"
+ " ! output-selector name=outs outs.src_0"
+ " ! tensor_sink name=sink0 async=false outs.src_1"
+ " ! tensor_sink name=sink1 async=false"
var pipeline = tizen.ml.pipeline.createPipeline(pipeline_def, function(state) {console.log(state);})
pipeline.getSwitch('outs')
// Switch {name: "outs", type: "OUTPUT_SELECTOR", _pipeline_id: 3}
Change-Id: I9316f6a9f6f225aaa741e25458b53109f7c17c16
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
Rafal Walczyna [Tue, 2 Feb 2021 14:38:14 +0000 (15:38 +0100)]
[ML][Common] Add unit tests to TensorsData::SetTensorRawData
[==========] 10 tests from 1 test suite ran. (60 ms total)
[ PASSED ] 10 tests.
[Verification] Built successful. Tested on TM1.
Change-Id: I1b89508d28973e3b4ed7ae4a39eee88fb8685fbe
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Tue, 26 Jan 2021 12:46:17 +0000 (13:46 +0100)]
[ML][Common] Add TensorsData.setTensorRawData location/size support
ACR: TWDAPI-273
Test code:
var ti = new tizen.ml.TensorsInfo();
ti.addTensorInfo("tensor", "INT16", [3, 3])
var td = ti.getTensorsData();
console.log(td.getTensorRawData(0).data)
// Int16Array(9) [0, 0, 0, 0, 0, 0, 0, 0, 0]
// 0 0 0
// 0 0 0
// 0 0 0
td.setTensorRawData(0, [1, 2, 3], [0, 2], [3, 1])
console.log(td.getTensorRawData(0).data)
// Int16Array(9) [0, 0, 0, 0, 0, 0, 1, 2, 3]
// 0 0 0
// 0 0 0
// 1 2 3
td.setTensorRawData(0, [4, 5, 6], [2, 0], [1, 3])
console.log(td.getTensorRawData(0).data)
// Int16Array(9) [0, 0, 4, 0, 0, 5, 1, 2, 6]
// 0 0 4
// 0 0 5
// 1 2 6
td.setTensorRawData(0, [9], [1, 1], [1, 1])
console.log(td.getTensorRawData(0).data)
// Int16Array(9) [0, 0, 4, 0, 9, 5, 1, 2, 6]
// 0 0 4
// 0 9 5
// 1 2 6
td.setTensorRawData(0, [-4,3,-7], [0, 2], [-1, 1])
console.log(td.getTensorRawData(0).data)
// Int16Array(9) [0, 0, 4, 0, 9, 5, -4, 3, -7]
// 0 0 4
// 0 9 5
// -4 3 -7
[Verification] Built successful. Tested in Chrome Dev console.
Change-Id: Ibc4ae4ddef35941678a765acd5a300cefa6671b0
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Pawel Wasowski [Wed, 10 Feb 2021 09:18:19 +0000 (10:18 +0100)]
[Notification] Fix SVACE issue
This commit fixes SVACE issue with WGID: 449860
[Verification] tct-notification-tizen-tests (auto): 100% pass rate
(The CommonNotification::SetAppControlInfoFrmJson function that was
changed, was called several times during tests)
Change-Id: If1caa5d141edb6c776a49ee9c2bfa5abc575efab
Piotr Kosko [Wed, 3 Feb 2021 09:14:15 +0000 (09:14 +0000)]
Merge "[ML][Pipeline] Input data" into tizen
Lukasz Bardeli [Fri, 29 Jan 2021 11:43:15 +0000 (12:43 +0100)]
[ML][Pipeline] Input data
ACR: TWDAPI-274
[Verification] Code compiles without error. Tested in chrome console.
var pipeline_input = tizen.ml.pipeline.createPipeline("appsrc name=srcx ! other/tensor,dimension=(string)1:1:1:1,type=(string)int8,framerate=(fraction)0/1 ! tensor_sink name=sinkx")
var source_input = pipeline_input.getSource("srcx")
var ti = new tizen.ml.TensorsInfo();
ti.addTensorInfo("tensor1", "UINT8", [1, 1])
var td = ti.getTensorsData();
console.log(td.count)
source_input.inputData(td)
tensor_input = source_input.inputTensorsInfo
td_input = tensor_input.getTensorsData()
tt = td_input.tensorsInfo
console.log(tt.getTensorName(0))
Change-Id: I4dd4c3cec5d77d36598551a5d3aa8d8a9fbc9b5a
Signed-off-by: Lukasz Bardeli <l.bardeli@samsung.com>
Pawel Wasowski [Mon, 1 Feb 2021 14:01:02 +0000 (15:01 +0100)]
[ML][common] Add a method for cloning native tensors
ACR: TWDAPI-273/TWDAPI-274
This commit adds a method for cloning data and info from
ml_tensors_data_h and ml_tensors_info_h to TensorsData and related
TensorsInfo objects.
[Verification] Code compiles. Operation is verified in the next commit.
Change-Id: I0268e4d902b7f9a25b5ae531471cdf2028acd77b
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>
[ML] Fixed logger type with macro
For some architectures int64_t is not casted to lld, for partablitiy
stackoverflow suggests using macro.
[Verification] Code compiles for aarch64 architecture
Change-Id: I7aaa3dabeacae6ea7b212c09c5070ff011c64ab1
Piotr Kosko [Mon, 1 Feb 2021 07:33:51 +0000 (07:33 +0000)]
Merge "[systeminfo] Prevent possible crash when failure initialization" into tizen
[systeminfo] Prevent possible crash when failure initialization
SVACE: 456450
[verification] Code compiles without errors
Change-Id: I0b2f0c0c8d27ff0cc6edf3099f7ec77a2d825c7c
Rafal Walczyna [Thu, 28 Jan 2021 16:35:08 +0000 (17:35 +0100)]
[ML][Common] Add TensorRawData and size/location validation on JS side
C++ validation will be added in future commit
Test code:
var ti = new tizen.ml.TensorsInfo();
ti.addTensorInfo("tensor1", "UINT8", [1, 1])
ti.addTensorInfo("tensor2", "INT16", [2, 4])
ti.addTensorInfo("tensor3", "FLOAT32", [2, 2])
var td = ti.getTensorsData();
console.log(td.getTensorRawData(0))
console.log(td.getTensorRawData(1))
console.log(td.getTensorRawData(2))
[Verification] Built successful. Tested in Chrome Dev console.
Change-Id: I14caa9a91b04ed2664cca241da54977a711b1abd
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Mon, 25 Jan 2021 14:31:38 +0000 (15:31 +0100)]
[ML][Common] Add TensorsData.setTensorRawData method
ACR: TWDAPI-273
Test code:
var ti = new tizen.ml.TensorsInfo();
ti.addTensorInfo("tensor1", "UINT8", [1, 1])
var td = ti.getTensorsData();
console.log(td.getTensorRawData(0));
td.setTensorRawData(0, [13]);
console.log(td.getTensorRawData(0));
[Verification] Built successful. Tested in Chrome Dev console.
Change-Id: I522112df9a69f1a5ec7bbcbc12094296a11ec1c9
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Rafal Walczyna [Mon, 25 Jan 2021 14:51:40 +0000 (15:51 +0100)]
[ML][Common] Add TensorsData.getTensorRawData method
ACR: TWDAPI-273
Test code:
var ti = new tizen.ml.TensorsInfo();
var types = ["INT8", "INT16", "INT32", "INT64", "UINT8", "UINT16",
"UINT32", "UINT64", "FLOAT32", "FLOAT64" ]
types.forEach((t) => {
ti.addTensorInfo("", t, [3, 3, 2]);
})
var td = ti.getTensorsData();
for(var i = 0; i < 10; i++) {
console.log(td.getTensorRawData(i));
}
[Verification] Built successful. Tested in Chrome Dev console.
Change-Id: Ia3772b7488d48a593f03dcd158ee66092633d886
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
Pawel Wasowski [Thu, 21 Jan 2021 09:19:14 +0000 (10:19 +0100)]
[ML][pipeline] implement Valve::{setOpen, isOpen}
ACR: TWDAPI-274
[Verification] Tested in Chrome DevTools with the snippets below, 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);});
// READY
// PAUSED
var v = pipeline.getValve('valve1')
// Valve {name: "valve1", _pipeline_id: 1}
v.isOpen
// true
pipeline.isOpen = false
v.isOpen
// true
v.setOpen(false)
v.isOpen
// false
Change-Id: Ibdeaba23082356b5143c2a1796bbd181b4d5d027
Signed-off-by: Pawel Wasowski <p.wasowski2@samsung.com>