Update set command function
[platform/adaptation/camera-hal-v4l2.git] / src / tizen_camera_v4l2.c
1 /*
2  * tizen_camera_v4l2.c
3  *
4  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <sys/ioctl.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/mman.h>
28 #include <fcntl.h>
29 #include <inttypes.h>
30 #include <stdio.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <glob.h>
34 #include <dlog.h>
35 #include <sched.h>
36 #include "tizen_camera_v4l2_private.h"
37
38 #ifdef LOG_TAG
39 #undef LOG_TAG
40 #endif /* LOG_TAG */
41 #define LOG_TAG "CAMERA_HAL"
42
43 #define TEST_JPEG_PATH          "/home/owner/media/Images/test.jpg"
44 #define DEVICE_NODE_PATH_MAX    16
45 #define DEVICE_NODE_PATH_PREFIX "/dev/video"
46 #define FOURCC_FORMAT           "%c%c%c%c"
47 #define FOURCC_CONVERT(fourcc)  \
48         fourcc & 0xff,\
49         (fourcc >> 8) & 0xff,\
50         (fourcc >> 16) & 0xff,\
51         (fourcc >> 24) & 0xff
52
53
54 static camera_device_info_list_t *g_device_info_list;
55 static guint32 device_caps;
56 static GMutex g_device_info_lock;
57
58
59 static void _camera_hal_v4l2_destructor(void) __attribute__((destructor));
60
61 static void _camera_hal_v4l2_destructor(void)
62 {
63         LOGD("release device info list %p", g_device_info_list);
64
65         g_free(g_device_info_list);
66
67         return;
68 }
69
70 static int _camera_v4l2_wait_frame(int device_fd, int wait_time)
71 {
72         int ret = CAMERA_ERROR_NONE;
73         fd_set fds;
74         struct timeval timeout;
75
76         if (device_fd < 0) {
77                 LOGE("invalid fd %d", device_fd);
78                 return CAMERA_ERROR_INVALID_PARAMETER;
79         }
80
81         FD_ZERO(&fds);
82         FD_SET(device_fd, &fds);
83
84         memset(&timeout, 0x0, sizeof(struct timeval));
85
86         timeout.tv_sec = wait_time;
87         timeout.tv_usec = 0;
88
89         LOGD("select : %d sec", wait_time);
90
91         ret = select(device_fd + 1, &fds, NULL, NULL, &timeout);
92         if (ret == -1) {
93                 if (EINTR == errno) {
94                         LOGD("select error : EINTR");
95                         return CAMERA_ERROR_NONE;
96                 }
97                 LOGE("select failed. errno %d", errno);
98                 return CAMERA_ERROR_INTERNAL;
99         }
100
101         if (ret == 0) {
102                 LOGE("select timeout.");
103                 return CAMERA_ERROR_INTERNAL;
104         }
105
106         LOGD("select done");
107
108         return CAMERA_ERROR_NONE;
109 }
110
111
112 static int _camera_v4l2_g_ctrl(int device_fd, int cid, int *value)
113 {
114         int ret = 0;
115         struct v4l2_control ctrl;
116
117         if (!value) {
118                 LOGE("NULL param");
119                 return CAMERA_ERROR_INVALID_PARAMETER;
120         }
121
122         memset(&ctrl, 0x0, sizeof(struct v4l2_control));
123
124         ctrl.id = cid;
125
126         ret = ioctl(device_fd, VIDIOC_G_CTRL, &ctrl);
127
128         *value = ctrl.value;
129
130         LOGD("G_CTRL id 0x%x, value %d, ret %d", cid, *value, ret);
131
132         return ret;
133 }
134
135
136 static int _camera_v4l2_s_ctrl(int device_fd, int cid, int value)
137 {
138         int ret = 0;
139         struct v4l2_control ctrl;
140
141         memset(&ctrl, 0x0, sizeof(struct v4l2_control));
142
143         ctrl.id = cid;
144         ctrl.value = value;
145
146         ret = ioctl(device_fd, VIDIOC_S_CTRL, &ctrl);
147
148         LOGD("S_CTRL id 0x%x, value %d, ret %d", cid, value, ret);
149
150         return ret;
151 }
152
153
154 static int _camera_v4l2_stream(int device_fd, int type, gboolean onoff)
155 {
156         if (device_fd < 0) {
157                 LOGE("invalid fd %d", device_fd);
158                 return CAMERA_ERROR_INVALID_PARAMETER;
159         }
160
161         if (ioctl(device_fd, onoff ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type) < 0) {
162                 LOGE("stream %d failed. [t:%d] errno %d", onoff, type, errno);
163                 return CAMERA_ERROR_INTERNAL;
164         }
165
166         LOGD("stream %d done [t:%d]", onoff, type);
167
168         return CAMERA_ERROR_NONE;
169 }
170
171
172 static int _camera_v4l2_reqbufs(int device_fd, int type, int memory, int count, int *result_count)
173 {
174         struct v4l2_requestbuffers v4l2_reqbuf;
175
176         if (device_fd < 0) {
177                 LOGE("invalid fd %d", device_fd);
178                 return CAMERA_ERROR_INVALID_PARAMETER;
179         }
180
181         if (!result_count) {
182                 LOGE("NULL parameter");
183                 return CAMERA_ERROR_INVALID_PARAMETER;
184         }
185
186         memset(&v4l2_reqbuf, 0x0, sizeof(struct v4l2_requestbuffers));
187
188         v4l2_reqbuf.type = type;
189         v4l2_reqbuf.memory = memory;
190         v4l2_reqbuf.count = count;
191
192         if (ioctl(device_fd, VIDIOC_REQBUFS, &v4l2_reqbuf) < 0) {
193                 LOGE("REQBUFS[count %d] failed. errno %d", count, errno);
194                 return CAMERA_ERROR_INTERNAL;
195         }
196
197         if (v4l2_reqbuf.count != count)
198                 LOGW("different count [req:%d, result:%d]", count, v4l2_reqbuf.count);
199
200         *result_count = v4l2_reqbuf.count;
201
202         return CAMERA_ERROR_NONE;
203 }
204
205
206 static int _camera_v4l2_qbuf(int device_fd, int type, int memory, int index)
207 {
208         struct v4l2_buffer v4l2_buf;
209         struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];
210
211         if (device_fd < 0) {
212                 LOGE("invalid fd %d", device_fd);
213                 return CAMERA_ERROR_INVALID_PARAMETER;
214         }
215
216         memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
217         memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
218
219         v4l2_buf.index = index;
220         v4l2_buf.type = type;
221         v4l2_buf.memory = memory;
222         v4l2_buf.m.planes = v4l2_planes;
223         v4l2_buf.length = 460800;
224         v4l2_buf.bytesused = 460800;
225
226         if (ioctl(device_fd, VIDIOC_QBUF, &v4l2_buf) < 0) {
227                 LOGE("qbuf failed.  [i: %d, t: %d, m: %d] errno %d",
228                         index, type, memory, errno);
229                 return CAMERA_ERROR_INTERNAL;
230         }
231
232         LOGD("QBUF done [i: %d, t: %d, m: %d]",
233                 index, type, memory);
234
235         return CAMERA_ERROR_NONE;
236 }
237
238
239 static int _camera_v4l2_dqbuf(int device_fd, int type, int memory, int *index)
240 {
241         int ret = CAMERA_ERROR_NONE;
242         struct v4l2_buffer v4l2_buf;
243         struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];
244
245         if (device_fd < 0) {
246                 LOGE("invalid fd %d", device_fd);
247                 return CAMERA_ERROR_INVALID_PARAMETER;
248         }
249
250         if (!index) {
251                 LOGE("NULL parameter");
252                 return CAMERA_ERROR_INVALID_PARAMETER;
253         }
254
255         memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
256         memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
257
258         v4l2_buf.type = type;
259         v4l2_buf.memory = memory;
260         v4l2_buf.m.planes = v4l2_planes;
261
262         ret = ioctl(device_fd, VIDIOC_DQBUF, &v4l2_buf);
263         if (ret < 0) {
264                 if (errno != EIO) {
265                         LOGE("dqbuf failed. [t: %d, m: %d] errno %d",
266                                 type, memory, errno);
267                         return CAMERA_ERROR_DEVICE_READ;
268                 }
269         }
270
271         *index = v4l2_buf.index;
272
273         LOGD("dqbuf index %d", *index);
274
275         return CAMERA_ERROR_NONE;
276 }
277
278
279 static int _camera_get_format(guint32 fourcc, int *pixel_format)
280 {
281         if (!pixel_format) {
282                 LOGE("NULL parameter");
283                 return CAMERA_ERROR_INVALID_PARAMETER;
284         }
285
286         switch (fourcc) {
287         case V4L2_PIX_FMT_NV12:
288         case V4L2_PIX_FMT_NV12M:
289         case V4L2_PIX_FMT_NV12MT:
290                 *pixel_format = CAMERA_PIXEL_FORMAT_NV12;
291                 break;
292         case V4L2_PIX_FMT_NV21:
293         case V4L2_PIX_FMT_NV21M:
294                 *pixel_format = CAMERA_PIXEL_FORMAT_NV21;
295                 break;
296         case V4L2_PIX_FMT_YUV420:
297                 *pixel_format = CAMERA_PIXEL_FORMAT_I420;
298                 break;
299         case V4L2_PIX_FMT_YVU420:
300                 *pixel_format = CAMERA_PIXEL_FORMAT_YV12;
301                 break;
302         case V4L2_PIX_FMT_YUYV:
303                 *pixel_format = CAMERA_PIXEL_FORMAT_YUYV;
304                 break;
305         case V4L2_PIX_FMT_UYVY:
306                 *pixel_format = CAMERA_PIXEL_FORMAT_UYVY;
307                 break;
308         case V4L2_PIX_FMT_JPEG:
309                 *pixel_format = CAMERA_PIXEL_FORMAT_JPEG;
310                 break;
311         case V4L2_PIX_FMT_H264:
312                 *pixel_format = CAMERA_PIXEL_FORMAT_H264;
313                 break;
314         default:
315                 LOGE("unknown fourcc "FOURCC_FORMAT, FOURCC_CONVERT(fourcc));
316                 return CAMERA_ERROR_INTERNAL;
317         }
318
319         LOGD("fourcc "FOURCC_FORMAT" -> %d",
320                 FOURCC_CONVERT(fourcc), *pixel_format);
321
322         return CAMERA_ERROR_NONE;
323 }
324
325 static int _camera_get_fourcc_plane_num(int pixel_format, guint32 *fourcc, uint8_t *plane_num)
326 {
327         if (!fourcc || !plane_num) {
328                 LOGE("NULL parameter %p %p", fourcc, plane_num);
329                 return CAMERA_ERROR_INVALID_PARAMETER;
330         }
331
332         switch (pixel_format) {
333         case CAMERA_PIXEL_FORMAT_NV12:
334                 *fourcc = V4L2_PIX_FMT_NV12;
335                 *plane_num = 2;
336                 break;
337         case CAMERA_PIXEL_FORMAT_NV21:
338                 *fourcc = V4L2_PIX_FMT_NV21;
339                 *plane_num = 2;
340                 break;
341         case CAMERA_PIXEL_FORMAT_I420:
342                 *fourcc = V4L2_PIX_FMT_YUV420;
343                 *plane_num = 3;
344                 break;
345         case CAMERA_PIXEL_FORMAT_YV12:
346                 *fourcc = V4L2_PIX_FMT_YVU420;
347                 *plane_num = 3;
348                 break;
349         case CAMERA_PIXEL_FORMAT_YUYV:
350                 *fourcc = V4L2_PIX_FMT_YUYV;
351                 *plane_num = 1;
352                 break;
353         case CAMERA_PIXEL_FORMAT_UYVY:
354                 *fourcc = V4L2_PIX_FMT_UYVY;
355                 *plane_num = 1;
356                 break;
357         case CAMERA_PIXEL_FORMAT_JPEG:
358                 *fourcc = V4L2_PIX_FMT_JPEG;
359                 *plane_num = 1;
360                 break;
361         case CAMERA_PIXEL_FORMAT_H264:
362                 *fourcc = V4L2_PIX_FMT_H264;
363                 *plane_num = 1;
364                 break;
365         default:
366                 LOGE("unknown format %d", pixel_format);
367                 return CAMERA_ERROR_INTERNAL;
368         }
369
370         LOGD("format %d -> fourcc "FOURCC_FORMAT,
371                 pixel_format, FOURCC_CONVERT(*fourcc));
372
373         return CAMERA_ERROR_NONE;
374 }
375
376
377 static int _camera_get_device_info(int device_index, int device_fd, camera_device_info_t *device_info, char *node_path)
378 {
379         int i = 0;
380         int j = 0;
381         int format_count = 0;
382         int resolution_count = 0;
383         int camera_format = 0;
384         struct v4l2_fmtdesc v4l2_format;
385         struct v4l2_frmsizeenum v4l2_frame;
386
387         if (device_fd < 0 || !device_info || !node_path) {
388                 LOGE("invalid param %d %p %p", device_fd, device_info, node_path);
389                 return CAMERA_ERROR_INVALID_PARAMETER;
390         }
391
392         LOGD("Get Supported format and resolution");
393
394         for (i = 0 ; ; i++) {
395                 memset(&v4l2_format, 0x0, sizeof(struct v4l2_fmtdesc));
396
397                 v4l2_format.index = i;
398                 v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
399
400                 if (ioctl(device_fd, VIDIOC_ENUM_FMT, &v4l2_format) < 0) {
401                         LOGW("\tformat : end of enumeration");
402                         break;
403                 }
404
405                 LOGD("\tformat[%d] "FOURCC_FORMAT, i, FOURCC_CONVERT(v4l2_format.pixelformat));
406
407                 if (_camera_get_format(v4l2_format.pixelformat, &camera_format) != CAMERA_ERROR_NONE)
408                         continue;
409
410                 device_info->format_list.formats[format_count] = camera_format;
411
412                 resolution_count = 0;
413
414                 for (j = 0 ; ; j++) {
415                         memset(&v4l2_frame, 0x0, sizeof(struct v4l2_frmsizeenum));
416
417                         v4l2_frame.index = j;
418                         v4l2_frame.pixel_format = v4l2_format.pixelformat;
419
420                         if (ioctl(device_fd, VIDIOC_ENUM_FRAMESIZES, &v4l2_frame) < 0) {
421                                 LOGW("\t\tframe : end of enumeration ");
422                                 break;
423                         }
424
425                         switch (v4l2_frame.type) {
426                         case V4L2_FRMSIZE_TYPE_DISCRETE:
427                                 device_info->preview_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
428                                 device_info->preview_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
429                                 device_info->capture_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
430                                 device_info->capture_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
431                                 device_info->video_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
432                                 device_info->video_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
433
434                                 resolution_count++;
435
436                                 LOGD("\t\tsize[%d] %ux%u", j,
437                                         v4l2_frame.discrete.width,
438                                         v4l2_frame.discrete.height);
439                                 break;
440                         case V4L2_FRMSIZE_TYPE_CONTINUOUS:
441                                 LOGW("\t\tsize[%d] %ux%u - %ux%u", j,
442                                         v4l2_frame.stepwise.min_width,
443                                         v4l2_frame.stepwise.min_height,
444                                         v4l2_frame.stepwise.max_width,
445                                         v4l2_frame.stepwise.max_height);
446                                 break;
447                         case V4L2_FRMSIZE_TYPE_STEPWISE:
448                                 LOGW("\t\tsize[%d] %ux%u - %ux%u (step %ux%u)", j,
449                                         v4l2_frame.stepwise.min_width,
450                                         v4l2_frame.stepwise.min_height,
451                                         v4l2_frame.stepwise.max_width,
452                                         v4l2_frame.stepwise.max_height,
453                                         v4l2_frame.stepwise.step_width,
454                                         v4l2_frame.stepwise.step_height);
455                                 break;
456                         default:
457                                 LOGE("\t\tunknown frame type %d", v4l2_frame.type);
458                                 break;
459                         }
460                 }
461
462                 device_info->preview_list.count = resolution_count;
463                 device_info->capture_list.count = resolution_count;
464                 device_info->video_list.count = resolution_count;
465
466                 LOGD("\t\tresolution count [%d]", resolution_count);
467
468                 format_count++;
469         }
470
471         device_info->index = device_index;
472         device_info->format_list.count = format_count;
473         device_info->facing_direction = CAMERA_FACING_DIRECTION_EXTERNAL;
474         snprintf(device_info->name, sizeof(device_info->name), "V4L2_CAMERA");
475         snprintf(device_info->node_path, sizeof(device_info->node_path), "%s", node_path);
476
477         LOGD("\tformat count [%d]", format_count);
478
479         return CAMERA_ERROR_NONE;
480 }
481
482 static int _camera_get_device_info_list(void)
483 {
484         int i = 0;
485         int ret = 0;
486         int device_count = 0;
487         int device_fd = CAMERA_HAL_INITIAL_FD;
488         glob_t glob_buf;
489         struct v4l2_capability v4l2_cap;
490         camera_device_info_list_t *device_info_list = NULL;
491
492         g_mutex_lock(&g_device_info_lock);
493
494         if (g_device_info_list) {
495                 LOGD("device info list is already existed");
496                 ret = CAMERA_ERROR_NONE;
497                 goto _GET_DEVICE_INFO_LIST_DONE;
498         }
499
500         device_info_list = g_new0(camera_device_info_list_t, 1);
501         if (!device_info_list) {
502                 LOGE("failed to alloc device info structure");
503                 ret = CAMERA_ERROR_OUT_OF_MEMORY;
504                 goto _GET_DEVICE_INFO_LIST_DONE;
505         }
506
507         memset(&glob_buf, 0x0, sizeof(glob_t));
508
509         ret = glob(DEVICE_NODE_PATH_PREFIX"*", 0, 0, &glob_buf);
510         if (ret != 0) {
511                 switch (ret) {
512                 case GLOB_NOSPACE:
513                         LOGE("out of memory");
514                         ret = CAMERA_ERROR_OUT_OF_MEMORY;
515                         goto _GET_DEVICE_INFO_LIST_DONE;
516                 case GLOB_ABORTED:
517                         LOGE("read error");
518                         ret = CAMERA_ERROR_INTERNAL;
519                         goto _GET_DEVICE_INFO_LIST_DONE;
520                 case GLOB_NOMATCH:
521                         LOGE("match not found");
522                         ret = CAMERA_ERROR_INTERNAL;
523                         goto _GET_DEVICE_INFO_LIST_DONE;
524                 default:
525                         LOGE("unknown eror : %d", ret);
526                         ret = CAMERA_ERROR_INTERNAL;
527                         goto _GET_DEVICE_INFO_LIST_DONE;
528                 }
529         }
530
531         LOGD("device node count : %zu", glob_buf.gl_pathc);
532
533         for (i = 0 ; i < glob_buf.gl_pathc ; i++) {
534                 LOGD("[%d] check device [%s]", i, glob_buf.gl_pathv[i]);
535
536                 device_fd = open(glob_buf.gl_pathv[i], O_RDWR);
537                 if (device_fd < 0) {
538                         LOGE("open failed [%s] errno %d", glob_buf.gl_pathv[i], errno);
539                         continue;
540                 }
541
542                 memset(&v4l2_cap, 0x0, sizeof(struct v4l2_capability));
543
544                 if (ioctl(device_fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0) {
545                         LOGE("querycap failed. errno %d", errno);
546                         close(device_fd);
547                         continue;
548                 }
549
550                 if (v4l2_cap.capabilities & V4L2_CAP_DEVICE_CAPS)
551                         device_caps = v4l2_cap.device_caps;
552                 else
553                         device_caps = v4l2_cap.capabilities;
554
555                 if (!(device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) ||
556                         (device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) {
557                         LOGW("[%s] is not a capture device 0x%x", glob_buf.gl_pathv[i], device_caps);
558                         close(device_fd);
559                         continue;
560                 }
561
562                 ret = _camera_get_device_info(device_count, device_fd,
563                         &device_info_list->device_info[device_count], glob_buf.gl_pathv[i]);
564
565                 close(device_fd);
566
567                 if (ret == CAMERA_ERROR_NONE)
568                         device_count++;
569         }
570
571         device_info_list->count = device_count;
572         g_device_info_list = device_info_list;
573
574         LOGD("new g_device_info_list %p - device count %d",
575                 g_device_info_list, device_count);
576
577 _GET_DEVICE_INFO_LIST_DONE:
578         g_mutex_unlock(&g_device_info_lock);
579         LOGD("ret 0x%x", ret);
580
581         if (ret != CAMERA_ERROR_NONE)
582                 g_free(device_info_list);
583
584         return ret;
585 }
586
587
588 static void *_camera_preview_handler_func(gpointer data)
589 {
590         int index = 0;
591         camera_hal_handle *handle = (camera_hal_handle *)data;
592
593         if (!handle) {
594                 LOGE("NULL handle for preview handler");
595                 return NULL;
596         }
597
598         LOGD("enter - preview handler thread");
599
600         /* run buffer thread */
601         g_mutex_lock(&handle->preview_cb_lock);
602
603         while (handle->preview_cb_run) {
604                 g_mutex_unlock(&handle->preview_cb_lock);
605
606                 if (_camera_v4l2_wait_frame(handle->device_fd, 5) != CAMERA_ERROR_NONE) {
607                         LOGE("frame wait failed");
608                         g_mutex_lock(&handle->preview_cb_lock);
609                         break;
610                 }
611
612                 if (_camera_v4l2_dqbuf(handle->device_fd, handle->v4l2_type, V4L2_MEMORY_MMAP, &index) != CAMERA_ERROR_NONE) {
613                         LOGE("dqbuf failed");
614                         g_mutex_lock(&handle->preview_cb_lock);
615                         break;
616                 }
617
618                 g_mutex_lock(&handle->preview_cb_lock);
619
620                 handle->live_buffer_num++;
621
622                 LOGD("live buffer num %d", handle->live_buffer_num);
623
624                 g_mutex_unlock(&handle->preview_cb_lock);
625
626                 if (handle->preview_cb) {
627                         ((camera_preview_frame_cb)handle->preview_cb)(&handle->preview_buffer[index], NULL, handle->preview_cb_data);
628                 } else {
629                         LOGW("preview callback is NULL");
630                         camera_release_preview_buffer((void *)handle, index);
631                 }
632
633                 sched_yield();
634
635                 g_mutex_lock(&handle->preview_cb_lock);
636         }
637
638         g_mutex_unlock(&handle->preview_cb_lock);
639
640         LOGD("leave - preview handler thread");
641
642         return NULL;
643 }
644
645
646 static void _camera_message_release_func(gpointer data)
647 {
648         camera_message_t *message = (camera_message_t *)data;
649
650         if (!message) {
651                 LOGW("NULL message");
652                 return;
653         }
654
655         LOGD("release message %p, type %d", message, message->type);
656
657         g_free(message);
658
659         return;
660 }
661
662
663 static void *_camera_message_handler_func(gpointer data)
664 {
665         int i = 0;
666         camera_message_t *message = NULL;
667         camera_hal_handle *handle = (camera_hal_handle *)data;
668
669         if (!handle) {
670                 LOGE("NULL handle for capture thread");
671                 return NULL;
672         }
673
674         LOGD("enter - message thread");
675
676         g_mutex_lock(&handle->message_cb_lock);
677
678         while (handle->message_cb_run) {
679                 if (g_queue_is_empty(handle->message_list)) {
680                         LOGD("wait for message");
681                         g_cond_wait(&handle->message_cb_cond, &handle->message_cb_lock);
682                         LOGD("message signal received");
683                 }
684
685                 if (!handle->message_cb_run) {
686                         LOGW("break message thread");
687                         break;
688                 }
689
690                 message = g_queue_pop_head(handle->message_list);
691                 if (!message) {
692                         LOGW("NULL message");
693                         continue;
694                 }
695
696                 g_mutex_unlock(&handle->message_cb_lock);
697
698                 for (i = 0 ; i < MESSAGE_CALLBACK_MAX ; i++) {
699                         if (handle->message_cb[i]) {
700                                 LOGD("call message callback type %d", message->type);
701                                 ((camera_message_cb)handle->message_cb[i])(message, handle->message_cb_data[i]);
702                         }
703                 }
704
705                 g_free(message);
706                 message = NULL;
707
708                 g_mutex_lock(&handle->message_cb_lock);
709         }
710
711         g_mutex_unlock(&handle->message_cb_lock);
712
713         LOGD("leave - message thread");
714
715         return NULL;
716 }
717
718
719 void _camera_release_handle(camera_hal_handle *handle)
720 {
721         if (!handle) {
722                 LOGW("NULL handle");
723                 return;
724         }
725
726         if (handle->message_thread) {
727                 g_mutex_lock(&handle->message_cb_lock);
728                 handle->message_cb_run = FALSE;
729                 g_cond_signal(&handle->message_cb_cond);
730                 g_mutex_unlock(&handle->message_cb_lock);
731                 g_thread_join(handle->message_thread);
732                 g_queue_free_full(handle->message_list, (GDestroyNotify)_camera_message_release_func);
733                 handle->message_list = NULL;
734         }
735
736         g_mutex_clear(&handle->lock);
737         g_mutex_clear(&handle->preview_cb_lock);
738         g_mutex_clear(&handle->message_cb_lock);
739         g_cond_clear(&handle->preview_cb_cond);
740         g_cond_clear(&handle->message_cb_cond);
741
742         if (handle->bufmgr) {
743                 tbm_bufmgr_deinit(handle->bufmgr);
744                 handle->bufmgr = NULL;
745         }
746
747         LOGD("camera HAL handle %p destroy", handle);
748
749         g_free(handle);
750
751         return;
752 }
753
754
755 int camera_init(void **camera_handle)
756 {
757         int ret = CAMERA_ERROR_NONE;
758         camera_hal_handle *new_handle = NULL;
759         tbm_bufmgr bufmgr = NULL;
760
761         LOGD("enter");
762
763         if (!camera_handle) {
764                 LOGE("NULL pointer for handle");
765                 return CAMERA_ERROR_INVALID_PARAMETER;
766         }
767
768         bufmgr = tbm_bufmgr_init(-1);
769         if (bufmgr == NULL) {
770                 LOGE("get tbm bufmgr failed");
771                 return CAMERA_ERROR_INTERNAL;
772         }
773
774         new_handle = g_new0(camera_hal_handle, 1);
775         if (!new_handle) {
776                 LOGE("failed to alloc camera hal handle");
777                 tbm_bufmgr_deinit(bufmgr);
778                 return CAMERA_ERROR_OUT_OF_MEMORY;
779         }
780
781         new_handle->bufmgr = bufmgr;
782
783         g_mutex_init(&new_handle->lock);
784         g_mutex_init(&new_handle->preview_cb_lock);
785         g_mutex_init(&new_handle->message_cb_lock);
786         g_cond_init(&new_handle->preview_cb_cond);
787         g_cond_init(&new_handle->message_cb_cond);
788
789         /* message thread */
790         new_handle->message_list = g_queue_new();
791         new_handle->message_cb_run = TRUE;
792         new_handle->message_thread = g_thread_try_new("camera_hal_message_thread",
793                 _camera_message_handler_func, (gpointer)new_handle, NULL);
794         if (!new_handle->message_thread) {
795                 LOGE("failed to create message thread");
796                 ret = CAMERA_ERROR_INTERNAL;
797                 goto _INIT_ERROR;
798         }
799
800         new_handle->device_index = CAMERA_HAL_INITIAL_INDEX;
801         new_handle->device_fd = CAMERA_HAL_INITIAL_FD;
802         new_handle->state = CAMERA_STATE_INITIALIZED;
803
804         ret = _camera_get_device_info_list();
805         if (ret != CAMERA_ERROR_NONE) {
806                 LOGE("get device info failed");
807                 goto _INIT_ERROR;
808         }
809
810         *camera_handle = new_handle;
811
812         LOGD("camera HAL handle %p", new_handle);
813
814         return CAMERA_ERROR_NONE;
815
816 _INIT_ERROR:
817         _camera_release_handle(new_handle);
818
819         return ret;
820 }
821
822 int camera_deinit(void *camera_handle)
823 {
824         camera_hal_handle *handle = NULL;
825
826         if (!camera_handle) {
827                 LOGE("NULL handle");
828                 return CAMERA_ERROR_INVALID_PARAMETER;
829         }
830
831         handle = (camera_hal_handle *)camera_handle;
832
833         g_mutex_lock(&handle->lock);
834
835         if (handle->state != CAMERA_STATE_INITIALIZED) {
836                 LOGE("invalid state %d, can not destroy handle", handle->state);
837                 g_mutex_unlock(&handle->lock);
838                 return CAMERA_ERROR_INVALID_STATE;
839         }
840
841         g_mutex_unlock(&handle->lock);
842
843         _camera_release_handle(handle);
844
845         return CAMERA_ERROR_NONE;
846 }
847
848 int camera_get_device_info_list(camera_device_info_list_t *device_info_list)
849 {
850         int ret = 0;
851
852         if (!device_info_list) {
853                 LOGE("NULL pointer for device_info_list");
854                 return CAMERA_ERROR_INVALID_PARAMETER;
855         }
856
857         ret = _camera_get_device_info_list();
858         if (ret != CAMERA_ERROR_NONE) {
859                 LOGE("get device info failed");
860                 return ret;
861         }
862
863         memcpy(device_info_list, g_device_info_list, sizeof(camera_device_info_list_t));
864
865         return CAMERA_ERROR_NONE;
866 }
867
868 int camera_open_device(void *camera_handle, int device_index)
869 {
870         int ret = CAMERA_ERROR_NONE;
871         int device_fd = CAMERA_HAL_INITIAL_FD;
872         char *node_path = NULL;
873         camera_hal_handle *handle = NULL;
874
875         if (!camera_handle) {
876                 LOGE("NULL handle");
877                 return CAMERA_ERROR_INVALID_PARAMETER;
878         }
879
880         handle = (camera_hal_handle *)camera_handle;
881
882         g_mutex_lock(&handle->lock);
883
884         if (handle->state != CAMERA_STATE_INITIALIZED) {
885                 LOGE("invalid state %d", handle->state);
886                 ret = CAMERA_ERROR_INVALID_STATE;
887                 goto _OPEN_DEVICE_DONE;
888         }
889
890         if (!g_device_info_list) {
891                 LOGE("NO DEVICE INFO");
892                 ret = CAMERA_ERROR_INTERNAL;
893                 goto _OPEN_DEVICE_DONE;
894         }
895
896         if (device_index >= g_device_info_list->count) {
897                 LOGE("invalid index %d [info:%d]", device_index, g_device_info_list->count);
898                 ret = CAMERA_ERROR_INVALID_PARAMETER;
899                 goto _OPEN_DEVICE_DONE;
900         }
901
902         node_path = g_device_info_list->device_info[device_index].node_path;
903
904         device_fd = open(node_path, O_RDWR);
905         if (device_fd < 0) {
906                 switch (errno) {
907                         case EACCES:
908                         case EPERM:
909                                 ret = CAMERA_ERROR_PERMISSION_DENIED;
910                                 break;
911                         case ENOENT:
912                                 ret = CAMERA_ERROR_DEVICE_NOT_FOUND;
913                                 break;
914                         case EBUSY:
915                                 ret = CAMERA_ERROR_DEVICE_BUSY;
916                                 break;
917                         default:
918                                 ret = CAMERA_ERROR_DEVICE_OPEN;
919                                 break;
920                 }
921
922                 LOGE("open [%s] failed 0x%x [errno %d]",
923                         node_path, ret, errno);
924
925                 goto _OPEN_DEVICE_DONE;
926         }
927
928         if (device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
929                 handle->v4l2_type = V4L2_CAP_VIDEO_CAPTURE_MPLANE;
930         else
931                 handle->v4l2_type = V4L2_CAP_VIDEO_CAPTURE;
932
933         handle->state = CAMERA_STATE_OPENED;
934         handle->device_index = device_index;
935         handle->device_fd = device_fd;
936
937         LOGD("[%d] device[%s] opened [fd %d, type %d]",
938                 device_index, node_path, device_fd, handle->v4l2_type);
939
940 _OPEN_DEVICE_DONE:
941         g_mutex_unlock(&handle->lock);
942
943         return ret;
944 }
945
946 int camera_close_device(void *camera_handle)
947 {
948         camera_hal_handle *handle = NULL;
949
950         if (!camera_handle) {
951                 LOGE("NULL handle");
952                 return CAMERA_ERROR_INVALID_PARAMETER;
953         }
954
955         handle = (camera_hal_handle *)camera_handle;
956
957         g_mutex_lock(&handle->lock);
958
959         if (handle->state != CAMERA_STATE_OPENED) {
960                 LOGE("invalid state %d", handle->state);
961                 g_mutex_unlock(&handle->lock);
962                 return CAMERA_ERROR_INVALID_STATE;
963         }
964
965         if (handle->device_fd >= 0) {
966                 LOGD("close fd %d", handle->device_fd);
967
968                 close(handle->device_fd);
969                 handle->device_fd = CAMERA_HAL_INITIAL_FD;
970         } else {
971                 LOGW("invalid fd %d", handle->device_fd);
972         }
973
974         handle->state = CAMERA_STATE_INITIALIZED;
975
976         LOGD("device [%d] closed", handle->device_index);
977
978         g_mutex_unlock(&handle->lock);
979
980         return CAMERA_ERROR_NONE;
981 }
982
983 int camera_add_message_callback(void *camera_handle, camera_message_cb callback, void *user_data, uint32_t *cb_id)
984 {
985         uint32_t i = 0;
986         camera_hal_handle *handle = NULL;
987
988         if (!camera_handle) {
989                 LOGE("NULL handle");
990                 return CAMERA_ERROR_INVALID_PARAMETER;
991         }
992
993         if (!callback || !cb_id) {
994                 LOGE("NULL pointer for callback %p or cb_id %p", callback, cb_id);
995                 return CAMERA_ERROR_INVALID_PARAMETER;
996         }
997
998         handle = (camera_hal_handle *)camera_handle;
999
1000         g_mutex_lock(&handle->lock);
1001
1002         if (handle->state != CAMERA_STATE_OPENED) {
1003                 LOGE("invalid state %d", handle->state);
1004                 g_mutex_unlock(&handle->lock);
1005                 return CAMERA_ERROR_INVALID_STATE;
1006         }
1007
1008         for (i = 0 ; i < MESSAGE_CALLBACK_MAX ; i++) {
1009                 if (handle->message_cb[i] == NULL) {
1010                         handle->message_cb[i] = callback;
1011                         handle->message_cb_data[i] = user_data;
1012                         *cb_id = i;
1013                         LOGD("message cb [%p] added, user data %p - id %u", callback, user_data, i);
1014                         g_mutex_unlock(&handle->lock);
1015                         return CAMERA_ERROR_NONE;
1016                 }
1017         }
1018
1019         g_mutex_unlock(&handle->lock);
1020
1021         LOGE("no available message cb slot");
1022
1023         return CAMERA_ERROR_INTERNAL;
1024 }
1025
1026 int camera_remove_message_callback(void *camera_handle, uint32_t cb_id)
1027 {
1028         camera_hal_handle *handle = NULL;
1029
1030         if (!camera_handle) {
1031                 LOGE("NULL handle");
1032                 return CAMERA_ERROR_INVALID_PARAMETER;
1033         }
1034
1035         if (cb_id >= MESSAGE_CALLBACK_MAX) {
1036                 LOGE("invalid cb_id %u", cb_id);
1037                 return CAMERA_ERROR_INVALID_PARAMETER;
1038         }
1039
1040         handle = (camera_hal_handle *)camera_handle;
1041
1042         g_mutex_lock(&handle->lock);
1043
1044         if (handle->state != CAMERA_STATE_OPENED) {
1045                 LOGE("invalid state %d", handle->state);
1046                 g_mutex_unlock(&handle->lock);
1047                 return CAMERA_ERROR_INVALID_STATE;
1048         }
1049
1050         if (handle->message_cb[cb_id]) {
1051                 LOGD("remove message callback %p, user data %p - cb_id %u",
1052                         handle->message_cb[cb_id], handle->message_cb_data[cb_id], cb_id);
1053
1054                 handle->message_cb[cb_id] = NULL;
1055                 handle->message_cb_data[cb_id] = NULL;
1056         } else {
1057                 LOGE("already removed message cb");
1058                 g_mutex_unlock(&handle->lock);
1059                 return CAMERA_ERROR_INTERNAL;
1060         }
1061
1062         g_mutex_unlock(&handle->lock);
1063
1064         return CAMERA_ERROR_NONE;
1065 }
1066
1067 int camera_set_preview_stream_format(void *camera_handle, camera_format_t *format)
1068 {
1069         int i = 0;
1070         int j = 0;
1071         int ret = CAMERA_ERROR_NONE;
1072         gboolean capability_check = FALSE;
1073         guint32 fourcc = 0;
1074         camera_hal_handle *handle = NULL;
1075         camera_device_info_t *device_info = NULL;
1076         struct v4l2_format v4l2_fmt;
1077         struct v4l2_streamparm v4l2_parm;
1078
1079         if (!camera_handle) {
1080                 LOGE("NULL handle");
1081                 return CAMERA_ERROR_INVALID_PARAMETER;
1082         }
1083
1084         if (!format) {
1085                 LOGE("NULL format");
1086                 return CAMERA_ERROR_INVALID_PARAMETER;
1087         }
1088
1089         if (!g_device_info_list) {
1090                 LOGE("no device info list");
1091                 return CAMERA_ERROR_INTERNAL;
1092         }
1093
1094         handle = (camera_hal_handle *)camera_handle;
1095
1096         g_mutex_lock(&handle->lock);
1097
1098         if (handle->state != CAMERA_STATE_OPENED) {
1099                 LOGE("invalid state %d", handle->state);
1100                 g_mutex_unlock(&handle->lock);
1101                 return CAMERA_ERROR_INVALID_STATE;
1102         }
1103
1104         /* check capability */
1105         device_info = &g_device_info_list->device_info[handle->device_index];
1106
1107         /* format */
1108         for (i = 0 ; i < device_info->format_list.count ; i++) {
1109                 if (format->stream_format == device_info->format_list.formats[i]) {
1110                         LOGD("format matched %d, check resolution.", format->stream_format);
1111
1112                         /* resolution */
1113                         for (j = 0 ; j < device_info->preview_list.count ; j++) {
1114                                 if (format->stream_resolution.width == device_info->preview_list.resolutions[j].width &&
1115                                         format->stream_resolution.height == device_info->preview_list.resolutions[j].height) {
1116                                         LOGD("resolution matched %dx%d",
1117                                                 format->stream_resolution.width,
1118                                                 format->stream_resolution.height);
1119                                         capability_check = TRUE;
1120                                         break;
1121                                 }
1122                         }
1123
1124                         break;
1125                 }
1126         }
1127
1128         if (!capability_check) {
1129                 LOGE("capability failed - %d, %dx%d",
1130                         format->stream_format,
1131                         format->stream_resolution.width,
1132                         format->stream_resolution.height);
1133                 g_mutex_unlock(&handle->lock);
1134                 return CAMERA_ERROR_INVALID_PARAMETER;
1135         }
1136
1137         /* S_FMT */
1138         ret = _camera_get_fourcc_plane_num(format->stream_format, &fourcc, &handle->plane_num);
1139         if (ret != CAMERA_ERROR_NONE) {
1140                 LOGE("get fourcc failed [format %d]", format->stream_format);
1141                 g_mutex_unlock(&handle->lock);
1142                 return ret;
1143         }
1144
1145         memset(&v4l2_fmt, 0x0, sizeof(struct v4l2_format));
1146
1147         v4l2_fmt.type = handle->v4l2_type;
1148         if (V4L2_TYPE_IS_MULTIPLANAR(handle->v4l2_type)) {
1149                 v4l2_fmt.fmt.pix_mp.width = format->stream_resolution.width;
1150                 v4l2_fmt.fmt.pix_mp.height = format->stream_resolution.height;
1151                 v4l2_fmt.fmt.pix_mp.pixelformat = fourcc;
1152                 v4l2_fmt.fmt.pix_mp.num_planes = handle->plane_num;
1153         } else {
1154                 v4l2_fmt.fmt.pix.width = format->stream_resolution.width;
1155                 v4l2_fmt.fmt.pix.height = format->stream_resolution.height;
1156                 v4l2_fmt.fmt.pix.pixelformat = fourcc;
1157                 v4l2_fmt.fmt.pix.bytesperline = format->stream_resolution.width;
1158         }
1159
1160         if (ioctl(handle->device_fd, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
1161                 LOGE("S_FMT failed. errno %d", errno);
1162                 g_mutex_unlock(&handle->lock);
1163                 return CAMERA_ERROR_INTERNAL;
1164         }
1165
1166         if (V4L2_TYPE_IS_MULTIPLANAR(handle->v4l2_type)) {
1167                 for (i = 0 ; i < v4l2_fmt.fmt.pix_mp.num_planes ; i++) {
1168                         LOGD("plane[%d] stride %u, sizeimage %u", i,
1169                                 v4l2_fmt.fmt.pix_mp.plane_fmt[i].bytesperline,
1170                                 v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
1171                 }
1172         } else {
1173                 LOGD("stride %d, sizeimage %d",
1174                         v4l2_fmt.fmt.pix.bytesperline,
1175                         v4l2_fmt.fmt.pix.sizeimage);
1176         }
1177
1178         /* G_PARM */
1179         memset(&v4l2_parm, 0x0, sizeof(struct v4l2_streamparm));
1180
1181         v4l2_parm.type = handle->v4l2_type;
1182
1183         if (ioctl(handle->device_fd, VIDIOC_G_PARM, &v4l2_parm) < 0) {
1184                 LOGE("G_PARM failed. errno %d", errno);
1185                 g_mutex_unlock(&handle->lock);
1186                 return CAMERA_ERROR_INTERNAL;
1187         }
1188
1189         /* S_PARM to set fps */
1190         v4l2_parm.parm.capture.timeperframe.numerator = 1;
1191         v4l2_parm.parm.capture.timeperframe.denominator = format->stream_fps;
1192
1193         if (ioctl(handle->device_fd, VIDIOC_S_PARM, &v4l2_parm) < 0) {
1194                 LOGE("S_PARM failed. errno %d", errno);
1195                 g_mutex_unlock(&handle->lock);
1196                 return CAMERA_ERROR_INTERNAL;
1197         }
1198
1199         memcpy(&handle->preview_format, format, sizeof(camera_format_t));
1200
1201         LOGD("set preview stream [%d: %dx%d, fps %d]",
1202                 format->stream_format,
1203                 format->stream_resolution.width,
1204                 format->stream_resolution.height,
1205                 format->stream_fps);
1206
1207         LOGW("CAPTURE STREAM [%d: %dx%d] IS NOT SUPPORTED",
1208                 format->capture_format,
1209                 format->capture_resolution.width,
1210                 format->capture_resolution.height);
1211
1212         g_mutex_unlock(&handle->lock);
1213
1214         return CAMERA_ERROR_NONE;
1215 }
1216
1217 int camera_get_preview_stream_format(void *camera_handle, camera_format_t *format)
1218 {
1219         camera_hal_handle *handle = NULL;
1220
1221         if (!camera_handle) {
1222                 LOGE("NULL handle");
1223                 return CAMERA_ERROR_INVALID_PARAMETER;
1224         }
1225
1226         if (!format) {
1227                 LOGE("NULL format");
1228                 return CAMERA_ERROR_INVALID_PARAMETER;
1229         }
1230
1231         handle = (camera_hal_handle *)camera_handle;
1232
1233         g_mutex_lock(&handle->lock);
1234
1235         memcpy(format, &handle->preview_format, sizeof(camera_format_t));
1236
1237         LOGD("get stream format %d, %dx%d", format->stream_format,
1238                 format->stream_resolution.width, format->stream_resolution.height);
1239
1240         g_mutex_unlock(&handle->lock);
1241
1242         return CAMERA_ERROR_NONE;
1243 }
1244
1245
1246 int camera_start_preview(void *camera_handle, camera_preview_frame_cb callback, void *user_data)
1247 {
1248         int i = 0;
1249         int ret = 0;
1250         int result_count = 0;
1251         camera_hal_handle *handle = NULL;
1252         camera_buffer_t *buffer = NULL;
1253
1254         struct v4l2_buffer v4l2_buf;
1255         struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];
1256
1257         if (!camera_handle) {
1258                 LOGE("NULL handle");
1259                 return CAMERA_ERROR_INVALID_PARAMETER;
1260         }
1261
1262         if (!callback) {
1263                 LOGE("NULL callback for preview");
1264                 return CAMERA_ERROR_INVALID_PARAMETER;
1265         }
1266
1267         handle = (camera_hal_handle *)camera_handle;
1268
1269         g_mutex_lock(&handle->lock);
1270
1271         if (handle->state != CAMERA_STATE_OPENED) {
1272                 LOGE("invalid state %d", handle->state);
1273                 g_mutex_unlock(&handle->lock);
1274                 return CAMERA_ERROR_INVALID_STATE;
1275         }
1276
1277         /* request buffer */
1278         ret = _camera_v4l2_reqbufs(handle->device_fd,
1279                 handle->v4l2_type, V4L2_MEMORY_MMAP, PREVIEW_BUFFER_MAX, &result_count);
1280         if (ret != CAMERA_ERROR_NONE) {
1281                 g_mutex_unlock(&handle->lock);
1282                 return ret;
1283         }
1284
1285         LOGD("REQUESTED buffer count %d", result_count);
1286
1287         handle->preview_buffer_num = result_count;
1288
1289         /* query buffer, mmap and qbuf */
1290         for (i = 0 ; i < handle->preview_buffer_num ; i++) {
1291                 memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
1292                 memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
1293
1294                 v4l2_buf.type = handle->v4l2_type;
1295                 v4l2_buf.memory = V4L2_MEMORY_MMAP;
1296                 v4l2_buf.index = i;
1297                 v4l2_buf.m.planes = v4l2_planes;
1298                 v4l2_buf.length = handle->plane_num;
1299
1300                 if (ioctl(handle->device_fd, VIDIOC_QUERYBUF, &v4l2_buf) < 0) {
1301                         LOGE("[%d] query buf failed. errno %d", i, errno);
1302                         goto _START_PREVIEW_FAILED;
1303                 }
1304
1305                 buffer = &handle->preview_buffer[i];
1306
1307                 buffer->index = i;
1308                 buffer->format = handle->preview_format.stream_format;
1309                 buffer->resolution = handle->preview_format.stream_resolution;
1310                 buffer->total_size = v4l2_buf.length;
1311                 buffer->num_planes = handle->plane_num;
1312                 buffer->planes[0].size = v4l2_buf.length;
1313                 buffer->planes[0].data = mmap(0,
1314                         v4l2_buf.length,
1315                         PROT_READ | PROT_WRITE,
1316                         MAP_SHARED,
1317                         handle->device_fd,
1318                         v4l2_buf.m.offset);
1319                 if (buffer->planes[0].data == MAP_FAILED) {
1320                         LOGE("[%d] mmap failed. errno %d", i, errno);
1321                         goto _START_PREVIEW_FAILED;
1322                 }
1323         }
1324
1325         for (i = 0 ; i < handle->preview_buffer_num ; i++) {
1326                 if (_camera_v4l2_qbuf(handle->device_fd, handle->v4l2_type, V4L2_MEMORY_MMAP, i) != CAMERA_ERROR_NONE) {
1327                         LOGE("qbuf failed");
1328                         goto _START_PREVIEW_FAILED;
1329                 }
1330         }
1331
1332         /* stream on */
1333         ret = _camera_v4l2_stream(handle->device_fd, handle->v4l2_type, TRUE);
1334         if (ret != CAMERA_ERROR_NONE) {
1335                 LOGE("stream on failed");
1336                 goto _START_PREVIEW_FAILED;
1337         }
1338
1339         g_mutex_lock(&handle->preview_cb_lock);
1340
1341         handle->preview_cb_run = TRUE;
1342
1343         handle->preview_thread = g_thread_try_new("camera_hal_preview_thread",
1344                 _camera_preview_handler_func, (gpointer)handle, NULL);
1345         if (!handle->preview_thread) {
1346                 LOGE("failed to create preview callback thread");
1347                 g_mutex_unlock(&handle->preview_cb_lock);
1348                 goto _START_PREVIEW_FAILED;
1349         }
1350
1351         handle->preview_cb = callback;
1352         handle->preview_cb_data = user_data;
1353
1354         g_mutex_unlock(&handle->preview_cb_lock);
1355
1356         handle->state = CAMERA_STATE_PREVIEWING;
1357
1358         LOGD("start preview done");
1359
1360         g_mutex_unlock(&handle->lock);
1361
1362         return CAMERA_ERROR_NONE;
1363
1364 _START_PREVIEW_FAILED:
1365         /* stream off */
1366         if (ioctl(handle->device_fd, VIDIOC_STREAMOFF, &handle->v4l2_type) < 0)
1367                 LOGE("stream off failed. errno %d", errno);
1368
1369         /* munmap */
1370         for (i = 0 ; i < handle->preview_buffer_num ; i++) {
1371                 buffer = &handle->preview_buffer[i];
1372                 if (buffer->planes[0].data != NULL &&
1373                         buffer->planes[0].data != MAP_FAILED) {
1374                         LOGW("munmap %p", buffer->planes[0].data);
1375                         munmap(buffer->planes[0].data, buffer->planes[0].size);
1376                 }
1377                 memset(buffer, 0x0, sizeof(camera_buffer_t));
1378         }
1379
1380         /* reqbufs 0 */
1381         if (_camera_v4l2_reqbufs(handle->device_fd,
1382                 handle->v4l2_type, V4L2_MEMORY_MMAP, 0, &result_count) != CAMERA_ERROR_NONE)
1383                 LOGE("reqbufs 0 failed");
1384
1385         g_mutex_unlock(&handle->lock);
1386
1387         return ret;
1388 }
1389
1390 int camera_release_preview_buffer(void *camera_handle, int buffer_index)
1391 {
1392         int ret = CAMERA_ERROR_NONE;
1393         camera_hal_handle *handle = NULL;
1394
1395         if (!camera_handle) {
1396                 LOGE("NULL handle");
1397                 return CAMERA_ERROR_INVALID_PARAMETER;
1398         }
1399
1400         handle = (camera_hal_handle *)camera_handle;
1401
1402         if (buffer_index >= handle->preview_buffer_num) {
1403                 LOGE("invalid buffer index %d", buffer_index);
1404                 g_mutex_unlock(&handle->preview_cb_lock);
1405                 return CAMERA_ERROR_INVALID_PARAMETER;
1406         }
1407
1408         ret = _camera_v4l2_qbuf(handle->device_fd,
1409                 handle->v4l2_type, V4L2_MEMORY_MMAP, buffer_index);
1410
1411         g_mutex_lock(&handle->preview_cb_lock);
1412
1413         if (ret == CAMERA_ERROR_NONE) {
1414                 handle->live_buffer_num--;
1415                 LOGD("qbud done : index %d, live buffer num %d",
1416                         buffer_index, handle->live_buffer_num);
1417         } else {
1418                 LOGE("qbuf failed [index %d]", buffer_index);
1419         }
1420
1421         g_cond_signal(&handle->preview_cb_cond);
1422
1423         g_mutex_unlock(&handle->preview_cb_lock);
1424
1425         return ret;
1426 }
1427
1428 int camera_stop_preview(void *camera_handle)
1429 {
1430         int ret = CAMERA_ERROR_NONE;
1431         int i = 0;
1432         int result_count = 0;
1433         gint64 end_time;
1434         camera_hal_handle *handle = NULL;
1435
1436         if (!camera_handle) {
1437                 LOGE("NULL handle");
1438                 return CAMERA_ERROR_INVALID_PARAMETER;
1439         }
1440
1441         handle = (camera_hal_handle *)camera_handle;
1442
1443         LOGD("start");
1444
1445         g_mutex_lock(&handle->lock);
1446
1447         if (handle->state != CAMERA_STATE_PREVIEWING) {
1448                 LOGE("invalid state %d", handle->state);
1449                 g_mutex_unlock(&handle->lock);
1450                 return CAMERA_ERROR_INVALID_STATE;
1451         }
1452
1453         g_mutex_lock(&handle->preview_cb_lock);
1454
1455         handle->preview_cb_run = FALSE;
1456
1457         while (handle->live_buffer_num > 0) {
1458                 LOGD("wait for live buffer [num %d]", handle->live_buffer_num);
1459                 end_time = g_get_monotonic_time() + 3 * G_TIME_SPAN_SECOND;
1460                 if (!g_cond_wait_until(&handle->preview_cb_cond, &handle->preview_cb_lock, end_time)) {
1461                         LOGE("buffer wait failed");
1462                         break;
1463                 } else {
1464                         LOGD("signal received. check again...");
1465                 }
1466         }
1467
1468         g_mutex_unlock(&handle->preview_cb_lock);
1469
1470         /* stream off */
1471         ret = _camera_v4l2_stream(handle->device_fd, handle->v4l2_type, FALSE);
1472
1473         LOGD("stream off : 0x%x", ret);
1474
1475         /* munmap */
1476         for (i = 0 ; i < handle->preview_buffer_num ; i++) {
1477                 if (handle->preview_buffer[i].planes[0].data != NULL) {
1478                         LOGW("munmap %p", handle->preview_buffer[i].planes[0].data);
1479
1480                         munmap(handle->preview_buffer[i].planes[0].data, handle->preview_buffer[i].planes[0].size);
1481
1482                         handle->preview_buffer[i].planes[0].data = 0;
1483                         handle->preview_buffer[i].planes[0].size = 0;
1484                 } else {
1485                         LOGW("NULL data [index %d]", i);
1486                 }
1487         }
1488
1489         /* reqbufs 0 */
1490         ret = _camera_v4l2_reqbufs(handle->device_fd,
1491                 handle->v4l2_type, V4L2_MEMORY_MMAP, 0, &result_count);
1492
1493         LOGD("reqbufs 0 : 0x%x", ret);
1494
1495         /* wait for preview thread exit */
1496         g_thread_join(handle->preview_thread);
1497         handle->preview_thread = NULL;
1498
1499         handle->state = CAMERA_STATE_OPENED;
1500
1501         LOGD("stop preview done");
1502
1503         g_mutex_unlock(&handle->lock);
1504
1505         return CAMERA_ERROR_NONE;
1506 }
1507
1508 int camera_start_auto_focus(void *camera_handle)
1509 {
1510         if (!camera_handle) {
1511                 LOGE("NULL handle");
1512                 return CAMERA_ERROR_INVALID_PARAMETER;
1513         }
1514
1515         LOGD("NOT SUPPORTED");
1516
1517         /* auto focus is not supported */
1518         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1519 }
1520
1521 int camera_stop_auto_focus(void *camera_handle)
1522 {
1523         if (!camera_handle) {
1524                 LOGE("NULL handle");
1525                 return CAMERA_ERROR_INVALID_PARAMETER;
1526         }
1527
1528         LOGD("NOT SUPPORTED");
1529
1530         /* auto focus is not supported */
1531         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1532 }
1533
1534
1535 int camera_start_capture(void *camera_handle, camera_capture_cb callback, void *user_data)
1536 {
1537         if (!camera_handle || !callback) {
1538                 LOGE("NULL handle %p or callback %p", camera_handle, callback);
1539                 return CAMERA_ERROR_INVALID_PARAMETER;
1540         }
1541
1542         LOGD("NOT SUPPORTED");
1543
1544         /* capture function is not supported */
1545         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1546 }
1547
1548 int camera_stop_capture(void *camera_handle)
1549 {
1550         if (!camera_handle) {
1551                 LOGE("NULL handle");
1552                 return CAMERA_ERROR_INVALID_PARAMETER;
1553         }
1554
1555         LOGD("NOT SUPPORTED");
1556
1557         /* capture function is not supported */
1558         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1559 }
1560
1561 int camera_set_video_stream_format(void *camera_handle, camera_format_t *format)
1562 {
1563         if (!camera_handle) {
1564                 LOGE("NULL handle");
1565                 return CAMERA_ERROR_INVALID_PARAMETER;
1566         }
1567
1568         if (!format) {
1569                 LOGE("NULL format");
1570                 return CAMERA_ERROR_INVALID_PARAMETER;
1571         }
1572
1573         LOGD("NOT SUPPORTED");
1574
1575         /* single stream device can not support video stream */
1576         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1577 }
1578
1579 int camera_get_video_stream_format(void *camera_handle, camera_format_t *format)
1580 {
1581         if (!camera_handle) {
1582                 LOGE("NULL handle");
1583                 return CAMERA_ERROR_INVALID_PARAMETER;
1584         }
1585
1586         if (!format) {
1587                 LOGE("NULL format");
1588                 return CAMERA_ERROR_INVALID_PARAMETER;
1589         }
1590
1591         LOGD("NOT SUPPORTED");
1592
1593         /* single stream device can not support video stream */
1594         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1595 }
1596
1597 int camera_start_record(void *camera_handle, camera_video_frame_cb callback, void *user_data)
1598 {
1599         if (!camera_handle) {
1600                 LOGE("NULL handle");
1601                 return CAMERA_ERROR_INVALID_PARAMETER;
1602         }
1603
1604         if (!callback) {
1605                 LOGE("NULL callback for video");
1606                 return CAMERA_ERROR_INVALID_PARAMETER;
1607         }
1608
1609         LOGD("NOT SUPPORTED");
1610
1611         /* single stream device can not support video stream */
1612         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1613 }
1614
1615 int camera_release_video_buffer(void *camera_handle, int buffer_index)
1616 {
1617         if (!camera_handle) {
1618                 LOGE("NULL handle");
1619                 return CAMERA_ERROR_INVALID_PARAMETER;
1620         }
1621
1622         LOGD("NOT SUPPORTED");
1623
1624         /* single stream device can not support video stream */
1625         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1626 }
1627
1628 int camera_stop_record(void *camera_handle)
1629 {
1630         if (!camera_handle) {
1631                 LOGE("NULL handle");
1632                 return CAMERA_ERROR_INVALID_PARAMETER;
1633         }
1634
1635         LOGD("NOT SUPPORTED");
1636
1637         /* single stream device can not support video stream */
1638         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1639 }
1640
1641 int camera_set_command(void *camera_handle, int64_t command, void *value)
1642 {
1643         int ret = CAMERA_ERROR_NONE;
1644         int cid = 0;
1645         int ctrl_ret = 0;
1646         camera_hal_handle *handle = NULL;
1647
1648         if (!camera_handle) {
1649                 LOGE("NULL handle");
1650                 return CAMERA_ERROR_INVALID_PARAMETER;
1651         }
1652
1653         handle = (camera_hal_handle *)camera_handle;
1654
1655         g_mutex_lock(&handle->lock);
1656
1657         if (handle->state < CAMERA_STATE_OPENED) {
1658                 LOGE("invalid state %d", handle->state);
1659                 g_mutex_unlock(&handle->lock);
1660                 return CAMERA_ERROR_INVALID_STATE;
1661         }
1662
1663         LOGD("set command %"PRId64" - state %d", command, handle->state);
1664
1665         switch (command) {
1666         case CAMERA_COMMAND_EXPOSURE:
1667                 cid = V4L2_CID_BRIGHTNESS;
1668                 break;
1669         case CAMERA_COMMAND_CONTRAST:
1670                 cid = V4L2_CID_CONTRAST;
1671                 break;
1672         case CAMERA_COMMAND_SATURATION:
1673                 cid = V4L2_CID_SATURATION;
1674                 break;
1675         case CAMERA_COMMAND_SHARPNESS:
1676                 cid = V4L2_CID_SHARPNESS;
1677                 break;
1678         case CAMERA_COMMAND_PTZ_TYPE:
1679                 g_mutex_unlock(&handle->lock);
1680
1681                 if ((int)(long)value != CAMERA_PTZ_TYPE_ELECTRONIC) {
1682                         LOGE("not supported PTZ type %d", (int)(long)value);
1683                         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1684                 }
1685
1686                 return CAMERA_ERROR_NONE;
1687         case CAMERA_COMMAND_PAN:
1688                 cid = V4L2_CID_PAN_ABSOLUTE;
1689                 break;
1690         case CAMERA_COMMAND_TILT:
1691                 cid = V4L2_CID_TILT_ABSOLUTE;
1692                 break;
1693         default:
1694                 LOGE("NOT_SUPPORTED %"PRId64, command);
1695                 g_mutex_unlock(&handle->lock);
1696                 return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1697         }
1698
1699         ctrl_ret = _camera_v4l2_s_ctrl(handle->device_fd, cid, ((int)(long)value));
1700         if (ctrl_ret < 0) {
1701                 switch (errno) {
1702                 case EACCES:
1703                 case EPERM:
1704                         LOGE("Permission denied %d", errno);
1705                         ret = CAMERA_ERROR_PERMISSION_DENIED;
1706                         break;
1707                 case EINVAL:
1708                         LOGE("Invalid argument");
1709                         ret = CAMERA_ERROR_INVALID_PARAMETER;
1710                         break;
1711                 case EBUSY:
1712                         LOGE("Device busy");
1713                         ret = CAMERA_ERROR_DEVICE_BUSY;
1714                         break;
1715                 case ENOTSUP:
1716                         LOGE("Not supported");
1717                         ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1718                         break;
1719                 default:
1720                         LOGE("Unknown errro %d", errno);
1721                         ret = CAMERA_ERROR_INTERNAL;
1722                         break;
1723                 }
1724         }
1725
1726         g_mutex_unlock(&handle->lock);
1727
1728         return ret;
1729 }
1730
1731 int camera_get_command(void *camera_handle, int64_t command, void **value)
1732 {
1733         int ret = CAMERA_ERROR_NONE;
1734         int cid = 0;
1735         int ctrl_ret = 0;
1736         camera_hal_handle *handle = NULL;
1737
1738         if (!camera_handle) {
1739                 LOGE("NULL handle");
1740                 return CAMERA_ERROR_INVALID_PARAMETER;
1741         }
1742
1743         if (!value) {
1744                 LOGE("invalid pointer for value");
1745                 return CAMERA_ERROR_INVALID_PARAMETER;
1746         }
1747
1748         handle = (camera_hal_handle *)camera_handle;
1749
1750         g_mutex_lock(&handle->lock);
1751
1752         LOGD("get command %"PRId64" - state %d", command, handle->state);
1753
1754         switch (command) {
1755         case CAMERA_COMMAND_EXPOSURE:
1756                 cid = V4L2_CID_BRIGHTNESS;
1757                 break;
1758         case CAMERA_COMMAND_CONTRAST:
1759                 cid = V4L2_CID_CONTRAST;
1760                 break;
1761         case CAMERA_COMMAND_SATURATION:
1762                 cid = V4L2_CID_SATURATION;
1763                 break;
1764         case CAMERA_COMMAND_SHARPNESS:
1765                 cid = V4L2_CID_SHARPNESS;
1766                 break;
1767         default:
1768                 LOGE("NOT_SUPPORTED %"PRId64, command);
1769                 g_mutex_unlock(&handle->lock);
1770                 return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1771         }
1772
1773         ctrl_ret = _camera_v4l2_g_ctrl(handle->device_fd, cid, (int *)value);
1774         if (ctrl_ret < 0) {
1775                 switch (errno) {
1776                 case EACCES:
1777                 case EPERM:
1778                         LOGE("Permission denied %d", errno);
1779                         ret = CAMERA_ERROR_PERMISSION_DENIED;
1780                         break;
1781                 case EINVAL:
1782                         LOGE("Invalid argument");
1783                         ret = CAMERA_ERROR_INVALID_PARAMETER;
1784                         break;
1785                 case EBUSY:
1786                         LOGE("Device busy");
1787                         ret = CAMERA_ERROR_DEVICE_BUSY;
1788                         break;
1789                 case ENOTSUP:
1790                         LOGE("Not supported");
1791                         ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1792                         break;
1793                 default:
1794                         LOGE("Unknown errro %d", errno);
1795                         ret = CAMERA_ERROR_INTERNAL;
1796                         break;
1797                 }
1798         }
1799
1800         g_mutex_unlock(&handle->lock);
1801
1802         return ret;
1803 }
1804
1805 int camera_set_batch_command(void *camera_handle, camera_batch_command_control_t *batch_command, int64_t *error_command)
1806 {
1807         camera_hal_handle *handle = NULL;
1808
1809         if (!camera_handle) {
1810                 LOGE("NULL handle");
1811                 return CAMERA_ERROR_INVALID_PARAMETER;
1812         }
1813
1814         if (!batch_command) {
1815                 LOGE("invalid pointer for batch_command");
1816                 return CAMERA_ERROR_INVALID_PARAMETER;
1817         }
1818
1819         handle = (camera_hal_handle *)camera_handle;
1820
1821         g_mutex_lock(&handle->lock);
1822
1823         LOGD("set batch command - flag %"PRIx64", state %d",
1824                 batch_command->command_set_flag, handle->state);
1825
1826         /* TODO: to be implemented */
1827
1828         g_mutex_unlock(&handle->lock);
1829
1830         return CAMERA_ERROR_NONE;
1831 }