5541e817c087c8760c19109c066e5c7573e0010e
[platform/core/api/mediavision.git] / mv_machine_learning / face_recognition / src / mv_face_recognition_open.cpp
1 /**
2  * Copyright (c) 2022 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 #include <algorithm>
18 #include <dlog.h>
19 #include <memory>
20
21 #include "face_recognition_adapter.h"
22 #include "facenet_adapter.h"
23 #include "mv_face_recognition_open.h"
24 #include "machine_learning_exception.h"
25 #include "context.h"
26
27 using namespace std;
28 using namespace mediavision::common;
29 using namespace mediavision::machine_learning;
30 using namespace mediavision::machine_learning::face_recognition;
31 using namespace mediavision::machine_learning::exception;
32 using FaceRecognitionTask = ITask<mv_face_recognition_input_s, mv_face_recognition_result_s>;
33 using FacenetTask = ITask<facenet_input_s, facenet_output_s>;
34
35 int mv_face_recognition_create_open(mv_face_recognition_h *handle)
36 {
37         if (!handle) {
38                 LOGE("Handle can't be created because handle pointer is NULL");
39                 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
40         }
41
42         Context *context = new (nothrow) Context();
43         if (!context) {
44                 LOGE("Fail to allocate a context.");
45                 return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
46         }
47
48         FaceRecognitionTask *face_recognition_task = new (nothrow)
49                         FaceRecognitionAdapter<mv_face_recognition_input_s, mv_face_recognition_result_s>();
50         if (!face_recognition_task) {
51                 delete context;
52                 LOGE("Fail to allocate a task.");
53                 return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
54         }
55
56         FacenetTask *facenet_task = new (nothrow) FacenetAdapter<facenet_input_s, facenet_output_s>();
57         if (!facenet_task) {
58                 delete face_recognition_task;
59                 delete context;
60                 LOGE("Fail to allocate a task.");
61                 return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
62         }
63
64         pair<map<string, void *>::iterator, bool> result;
65
66         result = context->__tasks.insert(pair<string, void *>("face_recognition", face_recognition_task));
67         if (!result.second) {
68                 delete facenet_task;
69                 delete face_recognition_task;
70                 delete context;
71                 LOGE("Fail to register a new task. Same task already exists.");
72                 return MEDIA_VISION_ERROR_INVALID_OPERATION;
73         }
74
75         result = context->__tasks.insert(pair<string, void *>("facenet", facenet_task));
76         if (!result.second) {
77                 delete facenet_task;
78                 delete face_recognition_task;
79                 delete context;
80                 LOGE("Fail to register a new task. Same task already exists.");
81                 return MEDIA_VISION_ERROR_INVALID_OPERATION;
82         }
83
84         *handle = static_cast<mv_face_recognition_h>(context);
85
86         LOGD("face recognition handle [%p] has been created", *handle);
87
88         return MEDIA_VISION_ERROR_NONE;
89 }
90
91 int mv_face_recognition_destroy_open(mv_face_recognition_h handle)
92 {
93         if (!handle) {
94                 LOGE("Handle is NULL.");
95                 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
96         }
97
98         Context *context = static_cast<Context *>(handle);
99         map<string, void *>::iterator iter;
100
101         for (iter = context->__tasks.begin(); iter != context->__tasks.end(); ++iter) {
102                 if (iter->first.compare("face_recognition") == 0) {
103                         auto face_recognition_task = static_cast<FaceRecognitionTask *>(iter->second);
104                         delete face_recognition_task;
105                 }
106
107                 if (iter->first.compare("facenet") == 0) {
108                         auto facenet_task = static_cast<FacenetTask *>(iter->second);
109                         delete facenet_task;
110                 }
111         }
112
113         delete context;
114
115         LOGD("Face recognition handle has been destroyed");
116
117         return MEDIA_VISION_ERROR_NONE;
118 }
119
120 int mv_face_recognition_prepare_open(mv_face_recognition_h handle)
121 {
122         LOGD("ENTER");
123
124         if (!handle) {
125                 LOGE("Handle is NULL.");
126                 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
127         }
128
129         try {
130                 Context *context = static_cast<Context *>(handle);
131                 auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
132                 auto facenet_task = static_cast<FacenetTask *>(context->__tasks["facenet"]);
133
134                 std::lock_guard<std::mutex> lock(context->_mutex);
135
136                 face_recognition_task->configure();
137                 facenet_task->configure();
138                 face_recognition_task->prepare();
139                 facenet_task->prepare();
140         } catch (const BaseException &e) {
141                 LOGE("%s", e.what());
142                 return e.getError();
143         }
144
145         LOGD("LEAVE");
146
147         return MEDIA_VISION_ERROR_NONE;
148 }
149
150 int mv_face_recognition_register_open(mv_face_recognition_h handle, mv_source_h source, const char *label)
151 {
152         LOGD("ENTER");
153
154         if (!handle) {
155                 LOGE("Handle is NULL.");
156                 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
157         }
158
159         try {
160                 Context *context = static_cast<Context *>(handle);
161                 auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
162                 auto facenet_task = static_cast<FacenetTask *>(context->__tasks["facenet"]);
163
164                 std::lock_guard<std::mutex> lock(context->_mutex);
165
166                 facenet_input_s facenet_input = { { source } };
167
168                 facenet_task->setInput(facenet_input);
169                 facenet_task->perform();
170
171                 facenet_output_s &facenet_output = facenet_task->getOutput();
172                 mv_face_recognition_input_s face_recognition_input = { .mode = mode::REGISTER };
173                 face_recognition_register_input_s facenet_to_face_reg_input = { facenet_output.outputs[0], string(label) };
174
175                 face_recognition_input.register_src.clear();
176                 face_recognition_input.register_src.push_back(facenet_to_face_reg_input);
177                 face_recognition_task->setInput(face_recognition_input);
178                 face_recognition_task->perform();
179         } catch (const BaseException &e) {
180                 LOGE("%s", e.what());
181                 return e.getError();
182         }
183
184         LOGD("LEAVE");
185
186         return MEDIA_VISION_ERROR_NONE;
187 }
188
189 int mv_face_recognition_unregister_open(mv_face_recognition_h handle, const char *label)
190 {
191         LOGD("ENTER");
192
193         if (!handle) {
194                 LOGE("Handle is NULL.");
195                 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
196         }
197
198         try {
199                 Context *context = static_cast<Context *>(handle);
200                 auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
201
202                 std::lock_guard<std::mutex> lock(context->_mutex);
203
204                 mv_face_recognition_input_s input = { mode::DELETE };
205
206                 input.labels.clear();
207                 input.labels.push_back(string(label));
208                 face_recognition_task->setInput(input);
209                 face_recognition_task->perform();
210         } catch (const BaseException &e) {
211                 LOGE("%s", e.what());
212                 return e.getError();
213         }
214
215         LOGD("LEAVE");
216
217         return MEDIA_VISION_ERROR_NONE;
218 }
219
220 int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h source)
221 {
222         LOGD("ENTER");
223
224         if (!handle) {
225                 LOGE("Handle is NULL.");
226                 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
227         }
228
229         try {
230                 Context *context = static_cast<Context *>(handle);
231                 auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
232                 auto facenet_task = static_cast<FacenetTask *>(context->__tasks["facenet"]);
233
234                 std::lock_guard<std::mutex> lock(context->_mutex);
235
236                 facenet_input_s facenet_input = { { source } };
237
238                 facenet_task->setInput(facenet_input);
239                 facenet_task->perform();
240                 facenet_output_s &facenet_output = facenet_task->getOutput();
241
242                 mv_face_recognition_input_s face_recognition_input = { mode::INFERENCE };
243
244                 face_recognition_input.inputs = facenet_output.outputs;
245                 face_recognition_task->setInput(face_recognition_input);
246                 face_recognition_task->perform();
247         } catch (const BaseException &e) {
248                 LOGE("%s", e.what());
249                 return e.getError();
250         }
251
252         LOGD("LEAVE");
253
254         return MEDIA_VISION_ERROR_NONE;
255 }
256
257 int mv_face_recognition_get_label_open(mv_face_recognition_h handle, const char **out_label)
258 {
259         LOGD("ENTER");
260
261         if (!handle) {
262                 LOGE("Handle is NULL.");
263                 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
264         }
265
266         try {
267                 Context *context = static_cast<Context *>(handle);
268                 auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
269
270                 std::lock_guard<std::mutex> lock(context->_mutex);
271
272                 *out_label = face_recognition_task->getOutput().label.c_str();
273         } catch (const BaseException &e) {
274                 LOGE("%s", e.what());
275                 return e.getError();
276         }
277
278         LOGD("LEAVE");
279
280         return MEDIA_VISION_ERROR_NONE;
281 }