Release 4.0.0-preview1-00051
[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
23 {
24     /// <summary>
25     /// Provides the ability to track faces on image sources.
26     /// </summary>
27     /// <since_tizen> 3</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 model will try to learn
37         /// (if it supports learning feature), otherwise 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.\n
42         ///     -or-\n
43         ///     <paramref name="trackingModel"/> is null.
44         /// </exception>
45         /// <exception cref="ObjectDisposedException">
46         ///     <paramref name="source"/> has already been disposed of.\n
47         ///     -or-\n
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         /// <since_tizen> 3</since_tizen>
53         public static async Task<FaceTrackingResult> TrackAsync(MediaVisionSource source,
54             FaceTrackingModel trackingModel, bool doLearn)
55         {
56             if (source == null)
57             {
58                 throw new ArgumentNullException(nameof(source));
59             }
60             if (trackingModel == null)
61             {
62                 throw new ArgumentNullException(nameof(trackingModel));
63             }
64
65             TaskCompletionSource<FaceTrackingResult> tcs = new TaskCompletionSource<FaceTrackingResult>();
66
67             using (var cb = ObjectKeeper.Get(GetTrackCallback(tcs)))
68             {
69                 InteropFace.Track(source.Handle, trackingModel.Handle, IntPtr.Zero,
70                     cb.Target, doLearn).Validate("Failed to perform face tracking.");
71
72                 return await tcs.Task;
73             }
74         }
75
76         private static InteropFace.TrackedCallback GetTrackCallback(TaskCompletionSource<FaceTrackingResult> tcs)
77         {
78             return (IntPtr sourceHandle, IntPtr trackingModelHandle, IntPtr engineCfgHandle,
79                 IntPtr locationPtr, double confidence, IntPtr _) =>
80             {
81                 try
82                 {
83                     Quadrangle area = null;
84                     if (locationPtr != IntPtr.Zero)
85                     {
86                         area = Marshal.PtrToStructure<global::Interop.MediaVision.Quadrangle>(locationPtr).ToApiStruct();
87                     }
88
89                     Log.Info(MediaVisionLog.Tag, $"Tracked area : {area}, confidence : {confidence}");
90
91                     if (!tcs.TrySetResult(new FaceTrackingResult(locationPtr != IntPtr.Zero, confidence, area)))
92                     {
93                         Log.Error(MediaVisionLog.Tag, "Failed to set tracking result");
94                     }
95                 }
96                 catch (Exception e)
97                 {
98                     MultimediaLog.Error(MediaVisionLog.Tag, "Setting tracking result failed.", e);
99                     tcs.TrySetException(e);
100                 }
101             };
102         }
103     }
104 }