[NUI] TCSACR-226 code change (#1032)
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Vision / MediaVision / FaceTracker.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.Runtime.InteropServices;
19 using System.Threading.Tasks;
20 using InteropFace = Interop.MediaVision.Face;
21
22 namespace Tizen.Multimedia.Vision
23 {
24     /// <summary>
25     /// Provides the ability to track faces on image sources.
26     /// </summary>
27     /// <since_tizen> 4 </since_tizen>
28     public static class FaceTracker
29     {
30
31         /// <summary>
32         /// Performs face tracking on the source with the trackingModel.
33         /// </summary>
34         /// <param name="source">The source of the media to recognize face for.</param>
35         /// <param name="trackingModel">The model will be used for tracking.</param>
36         /// <param name="doLearn">The value indicating whether model learning while tracking. If it is true, then the model will try to learn
37         /// (if it supports learning feature), otherwise the model will be not learned during the invoking tracking iteration.
38         /// Learning process improves tracking correctness, but can decrease tracking performance.</param>
39         /// <returns>A task that represents the asynchronous tracking operation.</returns>
40         /// <exception cref="ArgumentNullException">
41         ///     <paramref name="source"/> is null.<br/>
42         ///     -or-<br/>
43         ///     <paramref name="trackingModel"/> is null.
44         /// </exception>
45         /// <exception cref="ObjectDisposedException">
46         ///     <paramref name="source"/> has already been disposed of.<br/>
47         ///     -or-<br/>
48         ///     <paramref name="trackingModel"/> has already been disposed of.
49         /// </exception>
50         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
51         /// <exception cref="InvalidOperationException"><paramref name="trackingModel"/> is not prepared.</exception>
52         /// <feature>http://tizen.org/feature/vision.face_recognition</feature>
53         /// <since_tizen> 4 </since_tizen>
54         public static async Task<FaceTrackingResult> TrackAsync(MediaVisionSource source,
55             FaceTrackingModel trackingModel, bool doLearn)
56         {
57             if (source == null)
58             {
59                 throw new ArgumentNullException(nameof(source));
60             }
61             if (trackingModel == null)
62             {
63                 throw new ArgumentNullException(nameof(trackingModel));
64             }
65
66             TaskCompletionSource<FaceTrackingResult> tcs = new TaskCompletionSource<FaceTrackingResult>();
67
68             using (var cb = ObjectKeeper.Get(GetTrackCallback(tcs)))
69             {
70                 InteropFace.Track(source.Handle, trackingModel.Handle, IntPtr.Zero,
71                     cb.Target, doLearn).Validate("Failed to perform face tracking.");
72
73                 return await tcs.Task;
74             }
75         }
76
77         private static InteropFace.TrackedCallback GetTrackCallback(TaskCompletionSource<FaceTrackingResult> tcs)
78         {
79             return (IntPtr sourceHandle, IntPtr trackingModelHandle, IntPtr engineCfgHandle,
80                 IntPtr locationPtr, double confidence, IntPtr _) =>
81             {
82                 try
83                 {
84                     Quadrangle area = null;
85                     if (locationPtr != IntPtr.Zero)
86                     {
87                         area = Marshal.PtrToStructure<global::Interop.MediaVision.Quadrangle>(locationPtr).ToApiStruct();
88                     }
89
90                     Log.Info(MediaVisionLog.Tag, $"Tracked area : {area}, confidence : {confidence}");
91
92                     if (!tcs.TrySetResult(new FaceTrackingResult(locationPtr != IntPtr.Zero, confidence, area)))
93                     {
94                         Log.Error(MediaVisionLog.Tag, "Failed to set tracking result");
95                     }
96                 }
97                 catch (Exception e)
98                 {
99                     MultimediaLog.Error(MediaVisionLog.Tag, "Setting tracking result failed.", e);
100                     tcs.TrySetException(e);
101                 }
102             };
103         }
104     }
105 }