[WebRTC] Add new APIs for WebRTC transceiver codec (#4509)
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Vision / MediaVision / ObjectDetector.cs
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 using System.Threading.Tasks;
21 using InteropInference = Interop.MediaVision.Inference;
22
23 namespace Tizen.Multimedia.Vision
24 {
25     /// <summary>
26     /// Provides the ability to detect objects and get its locations on image source using inference engine.
27     /// </summary>
28     /// <since_tizen> 6 </since_tizen>
29     public static class ObjectDetector
30     {
31         /// <summary>
32         /// Detects objects and gets its locations on the source image using inference engine set in <paramref name="config"/>.<br/>
33         /// Each time when DetectAsync is called, a set of the detected objects at the media source are received asynchronously.
34         /// </summary>
35         /// <feature>http://tizen.org/feature/vision.inference</feature>
36         /// <feature>http://tizen.org/feature/vision.inference.image</feature>
37         /// <param name="source">The source of the media where faces will be detected.</param>
38         /// <param name="config">The engine's configuration that will be used for detecting.</param>
39         /// <returns>
40         /// A task that represents the asynchronous detect operation.<br/>
41         /// If there's no detected object, empty collection will be returned.
42         /// </returns>
43         /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="config"/> is null.</exception>
44         /// <exception cref="InvalidOperationException">Internal error.</exception>
45         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
46         /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
47         /// <seealso cref="InferenceModelConfiguration"/>
48         /// <since_tizen> 6 </since_tizen>
49         public static async Task<IEnumerable<ObjectDetectionResult>> DetectAsync(MediaVisionSource source,
50             InferenceModelConfiguration config)
51         {
52             // `vision.inference` feature is already checked, when config is created.
53             ValidationUtil.ValidateFeatureSupported(VisionFeatures.InferenceImage);
54
55             if (source == null)
56             {
57                 throw new ArgumentNullException(nameof(source));
58             }
59             if (config == null)
60             {
61                 throw new ArgumentNullException(nameof(config));
62             }
63
64             var tcs = new TaskCompletionSource<IEnumerable<ObjectDetectionResult>>();
65
66             using (var cb = ObjectKeeper.Get(GetCallback(tcs)))
67             {
68                 InteropInference.DetectObject(source.Handle, config.GetHandle(), cb.Target).
69                     Validate("Failed to detect object.");
70
71                 return await tcs.Task;
72             }
73         }
74
75         private static InteropInference.ObjectDetectedCallback GetCallback(TaskCompletionSource<IEnumerable<ObjectDetectionResult>> tcs)
76         {
77             return (IntPtr sourceHandle, int numberOfObjects, int[] indices, string[] names, float[] confidences,
78                 global::Interop.MediaVision.Rectangle[] locations, IntPtr _) =>
79             {
80                 try
81                 {
82                     if (!tcs.TrySetResult(GetResults(numberOfObjects, indices, names, confidences, locations)))
83                     {
84                         Log.Error(MediaVisionLog.Tag, "Failed to set object detection result.");
85                     }
86                 }
87                 catch (Exception e)
88                 {
89                     tcs.TrySetException(e);
90                 }
91             };
92         }
93
94         private static IEnumerable<ObjectDetectionResult> GetResults(int number, int[] indices,
95             string[] names, float[] confidences, global::Interop.MediaVision.Rectangle[] locations)
96         {
97             if (number == 0)
98             {
99                 return Enumerable.Empty<ObjectDetectionResult>();
100             }
101
102             var results = new List<ObjectDetectionResult>();
103
104             for (int i = 0; i < number; i++)
105             {
106                 results.Add(new ObjectDetectionResult(indices[i], names[i], confidences[i], locations[i]));
107             }
108
109             return results;
110         }
111     }
112 }