Setting since_tizen 3/4 on Tizen.NET API
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Vision / MediaVision / FaceDetector.cs
1 /*
2  * Copyright (c) 2016 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.Threading.Tasks;
19 using InteropFace = Interop.MediaVision.Face;
20
21 namespace Tizen.Multimedia.Vision
22 {
23     /// <summary>
24     /// Provides the ability to detect faces on image sources.
25     /// </summary>
26     /// <since_tizen> 4 </since_tizen>
27     public static class FaceDetector
28     {
29
30         /// <summary>
31         /// Detects faces on the source.<br/>
32         /// Each time when DetectAsync is called, a set of the detected faces at the media source are received asynchronously.
33         /// </summary>
34         /// <param name="source">The source of the media where faces will be detected.</param>
35         /// <returns>A task that represents the asynchronous detect operation.</returns>
36         /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
37         /// <exception cref="NotSupportedException">
38         ///     The feature is not supported.<br/>
39         ///     -or-<br/>
40         ///     The format of <paramref name="source"/> is not supported.
41         /// </exception>
42         /// <feature>http://tizen.org/feature/vision.face_recognition</feature>
43         /// <since_tizen> 4 </since_tizen>
44         public static async Task<Rectangle[]> DetectAsync(MediaVisionSource source)
45         {
46             return await DetectAsync(source, null);
47         }
48
49         /// <summary>
50         /// Detects faces on the source.<br/>
51         /// Each time when DetectAsync is called, a set of the detected faces at the media source are received asynchronously.
52         /// </summary>
53         /// <param name="source">The source of the media where faces will be detected.</param>
54         /// <param name="config">The configuration of engine will be used for detecting. This value can be null.</param>
55         /// <returns>A task that represents the asynchronous detect operation.</returns>
56         /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
57         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
58         /// <feature>http://tizen.org/feature/vision.face_recognition</feature>
59         /// <since_tizen> 4 </since_tizen>
60         public static async Task<Rectangle[]> DetectAsync(MediaVisionSource source,
61             FaceDetectionConfiguration config)
62         {
63             if (source == null)
64             {
65                 throw new ArgumentNullException(nameof(source));
66             }
67
68             TaskCompletionSource<Rectangle[]> tcs = new TaskCompletionSource<Rectangle[]>();
69
70             using (var cb = ObjectKeeper.Get(GetCallback(tcs)))
71             {
72                 InteropFace.Detect(source.Handle, EngineConfiguration.GetHandle(config), cb.Target).
73                     Validate("Failed to perform face detection");
74
75                 return await tcs.Task;
76             }
77         }
78
79         private static InteropFace.DetectedCallback GetCallback(TaskCompletionSource<Rectangle[]> tcs)
80         {
81             return (IntPtr sourceHandle, IntPtr engineConfig, global::Interop.MediaVision.Rectangle[] facesLocations,
82                 int numberOfFaces, IntPtr _) =>
83             {
84                 try
85                 {
86                     Log.Info(MediaVisionLog.Tag, $"Faces detected, count : {numberOfFaces}.");
87                     Rectangle[] locations = new Rectangle[numberOfFaces];
88                     for (int i = 0; i < numberOfFaces; i++)
89                     {
90                         locations[i] = facesLocations[i].ToApiStruct();
91                         Log.Info(MediaVisionLog.Tag, $"Face {0} detected : {locations}.");
92                     }
93
94                     if (!tcs.TrySetResult(locations))
95                     {
96                         Log.Error(MediaVisionLog.Tag, "Failed to set face detection result.");
97                     }
98                 }
99                 catch (Exception e)
100                 {
101                     MultimediaLog.Info(MediaVisionLog.Tag, "Failed to handle face detection.", e);
102                     tcs.TrySetException(e);
103                 }
104             };
105         }
106     }
107 }