Initialize Smart Camera project
[apps/native/smart-camera.git] / src / resource_camera.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
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 <camera.h>
18 #include <stdlib.h>
19 #include <pthread.h>
20
21 #include "controller.h"
22 #include "log.h"
23 #include "resource_camera.h"
24 #define DEFAULT_CAMERA_IMAGE_WIDTH 320 //int
25 #define DEFAULT_CAMERA_IMAGE_HEIGHT 240 //int
26 #define DEFAULT_CAMERA_IMAGE_QUALITY 100 //1~100
27
28 //      실습 3. 카메라 데이터
29 struct __camera_data {
30         camera_h cam_handle;
31
32         void *captured_file;
33         unsigned int image_size;
34
35         capture_completed_cb capture_completed_cb;
36         void *capture_completed_cb_data;
37
38         bool is_capturing;
39         bool is_focusing;
40         bool is_af_enabled;
41 };
42
43 static struct __camera_data *camera_data = NULL;
44
45 static const char * __cam_err_to_str(camera_error_e err)
46 {
47         const char *err_str;
48
49         switch (err) {
50         case CAMERA_ERROR_NONE:
51                 err_str = "CAMERA_ERROR_NONE";
52                 break;
53         case CAMERA_ERROR_INVALID_PARAMETER:
54                 err_str = "CAMERA_ERROR_INVALID_PARAMETER";
55                 break;
56         case CAMERA_ERROR_INVALID_STATE:
57                 err_str = "CAMERA_ERROR_INVALID_STATE";
58                 break;
59         case CAMERA_ERROR_OUT_OF_MEMORY:
60                 err_str = "CAMERA_ERROR_OUT_OF_MEMORY";
61                 break;
62         case CAMERA_ERROR_DEVICE:
63                 err_str = "CAMERA_ERROR_DEVICE";
64                 break;
65         case CAMERA_ERROR_INVALID_OPERATION:
66                 err_str = "CAMERA_ERROR_INVALID_OPERATION";
67                 break;
68         case CAMERA_ERROR_SOUND_POLICY:
69                 err_str = "CAMERA_ERROR_SOUND_POLICY";
70                 break;
71         case CAMERA_ERROR_SECURITY_RESTRICTED:
72                 err_str = "CAMERA_ERROR_SECURITY_RESTRICTED";
73                 break;
74         case CAMERA_ERROR_DEVICE_BUSY:
75                 err_str = "CAMERA_ERROR_DEVICE_BUSY";
76                 break;
77         case CAMERA_ERROR_DEVICE_NOT_FOUND:
78                 err_str = "CAMERA_ERROR_DEVICE_NOT_FOUND";
79                 break;
80         case CAMERA_ERROR_SOUND_POLICY_BY_CALL:
81                 err_str = "CAMERA_ERROR_SOUND_POLICY_BY_CALL";
82                 break;
83         case CAMERA_ERROR_SOUND_POLICY_BY_ALARM:
84                 err_str = "CAMERA_ERROR_SOUND_POLICY_BY_ALARM";
85                 break;
86         case CAMERA_ERROR_ESD:
87                 err_str = "CAMERA_ERROR_ESD";
88                 break;
89         case CAMERA_ERROR_PERMISSION_DENIED:
90                 err_str = "CAMERA_ERROR_PERMISSION_DENIED";
91                 break;
92         case CAMERA_ERROR_NOT_SUPPORTED:
93                 err_str = "CAMERA_ERROR_NOT_SUPPORTED";
94                 break;
95         case CAMERA_ERROR_RESOURCE_CONFLICT:
96                 err_str = "CAMERA_ERROR_RESOURCE_CONFLICT";
97                 break;
98         case CAMERA_ERROR_SERVICE_DISCONNECTED:
99                 err_str = "CAMERA_ERROR_SERVICE_DISCONNECTED";
100                 break;
101         default:
102                 err_str = "Unknown";
103                 break;
104         }
105         return err_str;
106 }
107
108 static void __print_thread_id(char *msg)
109 {
110     pthread_t id;
111     id = pthread_self();
112     _D("[%s] tid %u", msg,  (unsigned int)id);
113
114 }
115
116 static void __print_camera_state(camera_state_e previous, camera_state_e current, bool by_policy, void *user_data)
117 {
118         switch (current) {
119         case CAMERA_STATE_CREATED:
120                 _D("Camera state: CAMERA_STATE_CREATED");
121                 break;
122
123         case CAMERA_STATE_PREVIEW:
124                 _D("Camera state: CAMERA_STATE_PREVIEW");
125                 break;
126
127         case CAMERA_STATE_CAPTURING:
128                 _D("Camera state: CAMERA_STATE_CAPTURING");
129                 break;
130
131         case CAMERA_STATE_CAPTURED:
132                 _D("Camera state: CAMERA_STATE_CAPTURED");
133                 break;
134
135         default:
136                 _D("Camera state: CAMERA_STATE_NONE");
137                 break;
138         }
139 }
140
141 static bool __camera_attr_supported_af_mode_cb(camera_attr_af_mode_e mode, void *user_data)
142 {
143         struct __camera_data *camera_data = user_data;
144
145         _I("Auto-Focus Mode [%d]", mode);
146
147         if (mode != CAMERA_ATTR_AF_NONE)
148                 camera_data->is_af_enabled = true;
149
150         return true;
151 }
152
153 static void __capturing_cb(camera_image_data_s *image, camera_image_data_s *postview, camera_image_data_s *thumbnail, void *user_data)
154 {
155         struct __camera_data *camera_data = user_data;
156         if (image == NULL) {
157                 _E("Image is NULL");
158                 return;
159         }
160
161         __print_thread_id("CAPTURING");
162
163         free(camera_data->captured_file);
164         camera_data->captured_file = malloc(image->size);
165         if (camera_data->captured_file == NULL)
166                 return;
167
168         _D("Now is on Capturing: Image size[%d x %d]", image->width, image->height);
169
170 //      실습 6. 이미지 파일 복사
171         memcpy(camera_data->captured_file, image->data, image->size);
172         camera_data->image_size = image->size;
173
174         return;
175 }
176
177 static void __completed_cb(void *user_data)
178 {
179         int ret = 0;
180         struct __camera_data *camera_data = user_data;
181
182         _D("Capture is completed");
183
184 //      실습 7. 촬영 종료
185         if (camera_data->capture_completed_cb)
186                 camera_data->capture_completed_cb(camera_data->captured_file, camera_data->image_size, camera_data->capture_completed_cb_data);
187
188         camera_data->capture_completed_cb = NULL;
189         free(camera_data->captured_file);
190         camera_data->captured_file = NULL;
191
192         if (!camera_data->cam_handle) {
193                 _E("Camera is NULL");
194                 return;
195         }
196
197         ret = camera_start_preview(camera_data->cam_handle);
198         if (ret != CAMERA_ERROR_NONE) {
199                 _E("Failed to start preview [%s]", __cam_err_to_str(ret));
200                 return;
201         }
202
203         ret = camera_stop_preview(camera_data->cam_handle);
204         if (ret != CAMERA_ERROR_NONE) {
205                 _E("Failed to stop preview [%s]", __cam_err_to_str(ret));
206                 return;
207         }
208
209     if (camera_data->is_focusing)
210         camera_data->is_focusing = false;
211
212     if (camera_data->is_capturing)
213         camera_data->is_capturing = false;
214
215     return;
216 }
217
218 static void __start_capture(void *user_data)
219 {
220         int ret = 0;
221         struct __camera_data *camera_data = user_data;
222
223         ret = camera_start_capture(camera_data->cam_handle, __capturing_cb, __completed_cb, camera_data);
224         if (ret != CAMERA_ERROR_NONE) {
225                 _E("Failed to start capturing [%s]", __cam_err_to_str(ret));
226                 camera_data->is_focusing = false;
227                 return;
228         }
229
230         camera_data->is_capturing = true;
231 }
232
233 static void __camera_focus_cb(camera_focus_state_e state, void *user_data)
234 {
235         struct __camera_data *camera_data = user_data;
236         _D("Camera focus state: [%d]", state);
237
238         if (camera_data->is_af_enabled && state == CAMERA_FOCUS_STATE_FOCUSED && !camera_data->is_capturing) {
239                 __start_capture(camera_data);
240         }
241 }
242
243 static void __camera_preview_cb(camera_preview_data_s *frame, void *user_data)
244 {
245     __print_thread_id("PREVIEW Callback");
246 }
247
248 static int __init(void)
249 {
250         int ret = CAMERA_ERROR_NONE;
251
252         camera_data = malloc(sizeof(struct __camera_data));
253         if (camera_data == NULL) {
254                 _E("Failed to allocate Camera data");
255                 return -1;
256         }
257         memset(camera_data, 0, sizeof(struct __camera_data));
258
259         ret = camera_create(CAMERA_DEVICE_CAMERA0, &(camera_data->cam_handle));
260         if (ret != CAMERA_ERROR_NONE) {
261                 _E("Failed to create camera [%s]", __cam_err_to_str(ret));
262                 goto ERROR;
263         }
264
265         ret = camera_attr_set_image_quality(camera_data->cam_handle, DEFAULT_CAMERA_IMAGE_QUALITY);
266         if (ret != CAMERA_ERROR_NONE) {
267                 _E("Failed to set image quality [%s]", __cam_err_to_str(ret));
268                 goto ERROR;
269         }
270
271         ret = camera_set_preview_resolution(camera_data->cam_handle, DEFAULT_CAMERA_IMAGE_WIDTH, DEFAULT_CAMERA_IMAGE_HEIGHT);
272         if (ret != CAMERA_ERROR_NONE) {
273                 _E("Failed to set preview resolution [%s]", __cam_err_to_str(ret));
274                 goto ERROR;
275         }
276
277         ret = camera_set_capture_resolution(camera_data->cam_handle, DEFAULT_CAMERA_IMAGE_WIDTH, DEFAULT_CAMERA_IMAGE_HEIGHT);
278         if (ret != CAMERA_ERROR_NONE) {
279                 _E("Failed to set capture resolution [%s]", __cam_err_to_str(ret));
280                 goto ERROR;
281         }
282
283         ret = camera_set_capture_format(camera_data->cam_handle, CAMERA_PIXEL_FORMAT_JPEG);
284         if (ret != CAMERA_ERROR_NONE) {
285                 _E("Failed to set capture format [%s]", __cam_err_to_str(ret));
286                 goto ERROR;
287         }
288
289         ret = camera_set_state_changed_cb(camera_data->cam_handle, __print_camera_state, NULL);
290         if (ret != CAMERA_ERROR_NONE) {
291                 _E("Failed to set state changed callback [%s]", __cam_err_to_str(ret));
292                 goto ERROR;
293         }
294
295 //      실습 4. 카메라 초기화
296         ret = camera_set_preview_cb(camera_data->cam_handle, __camera_preview_cb, camera_data);
297         if (ret != CAMERA_ERROR_NONE) {
298                 _E("Failed to set preview callback [%s]", __cam_err_to_str(ret));
299                 goto ERROR;
300         }
301
302         ret = camera_set_focus_changed_cb(camera_data->cam_handle, __camera_focus_cb, camera_data);
303         if (ret != CAMERA_ERROR_NONE) {
304                 _E("Failed to set focus changed callback [%s]", __cam_err_to_str(ret));
305                 goto ERROR;
306         }
307
308         ret = camera_attr_foreach_supported_af_mode(camera_data->cam_handle, __camera_attr_supported_af_mode_cb, camera_data);
309         if (ret != CAMERA_ERROR_NONE) {
310                 _E("Failed to set auto focus attribute check callback [%s]", __cam_err_to_str(ret));
311                 goto ERROR;
312         }
313
314         return 0;
315
316 ERROR:
317         if (camera_data->cam_handle)
318                 camera_destroy(camera_data->cam_handle);
319
320         free(camera_data);
321         camera_data = NULL;
322         return -1;
323 }
324
325 int resource_camera_capture(capture_completed_cb capture_completed_cb, void *user_data)
326 {
327         camera_state_e state;
328         int ret = CAMERA_ERROR_NONE;
329
330         if (camera_data == NULL) {
331                 _I("Camera is not initialized");
332                 ret = __init();
333                 if (ret < 0) {
334                         _E("Failed to initialize camera");
335                         return -1;
336                 }
337         }
338
339         ret = camera_get_state(camera_data->cam_handle, &state);
340         if (ret != CAMERA_ERROR_NONE) {
341                 _E("Failed to get camera state [%s]", __cam_err_to_str(ret));
342                 return -1;
343         }
344
345         if (state == CAMERA_STATE_CAPTURING) {
346                 _D("Camera is now capturing");
347                 return -1;
348         }
349
350         if (state == CAMERA_STATE_PREVIEW) {
351                 _I("Capturing is not completed");
352                 ret = camera_stop_preview(camera_data->cam_handle);
353                 if (ret != CAMERA_ERROR_NONE) {
354                         _E("Failed to stop preview [%s]", __cam_err_to_str(ret));
355                         return -1;
356                 }
357                 camera_data->is_capturing = false;
358                 camera_data->is_focusing = false;
359         }
360
361         //      실습 5. 사진 찍기
362         camera_data->capture_completed_cb = capture_completed_cb;
363         camera_data->capture_completed_cb_data = user_data;
364
365         ret = camera_start_preview(camera_data->cam_handle);
366         if (ret != CAMERA_ERROR_NONE) {
367                 _E("Failed to start preview [%s]", __cam_err_to_str(ret));
368         }
369
370         if (!camera_data->is_af_enabled) {
371                 __start_capture(camera_data);
372         } else {
373                 ret = camera_start_focusing(camera_data->cam_handle, true);
374
375                 if (ret == CAMERA_ERROR_NOT_SUPPORTED) {
376                         camera_data->is_af_enabled = false;
377                         return -1;
378                 }
379
380                 camera_data->is_focusing = true;
381         }
382
383         return 0;
384 }
385
386 void resource_camera_close(void)
387 {
388         if (camera_data == NULL)
389                 return;
390
391         camera_stop_preview(camera_data->cam_handle);
392
393         camera_destroy(camera_data->cam_handle);
394         camera_data->cam_handle = NULL;
395
396         free(camera_data->captured_file);
397         camera_data->captured_file = NULL;
398
399         free(camera_data);
400         camera_data = NULL;
401 }