Support Next HAL for tizen 6.5 82/252582/3 accepted/tizen/unified/20210209.124342 submit/tizen/20210209.044918 submit/tizen/20210209.072453
authorJeongmo Yang <jm80.yang@samsung.com>
Fri, 29 Jan 2021 12:36:21 +0000 (21:36 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Mon, 8 Feb 2021 11:02:57 +0000 (20:02 +0900)
[Version] 0.1.0
[Issue Type] Update

Change-Id: I649fa88fef88033f2efe1ad263219e39c8db1452
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
configure.ac
packaging/camera-hal-v4l2.spec
src/Makefile.am
src/hal_camera_v4l2.c [new file with mode: 0644]
src/hal_camera_v4l2_private.h [new file with mode: 0644]
src/tizen_camera_v4l2.c [deleted file]
src/tizen_camera_v4l2_private.h [deleted file]

index e60590060f5849e37f77656b3bb9575459f47e99..ef6f7fc11ed5deee08aa3b2efb3cbfe36fc0bbb9 100644 (file)
@@ -35,6 +35,12 @@ PKG_CHECK_MODULES(DLOG, dlog)
 AC_SUBST(DLOG_CFLAGS)
 AC_SUBST(DLOG_LIBS)
 
+PKG_CHECK_MODULES(HAL_API_COMMON, hal-api-common)
+AC_SUBST(HAL_API_COMMON_CFLAGS)
+
+PKG_CHECK_MODULES(HAL_API_CAMERA, hal-api-camera)
+AC_SUBST(HAL_API_CAMERA_CFLAGS)
+
 # Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS([fcntl.h memory.h stdlib.h string.h sys/time.h unistd.h])
index 61e7eeee2581f6bdb54c6d5985b0302b1de2c4b8..fa0d652cefb5d2dd1e35fb34147a87d08614fbbf 100644 (file)
@@ -1,6 +1,6 @@
 Name:       camera-hal-v4l2
 Summary:    Tizen Camera Hal for V4L2
-Version:    0.0.13
+Version:    0.1.0
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
@@ -10,8 +10,8 @@ Requires(postun): /sbin/ldconfig
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(libtbm)
 BuildRequires:  pkgconfig(dlog)
-BuildRequires:  mm-hal-interface-devel
-BuildRequires:  gtest-devel
+BuildRequires:  pkgconfig(hal-api-common)
+BuildRequires:  pkgconfig(hal-api-camera)
 
 %description
 Tizen Camera Hal for V4L2.
@@ -23,7 +23,7 @@ Tizen Camera Hal for V4L2.
 
 %build
 ./autogen.sh
-%configure --disable-static
+%configure --disable-static --libdir=%{_hal_libdir}
 make %{?jobs:-j%jobs}
 
 %install
@@ -39,5 +39,5 @@ make %{?jobs:-j%jobs}
 %manifest %{name}.manifest
 %license LICENSE.APLv2
 %defattr(-,root,root,-)
-%{_libdir}/*.so
+%{_hal_libdir}/*.so
 
index 46be497f5510df3453a0490d52c740bae4a7cec3..58cb115836a486fabd79f247564159ae1f8a0e36 100644 (file)
@@ -1,20 +1,24 @@
 ACLOCAL_AMFLAGS='-I m4'
 
-lib_LTLIBRARIES = libtizen-camera.la
+lib_LTLIBRARIES = libhal-backend-camera.la
 
-noinst_HEADERS = tizen_camera_v4l2_private.h
+noinst_HEADERS = hal_camera_v4l2_private.h
 
-libtizen_camera_la_SOURCES = tizen_camera_v4l2.c
+libhal_backend_camera_la_SOURCES = hal_camera_v4l2.c
 
-libtizen_camera_la_CFLAGS = -I$(srcdir)/include \
-                            $(GLIB_CFLAGS) \
-                            $(DLOG_CFLAGS) \
-                            $(TBM_CFLAGS)
+libhal_backend_camera_la_CFLAGS = \
+       -I$(srcdir)/include \
+       $(GLIB_CFLAGS) \
+       $(DLOG_CFLAGS) \
+       $(HAL_API_COMMON_CFLAGS) \
+       $(HAL_API_CAMERA_CFLAGS) \
+       $(TBM_CFLAGS)
 
-libtizen_camera_la_LIBADD = $(GLIB_LIBS) \
-                           $(DLOG_LIBS) \
-                           $(TBM_LIBS)
+libhal_backend_camera_la_LIBADD = \
+       $(GLIB_LIBS) \
+       $(DLOG_LIBS) \
+       $(TBM_LIBS)
 
-libtizen_camera_la_CFLAGS += -fdata-sections -ffunction-sections -Wl,--gc-sections
-libtizen_camera_la_LDFLAGS = -Wl,--gc-sections -avoid-version
+libhal_backend_camera_la_CFLAGS += -fdata-sections -ffunction-sections -Wl,--gc-sections
+libhal_backend_camera_la_LDFLAGS = -Wl,--gc-sections -avoid-version
 
diff --git a/src/hal_camera_v4l2.c b/src/hal_camera_v4l2.c
new file mode 100644 (file)
index 0000000..e82d995
--- /dev/null
@@ -0,0 +1,2131 @@
+/*
+ * tizen_camera_v4l2.c
+ *
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <glob.h>
+#include <dlog.h>
+#include <sched.h>
+#include "hal_camera_v4l2_private.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif /* LOG_TAG */
+#define LOG_TAG "CAMERA_HAL"
+
+#define TEST_JPEG_PATH          "/home/owner/media/Images/test.jpg"
+#define DEVICE_NODE_PATH_MAX    16
+#define DEVICE_NODE_PATH_PREFIX "/dev/video"
+#define FOURCC_FORMAT           "%c%c%c%c"
+#define FOURCC_CONVERT(fourcc)  \
+       fourcc & 0xff,\
+       (fourcc >> 8) & 0xff,\
+       (fourcc >> 16) & 0xff,\
+       (fourcc >> 24) & 0xff
+
+
+static camera_device_info_list_s *g_device_info_list;
+static guint32 g_device_caps;
+static GMutex g_device_info_lock;
+
+
+static void __camera_hal_v4l2_destructor(void) __attribute__((destructor));
+
+
+static void __camera_hal_v4l2_destructor(void)
+{
+       LOGD("release device info list %p", g_device_info_list);
+
+       g_free(g_device_info_list);
+       g_device_info_list = NULL;
+
+       return;
+}
+
+
+static int __camera_v4l2_wait_frame(int device_fd, int wait_time)
+{
+       int ret = CAMERA_ERROR_NONE;
+       fd_set fds;
+       struct timeval timeout;
+
+       if (device_fd < 0) {
+               LOGE("invalid fd %d", device_fd);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       FD_ZERO(&fds);
+       FD_SET(device_fd, &fds);
+
+       memset(&timeout, 0x0, sizeof(struct timeval));
+
+       timeout.tv_sec = wait_time;
+       timeout.tv_usec = 0;
+
+       /*LOGD("select : %d sec", wait_time);*/
+
+       ret = select(device_fd + 1, &fds, NULL, NULL, &timeout);
+       if (ret == -1) {
+               if (EINTR == errno) {
+                       LOGD("select error : EINTR");
+                       return CAMERA_ERROR_NONE;
+               }
+               LOGE("select failed. errno %d", errno);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       if (ret == 0) {
+               LOGE("select timeout.");
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       /*LOGD("select done");*/
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+static int __camera_v4l2_g_ctrl(int device_fd, int cid, int *value)
+{
+       int ret = 0;
+       struct v4l2_control ctrl;
+
+       if (!value) {
+               LOGE("NULL param");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       memset(&ctrl, 0x0, sizeof(struct v4l2_control));
+
+       ctrl.id = cid;
+
+       ret = ioctl(device_fd, VIDIOC_G_CTRL, &ctrl);
+
+       *value = ctrl.value;
+
+       LOGD("G_CTRL id 0x%x, value %d, ret %d", cid, *value, ret);
+
+       return ret;
+}
+
+
+static int __camera_v4l2_s_ctrl(int device_fd, int cid, int value)
+{
+       int ret = 0;
+       struct v4l2_control ctrl;
+
+       memset(&ctrl, 0x0, sizeof(struct v4l2_control));
+
+       ctrl.id = cid;
+       ctrl.value = value;
+
+       ret = ioctl(device_fd, VIDIOC_S_CTRL, &ctrl);
+
+       LOGD("S_CTRL id 0x%x, value %d, ret %d", cid, value, ret);
+
+       return ret;
+}
+
+
+static int __camera_v4l2_stream(int device_fd, int type, gboolean onoff)
+{
+       if (device_fd < 0) {
+               LOGE("invalid fd %d", device_fd);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       if (ioctl(device_fd, onoff ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type) < 0) {
+               LOGE("stream %d failed. [t:%d] errno %d", onoff, type, errno);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       LOGD("stream %d done [t:%d]", onoff, type);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+static int __camera_v4l2_reqbufs(int device_fd, int type, int memory, uint32_t count, uint32_t *result_count)
+{
+       struct v4l2_requestbuffers v4l2_reqbuf;
+
+       if (device_fd < 0) {
+               LOGE("invalid fd %d", device_fd);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!result_count) {
+               LOGE("NULL parameter");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       memset(&v4l2_reqbuf, 0x0, sizeof(struct v4l2_requestbuffers));
+
+       v4l2_reqbuf.type = type;
+       v4l2_reqbuf.memory = memory;
+       v4l2_reqbuf.count = count;
+
+       if (ioctl(device_fd, VIDIOC_REQBUFS, &v4l2_reqbuf) < 0) {
+               LOGE("REQBUFS[count %d] failed. errno %d", count, errno);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       if (v4l2_reqbuf.count != count)
+               LOGW("different count [req:%d, result:%d]", count, v4l2_reqbuf.count);
+
+       *result_count = v4l2_reqbuf.count;
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+static int __camera_v4l2_qbuf(int device_fd, int type, int memory, int index)
+{
+       struct v4l2_buffer v4l2_buf;
+       struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];
+
+       if (device_fd < 0) {
+               LOGE("invalid fd %d", device_fd);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
+       memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
+
+       v4l2_buf.index = index;
+       v4l2_buf.type = type;
+       v4l2_buf.memory = memory;
+       v4l2_buf.m.planes = v4l2_planes;
+       v4l2_buf.length = 460800;
+       v4l2_buf.bytesused = 460800;
+
+       if (ioctl(device_fd, VIDIOC_QBUF, &v4l2_buf) < 0) {
+               LOGE("qbuf failed.  [i: %d, t: %d, m: %d] errno %d",
+                       index, type, memory, errno);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       /*LOGD("QBUF done [i: %d, t: %d, m: %d]", index, type, memory);*/
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+static int __camera_v4l2_dqbuf(int device_fd, int type, int memory, int *index)
+{
+       int ret = CAMERA_ERROR_NONE;
+       struct v4l2_buffer v4l2_buf;
+       struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];
+
+       if (device_fd < 0) {
+               LOGE("invalid fd %d", device_fd);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!index) {
+               LOGE("NULL parameter");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
+       memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
+
+       v4l2_buf.type = type;
+       v4l2_buf.memory = memory;
+       v4l2_buf.m.planes = v4l2_planes;
+
+       ret = ioctl(device_fd, VIDIOC_DQBUF, &v4l2_buf);
+       if (ret < 0) {
+               if (errno != EIO) {
+                       LOGE("dqbuf failed. [t: %d, m: %d] errno %d",
+                               type, memory, errno);
+                       return CAMERA_ERROR_DEVICE_READ;
+               }
+       }
+
+       *index = v4l2_buf.index;
+
+       /*LOGD("dqbuf index %d", *index);*/
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+static int __camera_get_format(guint32 fourcc, int *pixel_format)
+{
+       if (!pixel_format) {
+               LOGE("NULL parameter");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       switch (fourcc) {
+       case V4L2_PIX_FMT_NV12:
+       case V4L2_PIX_FMT_NV12M:
+       case V4L2_PIX_FMT_NV12MT:
+               *pixel_format = CAMERA_PIXEL_FORMAT_NV12;
+               break;
+       case V4L2_PIX_FMT_NV21:
+       case V4L2_PIX_FMT_NV21M:
+               *pixel_format = CAMERA_PIXEL_FORMAT_NV21;
+               break;
+       case V4L2_PIX_FMT_YUV420:
+               *pixel_format = CAMERA_PIXEL_FORMAT_I420;
+               break;
+       case V4L2_PIX_FMT_YVU420:
+               *pixel_format = CAMERA_PIXEL_FORMAT_YV12;
+               break;
+       case V4L2_PIX_FMT_YUYV:
+               *pixel_format = CAMERA_PIXEL_FORMAT_YUYV;
+               break;
+       case V4L2_PIX_FMT_UYVY:
+               *pixel_format = CAMERA_PIXEL_FORMAT_UYVY;
+               break;
+       case V4L2_PIX_FMT_JPEG:
+               *pixel_format = CAMERA_PIXEL_FORMAT_JPEG;
+               break;
+       case V4L2_PIX_FMT_H264:
+               *pixel_format = CAMERA_PIXEL_FORMAT_H264;
+               break;
+       default:
+               LOGE("unknown fourcc "FOURCC_FORMAT, FOURCC_CONVERT(fourcc));
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       LOGD("fourcc "FOURCC_FORMAT" -> %d",
+               FOURCC_CONVERT(fourcc), *pixel_format);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+static int __camera_get_fourcc_plane_num(int pixel_format, guint32 *fourcc, guint32 *plane_num)
+{
+       if (!fourcc || !plane_num) {
+               LOGE("NULL parameter %p %p", fourcc, plane_num);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       switch (pixel_format) {
+       case CAMERA_PIXEL_FORMAT_NV12:
+               *fourcc = V4L2_PIX_FMT_NV12;
+               *plane_num = 2;
+               break;
+       case CAMERA_PIXEL_FORMAT_NV21:
+               *fourcc = V4L2_PIX_FMT_NV21;
+               *plane_num = 2;
+               break;
+       case CAMERA_PIXEL_FORMAT_I420:
+               *fourcc = V4L2_PIX_FMT_YUV420;
+               *plane_num = 3;
+               break;
+       case CAMERA_PIXEL_FORMAT_YV12:
+               *fourcc = V4L2_PIX_FMT_YVU420;
+               *plane_num = 3;
+               break;
+       case CAMERA_PIXEL_FORMAT_YUYV:
+               *fourcc = V4L2_PIX_FMT_YUYV;
+               *plane_num = 1;
+               break;
+       case CAMERA_PIXEL_FORMAT_UYVY:
+               *fourcc = V4L2_PIX_FMT_UYVY;
+               *plane_num = 1;
+               break;
+       case CAMERA_PIXEL_FORMAT_JPEG:
+               *fourcc = V4L2_PIX_FMT_JPEG;
+               *plane_num = 1;
+               break;
+       case CAMERA_PIXEL_FORMAT_H264:
+               *fourcc = V4L2_PIX_FMT_H264;
+               *plane_num = 1;
+               break;
+       default:
+               LOGE("unknown format %d", pixel_format);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       LOGD("format %d -> fourcc "FOURCC_FORMAT,
+               pixel_format, FOURCC_CONVERT(*fourcc));
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+static int __camera_get_device_info(int device_index, int device_fd, camera_device_info_s *device_info, char *node_path)
+{
+       int i = 0;
+       int j = 0;
+       int format_count = 0;
+       int resolution_count = 0;
+       int camera_format = 0;
+       struct v4l2_fmtdesc v4l2_format;
+       struct v4l2_frmsizeenum v4l2_frame;
+
+       if (device_fd < 0 || !device_info || !node_path) {
+               LOGE("invalid param %d %p %p", device_fd, device_info, node_path);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGD("Get Supported format and resolution");
+
+       for (i = 0 ; ; i++) {
+               memset(&v4l2_format, 0x0, sizeof(struct v4l2_fmtdesc));
+
+               v4l2_format.index = i;
+               v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+               if (ioctl(device_fd, VIDIOC_ENUM_FMT, &v4l2_format) < 0) {
+                       LOGW("\tformat : end of enumeration");
+                       break;
+               }
+
+               LOGD("\tformat[%d] "FOURCC_FORMAT, i, FOURCC_CONVERT(v4l2_format.pixelformat));
+
+               if (__camera_get_format(v4l2_format.pixelformat, &camera_format) != CAMERA_ERROR_NONE)
+                       continue;
+
+               device_info->format_list.formats[format_count] = camera_format;
+
+               resolution_count = 0;
+
+               for (j = 0 ; ; j++) {
+                       memset(&v4l2_frame, 0x0, sizeof(struct v4l2_frmsizeenum));
+
+                       v4l2_frame.index = j;
+                       v4l2_frame.pixel_format = v4l2_format.pixelformat;
+
+                       if (ioctl(device_fd, VIDIOC_ENUM_FRAMESIZES, &v4l2_frame) < 0) {
+                               LOGW("\t\tframe : end of enumeration ");
+                               break;
+                       }
+
+                       switch (v4l2_frame.type) {
+                       case V4L2_FRMSIZE_TYPE_DISCRETE:
+                               device_info->preview_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
+                               device_info->preview_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
+                               device_info->capture_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
+                               device_info->capture_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
+                               device_info->video_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
+                               device_info->video_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
+
+                               resolution_count++;
+
+                               LOGD("\t\tsize[%d] %ux%u", j,
+                                       v4l2_frame.discrete.width,
+                                       v4l2_frame.discrete.height);
+                               break;
+                       case V4L2_FRMSIZE_TYPE_CONTINUOUS:
+                               LOGW("\t\tsize[%d] %ux%u - %ux%u", j,
+                                       v4l2_frame.stepwise.min_width,
+                                       v4l2_frame.stepwise.min_height,
+                                       v4l2_frame.stepwise.max_width,
+                                       v4l2_frame.stepwise.max_height);
+                               break;
+                       case V4L2_FRMSIZE_TYPE_STEPWISE:
+                               LOGW("\t\tsize[%d] %ux%u - %ux%u (step %ux%u)", j,
+                                       v4l2_frame.stepwise.min_width,
+                                       v4l2_frame.stepwise.min_height,
+                                       v4l2_frame.stepwise.max_width,
+                                       v4l2_frame.stepwise.max_height,
+                                       v4l2_frame.stepwise.step_width,
+                                       v4l2_frame.stepwise.step_height);
+                               break;
+                       default:
+                               LOGE("\t\tunknown frame type %d", v4l2_frame.type);
+                               break;
+                       }
+               }
+
+               device_info->preview_list.count = resolution_count;
+               device_info->capture_list.count = resolution_count;
+               device_info->video_list.count = resolution_count;
+
+               LOGD("\t\tresolution count [%d]", resolution_count);
+
+               format_count++;
+       }
+
+       device_info->index = device_index;
+       device_info->format_list.count = format_count;
+       device_info->facing_direction = CAMERA_FACING_DIRECTION_EXTERNAL;
+       snprintf(device_info->name, sizeof(device_info->name), "V4L2_CAMERA");
+       snprintf(device_info->node_path, sizeof(device_info->node_path), "%s", node_path);
+
+       LOGD("\tformat count [%d]", format_count);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+static int __camera_get_device_info_list(void)
+{
+       int i = 0;
+       int ret = 0;
+       int device_count = 0;
+       int device_fd = CAMERA_HAL_INITIAL_FD;
+       glob_t glob_buf;
+       struct v4l2_capability v4l2_cap;
+       camera_device_info_list_s *device_info_list = NULL;
+
+       g_mutex_lock(&g_device_info_lock);
+
+       if (g_device_info_list) {
+               LOGD("device info list is already existed");
+               ret = CAMERA_ERROR_NONE;
+               goto _GET_DEVICE_INFO_LIST_DONE;
+       }
+
+       device_info_list = g_new0(camera_device_info_list_s, 1);
+       if (!device_info_list) {
+               LOGE("failed to alloc device info structure");
+               ret = CAMERA_ERROR_OUT_OF_MEMORY;
+               goto _GET_DEVICE_INFO_LIST_DONE;
+       }
+
+       memset(&glob_buf, 0x0, sizeof(glob_t));
+
+       ret = glob(DEVICE_NODE_PATH_PREFIX"*", 0, 0, &glob_buf);
+       if (ret != 0) {
+               switch (ret) {
+               case GLOB_NOSPACE:
+                       LOGE("out of memory");
+                       ret = CAMERA_ERROR_OUT_OF_MEMORY;
+                       goto _GET_DEVICE_INFO_LIST_DONE;
+               case GLOB_ABORTED:
+                       LOGE("read error");
+                       ret = CAMERA_ERROR_INTERNAL;
+                       goto _GET_DEVICE_INFO_LIST_DONE;
+               case GLOB_NOMATCH:
+                       LOGE("match not found");
+                       ret = CAMERA_ERROR_INTERNAL;
+                       goto _GET_DEVICE_INFO_LIST_DONE;
+               default:
+                       LOGE("unknown error : %d", ret);
+                       ret = CAMERA_ERROR_INTERNAL;
+                       goto _GET_DEVICE_INFO_LIST_DONE;
+               }
+       }
+
+       LOGD("device node count : %zu", glob_buf.gl_pathc);
+
+       for (i = 0 ; i < glob_buf.gl_pathc ; i++) {
+               LOGD("[%d] check device [%s]", i, glob_buf.gl_pathv[i]);
+
+               device_fd = open(glob_buf.gl_pathv[i], O_RDWR);
+               if (device_fd < 0) {
+                       LOGE("open failed [%s] errno %d", glob_buf.gl_pathv[i], errno);
+                       continue;
+               }
+
+               memset(&v4l2_cap, 0x0, sizeof(struct v4l2_capability));
+
+               if (ioctl(device_fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0) {
+                       LOGE("querycap failed. errno %d", errno);
+                       close(device_fd);
+                       continue;
+               }
+
+               if (v4l2_cap.capabilities & V4L2_CAP_DEVICE_CAPS)
+                       g_device_caps = v4l2_cap.device_caps;
+               else
+                       g_device_caps = v4l2_cap.capabilities;
+
+               if (!(g_device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) ||
+                       (g_device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) {
+                       LOGW("[%s] is not a capture device 0x%x", glob_buf.gl_pathv[i], g_device_caps);
+                       close(device_fd);
+                       continue;
+               }
+
+               ret = __camera_get_device_info(device_count, device_fd,
+                       &device_info_list->device_info[device_count], glob_buf.gl_pathv[i]);
+
+               close(device_fd);
+
+               if (ret == CAMERA_ERROR_NONE)
+                       device_count++;
+       }
+
+       device_info_list->count = device_count;
+       g_device_info_list = device_info_list;
+
+       LOGD("new g_device_info_list %p - device count %d",
+               g_device_info_list, device_count);
+
+_GET_DEVICE_INFO_LIST_DONE:
+       g_mutex_unlock(&g_device_info_lock);
+       LOGD("ret 0x%x", ret);
+
+       if (ret != CAMERA_ERROR_NONE)
+               g_free(device_info_list);
+
+       return ret;
+}
+
+
+static int __camera_stop_stream(hal_camera_handle *handle, uint32_t buffer_count)
+{
+       int i = 0;
+       int ret = CAMERA_ERROR_NONE;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGD("buffer count[%d]", buffer_count);
+
+       /* stream off */
+       ret = __camera_v4l2_stream(handle->device_fd, handle->buffer_type, FALSE);
+
+       LOGD("stream off : 0x%x", ret);
+
+       /* munmap */
+       for (i = 0 ; i < buffer_count ; i++) {
+               if (handle->camera_buffers[i].planes[0].data != NULL) {
+                       LOGW("munmap %p", handle->camera_buffers[i].planes[0].data);
+
+                       munmap(handle->camera_buffers[i].planes[0].data, handle->camera_buffers[i].planes[0].size);
+
+                       handle->camera_buffers[i].planes[0].data = 0;
+                       handle->camera_buffers[i].planes[0].size = 0;
+               } else {
+                       LOGW("NULL data [index %d]", i);
+               }
+       }
+
+       /* reqbufs 0 */
+       ret = __camera_v4l2_reqbufs(handle->device_fd,
+               handle->buffer_type, V4L2_MEMORY_MMAP, 0, &buffer_count);
+
+       LOGD("reqbufs 0 : 0x%x", ret);
+
+       return ret;
+}
+
+
+static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_e pixel_format,
+       camera_resolution_s *resolution, uint32_t fps, uint32_t request_buffer_count)
+{
+       int i = 0;
+       int ret = CAMERA_ERROR_NONE;
+       camera_buffer_s *buffer = NULL;
+       struct v4l2_format v4l2_fmt;
+       struct v4l2_streamparm v4l2_parm;
+       struct v4l2_buffer v4l2_buf;
+       struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];;
+       guint32 fourcc = 0;
+       guint32 plane_num = 0;
+
+       if (!handle || !resolution) {
+               LOGE("NULL param %p %p", handle, resolution);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       /* S_FMT */
+       ret = __camera_get_fourcc_plane_num(pixel_format, &fourcc, &plane_num);
+       if (ret != CAMERA_ERROR_NONE) {
+               LOGE("get fourcc failed [format %d]", pixel_format);
+               return ret;
+       }
+
+       memset(&v4l2_fmt, 0x0, sizeof(struct v4l2_format));
+
+       v4l2_fmt.type = handle->buffer_type;
+       if (V4L2_TYPE_IS_MULTIPLANAR(handle->buffer_type)) {
+               v4l2_fmt.fmt.pix_mp.width = resolution->width;
+               v4l2_fmt.fmt.pix_mp.height = resolution->height;
+               v4l2_fmt.fmt.pix_mp.pixelformat = fourcc;
+               v4l2_fmt.fmt.pix_mp.num_planes = plane_num;
+       } else {
+               v4l2_fmt.fmt.pix.width = resolution->width;
+               v4l2_fmt.fmt.pix.height = resolution->height;
+               v4l2_fmt.fmt.pix.pixelformat = fourcc;
+               v4l2_fmt.fmt.pix.bytesperline = resolution->width;
+       }
+
+       if (ioctl(handle->device_fd, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
+               LOGE("S_FMT failed. errno %d", errno);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       if (V4L2_TYPE_IS_MULTIPLANAR(handle->buffer_type)) {
+               for (i = 0 ; i < v4l2_fmt.fmt.pix_mp.num_planes ; i++) {
+                       LOGD("plane[%d] stride %u, sizeimage %u", i,
+                               v4l2_fmt.fmt.pix_mp.plane_fmt[i].bytesperline,
+                               v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+               }
+       } else {
+               LOGD("stride %d, sizeimage %d",
+                       v4l2_fmt.fmt.pix.bytesperline,
+                       v4l2_fmt.fmt.pix.sizeimage);
+       }
+
+       /* G_PARM */
+       memset(&v4l2_parm, 0x0, sizeof(struct v4l2_streamparm));
+
+       v4l2_parm.type = handle->buffer_type;
+
+       if (ioctl(handle->device_fd, VIDIOC_G_PARM, &v4l2_parm) < 0) {
+               LOGE("G_PARM failed. errno %d", errno);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       /* S_PARM to set fps */
+       v4l2_parm.parm.capture.timeperframe.numerator = 1;
+       v4l2_parm.parm.capture.timeperframe.denominator = fps;
+
+       if (ioctl(handle->device_fd, VIDIOC_S_PARM, &v4l2_parm) < 0) {
+               LOGE("S_PARM failed. errno %d", errno);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       /* request buffer */
+       ret = __camera_v4l2_reqbufs(handle->device_fd,
+               handle->buffer_type, V4L2_MEMORY_MMAP, request_buffer_count, &handle->buffer_count);
+       if (ret != CAMERA_ERROR_NONE) {
+               return ret;
+       }
+
+       LOGD("buffer count : request %d -> result %d",
+               request_buffer_count, handle->buffer_count);
+
+       /* query buffer, mmap and qbuf */
+       for (i = 0 ; i < handle->buffer_count ; i++) {
+               memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
+               memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
+
+               v4l2_buf.type = handle->buffer_type;
+               v4l2_buf.memory = V4L2_MEMORY_MMAP;
+               v4l2_buf.index = i;
+               v4l2_buf.m.planes = v4l2_planes;
+               v4l2_buf.length = plane_num;
+
+               if (ioctl(handle->device_fd, VIDIOC_QUERYBUF, &v4l2_buf) < 0) {
+                       LOGE("[%d] query buf failed. errno %d", i, errno);
+                       goto _START_STREAM_FAILED;
+               }
+
+               buffer = &handle->camera_buffers[i];
+
+               buffer->index = i;
+               buffer->format = pixel_format;
+               buffer->resolution.width = resolution->width;
+               buffer->resolution.height = resolution->height;
+               buffer->total_size = v4l2_buf.length;
+               buffer->num_planes = plane_num;
+               buffer->planes[0].size = v4l2_buf.length;
+               buffer->planes[0].data = mmap(0,
+                       v4l2_buf.length,
+                       PROT_READ | PROT_WRITE,
+                       MAP_SHARED,
+                       handle->device_fd,
+                       v4l2_buf.m.offset);
+
+               if (buffer->planes[0].data == MAP_FAILED) {
+                       LOGE("[%d] mmap failed (errno %d)", i, errno);
+                       goto _START_STREAM_FAILED;
+               }
+
+               if (__camera_v4l2_qbuf(handle->device_fd, handle->buffer_type, V4L2_MEMORY_MMAP, i) != CAMERA_ERROR_NONE) {
+                       LOGE("[%d] qbuf failed (errno %d)", i, errno);
+                       goto _START_STREAM_FAILED;
+               }
+       }
+
+       /* stream on */
+       ret = __camera_v4l2_stream(handle->device_fd, handle->buffer_type, TRUE);
+       if (ret != CAMERA_ERROR_NONE) {
+               LOGE("stream on failed");
+               goto _START_STREAM_FAILED;
+       }
+
+       return CAMERA_ERROR_NONE;
+
+_START_STREAM_FAILED:
+       __camera_stop_stream(handle, handle->buffer_count);
+       return ret;
+}
+
+
+static void __camera_do_capture(hal_camera_handle *handle)
+{
+       int ret = CAMERA_ERROR_NONE;
+       int buffer_index = 0;
+       gint64 current_time = 0;
+       gint64 previous_time = 0;
+       gint64 interval_us = 0;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return;
+       }
+
+       LOGD("start");
+
+       if (handle->capture_count > 1)
+               interval_us = handle->capture_interval_ms * 1000;
+
+       /* restart stream for capture */
+       if (handle->capture_restart_stream) {
+               ret = __camera_stop_stream(handle, handle->buffer_count);
+               if (ret != CAMERA_ERROR_NONE) {
+                       LOGE("stop stream failed for capture[0x%x]", ret);
+                       goto _CAPTURE_DONE;
+               }
+
+               ret = __camera_start_stream(handle,
+                       handle->preview_format.capture_format,
+                       &handle->preview_format.capture_resolution,
+                       handle->preview_format.stream_fps,
+                       BUFFER_MAX);
+               if (ret != CAMERA_ERROR_NONE) {
+                       LOGE("start stream failed for capture[0x%x]", ret);
+                       goto _CAPTURE_DONE;
+               }
+       }
+
+       do {
+               /* get capture buffer */
+               ret = __camera_v4l2_wait_frame(handle->device_fd, 5);
+               if (ret != CAMERA_ERROR_NONE) {
+                       LOGE("frame wait failed for capture[0x%x]", ret);
+                       goto _CAPTURE_DONE;
+               }
+
+               ret = __camera_v4l2_dqbuf(handle->device_fd,
+                       handle->buffer_type, V4L2_MEMORY_MMAP, &buffer_index);
+               if (ret != CAMERA_ERROR_NONE) {
+                       LOGE("dqbuf failed for capture[0x%x]", ret);
+                       goto _CAPTURE_DONE;
+               }
+
+               if (handle->captured_count > 0) {
+                       g_mutex_lock(&handle->buffer_lock);
+                       if (handle->state != CAMERA_STATE_CAPTURING) {
+                               LOGW("stop continuous capture");
+                               handle->captured_count = handle->capture_count;
+                               g_mutex_unlock(&handle->buffer_lock);
+                               goto _TRY_NEXT;
+                       }
+                       g_mutex_unlock(&handle->buffer_lock);
+               }
+
+               if (handle->capture_count > 1) {
+                       current_time = g_get_monotonic_time();
+
+                       LOGI("time[prev:%"PRId64", cur:%"PRId64"] interval[%"PRId64" us]",
+                               previous_time, current_time, interval_us);
+
+                       if (current_time < previous_time + interval_us)
+                               goto _TRY_NEXT;
+               }
+
+               g_mutex_lock(&handle->buffer_lock);
+               handle->captured_count++;
+               g_mutex_unlock(&handle->buffer_lock);
+
+               LOGD("capture cb[%p], buffer index[%d],count[%d]",
+                       handle->capture_cb, buffer_index, handle->captured_count);
+
+               if (handle->capture_cb) {
+                       handle->capture_cb(&handle->camera_buffers[buffer_index],
+                               NULL, NULL, handle->capture_cb_data);
+               } else {
+                       LOGW("capture callback is NULL");
+                       /* Need to post error? */
+               }
+
+               previous_time = current_time;
+
+_TRY_NEXT:
+               ret = __camera_v4l2_qbuf(handle->device_fd,
+                       handle->buffer_type, V4L2_MEMORY_MMAP, buffer_index);
+               if (ret != CAMERA_ERROR_NONE)
+                       LOGE("qbuf failed for capture[0x%x]", ret);
+       } while (handle->captured_count < handle->capture_count);
+
+       g_mutex_lock(&handle->buffer_lock);
+
+       if (handle->state == CAMERA_STATE_CAPTURING) {
+               LOGD("wait for capture stop signal");
+               g_cond_wait(&handle->buffer_cond, &handle->buffer_lock);
+               LOGD("signal received");
+       } else {
+               LOGD("The state is already changed.");
+       }
+
+       g_mutex_unlock(&handle->buffer_lock);
+
+_CAPTURE_DONE:
+       /* restart stream for preview */
+       if (handle->capture_restart_stream) {
+               ret = __camera_stop_stream(handle, handle->buffer_count);
+               if (ret != CAMERA_ERROR_NONE)
+                       LOGE("stop stream failed for preview[0x%x]", ret);
+
+               ret = __camera_start_stream(handle,
+                       handle->preview_format.stream_format,
+                       &handle->preview_format.stream_resolution,
+                       handle->preview_format.stream_fps,
+                       BUFFER_MAX);
+               if (ret != CAMERA_ERROR_NONE)
+                       LOGE("start stream failed for preview[0x%x]", ret);
+       }
+
+       LOGD("done");
+}
+
+
+static void *__camera_buffer_handler_func(gpointer data)
+{
+       int index = 0;
+       hal_camera_handle *handle = (hal_camera_handle *)data;
+
+       if (!handle) {
+               LOGE("NULL handle for buffer handler");
+               return NULL;
+       }
+
+       LOGD("enter");
+
+       /* run buffer thread */
+       g_mutex_lock(&handle->buffer_lock);
+
+       while (handle->buffer_thread_run) {
+               g_mutex_unlock(&handle->buffer_lock);
+
+               if (__camera_v4l2_wait_frame(handle->device_fd, 5) != CAMERA_ERROR_NONE) {
+                       LOGE("frame wait failed");
+                       g_mutex_lock(&handle->buffer_lock);
+                       break;
+               }
+
+               g_mutex_lock(&handle->buffer_lock);
+
+               if (handle->buffer_thread_run == FALSE) {
+                       LOGW("stop buffer handler thread");
+                       break;
+               }
+
+               if (__camera_v4l2_dqbuf(handle->device_fd, handle->buffer_type, V4L2_MEMORY_MMAP, &index) != CAMERA_ERROR_NONE) {
+                       LOGE("dqbuf failed");
+                       break;
+               }
+
+               handle->buffer_dequeued_count++;
+
+               /*LOGD("dequeued buffer count %d", handle->buffer_dequeued_count);*/
+
+               g_mutex_unlock(&handle->buffer_lock);
+
+               if (handle->preview_cb) {
+                       handle->preview_cb(&handle->camera_buffers[index], NULL, handle->preview_cb_data);
+               } else {
+                       LOGW("preview callback is NULL");
+                       camera_v4l2_release_preview_buffer((void *)handle, index);
+               }
+
+               /* check capture request flag */
+               if (handle->capture_request) {
+                       __camera_do_capture(handle);
+                       handle->capture_request = FALSE;
+               }
+
+               sched_yield();
+
+               g_mutex_lock(&handle->buffer_lock);
+       }
+
+       g_mutex_unlock(&handle->buffer_lock);
+
+       LOGD("leave");
+
+       return NULL;
+}
+
+
+static void __camera_message_release_func(gpointer data)
+{
+       camera_message_s *message = (camera_message_s *)data;
+
+       if (!message) {
+               LOGW("NULL message");
+               return;
+       }
+
+       LOGD("release message %p, type %d", message, message->type);
+
+       g_free(message);
+
+       return;
+}
+
+
+static void *_camera_message_handler_func(gpointer data)
+{
+       int i = 0;
+       camera_message_s *message = NULL;
+       hal_camera_handle *handle = (hal_camera_handle *)data;
+
+       if (!handle) {
+               LOGE("NULL handle for capture thread");
+               return NULL;
+       }
+
+       LOGD("enter - message thread");
+
+       g_mutex_lock(&handle->msg_cb_lock);
+
+       while (handle->msg_cb_run) {
+               if (g_queue_is_empty(handle->msg_list)) {
+                       LOGD("wait for message");
+                       g_cond_wait(&handle->msg_cb_cond, &handle->msg_cb_lock);
+                       LOGD("message signal received");
+               }
+
+               if (!handle->msg_cb_run) {
+                       LOGW("break message thread");
+                       break;
+               }
+
+               message = g_queue_pop_head(handle->msg_list);
+               if (!message) {
+                       LOGW("NULL message");
+                       continue;
+               }
+
+               g_mutex_unlock(&handle->msg_cb_lock);
+
+               for (i = 0 ; i < MESSAGE_CALLBACK_MAX ; i++) {
+                       if (handle->msg_cb[i]) {
+                               LOGD("call message callback type %d", message->type);
+                               handle->msg_cb[i](message, handle->msg_cb_data[i]);
+                       }
+               }
+
+               g_free(message);
+               message = NULL;
+
+               g_mutex_lock(&handle->msg_cb_lock);
+       }
+
+       g_mutex_unlock(&handle->msg_cb_lock);
+
+       LOGD("leave - message thread");
+
+       return NULL;
+}
+
+
+static void __camera_release_handle(hal_camera_handle *handle)
+{
+       if (!handle) {
+               LOGW("NULL handle");
+               return;
+       }
+
+       if (handle->msg_thread) {
+               g_mutex_lock(&handle->msg_cb_lock);
+               handle->msg_cb_run = FALSE;
+               g_cond_signal(&handle->msg_cb_cond);
+               g_mutex_unlock(&handle->msg_cb_lock);
+               g_thread_join(handle->msg_thread);
+               g_queue_free_full(handle->msg_list, (GDestroyNotify)__camera_message_release_func);
+               handle->msg_list = NULL;
+       }
+
+       g_mutex_clear(&handle->lock);
+       g_mutex_clear(&handle->buffer_lock);
+       g_mutex_clear(&handle->msg_cb_lock);
+       g_cond_clear(&handle->buffer_cond);
+       g_cond_clear(&handle->msg_cb_cond);
+
+       if (handle->bufmgr) {
+               tbm_bufmgr_deinit(handle->bufmgr);
+               handle->bufmgr = NULL;
+       }
+
+       LOGD("camera HAL handle %p destroy", handle);
+
+       g_free(handle);
+
+       return;
+}
+
+
+int camera_v4l2_init(void **camera_handle)
+{
+       int ret = CAMERA_ERROR_NONE;
+       hal_camera_handle *new_handle = NULL;
+       tbm_bufmgr bufmgr = NULL;
+
+       LOGD("enter");
+
+       if (!camera_handle) {
+               LOGE("NULL pointer for handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       bufmgr = tbm_bufmgr_init(-1);
+       if (bufmgr == NULL) {
+               LOGE("get tbm bufmgr failed");
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       new_handle = g_new0(hal_camera_handle, 1);
+       if (!new_handle) {
+               LOGE("failed to alloc camera hal handle");
+               tbm_bufmgr_deinit(bufmgr);
+               return CAMERA_ERROR_OUT_OF_MEMORY;
+       }
+
+       new_handle->bufmgr = bufmgr;
+
+       g_mutex_init(&new_handle->lock);
+       g_mutex_init(&new_handle->buffer_lock);
+       g_mutex_init(&new_handle->msg_cb_lock);
+       g_cond_init(&new_handle->buffer_cond);
+       g_cond_init(&new_handle->msg_cb_cond);
+
+       /* message thread */
+       new_handle->msg_list = g_queue_new();
+       new_handle->msg_cb_run = TRUE;
+       new_handle->msg_thread = g_thread_try_new("camera_hal_msg_thread",
+               _camera_message_handler_func, (gpointer)new_handle, NULL);
+       if (!new_handle->msg_thread) {
+               LOGE("failed to create message thread");
+               ret = CAMERA_ERROR_INTERNAL;
+               goto _INIT_ERROR;
+       }
+
+       new_handle->device_index = CAMERA_HAL_INITIAL_INDEX;
+       new_handle->device_fd = CAMERA_HAL_INITIAL_FD;
+       new_handle->state = CAMERA_STATE_INITIALIZED;
+
+       ret = __camera_get_device_info_list();
+       if (ret != CAMERA_ERROR_NONE) {
+               LOGE("get device info failed");
+               goto _INIT_ERROR;
+       }
+
+       *camera_handle = new_handle;
+
+       LOGD("camera HAL handle %p", new_handle);
+
+       return CAMERA_ERROR_NONE;
+
+_INIT_ERROR:
+       __camera_release_handle(new_handle);
+
+       return ret;
+}
+
+
+int camera_v4l2_deinit(void *camera_handle)
+{
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_INITIALIZED) {
+               LOGE("invalid state %d, can not destroy handle", handle->state);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_STATE;
+       }
+
+       g_mutex_unlock(&handle->lock);
+
+       __camera_release_handle(handle);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_get_device_info_list(camera_device_info_list_s *device_info_list)
+{
+       int ret = 0;
+
+       if (!device_info_list) {
+               LOGE("NULL pointer for device_info_list");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = __camera_get_device_info_list();
+       if (ret != CAMERA_ERROR_NONE) {
+               LOGE("get device info failed");
+               return ret;
+       }
+
+       memcpy(device_info_list, g_device_info_list, sizeof(camera_device_info_list_s));
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_open_device(void *camera_handle, int device_index)
+{
+       int ret = CAMERA_ERROR_NONE;
+       int device_fd = CAMERA_HAL_INITIAL_FD;
+       char *node_path = NULL;
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_INITIALIZED) {
+               LOGE("invalid state %d", handle->state);
+               ret = CAMERA_ERROR_INVALID_STATE;
+               goto _OPEN_DEVICE_DONE;
+       }
+
+       if (!g_device_info_list) {
+               LOGE("NO DEVICE INFO");
+               ret = CAMERA_ERROR_INTERNAL;
+               goto _OPEN_DEVICE_DONE;
+       }
+
+       if (device_index >= g_device_info_list->count) {
+               LOGE("invalid index %d [info:%d]", device_index, g_device_info_list->count);
+               ret = CAMERA_ERROR_INVALID_PARAMETER;
+               goto _OPEN_DEVICE_DONE;
+       }
+
+       node_path = g_device_info_list->device_info[device_index].node_path;
+
+       device_fd = open(node_path, O_RDWR);
+       if (device_fd < 0) {
+               switch (errno) {
+                       case EACCES:
+                       case EPERM:
+                               ret = CAMERA_ERROR_PERMISSION_DENIED;
+                               break;
+                       case ENOENT:
+                               ret = CAMERA_ERROR_DEVICE_NOT_FOUND;
+                               break;
+                       case EBUSY:
+                               ret = CAMERA_ERROR_DEVICE_BUSY;
+                               break;
+                       default:
+                               ret = CAMERA_ERROR_DEVICE_OPEN;
+                               break;
+               }
+
+               LOGE("open [%s] failed 0x%x [errno %d]",
+                       node_path, ret, errno);
+
+               goto _OPEN_DEVICE_DONE;
+       }
+
+       if (g_device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
+               handle->buffer_type = V4L2_CAP_VIDEO_CAPTURE_MPLANE;
+       else
+               handle->buffer_type = V4L2_CAP_VIDEO_CAPTURE;
+
+       handle->state = CAMERA_STATE_OPENED;
+       handle->device_index = device_index;
+       handle->device_fd = device_fd;
+
+       LOGD("[%d] device[%s] opened [fd %d, type %d]",
+               device_index, node_path, device_fd, handle->buffer_type);
+
+_OPEN_DEVICE_DONE:
+       g_mutex_unlock(&handle->lock);
+
+       return ret;
+}
+
+
+int camera_v4l2_open_device_ext(void *camera_handle, const char *device_name)
+{
+       LOGE("NOT SUPPORTED");
+       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+}
+
+
+int camera_v4l2_close_device(void *camera_handle)
+{
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_OPENED) {
+               LOGE("invalid state %d", handle->state);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_STATE;
+       }
+
+       if (handle->device_fd >= 0) {
+               LOGD("close fd %d", handle->device_fd);
+
+               close(handle->device_fd);
+               handle->device_fd = CAMERA_HAL_INITIAL_FD;
+       } else {
+               LOGW("invalid fd %d", handle->device_fd);
+       }
+
+       handle->state = CAMERA_STATE_INITIALIZED;
+
+       LOGD("device [%d] closed", handle->device_index);
+
+       g_mutex_unlock(&handle->lock);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_add_message_callback(void *camera_handle, hal_camera_message_cb callback, void *user_data, uint32_t *cb_id)
+{
+       uint32_t i = 0;
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!callback || !cb_id) {
+               LOGE("NULL pointer for callback %p or cb_id %p", callback, cb_id);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_OPENED) {
+               LOGE("invalid state %d", handle->state);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_STATE;
+       }
+
+       for (i = 0 ; i < MESSAGE_CALLBACK_MAX ; i++) {
+               if (handle->msg_cb[i] == NULL) {
+                       handle->msg_cb[i] = callback;
+                       handle->msg_cb_data[i] = user_data;
+                       *cb_id = i;
+                       LOGD("message cb [%p] added, user data %p - id %u", callback, user_data, i);
+                       g_mutex_unlock(&handle->lock);
+                       return CAMERA_ERROR_NONE;
+               }
+       }
+
+       g_mutex_unlock(&handle->lock);
+
+       LOGE("no available message cb slot");
+
+       return CAMERA_ERROR_INTERNAL;
+}
+
+
+int camera_v4l2_remove_message_callback(void *camera_handle, uint32_t cb_id)
+{
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       if (cb_id >= MESSAGE_CALLBACK_MAX) {
+               LOGE("invalid cb_id %u", cb_id);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_OPENED) {
+               LOGE("invalid state %d", handle->state);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_STATE;
+       }
+
+       if (handle->msg_cb[cb_id]) {
+               LOGD("remove message callback %p, user data %p - cb_id %u",
+                       handle->msg_cb[cb_id], handle->msg_cb_data[cb_id], cb_id);
+
+               handle->msg_cb[cb_id] = NULL;
+               handle->msg_cb_data[cb_id] = NULL;
+       } else {
+               LOGE("already removed message cb");
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       g_mutex_unlock(&handle->lock);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_set_preview_stream_format(void *camera_handle, camera_format_s *format)
+{
+       int i = 0;
+       int j = 0;
+       int ret = CAMERA_ERROR_NONE;
+       gboolean capability_check = FALSE;
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+       camera_device_info_s *device_info = NULL;
+
+       if (!handle || !format) {
+               LOGE("NULL param %p %p", handle, format);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!g_device_info_list) {
+               LOGE("no device info list");
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_OPENED &&
+               handle->state != CAMERA_STATE_PREVIEWING) {
+               LOGE("invalid state %d", handle->state);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_STATE;
+       }
+
+       /* check capability */
+       device_info = &g_device_info_list->device_info[handle->device_index];
+
+       /* format */
+       for (i = 0 ; i < device_info->format_list.count ; i++) {
+               if (format->stream_format == device_info->format_list.formats[i]) {
+                       LOGD("format matched %d, check resolution.", format->stream_format);
+
+                       /* resolution */
+                       for (j = 0 ; j < device_info->preview_list.count ; j++) {
+                               if (format->stream_resolution.width == device_info->preview_list.resolutions[j].width &&
+                                       format->stream_resolution.height == device_info->preview_list.resolutions[j].height) {
+                                       LOGD("resolution matched %dx%d",
+                                               format->stream_resolution.width,
+                                               format->stream_resolution.height);
+                                       capability_check = TRUE;
+                                       break;
+                               }
+                       }
+
+                       break;
+               }
+       }
+
+       if (!capability_check) {
+               LOGE("capability failed - %d, %dx%d",
+                       format->stream_format,
+                       format->stream_resolution.width,
+                       format->stream_resolution.height);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       /* compare with current settings */
+       if (handle->state == CAMERA_STATE_PREVIEWING) {
+               if (handle->preview_format.stream_format == format->stream_format &&
+                       handle->preview_format.stream_resolution.width == format->stream_resolution.width &&
+                       handle->preview_format.stream_resolution.height == format->stream_resolution.height &&
+                       handle->preview_format.stream_fps == format->stream_fps &&
+                       handle->preview_format.stream_rotation == format->stream_rotation) {
+                       LOGD("no need to restart preview stream");
+                       goto _SET_PREVIEW_STREAM_FORMAT_DONE;
+               }
+
+               LOGD("Preview setting is changed. Restart preview now.");
+
+               /* stop preview stream to change it */
+               ret = __camera_stop_stream(handle, handle->buffer_count);
+               if (ret != CAMERA_ERROR_NONE) {
+                       LOGE("failed to stop stream");
+                       g_mutex_unlock(&handle->lock);
+                       return ret;
+               }
+
+               /* restart preview stream to change it */
+               ret = __camera_start_stream(handle,
+                       format->stream_format,
+                       &format->stream_resolution,
+                       format->stream_fps,
+                       BUFFER_MAX);
+               if (ret != CAMERA_ERROR_NONE) {
+                       LOGE("failed to start stream");
+                       g_mutex_unlock(&handle->lock);
+                       return ret;
+               }
+       }
+
+_SET_PREVIEW_STREAM_FORMAT_DONE:
+       /* set capture restart flag */
+       if (format->stream_format == format->capture_format &&
+               format->stream_resolution.width == format->capture_resolution.width &&
+               format->stream_resolution.height == format->capture_resolution.height)
+               handle->capture_restart_stream = FALSE;
+       else
+               handle->capture_restart_stream = TRUE;
+
+       memcpy(&handle->preview_format, format, sizeof(camera_format_s));
+
+       LOGD("set format PREVIEW[%d:%dx%d,fps:%d], CAPTURE[%d:%dx%d,restart:%d]",
+               format->stream_format,
+               format->stream_resolution.width,
+               format->stream_resolution.height,
+               format->stream_fps,
+               format->capture_format,
+               format->capture_resolution.width,
+               format->capture_resolution.height,
+               handle->capture_restart_stream);
+
+       g_mutex_unlock(&handle->lock);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_get_preview_stream_format(void *camera_handle, camera_format_s *format)
+{
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle || !format) {
+               LOGE("NULL param %p %p", handle, format);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       memcpy(format, &handle->preview_format, sizeof(camera_format_s));
+
+       LOGD("get stream format %d, %dx%d", format->stream_format,
+               format->stream_resolution.width, format->stream_resolution.height);
+
+       g_mutex_unlock(&handle->lock);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_set_user_buffer_fd(void *camera_handle, int *fds, int number)
+{
+       LOGE("NOT SUPPORTED");
+       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+}
+
+
+int camera_v4l2_start_preview(void *camera_handle, hal_camera_preview_frame_cb callback, void *user_data)
+{
+       int ret = 0;
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle || !callback) {
+               LOGE("NULL param %p %p", handle, callback);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_OPENED) {
+               LOGE("invalid state %d", handle->state);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_STATE;
+       }
+
+       ret = __camera_start_stream(handle,
+               handle->preview_format.stream_format,
+               &handle->preview_format.stream_resolution,
+               handle->preview_format.stream_fps,
+               BUFFER_MAX);
+       if (ret != CAMERA_ERROR_NONE) {
+               LOGE("__camera_start_stream failed[0x%x]", ret);
+               g_mutex_unlock(&handle->lock);
+               return ret;
+       }
+
+       g_mutex_lock(&handle->buffer_lock);
+
+       handle->buffer_thread_run = TRUE;
+
+       handle->buffer_thread = g_thread_try_new("camera_hal_buffer_thread",
+               __camera_buffer_handler_func, (gpointer)handle, NULL);
+       if (!handle->buffer_thread) {
+               LOGE("failed to create buffer handler thread");
+               g_mutex_unlock(&handle->buffer_lock);
+
+               __camera_stop_stream(handle, handle->buffer_count);
+
+               g_mutex_unlock(&handle->lock);
+
+               return ret;
+       }
+
+       handle->preview_cb = callback;
+       handle->preview_cb_data = user_data;
+
+       g_mutex_unlock(&handle->buffer_lock);
+
+       handle->state = CAMERA_STATE_PREVIEWING;
+
+       LOGD("start preview done");
+
+       g_mutex_unlock(&handle->lock);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_release_preview_buffer(void *camera_handle, int buffer_index)
+{
+       int ret = CAMERA_ERROR_NONE;
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       if (buffer_index >= handle->buffer_count) {
+               LOGE("invalid buffer index %d", buffer_index);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = __camera_v4l2_qbuf(handle->device_fd,
+               handle->buffer_type, V4L2_MEMORY_MMAP, buffer_index);
+
+       g_mutex_lock(&handle->buffer_lock);
+
+       if (ret == CAMERA_ERROR_NONE) {
+               if (handle->buffer_dequeued_count > 0)
+                       handle->buffer_dequeued_count--;
+               else
+                       LOGW("invalid dequeued buffer count[%u]", handle->buffer_dequeued_count);
+
+               /*LOGD("qbud done : index %d, dequeued buffer count %d",
+                       buffer_index, handle->buffer_dequeued_count);*/
+       } else {
+               LOGE("qbuf failed [index %d]", buffer_index);
+       }
+
+       g_cond_signal(&handle->buffer_cond);
+
+       g_mutex_unlock(&handle->buffer_lock);
+
+       return ret;
+}
+
+
+int camera_v4l2_stop_preview(void *camera_handle)
+{
+       int ret = CAMERA_ERROR_NONE;
+       gint64 end_time;
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGD("start");
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_PREVIEWING) {
+               LOGE("invalid state %d", handle->state);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_STATE;
+       }
+
+       g_mutex_lock(&handle->buffer_lock);
+
+       handle->buffer_thread_run = FALSE;
+
+       while (handle->buffer_dequeued_count > 0) {
+               LOGD("wait for dequeued buffer [%d]", handle->buffer_dequeued_count);
+               end_time = g_get_monotonic_time() + 3 * G_TIME_SPAN_SECOND;
+               if (!g_cond_wait_until(&handle->buffer_cond, &handle->buffer_lock, end_time)) {
+                       LOGE("buffer wait failed");
+                       break;
+               } else {
+                       LOGD("signal received. check again...");
+               }
+       }
+
+       g_mutex_unlock(&handle->buffer_lock);
+
+       ret = __camera_stop_stream(handle, handle->buffer_count);
+
+       /* wait for preview thread exit */
+       g_thread_join(handle->buffer_thread);
+       handle->buffer_thread = NULL;
+
+       handle->state = CAMERA_STATE_OPENED;
+
+       LOGD("stop preview done [0x%x]", ret);
+
+       g_mutex_unlock(&handle->lock);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_start_auto_focus(void *camera_handle)
+{
+       if (!camera_handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGE("NOT SUPPORTED");
+
+       /* auto focus is not supported */
+       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+}
+
+
+int camera_v4l2_stop_auto_focus(void *camera_handle)
+{
+       if (!camera_handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGE("NOT SUPPORTED");
+
+       /* auto focus is not supported */
+       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+}
+
+
+int camera_v4l2_start_capture(void *camera_handle, hal_camera_capture_cb callback, void *user_data)
+{
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle || !callback) {
+               LOGE("NULL param %p %p", camera_handle, callback);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_PREVIEWING) {
+               LOGE("invalid state %d", handle->state);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_STATE;
+       }
+
+       /* set callback and user data */
+       handle->capture_cb = callback;
+       handle->capture_cb_data = user_data;
+
+       /* reset captured count */
+       handle->captured_count = 0;
+
+       LOGD("start capture - count %u", handle->capture_count);
+
+       /* set capture request flag */
+       handle->capture_request = TRUE;
+
+       handle->state = CAMERA_STATE_CAPTURING;
+
+       g_mutex_unlock(&handle->lock);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_stop_capture(void *camera_handle)
+{
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state != CAMERA_STATE_CAPTURING) {
+               LOGE("invalid state %d", handle->state);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INVALID_STATE;
+       }
+
+       g_mutex_lock(&handle->buffer_lock);
+
+       if (handle->captured_count == 0) {
+               LOGE("No captured image yet.");
+               g_mutex_unlock(&handle->buffer_lock);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_INTERNAL;
+       }
+
+       LOGD("send signal to start preview after capture");
+
+       g_cond_signal(&handle->buffer_cond);
+       g_mutex_unlock(&handle->buffer_lock);
+
+       handle->state = CAMERA_STATE_PREVIEWING;
+
+       g_mutex_unlock(&handle->lock);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+int camera_v4l2_set_video_stream_format(void *camera_handle, camera_format_s *format)
+{
+       if (!camera_handle || !format) {
+               LOGE("NULL param %p %p", camera_handle, format);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGE("NOT SUPPORTED");
+
+       /* single stream device can not support video stream */
+       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+}
+
+
+int camera_v4l2_get_video_stream_format(void *camera_handle, camera_format_s *format)
+{
+       if (!camera_handle || !format) {
+               LOGE("NULL param %p %p", camera_handle, format);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGE("NOT SUPPORTED");
+
+       /* single stream device can not support video stream */
+       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+}
+
+
+int camera_v4l2_start_record(void *camera_handle, hal_camera_video_frame_cb callback, void *user_data)
+{
+       if (!camera_handle || !callback) {
+               LOGE("NULL param %p %p", camera_handle, callback);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGE("NOT SUPPORTED");
+
+       /* single stream device can not support video stream */
+       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+}
+
+
+int camera_v4l2_release_video_buffer(void *camera_handle, int buffer_index)
+{
+       if (!camera_handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGE("NOT SUPPORTED");
+
+       /* single stream device can not support video stream */
+       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+}
+
+
+int camera_v4l2_stop_record(void *camera_handle)
+{
+       if (!camera_handle) {
+               LOGE("NULL handle");
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       LOGE("NOT SUPPORTED");
+
+       /* single stream device can not support video stream */
+       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+}
+
+
+int camera_v4l2_set_command(void *camera_handle, int64_t command, void *value)
+{
+       int ret = CAMERA_ERROR_NONE;
+       int cid = 0;
+       int ctrl_ret = 0;
+       int set_value = 0;
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle || !value) {
+               LOGE("NULL param %p %p", handle, value);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       set_value = *(int *)value;
+
+       g_mutex_lock(&handle->lock);
+
+       if (handle->state < CAMERA_STATE_OPENED) {
+               LOGE("invalid state %d", handle->state);
+               ret = CAMERA_ERROR_INVALID_STATE;
+               goto _SET_COMMAND_DONE;
+       }
+
+       LOGD("set command %"PRIx64" - state %d", command, handle->state);
+
+       switch (command) {
+       case CAMERA_COMMAND_BRIGHTNESS:
+               cid = V4L2_CID_BRIGHTNESS;
+               break;
+       case CAMERA_COMMAND_CONTRAST:
+               cid = V4L2_CID_CONTRAST;
+               break;
+       case CAMERA_COMMAND_SATURATION:
+               cid = V4L2_CID_SATURATION;
+               break;
+       case CAMERA_COMMAND_SHARPNESS:
+               cid = V4L2_CID_SHARPNESS;
+               break;
+       case CAMERA_COMMAND_PTZ_TYPE:
+               if (set_value != CAMERA_PTZ_TYPE_ELECTRONIC) {
+                       LOGE("not supported PTZ type %d", set_value);
+                       ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+               }
+               goto _SET_COMMAND_DONE;
+       case CAMERA_COMMAND_PAN:
+               cid = V4L2_CID_PAN_ABSOLUTE;
+               break;
+       case CAMERA_COMMAND_TILT:
+               cid = V4L2_CID_TILT_ABSOLUTE;
+               break;
+       case CAMERA_COMMAND_FLIP:
+               if (set_value != CAMERA_FLIP_NONE) {
+                       LOGE("NOT_SUPPORTED flip %d", set_value);
+                       ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+               }
+               goto _SET_COMMAND_DONE;
+       case CAMERA_COMMAND_CAPTURE_COUNT:
+               handle->capture_count = set_value;
+               LOGI("capture count %u", handle->capture_count);
+               goto _SET_COMMAND_DONE;
+       case CAMERA_COMMAND_CAPTURE_INTERVAL:
+               handle->capture_interval_ms = set_value;
+               LOGI("capture interval %u ms", handle->capture_interval_ms);
+               goto _SET_COMMAND_DONE;
+       default:
+               LOGE("NOT_SUPPORTED command %"PRIx64, command);
+               ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+               goto _SET_COMMAND_DONE;
+       }
+
+       ctrl_ret = __camera_v4l2_s_ctrl(handle->device_fd, cid, set_value);
+       if (ctrl_ret < 0) {
+               switch (errno) {
+               case EACCES:
+               case EPERM:
+                       LOGE("Permission denied %d", errno);
+                       ret = CAMERA_ERROR_PERMISSION_DENIED;
+                       break;
+               case EINVAL:
+                       LOGE("Invalid argument");
+                       ret = CAMERA_ERROR_INVALID_PARAMETER;
+                       break;
+               case EBUSY:
+                       LOGE("Device busy");
+                       ret = CAMERA_ERROR_DEVICE_BUSY;
+                       break;
+               case ENOTSUP:
+                       LOGE("Not supported");
+                       ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+                       break;
+               default:
+                       LOGE("Unknown errro %d", errno);
+                       ret = CAMERA_ERROR_INTERNAL;
+                       break;
+               }
+       }
+
+_SET_COMMAND_DONE:
+       g_mutex_unlock(&handle->lock);
+
+       return ret;
+}
+
+
+int camera_v4l2_get_command(void *camera_handle, int64_t command, void **value)
+{
+       int ret = CAMERA_ERROR_NONE;
+       int cid = 0;
+       int ctrl_ret = 0;
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle || !value) {
+               LOGE("NULL param %p %p", handle, value);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       LOGD("get command %"PRId64" - state %d", command, handle->state);
+
+       switch (command) {
+       case CAMERA_COMMAND_BRIGHTNESS:
+               cid = V4L2_CID_BRIGHTNESS;
+               break;
+       case CAMERA_COMMAND_CONTRAST:
+               cid = V4L2_CID_CONTRAST;
+               break;
+       case CAMERA_COMMAND_SATURATION:
+               cid = V4L2_CID_SATURATION;
+               break;
+       case CAMERA_COMMAND_SHARPNESS:
+               cid = V4L2_CID_SHARPNESS;
+               break;
+       default:
+               LOGE("NOT_SUPPORTED %"PRId64, command);
+               g_mutex_unlock(&handle->lock);
+               return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+       }
+
+       ctrl_ret = __camera_v4l2_g_ctrl(handle->device_fd, cid, (int *)value);
+       if (ctrl_ret < 0) {
+               switch (errno) {
+               case EACCES:
+               case EPERM:
+                       LOGE("Permission denied %d", errno);
+                       ret = CAMERA_ERROR_PERMISSION_DENIED;
+                       break;
+               case EINVAL:
+                       LOGE("Invalid argument");
+                       ret = CAMERA_ERROR_INVALID_PARAMETER;
+                       break;
+               case EBUSY:
+                       LOGE("Device busy");
+                       ret = CAMERA_ERROR_DEVICE_BUSY;
+                       break;
+               case ENOTSUP:
+                       LOGE("Not supported");
+                       ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
+                       break;
+               default:
+                       LOGE("Unknown errro %d", errno);
+                       ret = CAMERA_ERROR_INTERNAL;
+                       break;
+               }
+       }
+
+       g_mutex_unlock(&handle->lock);
+
+       return ret;
+}
+
+
+int camera_v4l2_set_batch_command(void *camera_handle, camera_batch_command_control_s *batch_command, int64_t *error_command)
+{
+       hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
+
+       if (!handle || !batch_command) {
+               LOGE("NULL param %p %p", handle, batch_command);
+               return CAMERA_ERROR_INVALID_PARAMETER;
+       }
+
+       g_mutex_lock(&handle->lock);
+
+       LOGD("set batch command - flag %"PRIx64", state %d",
+               batch_command->command_set_flag, handle->state);
+
+       /* TODO: to be implemented */
+
+       g_mutex_unlock(&handle->lock);
+
+       return CAMERA_ERROR_NONE;
+}
+
+
+static int camera_v4l2_backend_init(void **data)
+{
+       hal_backend_camera_funcs *funcs;
+
+       funcs = calloc(1, sizeof(hal_backend_camera_funcs));
+       if (!funcs)
+               return CAMERA_ERROR_OUT_OF_MEMORY;
+
+       funcs->init = camera_v4l2_init;
+       funcs->deinit = camera_v4l2_deinit;
+       funcs->get_device_info_list = camera_v4l2_get_device_info_list;
+       funcs->open_device = camera_v4l2_open_device;
+       funcs->open_device_ext = camera_v4l2_open_device_ext;
+       funcs->close_device = camera_v4l2_close_device;
+       funcs->add_message_callback = camera_v4l2_add_message_callback;
+       funcs->remove_message_callback = camera_v4l2_remove_message_callback;
+       funcs->set_preview_stream_format = camera_v4l2_set_preview_stream_format;
+       funcs->get_preview_stream_format = camera_v4l2_get_preview_stream_format;
+       funcs->set_user_buffer_fd = camera_v4l2_set_user_buffer_fd;
+       funcs->start_preview = camera_v4l2_start_preview;
+       funcs->release_preview_buffer = camera_v4l2_release_preview_buffer;
+       funcs->stop_preview = camera_v4l2_stop_preview;
+       funcs->start_auto_focus = camera_v4l2_start_auto_focus;
+       funcs->stop_auto_focus = camera_v4l2_stop_auto_focus;
+       funcs->start_capture = camera_v4l2_start_capture;
+       funcs->stop_capture = camera_v4l2_stop_capture;
+       funcs->set_video_stream_format = camera_v4l2_set_video_stream_format;
+       funcs->get_video_stream_format = camera_v4l2_get_video_stream_format;
+       funcs->start_record = camera_v4l2_start_record;
+       funcs->release_video_buffer = camera_v4l2_release_video_buffer;
+       funcs->stop_record = camera_v4l2_stop_record;
+       funcs->set_command = camera_v4l2_set_command;
+       funcs->get_command = camera_v4l2_get_command;
+       funcs->set_batch_command = camera_v4l2_set_batch_command;
+
+       *data = (void *)funcs;
+
+       return 0;
+}
+
+
+static int camera_v4l2_backend_exit(void *data)
+{
+       if (!data)
+               return 0;
+
+       free(data);
+
+       return 0;
+}
+
+
+hal_backend hal_backend_camera_data = {
+       .name = "camera-v4l2",
+       .vendor = "TIZEN",
+       .abi_version = HAL_ABI_VERSION_TIZEN_6_5,
+       .init = camera_v4l2_backend_init,
+       .exit = camera_v4l2_backend_exit,
+};
diff --git a/src/hal_camera_v4l2_private.h b/src/hal_camera_v4l2_private.h
new file mode 100644 (file)
index 0000000..b6eb18a
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * hal_camera_v4l2_private.h
+ *
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __HAL_CAMERA_V4L2_PRIVATE_H__
+#define __HAL_CAMERA_V4L2_PRIVATE_H__
+
+#include <linux/videodev2.h>
+#include <glib.h>
+#include <tbm_bufmgr.h>
+#include <hal/hal-common-interface.h>
+#include <hal/hal-camera-interface.h>
+
+#define CAMERA_HAL_INITIAL_INDEX    -1
+#define CAMERA_HAL_INITIAL_FD       -1
+#define MESSAGE_CALLBACK_MAX        10
+#define BUFFER_MAX                  4
+#define V4L2_PLANES_MAX             4
+
+typedef struct _camera_hal_handle {
+       /* tbm */
+       tbm_bufmgr bufmgr;
+
+       /* device */
+       gint32 device_index;
+       gint32 device_fd;
+
+       /* buffer */
+       guint32 buffer_dequeued_count;
+       GThread *buffer_thread;
+       gboolean buffer_thread_run;
+       guint32 buffer_count;
+       camera_buffer_s camera_buffers[BUFFER_MAX];
+       enum v4l2_buf_type buffer_type;
+       GMutex buffer_lock;
+       GCond buffer_cond;
+
+       /* preview */
+       camera_format_s preview_format;
+       hal_camera_preview_frame_cb preview_cb;
+       gpointer preview_cb_data;
+
+       /* capture */
+       hal_camera_capture_cb capture_cb;
+       gpointer capture_cb_data;
+       guint32 capture_count;
+       guint32 capture_interval_ms;
+       guint32 captured_count;
+       gboolean capture_request;
+       gboolean capture_restart_stream;
+
+       /* message */
+       GThread *msg_thread;
+       hal_camera_message_cb msg_cb[MESSAGE_CALLBACK_MAX];
+       gpointer msg_cb_data[MESSAGE_CALLBACK_MAX];
+       gboolean msg_cb_run;
+       GQueue *msg_list;
+       GMutex msg_cb_lock;
+       GCond msg_cb_cond;
+
+       /* etc */
+       GMutex lock;
+       camera_state_e state;
+} hal_camera_handle;
+
+int camera_v4l2_init(void **camera_handle);
+int camera_v4l2_deinit(void *camera_handle);
+int camera_v4l2_get_device_info_list(camera_device_info_list_s *device_info_list);
+int camera_v4l2_open_device(void *camera_handle, int device_index);
+int camera_v4l2_open_device_ext(void *camera_handle, const char *device_name);
+int camera_v4l2_close_device(void *camera_handle);
+int camera_v4l2_add_message_callback(void *camera_handle, hal_camera_message_cb callback, void *user_data, uint32_t *cb_id);
+int camera_v4l2_remove_message_callback(void *camera_handle, uint32_t cb_id);
+int camera_v4l2_set_preview_stream_format(void *camera_handle, camera_format_s *format);
+int camera_v4l2_get_preview_stream_format(void *camera_handle, camera_format_s *format);
+int camera_v4l2_set_user_buffer_fd(void *camera_handle, int *fds, int number);
+int camera_v4l2_start_preview(void *camera_handle, hal_camera_preview_frame_cb callback, void *user_data);
+int camera_v4l2_release_preview_buffer(void *camera_handle, int buffer_index);
+int camera_v4l2_stop_preview(void *camera_handle);
+int camera_v4l2_start_auto_focus(void *camera_handle);
+int camera_v4l2_stop_auto_focus(void *camera_handle);
+int camera_v4l2_start_capture(void *camera_handle, hal_camera_capture_cb callback, void *user_data);
+int camera_v4l2_stop_capture(void *camera_handle);
+int camera_v4l2_set_video_stream_format(void *camera_handle, camera_format_s *format);
+int camera_v4l2_get_video_stream_format(void *camera_handle, camera_format_s *format);
+int camera_v4l2_start_record(void *camera_handle, hal_camera_video_frame_cb callback, void *user_data);
+int camera_v4l2_release_video_buffer(void *camera_handle, int buffer_index);
+int camera_v4l2_stop_record(void *camera_handle);
+int camera_v4l2_set_command(void *camera_handle, int64_t command, void *value);
+int camera_v4l2_get_command(void *camera_handle, int64_t command, void **value);
+int camera_v4l2_set_batch_command(void *camera_handle, camera_batch_command_control_s *batch_command, int64_t *error_command);
+
+#endif /* __HAL_CAMERA_V4L2_PRIVATE_H__ */
diff --git a/src/tizen_camera_v4l2.c b/src/tizen_camera_v4l2.c
deleted file mode 100644 (file)
index 11c1b32..0000000
+++ /dev/null
@@ -1,2032 +0,0 @@
-/*
- * tizen_camera_v4l2.c
- *
- * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <glob.h>
-#include <dlog.h>
-#include <sched.h>
-#include "tizen_camera_v4l2_private.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif /* LOG_TAG */
-#define LOG_TAG "CAMERA_HAL"
-
-#define TEST_JPEG_PATH          "/home/owner/media/Images/test.jpg"
-#define DEVICE_NODE_PATH_MAX    16
-#define DEVICE_NODE_PATH_PREFIX "/dev/video"
-#define FOURCC_FORMAT           "%c%c%c%c"
-#define FOURCC_CONVERT(fourcc)  \
-       fourcc & 0xff,\
-       (fourcc >> 8) & 0xff,\
-       (fourcc >> 16) & 0xff,\
-       (fourcc >> 24) & 0xff
-
-
-static camera_device_info_list_t *g_device_info_list;
-static guint32 g_device_caps;
-static GMutex g_device_info_lock;
-
-
-static void __camera_hal_v4l2_destructor(void) __attribute__((destructor));
-
-static void __camera_hal_v4l2_destructor(void)
-{
-       LOGD("release device info list %p", g_device_info_list);
-
-       g_free(g_device_info_list);
-       g_device_info_list = NULL;
-
-       return;
-}
-
-static int __camera_v4l2_wait_frame(int device_fd, int wait_time)
-{
-       int ret = CAMERA_ERROR_NONE;
-       fd_set fds;
-       struct timeval timeout;
-
-       if (device_fd < 0) {
-               LOGE("invalid fd %d", device_fd);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       FD_ZERO(&fds);
-       FD_SET(device_fd, &fds);
-
-       memset(&timeout, 0x0, sizeof(struct timeval));
-
-       timeout.tv_sec = wait_time;
-       timeout.tv_usec = 0;
-
-       /*LOGD("select : %d sec", wait_time);*/
-
-       ret = select(device_fd + 1, &fds, NULL, NULL, &timeout);
-       if (ret == -1) {
-               if (EINTR == errno) {
-                       LOGD("select error : EINTR");
-                       return CAMERA_ERROR_NONE;
-               }
-               LOGE("select failed. errno %d", errno);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       if (ret == 0) {
-               LOGE("select timeout.");
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       /*LOGD("select done");*/
-
-       return CAMERA_ERROR_NONE;
-}
-
-
-static int __camera_v4l2_g_ctrl(int device_fd, int cid, int *value)
-{
-       int ret = 0;
-       struct v4l2_control ctrl;
-
-       if (!value) {
-               LOGE("NULL param");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       memset(&ctrl, 0x0, sizeof(struct v4l2_control));
-
-       ctrl.id = cid;
-
-       ret = ioctl(device_fd, VIDIOC_G_CTRL, &ctrl);
-
-       *value = ctrl.value;
-
-       LOGD("G_CTRL id 0x%x, value %d, ret %d", cid, *value, ret);
-
-       return ret;
-}
-
-
-static int __camera_v4l2_s_ctrl(int device_fd, int cid, int value)
-{
-       int ret = 0;
-       struct v4l2_control ctrl;
-
-       memset(&ctrl, 0x0, sizeof(struct v4l2_control));
-
-       ctrl.id = cid;
-       ctrl.value = value;
-
-       ret = ioctl(device_fd, VIDIOC_S_CTRL, &ctrl);
-
-       LOGD("S_CTRL id 0x%x, value %d, ret %d", cid, value, ret);
-
-       return ret;
-}
-
-
-static int __camera_v4l2_stream(int device_fd, int type, gboolean onoff)
-{
-       if (device_fd < 0) {
-               LOGE("invalid fd %d", device_fd);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       if (ioctl(device_fd, onoff ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type) < 0) {
-               LOGE("stream %d failed. [t:%d] errno %d", onoff, type, errno);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       LOGD("stream %d done [t:%d]", onoff, type);
-
-       return CAMERA_ERROR_NONE;
-}
-
-
-static int __camera_v4l2_reqbufs(int device_fd, int type, int memory, uint32_t count, uint32_t *result_count)
-{
-       struct v4l2_requestbuffers v4l2_reqbuf;
-
-       if (device_fd < 0) {
-               LOGE("invalid fd %d", device_fd);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       if (!result_count) {
-               LOGE("NULL parameter");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       memset(&v4l2_reqbuf, 0x0, sizeof(struct v4l2_requestbuffers));
-
-       v4l2_reqbuf.type = type;
-       v4l2_reqbuf.memory = memory;
-       v4l2_reqbuf.count = count;
-
-       if (ioctl(device_fd, VIDIOC_REQBUFS, &v4l2_reqbuf) < 0) {
-               LOGE("REQBUFS[count %d] failed. errno %d", count, errno);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       if (v4l2_reqbuf.count != count)
-               LOGW("different count [req:%d, result:%d]", count, v4l2_reqbuf.count);
-
-       *result_count = v4l2_reqbuf.count;
-
-       return CAMERA_ERROR_NONE;
-}
-
-
-static int __camera_v4l2_qbuf(int device_fd, int type, int memory, int index)
-{
-       struct v4l2_buffer v4l2_buf;
-       struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];
-
-       if (device_fd < 0) {
-               LOGE("invalid fd %d", device_fd);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
-       memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
-
-       v4l2_buf.index = index;
-       v4l2_buf.type = type;
-       v4l2_buf.memory = memory;
-       v4l2_buf.m.planes = v4l2_planes;
-       v4l2_buf.length = 460800;
-       v4l2_buf.bytesused = 460800;
-
-       if (ioctl(device_fd, VIDIOC_QBUF, &v4l2_buf) < 0) {
-               LOGE("qbuf failed.  [i: %d, t: %d, m: %d] errno %d",
-                       index, type, memory, errno);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       /*LOGD("QBUF done [i: %d, t: %d, m: %d]", index, type, memory);*/
-
-       return CAMERA_ERROR_NONE;
-}
-
-
-static int __camera_v4l2_dqbuf(int device_fd, int type, int memory, int *index)
-{
-       int ret = CAMERA_ERROR_NONE;
-       struct v4l2_buffer v4l2_buf;
-       struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];
-
-       if (device_fd < 0) {
-               LOGE("invalid fd %d", device_fd);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       if (!index) {
-               LOGE("NULL parameter");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
-       memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
-
-       v4l2_buf.type = type;
-       v4l2_buf.memory = memory;
-       v4l2_buf.m.planes = v4l2_planes;
-
-       ret = ioctl(device_fd, VIDIOC_DQBUF, &v4l2_buf);
-       if (ret < 0) {
-               if (errno != EIO) {
-                       LOGE("dqbuf failed. [t: %d, m: %d] errno %d",
-                               type, memory, errno);
-                       return CAMERA_ERROR_DEVICE_READ;
-               }
-       }
-
-       *index = v4l2_buf.index;
-
-       /*LOGD("dqbuf index %d", *index);*/
-
-       return CAMERA_ERROR_NONE;
-}
-
-
-static int __camera_get_format(guint32 fourcc, int *pixel_format)
-{
-       if (!pixel_format) {
-               LOGE("NULL parameter");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       switch (fourcc) {
-       case V4L2_PIX_FMT_NV12:
-       case V4L2_PIX_FMT_NV12M:
-       case V4L2_PIX_FMT_NV12MT:
-               *pixel_format = CAMERA_PIXEL_FORMAT_NV12;
-               break;
-       case V4L2_PIX_FMT_NV21:
-       case V4L2_PIX_FMT_NV21M:
-               *pixel_format = CAMERA_PIXEL_FORMAT_NV21;
-               break;
-       case V4L2_PIX_FMT_YUV420:
-               *pixel_format = CAMERA_PIXEL_FORMAT_I420;
-               break;
-       case V4L2_PIX_FMT_YVU420:
-               *pixel_format = CAMERA_PIXEL_FORMAT_YV12;
-               break;
-       case V4L2_PIX_FMT_YUYV:
-               *pixel_format = CAMERA_PIXEL_FORMAT_YUYV;
-               break;
-       case V4L2_PIX_FMT_UYVY:
-               *pixel_format = CAMERA_PIXEL_FORMAT_UYVY;
-               break;
-       case V4L2_PIX_FMT_JPEG:
-               *pixel_format = CAMERA_PIXEL_FORMAT_JPEG;
-               break;
-       case V4L2_PIX_FMT_H264:
-               *pixel_format = CAMERA_PIXEL_FORMAT_H264;
-               break;
-       default:
-               LOGE("unknown fourcc "FOURCC_FORMAT, FOURCC_CONVERT(fourcc));
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       LOGD("fourcc "FOURCC_FORMAT" -> %d",
-               FOURCC_CONVERT(fourcc), *pixel_format);
-
-       return CAMERA_ERROR_NONE;
-}
-
-static int __camera_get_fourcc_plane_num(int pixel_format, guint32 *fourcc, guint32 *plane_num)
-{
-       if (!fourcc || !plane_num) {
-               LOGE("NULL parameter %p %p", fourcc, plane_num);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       switch (pixel_format) {
-       case CAMERA_PIXEL_FORMAT_NV12:
-               *fourcc = V4L2_PIX_FMT_NV12;
-               *plane_num = 2;
-               break;
-       case CAMERA_PIXEL_FORMAT_NV21:
-               *fourcc = V4L2_PIX_FMT_NV21;
-               *plane_num = 2;
-               break;
-       case CAMERA_PIXEL_FORMAT_I420:
-               *fourcc = V4L2_PIX_FMT_YUV420;
-               *plane_num = 3;
-               break;
-       case CAMERA_PIXEL_FORMAT_YV12:
-               *fourcc = V4L2_PIX_FMT_YVU420;
-               *plane_num = 3;
-               break;
-       case CAMERA_PIXEL_FORMAT_YUYV:
-               *fourcc = V4L2_PIX_FMT_YUYV;
-               *plane_num = 1;
-               break;
-       case CAMERA_PIXEL_FORMAT_UYVY:
-               *fourcc = V4L2_PIX_FMT_UYVY;
-               *plane_num = 1;
-               break;
-       case CAMERA_PIXEL_FORMAT_JPEG:
-               *fourcc = V4L2_PIX_FMT_JPEG;
-               *plane_num = 1;
-               break;
-       case CAMERA_PIXEL_FORMAT_H264:
-               *fourcc = V4L2_PIX_FMT_H264;
-               *plane_num = 1;
-               break;
-       default:
-               LOGE("unknown format %d", pixel_format);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       LOGD("format %d -> fourcc "FOURCC_FORMAT,
-               pixel_format, FOURCC_CONVERT(*fourcc));
-
-       return CAMERA_ERROR_NONE;
-}
-
-
-static int __camera_get_device_info(int device_index, int device_fd, camera_device_info_t *device_info, char *node_path)
-{
-       int i = 0;
-       int j = 0;
-       int format_count = 0;
-       int resolution_count = 0;
-       int camera_format = 0;
-       struct v4l2_fmtdesc v4l2_format;
-       struct v4l2_frmsizeenum v4l2_frame;
-
-       if (device_fd < 0 || !device_info || !node_path) {
-               LOGE("invalid param %d %p %p", device_fd, device_info, node_path);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGD("Get Supported format and resolution");
-
-       for (i = 0 ; ; i++) {
-               memset(&v4l2_format, 0x0, sizeof(struct v4l2_fmtdesc));
-
-               v4l2_format.index = i;
-               v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-               if (ioctl(device_fd, VIDIOC_ENUM_FMT, &v4l2_format) < 0) {
-                       LOGW("\tformat : end of enumeration");
-                       break;
-               }
-
-               LOGD("\tformat[%d] "FOURCC_FORMAT, i, FOURCC_CONVERT(v4l2_format.pixelformat));
-
-               if (__camera_get_format(v4l2_format.pixelformat, &camera_format) != CAMERA_ERROR_NONE)
-                       continue;
-
-               device_info->format_list.formats[format_count] = camera_format;
-
-               resolution_count = 0;
-
-               for (j = 0 ; ; j++) {
-                       memset(&v4l2_frame, 0x0, sizeof(struct v4l2_frmsizeenum));
-
-                       v4l2_frame.index = j;
-                       v4l2_frame.pixel_format = v4l2_format.pixelformat;
-
-                       if (ioctl(device_fd, VIDIOC_ENUM_FRAMESIZES, &v4l2_frame) < 0) {
-                               LOGW("\t\tframe : end of enumeration ");
-                               break;
-                       }
-
-                       switch (v4l2_frame.type) {
-                       case V4L2_FRMSIZE_TYPE_DISCRETE:
-                               device_info->preview_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
-                               device_info->preview_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
-                               device_info->capture_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
-                               device_info->capture_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
-                               device_info->video_list.resolutions[resolution_count].width = v4l2_frame.discrete.width;
-                               device_info->video_list.resolutions[resolution_count].height = v4l2_frame.discrete.height;
-
-                               resolution_count++;
-
-                               LOGD("\t\tsize[%d] %ux%u", j,
-                                       v4l2_frame.discrete.width,
-                                       v4l2_frame.discrete.height);
-                               break;
-                       case V4L2_FRMSIZE_TYPE_CONTINUOUS:
-                               LOGW("\t\tsize[%d] %ux%u - %ux%u", j,
-                                       v4l2_frame.stepwise.min_width,
-                                       v4l2_frame.stepwise.min_height,
-                                       v4l2_frame.stepwise.max_width,
-                                       v4l2_frame.stepwise.max_height);
-                               break;
-                       case V4L2_FRMSIZE_TYPE_STEPWISE:
-                               LOGW("\t\tsize[%d] %ux%u - %ux%u (step %ux%u)", j,
-                                       v4l2_frame.stepwise.min_width,
-                                       v4l2_frame.stepwise.min_height,
-                                       v4l2_frame.stepwise.max_width,
-                                       v4l2_frame.stepwise.max_height,
-                                       v4l2_frame.stepwise.step_width,
-                                       v4l2_frame.stepwise.step_height);
-                               break;
-                       default:
-                               LOGE("\t\tunknown frame type %d", v4l2_frame.type);
-                               break;
-                       }
-               }
-
-               device_info->preview_list.count = resolution_count;
-               device_info->capture_list.count = resolution_count;
-               device_info->video_list.count = resolution_count;
-
-               LOGD("\t\tresolution count [%d]", resolution_count);
-
-               format_count++;
-       }
-
-       device_info->index = device_index;
-       device_info->format_list.count = format_count;
-       device_info->facing_direction = CAMERA_FACING_DIRECTION_EXTERNAL;
-       snprintf(device_info->name, sizeof(device_info->name), "V4L2_CAMERA");
-       snprintf(device_info->node_path, sizeof(device_info->node_path), "%s", node_path);
-
-       LOGD("\tformat count [%d]", format_count);
-
-       return CAMERA_ERROR_NONE;
-}
-
-static int __camera_get_device_info_list(void)
-{
-       int i = 0;
-       int ret = 0;
-       int device_count = 0;
-       int device_fd = CAMERA_HAL_INITIAL_FD;
-       glob_t glob_buf;
-       struct v4l2_capability v4l2_cap;
-       camera_device_info_list_t *device_info_list = NULL;
-
-       g_mutex_lock(&g_device_info_lock);
-
-       if (g_device_info_list) {
-               LOGD("device info list is already existed");
-               ret = CAMERA_ERROR_NONE;
-               goto _GET_DEVICE_INFO_LIST_DONE;
-       }
-
-       device_info_list = g_new0(camera_device_info_list_t, 1);
-       if (!device_info_list) {
-               LOGE("failed to alloc device info structure");
-               ret = CAMERA_ERROR_OUT_OF_MEMORY;
-               goto _GET_DEVICE_INFO_LIST_DONE;
-       }
-
-       memset(&glob_buf, 0x0, sizeof(glob_t));
-
-       ret = glob(DEVICE_NODE_PATH_PREFIX"*", 0, 0, &glob_buf);
-       if (ret != 0) {
-               switch (ret) {
-               case GLOB_NOSPACE:
-                       LOGE("out of memory");
-                       ret = CAMERA_ERROR_OUT_OF_MEMORY;
-                       goto _GET_DEVICE_INFO_LIST_DONE;
-               case GLOB_ABORTED:
-                       LOGE("read error");
-                       ret = CAMERA_ERROR_INTERNAL;
-                       goto _GET_DEVICE_INFO_LIST_DONE;
-               case GLOB_NOMATCH:
-                       LOGE("match not found");
-                       ret = CAMERA_ERROR_INTERNAL;
-                       goto _GET_DEVICE_INFO_LIST_DONE;
-               default:
-                       LOGE("unknown error : %d", ret);
-                       ret = CAMERA_ERROR_INTERNAL;
-                       goto _GET_DEVICE_INFO_LIST_DONE;
-               }
-       }
-
-       LOGD("device node count : %zu", glob_buf.gl_pathc);
-
-       for (i = 0 ; i < glob_buf.gl_pathc ; i++) {
-               LOGD("[%d] check device [%s]", i, glob_buf.gl_pathv[i]);
-
-               device_fd = open(glob_buf.gl_pathv[i], O_RDWR);
-               if (device_fd < 0) {
-                       LOGE("open failed [%s] errno %d", glob_buf.gl_pathv[i], errno);
-                       continue;
-               }
-
-               memset(&v4l2_cap, 0x0, sizeof(struct v4l2_capability));
-
-               if (ioctl(device_fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0) {
-                       LOGE("querycap failed. errno %d", errno);
-                       close(device_fd);
-                       continue;
-               }
-
-               if (v4l2_cap.capabilities & V4L2_CAP_DEVICE_CAPS)
-                       g_device_caps = v4l2_cap.device_caps;
-               else
-                       g_device_caps = v4l2_cap.capabilities;
-
-               if (!(g_device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) ||
-                       (g_device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) {
-                       LOGW("[%s] is not a capture device 0x%x", glob_buf.gl_pathv[i], g_device_caps);
-                       close(device_fd);
-                       continue;
-               }
-
-               ret = __camera_get_device_info(device_count, device_fd,
-                       &device_info_list->device_info[device_count], glob_buf.gl_pathv[i]);
-
-               close(device_fd);
-
-               if (ret == CAMERA_ERROR_NONE)
-                       device_count++;
-       }
-
-       device_info_list->count = device_count;
-       g_device_info_list = device_info_list;
-
-       LOGD("new g_device_info_list %p - device count %d",
-               g_device_info_list, device_count);
-
-_GET_DEVICE_INFO_LIST_DONE:
-       g_mutex_unlock(&g_device_info_lock);
-       LOGD("ret 0x%x", ret);
-
-       if (ret != CAMERA_ERROR_NONE)
-               g_free(device_info_list);
-
-       return ret;
-}
-
-
-static int __camera_stop_stream(camera_hal_handle *handle, uint32_t buffer_count)
-{
-       int i = 0;
-       int ret = CAMERA_ERROR_NONE;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGD("buffer count[%d]", buffer_count);
-
-       /* stream off */
-       ret = __camera_v4l2_stream(handle->device_fd, handle->buffer_type, FALSE);
-
-       LOGD("stream off : 0x%x", ret);
-
-       /* munmap */
-       for (i = 0 ; i < buffer_count ; i++) {
-               if (handle->camera_buffers[i].planes[0].data != NULL) {
-                       LOGW("munmap %p", handle->camera_buffers[i].planes[0].data);
-
-                       munmap(handle->camera_buffers[i].planes[0].data, handle->camera_buffers[i].planes[0].size);
-
-                       handle->camera_buffers[i].planes[0].data = 0;
-                       handle->camera_buffers[i].planes[0].size = 0;
-               } else {
-                       LOGW("NULL data [index %d]", i);
-               }
-       }
-
-       /* reqbufs 0 */
-       ret = __camera_v4l2_reqbufs(handle->device_fd,
-               handle->buffer_type, V4L2_MEMORY_MMAP, 0, &buffer_count);
-
-       LOGD("reqbufs 0 : 0x%x", ret);
-
-       return ret;
-}
-
-
-static int __camera_start_stream(camera_hal_handle *handle, camera_pixel_format_t pixel_format,
-       camera_resolution_t *resolution, uint32_t fps, uint32_t request_buffer_count)
-{
-       int i = 0;
-       int ret = CAMERA_ERROR_NONE;
-       camera_buffer_t *buffer = NULL;
-       struct v4l2_format v4l2_fmt;
-       struct v4l2_streamparm v4l2_parm;
-       struct v4l2_buffer v4l2_buf;
-       struct v4l2_plane v4l2_planes[V4L2_PLANES_MAX];;
-       guint32 fourcc = 0;
-       guint32 plane_num = 0;
-
-       if (!handle || !resolution) {
-               LOGE("NULL param %p %p", handle, resolution);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       /* S_FMT */
-       ret = __camera_get_fourcc_plane_num(pixel_format, &fourcc, &plane_num);
-       if (ret != CAMERA_ERROR_NONE) {
-               LOGE("get fourcc failed [format %d]", pixel_format);
-               return ret;
-       }
-
-       memset(&v4l2_fmt, 0x0, sizeof(struct v4l2_format));
-
-       v4l2_fmt.type = handle->buffer_type;
-       if (V4L2_TYPE_IS_MULTIPLANAR(handle->buffer_type)) {
-               v4l2_fmt.fmt.pix_mp.width = resolution->width;
-               v4l2_fmt.fmt.pix_mp.height = resolution->height;
-               v4l2_fmt.fmt.pix_mp.pixelformat = fourcc;
-               v4l2_fmt.fmt.pix_mp.num_planes = plane_num;
-       } else {
-               v4l2_fmt.fmt.pix.width = resolution->width;
-               v4l2_fmt.fmt.pix.height = resolution->height;
-               v4l2_fmt.fmt.pix.pixelformat = fourcc;
-               v4l2_fmt.fmt.pix.bytesperline = resolution->width;
-       }
-
-       if (ioctl(handle->device_fd, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
-               LOGE("S_FMT failed. errno %d", errno);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       if (V4L2_TYPE_IS_MULTIPLANAR(handle->buffer_type)) {
-               for (i = 0 ; i < v4l2_fmt.fmt.pix_mp.num_planes ; i++) {
-                       LOGD("plane[%d] stride %u, sizeimage %u", i,
-                               v4l2_fmt.fmt.pix_mp.plane_fmt[i].bytesperline,
-                               v4l2_fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
-               }
-       } else {
-               LOGD("stride %d, sizeimage %d",
-                       v4l2_fmt.fmt.pix.bytesperline,
-                       v4l2_fmt.fmt.pix.sizeimage);
-       }
-
-       /* G_PARM */
-       memset(&v4l2_parm, 0x0, sizeof(struct v4l2_streamparm));
-
-       v4l2_parm.type = handle->buffer_type;
-
-       if (ioctl(handle->device_fd, VIDIOC_G_PARM, &v4l2_parm) < 0) {
-               LOGE("G_PARM failed. errno %d", errno);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       /* S_PARM to set fps */
-       v4l2_parm.parm.capture.timeperframe.numerator = 1;
-       v4l2_parm.parm.capture.timeperframe.denominator = fps;
-
-       if (ioctl(handle->device_fd, VIDIOC_S_PARM, &v4l2_parm) < 0) {
-               LOGE("S_PARM failed. errno %d", errno);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       /* request buffer */
-       ret = __camera_v4l2_reqbufs(handle->device_fd,
-               handle->buffer_type, V4L2_MEMORY_MMAP, request_buffer_count, &handle->buffer_count);
-       if (ret != CAMERA_ERROR_NONE) {
-               return ret;
-       }
-
-       LOGD("buffer count : request %d -> result %d",
-               request_buffer_count, handle->buffer_count);
-
-       /* query buffer, mmap and qbuf */
-       for (i = 0 ; i < handle->buffer_count ; i++) {
-               memset(&v4l2_buf, 0x0, sizeof(struct v4l2_buffer));
-               memset(v4l2_planes, 0x0, sizeof(v4l2_planes));
-
-               v4l2_buf.type = handle->buffer_type;
-               v4l2_buf.memory = V4L2_MEMORY_MMAP;
-               v4l2_buf.index = i;
-               v4l2_buf.m.planes = v4l2_planes;
-               v4l2_buf.length = plane_num;
-
-               if (ioctl(handle->device_fd, VIDIOC_QUERYBUF, &v4l2_buf) < 0) {
-                       LOGE("[%d] query buf failed. errno %d", i, errno);
-                       goto _START_STREAM_FAILED;
-               }
-
-               buffer = &handle->camera_buffers[i];
-
-               buffer->index = i;
-               buffer->format = pixel_format;
-               buffer->resolution.width = resolution->width;
-               buffer->resolution.height = resolution->height;
-               buffer->total_size = v4l2_buf.length;
-               buffer->num_planes = plane_num;
-               buffer->planes[0].size = v4l2_buf.length;
-               buffer->planes[0].data = mmap(0,
-                       v4l2_buf.length,
-                       PROT_READ | PROT_WRITE,
-                       MAP_SHARED,
-                       handle->device_fd,
-                       v4l2_buf.m.offset);
-
-               if (buffer->planes[0].data == MAP_FAILED) {
-                       LOGE("[%d] mmap failed (errno %d)", i, errno);
-                       goto _START_STREAM_FAILED;
-               }
-
-               if (__camera_v4l2_qbuf(handle->device_fd, handle->buffer_type, V4L2_MEMORY_MMAP, i) != CAMERA_ERROR_NONE) {
-                       LOGE("[%d] qbuf failed (errno %d)", i, errno);
-                       goto _START_STREAM_FAILED;
-               }
-       }
-
-       /* stream on */
-       ret = __camera_v4l2_stream(handle->device_fd, handle->buffer_type, TRUE);
-       if (ret != CAMERA_ERROR_NONE) {
-               LOGE("stream on failed");
-               goto _START_STREAM_FAILED;
-       }
-
-       return CAMERA_ERROR_NONE;
-
-_START_STREAM_FAILED:
-       __camera_stop_stream(handle, handle->buffer_count);
-       return ret;
-}
-
-
-static void __camera_do_capture(camera_hal_handle *handle)
-{
-       int ret = CAMERA_ERROR_NONE;
-       int buffer_index = 0;
-       gint64 current_time = 0;
-       gint64 previous_time = 0;
-       gint64 interval_us = 0;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return;
-       }
-
-       LOGD("start");
-
-       if (handle->capture_count > 1)
-               interval_us = handle->capture_interval_ms * 1000;
-
-       /* restart stream for capture */
-       if (handle->capture_restart_stream) {
-               ret = __camera_stop_stream(handle, handle->buffer_count);
-               if (ret != CAMERA_ERROR_NONE) {
-                       LOGE("stop stream failed for capture[0x%x]", ret);
-                       goto _CAPTURE_DONE;
-               }
-
-               ret = __camera_start_stream(handle,
-                       handle->preview_format.capture_format,
-                       &handle->preview_format.capture_resolution,
-                       handle->preview_format.stream_fps,
-                       BUFFER_MAX);
-               if (ret != CAMERA_ERROR_NONE) {
-                       LOGE("start stream failed for capture[0x%x]", ret);
-                       goto _CAPTURE_DONE;
-               }
-       }
-
-       do {
-               /* get capture buffer */
-               ret = __camera_v4l2_wait_frame(handle->device_fd, 5);
-               if (ret != CAMERA_ERROR_NONE) {
-                       LOGE("frame wait failed for capture[0x%x]", ret);
-                       goto _CAPTURE_DONE;
-               }
-
-               ret = __camera_v4l2_dqbuf(handle->device_fd,
-                       handle->buffer_type, V4L2_MEMORY_MMAP, &buffer_index);
-               if (ret != CAMERA_ERROR_NONE) {
-                       LOGE("dqbuf failed for capture[0x%x]", ret);
-                       goto _CAPTURE_DONE;
-               }
-
-               if (handle->captured_count > 0) {
-                       g_mutex_lock(&handle->buffer_lock);
-                       if (handle->state != CAMERA_STATE_CAPTURING) {
-                               LOGW("stop continuous capture");
-                               handle->captured_count = handle->capture_count;
-                               g_mutex_unlock(&handle->buffer_lock);
-                               goto _TRY_NEXT;
-                       }
-                       g_mutex_unlock(&handle->buffer_lock);
-               }
-
-               if (handle->capture_count > 1) {
-                       current_time = g_get_monotonic_time();
-
-                       LOGI("time[prev:%"PRId64", cur:%"PRId64"] interval[%"PRId64" us]",
-                               previous_time, current_time, interval_us);
-
-                       if (current_time < previous_time + interval_us)
-                               goto _TRY_NEXT;
-               }
-
-               g_mutex_lock(&handle->buffer_lock);
-               handle->captured_count++;
-               g_mutex_unlock(&handle->buffer_lock);
-
-               LOGD("capture cb[%p], buffer index[%d],count[%d]",
-                       handle->capture_cb, buffer_index, handle->captured_count);
-
-               if (handle->capture_cb) {
-                       ((camera_capture_cb)handle->capture_cb)(&handle->camera_buffers[buffer_index],
-                               NULL, NULL, handle->capture_cb_data);
-               } else {
-                       LOGW("capture callback is NULL");
-                       /* Need to post error? */
-               }
-
-               previous_time = current_time;
-
-_TRY_NEXT:
-               ret = __camera_v4l2_qbuf(handle->device_fd,
-                       handle->buffer_type, V4L2_MEMORY_MMAP, buffer_index);
-               if (ret != CAMERA_ERROR_NONE)
-                       LOGE("qbuf failed for capture[0x%x]", ret);
-       } while (handle->captured_count < handle->capture_count);
-
-       g_mutex_lock(&handle->buffer_lock);
-
-       if (handle->state == CAMERA_STATE_CAPTURING) {
-               LOGD("wait for capture stop signal");
-               g_cond_wait(&handle->buffer_cond, &handle->buffer_lock);
-               LOGD("signal received");
-       } else {
-               LOGD("The state is already changed.");
-       }
-
-       g_mutex_unlock(&handle->buffer_lock);
-
-_CAPTURE_DONE:
-       /* restart stream for preview */
-       if (handle->capture_restart_stream) {
-               ret = __camera_stop_stream(handle, handle->buffer_count);
-               if (ret != CAMERA_ERROR_NONE)
-                       LOGE("stop stream failed for preview[0x%x]", ret);
-
-               ret = __camera_start_stream(handle,
-                       handle->preview_format.stream_format,
-                       &handle->preview_format.stream_resolution,
-                       handle->preview_format.stream_fps,
-                       BUFFER_MAX);
-               if (ret != CAMERA_ERROR_NONE)
-                       LOGE("start stream failed for preview[0x%x]", ret);
-       }
-
-       LOGD("done");
-}
-
-
-static void *__camera_buffer_handler_func(gpointer data)
-{
-       int index = 0;
-       camera_hal_handle *handle = (camera_hal_handle *)data;
-
-       if (!handle) {
-               LOGE("NULL handle for buffer handler");
-               return NULL;
-       }
-
-       LOGD("enter");
-
-       /* run buffer thread */
-       g_mutex_lock(&handle->buffer_lock);
-
-       while (handle->buffer_thread_run) {
-               g_mutex_unlock(&handle->buffer_lock);
-
-               if (__camera_v4l2_wait_frame(handle->device_fd, 5) != CAMERA_ERROR_NONE) {
-                       LOGE("frame wait failed");
-                       g_mutex_lock(&handle->buffer_lock);
-                       break;
-               }
-
-               g_mutex_lock(&handle->buffer_lock);
-
-               if (handle->buffer_thread_run == FALSE) {
-                       LOGW("stop buffer handler thread");
-                       break;
-               }
-
-               if (__camera_v4l2_dqbuf(handle->device_fd, handle->buffer_type, V4L2_MEMORY_MMAP, &index) != CAMERA_ERROR_NONE) {
-                       LOGE("dqbuf failed");
-                       break;
-               }
-
-               handle->buffer_dequeued_count++;
-
-               /*LOGD("dequeued buffer count %d", handle->buffer_dequeued_count);*/
-
-               g_mutex_unlock(&handle->buffer_lock);
-
-               if (handle->preview_cb) {
-                       ((camera_preview_frame_cb)handle->preview_cb)(&handle->camera_buffers[index], NULL, handle->preview_cb_data);
-               } else {
-                       LOGW("preview callback is NULL");
-                       camera_release_preview_buffer((void *)handle, index);
-               }
-
-               /* check capture request flag */
-               if (handle->capture_request) {
-                       __camera_do_capture(handle);
-                       handle->capture_request = FALSE;
-               }
-
-               sched_yield();
-
-               g_mutex_lock(&handle->buffer_lock);
-       }
-
-       g_mutex_unlock(&handle->buffer_lock);
-
-       LOGD("leave");
-
-       return NULL;
-}
-
-
-static void __camera_message_release_func(gpointer data)
-{
-       camera_message_t *message = (camera_message_t *)data;
-
-       if (!message) {
-               LOGW("NULL message");
-               return;
-       }
-
-       LOGD("release message %p, type %d", message, message->type);
-
-       g_free(message);
-
-       return;
-}
-
-
-static void *_camera_message_handler_func(gpointer data)
-{
-       int i = 0;
-       camera_message_t *message = NULL;
-       camera_hal_handle *handle = (camera_hal_handle *)data;
-
-       if (!handle) {
-               LOGE("NULL handle for capture thread");
-               return NULL;
-       }
-
-       LOGD("enter - message thread");
-
-       g_mutex_lock(&handle->msg_cb_lock);
-
-       while (handle->msg_cb_run) {
-               if (g_queue_is_empty(handle->msg_list)) {
-                       LOGD("wait for message");
-                       g_cond_wait(&handle->msg_cb_cond, &handle->msg_cb_lock);
-                       LOGD("message signal received");
-               }
-
-               if (!handle->msg_cb_run) {
-                       LOGW("break message thread");
-                       break;
-               }
-
-               message = g_queue_pop_head(handle->msg_list);
-               if (!message) {
-                       LOGW("NULL message");
-                       continue;
-               }
-
-               g_mutex_unlock(&handle->msg_cb_lock);
-
-               for (i = 0 ; i < MESSAGE_CALLBACK_MAX ; i++) {
-                       if (handle->msg_cb[i]) {
-                               LOGD("call message callback type %d", message->type);
-                               ((camera_message_cb)handle->msg_cb[i])(message, handle->msg_cb_data[i]);
-                       }
-               }
-
-               g_free(message);
-               message = NULL;
-
-               g_mutex_lock(&handle->msg_cb_lock);
-       }
-
-       g_mutex_unlock(&handle->msg_cb_lock);
-
-       LOGD("leave - message thread");
-
-       return NULL;
-}
-
-
-static void __camera_release_handle(camera_hal_handle *handle)
-{
-       if (!handle) {
-               LOGW("NULL handle");
-               return;
-       }
-
-       if (handle->msg_thread) {
-               g_mutex_lock(&handle->msg_cb_lock);
-               handle->msg_cb_run = FALSE;
-               g_cond_signal(&handle->msg_cb_cond);
-               g_mutex_unlock(&handle->msg_cb_lock);
-               g_thread_join(handle->msg_thread);
-               g_queue_free_full(handle->msg_list, (GDestroyNotify)__camera_message_release_func);
-               handle->msg_list = NULL;
-       }
-
-       g_mutex_clear(&handle->lock);
-       g_mutex_clear(&handle->buffer_lock);
-       g_mutex_clear(&handle->msg_cb_lock);
-       g_cond_clear(&handle->buffer_cond);
-       g_cond_clear(&handle->msg_cb_cond);
-
-       if (handle->bufmgr) {
-               tbm_bufmgr_deinit(handle->bufmgr);
-               handle->bufmgr = NULL;
-       }
-
-       LOGD("camera HAL handle %p destroy", handle);
-
-       g_free(handle);
-
-       return;
-}
-
-
-int camera_init(void **camera_handle)
-{
-       int ret = CAMERA_ERROR_NONE;
-       camera_hal_handle *new_handle = NULL;
-       tbm_bufmgr bufmgr = NULL;
-
-       LOGD("enter");
-
-       if (!camera_handle) {
-               LOGE("NULL pointer for handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       bufmgr = tbm_bufmgr_init(-1);
-       if (bufmgr == NULL) {
-               LOGE("get tbm bufmgr failed");
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       new_handle = g_new0(camera_hal_handle, 1);
-       if (!new_handle) {
-               LOGE("failed to alloc camera hal handle");
-               tbm_bufmgr_deinit(bufmgr);
-               return CAMERA_ERROR_OUT_OF_MEMORY;
-       }
-
-       new_handle->bufmgr = bufmgr;
-
-       g_mutex_init(&new_handle->lock);
-       g_mutex_init(&new_handle->buffer_lock);
-       g_mutex_init(&new_handle->msg_cb_lock);
-       g_cond_init(&new_handle->buffer_cond);
-       g_cond_init(&new_handle->msg_cb_cond);
-
-       /* message thread */
-       new_handle->msg_list = g_queue_new();
-       new_handle->msg_cb_run = TRUE;
-       new_handle->msg_thread = g_thread_try_new("camera_hal_msg_thread",
-               _camera_message_handler_func, (gpointer)new_handle, NULL);
-       if (!new_handle->msg_thread) {
-               LOGE("failed to create message thread");
-               ret = CAMERA_ERROR_INTERNAL;
-               goto _INIT_ERROR;
-       }
-
-       new_handle->device_index = CAMERA_HAL_INITIAL_INDEX;
-       new_handle->device_fd = CAMERA_HAL_INITIAL_FD;
-       new_handle->state = CAMERA_STATE_INITIALIZED;
-
-       ret = __camera_get_device_info_list();
-       if (ret != CAMERA_ERROR_NONE) {
-               LOGE("get device info failed");
-               goto _INIT_ERROR;
-       }
-
-       *camera_handle = new_handle;
-
-       LOGD("camera HAL handle %p", new_handle);
-
-       return CAMERA_ERROR_NONE;
-
-_INIT_ERROR:
-       __camera_release_handle(new_handle);
-
-       return ret;
-}
-
-int camera_deinit(void *camera_handle)
-{
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_INITIALIZED) {
-               LOGE("invalid state %d, can not destroy handle", handle->state);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_STATE;
-       }
-
-       g_mutex_unlock(&handle->lock);
-
-       __camera_release_handle(handle);
-
-       return CAMERA_ERROR_NONE;
-}
-
-int camera_get_device_info_list(camera_device_info_list_t *device_info_list)
-{
-       int ret = 0;
-
-       if (!device_info_list) {
-               LOGE("NULL pointer for device_info_list");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       ret = __camera_get_device_info_list();
-       if (ret != CAMERA_ERROR_NONE) {
-               LOGE("get device info failed");
-               return ret;
-       }
-
-       memcpy(device_info_list, g_device_info_list, sizeof(camera_device_info_list_t));
-
-       return CAMERA_ERROR_NONE;
-}
-
-int camera_open_device(void *camera_handle, int device_index)
-{
-       int ret = CAMERA_ERROR_NONE;
-       int device_fd = CAMERA_HAL_INITIAL_FD;
-       char *node_path = NULL;
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_INITIALIZED) {
-               LOGE("invalid state %d", handle->state);
-               ret = CAMERA_ERROR_INVALID_STATE;
-               goto _OPEN_DEVICE_DONE;
-       }
-
-       if (!g_device_info_list) {
-               LOGE("NO DEVICE INFO");
-               ret = CAMERA_ERROR_INTERNAL;
-               goto _OPEN_DEVICE_DONE;
-       }
-
-       if (device_index >= g_device_info_list->count) {
-               LOGE("invalid index %d [info:%d]", device_index, g_device_info_list->count);
-               ret = CAMERA_ERROR_INVALID_PARAMETER;
-               goto _OPEN_DEVICE_DONE;
-       }
-
-       node_path = g_device_info_list->device_info[device_index].node_path;
-
-       device_fd = open(node_path, O_RDWR);
-       if (device_fd < 0) {
-               switch (errno) {
-                       case EACCES:
-                       case EPERM:
-                               ret = CAMERA_ERROR_PERMISSION_DENIED;
-                               break;
-                       case ENOENT:
-                               ret = CAMERA_ERROR_DEVICE_NOT_FOUND;
-                               break;
-                       case EBUSY:
-                               ret = CAMERA_ERROR_DEVICE_BUSY;
-                               break;
-                       default:
-                               ret = CAMERA_ERROR_DEVICE_OPEN;
-                               break;
-               }
-
-               LOGE("open [%s] failed 0x%x [errno %d]",
-                       node_path, ret, errno);
-
-               goto _OPEN_DEVICE_DONE;
-       }
-
-       if (g_device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
-               handle->buffer_type = V4L2_CAP_VIDEO_CAPTURE_MPLANE;
-       else
-               handle->buffer_type = V4L2_CAP_VIDEO_CAPTURE;
-
-       handle->state = CAMERA_STATE_OPENED;
-       handle->device_index = device_index;
-       handle->device_fd = device_fd;
-
-       LOGD("[%d] device[%s] opened [fd %d, type %d]",
-               device_index, node_path, device_fd, handle->buffer_type);
-
-_OPEN_DEVICE_DONE:
-       g_mutex_unlock(&handle->lock);
-
-       return ret;
-}
-
-int camera_close_device(void *camera_handle)
-{
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_OPENED) {
-               LOGE("invalid state %d", handle->state);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_STATE;
-       }
-
-       if (handle->device_fd >= 0) {
-               LOGD("close fd %d", handle->device_fd);
-
-               close(handle->device_fd);
-               handle->device_fd = CAMERA_HAL_INITIAL_FD;
-       } else {
-               LOGW("invalid fd %d", handle->device_fd);
-       }
-
-       handle->state = CAMERA_STATE_INITIALIZED;
-
-       LOGD("device [%d] closed", handle->device_index);
-
-       g_mutex_unlock(&handle->lock);
-
-       return CAMERA_ERROR_NONE;
-}
-
-int camera_add_message_callback(void *camera_handle, camera_message_cb callback, void *user_data, uint32_t *cb_id)
-{
-       uint32_t i = 0;
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       if (!callback || !cb_id) {
-               LOGE("NULL pointer for callback %p or cb_id %p", callback, cb_id);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_OPENED) {
-               LOGE("invalid state %d", handle->state);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_STATE;
-       }
-
-       for (i = 0 ; i < MESSAGE_CALLBACK_MAX ; i++) {
-               if (handle->msg_cb[i] == NULL) {
-                       handle->msg_cb[i] = callback;
-                       handle->msg_cb_data[i] = user_data;
-                       *cb_id = i;
-                       LOGD("message cb [%p] added, user data %p - id %u", callback, user_data, i);
-                       g_mutex_unlock(&handle->lock);
-                       return CAMERA_ERROR_NONE;
-               }
-       }
-
-       g_mutex_unlock(&handle->lock);
-
-       LOGE("no available message cb slot");
-
-       return CAMERA_ERROR_INTERNAL;
-}
-
-int camera_remove_message_callback(void *camera_handle, uint32_t cb_id)
-{
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       if (cb_id >= MESSAGE_CALLBACK_MAX) {
-               LOGE("invalid cb_id %u", cb_id);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_OPENED) {
-               LOGE("invalid state %d", handle->state);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_STATE;
-       }
-
-       if (handle->msg_cb[cb_id]) {
-               LOGD("remove message callback %p, user data %p - cb_id %u",
-                       handle->msg_cb[cb_id], handle->msg_cb_data[cb_id], cb_id);
-
-               handle->msg_cb[cb_id] = NULL;
-               handle->msg_cb_data[cb_id] = NULL;
-       } else {
-               LOGE("already removed message cb");
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       g_mutex_unlock(&handle->lock);
-
-       return CAMERA_ERROR_NONE;
-}
-
-int camera_set_preview_stream_format(void *camera_handle, camera_format_t *format)
-{
-       int i = 0;
-       int j = 0;
-       int ret = CAMERA_ERROR_NONE;
-       gboolean capability_check = FALSE;
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-       camera_device_info_t *device_info = NULL;
-
-       if (!handle || !format) {
-               LOGE("NULL param %p %p", handle, format);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       if (!g_device_info_list) {
-               LOGE("no device info list");
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_OPENED &&
-               handle->state != CAMERA_STATE_PREVIEWING) {
-               LOGE("invalid state %d", handle->state);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_STATE;
-       }
-
-       /* check capability */
-       device_info = &g_device_info_list->device_info[handle->device_index];
-
-       /* format */
-       for (i = 0 ; i < device_info->format_list.count ; i++) {
-               if (format->stream_format == device_info->format_list.formats[i]) {
-                       LOGD("format matched %d, check resolution.", format->stream_format);
-
-                       /* resolution */
-                       for (j = 0 ; j < device_info->preview_list.count ; j++) {
-                               if (format->stream_resolution.width == device_info->preview_list.resolutions[j].width &&
-                                       format->stream_resolution.height == device_info->preview_list.resolutions[j].height) {
-                                       LOGD("resolution matched %dx%d",
-                                               format->stream_resolution.width,
-                                               format->stream_resolution.height);
-                                       capability_check = TRUE;
-                                       break;
-                               }
-                       }
-
-                       break;
-               }
-       }
-
-       if (!capability_check) {
-               LOGE("capability failed - %d, %dx%d",
-                       format->stream_format,
-                       format->stream_resolution.width,
-                       format->stream_resolution.height);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       /* compare with current settings */
-       if (handle->state == CAMERA_STATE_PREVIEWING) {
-               if (handle->preview_format.stream_format == format->stream_format &&
-                       handle->preview_format.stream_resolution.width == format->stream_resolution.width &&
-                       handle->preview_format.stream_resolution.height == format->stream_resolution.height &&
-                       handle->preview_format.stream_fps == format->stream_fps &&
-                       handle->preview_format.stream_rotation == format->stream_rotation) {
-                       LOGD("no need to restart preview stream");
-                       goto _SET_PREVIEW_STREAM_FORMAT_DONE;
-               }
-
-               LOGD("Preview setting is changed. Restart preview now.");
-
-               /* stop preview stream to change it */
-               ret = __camera_stop_stream(handle, handle->buffer_count);
-               if (ret != CAMERA_ERROR_NONE) {
-                       LOGE("failed to stop stream");
-                       g_mutex_unlock(&handle->lock);
-                       return ret;
-               }
-
-               /* restart preview stream to change it */
-               ret = __camera_start_stream(handle,
-                       format->stream_format,
-                       &format->stream_resolution,
-                       format->stream_fps,
-                       BUFFER_MAX);
-               if (ret != CAMERA_ERROR_NONE) {
-                       LOGE("failed to start stream");
-                       g_mutex_unlock(&handle->lock);
-                       return ret;
-               }
-       }
-
-_SET_PREVIEW_STREAM_FORMAT_DONE:
-       /* set capture restart flag */
-       if (format->stream_format == format->capture_format &&
-               format->stream_resolution.width == format->capture_resolution.width &&
-               format->stream_resolution.height == format->capture_resolution.height)
-               handle->capture_restart_stream = FALSE;
-       else
-               handle->capture_restart_stream = TRUE;
-
-       memcpy(&handle->preview_format, format, sizeof(camera_format_t));
-
-       LOGD("set format PREVIEW[%d:%dx%d,fps:%d], CAPTURE[%d:%dx%d,restart:%d]",
-               format->stream_format,
-               format->stream_resolution.width,
-               format->stream_resolution.height,
-               format->stream_fps,
-               format->capture_format,
-               format->capture_resolution.width,
-               format->capture_resolution.height,
-               handle->capture_restart_stream);
-
-       g_mutex_unlock(&handle->lock);
-
-       return CAMERA_ERROR_NONE;
-}
-
-int camera_get_preview_stream_format(void *camera_handle, camera_format_t *format)
-{
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle || !format) {
-               LOGE("NULL param %p %p", handle, format);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       memcpy(format, &handle->preview_format, sizeof(camera_format_t));
-
-       LOGD("get stream format %d, %dx%d", format->stream_format,
-               format->stream_resolution.width, format->stream_resolution.height);
-
-       g_mutex_unlock(&handle->lock);
-
-       return CAMERA_ERROR_NONE;
-}
-
-
-int camera_start_preview(void *camera_handle, camera_preview_frame_cb callback, void *user_data)
-{
-       int ret = 0;
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle || !callback) {
-               LOGE("NULL param %p %p", handle, callback);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_OPENED) {
-               LOGE("invalid state %d", handle->state);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_STATE;
-       }
-
-       ret = __camera_start_stream(handle,
-               handle->preview_format.stream_format,
-               &handle->preview_format.stream_resolution,
-               handle->preview_format.stream_fps,
-               BUFFER_MAX);
-       if (ret != CAMERA_ERROR_NONE) {
-               LOGE("__camera_start_stream failed[0x%x]", ret);
-               g_mutex_unlock(&handle->lock);
-               return ret;
-       }
-
-       g_mutex_lock(&handle->buffer_lock);
-
-       handle->buffer_thread_run = TRUE;
-
-       handle->buffer_thread = g_thread_try_new("camera_hal_buffer_thread",
-               __camera_buffer_handler_func, (gpointer)handle, NULL);
-       if (!handle->buffer_thread) {
-               LOGE("failed to create buffer handler thread");
-               g_mutex_unlock(&handle->buffer_lock);
-
-               __camera_stop_stream(handle, handle->buffer_count);
-
-               g_mutex_unlock(&handle->lock);
-
-               return ret;
-       }
-
-       handle->preview_cb = callback;
-       handle->preview_cb_data = user_data;
-
-       g_mutex_unlock(&handle->buffer_lock);
-
-       handle->state = CAMERA_STATE_PREVIEWING;
-
-       LOGD("start preview done");
-
-       g_mutex_unlock(&handle->lock);
-
-       return CAMERA_ERROR_NONE;
-}
-
-int camera_release_preview_buffer(void *camera_handle, int buffer_index)
-{
-       int ret = CAMERA_ERROR_NONE;
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       if (buffer_index >= handle->buffer_count) {
-               LOGE("invalid buffer index %d", buffer_index);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       ret = __camera_v4l2_qbuf(handle->device_fd,
-               handle->buffer_type, V4L2_MEMORY_MMAP, buffer_index);
-
-       g_mutex_lock(&handle->buffer_lock);
-
-       if (ret == CAMERA_ERROR_NONE) {
-               if (handle->buffer_dequeued_count > 0)
-                       handle->buffer_dequeued_count--;
-               else
-                       LOGW("invalid dequeued buffer count[%u]", handle->buffer_dequeued_count);
-
-               /*LOGD("qbud done : index %d, dequeued buffer count %d",
-                       buffer_index, handle->buffer_dequeued_count);*/
-       } else {
-               LOGE("qbuf failed [index %d]", buffer_index);
-       }
-
-       g_cond_signal(&handle->buffer_cond);
-
-       g_mutex_unlock(&handle->buffer_lock);
-
-       return ret;
-}
-
-
-int camera_stop_preview(void *camera_handle)
-{
-       int ret = CAMERA_ERROR_NONE;
-       gint64 end_time;
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGD("start");
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_PREVIEWING) {
-               LOGE("invalid state %d", handle->state);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_STATE;
-       }
-
-       g_mutex_lock(&handle->buffer_lock);
-
-       handle->buffer_thread_run = FALSE;
-
-       while (handle->buffer_dequeued_count > 0) {
-               LOGD("wait for dequeued buffer [%d]", handle->buffer_dequeued_count);
-               end_time = g_get_monotonic_time() + 3 * G_TIME_SPAN_SECOND;
-               if (!g_cond_wait_until(&handle->buffer_cond, &handle->buffer_lock, end_time)) {
-                       LOGE("buffer wait failed");
-                       break;
-               } else {
-                       LOGD("signal received. check again...");
-               }
-       }
-
-       g_mutex_unlock(&handle->buffer_lock);
-
-       ret = __camera_stop_stream(handle, handle->buffer_count);
-
-       /* wait for preview thread exit */
-       g_thread_join(handle->buffer_thread);
-       handle->buffer_thread = NULL;
-
-       handle->state = CAMERA_STATE_OPENED;
-
-       LOGD("stop preview done [0x%x]", ret);
-
-       g_mutex_unlock(&handle->lock);
-
-       return CAMERA_ERROR_NONE;
-}
-
-int camera_start_auto_focus(void *camera_handle)
-{
-       if (!camera_handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGE("NOT SUPPORTED");
-
-       /* auto focus is not supported */
-       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-}
-
-int camera_stop_auto_focus(void *camera_handle)
-{
-       if (!camera_handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGE("NOT SUPPORTED");
-
-       /* auto focus is not supported */
-       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-}
-
-
-int camera_start_capture(void *camera_handle, camera_capture_cb callback, void *user_data)
-{
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle || !callback) {
-               LOGE("NULL param %p %p", camera_handle, callback);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_PREVIEWING) {
-               LOGE("invalid state %d", handle->state);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_STATE;
-       }
-
-       /* set callback and user data */
-       handle->capture_cb = callback;
-       handle->capture_cb_data = user_data;
-
-       /* reset captured count */
-       handle->captured_count = 0;
-
-       LOGD("start capture - count %u", handle->capture_count);
-
-       /* set capture request flag */
-       handle->capture_request = TRUE;
-
-       handle->state = CAMERA_STATE_CAPTURING;
-
-       g_mutex_unlock(&handle->lock);
-
-       return CAMERA_ERROR_NONE;
-}
-
-int camera_stop_capture(void *camera_handle)
-{
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state != CAMERA_STATE_CAPTURING) {
-               LOGE("invalid state %d", handle->state);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INVALID_STATE;
-       }
-
-       g_mutex_lock(&handle->buffer_lock);
-
-       if (handle->captured_count == 0) {
-               LOGE("No captured image yet.");
-               g_mutex_unlock(&handle->buffer_lock);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_INTERNAL;
-       }
-
-       LOGD("send signal to start preview after capture");
-
-       g_cond_signal(&handle->buffer_cond);
-       g_mutex_unlock(&handle->buffer_lock);
-
-       handle->state = CAMERA_STATE_PREVIEWING;
-
-       g_mutex_unlock(&handle->lock);
-
-       return CAMERA_ERROR_NONE;
-}
-
-int camera_set_video_stream_format(void *camera_handle, camera_format_t *format)
-{
-       if (!camera_handle || !format) {
-               LOGE("NULL param %p %p", camera_handle, format);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGE("NOT SUPPORTED");
-
-       /* single stream device can not support video stream */
-       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-}
-
-int camera_get_video_stream_format(void *camera_handle, camera_format_t *format)
-{
-       if (!camera_handle || !format) {
-               LOGE("NULL param %p %p", camera_handle, format);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGE("NOT SUPPORTED");
-
-       /* single stream device can not support video stream */
-       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-}
-
-int camera_start_record(void *camera_handle, camera_video_frame_cb callback, void *user_data)
-{
-       if (!camera_handle || !callback) {
-               LOGE("NULL param %p %p", camera_handle, callback);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGE("NOT SUPPORTED");
-
-       /* single stream device can not support video stream */
-       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-}
-
-int camera_release_video_buffer(void *camera_handle, int buffer_index)
-{
-       if (!camera_handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGE("NOT SUPPORTED");
-
-       /* single stream device can not support video stream */
-       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-}
-
-int camera_stop_record(void *camera_handle)
-{
-       if (!camera_handle) {
-               LOGE("NULL handle");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       LOGE("NOT SUPPORTED");
-
-       /* single stream device can not support video stream */
-       return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-}
-
-int camera_set_command(void *camera_handle, int64_t command, void *value)
-{
-       int ret = CAMERA_ERROR_NONE;
-       int cid = 0;
-       int ctrl_ret = 0;
-       int set_value = 0;
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle || !value) {
-               LOGE("NULL param %p %p", handle, value);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       set_value = *(int *)value;
-
-       g_mutex_lock(&handle->lock);
-
-       if (handle->state < CAMERA_STATE_OPENED) {
-               LOGE("invalid state %d", handle->state);
-               ret = CAMERA_ERROR_INVALID_STATE;
-               goto _SET_COMMAND_DONE;
-       }
-
-       LOGD("set command %"PRIx64" - state %d", command, handle->state);
-
-       switch (command) {
-       case CAMERA_COMMAND_BRIGHTNESS:
-               cid = V4L2_CID_BRIGHTNESS;
-               break;
-       case CAMERA_COMMAND_CONTRAST:
-               cid = V4L2_CID_CONTRAST;
-               break;
-       case CAMERA_COMMAND_SATURATION:
-               cid = V4L2_CID_SATURATION;
-               break;
-       case CAMERA_COMMAND_SHARPNESS:
-               cid = V4L2_CID_SHARPNESS;
-               break;
-       case CAMERA_COMMAND_PTZ_TYPE:
-               if (set_value != CAMERA_PTZ_TYPE_ELECTRONIC) {
-                       LOGE("not supported PTZ type %d", set_value);
-                       ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-               }
-               goto _SET_COMMAND_DONE;
-       case CAMERA_COMMAND_PAN:
-               cid = V4L2_CID_PAN_ABSOLUTE;
-               break;
-       case CAMERA_COMMAND_TILT:
-               cid = V4L2_CID_TILT_ABSOLUTE;
-               break;
-       case CAMERA_COMMAND_FLIP:
-               if (set_value != CAMERA_FLIP_NONE) {
-                       LOGE("NOT_SUPPORTED flip %d", set_value);
-                       ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-               }
-               goto _SET_COMMAND_DONE;
-       case CAMERA_COMMAND_CAPTURE_COUNT:
-               handle->capture_count = set_value;
-               LOGI("capture count %u", handle->capture_count);
-               goto _SET_COMMAND_DONE;
-       case CAMERA_COMMAND_CAPTURE_INTERVAL:
-               handle->capture_interval_ms = set_value;
-               LOGI("capture interval %u ms", handle->capture_interval_ms);
-               goto _SET_COMMAND_DONE;
-       default:
-               LOGE("NOT_SUPPORTED command %"PRIx64, command);
-               ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-               goto _SET_COMMAND_DONE;
-       }
-
-       ctrl_ret = __camera_v4l2_s_ctrl(handle->device_fd, cid, set_value);
-       if (ctrl_ret < 0) {
-               switch (errno) {
-               case EACCES:
-               case EPERM:
-                       LOGE("Permission denied %d", errno);
-                       ret = CAMERA_ERROR_PERMISSION_DENIED;
-                       break;
-               case EINVAL:
-                       LOGE("Invalid argument");
-                       ret = CAMERA_ERROR_INVALID_PARAMETER;
-                       break;
-               case EBUSY:
-                       LOGE("Device busy");
-                       ret = CAMERA_ERROR_DEVICE_BUSY;
-                       break;
-               case ENOTSUP:
-                       LOGE("Not supported");
-                       ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-                       break;
-               default:
-                       LOGE("Unknown errro %d", errno);
-                       ret = CAMERA_ERROR_INTERNAL;
-                       break;
-               }
-       }
-
-_SET_COMMAND_DONE:
-       g_mutex_unlock(&handle->lock);
-
-       return ret;
-}
-
-int camera_get_command(void *camera_handle, int64_t command, void **value)
-{
-       int ret = CAMERA_ERROR_NONE;
-       int cid = 0;
-       int ctrl_ret = 0;
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle || !value) {
-               LOGE("NULL param %p %p", handle, value);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       LOGD("get command %"PRId64" - state %d", command, handle->state);
-
-       switch (command) {
-       case CAMERA_COMMAND_BRIGHTNESS:
-               cid = V4L2_CID_BRIGHTNESS;
-               break;
-       case CAMERA_COMMAND_CONTRAST:
-               cid = V4L2_CID_CONTRAST;
-               break;
-       case CAMERA_COMMAND_SATURATION:
-               cid = V4L2_CID_SATURATION;
-               break;
-       case CAMERA_COMMAND_SHARPNESS:
-               cid = V4L2_CID_SHARPNESS;
-               break;
-       default:
-               LOGE("NOT_SUPPORTED %"PRId64, command);
-               g_mutex_unlock(&handle->lock);
-               return CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-       }
-
-       ctrl_ret = __camera_v4l2_g_ctrl(handle->device_fd, cid, (int *)value);
-       if (ctrl_ret < 0) {
-               switch (errno) {
-               case EACCES:
-               case EPERM:
-                       LOGE("Permission denied %d", errno);
-                       ret = CAMERA_ERROR_PERMISSION_DENIED;
-                       break;
-               case EINVAL:
-                       LOGE("Invalid argument");
-                       ret = CAMERA_ERROR_INVALID_PARAMETER;
-                       break;
-               case EBUSY:
-                       LOGE("Device busy");
-                       ret = CAMERA_ERROR_DEVICE_BUSY;
-                       break;
-               case ENOTSUP:
-                       LOGE("Not supported");
-                       ret = CAMERA_ERROR_DEVICE_NOT_SUPPORTED;
-                       break;
-               default:
-                       LOGE("Unknown errro %d", errno);
-                       ret = CAMERA_ERROR_INTERNAL;
-                       break;
-               }
-       }
-
-       g_mutex_unlock(&handle->lock);
-
-       return ret;
-}
-
-int camera_set_batch_command(void *camera_handle, camera_batch_command_control_t *batch_command, int64_t *error_command)
-{
-       camera_hal_handle *handle = (camera_hal_handle *)camera_handle;
-
-       if (!handle || !batch_command) {
-               LOGE("NULL param %p %p", handle, batch_command);
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       g_mutex_lock(&handle->lock);
-
-       LOGD("set batch command - flag %"PRIx64", state %d",
-               batch_command->command_set_flag, handle->state);
-
-       /* TODO: to be implemented */
-
-       g_mutex_unlock(&handle->lock);
-
-       return CAMERA_ERROR_NONE;
-}
diff --git a/src/tizen_camera_v4l2_private.h b/src/tizen_camera_v4l2_private.h
deleted file mode 100644 (file)
index 035316b..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * tizen_camera_private.c
- *
- * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef __TIZEN_CAMERA_PRIVATE_H__
-#define __TIZEN_CAMERA_PRIVATE_H__
-
-#include <linux/videodev2.h>
-#include <glib.h>
-#include <tbm_bufmgr.h>
-#include <tizen-camera.h>
-
-#define CAMERA_HAL_INITIAL_INDEX    -1
-#define CAMERA_HAL_INITIAL_FD       -1
-#define MESSAGE_CALLBACK_MAX        10
-#define BUFFER_MAX                  4
-#define V4L2_PLANES_MAX             4
-
-typedef struct _camera_hal_handle {
-       /* tbm */
-       tbm_bufmgr bufmgr;
-
-       /* device */
-       gint32 device_index;
-       gint32 device_fd;
-
-       /* buffer */
-       guint32 buffer_dequeued_count;
-       GThread *buffer_thread;
-       gboolean buffer_thread_run;
-       guint32 buffer_count;
-       camera_buffer_t camera_buffers[BUFFER_MAX];
-       enum v4l2_buf_type buffer_type;
-       GMutex buffer_lock;
-       GCond buffer_cond;
-
-       /* preview */
-       camera_format_t preview_format;
-       camera_preview_frame_cb preview_cb;
-       gpointer preview_cb_data;
-
-       /* capture */
-       camera_capture_cb capture_cb;
-       gpointer capture_cb_data;
-       guint32 capture_count;
-       guint32 capture_interval_ms;
-       guint32 captured_count;
-       gboolean capture_request;
-       gboolean capture_restart_stream;
-
-       /* message */
-       GThread *msg_thread;
-       camera_message_cb msg_cb[MESSAGE_CALLBACK_MAX];
-       gpointer msg_cb_data[MESSAGE_CALLBACK_MAX];
-       gboolean msg_cb_run;
-       GQueue *msg_list;
-       GMutex msg_cb_lock;
-       GCond msg_cb_cond;
-
-       /* etc */
-       GMutex lock;
-       camera_state_t state;
-} camera_hal_handle;
-
-#endif /* __TIZEN_CAMERA_PRIVATE_H__ */