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