80b5f3c45dce0e96ff184b197808162d4858d309
[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 (cb_id >= MESSAGE_CALLBACK_MAX) {
1051                 LOGE("invalid id %u", cb_id);
1052                 g_mutex_unlock(&handle->lock);
1053                 return CAMERA_ERROR_INVALID_PARAMETER;
1054         }
1055
1056         if (handle->message_cb[cb_id]) {
1057                 LOGD("remove message callback %p, user data %p - cb_id %u",
1058                         handle->message_cb[cb_id], handle->message_cb_data[cb_id], cb_id);
1059
1060                 handle->message_cb[cb_id] = NULL;
1061                 handle->message_cb_data[cb_id] = NULL;
1062         } else {
1063                 LOGE("already removed message cb");
1064                 g_mutex_unlock(&handle->lock);
1065                 return CAMERA_ERROR_INTERNAL;
1066         }
1067
1068         g_mutex_unlock(&handle->lock);
1069
1070         return CAMERA_ERROR_NONE;
1071 }
1072
1073 int camera_set_preview_stream_format(void *camera_handle, camera_format_t *format)
1074 {
1075         int i = 0;
1076         int j = 0;
1077         int ret = CAMERA_ERROR_NONE;
1078         gboolean capability_check = FALSE;
1079         guint32 fourcc = 0;
1080         camera_hal_handle *handle = NULL;
1081         camera_device_info_t *device_info = NULL;
1082         struct v4l2_format v4l2_fmt;
1083         struct v4l2_streamparm v4l2_parm;
1084
1085         if (!camera_handle) {
1086                 LOGE("NULL handle");
1087                 return CAMERA_ERROR_INVALID_PARAMETER;
1088         }
1089
1090         if (!format) {
1091                 LOGE("NULL format");
1092                 return CAMERA_ERROR_INVALID_PARAMETER;
1093         }
1094
1095         if (!g_device_info_list) {
1096                 LOGE("no device info list");
1097                 return CAMERA_ERROR_INTERNAL;
1098         }
1099
1100         handle = (camera_hal_handle *)camera_handle;
1101
1102         g_mutex_lock(&handle->lock);
1103
1104         if (handle->state != CAMERA_STATE_OPENED) {
1105                 LOGE("invalid state %d", handle->state);
1106                 g_mutex_unlock(&handle->lock);
1107                 return CAMERA_ERROR_INVALID_STATE;
1108         }
1109
1110         /* check capability */
1111         device_info = &g_device_info_list->device_info[handle->device_index];
1112
1113         /* format */
1114         for (i = 0 ; i < device_info->format_list.count ; i++) {
1115                 if (format->stream_format == device_info->format_list.formats[i]) {
1116                         LOGD("format matched %d, check resolution.", format->stream_format);
1117
1118                         /* resolution */
1119                         for (j = 0 ; j < device_info->preview_list.count ; j++) {
1120                                 if (format->stream_resolution.width == device_info->preview_list.resolutions[j].width &&
1121                                         format->stream_resolution.height == device_info->preview_list.resolutions[j].height) {
1122                                         LOGD("resolution matched %dx%d",
1123                                                 format->stream_resolution.width,
1124                                                 format->stream_resolution.height);
1125                                         capability_check = TRUE;
1126                                         break;
1127                                 }
1128                         }
1129
1130                         break;
1131                 }
1132         }
1133
1134         if (!capability_check) {
1135                 LOGE("capability failed - %d, %dx%d",
1136                         format->stream_format,
1137                         format->stream_resolution.width,
1138                         format->stream_resolution.height);
1139                 g_mutex_unlock(&handle->lock);
1140                 return CAMERA_ERROR_INVALID_PARAMETER;
1141         }
1142
1143         /* S_FMT */
1144         ret = _camera_get_fourcc_plane_num(format->stream_format, &fourcc, &handle->plane_num);
1145         if (ret != CAMERA_ERROR_NONE) {
1146                 LOGE("get fourcc failed [format %d]", format->stream_format);
1147                 g_mutex_unlock(&handle->lock);
1148                 return ret;
1149         }
1150
1151         memset(&v4l2_fmt, 0x0, sizeof(struct v4l2_format));
1152
1153         v4l2_fmt.type = handle->v4l2_type;
1154         if (V4L2_TYPE_IS_MULTIPLANAR(handle->v4l2_type)) {
1155                 v4l2_fmt.fmt.pix_mp.width = format->stream_resolution.width;
1156                 v4l2_fmt.fmt.pix_mp.height = format->stream_resolution.height;
1157                 v4l2_fmt.fmt.pix_mp.pixelformat = fourcc;
1158                 v4l2_fmt.fmt.pix_mp.num_planes = handle->plane_num;
1159         } else {
1160                 v4l2_fmt.fmt.pix.width = format->stream_resolution.width;
1161                 v4l2_fmt.fmt.pix.height = format->stream_resolution.height;
1162                 v4l2_fmt.fmt.pix.pixelformat = fourcc;
1163                 v4l2_fmt.fmt.pix.bytesperline = format->stream_resolution.width;
1164         }
1165
1166         if (ioctl(handle->device_fd, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
1167                 LOGE("S_FMT failed. errno %d", errno);
1168                 g_mutex_unlock(&handle->lock);
1169                 return CAMERA_ERROR_INTERNAL;
1170         }
1171
1172         if (V4L2_TYPE_IS_MULTIPLANAR(handle->v4l2_type)) {
1173                 for (i = 0 ; i < v4l2_fmt.fmt.pix_mp.num_planes ; i++) {
1174                         LOGD("plane[%d] stride %u, sizeimage %u", i,
1175                                 v4l2_fmt.fmt.pix_mp.plane_fmt[i].bytesperline,
1176                                 v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
1177                 }
1178         } else {
1179                 LOGD("stride %d, sizeimage %d",
1180                         v4l2_fmt.fmt.pix.bytesperline,
1181                         v4l2_fmt.fmt.pix.sizeimage);
1182         }
1183
1184         /* G_PARM */
1185         memset(&v4l2_parm, 0x0, sizeof(struct v4l2_streamparm));
1186
1187         v4l2_parm.type = handle->v4l2_type;
1188
1189         if (ioctl(handle->device_fd, VIDIOC_G_PARM, &v4l2_parm) < 0) {
1190                 LOGE("G_PARM failed. errno %d", errno);
1191                 g_mutex_unlock(&handle->lock);
1192                 return CAMERA_ERROR_INTERNAL;
1193         }
1194
1195         /* S_PARM to set fps */
1196         v4l2_parm.parm.capture.timeperframe.numerator = 1;
1197         v4l2_parm.parm.capture.timeperframe.denominator = format->stream_fps;
1198
1199         if (ioctl(handle->device_fd, VIDIOC_S_PARM, &v4l2_parm) < 0) {
1200                 LOGE("S_PARM failed. errno %d", errno);
1201                 g_mutex_unlock(&handle->lock);
1202                 return CAMERA_ERROR_INTERNAL;
1203         }
1204
1205         memcpy(&handle->preview_format, format, sizeof(camera_format_t));
1206
1207         LOGD("set preview stream [%d: %dx%d, fps %d]",
1208                 format->stream_format,
1209                 format->stream_resolution.width,
1210                 format->stream_resolution.height,
1211                 format->stream_fps);
1212
1213         LOGW("CAPTURE STREAM [%d: %dx%d] IS NOT SUPPORTED",
1214                 format->capture_format,
1215                 format->capture_resolution.width,
1216                 format->capture_resolution.height);
1217
1218         g_mutex_unlock(&handle->lock);
1219
1220         return CAMERA_ERROR_NONE;
1221 }
1222
1223 int camera_get_preview_stream_format(void *camera_handle, camera_format_t *format)
1224 {
1225         camera_hal_handle *handle = NULL;
1226
1227         if (!camera_handle) {
1228                 LOGE("NULL handle");
1229                 return CAMERA_ERROR_INVALID_PARAMETER;
1230         }
1231
1232         if (!format) {
1233                 LOGE("NULL format");
1234                 return CAMERA_ERROR_INVALID_PARAMETER;
1235         }
1236
1237         handle = (camera_hal_handle *)camera_handle;
1238
1239         g_mutex_lock(&handle->lock);
1240
1241         memcpy(format, &handle->preview_format, sizeof(camera_format_t));
1242
1243         LOGD("get stream format %d, %dx%d", format->stream_format,
1244                 format->stream_resolution.width, format->stream_resolution.height);
1245
1246         g_mutex_unlock(&handle->lock);
1247
1248         return CAMERA_ERROR_NONE;
1249 }
1250
1251
1252 int camera_start_preview(void *camera_handle, camera_preview_frame_cb callback, void *user_data)
1253 {
1254         int i = 0;
1255         int ret = 0;
1256         int result_count = 0;
1257         camera_hal_handle *handle = NULL;
1258         camera_buffer_t *buffer = NULL;
1259
1260         struct v4l2_buffer v4l2_buf;
1261         struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];
1262
1263         if (!camera_handle) {
1264                 LOGE("NULL handle");
1265                 return CAMERA_ERROR_INVALID_PARAMETER;
1266         }
1267
1268         if (!callback) {
1269                 LOGE("NULL callback for preview");
1270                 return CAMERA_ERROR_INVALID_PARAMETER;
1271         }
1272
1273         handle = (camera_hal_handle *)camera_handle;
1274
1275         g_mutex_lock(&handle->lock);
1276
1277         if (handle->state != CAMERA_STATE_OPENED) {
1278                 LOGE("invalid state %d", handle->state);
1279                 g_mutex_unlock(&handle->lock);
1280                 return CAMERA_ERROR_INVALID_STATE;
1281         }
1282
1283         /* request buffer */
1284         ret = _camera_v4l2_reqbufs(handle->device_fd,
1285                 handle->v4l2_type, V4L2_MEMORY_MMAP, PREVIEW_BUFFER_MAX, &result_count);
1286         if (ret != CAMERA_ERROR_NONE) {
1287                 g_mutex_unlock(&handle->lock);
1288                 return ret;
1289         }
1290
1291         LOGD("REQUESTED buffer count %d", result_count);
1292
1293         handle->preview_buffer_num = result_count;
1294
1295         /* query buffer, mmap and qbuf */
1296         for (i = 0 ; i < handle->preview_buffer_num ; i++) {
1297                 memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
1298                 memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
1299
1300                 v4l2_buf.type = handle->v4l2_type;
1301                 v4l2_buf.memory = V4L2_MEMORY_MMAP;
1302                 v4l2_buf.index = i;
1303                 v4l2_buf.m.planes = v4l2_planes;
1304                 v4l2_buf.length = handle->plane_num;
1305
1306                 if (ioctl(handle->device_fd, VIDIOC_QUERYBUF, &v4l2_buf) < 0) {
1307                         LOGE("[%d] query buf failed. errno %d", i, errno);
1308                         goto _START_PREVIEW_FAILED;
1309                 }
1310
1311                 buffer = &handle->preview_buffer[i];
1312
1313                 buffer->index = i;
1314                 buffer->format = handle->preview_format.stream_format;
1315                 buffer->resolution = handle->preview_format.stream_resolution;
1316                 buffer->total_size = v4l2_buf.length;
1317                 buffer->num_planes = handle->plane_num;
1318                 buffer->planes[0].size = v4l2_buf.length;
1319                 buffer->planes[0].data = mmap(0,
1320                         v4l2_buf.length,
1321                         PROT_READ | PROT_WRITE,
1322                         MAP_SHARED,
1323                         handle->device_fd,
1324                         v4l2_buf.m.offset);
1325                 if (buffer->planes[0].data == MAP_FAILED) {
1326                         LOGE("[%d] mmap failed. errno %d", i, errno);
1327                         goto _START_PREVIEW_FAILED;
1328                 }
1329         }
1330
1331         for (i = 0 ; i < handle->preview_buffer_num ; i++) {
1332                 if (_camera_v4l2_qbuf(handle->device_fd, handle->v4l2_type, V4L2_MEMORY_MMAP, i) != CAMERA_ERROR_NONE) {
1333                         LOGE("qbuf failed");
1334                         goto _START_PREVIEW_FAILED;
1335                 }
1336         }
1337
1338         /* stream on */
1339         ret = _camera_v4l2_stream(handle->device_fd, handle->v4l2_type, TRUE);
1340         if (ret != CAMERA_ERROR_NONE) {
1341                 LOGE("stream on failed");
1342                 goto _START_PREVIEW_FAILED;
1343         }
1344
1345         g_mutex_lock(&handle->preview_cb_lock);
1346
1347         handle->preview_cb_run = TRUE;
1348
1349         handle->preview_thread = g_thread_try_new("camera_hal_preview_thread",
1350                 _camera_preview_handler_func, (gpointer)handle, NULL);
1351         if (!handle->preview_thread) {
1352                 LOGE("failed to create preview callback thread");
1353                 g_mutex_unlock(&handle->preview_cb_lock);
1354                 goto _START_PREVIEW_FAILED;
1355         }
1356
1357         handle->preview_cb = callback;
1358         handle->preview_cb_data = user_data;
1359
1360         g_mutex_unlock(&handle->preview_cb_lock);
1361
1362         handle->state = CAMERA_STATE_PREVIEWING;
1363
1364         LOGD("start preview done");
1365
1366         g_mutex_unlock(&handle->lock);
1367
1368         return CAMERA_ERROR_NONE;
1369
1370 _START_PREVIEW_FAILED:
1371         /* stream off */
1372         if (ioctl(handle->device_fd, VIDIOC_STREAMOFF, &handle->v4l2_type) < 0)
1373                 LOGE("stream off failed. errno %d", errno);
1374
1375         /* munmap */
1376         for (i = 0 ; i < handle->preview_buffer_num ; i++) {
1377                 buffer = &handle->preview_buffer[i];
1378                 if (buffer->planes[0].data != NULL &&
1379                         buffer->planes[0].data != MAP_FAILED) {
1380                         LOGW("munmap %p", buffer->planes[0].data);
1381                         munmap(buffer->planes[0].data, buffer->planes[0].size);
1382                 }
1383                 memset(buffer, 0x0, sizeof(camera_buffer_t));
1384         }
1385
1386         /* reqbufs 0 */
1387         if (_camera_v4l2_reqbufs(handle->device_fd,
1388                 handle->v4l2_type, V4L2_MEMORY_MMAP, 0, &result_count) != CAMERA_ERROR_NONE)
1389                 LOGE("reqbufs 0 failed");
1390
1391         g_mutex_unlock(&handle->lock);
1392
1393         return ret;
1394 }
1395
1396 int camera_release_preview_buffer(void *camera_handle, int buffer_index)
1397 {
1398         int ret = CAMERA_ERROR_NONE;
1399         camera_hal_handle *handle = NULL;
1400
1401         if (!camera_handle) {
1402                 LOGE("NULL handle");
1403                 return CAMERA_ERROR_INVALID_PARAMETER;
1404         }
1405
1406         handle = (camera_hal_handle *)camera_handle;
1407
1408         if (buffer_index >= handle->preview_buffer_num) {
1409                 LOGE("invalid buffer index %d", buffer_index);
1410                 g_mutex_unlock(&handle->preview_cb_lock);
1411                 return CAMERA_ERROR_INVALID_PARAMETER;
1412         }
1413
1414         ret = _camera_v4l2_qbuf(handle->device_fd,
1415                 handle->v4l2_type, V4L2_MEMORY_MMAP, buffer_index);
1416
1417         g_mutex_lock(&handle->preview_cb_lock);
1418
1419         if (ret == CAMERA_ERROR_NONE) {
1420                 handle->live_buffer_num--;
1421                 LOGD("qbud done : index %d, live buffer num %d",
1422                         buffer_index, handle->live_buffer_num);
1423         } else {
1424                 LOGE("qbuf failed [index %d]", buffer_index);
1425         }
1426
1427         g_cond_signal(&handle->preview_cb_cond);
1428
1429         g_mutex_unlock(&handle->preview_cb_lock);
1430
1431         return ret;
1432 }
1433
1434 int camera_stop_preview(void *camera_handle)
1435 {
1436         int ret = CAMERA_ERROR_NONE;
1437         int i = 0;
1438         int result_count = 0;
1439         gint64 end_time;
1440         camera_hal_handle *handle = NULL;
1441
1442         if (!camera_handle) {
1443                 LOGE("NULL handle");
1444                 return CAMERA_ERROR_INVALID_PARAMETER;
1445         }
1446
1447         handle = (camera_hal_handle *)camera_handle;
1448
1449         LOGD("start");
1450
1451         g_mutex_lock(&handle->lock);
1452
1453         if (handle->state != CAMERA_STATE_PREVIEWING) {
1454                 LOGE("invalid state %d", handle->state);
1455                 g_mutex_unlock(&handle->lock);
1456                 return CAMERA_ERROR_INVALID_STATE;
1457         }
1458
1459         g_mutex_lock(&handle->preview_cb_lock);
1460
1461         handle->preview_cb_run = FALSE;
1462
1463         while (handle->live_buffer_num > 0) {
1464                 LOGD("wait for live buffer [num %d]", handle->live_buffer_num);
1465                 end_time = g_get_monotonic_time() + 3 * G_TIME_SPAN_SECOND;
1466                 if (!g_cond_wait_until(&handle->preview_cb_cond, &handle->preview_cb_lock, end_time)) {
1467                         LOGE("buffer wait failed");
1468                         break;
1469                 } else {
1470                         LOGD("signal received. check again...");
1471                 }
1472         }
1473
1474         g_mutex_unlock(&handle->preview_cb_lock);
1475
1476         /* stream off */
1477         ret = _camera_v4l2_stream(handle->device_fd, handle->v4l2_type, FALSE);
1478
1479         LOGD("stream off : 0x%x", ret);
1480
1481         /* munmap */
1482         for (i = 0 ; i < handle->preview_buffer_num ; i++) {
1483                 if (handle->preview_buffer[i].planes[0].data != NULL) {
1484                         LOGW("munmap %p", handle->preview_buffer[i].planes[0].data);
1485
1486                         munmap(handle->preview_buffer[i].planes[0].data, handle->preview_buffer[i].planes[0].size);
1487
1488                         handle->preview_buffer[i].planes[0].data = 0;
1489                         handle->preview_buffer[i].planes[0].size = 0;
1490                 } else {
1491                         LOGW("NULL data [index %d]", i);
1492                 }
1493         }
1494
1495         /* reqbufs 0 */
1496         ret = _camera_v4l2_reqbufs(handle->device_fd,
1497                 handle->v4l2_type, V4L2_MEMORY_MMAP, 0, &result_count);
1498
1499         LOGD("reqbufs 0 : 0x%x", ret);
1500
1501         /* wait for preview thread exit */
1502         g_thread_join(handle->preview_thread);
1503         handle->preview_thread = NULL;
1504
1505         handle->state = CAMERA_STATE_OPENED;
1506
1507         LOGD("stop preview done");
1508
1509         g_mutex_unlock(&handle->lock);
1510
1511         return CAMERA_ERROR_NONE;
1512 }
1513
1514 int camera_start_auto_focus(void *camera_handle)
1515 {
1516         if (!camera_handle) {
1517                 LOGE("NULL handle");
1518                 return CAMERA_ERROR_INVALID_PARAMETER;
1519         }
1520
1521         LOGD("NOT SUPPORTED");
1522
1523         /* auto focus is not supported */
1524         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1525 }
1526
1527 int camera_stop_auto_focus(void *camera_handle)
1528 {
1529         if (!camera_handle) {
1530                 LOGE("NULL handle");
1531                 return CAMERA_ERROR_INVALID_PARAMETER;
1532         }
1533
1534         LOGD("NOT SUPPORTED");
1535
1536         /* auto focus is not supported */
1537         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1538 }
1539
1540
1541 int camera_start_capture(void *camera_handle, camera_capture_cb callback, void *user_data)
1542 {
1543         if (!camera_handle || !callback) {
1544                 LOGE("NULL handle %p or callback %p", camera_handle, callback);
1545                 return CAMERA_ERROR_INVALID_PARAMETER;
1546         }
1547
1548         LOGD("NOT SUPPORTED");
1549
1550         /* capture function is not supported */
1551         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1552 }
1553
1554 int camera_stop_capture(void *camera_handle)
1555 {
1556         if (!camera_handle) {
1557                 LOGE("NULL handle");
1558                 return CAMERA_ERROR_INVALID_PARAMETER;
1559         }
1560
1561         LOGD("NOT SUPPORTED");
1562
1563         /* capture function is not supported */
1564         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1565 }
1566
1567 int camera_set_video_stream_format(void *camera_handle, camera_format_t *format)
1568 {
1569         if (!camera_handle) {
1570                 LOGE("NULL handle");
1571                 return CAMERA_ERROR_INVALID_PARAMETER;
1572         }
1573
1574         if (!format) {
1575                 LOGE("NULL format");
1576                 return CAMERA_ERROR_INVALID_PARAMETER;
1577         }
1578
1579         LOGD("NOT SUPPORTED");
1580
1581         /* single stream device can not support video stream */
1582         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1583 }
1584
1585 int camera_get_video_stream_format(void *camera_handle, camera_format_t *format)
1586 {
1587         if (!camera_handle) {
1588                 LOGE("NULL handle");
1589                 return CAMERA_ERROR_INVALID_PARAMETER;
1590         }
1591
1592         if (!format) {
1593                 LOGE("NULL format");
1594                 return CAMERA_ERROR_INVALID_PARAMETER;
1595         }
1596
1597         LOGD("NOT SUPPORTED");
1598
1599         /* single stream device can not support video stream */
1600         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1601 }
1602
1603 int camera_start_record(void *camera_handle, camera_video_frame_cb callback, void *user_data)
1604 {
1605         if (!camera_handle) {
1606                 LOGE("NULL handle");
1607                 return CAMERA_ERROR_INVALID_PARAMETER;
1608         }
1609
1610         if (!callback) {
1611                 LOGE("NULL callback for video");
1612                 return CAMERA_ERROR_INVALID_PARAMETER;
1613         }
1614
1615         LOGD("NOT SUPPORTED");
1616
1617         /* single stream device can not support video stream */
1618         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1619 }
1620
1621 int camera_release_video_buffer(void *camera_handle, int buffer_index)
1622 {
1623         if (!camera_handle) {
1624                 LOGE("NULL handle");
1625                 return CAMERA_ERROR_INVALID_PARAMETER;
1626         }
1627
1628         LOGD("NOT SUPPORTED");
1629
1630         /* single stream device can not support video stream */
1631         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1632 }
1633
1634 int camera_stop_record(void *camera_handle)
1635 {
1636         if (!camera_handle) {
1637                 LOGE("NULL handle");
1638                 return CAMERA_ERROR_INVALID_PARAMETER;
1639         }
1640
1641         LOGD("NOT SUPPORTED");
1642
1643         /* single stream device can not support video stream */
1644         return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1645 }
1646
1647 int camera_set_command(void *camera_handle, int64_t command, void *value)
1648 {
1649         int ret = CAMERA_ERROR_NONE;
1650         int cid = 0;
1651         int ctrl_ret = 0;
1652         camera_hal_handle *handle = NULL;
1653
1654         if (!camera_handle) {
1655                 LOGE("NULL handle");
1656                 return CAMERA_ERROR_INVALID_PARAMETER;
1657         }
1658
1659         if (!value) {
1660                 LOGE("invalid pointer for value");
1661                 return CAMERA_ERROR_INVALID_PARAMETER;
1662         }
1663
1664         handle = (camera_hal_handle *)camera_handle;
1665
1666         g_mutex_lock(&handle->lock);
1667
1668         if (handle->state < CAMERA_STATE_OPENED) {
1669                 LOGE("invalid state %d", handle->state);
1670                 g_mutex_unlock(&handle->lock);
1671                 return CAMERA_ERROR_INVALID_STATE;
1672         }
1673
1674         LOGD("set command %"PRId64" - state %d", command, handle->state);
1675
1676         switch (command) {
1677         case CAMERA_COMMAND_EXPOSURE:
1678                 cid = V4L2_CID_BRIGHTNESS;
1679                 break;
1680         case CAMERA_COMMAND_CONTRAST:
1681                 cid = V4L2_CID_CONTRAST;
1682                 break;
1683         case CAMERA_COMMAND_SATURATION:
1684                 cid = V4L2_CID_SATURATION;
1685                 break;
1686         case CAMERA_COMMAND_SHARPNESS:
1687                 cid = V4L2_CID_SHARPNESS;
1688                 break;
1689         default:
1690                 LOGE("NOT_SUPPORTED %"PRId64, command);
1691                 g_mutex_unlock(&handle->lock);
1692                 return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1693         }
1694
1695         ctrl_ret = _camera_v4l2_s_ctrl(handle->device_fd, cid, ((int)(long)value));
1696         if (ctrl_ret < 0) {
1697                 switch (errno) {
1698                 case EACCES:
1699                 case EPERM:
1700                         LOGE("Permission denied %d", errno);
1701                         ret = CAMERA_ERROR_PERMISSION_DENIED;
1702                         break;
1703                 case EINVAL:
1704                         LOGE("Invalid argument");
1705                         ret = CAMERA_ERROR_INVALID_PARAMETER;
1706                         break;
1707                 case EBUSY:
1708                         LOGE("Device busy");
1709                         ret = CAMERA_ERROR_DEVICE_BUSY;
1710                         break;
1711                 case ENOTSUP:
1712                         LOGE("Not supported");
1713                         ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1714                         break;
1715                 default:
1716                         LOGE("Unknown errro %d", errno);
1717                         ret = CAMERA_ERROR_INTERNAL;
1718                         break;
1719                 }
1720         }
1721
1722         g_mutex_unlock(&handle->lock);
1723
1724         return ret;
1725 }
1726
1727 int camera_get_command(void *camera_handle, int64_t command, void **value)
1728 {
1729         int ret = CAMERA_ERROR_NONE;
1730         int cid = 0;
1731         int ctrl_ret = 0;
1732         camera_hal_handle *handle = NULL;
1733
1734         if (!camera_handle) {
1735                 LOGE("NULL handle");
1736                 return CAMERA_ERROR_INVALID_PARAMETER;
1737         }
1738
1739         if (!value) {
1740                 LOGE("invalid pointer for value");
1741                 return CAMERA_ERROR_INVALID_PARAMETER;
1742         }
1743
1744         handle = (camera_hal_handle *)camera_handle;
1745
1746         g_mutex_lock(&handle->lock);
1747
1748         LOGD("get command %"PRId64" - state %d", command, handle->state);
1749
1750         switch (command) {
1751         case CAMERA_COMMAND_EXPOSURE:
1752                 cid = V4L2_CID_BRIGHTNESS;
1753                 break;
1754         case CAMERA_COMMAND_CONTRAST:
1755                 cid = V4L2_CID_CONTRAST;
1756                 break;
1757         case CAMERA_COMMAND_SATURATION:
1758                 cid = V4L2_CID_SATURATION;
1759                 break;
1760         case CAMERA_COMMAND_SHARPNESS:
1761                 cid = V4L2_CID_SHARPNESS;
1762                 break;
1763         default:
1764                 LOGE("NOT_SUPPORTED %"PRId64, command);
1765                 g_mutex_unlock(&handle->lock);
1766                 return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1767         }
1768
1769         ctrl_ret = _camera_v4l2_g_ctrl(handle->device_fd, cid, (int *)value);
1770         if (ctrl_ret < 0) {
1771                 switch (errno) {
1772                 case EACCES:
1773                 case EPERM:
1774                         LOGE("Permission denied %d", errno);
1775                         ret = CAMERA_ERROR_PERMISSION_DENIED;
1776                         break;
1777                 case EINVAL:
1778                         LOGE("Invalid argument");
1779                         ret = CAMERA_ERROR_INVALID_PARAMETER;
1780                         break;
1781                 case EBUSY:
1782                         LOGE("Device busy");
1783                         ret = CAMERA_ERROR_DEVICE_BUSY;
1784                         break;
1785                 case ENOTSUP:
1786                         LOGE("Not supported");
1787                         ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
1788                         break;
1789                 default:
1790                         LOGE("Unknown errro %d", errno);
1791                         ret = CAMERA_ERROR_INTERNAL;
1792                         break;
1793                 }
1794         }
1795
1796         g_mutex_unlock(&handle->lock);
1797
1798         return ret;
1799 }
1800
1801 int camera_set_batch_command(void *camera_handle, camera_batch_command_control_t *batch_command, int64_t *error_command)
1802 {
1803         camera_hal_handle *handle = NULL;
1804
1805         if (!camera_handle) {
1806                 LOGE("NULL handle");
1807                 return CAMERA_ERROR_INVALID_PARAMETER;
1808         }
1809
1810         if (!batch_command) {
1811                 LOGE("invalid pointer for batch_command");
1812                 return CAMERA_ERROR_INVALID_PARAMETER;
1813         }
1814
1815         handle = (camera_hal_handle *)camera_handle;
1816
1817         g_mutex_lock(&handle->lock);
1818
1819         LOGD("set batch command - flag %"PRIx64", state %d",
1820                 batch_command->command_set_flag, handle->state);
1821
1822         /* TODO: to be implemented */
1823
1824         g_mutex_unlock(&handle->lock);
1825
1826         return CAMERA_ERROR_NONE;
1827 }